@honeybbq/teamspeak 1.0.0-beta.10 → 1.0.0-beta.12

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.
Files changed (125) hide show
  1. package/README.md +17 -7
  2. package/dist/client/api/voice.d.ts +13 -0
  3. package/dist/client/api/voice.d.ts.map +1 -1
  4. package/dist/client/api/voice.js +20 -1
  5. package/dist/client/api/voice.js.map +1 -1
  6. package/dist/client/client.d.ts +9 -0
  7. package/dist/client/client.d.ts.map +1 -1
  8. package/dist/client/client.js +105 -12
  9. package/dist/client/client.js.map +1 -1
  10. package/dist/client/crypto/crypt.d.ts +25 -4
  11. package/dist/client/crypto/crypt.d.ts.map +1 -1
  12. package/dist/client/crypto/crypt.js +41 -9
  13. package/dist/client/crypto/crypt.js.map +1 -1
  14. package/dist/client/errors.d.ts +14 -0
  15. package/dist/client/errors.d.ts.map +1 -1
  16. package/dist/client/errors.js +28 -0
  17. package/dist/client/errors.js.map +1 -1
  18. package/dist/client/handshake/crypt-handshake.d.ts +8 -2
  19. package/dist/client/handshake/crypt-handshake.d.ts.map +1 -1
  20. package/dist/client/handshake/crypt-handshake.js +26 -20
  21. package/dist/client/handshake/crypt-handshake.js.map +1 -1
  22. package/dist/client/index.d.ts +2 -1
  23. package/dist/client/index.d.ts.map +1 -1
  24. package/dist/client/index.js +1 -1
  25. package/dist/client/index.js.map +1 -1
  26. package/dist/client/types.d.ts +35 -0
  27. package/dist/client/types.d.ts.map +1 -1
  28. package/dist/client/types.js +4 -0
  29. package/dist/client/types.js.map +1 -1
  30. package/dist/client/view.d.ts +229 -0
  31. package/dist/client/view.d.ts.map +1 -0
  32. package/dist/client/view.js +388 -0
  33. package/dist/client/view.js.map +1 -0
  34. package/dist/core/api/clients.d.ts +4 -0
  35. package/dist/core/api/clients.d.ts.map +1 -1
  36. package/dist/core/api/clients.js +4 -0
  37. package/dist/core/api/clients.js.map +1 -1
  38. package/dist/core/api/group-rows.d.ts +12 -0
  39. package/dist/core/api/group-rows.d.ts.map +1 -0
  40. package/dist/core/api/group-rows.js +34 -0
  41. package/dist/core/api/group-rows.js.map +1 -0
  42. package/dist/core/api/groups.d.ts.map +1 -1
  43. package/dist/core/api/groups.js +2 -13
  44. package/dist/core/api/groups.js.map +1 -1
  45. package/dist/core/api/server.d.ts.map +1 -1
  46. package/dist/core/api/server.js +2 -13
  47. package/dist/core/api/server.js.map +1 -1
  48. package/dist/core/channel-tree.d.ts +87 -0
  49. package/dist/core/channel-tree.d.ts.map +1 -0
  50. package/dist/core/channel-tree.js +378 -0
  51. package/dist/core/channel-tree.js.map +1 -0
  52. package/dist/core/command/responses.d.ts +4 -1
  53. package/dist/core/command/responses.d.ts.map +1 -1
  54. package/dist/core/command/responses.js +10 -1
  55. package/dist/core/command/responses.js.map +1 -1
  56. package/dist/core/errorcode.d.ts +16 -0
  57. package/dist/core/errorcode.d.ts.map +1 -1
  58. package/dist/core/errorcode.js +16 -0
  59. package/dist/core/errorcode.js.map +1 -1
  60. package/dist/core/events.d.ts +34 -2
  61. package/dist/core/events.d.ts.map +1 -1
  62. package/dist/core/index.d.ts +1 -0
  63. package/dist/core/index.d.ts.map +1 -1
  64. package/dist/core/index.js +1 -0
  65. package/dist/core/index.js.map +1 -1
  66. package/dist/core/internal.d.ts +1 -0
  67. package/dist/core/internal.d.ts.map +1 -1
  68. package/dist/core/internal.js +1 -0
  69. package/dist/core/internal.js.map +1 -1
  70. package/dist/query/client.d.ts +4 -4
  71. package/dist/query/client.d.ts.map +1 -1
  72. package/dist/query/client.js +64 -7
  73. package/dist/query/client.js.map +1 -1
  74. package/dist/query/errors.d.ts +21 -0
  75. package/dist/query/errors.d.ts.map +1 -1
  76. package/dist/query/errors.js +34 -0
  77. package/dist/query/errors.js.map +1 -1
  78. package/dist/query/index.d.ts +3 -2
  79. package/dist/query/index.d.ts.map +1 -1
  80. package/dist/query/index.js +3 -2
  81. package/dist/query/index.js.map +1 -1
  82. package/dist/query/options.d.ts +20 -15
  83. package/dist/query/options.d.ts.map +1 -1
  84. package/dist/query/options.js +20 -16
  85. package/dist/query/options.js.map +1 -1
  86. package/dist/query/ssh.d.ts +3 -1
  87. package/dist/query/ssh.d.ts.map +1 -1
  88. package/dist/query/ssh.js.map +1 -1
  89. package/dist/query/stream.d.ts +8 -0
  90. package/dist/query/stream.d.ts.map +1 -1
  91. package/dist/query/stream.js +31 -3
  92. package/dist/query/stream.js.map +1 -1
  93. package/dist/query/transport.d.ts +4 -3
  94. package/dist/query/transport.d.ts.map +1 -1
  95. package/dist/query/web.d.ts +8 -2
  96. package/dist/query/web.d.ts.map +1 -1
  97. package/dist/query/web.js +2 -1
  98. package/dist/query/web.js.map +1 -1
  99. package/package.json +3 -3
  100. package/src/client/api/voice.ts +25 -1
  101. package/src/client/client.ts +119 -12
  102. package/src/client/crypto/crypt.ts +46 -9
  103. package/src/client/errors.ts +31 -0
  104. package/src/client/handshake/crypt-handshake.ts +51 -16
  105. package/src/client/index.ts +3 -0
  106. package/src/client/types.ts +35 -0
  107. package/src/client/view.ts +592 -0
  108. package/src/core/api/clients.ts +4 -0
  109. package/src/core/api/group-rows.ts +38 -0
  110. package/src/core/api/groups.ts +1 -14
  111. package/src/core/api/server.ts +1 -15
  112. package/src/core/channel-tree.ts +398 -0
  113. package/src/core/command/responses.ts +14 -2
  114. package/src/core/errorcode.ts +16 -0
  115. package/src/core/events.ts +34 -2
  116. package/src/core/index.ts +1 -0
  117. package/src/core/internal.ts +1 -0
  118. package/src/query/client.ts +66 -7
  119. package/src/query/errors.ts +37 -0
  120. package/src/query/index.ts +8 -2
  121. package/src/query/options.ts +39 -29
  122. package/src/query/ssh.ts +3 -1
  123. package/src/query/stream.ts +34 -3
  124. package/src/query/transport.ts +4 -3
  125. package/src/query/web.ts +8 -2
package/README.md CHANGED
@@ -537,11 +537,18 @@ the way the voice protocol cannot: the same typed commands the core exports,
537
537
  plus the ones only an administrator may run, over the three transports a
538
538
  ServerQuery speaks.
539
539
 
540
- | Transport | Where | Server | Login | Notifications |
541
- | --------- | ------------ | ---------------- | ------------------- | ------------- |
542
- | `tcp` | 10011 | TeamSpeak 3 only | the `login` command | yes |
543
- | `ssh` | 10022 | both | the SSH login | yes |
544
- | `web` | 10080 (HTTP) | TeamSpeak 6 | the api key | **no** |
540
+ | Transport | Where | Server | Login | Notifications |
541
+ | --------- | ------------ | ---------------- | ----------------- | ------------- |
542
+ | `tcp` | 10011 | TeamSpeak 3 only | `transport.login` | yes |
543
+ | `ssh` | 10022 | both | the SSH login | yes |
544
+ | `web` | 10080 (HTTP) | both | the api key | **no** |
545
+
546
+ TeamSpeak 3 (3.12 and later for WebQuery, 3.3 and later for SSH) serves SSH and
547
+ WebQuery as well as raw TCP, but only the raw port is on until
548
+ `query_protocols` lists the others; the official Docker image takes it as
549
+ `TS3SERVER_QUERY_PROTOCOLS=raw,ssh,http`. TeamSpeak 6 has no raw port. Its
550
+ WebQuery also answers a request with no api key as a guest; TeamSpeak 3 refuses
551
+ one.
545
552
 
546
553
  Only raw TCP and SSH carry notifications: the server pushes them down the same
547
554
  connection. WebQuery has no session to push to and refuses to register, so the
@@ -554,8 +561,11 @@ import { QueryClient } from "@honeybbq/teamspeak/query";
554
561
  import { listChannels } from "@honeybbq/teamspeak";
555
562
 
556
563
  const client = new QueryClient({
557
- transport: { kind: "tcp", host: "ts.example.com" }, // 10011
558
- login: { name: "serveradmin", password: process.env.QUERY_PASSWORD! },
564
+ transport: {
565
+ kind: "tcp", // 10011
566
+ host: "ts.example.com",
567
+ login: { name: "serveradmin", password: process.env.QUERY_PASSWORD! },
568
+ },
559
569
  server: { id: 1 },
560
570
  nickname: "bot",
561
571
  events: { categories: ["textserver", "textprivate"] },
@@ -14,6 +14,19 @@ import type { ChannelID, ClientID, CommandOptions } from "@honeybbq/teamspeak";
14
14
  * a `channelEdited` event, since it is no edit.
15
15
  */
16
16
  export declare function getChannelDescription(client: Client, cid: ChannelID, options?: CommandOptions): Promise<string>;
17
+ /**
18
+ * The virtual server's properties as the server sends them on request, which
19
+ * is a different set from `getServerInfo`'s: it has the settings, limits and
20
+ * counters (clients online, uptime, traffic) and lacks the identity ones such as
21
+ * the unique identifier. It is the whole row, counters included.
22
+ *
23
+ * The client's `view.server` takes every answer in, whoever asked, less the
24
+ * counters, so this is also how to bring it up to date after an edit the
25
+ * server did not spell out. The answer goes to the asker alone.
26
+ *
27
+ * @experimental New in 1.x and may change in a minor release.
28
+ */
29
+ export declare function getServerVariables(client: Client, options?: CommandOptions): Promise<Readonly<Record<string, string>>>;
17
30
  /**
18
31
  * Subscribe to a channel: receive its clients' events and voice without
19
32
  * joining it.
@@ -1 +1 @@
1
- {"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../../src/client/api/voice.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE/E;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,8DAA8D;AAC9D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,gDAAgD;AAChD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,oDAAoD;AACpD,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAaD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,OAAO,CAAC,CAalB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAaD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf"}
1
+ {"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../../src/client/api/voice.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE/E;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAO3C;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,8DAA8D;AAC9D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,gDAAgD;AAChD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,oDAAoD;AACpD,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAaD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,OAAO,CAAC,CAalB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAaD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf"}
@@ -6,7 +6,7 @@
6
6
  * `channelinfo` already carries the description. These run on the voice
7
7
  * client alone, which is why they take one rather than any CommandExecutor.
8
8
  */
9
- import { ErrorCode, ServerError } from "@honeybbq/teamspeak";
9
+ import { ErrorCode, NoDataError, ServerError } from "@honeybbq/teamspeak";
10
10
  /**
11
11
  * The channel's description, which `listChannels` omits for bandwidth. The
12
12
  * server answers with a `notifychanneledited` that the client does not report as
@@ -20,6 +20,25 @@ export async function getChannelDescription(client, cid, options) {
20
20
  const answer = rows.find((row) => row["cid"] === String(cid) && "channel_description" in row);
21
21
  return answer?.["channel_description"] ?? "";
22
22
  }
23
+ /**
24
+ * The virtual server's properties as the server sends them on request, which
25
+ * is a different set from `getServerInfo`'s: it has the settings, limits and
26
+ * counters (clients online, uptime, traffic) and lacks the identity ones such as
27
+ * the unique identifier. It is the whole row, counters included.
28
+ *
29
+ * The client's `view.server` takes every answer in, whoever asked, less the
30
+ * counters, so this is also how to bring it up to date after an edit the
31
+ * server did not spell out. The answer goes to the asker alone.
32
+ *
33
+ * @experimental New in 1.x and may change in a minor release.
34
+ */
35
+ export async function getServerVariables(client, options) {
36
+ const rows = await client.send({ command: "servergetvariables" }, options);
37
+ const answer = rows.find((row) => Object.keys(row).some((key) => key.startsWith("virtualserver_")));
38
+ if (answer === undefined)
39
+ throw new NoDataError("servergetvariables");
40
+ return answer;
41
+ }
23
42
  /**
24
43
  * Subscribe to a channel: receive its clients' events and voice without
25
44
  * joining it.
@@ -1 +1 @@
1
- {"version":3,"file":"voice.js","sourceRoot":"","sources":["../../../src/client/api/voice.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAG7D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAc,EACd,GAAc,EACd,OAAwB;IAExB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAC5B,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,EAC5D,OAAO,CACR,CAAC;IACF,2EAA2E;IAC3E,yEAAyE;IACzE,4CAA4C;IAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,qBAAqB,IAAI,GAAG,CAAC,CAAC;IAC9F,OAAO,MAAM,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,GAAc,EACd,OAAwB;IAExB,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AACtF,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAc,EACd,GAAc,EACd,OAAwB;IAExB,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AACxF,CAAC;AAED,gDAAgD;AAChD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAc,EACd,OAAwB;IAExB,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,EAAE,OAAO,CAAC,CAAC;AACjE,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAc,EACd,OAAwB;IAExB,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,uBAAuB,EAAE,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC;AAED,0GAA0G;AAC1G,KAAK,UAAU,eAAe,CAAC,GAA2B,EAAE,QAAgB;IAC1E,IAAI,CAAC;QACH,MAAM,GAAG,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC1E,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAc,EACd,QAAgB,EAChB,OAAwB;IAExB,OAAO,eAAe,CACpB,GAAG,EAAE,CACH,MAAM,CAAC,IAAI,CACT;QACE,OAAO,EAAE,sBAAsB;QAC/B,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAChC,SAAS,EAAE,CAAC,UAAU,CAAC;KACxB,EACD,OAAO,CACR,EACH,SAAS,CAAC,qBAAqB,CAChC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAc,EACd,GAAc,EACd,QAAgB,EAChB,OAAwB;IAExB,OAAO,eAAe,CACpB,GAAG,EAAE,CACH,MAAM,CAAC,IAAI,CACT;QACE,OAAO,EAAE,uBAAuB;QAChC,MAAM,EAAE;YACN,CAAC,KAAK,EAAE,GAAG,CAAC;YACZ,CAAC,UAAU,EAAE,QAAQ,CAAC;SACvB;QACD,SAAS,EAAE,CAAC,UAAU,CAAC;KACxB,EACD,OAAO,CACR,EACH,SAAS,CAAC,sBAAsB,CACjC,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,KAAK,UAAU,QAAQ,CACrB,MAAc,EACd,OAAsC,EACtC,SAA8B,EAC9B,OAAwB;IAExB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACnC,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC3F,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,SAA8B,EAC9B,OAAwB;IAExB,OAAO,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAc,EACd,SAA8B,EAC9B,OAAwB;IAExB,OAAO,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"voice.js","sourceRoot":"","sources":["../../../src/client/api/voice.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ import type { ClientVersion, CommandExecutor, CommandRequest } from "@honeybbq/t
6
6
  import type { FileUploadInfo, FileDownloadInfo } from "@honeybbq/teamspeak";
7
7
  import type { Readable, Writable } from "node:stream";
8
8
  import { type ServerCapabilities } from "./capabilities.js";
9
+ import { type ServerView } from "./view.js";
9
10
  /**
10
11
  * What clientinit sends about the connection, with the passwords already in
11
12
  * their wire form, `base64(sha1(password))`: hashed once, when the client is
@@ -32,6 +33,14 @@ export interface ClientInitOptions {
32
33
  export declare class Client implements CommandExecutor, AsyncDisposable {
33
34
  #private;
34
35
  constructor(identity: Identity, addr: string, nickname: string, options?: ClientOptions);
36
+ /**
37
+ * What this client knows of the server: the channel tree, the clients it
38
+ * has been told about, and itself. Always there, and `"empty"` until the
39
+ * first `connect()`.
40
+ *
41
+ * @experimental New in 1.x and may change in a minor release.
42
+ */
43
+ get view(): ServerView;
35
44
  /** Where the client is in its connection's life. */
36
45
  get status(): ClientStatus;
37
46
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ import { buildEventChain } from "./events.js";
17
17
  import { processInit1 } from "./handshake/crypt-handshake.js";
18
18
  import { handleHandshakeInitIV, handleHandshakeExpand2, defaultClientVersion, handleInitServer, prepareClientPassword, } from "./handshake.js";
19
19
  import { handleNotification } from "../core/internal.js";
20
- import { parseCommand } from "../core/internal.js";
20
+ import { parseChannel, parseChannelGroup, parseCommand, parseServerGroup, parseUint16, } from "../core/internal.js";
21
21
  import { CommandThrottle } from "./throttle.js";
22
22
  import { splitCommandRows, sleep } from "../core/internal.js";
23
23
  import { isAutoNicknameMatch } from "./helpers.js";
@@ -27,6 +27,7 @@ import { unknownServerCapabilities } from "./capabilities.js";
27
27
  import { joinHostPort, parseConnectAddress, splitHostPort } from "./address.js";
28
28
  import { commandChannel, incomingChannel } from "./diagnostics.js";
29
29
  import { defaultShouldRetry } from "./reconnect.js";
30
+ import { ViewStore } from "./view.js";
30
31
  /** The signature is Ed25519, 64 bytes; the server verifies it, so only its shape is checked. */
31
32
  function normalizeClientVersion(version) {
32
33
  if (version === undefined)
@@ -213,12 +214,15 @@ export class Client {
213
214
  #status = ClientStatus.Disconnected;
214
215
  #throttle = new CommandThrottle();
215
216
  #cmdTrack = new CommandTracker(() => this.#clid);
216
- #clients = new Map();
217
+ #viewStore;
218
+ #clients;
217
219
  #attempt = newConnectAttempt();
218
220
  #listeners = new Map();
219
221
  /** Deliveries waiting for their turn; see #emit. */
220
222
  #queue = [];
221
223
  #draining = false;
224
+ /** The group list rows of the command line being handled, by the name of the line. */
225
+ #groupLine;
222
226
  #voiceDropped = 0;
223
227
  #voiceDropWarnedAt = -Infinity;
224
228
  #eventMiddlewares;
@@ -235,6 +239,8 @@ export class Client {
235
239
  this.#fileTransferSocketFactory = options.fileTransferSocketFactory;
236
240
  this.#reconnectOptions = options.reconnect;
237
241
  this.#trace = options.trace === undefined ? undefined : { ...options.trace };
242
+ this.#viewStore = new ViewStore(this.#logger, () => this.#clid, () => this.#scheduleDrain());
243
+ this.#clients = this.#viewStore.roster;
238
244
  this.#crypt = new Crypt(identity);
239
245
  this.#handler = this.#newHandler();
240
246
  // oxlint-disable-next-line no-this-alias -- accessors cannot be arrow functions
@@ -285,6 +291,16 @@ export class Client {
285
291
  this.#send = buildCommandChain(cmdMiddlewares, (request, commandOptions = {}) => this.#exec(encodeRequest(request, prepareClientPassword), commandOptions, false));
286
292
  this.#eventChain = buildEventChain([...this.#eventMiddlewares], (event) => this.#deliver(event.name, event.payload));
287
293
  }
294
+ /**
295
+ * What this client knows of the server: the channel tree, the clients it
296
+ * has been told about, and itself. Always there, and `"empty"` until the
297
+ * first `connect()`.
298
+ *
299
+ * @experimental New in 1.x and may change in a minor release.
300
+ */
301
+ get view() {
302
+ return this.#viewStore.view;
303
+ }
288
304
  /** Where the client is in its connection's life. */
289
305
  get status() {
290
306
  return this.#status;
@@ -955,6 +971,7 @@ export class Client {
955
971
  }
956
972
  /** Report the end of the session in progress, once. */
957
973
  #endSession(error) {
974
+ this.#viewStore.end(error);
958
975
  const session = this.#session;
959
976
  if (session === undefined)
960
977
  return;
@@ -1004,7 +1021,7 @@ export class Client {
1004
1021
  this.#handler = this.#newHandler();
1005
1022
  this.#attempt = newConnectAttempt();
1006
1023
  this.#cmdTrack.reset(new NotConnectedError());
1007
- this.#clients.clear();
1024
+ this.#viewStore.reset();
1008
1025
  this.#clid = 0;
1009
1026
  this.#capabilities = unknownServerCapabilities();
1010
1027
  }
@@ -1061,9 +1078,23 @@ export class Client {
1061
1078
  if (pType === 8 /* Init1 */) {
1062
1079
  if (this.#crypt.cryptoInitComplete)
1063
1080
  return;
1064
- const response = processInit1(this.#crypt, p.data);
1065
- if (response) {
1066
- this.#handler.sendPacket(PacketType.Init1, response, 0);
1081
+ const signal = this.#attempt.signal;
1082
+ const handler = this.#handler;
1083
+ const response = processInit1(this.#crypt, p.data, signal);
1084
+ if (response instanceof Promise) {
1085
+ // The puzzle: solved in slices, so the loop keeps running meanwhile.
1086
+ response.then((answer) => {
1087
+ if (answer && !signal.aborted)
1088
+ handler.sendPacket(PacketType.Init1, answer, 0);
1089
+ }, (error) => {
1090
+ // An attempt that ended did so for its own reason; the abandoned
1091
+ // solve has nothing more to report.
1092
+ if (!signal.aborted)
1093
+ this.#handleReceiveError(error);
1094
+ });
1095
+ }
1096
+ else if (response) {
1097
+ handler.sendPacket(PacketType.Init1, response, 0);
1067
1098
  }
1068
1099
  return;
1069
1100
  }
@@ -1111,6 +1142,23 @@ export class Client {
1111
1142
  for (const row of splitCommandRows(trimmed)) {
1112
1143
  this.#handleCommandStr(row);
1113
1144
  }
1145
+ this.#applyGroupLine();
1146
+ }
1147
+ }
1148
+ /**
1149
+ * A group list is a whole set, and the server sends it as one command line,
1150
+ * so it is applied once its last row has been handled.
1151
+ */
1152
+ #applyGroupLine() {
1153
+ const line = this.#groupLine;
1154
+ if (line === undefined)
1155
+ return;
1156
+ this.#groupLine = undefined;
1157
+ if (line.name === "notifyservergrouplist") {
1158
+ this.#viewStore.setServerGroups(line.rows.map(parseServerGroup).filter((group) => group.id !== 0n));
1159
+ }
1160
+ else {
1161
+ this.#viewStore.setChannelGroups(line.rows.map(parseChannelGroup).filter((group) => group.id !== 0n));
1114
1162
  }
1115
1163
  }
1116
1164
  #handleCommandStr(s) {
@@ -1143,14 +1191,24 @@ export class Client {
1143
1191
  // buffered as if they were the response to the caller's first command,
1144
1192
  // which is how a channellist could come back with duplicate and empty rows.
1145
1193
  if (cmd.name === "channellistfinished") {
1194
+ // The tree and the clients of the own channel are complete here, so the
1195
+ // view is too; the group lists and permissions the server sends next
1196
+ // are not part of it.
1197
+ const revision = this.#status === ClientStatus.Connected ? this.#viewStore.finish() : undefined;
1198
+ if (revision !== undefined)
1199
+ this.#emit("viewReady", { revision });
1146
1200
  this.#cmdTrack.signalWelcomeComplete();
1147
1201
  this.#markWelcomeDone();
1148
1202
  return;
1149
1203
  }
1150
1204
  if (cmd.name === "channellist") {
1151
1205
  const trace = this.#attempt.trace;
1152
- if (trace !== undefined && !trace.welcomeDone)
1206
+ if (trace !== undefined && !trace.welcomeDone) {
1153
1207
  trace.channels++;
1208
+ if (this.#status === ClientStatus.Connected) {
1209
+ this.#viewStore.collect(parseChannel(cmd.params));
1210
+ }
1211
+ }
1154
1212
  }
1155
1213
  // The server answers our goodbye by announcing that we left, not with an
1156
1214
  // error line; that announcement is what disconnect() waits for.
@@ -1169,8 +1227,21 @@ export class Client {
1169
1227
  }
1170
1228
  if (cmd.name === "notifyconnectioninforequest")
1171
1229
  this.#answerConnectionInfoRequest();
1230
+ if (cmd.name === "notifyservergrouplist" || cmd.name === "notifychannelgrouplist") {
1231
+ if (this.#groupLine?.name !== cmd.name)
1232
+ this.#applyGroupLine();
1233
+ this.#groupLine ??= { name: cmd.name, rows: [] };
1234
+ this.#groupLine.rows.push(cmd.params);
1235
+ }
1236
+ else if (cmd.name === "notifyserverupdated") {
1237
+ this.#viewStore.mergeServer(cmd.params);
1238
+ }
1239
+ // The roster entry goes with the notification, so it is read first.
1240
+ const leaving = cmd.name === "notifyclientleftview"
1241
+ ? this.#clients.get(parseUint16(cmd.params["clid"] ?? ""))
1242
+ : undefined;
1172
1243
  const result = handleNotification(cmd, this.#clid, this.#clients);
1173
- this.#processNotificationResult(result);
1244
+ this.#processNotificationResult(result, leaving);
1174
1245
  if (this.#listeners.get("notification")?.length || this.#eventMiddlewares.length > 0) {
1175
1246
  this.#emitServerEvent({
1176
1247
  name: "notification",
@@ -1196,6 +1267,7 @@ export class Client {
1196
1267
  // report a connection whose next command — clientinit with its password
1197
1268
  // hashes among them — goes out under that dummy key.
1198
1269
  if (this.#status === ClientStatus.Connecting && this.#crypt.cryptoInitComplete) {
1270
+ this.#viewStore.seedServer(cmd.params);
1199
1271
  handleInitServer(this.#internals, cmd.params);
1200
1272
  }
1201
1273
  break;
@@ -1248,7 +1320,7 @@ export class Client {
1248
1320
  });
1249
1321
  }
1250
1322
  }
1251
- #processNotificationResult(result) {
1323
+ #processNotificationResult(result, leaving) {
1252
1324
  switch (result.kind) {
1253
1325
  case "clientEnter": {
1254
1326
  const info = result.info;
@@ -1278,7 +1350,7 @@ export class Client {
1278
1350
  break;
1279
1351
  }
1280
1352
  case "clientLeave": {
1281
- const event = result.event;
1353
+ const event = leaving === undefined ? result.event : { ...result.event, previous: leaving };
1282
1354
  this.#emitServerEvent({ name: "clientLeave", payload: event });
1283
1355
  if (!result.isSelf)
1284
1356
  break;
@@ -1317,17 +1389,26 @@ export class Client {
1317
1389
  this.#emitServerEvent({ name: "clientChannelGroupChanged", payload: result.event });
1318
1390
  break;
1319
1391
  case "channelCreated":
1392
+ this.#viewStore.applyCreated(result.event);
1320
1393
  this.#emitServerEvent({ name: "channelCreated", payload: result.event });
1321
1394
  break;
1322
1395
  case "channelEdited":
1396
+ this.#viewStore.applyEdited(result.event);
1323
1397
  this.#emitServerEvent({ name: "channelEdited", payload: result.event });
1324
1398
  break;
1325
1399
  case "channelMoved":
1400
+ this.#viewStore.applyMoved(result.event);
1326
1401
  this.#emitServerEvent({ name: "channelMoved", payload: result.event });
1327
1402
  break;
1328
- case "channelDeleted":
1329
- this.#emitServerEvent({ name: "channelDeleted", payload: result.event });
1403
+ case "channelDeleted": {
1404
+ const previous = this.#viewStore.channelBeforeDeletion(result.event.channelID);
1405
+ this.#viewStore.applyDeleted(result.event);
1406
+ this.#emitServerEvent({
1407
+ name: "channelDeleted",
1408
+ payload: previous === undefined ? result.event : { ...result.event, previous },
1409
+ });
1330
1410
  break;
1411
+ }
1331
1412
  case "channelDescriptionChanged":
1332
1413
  this.#emitServerEvent({ name: "channelDescriptionChanged", payload: result.event });
1333
1414
  break;
@@ -1335,12 +1416,15 @@ export class Client {
1335
1416
  this.#emitServerEvent({ name: "channelPasswordChanged", payload: result.event });
1336
1417
  break;
1337
1418
  case "serverEdited":
1419
+ this.#viewStore.patchServer(result.event.changes);
1338
1420
  this.#emitServerEvent({ name: "serverEdited", payload: result.event });
1339
1421
  break;
1340
1422
  case "channelSubscribed":
1341
1423
  this.#emitServerEvent({ name: "channelSubscribed", payload: result.event });
1342
1424
  break;
1343
1425
  case "channelUnsubscribed":
1426
+ // The server does not say the clients of the channel left.
1427
+ this.#viewStore.dropChannel(result.event.channelID);
1344
1428
  this.#emitServerEvent({ name: "channelUnsubscribed", payload: result.event });
1345
1429
  break;
1346
1430
  case "pluginCommand":
@@ -1437,6 +1521,9 @@ export class Client {
1437
1521
  */
1438
1522
  #enqueue(delivery) {
1439
1523
  this.#queue.push(delivery);
1524
+ this.#scheduleDrain();
1525
+ }
1526
+ #scheduleDrain() {
1440
1527
  if (this.#draining)
1441
1528
  return;
1442
1529
  this.#draining = true;
@@ -1446,6 +1533,11 @@ export class Client {
1446
1533
  try {
1447
1534
  while (this.#queue.length > 0)
1448
1535
  this.#queue.shift()();
1536
+ // Everything handled so far is delivered: say once that the view moved.
1537
+ // Listeners cannot change the view, so this is the last word of the run.
1538
+ const revision = this.#viewStore.announce();
1539
+ if (revision !== undefined)
1540
+ this.#deliver("viewChanged", { revision });
1449
1541
  }
1450
1542
  finally {
1451
1543
  if (this.#queue.length > 0)
@@ -1612,6 +1704,7 @@ export class Client {
1612
1704
  if (this.#status === ClientStatus.Connected)
1613
1705
  return;
1614
1706
  this.#attempt.reject(error);
1707
+ this.#viewStore.end(error);
1615
1708
  if (this.#status === ClientStatus.Disconnected)
1616
1709
  return;
1617
1710
  this.#status = ClientStatus.Disconnected;