@honeybbq/teamspeak-client 1.0.0-beta.1 → 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,10 +4,12 @@
4
4
 
5
5
  **A clean-room TeamSpeak client protocol library written in pure TypeScript.**
6
6
 
7
- Compatible with TeamSpeak 3, 5 & 6. No proprietary SDK. No copy-pasted code.
7
+ Works with TeamSpeak 3 and TeamSpeak 6 servers. No proprietary SDK, no copied code.
8
8
 
9
9
  [![CI](https://github.com/honeybbq/teamspeak-js/actions/workflows/ci.yml/badge.svg)](https://github.com/honeybbq/teamspeak-js/actions/workflows/ci.yml)
10
10
  [![npm](https://img.shields.io/npm/v/@honeybbq/teamspeak-client)](https://www.npmjs.com/package/@honeybbq/teamspeak-client)
11
+ [![npm beta](https://img.shields.io/npm/v/@honeybbq/teamspeak-client/beta?label=beta)](https://www.npmjs.com/package/@honeybbq/teamspeak-client?activeTab=versions)
12
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/HoneyBBQ/teamspeak-js/badge)](https://scorecard.dev/viewer/?uri=github.com/HoneyBBQ/teamspeak-js)
11
13
  [![Node Version](https://img.shields.io/node/v/@honeybbq/teamspeak-client)](package.json)
12
14
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
13
15
 
@@ -28,20 +30,23 @@ Upgrading from 0.x? See the [migration guide](https://github.com/HoneyBBQ/teamsp
28
30
  - **Identity management** — Generate, import/export, and upgrade security level of identities
29
31
  - **Full command set** — 111 typed functions covering every command the voice protocol answers
30
32
  - **Reconnection** — Opt-in retry with backoff, tuned for TeamSpeak's antiflood ban
31
- - **Server capabilities** — Reports the server version and the uid hash it uses (SHA-1 on TS3, SHA-256 on TS6)
33
+ - **Server capabilities** — Reports the server version and the uid hash it uses (SHA-1 on TS3, SHA-256 on TS6), and the server's name, icon, banner and welcome message
32
34
  - **Custom transports** — Supply your own socket, for proxies, tunnels or tests
33
35
  - **ESM with types** — Ships ES modules with full TypeScript declarations
34
36
  - **Zero native deps** — Pure TypeScript, no native addons required
35
37
 
36
38
  ## Installation
37
39
 
40
+ 1.0 is in beta, published under the `beta` tag. A plain `npm install` still
41
+ gets 0.3, so ask for the beta:
42
+
38
43
  ```bash
39
- npm install @honeybbq/teamspeak-client
44
+ npm install @honeybbq/teamspeak-client@beta
40
45
  # or
41
- pnpm add @honeybbq/teamspeak-client
46
+ pnpm add @honeybbq/teamspeak-client@beta
42
47
  ```
43
48
 
44
- Requires **Node.js 20.19** or later.
49
+ Everything in this README is the 1.0 API. You need Node.js 22.12 or newer.
45
50
 
46
51
  ## Quick Start
47
52
 
@@ -152,7 +157,15 @@ for await (const msg of client.events("textMessage", { signal })) {
152
157
  ```
153
158
 
154
159
  `notification` delivers every notification as it arrived, for the ones the SDK
155
- does not model.
160
+ does not model. `NotificationName` names them:
161
+
162
+ ```typescript
163
+ import { NotificationName } from "@honeybbq/teamspeak-client";
164
+
165
+ client.on("notification", (n) => {
166
+ if (n.name === NotificationName.ChannelEdited) console.log(n.params);
167
+ });
168
+ ```
156
169
 
157
170
  ### Commands
158
171
 
@@ -176,6 +189,7 @@ import {
176
189
  addServerGroupPermission,
177
190
  iterateClientDatabase,
178
191
  permissionByName,
192
+ PermissionName,
179
193
  asClientID,
180
194
  Codec,
181
195
  Reason,
@@ -195,7 +209,7 @@ await sendChannelMessage(client, "hello");
195
209
  await kickClient(client, someone, Reason.KickChannel, { reasonMessage: "take a break" });
196
210
 
197
211
  await addServerGroupPermission(client, sgid, {
198
- permission: permissionByName("i_client_talk_power"),
212
+ permission: permissionByName(PermissionName.ClientTalkPower),
199
213
  value: 50,
200
214
  });
201
215
 
@@ -215,7 +229,8 @@ and only the fields you set are sent: an unset field leaves the setting alone,
215
229
  while `""` sends it empty — `editChannel(client, cid, { password: "" })` clears
216
230
  a password. A key an options type does not name is never sent. The exceptions
217
231
  are `editServer` and `editInstance`, which take the raw `virtualserver_*` and
218
- `serverinstance_*` properties as `getServerInfo` reports them.
232
+ `serverinstance_*` properties as `getServerInfo` reports them; `PropertyName` names
233
+ the keys.
219
234
 
220
235
  Results are camelCase too. Timestamps are `Date`s (`undefined` where the server
221
236
  sends 0 for "never"), durations are milliseconds with an `Ms` suffix
@@ -397,7 +412,11 @@ const client = new Client(identity, "ts.example.com", "Bot", {
397
412
 
398
413
  ```typescript
399
414
  const caps = client.serverCapabilities;
400
- // { version: "6.0.0-beta13.1", major: 6, family: "ts6", uidAlgorithm: "sha256" }
415
+ // {
416
+ // version: "6.0.0-beta13.1 [Build: 1790080330]", major: 6, family: "ts6",
417
+ // uidAlgorithm: "sha256", name: "TeamSpeak 6 Server", iconID: undefined,
418
+ // hostBannerImageURL: undefined, welcomeMessage: "…"
419
+ // }
401
420
  ```
402
421
 
403
422
  Read from `initserver` during the handshake, so it costs no extra round trip.
package/dist/client.d.ts CHANGED
@@ -77,7 +77,7 @@ export declare class Client implements CommandExecutor, AsyncDisposable {
77
77
  * Send a raw command line and return the rows that answer it: the escape
78
78
  * hatch for a command the typed functions do not cover. The line is sent as
79
79
  * given, so its values must already be escaped and any channel password
80
- * already hashed.
80
+ * already hashed. `CommandName` lists the command names.
81
81
  *
82
82
  * Rejects with a NotConnectedError unless the client is connected: while it
83
83
  * is still connecting, the session's keys may not exist yet.
@@ -85,7 +85,8 @@ export declare class Client implements CommandExecutor, AsyncDisposable {
85
85
  exec(command: string, options?: CommandOptions): Promise<Record<string, string>[]>;
86
86
  /**
87
87
  * Send a raw command line without waiting for an answer, for the few
88
- * commands the server answers with nothing at all.
88
+ * commands the server answers with nothing at all. `CommandName` lists
89
+ * the command names.
89
90
  *
90
91
  * Commands are paced by a flood throttle; aborting `signal` while this waits
91
92
  * for its turn rejects with the signal's reason and sends nothing. Rejects
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"handshake.d.ts","sourceRoot":"","sources":["../src/handshake.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,mEAAmE;AACnE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,IAAI,CAQN;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,IAAI,CAYN;AAED,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CA0B9F;AAwBD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAG5D"}
1
+ {"version":3,"file":"handshake.d.ts","sourceRoot":"","sources":["../src/handshake.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,mEAAmE;AACnE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,IAAI,CASN;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,IAAI,CAYN;AAED,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CA0B9F;AAwBD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAG5D"}
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
  export * from "@honeybbq/teamspeak-core";
9
9
  export { Client, ClientStatus } from "./client.js";
10
- export type { TextMessageEvent, ClientMovedEvent, ClientLeaveEvent, KickedEvent, NotificationEvent, ClientEnterEvent, PokeEvent, VoiceDataEvent, EventMap, EventMiddleware, Listener, ServerEvent, ServerEventName, Unsubscribe, AddrResolver, ClientOptions, ResolvedAddr, DatagramSocket, SocketFactory, FileTransferSocketFactory, } from "./types.js";
10
+ export type { EventMap, EventMiddleware, Listener, ServerEvent, ServerEventName, Unsubscribe, AddrResolver, ClientOptions, ResolvedAddr, DatagramSocket, SocketFactory, FileTransferSocketFactory, } from "./types.js";
11
11
  export { AlreadyConnectedError, FileTransferError, CryptoInitError, InvalidAddressError, InvalidIdentityError, RemovedError, ConnectionTimeoutError, } from "./errors.js";
12
12
  export * from "./api/voice.js";
13
13
  export { dialFileTransfer, uploadFileData, downloadFileData } from "./transfer.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,0BAA0B,CAAC;AAGzC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEnD,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,WAAW,EACX,eAAe,EACf,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,cAAc,EACd,aAAa,EACb,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,sBAAsB,GACvB,MAAM,aAAa,CAAC;AAGrB,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnF,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG1E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGlE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACxF,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGtE,OAAO,EACL,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,0BAA0B,CAAC;AAGzC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEnD,YAAY,EACV,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,WAAW,EACX,eAAe,EACf,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,cAAc,EACd,aAAa,EACb,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,sBAAsB,GACvB,MAAM,aAAa,CAAC;AAGrB,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnF,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG1E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGlE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACxF,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGtE,OAAO,EACL,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -1220,10 +1220,30 @@ var GenerationWindow = class {
1220
1220
  if (maxOffset < this.#mod) return mappedValue >= this.#mappedBaseOffset && mappedValue < maxOffset;
1221
1221
  return mappedValue >= this.#mappedBaseOffset || mappedValue < maxOffset - this.#mod;
1222
1222
  }
1223
+ /**
1224
+ * The offset from the window base: negative means stale, `receiveWindow` or
1225
+ * more too far ahead. An id up to `receiveWindow` behind the base across the
1226
+ * last wrap, which reads as a high number, is stale too.
1227
+ */
1223
1228
  mappedToIndex(mappedValue) {
1224
1229
  if (this.#isNextGen(mappedValue)) return mappedValue + this.#mod - this.#mappedBaseOffset;
1225
- return mappedValue - this.#mappedBaseOffset;
1230
+ const index = mappedValue - this.#mappedBaseOffset;
1231
+ return this.#isBehindAcrossWrap(index) ? index - this.#mod : index;
1232
+ }
1233
+ /**
1234
+ * Whether an id `index` past the base is really up to `receiveWindow` behind
1235
+ * it, in the generation before: the base has wrapped since, so the id reads as
1236
+ * nearly a whole generation ahead. Before the first wrap no id lies behind the
1237
+ * base across it.
1238
+ */
1239
+ #isBehindAcrossWrap(index) {
1240
+ return this.#generation > 0 && index >= this.#receiveWindow && index >= this.#mod - this.#receiveWindow;
1226
1241
  }
1242
+ /**
1243
+ * Whether the id is before the receive window: a packet whose acknowledgement
1244
+ * was lost is sent again after the window has moved past it, also when the
1245
+ * move wrapped the 16-bit id.
1246
+ */
1227
1247
  isOldPacket(mappedValue) {
1228
1248
  return this.mappedToIndex(mappedValue) < 0;
1229
1249
  }
@@ -1233,8 +1253,14 @@ var GenerationWindow = class {
1233
1253
  #isNextGen(mappedValue) {
1234
1254
  return this.#mappedBaseOffset > this.#mod - this.#receiveWindow && mappedValue < this.#mappedBaseOffset + this.#receiveWindow - this.#mod;
1235
1255
  }
1256
+ /**
1257
+ * The generation the id belongs to: one past the current generation if the id
1258
+ * has already wrapped, one before it if the id is just behind the base across
1259
+ * the last wrap.
1260
+ */
1236
1261
  getGeneration(mappedValue) {
1237
1262
  if (this.#isNextGen(mappedValue)) return this.#generation + 1;
1263
+ if (this.#isBehindAcrossWrap(mappedValue - this.#mappedBaseOffset)) return this.#generation - 1;
1238
1264
  return this.#generation;
1239
1265
  }
1240
1266
  reset() {
@@ -1529,6 +1555,12 @@ var PacketHandler = class {
1529
1555
  /** The bytes held in both command queues; see MAX_QUEUED_BYTES. */
1530
1556
  #queuedBytes = 0;
1531
1557
  #ackManager = /* @__PURE__ */ new Map();
1558
+ /**
1559
+ * The last Init1 packet the client sent, resent until the handshake's final
1560
+ * acknowledgement. Init1 packets are not acknowledged one by one: each step
1561
+ * the client sends replaces it, and only `receivedFinalInitAck` clears it.
1562
+ * Receiving an Init1 does not, as the client may have nothing to answer with.
1563
+ */
1532
1564
  #initPacketCheck = null;
1533
1565
  /**
1534
1566
  * Command packets sent under the dummy key, before crypto init completed:
@@ -1633,6 +1665,13 @@ var PacketHandler = class {
1633
1665
  const resendTimer = setInterval(() => this.#checkResends(), RESEND_LOOP_INTERVAL_MS);
1634
1666
  this.#stopResend = () => clearInterval(resendTimer);
1635
1667
  }
1668
+ /**
1669
+ * Stop resending the last Init1 packet the client sent. Until this is called,
1670
+ * the latest step stays pending whatever the server sends in between: a step
1671
+ * the client does not answer, an unknown one or a second RSA challenge, must
1672
+ * not stop the resending of its own. The server's `initivexpand2` command
1673
+ * acknowledges the last step, not an Init1 reply.
1674
+ */
1636
1675
  receivedFinalInitAck() {
1637
1676
  this.#initPacketCheck = null;
1638
1677
  }
@@ -1937,7 +1976,6 @@ var PacketHandler = class {
1937
1976
  let totalSize = 0;
1938
1977
  let currID = nextID;
1939
1978
  let startSeen = false;
1940
- let complete = false;
1941
1979
  while (true) {
1942
1980
  const frag = queue.get(currID);
1943
1981
  if (!frag) return null;
@@ -1954,17 +1992,10 @@ var PacketHandler = class {
1954
1992
  const fragmented = (packetFlags(frag) & PacketFlags.Fragmented) !== 0;
1955
1993
  if (!startSeen) {
1956
1994
  startSeen = true;
1957
- if (!fragmented) {
1958
- complete = true;
1959
- break;
1960
- }
1961
- } else if (fragmented) {
1962
- complete = true;
1963
- break;
1964
- }
1995
+ if (!fragmented) break;
1996
+ } else if (fragmented) break;
1965
1997
  currID = currID + 1 & 65535;
1966
1998
  }
1967
- if (!complete) return null;
1968
1999
  const combined = new Uint8Array(totalSize);
1969
2000
  let pos = 0;
1970
2001
  for (const frag of fragments) {
@@ -1995,10 +2026,6 @@ var PacketHandler = class {
1995
2026
  }
1996
2027
  #updatePostReceiveState(p) {
1997
2028
  const pType = packetType(p);
1998
- if (pType === PacketType.Init1) {
1999
- this.#initPacketCheck = null;
2000
- return;
2001
- }
2002
2029
  if ((pType === PacketType.Ack || pType === PacketType.AckLow) && p.data.length >= 2) {
2003
2030
  const ackID = new DataView(p.data.buffer, p.data.byteOffset).getUint16(0, false);
2004
2031
  const key = (pType === PacketType.Ack ? PacketType.Command : PacketType.CommandLow) << 16 | ackID;
@@ -2589,6 +2616,7 @@ function handleHandshakeInitIV(client, params) {
2589
2616
  const alpha = params["alpha"] ?? "";
2590
2617
  const beta = params["beta"] ?? "";
2591
2618
  const omega = params["omega"] ?? "";
2619
+ client.handler.receivedFinalInitAck();
2592
2620
  client.crypt.initCrypto(alpha, beta, omega);
2593
2621
  client.logger.info("crypto initialized (P-256 path), sending clientinit");
2594
2622
  sendClientInit(client);
@@ -3265,7 +3293,7 @@ var Client = class {
3265
3293
  * Send a raw command line and return the rows that answer it: the escape
3266
3294
  * hatch for a command the typed functions do not cover. The line is sent as
3267
3295
  * given, so its values must already be escaped and any channel password
3268
- * already hashed.
3296
+ * already hashed. `CommandName` lists the command names.
3269
3297
  *
3270
3298
  * Rejects with a NotConnectedError unless the client is connected: while it
3271
3299
  * is still connecting, the session's keys may not exist yet.
@@ -3275,7 +3303,8 @@ var Client = class {
3275
3303
  }
3276
3304
  /**
3277
3305
  * Send a raw command line without waiting for an answer, for the few
3278
- * commands the server answers with nothing at all.
3306
+ * commands the server answers with nothing at all. `CommandName` lists
3307
+ * the command names.
3279
3308
  *
3280
3309
  * Commands are paced by a flood throttle; aborting `signal` while this waits
3281
3310
  * for its turn rejects with the signal's reason and sends nothing. Rejects