@honeybbq/teamspeak 0.0.1 → 1.0.0-beta.7

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 (393) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +726 -2
  3. package/dist/client/abort.d.ts +5 -0
  4. package/dist/client/abort.d.ts.map +1 -0
  5. package/dist/client/abort.js +23 -0
  6. package/dist/client/abort.js.map +1 -0
  7. package/dist/client/address.d.ts +17 -0
  8. package/dist/client/address.d.ts.map +1 -0
  9. package/dist/client/address.js +66 -0
  10. package/dist/client/address.js.map +1 -0
  11. package/dist/client/api/voice.d.ts +24 -0
  12. package/dist/client/api/voice.d.ts.map +1 -0
  13. package/dist/client/api/voice.js +33 -0
  14. package/dist/client/api/voice.js.map +1 -0
  15. package/dist/client/capabilities.d.ts +68 -0
  16. package/dist/client/capabilities.d.ts.map +1 -0
  17. package/dist/client/capabilities.js +59 -0
  18. package/dist/client/capabilities.js.map +1 -0
  19. package/dist/client/client.d.ts +196 -0
  20. package/dist/client/client.d.ts.map +1 -0
  21. package/dist/client/client.js +1523 -0
  22. package/dist/client/client.js.map +1 -0
  23. package/dist/client/commands.d.ts +66 -0
  24. package/dist/client/commands.d.ts.map +1 -0
  25. package/dist/client/commands.js +162 -0
  26. package/dist/client/commands.js.map +1 -0
  27. package/dist/client/crypto/crypt-ops.d.ts +7 -0
  28. package/dist/client/crypto/crypt-ops.d.ts.map +1 -0
  29. package/dist/client/crypto/crypt-ops.js +2 -0
  30. package/dist/client/crypto/crypt-ops.js.map +1 -0
  31. package/dist/client/crypto/crypt.d.ts +37 -0
  32. package/dist/client/crypto/crypt.d.ts.map +1 -0
  33. package/dist/client/crypto/crypt.js +203 -0
  34. package/dist/client/crypto/crypt.js.map +1 -0
  35. package/dist/client/crypto/eax.d.ts +12 -0
  36. package/dist/client/crypto/eax.d.ts.map +1 -0
  37. package/dist/client/crypto/eax.js +118 -0
  38. package/dist/client/crypto/eax.js.map +1 -0
  39. package/dist/client/crypto/identity.d.ts +97 -0
  40. package/dist/client/crypto/identity.d.ts.map +1 -0
  41. package/dist/client/crypto/identity.js +412 -0
  42. package/dist/client/crypto/identity.js.map +1 -0
  43. package/dist/client/crypto/index.d.ts +7 -0
  44. package/dist/client/crypto/index.d.ts.map +1 -0
  45. package/dist/client/crypto/index.js +5 -0
  46. package/dist/client/crypto/index.js.map +1 -0
  47. package/dist/client/crypto/primitives.d.ts +43 -0
  48. package/dist/client/crypto/primitives.d.ts.map +1 -0
  49. package/dist/client/crypto/primitives.js +116 -0
  50. package/dist/client/crypto/primitives.js.map +1 -0
  51. package/dist/client/diagnostics.d.ts +45 -0
  52. package/dist/client/diagnostics.d.ts.map +1 -0
  53. package/dist/client/diagnostics.js +30 -0
  54. package/dist/client/diagnostics.js.map +1 -0
  55. package/dist/client/discovery/index.d.ts +2 -0
  56. package/dist/client/discovery/index.d.ts.map +1 -0
  57. package/dist/client/discovery/index.js +2 -0
  58. package/dist/client/discovery/index.js.map +1 -0
  59. package/dist/client/discovery/resolver.d.ts +26 -0
  60. package/dist/client/discovery/resolver.d.ts.map +1 -0
  61. package/dist/client/discovery/resolver.js +275 -0
  62. package/dist/client/discovery/resolver.js.map +1 -0
  63. package/dist/client/errors.d.ts +82 -0
  64. package/dist/client/errors.d.ts.map +1 -0
  65. package/dist/client/errors.js +201 -0
  66. package/dist/client/errors.js.map +1 -0
  67. package/dist/client/events.d.ts +3 -0
  68. package/dist/client/events.d.ts.map +1 -0
  69. package/dist/client/events.js +8 -0
  70. package/dist/client/events.js.map +1 -0
  71. package/dist/client/handshake/crypt-handshake.d.ts +17 -0
  72. package/dist/client/handshake/crypt-handshake.d.ts.map +1 -0
  73. package/dist/client/handshake/crypt-handshake.js +128 -0
  74. package/dist/client/handshake/crypt-handshake.js.map +1 -0
  75. package/dist/client/handshake/crypt-init2.d.ts +7 -0
  76. package/dist/client/handshake/crypt-init2.d.ts.map +1 -0
  77. package/dist/client/handshake/crypt-init2.js +37 -0
  78. package/dist/client/handshake/crypt-init2.js.map +1 -0
  79. package/dist/client/handshake/index.d.ts +4 -0
  80. package/dist/client/handshake/index.d.ts.map +1 -0
  81. package/dist/client/handshake/index.js +4 -0
  82. package/dist/client/handshake/index.js.map +1 -0
  83. package/dist/client/handshake/license.d.ts +35 -0
  84. package/dist/client/handshake/license.d.ts.map +1 -0
  85. package/dist/client/handshake/license.js +169 -0
  86. package/dist/client/handshake/license.js.map +1 -0
  87. package/dist/client/handshake.d.ts +27 -0
  88. package/dist/client/handshake.d.ts.map +1 -0
  89. package/dist/client/handshake.js +126 -0
  90. package/dist/client/handshake.js.map +1 -0
  91. package/dist/client/helpers.d.ts +6 -0
  92. package/dist/client/helpers.d.ts.map +1 -0
  93. package/dist/client/helpers.js +13 -0
  94. package/dist/client/helpers.js.map +1 -0
  95. package/dist/client/hooks.d.ts +7 -0
  96. package/dist/client/hooks.d.ts.map +1 -0
  97. package/dist/client/hooks.js +28 -0
  98. package/dist/client/hooks.js.map +1 -0
  99. package/dist/client/index.d.ts +26 -0
  100. package/dist/client/index.d.ts.map +1 -0
  101. package/dist/client/index.js +28 -0
  102. package/dist/client/index.js.map +1 -0
  103. package/dist/client/reconnect.d.ts +12 -0
  104. package/dist/client/reconnect.d.ts.map +1 -0
  105. package/dist/client/reconnect.js +44 -0
  106. package/dist/client/reconnect.js.map +1 -0
  107. package/dist/client/throttle.d.ts +20 -0
  108. package/dist/client/throttle.d.ts.map +1 -0
  109. package/dist/client/throttle.js +83 -0
  110. package/dist/client/throttle.js.map +1 -0
  111. package/dist/client/trace.d.ts +223 -0
  112. package/dist/client/trace.d.ts.map +1 -0
  113. package/dist/client/trace.js +13 -0
  114. package/dist/client/trace.js.map +1 -0
  115. package/dist/client/transfer.d.ts +111 -0
  116. package/dist/client/transfer.d.ts.map +1 -0
  117. package/dist/client/transfer.js +243 -0
  118. package/dist/client/transfer.js.map +1 -0
  119. package/dist/client/transport/generation-window.d.ts +30 -0
  120. package/dist/client/transport/generation-window.d.ts.map +1 -0
  121. package/dist/client/transport/generation-window.js +97 -0
  122. package/dist/client/transport/generation-window.js.map +1 -0
  123. package/dist/client/transport/handler.d.ts +61 -0
  124. package/dist/client/transport/handler.d.ts.map +1 -0
  125. package/dist/client/transport/handler.js +793 -0
  126. package/dist/client/transport/handler.js.map +1 -0
  127. package/dist/client/transport/index.d.ts +6 -0
  128. package/dist/client/transport/index.d.ts.map +1 -0
  129. package/dist/client/transport/index.js +5 -0
  130. package/dist/client/transport/index.js.map +1 -0
  131. package/dist/client/transport/packet.d.ts +36 -0
  132. package/dist/client/transport/packet.d.ts.map +1 -0
  133. package/dist/client/transport/packet.js +55 -0
  134. package/dist/client/transport/packet.js.map +1 -0
  135. package/dist/client/transport/quicklz.d.ts +24 -0
  136. package/dist/client/transport/quicklz.d.ts.map +1 -0
  137. package/dist/client/transport/quicklz.js +179 -0
  138. package/dist/client/transport/quicklz.js.map +1 -0
  139. package/dist/client/types.d.ts +226 -0
  140. package/dist/client/types.d.ts.map +1 -0
  141. package/dist/client/types.js +39 -0
  142. package/dist/client/types.js.map +1 -0
  143. package/dist/core/api/channels.d.ts +182 -0
  144. package/dist/core/api/channels.d.ts.map +1 -0
  145. package/dist/core/api/channels.js +155 -0
  146. package/dist/core/api/channels.js.map +1 -0
  147. package/dist/core/api/clients.d.ts +304 -0
  148. package/dist/core/api/clients.d.ts.map +1 -0
  149. package/dist/core/api/clients.js +260 -0
  150. package/dist/core/api/clients.js.map +1 -0
  151. package/dist/core/api/command.d.ts +305 -0
  152. package/dist/core/api/command.d.ts.map +1 -0
  153. package/dist/core/api/command.js +363 -0
  154. package/dist/core/api/command.js.map +1 -0
  155. package/dist/core/api/files.d.ts +153 -0
  156. package/dist/core/api/files.d.ts.map +1 -0
  157. package/dist/core/api/files.js +181 -0
  158. package/dist/core/api/files.js.map +1 -0
  159. package/dist/core/api/groups.d.ts +248 -0
  160. package/dist/core/api/groups.d.ts.map +1 -0
  161. package/dist/core/api/groups.js +271 -0
  162. package/dist/core/api/groups.js.map +1 -0
  163. package/dist/core/api/moderation.d.ts +205 -0
  164. package/dist/core/api/moderation.d.ts.map +1 -0
  165. package/dist/core/api/moderation.js +209 -0
  166. package/dist/core/api/moderation.js.map +1 -0
  167. package/dist/core/api/parse.d.ts +16 -0
  168. package/dist/core/api/parse.d.ts.map +1 -0
  169. package/dist/core/api/parse.js +40 -0
  170. package/dist/core/api/parse.js.map +1 -0
  171. package/dist/core/api/server.d.ts +310 -0
  172. package/dist/core/api/server.d.ts.map +1 -0
  173. package/dist/core/api/server.js +290 -0
  174. package/dist/core/api/server.js.map +1 -0
  175. package/dist/core/command/command.d.ts +20 -0
  176. package/dist/core/command/command.d.ts.map +1 -0
  177. package/dist/core/command/command.js +112 -0
  178. package/dist/core/command/command.js.map +1 -0
  179. package/dist/core/command/ids.d.ts +125 -0
  180. package/dist/core/command/ids.d.ts.map +1 -0
  181. package/dist/core/command/ids.js +85 -0
  182. package/dist/core/command/ids.js.map +1 -0
  183. package/dist/core/command/parser.d.ts +17 -0
  184. package/dist/core/command/parser.d.ts.map +1 -0
  185. package/dist/core/command/parser.js +65 -0
  186. package/dist/core/command/parser.js.map +1 -0
  187. package/dist/core/command/request.d.ts +61 -0
  188. package/dist/core/command/request.d.ts.map +1 -0
  189. package/dist/core/command/request.js +64 -0
  190. package/dist/core/command/request.js.map +1 -0
  191. package/dist/core/command/responses.d.ts +59 -0
  192. package/dist/core/command/responses.d.ts.map +1 -0
  193. package/dist/core/command/responses.js +74 -0
  194. package/dist/core/command/responses.js.map +1 -0
  195. package/dist/core/command-name.d.ts +333 -0
  196. package/dist/core/command-name.d.ts.map +1 -0
  197. package/dist/core/command-name.js +331 -0
  198. package/dist/core/command-name.js.map +1 -0
  199. package/dist/core/enums.d.ts +146 -0
  200. package/dist/core/enums.d.ts.map +1 -0
  201. package/dist/core/enums.js +132 -0
  202. package/dist/core/enums.js.map +1 -0
  203. package/dist/core/errorcode.d.ts +413 -0
  204. package/dist/core/errorcode.d.ts.map +1 -0
  205. package/dist/core/errorcode.js +410 -0
  206. package/dist/core/errorcode.js.map +1 -0
  207. package/dist/core/errors.d.ts +111 -0
  208. package/dist/core/errors.d.ts.map +1 -0
  209. package/dist/core/errors.js +233 -0
  210. package/dist/core/errors.js.map +1 -0
  211. package/dist/core/events.d.ts +207 -0
  212. package/dist/core/events.d.ts.map +1 -0
  213. package/dist/core/events.js +6 -0
  214. package/dist/core/events.js.map +1 -0
  215. package/dist/core/helpers.d.ts +42 -0
  216. package/dist/core/helpers.d.ts.map +1 -0
  217. package/dist/core/helpers.js +156 -0
  218. package/dist/core/helpers.js.map +1 -0
  219. package/dist/core/index.d.ts +35 -0
  220. package/dist/core/index.d.ts.map +1 -0
  221. package/dist/core/index.js +34 -0
  222. package/dist/core/index.js.map +1 -0
  223. package/dist/core/internal.d.ts +23 -0
  224. package/dist/core/internal.d.ts.map +1 -0
  225. package/dist/core/internal.js +20 -0
  226. package/dist/core/internal.js.map +1 -0
  227. package/dist/core/middleware.d.ts +14 -0
  228. package/dist/core/middleware.d.ts.map +1 -0
  229. package/dist/core/middleware.js +18 -0
  230. package/dist/core/middleware.js.map +1 -0
  231. package/dist/core/notification-name.d.ts +154 -0
  232. package/dist/core/notification-name.d.ts.map +1 -0
  233. package/dist/core/notification-name.js +152 -0
  234. package/dist/core/notification-name.js.map +1 -0
  235. package/dist/core/notifications.d.ts +43 -0
  236. package/dist/core/notifications.d.ts.map +1 -0
  237. package/dist/core/notifications.js +116 -0
  238. package/dist/core/notifications.js.map +1 -0
  239. package/dist/core/permission-name.d.ts +533 -0
  240. package/dist/core/permission-name.d.ts.map +1 -0
  241. package/dist/core/permission-name.js +531 -0
  242. package/dist/core/permission-name.js.map +1 -0
  243. package/dist/core/permission.d.ts +31 -0
  244. package/dist/core/permission.d.ts.map +1 -0
  245. package/dist/core/permission.js +20 -0
  246. package/dist/core/permission.js.map +1 -0
  247. package/dist/core/property-name.d.ts +403 -0
  248. package/dist/core/property-name.d.ts.map +1 -0
  249. package/dist/core/property-name.js +405 -0
  250. package/dist/core/property-name.js.map +1 -0
  251. package/dist/core/reason.d.ts +39 -0
  252. package/dist/core/reason.d.ts.map +1 -0
  253. package/dist/core/reason.js +36 -0
  254. package/dist/core/reason.js.map +1 -0
  255. package/dist/core/reconnect.d.ts +59 -0
  256. package/dist/core/reconnect.d.ts.map +1 -0
  257. package/dist/core/reconnect.js +55 -0
  258. package/dist/core/reconnect.js.map +1 -0
  259. package/dist/core/types.d.ts +110 -0
  260. package/dist/core/types.d.ts.map +1 -0
  261. package/dist/core/types.js +27 -0
  262. package/dist/core/types.js.map +1 -0
  263. package/dist/query/client.d.ts +194 -0
  264. package/dist/query/client.d.ts.map +1 -0
  265. package/dist/query/client.js +967 -0
  266. package/dist/query/client.js.map +1 -0
  267. package/dist/query/errors.d.ts +61 -0
  268. package/dist/query/errors.d.ts.map +1 -0
  269. package/dist/query/errors.js +100 -0
  270. package/dist/query/errors.js.map +1 -0
  271. package/dist/query/index.d.ts +36 -0
  272. package/dist/query/index.d.ts.map +1 -0
  273. package/dist/query/index.js +34 -0
  274. package/dist/query/index.js.map +1 -0
  275. package/dist/query/knownhosts.d.ts +61 -0
  276. package/dist/query/knownhosts.d.ts.map +1 -0
  277. package/dist/query/knownhosts.js +223 -0
  278. package/dist/query/knownhosts.js.map +1 -0
  279. package/dist/query/lines.d.ts +14 -0
  280. package/dist/query/lines.d.ts.map +1 -0
  281. package/dist/query/lines.js +29 -0
  282. package/dist/query/lines.js.map +1 -0
  283. package/dist/query/options.d.ts +187 -0
  284. package/dist/query/options.d.ts.map +1 -0
  285. package/dist/query/options.js +213 -0
  286. package/dist/query/options.js.map +1 -0
  287. package/dist/query/reconnect.d.ts +29 -0
  288. package/dist/query/reconnect.d.ts.map +1 -0
  289. package/dist/query/reconnect.js +87 -0
  290. package/dist/query/reconnect.js.map +1 -0
  291. package/dist/query/ssh.d.ts +345 -0
  292. package/dist/query/ssh.d.ts.map +1 -0
  293. package/dist/query/ssh.js +241 -0
  294. package/dist/query/ssh.js.map +1 -0
  295. package/dist/query/stream.d.ts +38 -0
  296. package/dist/query/stream.d.ts.map +1 -0
  297. package/dist/query/stream.js +70 -0
  298. package/dist/query/stream.js.map +1 -0
  299. package/dist/query/tcp.d.ts +38 -0
  300. package/dist/query/tcp.d.ts.map +1 -0
  301. package/dist/query/tcp.js +53 -0
  302. package/dist/query/tcp.js.map +1 -0
  303. package/dist/query/transport.d.ts +36 -0
  304. package/dist/query/transport.d.ts.map +1 -0
  305. package/dist/query/transport.js +2 -0
  306. package/dist/query/transport.js.map +1 -0
  307. package/dist/query/web.d.ts +54 -0
  308. package/dist/query/web.d.ts.map +1 -0
  309. package/dist/query/web.js +146 -0
  310. package/dist/query/web.js.map +1 -0
  311. package/dist/versions/index.d.ts +3094 -0
  312. package/dist/versions/index.d.ts.map +1 -0
  313. package/dist/versions/index.js +9237 -0
  314. package/dist/versions/index.js.map +1 -0
  315. package/package.json +118 -4
  316. package/src/client/abort.ts +24 -0
  317. package/src/client/address.ts +74 -0
  318. package/src/client/api/voice.ts +61 -0
  319. package/src/client/capabilities.ts +106 -0
  320. package/src/client/client.ts +1809 -0
  321. package/src/client/commands.ts +193 -0
  322. package/src/client/crypto/crypt-ops.ts +6 -0
  323. package/src/client/crypto/crypt.ts +275 -0
  324. package/src/client/crypto/eax.ts +152 -0
  325. package/src/client/crypto/identity.ts +484 -0
  326. package/src/client/crypto/index.ts +21 -0
  327. package/src/client/crypto/primitives.ts +141 -0
  328. package/src/client/diagnostics.ts +58 -0
  329. package/src/client/discovery/index.ts +1 -0
  330. package/src/client/discovery/resolver.ts +325 -0
  331. package/src/client/errors.ts +217 -0
  332. package/src/client/events.ts +12 -0
  333. package/src/client/handshake/crypt-handshake.ts +157 -0
  334. package/src/client/handshake/crypt-init2.ts +48 -0
  335. package/src/client/handshake/index.ts +3 -0
  336. package/src/client/handshake/license.ts +208 -0
  337. package/src/client/handshake.ts +150 -0
  338. package/src/client/helpers.ts +10 -0
  339. package/src/client/hooks.ts +30 -0
  340. package/src/client/index.ts +93 -0
  341. package/src/client/reconnect.ts +43 -0
  342. package/src/client/throttle.ts +92 -0
  343. package/src/client/trace.ts +237 -0
  344. package/src/client/transfer.ts +436 -0
  345. package/src/client/transport/generation-window.ts +108 -0
  346. package/src/client/transport/handler.ts +926 -0
  347. package/src/client/transport/index.ts +14 -0
  348. package/src/client/transport/packet.ts +69 -0
  349. package/src/client/transport/quicklz.ts +209 -0
  350. package/src/client/types.ts +268 -0
  351. package/src/core/api/channels.ts +396 -0
  352. package/src/core/api/clients.ts +654 -0
  353. package/src/core/api/command.ts +563 -0
  354. package/src/core/api/files.ts +405 -0
  355. package/src/core/api/groups.ts +622 -0
  356. package/src/core/api/moderation.ts +525 -0
  357. package/src/core/api/parse.ts +52 -0
  358. package/src/core/api/server.ts +709 -0
  359. package/src/core/command/command.ts +125 -0
  360. package/src/core/command/ids.ts +149 -0
  361. package/src/core/command/parser.ts +68 -0
  362. package/src/core/command/request.ts +119 -0
  363. package/src/core/command/responses.ts +114 -0
  364. package/src/core/command-name.ts +334 -0
  365. package/src/core/enums.ts +167 -0
  366. package/src/core/errorcode.ts +412 -0
  367. package/src/core/errors.ts +258 -0
  368. package/src/core/events.ts +219 -0
  369. package/src/core/helpers.ts +161 -0
  370. package/src/core/index.ts +126 -0
  371. package/src/core/internal.ts +23 -0
  372. package/src/core/middleware.ts +24 -0
  373. package/src/core/notification-name.ts +155 -0
  374. package/src/core/notifications.ts +157 -0
  375. package/src/core/permission-name.ts +538 -0
  376. package/src/core/permission.ts +34 -0
  377. package/src/core/property-name.ts +411 -0
  378. package/src/core/reason.ts +38 -0
  379. package/src/core/reconnect.ts +98 -0
  380. package/src/core/types.ts +138 -0
  381. package/src/query/client.ts +1132 -0
  382. package/src/query/errors.ts +108 -0
  383. package/src/query/index.ts +65 -0
  384. package/src/query/knownhosts.ts +257 -0
  385. package/src/query/lines.ts +28 -0
  386. package/src/query/options.ts +388 -0
  387. package/src/query/reconnect.ts +84 -0
  388. package/src/query/ssh.ts +614 -0
  389. package/src/query/stream.ts +91 -0
  390. package/src/query/tcp.ts +85 -0
  391. package/src/query/transport.ts +35 -0
  392. package/src/query/web.ts +195 -0
  393. package/src/versions/index.ts +10774 -0
@@ -0,0 +1,169 @@
1
+ import { hash512 } from "../crypto/identity.js";
2
+ import { clampScalar, scalarMultFull, bytesToBigIntLE } from "../crypto/primitives.js";
3
+ import { ed25519 } from "@noble/curves/ed25519.js";
4
+ // The root key is a 33-byte Ed25519 point
5
+ const LICENSE_ROOT_KEY = new Uint8Array([
6
+ 0xcd, 0x0d, 0xe2, 0xae, 0xd4, 0x63, 0x45, 0x50, 0x9a, 0x7e, 0x3c, 0xfd, 0x8f, 0x68, 0xb3, 0xdc,
7
+ 0x75, 0x55, 0xb2, 0x9d, 0xcc, 0xec, 0x73, 0xcd, 0x18, 0x75, 0x0f, 0x99, 0x38, 0x12, 0x40, 0x8a,
8
+ ]);
9
+ var LicenseBlockType;
10
+ (function (LicenseBlockType) {
11
+ LicenseBlockType[LicenseBlockType["Intermediate"] = 0] = "Intermediate";
12
+ LicenseBlockType[LicenseBlockType["Server"] = 2] = "Server";
13
+ LicenseBlockType[LicenseBlockType["Ts5Server"] = 8] = "Ts5Server";
14
+ LicenseBlockType[LicenseBlockType["Ephemeral"] = 32] = "Ephemeral";
15
+ })(LicenseBlockType || (LicenseBlockType = {}));
16
+ export class LicenseChain {
17
+ blocks;
18
+ constructor(blocks) {
19
+ this.blocks = blocks;
20
+ }
21
+ /**
22
+ * Derive the session key by chaining Ed25519 point arithmetic starting from
23
+ * the root key through each license block.
24
+ */
25
+ deriveKey() {
26
+ let round = Uint8Array.from(LICENSE_ROOT_KEY);
27
+ for (const block of this.blocks) {
28
+ round = deriveKeyFromBlock(block, round);
29
+ }
30
+ return round;
31
+ }
32
+ }
33
+ /**
34
+ * The most blocks a license chain may have. Real chains have two or three —
35
+ * root-issued intermediate, server, ephemeral — and every block costs a
36
+ * point multiplication to derive, so a server's chain of thousands would hold
37
+ * the event loop for seconds.
38
+ */
39
+ export const MAX_LICENSE_BLOCKS = 8;
40
+ export function parseLicenses(data) {
41
+ if (data.length < 1)
42
+ throw new Error("license too short");
43
+ if (data[0] !== 1)
44
+ throw new Error("unsupported license version");
45
+ let remaining = data.slice(1);
46
+ const blocks = [];
47
+ while (remaining.length > 0) {
48
+ if (blocks.length === MAX_LICENSE_BLOCKS) {
49
+ throw new Error(`license chain longer than ${MAX_LICENSE_BLOCKS} blocks`);
50
+ }
51
+ const { block, consumed } = parseLicenseBlock(remaining);
52
+ blocks.push(block);
53
+ remaining = remaining.slice(consumed);
54
+ }
55
+ return new LicenseChain(blocks);
56
+ }
57
+ function parseLicenseBlock(data) {
58
+ const MIN_BLOCK_LEN = 42;
59
+ if (data.length < MIN_BLOCK_LEN)
60
+ throw new Error("license too short");
61
+ if (data[0] !== 0)
62
+ throw new Error(`wrong key kind in license: ${data[0]}`);
63
+ const blockType = data[33];
64
+ // Timestamps are seconds since Unix epoch offset by 0x50e22700
65
+ const UNIX_OFFSET = 0x50e22700;
66
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
67
+ const notValidBefore = new Date((view.getUint32(34, false) + UNIX_OFFSET) * 1000);
68
+ const notValidAfter = new Date((view.getUint32(38, false) + UNIX_OFFSET) * 1000);
69
+ if (notValidAfter < notValidBefore) {
70
+ throw new Error("license times are invalid");
71
+ }
72
+ const key = Uint8Array.from(data.slice(1, 33));
73
+ const { payload, payloadRead } = parseBlockPayload(blockType, data, MIN_BLOCK_LEN);
74
+ const allLen = MIN_BLOCK_LEN + payloadRead;
75
+ if (allLen > data.length)
76
+ throw new Error("license block longer than the license");
77
+ const hashInput = data.slice(1, allLen);
78
+ const hashFull = hash512(Uint8Array.from(hashInput));
79
+ const hash = Uint8Array.from(hashFull.slice(0, 32));
80
+ return {
81
+ block: {
82
+ key,
83
+ hash,
84
+ properties: payload.properties,
85
+ issuer: payload.issuer,
86
+ notValidBefore,
87
+ notValidAfter,
88
+ blockType,
89
+ serverType: payload.serverType,
90
+ },
91
+ consumed: allLen,
92
+ };
93
+ }
94
+ function parseBlockPayload(blockType, data, minBlockLen) {
95
+ switch (blockType) {
96
+ case LicenseBlockType.Intermediate: {
97
+ const { str, read } = readNullString(data.slice(46));
98
+ return {
99
+ payload: { issuer: str, serverType: 0, properties: [], read: 5 + read },
100
+ payloadRead: 5 + read,
101
+ };
102
+ }
103
+ case LicenseBlockType.Server: {
104
+ const { str, read } = readNullString(data.slice(47));
105
+ return {
106
+ payload: { issuer: str, serverType: data[42] ?? 0, properties: [], read: 6 + read },
107
+ payloadRead: 6 + read,
108
+ };
109
+ }
110
+ case LicenseBlockType.Ts5Server: {
111
+ const propCount = data[43] !== undefined ? data[43] : 0;
112
+ let pos = 44;
113
+ const properties = [];
114
+ for (let i = 0; i < propCount; i++) {
115
+ if (pos >= data.length)
116
+ throw new Error("license too short");
117
+ const propLen = data[pos++];
118
+ if (pos + propLen > data.length)
119
+ throw new Error("license too short");
120
+ properties.push(Uint8Array.from(data.slice(pos, pos + propLen)));
121
+ pos += propLen;
122
+ }
123
+ return {
124
+ payload: { issuer: "", serverType: data[42] ?? 0, properties, read: pos - minBlockLen },
125
+ payloadRead: pos - minBlockLen,
126
+ };
127
+ }
128
+ case LicenseBlockType.Ephemeral:
129
+ return { payload: { issuer: "", serverType: 0, properties: [], read: 0 }, payloadRead: 0 };
130
+ default:
131
+ throw new Error(`invalid license block type: ${String(blockType)}`);
132
+ }
133
+ }
134
+ /**
135
+ * Scan for a null-terminated string and return its content and the index
136
+ * of the null byte (NOT including it in the count, matching Go behaviour).
137
+ * The parent formulas (`5 + read`, `6 + read`) already add 1 for the null.
138
+ */
139
+ function readNullString(data) {
140
+ for (let i = 0; i < data.length; i++) {
141
+ if (data[i] === 0) {
142
+ return { str: new TextDecoder().decode(data.slice(0, i)), read: i };
143
+ }
144
+ }
145
+ throw new Error("non-null-terminated issuer string");
146
+ }
147
+ /**
148
+ * Derive the next key given a parent key and a license block.
149
+ * Mirrors Go's licenseBlock.deriveKey.
150
+ */
151
+ function deriveKeyFromBlock(block, parent) {
152
+ const scalarBytes = Uint8Array.from(block.hash);
153
+ clampScalar(scalarBytes);
154
+ // Use raw scalar WITHOUT reducing mod n — NaCl's ge_scalarmult_vartime
155
+ // uses the raw 256-bit scalar. Reducing mod n changes the result when
156
+ // the point has a small-order component (Ed25519 cofactor = 8).
157
+ const scalar = bytesToBigIntLE(scalarBytes);
158
+ const pub = ed25519.Point.fromBytes(block.key);
159
+ const negPub = pub.negate();
160
+ const par = ed25519.Point.fromBytes(parent);
161
+ const negPar = par.negate();
162
+ const res = scalarMultFull(negPub, scalar).add(negPar);
163
+ const raw = res.toBytes();
164
+ const final = new Uint8Array(raw.length);
165
+ final.set(raw);
166
+ final[31] = (final[31] !== undefined ? final[31] : 0) ^ 0x80;
167
+ return final;
168
+ }
169
+ //# sourceMappingURL=license.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.js","sourceRoot":"","sources":["../../../src/client/handshake/license.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { ClientVersion } from "@honeybbq/teamspeak";
2
+ import type { ClientInternals } from "./client.js";
3
+ /** Handle the `clientinitiv` message (P-256 based crypto path). */
4
+ export declare function handleHandshakeInitIV(client: ClientInternals, params: Record<string, string>): void;
5
+ /** Handle the `initivexpand2` message (Ed25519 / TS3 crypto path). */
6
+ export declare function handleHandshakeExpand2(client: ClientInternals, params: Record<string, string>): void;
7
+ /** Handle `initserver` — marks the client as connected. */
8
+ export declare function handleInitServer(client: ClientInternals, params: Record<string, string>): void;
9
+ /**
10
+ * Encode a password field for the command protocol.
11
+ *
12
+ * TeamSpeak expects password fields as base64(sha1(password)) — server and
13
+ * channel passwords during the handshake, the `clientmove` channel password,
14
+ * and the `cpw` field of the file transfer commands. Sending the plain text
15
+ * instead makes the server reject correct passwords with error 781.
16
+ */
17
+ export declare function prepareClientPassword(password: string): string;
18
+ /**
19
+ * The version `clientinit` sends unless the `version` option says otherwise.
20
+ *
21
+ * A literal on purpose: `@honeybbq/teamspeak/versions` holds over a thousand
22
+ * constants, and the client must not load them. A test holds this equal to the
23
+ * table's `Windows_3_X_X_5680278000`.
24
+ */
25
+ export declare const defaultClientVersion: ClientVersion;
26
+ export declare function sendClientInit(client: ClientInternals): void;
27
+ //# sourceMappingURL=handshake.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handshake.d.ts","sourceRoot":"","sources":["../../src/client/handshake.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,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,CAUN;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,IAAI,CAaN;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;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAIlC,CAAC;AAEF,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAG5D"}
@@ -0,0 +1,126 @@
1
+ import { createHash } from "node:crypto";
2
+ import { buildCommandOrdered, buildCommand } from "../core/internal.js";
3
+ import { sign, generateTemporaryKey } from "./crypto/primitives.js";
4
+ import { identityPrivateKey } from "./crypto/identity.js";
5
+ import { parseServerCapabilities } from "./capabilities.js";
6
+ import { cryptoInit2 } from "./handshake/crypt-init2.js";
7
+ import { PacketType } from "./transport/packet.js";
8
+ /** Handle the `clientinitiv` message (P-256 based crypto path). */
9
+ export function handleHandshakeInitIV(client, params) {
10
+ const alpha = params["alpha"] ?? "";
11
+ const beta = params["beta"] ?? "";
12
+ const omega = params["omega"] ?? "";
13
+ client.handler.receivedFinalInitAck();
14
+ client.crypt.initCrypto(alpha, beta, omega);
15
+ client.markHandshakeDone(omega);
16
+ client.logger.info("crypto initialized (P-256 path), sending clientinit");
17
+ sendClientInit(client);
18
+ }
19
+ /** Handle the `initivexpand2` message (Ed25519 / TS3 crypto path). */
20
+ export function handleHandshakeExpand2(client, params) {
21
+ client.logger.info("received initivexpand2");
22
+ client.handler.receivedFinalInitAck();
23
+ const license = params["l"] ?? "";
24
+ const omega = params["omega"] ?? "";
25
+ const proof = params["proof"] ?? "";
26
+ const beta = params["beta"] ?? "";
27
+ const privateKey = sendClientEkPacket(client, beta);
28
+ cryptoInit2(client.crypt, license, omega, proof, beta, privateKey);
29
+ client.markHandshakeDone(omega);
30
+ sendClientInit(client);
31
+ }
32
+ /** Handle `initserver` — marks the client as connected. */
33
+ export function handleInitServer(client, params) {
34
+ const idStr = params["aclid"] ?? params["clid"] ?? "";
35
+ const clid = idStr ? parseInt(idStr, 10) : 0;
36
+ if (clid > 0) {
37
+ client.clid = clid;
38
+ client.handler.setClientID(clid);
39
+ }
40
+ // initserver is the only place the server names itself, and it determines how
41
+ // the server hashes our public key into client_unique_identifier: SHA-1 on
42
+ // TS3, SHA-256 on TS6. Recording the whole capability set here keeps callers
43
+ // from re-deriving it, or assuming one server generation.
44
+ client.capabilities = parseServerCapabilities(params);
45
+ client.logger.info("connected to server", { selfId: client.clid });
46
+ client.markConnected(params);
47
+ // Inform the server about mute state
48
+ setImmediate(() => {
49
+ const updateCmd = buildCommand("clientupdate", {
50
+ client_input_muted: "0",
51
+ client_output_muted: "0",
52
+ });
53
+ client.execNoWait(updateCmd).catch(() => { });
54
+ });
55
+ }
56
+ function sendClientEkPacket(client, beta) {
57
+ const [publicKey, privateKey] = generateTemporaryKey();
58
+ const ekBase64 = Buffer.from(publicKey).toString("base64");
59
+ const clientProof = buildClientEkProof(client, publicKey, beta);
60
+ const clientEk = buildCommandOrdered("clientek", [
61
+ ["ek", ekBase64],
62
+ ["proof", clientProof],
63
+ ]);
64
+ client.handler.sendPacket(PacketType.Command, Buffer.from(clientEk), 0);
65
+ return privateKey;
66
+ }
67
+ function buildClientEkProof(client, publicKey, beta) {
68
+ const betaBytes = Buffer.from(beta, "base64");
69
+ const toSign = new Uint8Array(86);
70
+ toSign.set(publicKey.subarray(0, 32));
71
+ toSign.set(betaBytes.subarray(0, Math.min(54, betaBytes.length)), 32);
72
+ const sig = sign(identityPrivateKey(client.crypt.identity), toSign);
73
+ return Buffer.from(sig).toString("base64");
74
+ }
75
+ /**
76
+ * Encode a password field for the command protocol.
77
+ *
78
+ * TeamSpeak expects password fields as base64(sha1(password)) — server and
79
+ * channel passwords during the handshake, the `clientmove` channel password,
80
+ * and the `cpw` field of the file transfer commands. Sending the plain text
81
+ * instead makes the server reject correct passwords with error 781.
82
+ */
83
+ export function prepareClientPassword(password) {
84
+ if (password === "")
85
+ return "";
86
+ return createHash("sha1").update(password).digest().toString("base64");
87
+ }
88
+ /**
89
+ * The version `clientinit` sends unless the `version` option says otherwise.
90
+ *
91
+ * A literal on purpose: `@honeybbq/teamspeak/versions` holds over a thousand
92
+ * constants, and the client must not load them. A test holds this equal to the
93
+ * table's `Windows_3_X_X_5680278000`.
94
+ */
95
+ export const defaultClientVersion = {
96
+ platform: "Windows",
97
+ version: "3.?.? [Build: 5680278000]",
98
+ sign: "DX5NIYLvfJEUjuIbCidnoeozxIDRRkpq3I9vVMBmE9L2qnekOoBzSenkzsg2lC9CMv8K5hkEzhr2TYUYSwUXCg==",
99
+ };
100
+ export function sendClientInit(client) {
101
+ const cmd = buildClientInitCommand(client);
102
+ client.handler.sendPacket(PacketType.Command, Buffer.from(cmd), 0);
103
+ }
104
+ function buildClientInitCommand(client) {
105
+ const pubKeyBase64 = client.crypt.identity.publicKey();
106
+ const initOptions = client.initOptions;
107
+ // HWID should match TS3 client UID format: base64(SHA1(publicKey()))
108
+ const hwid = createHash("sha1").update(pubKeyBase64).digest().toString("base64");
109
+ return buildCommandOrdered("clientinit", [
110
+ ["client_nickname", client.nickname],
111
+ ["client_version", initOptions.version.version],
112
+ ["client_platform", initOptions.version.platform],
113
+ ["client_input_hardware", "1"],
114
+ ["client_output_hardware", "1"],
115
+ ["client_default_channel", initOptions.defaultChannel],
116
+ ["client_default_channel_password", initOptions.defaultChannelPasswordHash],
117
+ ["client_server_password", initOptions.serverPasswordHash],
118
+ ["client_meta_data", ""],
119
+ ["client_version_sign", initOptions.version.sign],
120
+ ["client_key_offset", String(client.crypt.identity.offset)],
121
+ ["client_nickname_phonetic", ""],
122
+ ["client_default_token", ""],
123
+ ["hwid", hwid],
124
+ ]);
125
+ }
126
+ //# sourceMappingURL=handshake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../src/client/handshake.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Reports whether `actual` equals `expected` or equals `expected` followed by
3
+ * only digits — the pattern TeamSpeak uses when a nickname is already taken.
4
+ */
5
+ export declare function isAutoNicknameMatch(expected: string, actual: string): boolean;
6
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/client/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAK7E"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Reports whether `actual` equals `expected` or equals `expected` followed by
3
+ * only digits — the pattern TeamSpeak uses when a nickname is already taken.
4
+ */
5
+ export function isAutoNicknameMatch(expected, actual) {
6
+ if (actual === expected)
7
+ return true;
8
+ if (!actual.startsWith(expected))
9
+ return false;
10
+ const suffix = actual.slice(expected.length);
11
+ return /^\d+$/.test(suffix);
12
+ }
13
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/client/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,MAAc;IAClE,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC7C,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Call a trace hook, if there is one, and never let it touch what called it:
3
+ * a throw, or the rejection of a promise it returns, is reported as a
4
+ * throwing listener's is. The info is built only when there is a hook.
5
+ */
6
+ export declare function callHook<I>(hook: ((info: I) => unknown) | undefined, owner: object | undefined, info: () => I): void;
7
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/client/hooks.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,SAAS,EACxC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,IAAI,EAAE,MAAM,CAAC,GACZ,IAAI,CAUN"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Report an error from a trace hook the way a throwing event listener's is
3
+ * reported: rethrown on its own, as an uncaught exception.
4
+ */
5
+ function reportHookError(error) {
6
+ queueMicrotask(() => {
7
+ throw error;
8
+ });
9
+ }
10
+ /**
11
+ * Call a trace hook, if there is one, and never let it touch what called it:
12
+ * a throw, or the rejection of a promise it returns, is reported as a
13
+ * throwing listener's is. The info is built only when there is a hook.
14
+ */
15
+ export function callHook(hook, owner, info) {
16
+ if (hook === undefined)
17
+ return;
18
+ try {
19
+ const result = hook.call(owner, info());
20
+ if (result !== null && typeof result === "object" && "then" in result) {
21
+ Promise.resolve(result).then(undefined, reportHookError);
22
+ }
23
+ }
24
+ catch (error) {
25
+ reportHookError(error);
26
+ }
27
+ }
28
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/client/hooks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,SAAS,eAAe,CAAC,KAAc;IACrC,cAAc,CAAC,GAAG,EAAE;QAClB,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAwC,EACxC,KAAyB,EACzB,IAAa;IAEb,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;YACtE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAe,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * A clean-room TeamSpeak client: it connects over the voice protocol, the way
3
+ * the TeamSpeak application does.
4
+ *
5
+ * Only what belongs to the voice protocol is exported here. The typed commands,
6
+ * ids and errors every client shares come from `@honeybbq/teamspeak`.
7
+ *
8
+ * @module @honeybbq/teamspeak/client
9
+ */
10
+ export { Client } from "./client.js";
11
+ export { EventName } from "./types.js";
12
+ export type { EventMap, EventMiddleware, ServerEvent, ServerEventName, VoiceOptions, WhisperTargets, AddrResolver, ClientOptions, ResolvedAddr, DatagramSocket, SocketFactory, FileTransferSocketFactory, } from "./types.js";
13
+ export { FileTransferError, HandshakeError, InvalidAddressError, InvalidIdentityError, RemovedError, ConnectionTimeoutError, } from "./errors.js";
14
+ export * from "./api/voice.js";
15
+ export { dialFileTransfer, uploadFileData, downloadFileData } from "./transfer.js";
16
+ export type { FileTransferOptions, FileTransferTrace, FileTransferStage, FileTransferDialStartInfo, FileTransferDialDoneInfo, FileTransferProgressInfo, FileTransferDoneInfo, FileTransferFailedInfo, } from "./transfer.js";
17
+ export { ConnectPhase } from "./trace.js";
18
+ export type { ClientTrace, ResolveStartInfo, ResolveDoneInfo, ConnectStartInfo, ConnectDoneInfo, HandshakeDoneInfo, SessionStartInfo, WelcomeDoneInfo, AttemptFailedInfo, ReconnectScheduledInfo, DisconnectStartInfo, DisconnectDoneInfo, SessionEndInfo, ReconnectStoppedInfo, } from "./trace.js";
19
+ export { unknownServerCapabilities } from "./capabilities.js";
20
+ export type { ServerCapabilities } from "./capabilities.js";
21
+ export { commandChannel, incomingChannel } from "./diagnostics.js";
22
+ export type { CommandTrace, IncomingTrace } from "./diagnostics.js";
23
+ export { defaultShouldRetry } from "./reconnect.js";
24
+ export { Identity, parseIdentity, generateIdentity, generateIdentitySync, uidFromPublicKey, } from "./crypto/index.js";
25
+ export type { UIDAlgorithm } from "./crypto/index.js";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,YAAY,EACV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,eAAe,EACf,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,cAAc,EACd,aAAa,EACb,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,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,EACV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpD,OAAO,EACL,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A clean-room TeamSpeak client: it connects over the voice protocol, the way
3
+ * the TeamSpeak application does.
4
+ *
5
+ * Only what belongs to the voice protocol is exported here. The typed commands,
6
+ * ids and errors every client shares come from `@honeybbq/teamspeak`.
7
+ *
8
+ * @module @honeybbq/teamspeak/client
9
+ */
10
+ // The client
11
+ export { Client } from "./client.js";
12
+ export { EventName } from "./types.js";
13
+ export { FileTransferError, HandshakeError, InvalidAddressError, InvalidIdentityError, RemovedError, ConnectionTimeoutError, } from "./errors.js";
14
+ // Commands only the voice protocol has.
15
+ export * from "./api/voice.js";
16
+ // File transfer data
17
+ export { dialFileTransfer, uploadFileData, downloadFileData } from "./transfer.js";
18
+ // Tracing a connection attempt
19
+ export { ConnectPhase } from "./trace.js";
20
+ // Server capabilities, read from the handshake
21
+ export { unknownServerCapabilities } from "./capabilities.js";
22
+ // Tracing points for diagnostics_channel subscribers
23
+ export { commandChannel, incomingChannel } from "./diagnostics.js";
24
+ // Reconnection policy
25
+ export { defaultShouldRetry } from "./reconnect.js";
26
+ // Identity
27
+ export { Identity, parseIdentity, generateIdentity, generateIdentitySync, uidFromPublicKey, } from "./crypto/index.js";
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,aAAa;AACb,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAiBvC,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,sBAAsB,GACvB,MAAM,aAAa,CAAC;AAErB,wCAAwC;AACxC,cAAc,gBAAgB,CAAC;AAE/B,qBAAqB;AACrB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAYnF,+BAA+B;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAkB1C,+CAA+C;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,qDAAqD;AACrD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGnE,sBAAsB;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,WAAW;AACX,OAAO,EACL,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Whether a failure is worth another attempt.
3
+ *
4
+ * Transport failures are retried; so is a server that stopped, and a server
5
+ * error other than the known refusals — a ban, flooding, a wrong server or
6
+ * channel password, missing permissions — since some, such as 521 "too many
7
+ * clones" right after a drop, clear by themselves. A kick or a ban is not:
8
+ * someone removed the client on purpose. Nor is an AlreadyConnectedError: the
9
+ * client was connected by other means; nor an InvalidAddressError.
10
+ */
11
+ export declare function defaultShouldRetry(error: Error | undefined): boolean;
12
+ //# sourceMappingURL=reconnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/client/reconnect.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,OAAO,CASpE"}
@@ -0,0 +1,44 @@
1
+ import { ErrorCode, Reason, ServerError, AlreadyConnectedError } from "@honeybbq/teamspeak";
2
+ import { InvalidAddressError, RemovedError } from "./errors.js";
3
+ /**
4
+ * Server errors where retrying cannot help.
5
+ *
6
+ * Deliberately a short list of codes known to be refusals, rather than "any
7
+ * ServerError". The server also answers transiently: after a dropped
8
+ * connection it still holds the old session, and a reconnect with the same
9
+ * identity is refused with 521 "too many clones already connected" until it
10
+ * reaps the zombie — a condition that clears itself and is worth retrying.
11
+ *
12
+ * The asymmetry is deliberate. Retrying a permanent failure costs a few bounded
13
+ * attempts; not retrying a transient one means never recovering.
14
+ */
15
+ const PERMANENT_SERVER_ERRORS = new Set([
16
+ ErrorCode.ConnectFailedBanned,
17
+ ErrorCode.BanFlooding,
18
+ ErrorCode.ServerInvalidPassword,
19
+ ErrorCode.ChannelInvalidPassword,
20
+ ErrorCode.PermissionsClientInsufficient,
21
+ ]);
22
+ /**
23
+ * Whether a failure is worth another attempt.
24
+ *
25
+ * Transport failures are retried; so is a server that stopped, and a server
26
+ * error other than the known refusals — a ban, flooding, a wrong server or
27
+ * channel password, missing permissions — since some, such as 521 "too many
28
+ * clones" right after a drop, clear by themselves. A kick or a ban is not:
29
+ * someone removed the client on purpose. Nor is an AlreadyConnectedError: the
30
+ * client was connected by other means; nor an InvalidAddressError.
31
+ */
32
+ export function defaultShouldRetry(error) {
33
+ // The client is connected, or connecting, already: there is nothing to retry.
34
+ if (error instanceof AlreadyConnectedError)
35
+ return false;
36
+ // An address that cannot be one stays that way.
37
+ if (error instanceof InvalidAddressError)
38
+ return false;
39
+ if (error instanceof RemovedError) {
40
+ return error.reason !== Reason.KickServer && error.reason !== Reason.KickServerBan;
41
+ }
42
+ return !(error instanceof ServerError && PERMANENT_SERVER_ERRORS.has(error.code));
43
+ }
44
+ //# sourceMappingURL=reconnect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect.js","sourceRoot":"","sources":["../../src/client/reconnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC;IAC3D,SAAS,CAAC,mBAAmB;IAC7B,SAAS,CAAC,WAAW;IACrB,SAAS,CAAC,qBAAqB;IAC/B,SAAS,CAAC,sBAAsB;IAChC,SAAS,CAAC,6BAA6B;CACxC,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAwB;IACzD,8EAA8E;IAC9E,IAAI,KAAK,YAAY,qBAAqB;QAAE,OAAO,KAAK,CAAC;IACzD,gDAAgD;IAChD,IAAI,KAAK,YAAY,mBAAmB;QAAE,OAAO,KAAK,CAAC;IACvD,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,aAAa,CAAC;IACrF,CAAC;IACD,OAAO,CAAC,CAAC,KAAK,YAAY,WAAW,IAAI,uBAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACpF,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Token-bucket limiter for outbound TS3 commands.
3
+ * Mirrors Go's commandThrottle.
4
+ *
5
+ * Waiters are released in the order they arrived: each used to poll for a
6
+ * token on its own timer, so a command that came later could take the turn of
7
+ * one that had waited longer, and the commands went out of order.
8
+ */
9
+ export declare class CommandThrottle {
10
+ #private;
11
+ static readonly TOKEN_RATE = 4;
12
+ static readonly TOKEN_MAX = 8;
13
+ /**
14
+ * Wait for a token, behind every earlier waiter. Aborting `signal` rejects
15
+ * with its reason and gives the place in line up; the abort listener is
16
+ * removed however the wait ends.
17
+ */
18
+ wait(signal?: AbortSignal): Promise<void>;
19
+ }
20
+ //# sourceMappingURL=throttle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../src/client/throttle.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,qBAAa,eAAe;;IAC1B,MAAM,CAAC,QAAQ,CAAC,UAAU,KAAO;IACjC,MAAM,CAAC,QAAQ,CAAC,SAAS,KAAO;IAOhC;;;;OAIG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBxC;CAyCF"}