From f21bef263d33ef65ad09e9dafeef09c1641607c1 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Thu, 14 Sep 2023 22:43:25 -0500 Subject: [PATCH] convert to typescript --- .gitignore | 3 +- benchmark.js | 2 +- examples/psn_client.js | 9 +- examples/psn_server.js | 2 +- index.js | 9 - package-lock.json | 446 +++++++++++++++++- package.json | 17 +- src/constants.js | 5 - src/constants.ts | 5 + src/decoder.js | 109 ----- src/decoder.ts | 117 +++++ src/decoders/{chunk.js => chunk.ts} | 11 +- src/decoders/data/data-packet-chunk.js | 29 -- src/decoders/data/data-packet-chunk.ts | 38 ++ src/decoders/data/data-tracker-chunk.js | 41 -- src/decoders/data/data-tracker-chunk.ts | 53 +++ src/decoders/data/data-tracker-field-chunk.js | 43 -- src/decoders/data/data-tracker-field-chunk.ts | 50 ++ src/decoders/data/data-tracker-list-chunk.js | 17 - src/decoders/data/data-tracker-list-chunk.ts | 30 ++ src/decoders/info/info-packet-chunk.js | 35 -- src/decoders/info/info-packet-chunk.ts | 47 ++ src/decoders/info/info-system-name-chunk.js | 9 - src/decoders/info/info-system-name-chunk.ts | 13 + src/decoders/info/info-tracker-chunk.js | 24 - src/decoders/info/info-tracker-chunk.ts | 30 ++ src/decoders/info/info-tracker-list-chunk.js | 17 - src/decoders/info/info-tracker-list-chunk.ts | 29 ++ src/decoders/info/info-tracker-name-chunk.js | 8 - src/decoders/info/info-tracker-name-chunk.ts | 11 + src/decoders/packet-header-chunk.js | 12 - src/decoders/packet-header-chunk.ts | 21 + src/decoders/packet.js | 14 - src/decoders/packet.ts | 15 + src/{encoder.js => encoder.ts} | 57 +-- src/encoders/{chunk.js => chunk.ts} | 2 +- src/encoders/data/data-packet-chunk.js | 4 - src/encoders/data/data-packet-chunk.ts | 3 + ...l-chunk.js => data-tracker-accel-chunk.ts} | 4 +- src/encoders/data/data-tracker-chunk.js | 3 - src/encoders/data/data-tracker-chunk.ts | 4 + src/encoders/data/data-tracker-list-chunk.js | 3 - src/encoders/data/data-tracker-list-chunk.ts | 3 + ...ori-chunk.js => data-tracker-ori-chunk.ts} | 4 +- ...pos-chunk.js => data-tracker-pos-chunk.ts} | 4 +- ...d-chunk.js => data-tracker-speed-chunk.ts} | 4 +- ...-chunk.js => data-tracker-status-chunk.ts} | 4 +- ...unk.js => data-tracker-timestamp-chunk.ts} | 4 +- ...chunk.js => data-tracker-trgtpos-chunk.ts} | 4 +- src/encoders/info/info-packet-chunk.js | 4 - src/encoders/info/info-packet-chunk.ts | 4 + src/encoders/info/info-system-name-chunk.js | 3 - src/encoders/info/info-system-name-chunk.ts | 3 + src/encoders/info/info-tracker-chunk.js | 3 - src/encoders/info/info-tracker-chunk.ts | 3 + src/encoders/info/info-tracker-list-chunk.js | 3 - src/encoders/info/info-tracker-list-chunk.ts | 3 + src/encoders/info/info-tracker-name-chunk.js | 3 - src/encoders/info/info-tracker-name-chunk.ts | 3 + ...header-chunk.js => packet-header-chunk.ts} | 10 +- src/index.ts | 3 + src/models/tracker.js | 128 ----- src/models/tracker.ts | 100 ++++ tsconfig.json | 13 + 64 files changed, 1109 insertions(+), 605 deletions(-) delete mode 100644 index.js delete mode 100644 src/constants.js create mode 100644 src/constants.ts delete mode 100644 src/decoder.js create mode 100644 src/decoder.ts rename src/decoders/{chunk.js => chunk.ts} (71%) delete mode 100644 src/decoders/data/data-packet-chunk.js create mode 100644 src/decoders/data/data-packet-chunk.ts delete mode 100644 src/decoders/data/data-tracker-chunk.js create mode 100644 src/decoders/data/data-tracker-chunk.ts delete mode 100644 src/decoders/data/data-tracker-field-chunk.js create mode 100644 src/decoders/data/data-tracker-field-chunk.ts delete mode 100644 src/decoders/data/data-tracker-list-chunk.js create mode 100644 src/decoders/data/data-tracker-list-chunk.ts delete mode 100644 src/decoders/info/info-packet-chunk.js create mode 100644 src/decoders/info/info-packet-chunk.ts delete mode 100644 src/decoders/info/info-system-name-chunk.js create mode 100644 src/decoders/info/info-system-name-chunk.ts delete mode 100644 src/decoders/info/info-tracker-chunk.js create mode 100644 src/decoders/info/info-tracker-chunk.ts delete mode 100644 src/decoders/info/info-tracker-list-chunk.js create mode 100644 src/decoders/info/info-tracker-list-chunk.ts delete mode 100644 src/decoders/info/info-tracker-name-chunk.js create mode 100644 src/decoders/info/info-tracker-name-chunk.ts delete mode 100644 src/decoders/packet-header-chunk.js create mode 100644 src/decoders/packet-header-chunk.ts delete mode 100644 src/decoders/packet.js create mode 100644 src/decoders/packet.ts rename src/{encoder.js => encoder.ts} (51%) rename src/encoders/{chunk.js => chunk.ts} (80%) delete mode 100644 src/encoders/data/data-packet-chunk.js create mode 100644 src/encoders/data/data-packet-chunk.ts rename src/encoders/data/{data-tracker-accel-chunk.js => data-tracker-accel-chunk.ts} (61%) delete mode 100644 src/encoders/data/data-tracker-chunk.js create mode 100644 src/encoders/data/data-tracker-chunk.ts delete mode 100644 src/encoders/data/data-tracker-list-chunk.js create mode 100644 src/encoders/data/data-tracker-list-chunk.ts rename src/encoders/data/{data-tracker-ori-chunk.js => data-tracker-ori-chunk.ts} (61%) rename src/encoders/data/{data-tracker-pos-chunk.js => data-tracker-pos-chunk.ts} (61%) rename src/encoders/data/{data-tracker-speed-chunk.js => data-tracker-speed-chunk.ts} (61%) rename src/encoders/data/{data-tracker-status-chunk.js => data-tracker-status-chunk.ts} (56%) rename src/encoders/data/{data-tracker-timestamp-chunk.js => data-tracker-timestamp-chunk.ts} (59%) rename src/encoders/data/{data-tracker-trgtpos-chunk.js => data-tracker-trgtpos-chunk.ts} (61%) delete mode 100644 src/encoders/info/info-packet-chunk.js create mode 100644 src/encoders/info/info-packet-chunk.ts delete mode 100644 src/encoders/info/info-system-name-chunk.js create mode 100644 src/encoders/info/info-system-name-chunk.ts delete mode 100644 src/encoders/info/info-tracker-chunk.js create mode 100644 src/encoders/info/info-tracker-chunk.ts delete mode 100644 src/encoders/info/info-tracker-list-chunk.js create mode 100644 src/encoders/info/info-tracker-list-chunk.ts delete mode 100644 src/encoders/info/info-tracker-name-chunk.js create mode 100644 src/encoders/info/info-tracker-name-chunk.ts rename src/encoders/{packet-header-chunk.js => packet-header-chunk.ts} (69%) create mode 100644 src/index.ts delete mode 100644 src/models/tracker.js create mode 100644 src/models/tracker.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index b512c09..76add87 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules \ No newline at end of file +node_modules +dist \ No newline at end of file diff --git a/benchmark.js b/benchmark.js index d96bb32..9f15831 100644 --- a/benchmark.js +++ b/benchmark.js @@ -1,4 +1,4 @@ -const { Encoder, Decoder, Tracker } = require('.'); +const { Encoder, Tracker } = require('./dist'); const testSizes = [1, 10, 100]; diff --git a/examples/psn_client.js b/examples/psn_client.js index 38161b7..4d8e9bd 100644 --- a/examples/psn_client.js +++ b/examples/psn_client.js @@ -1,6 +1,6 @@ // recreation of psn_client.cpp example from https://github.com/vyv/psn-cpp const dgram = require('dgram'); -const { Decoder } = require('..'); +const { Decoder } = require('../dist'); const client = dgram.createSocket('udp4'); const decoder = new Decoder(); @@ -23,11 +23,8 @@ setInterval(() => { } Object.entries(decoder.trackers).forEach(([trackerId, tracker]) => { - console.log( - `Tracker - id: ${trackerId} | name: ${ - decoder.trackers[trackerId]?.tracker_name ? decoder.trackers[trackerId]?.tracker_name : '' - }` - ); + const trackerName = decoder.trackers[trackerId]?.tracker_name?.tracker_name; + console.log(`Tracker - id: ${trackerId} | name: ${trackerName || ''}`); if (tracker.pos) { console.log(`\tpos: ${tracker.pos.pos_x}, ${tracker.pos.pos_y}, ${tracker.pos.pos_z}`); } diff --git a/examples/psn_server.js b/examples/psn_server.js index d29a72d..193a4a5 100644 --- a/examples/psn_server.js +++ b/examples/psn_server.js @@ -1,6 +1,6 @@ // recreation of psn_server.cpp example from https://github.com/vyv/psn-cpp const dgram = require('dgram'); -const { Encoder, Tracker, Decoder } = require('..'); +const { Encoder, Tracker, Decoder } = require('../dist'); const client = dgram.createSocket('udp4'); const encoder = new Encoder('Test PSN Server', 2, 0); diff --git a/index.js b/index.js deleted file mode 100644 index 439d0a5..0000000 --- a/index.js +++ /dev/null @@ -1,9 +0,0 @@ -const Decoder = require('./src/decoder.js'); -const Encoder = require('./src/encoder.js'); -const Tracker = require('./src/models/tracker.js'); - -module.exports = { - Encoder, - Decoder, - Tracker, -}; diff --git a/package-lock.json b/package-lock.json index 2cbe557..af3a072 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,21 @@ { "name": "@jwetzell/posistagenet", - "version": "0.2.1", + "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@jwetzell/posistagenet", - "version": "0.2.1", + "version": "0.3.0", "license": "ISC", "devDependencies": { + "@types/node": "^20.6.0", "eslint": "^8.48.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^9.0.0", - "prettier": "^3.0.3" + "prettier": "^3.0.3", + "rimraf": "^5.0.1", + "typescript": "^5.2.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -126,6 +129,50 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -161,6 +208,16 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -168,6 +225,12 @@ "dev": true, "peer": true }, + "node_modules/@types/node": { + "version": "20.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", + "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", + "dev": true + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -586,12 +649,17 @@ "node": ">=6.0.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/es-abstract": { "version": "1.22.1", @@ -1195,6 +1263,41 @@ "node": ">=12.0.0" } }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", @@ -1210,6 +1313,22 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1281,20 +1400,22 @@ } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", + "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1312,6 +1433,30 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "13.21.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", @@ -1625,6 +1770,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -1843,6 +1997,24 @@ "reflect.getprototypeof": "^1.0.3" } }, + "node_modules/jackspeak": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.3.tgz", + "integrity": "sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -1982,6 +2154,15 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2004,6 +2185,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2241,6 +2431,22 @@ "dev": true, "peer": true }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2396,15 +2602,18 @@ } }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", + "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^10.2.5" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -2509,6 +2718,83 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.9.tgz", @@ -2586,6 +2872,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -2741,6 +3040,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -2858,6 +3170,100 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 88b1647..9cdcf0f 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,18 @@ { "name": "@jwetzell/posistagenet", - "version": "0.3.0", + "version": "0.4.0", "description": "", - "main": "index.js", + "main": "dist/index.js", "scripts": { + "prebuild": "rimraf dist", + "build": "tsc", "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" }, + "files": [ + "dist" + ], "author": { "name": "Joel Wetzell", "email": "me@jwetzell.com", @@ -15,9 +21,12 @@ "repository": "https://github.com/jwetzell/psn-js", "license": "ISC", "devDependencies": { + "@types/node": "^20.6.0", "eslint": "^8.48.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^9.0.0", - "prettier": "^3.0.3" + "prettier": "^3.0.3", + "rimraf": "^5.0.1", + "typescript": "^5.2.2" } } diff --git a/src/constants.js b/src/constants.js deleted file mode 100644 index 32a45d4..0000000 --- a/src/constants.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - PACKET_HEADER_SIZE: 16, - MAX_UDP_PACKET_SIZE: 1500, - CHUNK_HEADER_SIZE: 4, -}; diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..8e7ec16 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,5 @@ +export class Constants { + static readonly PACKET_HEADER_SIZE = 16; + static readonly MAX_UDP_PACKET_SIZE = 1500; + static readonly CHUNK_HEADER_SIZE = 4; +} diff --git a/src/decoder.js b/src/decoder.js deleted file mode 100644 index 047d5b3..0000000 --- a/src/decoder.js +++ /dev/null @@ -1,109 +0,0 @@ -const packetDecoder = require('./decoders/packet'); - -class Decoder { - // TODO(jwetzell): check if these last packet headers are necessary to hold on to - lastInfoPacketHeader; - - lastDataPacketHeader; - - infoPacketFrames = {}; - - dataPacketFrames = {}; - - constructor() { - this.system_name = ''; - - this.trackers = {}; - } - - updateInfo(framePackets) { - framePackets.forEach((packet) => { - if (packet.system_name) { - this.system_name = packet.system_name.system_name; - } - - if (packet.tracker_list?.trackers) { - Object.entries(packet.tracker_list.trackers).forEach(([trackerId, tracker]) => { - this.trackers[trackerId] = { - ...this.trackers[trackerId], - ...tracker.tracker_name, - }; - }); - } - }); - } - - updateData(framePackets) { - framePackets.forEach((packet) => { - if (packet.tracker_list) { - Object.entries(packet.tracker_list.trackers).forEach(([trackerId, tracker]) => { - this.trackers[trackerId] = { - ...this.trackers[trackerId], - ...tracker, - }; - }); - } - }); - } - - // TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete - decode(packetBuf) { - const packet = packetDecoder(packetBuf); - if (packet.id === 0x6756) { - const infoPacket = packet; - if (infoPacket) { - if (infoPacket.has_subchunks > 0) { - const currentInfoPacketHeader = infoPacket.packet_header; - if (!currentInfoPacketHeader) { - // NOTE(jwetzell): not sure that info packets without a header subchunk are valid? - throw new Error('malformed packet'); - } - - const systemSubChunk = infoPacket.system_name; - if (!systemSubChunk) { - // NOTE(jwetzell): not sure that info packets without a system subchunk are valid? - throw new Error('malformed packet'); - } - - if (this.infoPacketFrames[currentInfoPacketHeader.frame_id] === undefined) { - this.infoPacketFrames[currentInfoPacketHeader.frame_id] = []; - } - this.infoPacketFrames[currentInfoPacketHeader.frame_id].push(infoPacket); - - if ( - this.infoPacketFrames[currentInfoPacketHeader.frame_id].length === - currentInfoPacketHeader.frame_packet_count - ) { - this.updateInfo(this.infoPacketFrames[currentInfoPacketHeader.frame_id]); - delete this.infoPacketFrames[currentInfoPacketHeader.frame_id]; - } - - this.lastInfoPacketHeader = currentInfoPacketHeader; - } - } - } else if (packet.id === 0x6755) { - const dataPacket = packet; - if (dataPacket.has_subchunks) { - const currentDataPacketHeader = dataPacket.packet_header; - if (!currentDataPacketHeader) { - // NOTE(jwetzell): not sure that info packets without a header subchunk are valid? - throw new Error('malformed packet'); - } - if (this.dataPacketFrames[currentDataPacketHeader.frame_id] === undefined) { - this.dataPacketFrames[currentDataPacketHeader.frame_id] = []; - } - this.dataPacketFrames[currentDataPacketHeader.frame_id].push(dataPacket); - if ( - this.dataPacketFrames[currentDataPacketHeader.frame_id].length === currentDataPacketHeader.frame_packet_count - ) { - this.updateData(this.dataPacketFrames[currentDataPacketHeader.frame_id]); - delete this.dataPacketFrames[currentDataPacketHeader.frame_id]; - } - this.lastDataPacketHeader = currentDataPacketHeader; - } - } - return packet; - } -} - -module.exports = Decoder; diff --git a/src/decoder.ts b/src/decoder.ts new file mode 100644 index 0000000..9c115f8 --- /dev/null +++ b/src/decoder.ts @@ -0,0 +1,117 @@ +import { DataPacketChunk } from './decoders/data/data-packet-chunk'; +import { InfoPacketChunk } from './decoders/info/info-packet-chunk'; +import { InfoTrackerChunk } from './decoders/info/info-tracker-chunk'; +import packetDecoder from './decoders/packet'; +import { PacketHeaderChunk } from './decoders/packet-header-chunk'; + +export class Decoder { + // TODO(jwetzell): check if these last packet headers are necessary to hold on to + lastInfoPacketHeader?: PacketHeaderChunk; + + lastDataPacketHeader?: PacketHeaderChunk; + + infoPacketFrames: { [key: number]: InfoPacketChunk[] } = {}; + + dataPacketFrames: { [key: number]: DataPacketChunk[] } = {}; + + trackers: { [key: string]: InfoTrackerChunk } = {}; + + system_name: string = ''; + constructor() {} + + updateInfo(framePackets: InfoPacketChunk[]) { + framePackets.forEach((packet) => { + if (packet.system_name) { + this.system_name = packet.system_name.system_name; + } + + if (packet.tracker_list?.trackers) { + Object.entries(packet.tracker_list.trackers).forEach(([trackerId, tracker]) => { + if (!this.trackers[trackerId]) { + this.trackers[trackerId] = {}; + } + this.trackers[trackerId].tracker_name = tracker.tracker_name; + }); + } + }); + } + + updateData(framePackets: DataPacketChunk[]) { + framePackets.forEach((packet) => { + if (packet.tracker_list) { + Object.entries(packet.tracker_list.trackers).forEach(([trackerId, tracker]) => { + this.trackers[trackerId] = { + ...this.trackers[trackerId], + ...tracker, + }; + }); + } + }); + } + + // TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete + decode(packetBuf: Buffer): DataPacketChunk | InfoPacketChunk | undefined { + const packet = packetDecoder(packetBuf); + if (packet === undefined) { + return packet; + } + + if (packet.id === 0x6756) { + const infoPacket = packet as InfoPacketChunk; + if (infoPacket && infoPacket.has_subchunks) { + const currentInfoPacketHeader = infoPacket.packet_header; + if (!currentInfoPacketHeader) { + // NOTE(jwetzell): not sure that info packets without a header subchunk are valid? + throw new Error('malformed packet'); + } + + const systemSubChunk = infoPacket.system_name; + if (!systemSubChunk) { + // NOTE(jwetzell): not sure that info packets without a system subchunk are valid? + throw new Error('malformed packet'); + } + if (currentInfoPacketHeader.frame_id) { + if (this.infoPacketFrames[currentInfoPacketHeader.frame_id] === undefined) { + this.infoPacketFrames[currentInfoPacketHeader.frame_id] = []; + } + this.infoPacketFrames[currentInfoPacketHeader.frame_id].push(infoPacket); + + if ( + this.infoPacketFrames[currentInfoPacketHeader.frame_id].length === + currentInfoPacketHeader.frame_packet_count + ) { + this.updateInfo(this.infoPacketFrames[currentInfoPacketHeader.frame_id]); + delete this.infoPacketFrames[currentInfoPacketHeader.frame_id]; + } + } + + this.lastInfoPacketHeader = currentInfoPacketHeader; + } + } else if (packet.id === 0x6755) { + const dataPacket = packet as DataPacketChunk; + if (dataPacket.has_subchunks) { + const currentDataPacketHeader = dataPacket.packet_header; + if (!currentDataPacketHeader) { + // NOTE(jwetzell): not sure that info packets without a header subchunk are valid? + throw new Error('malformed packet'); + } + + if (currentDataPacketHeader.frame_id) { + if (this.dataPacketFrames[currentDataPacketHeader.frame_id] === undefined) { + this.dataPacketFrames[currentDataPacketHeader.frame_id] = []; + } + this.dataPacketFrames[currentDataPacketHeader.frame_id].push(dataPacket); + if ( + this.dataPacketFrames[currentDataPacketHeader.frame_id].length === + currentDataPacketHeader.frame_packet_count + ) { + this.updateData(this.dataPacketFrames[currentDataPacketHeader.frame_id]); + delete this.dataPacketFrames[currentDataPacketHeader.frame_id]; + } + } + this.lastDataPacketHeader = currentDataPacketHeader; + } + } + return packet; + } +} diff --git a/src/decoders/chunk.js b/src/decoders/chunk.ts similarity index 71% rename from src/decoders/chunk.js rename to src/decoders/chunk.ts index a47cd6e..b02ba9a 100644 --- a/src/decoders/chunk.js +++ b/src/decoders/chunk.ts @@ -1,6 +1,13 @@ -module.exports = (buffer, dataDecoder) => { +export interface Chunk { + id?: number; + has_subchunks?: boolean; + data_len?: number; + chunk_data?: Buffer; +} + +export default (buffer: Buffer, dataDecoder: Function): Chunk => { let offset = 0; - const chunk = {}; + const chunk: Chunk = {}; chunk.id = buffer.readUInt16LE(offset); offset += 2; diff --git a/src/decoders/data/data-packet-chunk.js b/src/decoders/data/data-packet-chunk.js deleted file mode 100644 index c22bbd2..0000000 --- a/src/decoders/data/data-packet-chunk.js +++ /dev/null @@ -1,29 +0,0 @@ -const { CHUNK_HEADER_SIZE } = require('../../constants'); -const chunk = require('../chunk'); -const packetHeaderChunk = require('../packet-header-chunk'); -const dataTrackerListChunk = require('./data-tracker-list-chunk'); - -function decodeDataPacketChunk(dataPacketChunk) { - if (dataPacketChunk.has_subchunks && dataPacketChunk.chunk_data) { - let offset = 0; - while (offset < dataPacketChunk.data_len) { - const chunkId = dataPacketChunk.chunk_data.readUInt16LE(offset); - switch (chunkId) { - case 0x0000: - dataPacketChunk.packet_header = packetHeaderChunk(dataPacketChunk.chunk_data.subarray(offset)); - offset += CHUNK_HEADER_SIZE; - offset += dataPacketChunk.packet_header.data_len; - break; - case 0x0001: - dataPacketChunk.tracker_list = dataTrackerListChunk(dataPacketChunk.chunk_data.subarray(offset)); - offset += CHUNK_HEADER_SIZE; - offset += dataPacketChunk.tracker_list.data_len; - break; - default: - break; - } - } - } -} - -module.exports = (buffer) => chunk(buffer, decodeDataPacketChunk); diff --git a/src/decoders/data/data-packet-chunk.ts b/src/decoders/data/data-packet-chunk.ts new file mode 100644 index 0000000..ea06699 --- /dev/null +++ b/src/decoders/data/data-packet-chunk.ts @@ -0,0 +1,38 @@ +import { Constants } from '../../constants'; +import chunk, { Chunk } from '../chunk'; +import packetHeaderChunk, { PacketHeaderChunk } from '../packet-header-chunk'; +import dataTrackerListChunk, { DataTrackerListChunk } from './data-tracker-list-chunk'; + +export interface DataPacketChunk extends Chunk { + packet_header: PacketHeaderChunk; + tracker_list: DataTrackerListChunk; +} + +function decodeDataPacketChunk(dataPacketChunk: DataPacketChunk) { + if (dataPacketChunk.has_subchunks && dataPacketChunk.chunk_data && dataPacketChunk.data_len) { + let offset = 0; + while (offset < dataPacketChunk.data_len) { + const chunkId = dataPacketChunk.chunk_data.readUInt16LE(offset); + switch (chunkId) { + case 0x0000: + dataPacketChunk.packet_header = packetHeaderChunk(dataPacketChunk.chunk_data.subarray(offset)); + offset += Constants.CHUNK_HEADER_SIZE; + if (dataPacketChunk.packet_header?.data_len) { + offset += dataPacketChunk.packet_header.data_len; + } + break; + case 0x0001: + dataPacketChunk.tracker_list = dataTrackerListChunk(dataPacketChunk.chunk_data.subarray(offset)); + offset += Constants.CHUNK_HEADER_SIZE; + if (dataPacketChunk.tracker_list.data_len) { + offset += dataPacketChunk.tracker_list.data_len; + } + break; + default: + break; + } + } + } +} + +export default (buffer: Buffer): DataPacketChunk => chunk(buffer, decodeDataPacketChunk) as DataPacketChunk; diff --git a/src/decoders/data/data-tracker-chunk.js b/src/decoders/data/data-tracker-chunk.js deleted file mode 100644 index b389d49..0000000 --- a/src/decoders/data/data-tracker-chunk.js +++ /dev/null @@ -1,41 +0,0 @@ -const { CHUNK_HEADER_SIZE } = require('../../constants'); -const chunk = require('../chunk'); -const dataTrackerFieldChunk = require('./data-tracker-field-chunk'); - -function decodeTrackerChunk(trackerChunk) { - if (trackerChunk.chunk_data && trackerChunk.data_len > 0) { - let offset = 0; - while (offset < trackerChunk.data_len) { - const trackerFieldChunk = dataTrackerFieldChunk(trackerChunk.chunk_data.subarray(offset)); - offset += CHUNK_HEADER_SIZE; - offset += trackerFieldChunk.data_len; - switch (trackerFieldChunk.id) { - case 0x0000: - trackerChunk.pos = trackerFieldChunk; - break; - case 0x0001: - trackerChunk.speed = trackerFieldChunk; - break; - case 0x0002: - trackerChunk.ori = trackerFieldChunk; - break; - case 0x0003: - trackerChunk.status = trackerFieldChunk; - break; - case 0x0004: - trackerChunk.accel = trackerFieldChunk; - break; - case 0x0005: - trackerChunk.trgtpos = trackerFieldChunk; - break; - case 0x0006: - trackerChunk.timestamp = trackerFieldChunk; - break; - default: - break; - } - } - } -} - -module.exports = (buffer) => chunk(buffer, decodeTrackerChunk); diff --git a/src/decoders/data/data-tracker-chunk.ts b/src/decoders/data/data-tracker-chunk.ts new file mode 100644 index 0000000..65a2fd2 --- /dev/null +++ b/src/decoders/data/data-tracker-chunk.ts @@ -0,0 +1,53 @@ +import { Constants } from '../../constants'; +import chunk, { Chunk } from '../chunk'; +import dataTrackerFieldChunk, { DataTrackerFieldChunk } from './data-tracker-field-chunk'; + +export interface DataTrackerChunk extends Chunk { + pos: DataTrackerFieldChunk; + speed: DataTrackerFieldChunk; + ori: DataTrackerFieldChunk; + status: DataTrackerFieldChunk; + accel: DataTrackerFieldChunk; + trgtpos: DataTrackerFieldChunk; + timestamp: DataTrackerFieldChunk; +} + +function decodeTrackerChunk(trackerChunk: DataTrackerChunk) { + if (trackerChunk.chunk_data && trackerChunk.data_len) { + let offset = 0; + while (offset < trackerChunk.data_len) { + const trackerFieldChunk = dataTrackerFieldChunk(trackerChunk.chunk_data.subarray(offset)); + offset += Constants.CHUNK_HEADER_SIZE; + if (trackerFieldChunk.data_len) { + offset += trackerFieldChunk.data_len; + switch (trackerFieldChunk.id) { + case 0x0000: + trackerChunk.pos = trackerFieldChunk; + break; + case 0x0001: + trackerChunk.speed = trackerFieldChunk; + break; + case 0x0002: + trackerChunk.ori = trackerFieldChunk; + break; + case 0x0003: + trackerChunk.status = trackerFieldChunk; + break; + case 0x0004: + trackerChunk.accel = trackerFieldChunk; + break; + case 0x0005: + trackerChunk.trgtpos = trackerFieldChunk; + break; + case 0x0006: + trackerChunk.timestamp = trackerFieldChunk; + break; + default: + break; + } + } + } + } +} + +export default (buffer: Buffer): DataTrackerChunk => chunk(buffer, decodeTrackerChunk) as DataTrackerChunk; diff --git a/src/decoders/data/data-tracker-field-chunk.js b/src/decoders/data/data-tracker-field-chunk.js deleted file mode 100644 index d2a7456..0000000 --- a/src/decoders/data/data-tracker-field-chunk.js +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable no-case-declarations */ -const chunk = require('../chunk'); - -function readXYZ(trackerFieldChunk, prefix) { - if (prefix === undefined) { - prefix = ''; - } - - trackerFieldChunk[`${prefix}x`] = trackerFieldChunk.chunk_data.readFloatLE(0); - trackerFieldChunk[`${prefix}y`] = trackerFieldChunk.chunk_data.readFloatLE(4); - trackerFieldChunk[`${prefix}z`] = trackerFieldChunk.chunk_data.readFloatLE(8); -} -function decodeTrackerFieldChunk(trackerFieldChunk) { - if (trackerFieldChunk.id !== undefined) { - switch (trackerFieldChunk.id) { - case 0x0000: - readXYZ(trackerFieldChunk, 'pos_'); - break; - case 0x0001: - readXYZ(trackerFieldChunk, 'speed_'); - break; - case 0x0002: - readXYZ(trackerFieldChunk, 'ori_'); - break; - case 0x0003: - trackerFieldChunk.validity = trackerFieldChunk.chunk_data.readFloatLE(); - break; - case 0x0004: - readXYZ(trackerFieldChunk, 'accel_'); - break; - case 0x0005: - readXYZ(trackerFieldChunk, 'trgtpos_'); - break; - case 0x0006: - trackerFieldChunk.tracker_timestamp = trackerFieldChunk.chunk_data.readBigUInt64LE(); - break; - default: - break; - } - } -} - -module.exports = (buffer) => chunk(buffer, decodeTrackerFieldChunk); diff --git a/src/decoders/data/data-tracker-field-chunk.ts b/src/decoders/data/data-tracker-field-chunk.ts new file mode 100644 index 0000000..bca40ac --- /dev/null +++ b/src/decoders/data/data-tracker-field-chunk.ts @@ -0,0 +1,50 @@ +/* eslint-disable no-case-declarations */ +import chunk, { Chunk } from '../chunk'; + +export interface DataTrackerFieldChunk extends Chunk { + [key: string]: number | bigint | number[] | Buffer | undefined | boolean; +} + +function readXYZ(trackerFieldChunk: DataTrackerFieldChunk, prefix: string = '') { + if (trackerFieldChunk.chunk_data) { + trackerFieldChunk[`${prefix}x`] = trackerFieldChunk.chunk_data.readFloatLE(0); + trackerFieldChunk[`${prefix}y`] = trackerFieldChunk.chunk_data.readFloatLE(4); + trackerFieldChunk[`${prefix}z`] = trackerFieldChunk.chunk_data.readFloatLE(8); + } +} +function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) { + if (trackerFieldChunk.id !== undefined) { + switch (trackerFieldChunk.id) { + case 0x0000: + readXYZ(trackerFieldChunk, 'pos_'); + break; + case 0x0001: + readXYZ(trackerFieldChunk, 'speed_'); + break; + case 0x0002: + readXYZ(trackerFieldChunk, 'ori_'); + break; + case 0x0003: + if (trackerFieldChunk.chunk_data) { + trackerFieldChunk.validity = trackerFieldChunk.chunk_data.readFloatLE(); + } + break; + case 0x0004: + readXYZ(trackerFieldChunk, 'accel_'); + break; + case 0x0005: + readXYZ(trackerFieldChunk, 'trgtpos_'); + break; + case 0x0006: + if (trackerFieldChunk.chunk_data) { + trackerFieldChunk.tracker_timestamp = trackerFieldChunk.chunk_data.readBigUInt64LE(); + } + break; + default: + break; + } + } +} + +export default (buffer: Buffer): DataTrackerFieldChunk => + chunk(buffer, decodeTrackerFieldChunk) as DataTrackerFieldChunk; diff --git a/src/decoders/data/data-tracker-list-chunk.js b/src/decoders/data/data-tracker-list-chunk.js deleted file mode 100644 index 5455632..0000000 --- a/src/decoders/data/data-tracker-list-chunk.js +++ /dev/null @@ -1,17 +0,0 @@ -const { CHUNK_HEADER_SIZE } = require('../../constants'); -const chunk = require('../chunk'); -const dataTrackerChunk = require('./data-tracker-chunk'); - -function decodeDataTrackerListChunk(dataTrackerListChunk) { - dataTrackerListChunk.trackers = {}; - - // TODO(jwetzell): add error handling - let offset = 0; - while (offset < dataTrackerListChunk.chunk_data.length) { - const trackerChunk = dataTrackerChunk(dataTrackerListChunk.chunk_data.subarray(offset)); - offset += CHUNK_HEADER_SIZE; - offset += trackerChunk.data_len; - dataTrackerListChunk.trackers[trackerChunk.id] = trackerChunk; - } -} -module.exports = (buffer) => chunk(buffer, decodeDataTrackerListChunk); diff --git a/src/decoders/data/data-tracker-list-chunk.ts b/src/decoders/data/data-tracker-list-chunk.ts new file mode 100644 index 0000000..9d4022b --- /dev/null +++ b/src/decoders/data/data-tracker-list-chunk.ts @@ -0,0 +1,30 @@ +import { Constants } from '../../constants'; +import chunk, { Chunk } from '../chunk'; +import dataTrackerChunk, { DataTrackerChunk } from './data-tracker-chunk'; + +export interface DataTrackerListChunk extends Chunk { + trackers: { + [key: number]: DataTrackerChunk; + }; +} + +function decodeDataTrackerListChunk(dataTrackerListChunk: DataTrackerListChunk) { + dataTrackerListChunk.trackers = {}; + + // TODO(jwetzell): add error handling + let offset = 0; + if (dataTrackerListChunk.chunk_data) { + while (offset < dataTrackerListChunk.chunk_data.length) { + const trackerChunk = dataTrackerChunk(dataTrackerListChunk.chunk_data.subarray(offset)); + offset += Constants.CHUNK_HEADER_SIZE; + if (trackerChunk.data_len) { + offset += trackerChunk.data_len; + } + if (trackerChunk.id) { + dataTrackerListChunk.trackers[trackerChunk.id] = trackerChunk; + } + } + } +} +export default (buffer: Buffer): DataTrackerListChunk => + chunk(buffer, decodeDataTrackerListChunk) as DataTrackerListChunk; diff --git a/src/decoders/info/info-packet-chunk.js b/src/decoders/info/info-packet-chunk.js deleted file mode 100644 index f56da20..0000000 --- a/src/decoders/info/info-packet-chunk.js +++ /dev/null @@ -1,35 +0,0 @@ -const { CHUNK_HEADER_SIZE } = require('../../constants'); -const chunk = require('../chunk'); -const packetHeaderChunk = require('../packet-header-chunk'); -const infoSystemNameChunk = require('./info-system-name-chunk'); -const infoTrackerListChunk = require('./info-tracker-list-chunk'); - -function decodeInfoPacketChunk(infoPacketChunk) { - if (infoPacketChunk.has_subchunks && infoPacketChunk.chunk_data) { - let offset = 0; - while (offset < infoPacketChunk.data_len) { - const chunkId = infoPacketChunk.chunk_data.readUInt16LE(offset); - switch (chunkId) { - case 0x0000: - infoPacketChunk.packet_header = packetHeaderChunk(infoPacketChunk.chunk_data.subarray(offset)); - offset += CHUNK_HEADER_SIZE; - offset += infoPacketChunk.packet_header.data_len; - break; - case 0x0001: - infoPacketChunk.system_name = infoSystemNameChunk(infoPacketChunk.chunk_data.subarray(offset)); - offset += CHUNK_HEADER_SIZE; - offset += infoPacketChunk.system_name.data_len; - break; - case 0x0002: - infoPacketChunk.tracker_list = infoTrackerListChunk(infoPacketChunk.chunk_data.subarray(offset)); - offset += CHUNK_HEADER_SIZE; - offset += infoPacketChunk.tracker_list.data_len; - break; - default: - break; - } - } - } -} - -module.exports = (buffer) => chunk(buffer, decodeInfoPacketChunk); diff --git a/src/decoders/info/info-packet-chunk.ts b/src/decoders/info/info-packet-chunk.ts new file mode 100644 index 0000000..c16ac3c --- /dev/null +++ b/src/decoders/info/info-packet-chunk.ts @@ -0,0 +1,47 @@ +import { Constants } from '../../constants'; +import chunk, { Chunk } from '../chunk'; +import packetHeaderChunk, { PacketHeaderChunk } from '../packet-header-chunk'; +import infoSystemNameChunk, { InfoSystemNameChunk } from './info-system-name-chunk'; +import infoTrackerListChunk, { InfoTrackerListChunk } from './info-tracker-list-chunk'; + +export interface InfoPacketChunk extends Chunk { + packet_header: PacketHeaderChunk; + system_name: InfoSystemNameChunk; + tracker_list: InfoTrackerListChunk; +} + +function decodeInfoPacketChunk(infoPacketChunk: InfoPacketChunk) { + if (infoPacketChunk.has_subchunks && infoPacketChunk.chunk_data && infoPacketChunk.data_len) { + let offset = 0; + while (offset < infoPacketChunk.data_len) { + const chunkId = infoPacketChunk.chunk_data.readUInt16LE(offset); + switch (chunkId) { + case 0x0000: + infoPacketChunk.packet_header = packetHeaderChunk(infoPacketChunk.chunk_data.subarray(offset)); + offset += Constants.CHUNK_HEADER_SIZE; + if (infoPacketChunk.packet_header?.data_len) { + offset += infoPacketChunk.packet_header.data_len; + } + break; + case 0x0001: + infoPacketChunk.system_name = infoSystemNameChunk(infoPacketChunk.chunk_data.subarray(offset)); + offset += Constants.CHUNK_HEADER_SIZE; + if (infoPacketChunk.system_name?.data_len) { + offset += infoPacketChunk.system_name.data_len; + } + break; + case 0x0002: + infoPacketChunk.tracker_list = infoTrackerListChunk(infoPacketChunk.chunk_data.subarray(offset)); + offset += Constants.CHUNK_HEADER_SIZE; + if (infoPacketChunk.tracker_list?.data_len) { + offset += infoPacketChunk.tracker_list.data_len; + } + break; + default: + break; + } + } + } +} + +export default (buffer: Buffer): InfoPacketChunk => chunk(buffer, decodeInfoPacketChunk) as InfoPacketChunk; diff --git a/src/decoders/info/info-system-name-chunk.js b/src/decoders/info/info-system-name-chunk.js deleted file mode 100644 index 6a44bac..0000000 --- a/src/decoders/info/info-system-name-chunk.js +++ /dev/null @@ -1,9 +0,0 @@ -const chunk = require('../chunk'); - -function decodeSystemNameChunk(systemNameChunk) { - if (systemNameChunk.chunk_data !== undefined && systemNameChunk.data_len !== undefined) { - systemNameChunk.system_name = systemNameChunk.chunk_data.subarray(0, systemNameChunk.data_len).toString(); - } -} - -module.exports = (buffer) => chunk(buffer, decodeSystemNameChunk); diff --git a/src/decoders/info/info-system-name-chunk.ts b/src/decoders/info/info-system-name-chunk.ts new file mode 100644 index 0000000..765bb88 --- /dev/null +++ b/src/decoders/info/info-system-name-chunk.ts @@ -0,0 +1,13 @@ +import chunk, { Chunk } from '../chunk'; + +export interface InfoSystemNameChunk extends Chunk { + system_name: string; +} + +function decodeSystemNameChunk(systemNameChunk: InfoSystemNameChunk) { + if (systemNameChunk.chunk_data !== undefined && systemNameChunk.data_len !== undefined) { + systemNameChunk.system_name = systemNameChunk.chunk_data.subarray(0, systemNameChunk.data_len).toString(); + } +} + +export default (buffer: Buffer): InfoSystemNameChunk => chunk(buffer, decodeSystemNameChunk) as InfoSystemNameChunk; diff --git a/src/decoders/info/info-tracker-chunk.js b/src/decoders/info/info-tracker-chunk.js deleted file mode 100644 index 468d30f..0000000 --- a/src/decoders/info/info-tracker-chunk.js +++ /dev/null @@ -1,24 +0,0 @@ -const { CHUNK_HEADER_SIZE } = require('../../constants'); -const chunk = require('../chunk'); -const infoTrackerNameChunk = require('./info-tracker-name-chunk'); - -function decodeInfoTrackerChunk(infoTrackerChunk) { - if (infoTrackerChunk.has_subchunks && infoTrackerChunk.chunk_data) { - let offset = 0; - while (offset < infoTrackerChunk.data_len) { - const chunkId = infoTrackerChunk.chunk_data.readUInt16LE(offset); - switch (chunkId) { - case 0x0000: - infoTrackerChunk.tracker_name = infoTrackerNameChunk(infoTrackerChunk.chunk_data.subarray(offset)); - offset += CHUNK_HEADER_SIZE; - offset += infoTrackerChunk.tracker_name.data_len; - break; - - default: - break; - } - } - } -} - -module.exports = (buffer) => chunk(buffer, decodeInfoTrackerChunk); diff --git a/src/decoders/info/info-tracker-chunk.ts b/src/decoders/info/info-tracker-chunk.ts new file mode 100644 index 0000000..5c2b5a6 --- /dev/null +++ b/src/decoders/info/info-tracker-chunk.ts @@ -0,0 +1,30 @@ +import { Constants } from '../../constants'; +import chunk, { Chunk } from '../chunk'; +import infoTrackerNameChunk, { InfoTrackerNameChunk } from './info-tracker-name-chunk'; + +export interface InfoTrackerChunk extends Chunk { + tracker_name?: InfoTrackerNameChunk; +} + +function decodeInfoTrackerChunk(infoTrackerChunk: InfoTrackerChunk) { + if (infoTrackerChunk.has_subchunks && infoTrackerChunk.chunk_data && infoTrackerChunk.data_len) { + let offset = 0; + while (offset < infoTrackerChunk.data_len) { + const chunkId = infoTrackerChunk.chunk_data.readUInt16LE(offset); + switch (chunkId) { + case 0x0000: + infoTrackerChunk.tracker_name = infoTrackerNameChunk(infoTrackerChunk.chunk_data.subarray(offset)); + offset += Constants.CHUNK_HEADER_SIZE; + if (infoTrackerChunk.tracker_name?.data_len) { + offset += infoTrackerChunk?.tracker_name?.data_len; + } + break; + + default: + break; + } + } + } +} + +export default (buffer: Buffer): InfoTrackerChunk => chunk(buffer, decodeInfoTrackerChunk); diff --git a/src/decoders/info/info-tracker-list-chunk.js b/src/decoders/info/info-tracker-list-chunk.js deleted file mode 100644 index c0a6ccf..0000000 --- a/src/decoders/info/info-tracker-list-chunk.js +++ /dev/null @@ -1,17 +0,0 @@ -const { CHUNK_HEADER_SIZE } = require('../../constants'); -const chunk = require('../chunk'); -const infoTrackerChunk = require('./info-tracker-chunk'); - -function decodeInfoTrackerListChunk(infoTrackerListChunk) { - infoTrackerListChunk.trackers = {}; - if (infoTrackerListChunk.has_subchunks && infoTrackerListChunk.chunk_data) { - let offset = 0; - while (offset < infoTrackerListChunk.data_len) { - const trackerChunk = infoTrackerChunk(infoTrackerListChunk.chunk_data.subarray(offset)); - offset += CHUNK_HEADER_SIZE; - offset += trackerChunk.data_len; - infoTrackerListChunk.trackers[trackerChunk.id] = trackerChunk; - } - } -} -module.exports = (buffer) => chunk(buffer, decodeInfoTrackerListChunk); diff --git a/src/decoders/info/info-tracker-list-chunk.ts b/src/decoders/info/info-tracker-list-chunk.ts new file mode 100644 index 0000000..b126883 --- /dev/null +++ b/src/decoders/info/info-tracker-list-chunk.ts @@ -0,0 +1,29 @@ +import { Constants } from '../../constants'; +import chunk, { Chunk } from '../chunk'; +import infoTrackerChunk, { InfoTrackerChunk } from './info-tracker-chunk'; + +export interface InfoTrackerListChunk extends Chunk { + trackers: { + [key: number]: InfoTrackerChunk; + }; +} +function decodeInfoTrackerListChunk(infoTrackerListChunk: InfoTrackerListChunk) { + infoTrackerListChunk.trackers = {}; + if (infoTrackerListChunk.has_subchunks && infoTrackerListChunk.chunk_data) { + let offset = 0; + if (infoTrackerListChunk.data_len) { + while (offset < infoTrackerListChunk.data_len) { + const trackerChunk = infoTrackerChunk(infoTrackerListChunk.chunk_data.subarray(offset)); + offset += Constants.CHUNK_HEADER_SIZE; + if (trackerChunk.data_len) { + offset += trackerChunk.data_len; + } + if (trackerChunk.id) { + infoTrackerListChunk.trackers[trackerChunk.id] = trackerChunk; + } + } + } + } +} +export default (buffer: Buffer): InfoTrackerListChunk => + chunk(buffer, decodeInfoTrackerListChunk) as InfoTrackerListChunk; diff --git a/src/decoders/info/info-tracker-name-chunk.js b/src/decoders/info/info-tracker-name-chunk.js deleted file mode 100644 index c07cb93..0000000 --- a/src/decoders/info/info-tracker-name-chunk.js +++ /dev/null @@ -1,8 +0,0 @@ -const chunk = require('../chunk'); - -function decodeTrackerNameChunk(trackerNameChunk) { - if (trackerNameChunk.chunk_data !== undefined && trackerNameChunk.data_len !== undefined) { - trackerNameChunk.tracker_name = trackerNameChunk.chunk_data.subarray(0, trackerNameChunk.data_len).toString(); - } -} -module.exports = (buffer) => chunk(buffer, decodeTrackerNameChunk); diff --git a/src/decoders/info/info-tracker-name-chunk.ts b/src/decoders/info/info-tracker-name-chunk.ts new file mode 100644 index 0000000..757673b --- /dev/null +++ b/src/decoders/info/info-tracker-name-chunk.ts @@ -0,0 +1,11 @@ +import chunk, { Chunk } from '../chunk'; +export interface InfoTrackerNameChunk extends Chunk { + tracker_name: string; +} + +function decodeTrackerNameChunk(trackerNameChunk: InfoTrackerNameChunk) { + if (trackerNameChunk.chunk_data !== undefined && trackerNameChunk.data_len !== undefined) { + trackerNameChunk.tracker_name = trackerNameChunk.chunk_data.subarray(0, trackerNameChunk.data_len).toString(); + } +} +export default (buffer: Buffer): InfoTrackerNameChunk => chunk(buffer, decodeTrackerNameChunk) as InfoTrackerNameChunk; diff --git a/src/decoders/packet-header-chunk.js b/src/decoders/packet-header-chunk.js deleted file mode 100644 index f2233ab..0000000 --- a/src/decoders/packet-header-chunk.js +++ /dev/null @@ -1,12 +0,0 @@ -const chunk = require('./chunk'); - -function decodePacketHeaderChunk(packetHeaderChunk) { - // TODO(jwetzell): remove the string conversion - packetHeaderChunk.packet_timestamp = packetHeaderChunk.chunk_data.readBigUInt64LE(0); - packetHeaderChunk.version_high = packetHeaderChunk.chunk_data.readUInt8(8); - packetHeaderChunk.version_low = packetHeaderChunk.chunk_data.readUInt8(9); - packetHeaderChunk.frame_id = packetHeaderChunk.chunk_data.readUInt8(10); - packetHeaderChunk.frame_packet_count = packetHeaderChunk.chunk_data.readUInt8(11); -} - -module.exports = (buffer) => chunk(buffer, decodePacketHeaderChunk); diff --git a/src/decoders/packet-header-chunk.ts b/src/decoders/packet-header-chunk.ts new file mode 100644 index 0000000..c68a77e --- /dev/null +++ b/src/decoders/packet-header-chunk.ts @@ -0,0 +1,21 @@ +import chunk, { Chunk } from './chunk'; +export interface PacketHeaderChunk extends Chunk { + packet_timestamp?: bigint; + version_high?: number; + version_low?: number; + frame_id?: number; + frame_packet_count?: number; +} + +function decodePacketHeaderChunk(packetHeaderChunk: PacketHeaderChunk) { + // TODO(jwetzell): remove the string conversion + if (packetHeaderChunk.chunk_data) { + packetHeaderChunk.packet_timestamp = packetHeaderChunk.chunk_data.readBigUInt64LE(0); + packetHeaderChunk.version_high = packetHeaderChunk.chunk_data.readUInt8(8); + packetHeaderChunk.version_low = packetHeaderChunk.chunk_data.readUInt8(9); + packetHeaderChunk.frame_id = packetHeaderChunk.chunk_data.readUInt8(10); + packetHeaderChunk.frame_packet_count = packetHeaderChunk.chunk_data.readUInt8(11); + } +} + +export default (buffer: Buffer): PacketHeaderChunk => chunk(buffer, decodePacketHeaderChunk); diff --git a/src/decoders/packet.js b/src/decoders/packet.js deleted file mode 100644 index 9c4d0d0..0000000 --- a/src/decoders/packet.js +++ /dev/null @@ -1,14 +0,0 @@ -const dataPacketChunk = require('./data/data-packet-chunk'); -const infoPacketChunk = require('./info/info-packet-chunk'); - -module.exports = (buffer) => { - const chunkId = buffer.readUInt16LE(); - switch (chunkId) { - case 0x6756: - return infoPacketChunk(buffer); - case 0x6755: - return dataPacketChunk(buffer); - default: - return {}; - } -}; diff --git a/src/decoders/packet.ts b/src/decoders/packet.ts new file mode 100644 index 0000000..fba1bf6 --- /dev/null +++ b/src/decoders/packet.ts @@ -0,0 +1,15 @@ +import infoPacketChunk, { InfoPacketChunk } from './info/info-packet-chunk'; + +import dataPacketChunk, { DataPacketChunk } from './data/data-packet-chunk'; + +export default (buffer: Buffer): InfoPacketChunk | DataPacketChunk | undefined => { + const chunkId = buffer.readUInt16LE(); + switch (chunkId) { + case 0x6756: + return infoPacketChunk(buffer); + case 0x6755: + return dataPacketChunk(buffer); + default: + return undefined; + } +}; diff --git a/src/encoder.js b/src/encoder.ts similarity index 51% rename from src/encoder.js rename to src/encoder.ts index 1bc101e..0724323 100644 --- a/src/encoder.js +++ b/src/encoder.ts @@ -1,34 +1,39 @@ -const { MAX_UDP_PACKET_SIZE, PACKET_HEADER_SIZE, CHUNK_HEADER_SIZE } = require('./constants'); -const dataPacketChunk = require('./encoders/data/data-packet-chunk'); -const dataTrackerListChunk = require('./encoders/data/data-tracker-list-chunk'); -const infoPacketChunk = require('./encoders/info/info-packet-chunk'); -const infoSystemNameChunk = require('./encoders/info/info-system-name-chunk'); -const infoTrackerListChunk = require('./encoders/info/info-tracker-list-chunk'); -const packetHeaderChunk = require('./encoders/packet-header-chunk'); +import { Tracker } from './models/tracker'; -class Encoder { - constructor(systemName, versionHigh = 2, versionLow = 3) { +import { Constants } from './constants'; +import dataPacketChunk from './encoders/data/data-packet-chunk'; +import dataTrackerListChunk from './encoders/data/data-tracker-list-chunk'; +import infoPacketChunk from './encoders/info/info-packet-chunk'; +import infoSystemNameChunk from './encoders/info/info-system-name-chunk'; +import infoTrackerListChunk from './encoders/info/info-tracker-list-chunk'; +import packetHeaderChunk from './encoders/packet-header-chunk'; + +export class Encoder { + private systemName: string; + private versionHigh: number; + private versionLow: number; + dataFrameId: number = 1; + infoFrameId: number = 1; + constructor(systemName: string, versionHigh: number = 2, versionLow: number = 3) { this.systemName = systemName; this.versionHigh = versionHigh; this.versionLow = versionLow; - this.dataFrameId = 1; - this.infoFrameId = 1; } - getInfoPackets(timestamp, trackers) { + getInfoPackets(timestamp: bigint, trackers: Tracker[]) { const systemNameChunk = infoSystemNameChunk(this.systemName); - const trackerChunks = trackers.map((tracker) => tracker.getInfoChunk()); + const trackerChunks = trackers.map((tracker: Tracker) => tracker.getInfoChunk()); - const infoPackets = []; + const infoPackets: Buffer[] = []; - const trackerChunksLists = []; - let currentTrackerList = []; + const trackerChunksLists: Buffer[][] = []; + let currentTrackerList: Buffer[] = []; - let currentInfoPacketSize = PACKET_HEADER_SIZE + systemNameChunk.length + CHUNK_HEADER_SIZE; + let currentInfoPacketSize = Constants.MAX_UDP_PACKET_SIZE + systemNameChunk.length + Constants.CHUNK_HEADER_SIZE; - trackerChunks.forEach((trackerChunk) => { - if (currentInfoPacketSize + trackerChunk.length > MAX_UDP_PACKET_SIZE) { + trackerChunks.forEach((trackerChunk: Buffer) => { + if (currentInfoPacketSize + trackerChunk.length > Constants.MAX_UDP_PACKET_SIZE) { trackerChunksLists.push(currentTrackerList); currentTrackerList = []; currentInfoPacketSize = 0; @@ -54,17 +59,17 @@ class Encoder { return infoPackets; } - getDataPackets(timestamp, trackers) { + getDataPackets(timestamp: bigint, trackers: Tracker[]) { const allTrackerChunks = trackers.map((tracker) => tracker.getDataChunk()); - const dataPackets = []; + const dataPackets: Buffer[] = []; - const trackerChunksLists = []; - let currentTrackerList = []; + const trackerChunksLists: Buffer[][] = []; + let currentTrackerList: Buffer[] = []; - let currentDataPacketSize = PACKET_HEADER_SIZE + CHUNK_HEADER_SIZE; + let currentDataPacketSize = Constants.PACKET_HEADER_SIZE + Constants.CHUNK_HEADER_SIZE; allTrackerChunks.forEach((trackerChunk) => { - if (currentDataPacketSize + trackerChunk.length > MAX_UDP_PACKET_SIZE) { + if (currentDataPacketSize + trackerChunk.length > Constants.MAX_UDP_PACKET_SIZE) { trackerChunksLists.push(currentTrackerList); currentTrackerList = []; currentDataPacketSize = 0; @@ -91,5 +96,3 @@ class Encoder { return dataPackets; } } - -module.exports = Encoder; diff --git a/src/encoders/chunk.js b/src/encoders/chunk.ts similarity index 80% rename from src/encoders/chunk.js rename to src/encoders/chunk.ts index 20029b5..7295547 100644 --- a/src/encoders/chunk.js +++ b/src/encoders/chunk.ts @@ -1,4 +1,4 @@ -module.exports = (id, chunkData, hasSubchunks) => { +export default (id: number, chunkData: Buffer, hasSubchunks: boolean): Buffer => { if (chunkData.length > 0x7fff) { throw new Error('chunkData can not be greater than 32767 bytes'); } diff --git a/src/encoders/data/data-packet-chunk.js b/src/encoders/data/data-packet-chunk.js deleted file mode 100644 index 131ebe1..0000000 --- a/src/encoders/data/data-packet-chunk.js +++ /dev/null @@ -1,4 +0,0 @@ -const chunk = require('../chunk'); - -module.exports = (packetHeaderChunk, trackerListChunk) => - chunk(0x6755, Buffer.concat([packetHeaderChunk, trackerListChunk]), true); diff --git a/src/encoders/data/data-packet-chunk.ts b/src/encoders/data/data-packet-chunk.ts new file mode 100644 index 0000000..6e63cbc --- /dev/null +++ b/src/encoders/data/data-packet-chunk.ts @@ -0,0 +1,3 @@ +import chunk from '../chunk'; +export default (packetHeaderChunk: Buffer, trackerListChunk: Buffer): Buffer => + chunk(0x6755, Buffer.concat([packetHeaderChunk, trackerListChunk]), true); diff --git a/src/encoders/data/data-tracker-accel-chunk.js b/src/encoders/data/data-tracker-accel-chunk.ts similarity index 61% rename from src/encoders/data/data-tracker-accel-chunk.js rename to src/encoders/data/data-tracker-accel-chunk.ts index b348e56..049e929 100644 --- a/src/encoders/data/data-tracker-accel-chunk.js +++ b/src/encoders/data/data-tracker-accel-chunk.ts @@ -1,6 +1,6 @@ -const chunk = require('../chunk'); +import chunk from '../chunk'; -module.exports = (x, y, z) => { +export default (x: number, y: number, z: number): Buffer => { const buf = Buffer.alloc(12); buf.writeFloatLE(x); buf.writeFloatLE(y, 4); diff --git a/src/encoders/data/data-tracker-chunk.js b/src/encoders/data/data-tracker-chunk.js deleted file mode 100644 index 76bb4a0..0000000 --- a/src/encoders/data/data-tracker-chunk.js +++ /dev/null @@ -1,3 +0,0 @@ -const chunk = require('../chunk'); - -module.exports = (trackerId, fieldChunks) => chunk(trackerId, Buffer.concat(fieldChunks), fieldChunks.length > 0); diff --git a/src/encoders/data/data-tracker-chunk.ts b/src/encoders/data/data-tracker-chunk.ts new file mode 100644 index 0000000..29af047 --- /dev/null +++ b/src/encoders/data/data-tracker-chunk.ts @@ -0,0 +1,4 @@ +import chunk from '../chunk'; + +export default (trackerId: number, fieldChunks: Buffer[]): Buffer => + chunk(trackerId, Buffer.concat(fieldChunks), fieldChunks.length > 0); diff --git a/src/encoders/data/data-tracker-list-chunk.js b/src/encoders/data/data-tracker-list-chunk.js deleted file mode 100644 index b040226..0000000 --- a/src/encoders/data/data-tracker-list-chunk.js +++ /dev/null @@ -1,3 +0,0 @@ -const chunk = require('../chunk'); - -module.exports = (trackerChunks) => chunk(0x0001, Buffer.concat(trackerChunks), true); diff --git a/src/encoders/data/data-tracker-list-chunk.ts b/src/encoders/data/data-tracker-list-chunk.ts new file mode 100644 index 0000000..7378ce1 --- /dev/null +++ b/src/encoders/data/data-tracker-list-chunk.ts @@ -0,0 +1,3 @@ +import chunk from '../chunk'; + +export default (trackerChunks: Buffer[]) => chunk(0x0001, Buffer.concat(trackerChunks), true); diff --git a/src/encoders/data/data-tracker-ori-chunk.js b/src/encoders/data/data-tracker-ori-chunk.ts similarity index 61% rename from src/encoders/data/data-tracker-ori-chunk.js rename to src/encoders/data/data-tracker-ori-chunk.ts index 074cb47..a77aae0 100644 --- a/src/encoders/data/data-tracker-ori-chunk.js +++ b/src/encoders/data/data-tracker-ori-chunk.ts @@ -1,6 +1,6 @@ -const chunk = require('../chunk'); +import chunk from '../chunk'; -module.exports = (x, y, z) => { +export default (x: number, y: number, z: number): Buffer => { const buf = Buffer.alloc(12); buf.writeFloatLE(x); buf.writeFloatLE(y, 4); diff --git a/src/encoders/data/data-tracker-pos-chunk.js b/src/encoders/data/data-tracker-pos-chunk.ts similarity index 61% rename from src/encoders/data/data-tracker-pos-chunk.js rename to src/encoders/data/data-tracker-pos-chunk.ts index 95ebdfb..38f3827 100644 --- a/src/encoders/data/data-tracker-pos-chunk.js +++ b/src/encoders/data/data-tracker-pos-chunk.ts @@ -1,6 +1,6 @@ -const chunk = require('../chunk'); +import chunk from '../chunk'; -module.exports = (x, y, z) => { +export default (x: number, y: number, z: number): Buffer => { const buf = Buffer.alloc(12); buf.writeFloatLE(x); buf.writeFloatLE(y, 4); diff --git a/src/encoders/data/data-tracker-speed-chunk.js b/src/encoders/data/data-tracker-speed-chunk.ts similarity index 61% rename from src/encoders/data/data-tracker-speed-chunk.js rename to src/encoders/data/data-tracker-speed-chunk.ts index 659fded..681129f 100644 --- a/src/encoders/data/data-tracker-speed-chunk.js +++ b/src/encoders/data/data-tracker-speed-chunk.ts @@ -1,6 +1,6 @@ -const chunk = require('../chunk'); +import chunk from '../chunk'; -module.exports = (x, y, z) => { +export default (x: number, y: number, z: number): Buffer => { const buf = Buffer.alloc(12); buf.writeFloatLE(x); buf.writeFloatLE(y, 4); diff --git a/src/encoders/data/data-tracker-status-chunk.js b/src/encoders/data/data-tracker-status-chunk.ts similarity index 56% rename from src/encoders/data/data-tracker-status-chunk.js rename to src/encoders/data/data-tracker-status-chunk.ts index 5c7ca46..873d524 100644 --- a/src/encoders/data/data-tracker-status-chunk.js +++ b/src/encoders/data/data-tracker-status-chunk.ts @@ -1,6 +1,6 @@ -const chunk = require('../chunk'); +import chunk from '../chunk'; -module.exports = (validity) => { +export default (validity: number): Buffer => { const buf = Buffer.alloc(4); buf.writeFloatLE(validity); return chunk(0x0003, buf, false); diff --git a/src/encoders/data/data-tracker-timestamp-chunk.js b/src/encoders/data/data-tracker-timestamp-chunk.ts similarity index 59% rename from src/encoders/data/data-tracker-timestamp-chunk.js rename to src/encoders/data/data-tracker-timestamp-chunk.ts index 4bdf06f..082a0fd 100644 --- a/src/encoders/data/data-tracker-timestamp-chunk.js +++ b/src/encoders/data/data-tracker-timestamp-chunk.ts @@ -1,6 +1,6 @@ -const chunk = require('../chunk'); +import chunk from '../chunk'; -module.exports = (timestamp) => { +export default (timestamp: bigint): Buffer => { const buf = Buffer.alloc(8); buf.writeBigUInt64LE(BigInt(timestamp)); return chunk(0x0006, buf, false); diff --git a/src/encoders/data/data-tracker-trgtpos-chunk.js b/src/encoders/data/data-tracker-trgtpos-chunk.ts similarity index 61% rename from src/encoders/data/data-tracker-trgtpos-chunk.js rename to src/encoders/data/data-tracker-trgtpos-chunk.ts index b71765e..b82ee27 100644 --- a/src/encoders/data/data-tracker-trgtpos-chunk.js +++ b/src/encoders/data/data-tracker-trgtpos-chunk.ts @@ -1,6 +1,6 @@ -const chunk = require('../chunk'); +import chunk from '../chunk'; -module.exports = (x, y, z) => { +export default (x: number, y: number, z: number): Buffer => { const buf = Buffer.alloc(12); buf.writeFloatLE(x); buf.writeFloatLE(y, 4); diff --git a/src/encoders/info/info-packet-chunk.js b/src/encoders/info/info-packet-chunk.js deleted file mode 100644 index 34e32ca..0000000 --- a/src/encoders/info/info-packet-chunk.js +++ /dev/null @@ -1,4 +0,0 @@ -const chunk = require('../chunk'); - -module.exports = (packetHeaderChunk, systemNameChunk, trackerListChunk) => - chunk(0x6756, Buffer.concat([packetHeaderChunk, systemNameChunk, trackerListChunk]), true); diff --git a/src/encoders/info/info-packet-chunk.ts b/src/encoders/info/info-packet-chunk.ts new file mode 100644 index 0000000..27f4fb0 --- /dev/null +++ b/src/encoders/info/info-packet-chunk.ts @@ -0,0 +1,4 @@ +import chunk from '../chunk'; + +export default (packetHeaderChunk: Buffer, systemNameChunk: Buffer, trackerListChunk: Buffer): Buffer => + chunk(0x6756, Buffer.concat([packetHeaderChunk, systemNameChunk, trackerListChunk]), true); diff --git a/src/encoders/info/info-system-name-chunk.js b/src/encoders/info/info-system-name-chunk.js deleted file mode 100644 index f41f165..0000000 --- a/src/encoders/info/info-system-name-chunk.js +++ /dev/null @@ -1,3 +0,0 @@ -const chunk = require('../chunk'); - -module.exports = (systemName) => chunk(0x0001, Buffer.from(systemName), false); diff --git a/src/encoders/info/info-system-name-chunk.ts b/src/encoders/info/info-system-name-chunk.ts new file mode 100644 index 0000000..246b5ab --- /dev/null +++ b/src/encoders/info/info-system-name-chunk.ts @@ -0,0 +1,3 @@ +import chunk from '../chunk'; + +export default (systemName: string): Buffer => chunk(0x0001, Buffer.from(systemName), false); diff --git a/src/encoders/info/info-tracker-chunk.js b/src/encoders/info/info-tracker-chunk.js deleted file mode 100644 index ef9ff8f..0000000 --- a/src/encoders/info/info-tracker-chunk.js +++ /dev/null @@ -1,3 +0,0 @@ -const chunk = require('../chunk'); - -module.exports = (trackerId, trackerNameChunk) => chunk(trackerId, trackerNameChunk, true); diff --git a/src/encoders/info/info-tracker-chunk.ts b/src/encoders/info/info-tracker-chunk.ts new file mode 100644 index 0000000..f761b74 --- /dev/null +++ b/src/encoders/info/info-tracker-chunk.ts @@ -0,0 +1,3 @@ +import chunk from '../chunk'; + +export default (trackerId: number, trackerNameChunk: Buffer): Buffer => chunk(trackerId, trackerNameChunk, true); diff --git a/src/encoders/info/info-tracker-list-chunk.js b/src/encoders/info/info-tracker-list-chunk.js deleted file mode 100644 index a13b1e5..0000000 --- a/src/encoders/info/info-tracker-list-chunk.js +++ /dev/null @@ -1,3 +0,0 @@ -const chunk = require('../chunk'); - -module.exports = (trackerChunks) => chunk(0x0002, Buffer.concat(trackerChunks), true); diff --git a/src/encoders/info/info-tracker-list-chunk.ts b/src/encoders/info/info-tracker-list-chunk.ts new file mode 100644 index 0000000..4dd6b81 --- /dev/null +++ b/src/encoders/info/info-tracker-list-chunk.ts @@ -0,0 +1,3 @@ +import chunk from '../chunk'; + +export default (trackerChunks: Buffer[]): Buffer => chunk(0x0002, Buffer.concat(trackerChunks), true); diff --git a/src/encoders/info/info-tracker-name-chunk.js b/src/encoders/info/info-tracker-name-chunk.js deleted file mode 100644 index 78a1c32..0000000 --- a/src/encoders/info/info-tracker-name-chunk.js +++ /dev/null @@ -1,3 +0,0 @@ -const chunk = require('../chunk'); - -module.exports = (trackerName) => chunk(0x0000, Buffer.from(trackerName), false); diff --git a/src/encoders/info/info-tracker-name-chunk.ts b/src/encoders/info/info-tracker-name-chunk.ts new file mode 100644 index 0000000..c116bb3 --- /dev/null +++ b/src/encoders/info/info-tracker-name-chunk.ts @@ -0,0 +1,3 @@ +import chunk from '../chunk'; + +export default (trackerName: string) => chunk(0x0000, Buffer.from(trackerName), false); diff --git a/src/encoders/packet-header-chunk.js b/src/encoders/packet-header-chunk.ts similarity index 69% rename from src/encoders/packet-header-chunk.js rename to src/encoders/packet-header-chunk.ts index 2edb990..6a45df1 100644 --- a/src/encoders/packet-header-chunk.js +++ b/src/encoders/packet-header-chunk.ts @@ -1,6 +1,12 @@ -const chunk = require('./chunk'); +import chunk from './chunk'; -module.exports = (timestamp, versionHigh, versionLow, frameId, framePacketCount) => { +export default ( + timestamp: bigint, + versionHigh: number, + versionLow: number, + frameId: number, + framePacketCount: number +): Buffer => { if (frameId > 255) { throw new Error('frame id must be >= 0 and <= 255'); } diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..626f0ff --- /dev/null +++ b/src/index.ts @@ -0,0 +1,3 @@ +export { Decoder } from './decoder'; +export { Encoder } from './encoder'; +export { Tracker } from './models/tracker'; diff --git a/src/models/tracker.js b/src/models/tracker.js deleted file mode 100644 index da63a7f..0000000 --- a/src/models/tracker.js +++ /dev/null @@ -1,128 +0,0 @@ -const dataTrackerAccelChunk = require('../encoders/data/data-tracker-accel-chunk'); -const dataTrackerChunk = require('../encoders/data/data-tracker-chunk'); -const dataTrackerOriChunk = require('../encoders/data/data-tracker-ori-chunk'); -const dataTrackerPosChunk = require('../encoders/data/data-tracker-pos-chunk'); -const dataTrackerSpeedChunk = require('../encoders/data/data-tracker-speed-chunk'); -const dataTrackerStatusChunk = require('../encoders/data/data-tracker-status-chunk'); -const dataTrackerTimestampChunk = require('../encoders/data/data-tracker-timestamp-chunk'); -const dataTrackerTrgtposChunk = require('../encoders/data/data-tracker-trgtpos-chunk'); -const infoTrackerChunk = require('../encoders/info/info-tracker-chunk'); -const infoTrackerNameChunk = require('../encoders/info/info-tracker-name-chunk'); - -class Tracker { - /** - * @constructor - * @param {number} id - tracker id - * @param {string} name - tracker name - */ - constructor(id, name) { - this.id = id; - this.name = name; - this.pos = undefined; - this.speed = undefined; - this.ori = undefined; - this.validity = undefined; - this.accel = undefined; - this.trgtpos = undefined; - this.timestamp = undefined; - } - - /** - * @param {float} x - * @param {float} y - * @param {float} z - */ - setPos(x, y, z) { - this.pos = [x, y, z]; - } - - /** - * @param {float} x - * @param {float} y - * @param {float} z - */ - setSpeed(x, y, z) { - this.speed = [x, y, z]; - } - - /** - * @param {float} x - * @param {float} y - * @param {float} z - */ - setOri(x, y, z) { - this.ori = [x, y, z]; - } - - /** - * @param {float} validity - */ - setStatus(validity) { - this.validity = validity; - } - - /** - * @param {float} x - * @param {float} y - * @param {float} z - */ - setAccel(x, y, z) { - this.accel = [x, y, z]; - } - - /** - * @param {float} x - * @param {float} y - * @param {float} z - */ - setTrgtPos(x, y, z) { - this.trgtpos = [x, y, z]; - } - - /** - * @param {BigInt} timestamp - */ - setTimestamp(timestamp) { - this.timestamp = timestamp; - } - - getDataChunk() { - const fieldChunks = []; - - if (this.pos) { - fieldChunks.push(dataTrackerPosChunk(...this.pos)); - } - - if (this.speed) { - fieldChunks.push(dataTrackerSpeedChunk(...this.speed)); - } - - if (this.ori) { - fieldChunks.push(dataTrackerOriChunk(...this.ori)); - } - - if (this.validity) { - fieldChunks.push(dataTrackerStatusChunk(this.validity)); - } - - if (this.accel) { - fieldChunks.push(dataTrackerAccelChunk(...this.accel)); - } - - if (this.trgtpos) { - fieldChunks.push(dataTrackerTrgtposChunk(...this.trgtpos)); - } - - if (this.timestamp) { - fieldChunks.push(dataTrackerTimestampChunk(this.timestamp)); - } - - return dataTrackerChunk(this.id, fieldChunks); - } - - getInfoChunk() { - return infoTrackerChunk(this.id, infoTrackerNameChunk(this.name)); - } -} - -module.exports = Tracker; diff --git a/src/models/tracker.ts b/src/models/tracker.ts new file mode 100644 index 0000000..ccb44d7 --- /dev/null +++ b/src/models/tracker.ts @@ -0,0 +1,100 @@ +import dataTrackerAccelChunk from '../encoders/data/data-tracker-accel-chunk'; +import dataTrackerChunk from '../encoders/data/data-tracker-chunk'; +import dataTrackerOriChunk from '../encoders/data/data-tracker-ori-chunk'; +import dataTrackerPosChunk from '../encoders/data/data-tracker-pos-chunk'; +import dataTrackerSpeedChunk from '../encoders/data/data-tracker-speed-chunk'; +import dataTrackerStatusChunk from '../encoders/data/data-tracker-status-chunk'; +import dataTrackerTimestampChunk from '../encoders/data/data-tracker-timestamp-chunk'; +import dataTrackerTrgtposChunk from '../encoders/data/data-tracker-trgtpos-chunk'; +import infoTrackerChunk from '../encoders/info/info-tracker-chunk'; +import infoTrackerNameChunk from '../encoders/info/info-tracker-name-chunk'; + +export class Tracker { + id: number; + name: string; + pos?: [number, number, number]; + speed?: [number, number, number]; + ori?: [number, number, number]; + validity?: number; + accel?: [number, number, number]; + trgtpos?: [number, number, number]; + timestamp?: bigint; + + constructor(id: number, name: string) { + this.id = id; + this.name = name; + this.pos = undefined; + this.speed = undefined; + this.ori = undefined; + this.validity = undefined; + this.accel = undefined; + this.trgtpos = undefined; + this.timestamp = undefined; + } + + setPos(x: number, y: number, z: number) { + this.pos = [x, y, z]; + } + + setSpeed(x: number, y: number, z: number) { + this.speed = [x, y, z]; + } + + setOri(x: number, y: number, z: number) { + this.ori = [x, y, z]; + } + + setStatus(validity: number) { + this.validity = validity; + } + + setAccel(x: number, y: number, z: number) { + this.accel = [x, y, z]; + } + + setTrgtPos(x: number, y: number, z: number) { + this.trgtpos = [x, y, z]; + } + + setTimestamp(timestamp: bigint) { + this.timestamp = timestamp; + } + + getDataChunk() { + const fieldChunks: Buffer[] = []; + + if (this.pos) { + fieldChunks.push(dataTrackerPosChunk(...this.pos)); + } + + if (this.speed) { + fieldChunks.push(dataTrackerSpeedChunk(...this.speed)); + } + + if (this.ori) { + fieldChunks.push(dataTrackerOriChunk(...this.ori)); + } + + if (this.validity) { + fieldChunks.push(dataTrackerStatusChunk(this.validity)); + } + + if (this.accel) { + fieldChunks.push(dataTrackerAccelChunk(...this.accel)); + } + + if (this.trgtpos) { + fieldChunks.push(dataTrackerTrgtposChunk(...this.trgtpos)); + } + + if (this.timestamp) { + fieldChunks.push(dataTrackerTimestampChunk(this.timestamp)); + } + + return dataTrackerChunk(this.id, fieldChunks); + } + + getInfoChunk() { + return infoTrackerChunk(this.id, infoTrackerNameChunk(this.name)); + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..d7822a4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "module": "commonjs", + "target": "es2016", + "declaration": true, + "moduleResolution": "node", + "rootDir": "./src", + "strict": true, + "outDir": "dist" + }, + "exclude": ["node_modules", "dist", "examples"] +}