@honeybbq/teamspeak 0.0.1 → 1.0.0-beta.10
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/LICENSE +21 -0
- package/README.md +749 -2
- package/dist/client/abort.d.ts +5 -0
- package/dist/client/abort.d.ts.map +1 -0
- package/dist/client/abort.js +23 -0
- package/dist/client/abort.js.map +1 -0
- package/dist/client/address.d.ts +17 -0
- package/dist/client/address.d.ts.map +1 -0
- package/dist/client/address.js +66 -0
- package/dist/client/address.js.map +1 -0
- package/dist/client/api/avatars.d.ts +65 -0
- package/dist/client/api/avatars.d.ts.map +1 -0
- package/dist/client/api/avatars.js +118 -0
- package/dist/client/api/avatars.js.map +1 -0
- package/dist/client/api/voice.d.ts +59 -0
- package/dist/client/api/voice.d.ts.map +1 -0
- package/dist/client/api/voice.js +110 -0
- package/dist/client/api/voice.js.map +1 -0
- package/dist/client/capabilities.d.ts +68 -0
- package/dist/client/capabilities.d.ts.map +1 -0
- package/dist/client/capabilities.js +59 -0
- package/dist/client/capabilities.js.map +1 -0
- package/dist/client/client.d.ts +226 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +1634 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/commands.d.ts +66 -0
- package/dist/client/commands.d.ts.map +1 -0
- package/dist/client/commands.js +168 -0
- package/dist/client/commands.js.map +1 -0
- package/dist/client/connection-info.d.ts +14 -0
- package/dist/client/connection-info.d.ts.map +1 -0
- package/dist/client/connection-info.js +47 -0
- package/dist/client/connection-info.js.map +1 -0
- package/dist/client/crypto/crypt-ops.d.ts +7 -0
- package/dist/client/crypto/crypt-ops.d.ts.map +1 -0
- package/dist/client/crypto/crypt-ops.js +2 -0
- package/dist/client/crypto/crypt-ops.js.map +1 -0
- package/dist/client/crypto/crypt.d.ts +37 -0
- package/dist/client/crypto/crypt.d.ts.map +1 -0
- package/dist/client/crypto/crypt.js +203 -0
- package/dist/client/crypto/crypt.js.map +1 -0
- package/dist/client/crypto/eax.d.ts +12 -0
- package/dist/client/crypto/eax.d.ts.map +1 -0
- package/dist/client/crypto/eax.js +118 -0
- package/dist/client/crypto/eax.js.map +1 -0
- package/dist/client/crypto/identity.d.ts +97 -0
- package/dist/client/crypto/identity.d.ts.map +1 -0
- package/dist/client/crypto/identity.js +412 -0
- package/dist/client/crypto/identity.js.map +1 -0
- package/dist/client/crypto/index.d.ts +7 -0
- package/dist/client/crypto/index.d.ts.map +1 -0
- package/dist/client/crypto/index.js +5 -0
- package/dist/client/crypto/index.js.map +1 -0
- package/dist/client/crypto/primitives.d.ts +43 -0
- package/dist/client/crypto/primitives.d.ts.map +1 -0
- package/dist/client/crypto/primitives.js +116 -0
- package/dist/client/crypto/primitives.js.map +1 -0
- package/dist/client/diagnostics.d.ts +45 -0
- package/dist/client/diagnostics.d.ts.map +1 -0
- package/dist/client/diagnostics.js +30 -0
- package/dist/client/diagnostics.js.map +1 -0
- package/dist/client/discovery/index.d.ts +2 -0
- package/dist/client/discovery/index.d.ts.map +1 -0
- package/dist/client/discovery/index.js +2 -0
- package/dist/client/discovery/index.js.map +1 -0
- package/dist/client/discovery/resolver.d.ts +26 -0
- package/dist/client/discovery/resolver.d.ts.map +1 -0
- package/dist/client/discovery/resolver.js +275 -0
- package/dist/client/discovery/resolver.js.map +1 -0
- package/dist/client/errors.d.ts +82 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +201 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/events.d.ts +3 -0
- package/dist/client/events.d.ts.map +1 -0
- package/dist/client/events.js +8 -0
- package/dist/client/events.js.map +1 -0
- package/dist/client/handshake/crypt-handshake.d.ts +17 -0
- package/dist/client/handshake/crypt-handshake.d.ts.map +1 -0
- package/dist/client/handshake/crypt-handshake.js +128 -0
- package/dist/client/handshake/crypt-handshake.js.map +1 -0
- package/dist/client/handshake/crypt-init2.d.ts +7 -0
- package/dist/client/handshake/crypt-init2.d.ts.map +1 -0
- package/dist/client/handshake/crypt-init2.js +37 -0
- package/dist/client/handshake/crypt-init2.js.map +1 -0
- package/dist/client/handshake/index.d.ts +4 -0
- package/dist/client/handshake/index.d.ts.map +1 -0
- package/dist/client/handshake/index.js +4 -0
- package/dist/client/handshake/index.js.map +1 -0
- package/dist/client/handshake/license.d.ts +35 -0
- package/dist/client/handshake/license.d.ts.map +1 -0
- package/dist/client/handshake/license.js +169 -0
- package/dist/client/handshake/license.js.map +1 -0
- package/dist/client/handshake.d.ts +27 -0
- package/dist/client/handshake.d.ts.map +1 -0
- package/dist/client/handshake.js +126 -0
- package/dist/client/handshake.js.map +1 -0
- package/dist/client/helpers.d.ts +6 -0
- package/dist/client/helpers.d.ts.map +1 -0
- package/dist/client/helpers.js +13 -0
- package/dist/client/helpers.js.map +1 -0
- package/dist/client/hooks.d.ts +7 -0
- package/dist/client/hooks.d.ts.map +1 -0
- package/dist/client/hooks.js +28 -0
- package/dist/client/hooks.js.map +1 -0
- package/dist/client/index.d.ts +27 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +29 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/reconnect.d.ts +12 -0
- package/dist/client/reconnect.d.ts.map +1 -0
- package/dist/client/reconnect.js +44 -0
- package/dist/client/reconnect.js.map +1 -0
- package/dist/client/throttle.d.ts +20 -0
- package/dist/client/throttle.d.ts.map +1 -0
- package/dist/client/throttle.js +83 -0
- package/dist/client/throttle.js.map +1 -0
- package/dist/client/trace.d.ts +223 -0
- package/dist/client/trace.d.ts.map +1 -0
- package/dist/client/trace.js +13 -0
- package/dist/client/trace.js.map +1 -0
- package/dist/client/transfer.d.ts +111 -0
- package/dist/client/transfer.d.ts.map +1 -0
- package/dist/client/transfer.js +243 -0
- package/dist/client/transfer.js.map +1 -0
- package/dist/client/transport/generation-window.d.ts +30 -0
- package/dist/client/transport/generation-window.d.ts.map +1 -0
- package/dist/client/transport/generation-window.js +97 -0
- package/dist/client/transport/generation-window.js.map +1 -0
- package/dist/client/transport/handler.d.ts +79 -0
- package/dist/client/transport/handler.d.ts.map +1 -0
- package/dist/client/transport/handler.js +868 -0
- package/dist/client/transport/handler.js.map +1 -0
- package/dist/client/transport/index.d.ts +6 -0
- package/dist/client/transport/index.d.ts.map +1 -0
- package/dist/client/transport/index.js +5 -0
- package/dist/client/transport/index.js.map +1 -0
- package/dist/client/transport/packet.d.ts +36 -0
- package/dist/client/transport/packet.d.ts.map +1 -0
- package/dist/client/transport/packet.js +55 -0
- package/dist/client/transport/packet.js.map +1 -0
- package/dist/client/transport/quicklz.d.ts +24 -0
- package/dist/client/transport/quicklz.d.ts.map +1 -0
- package/dist/client/transport/quicklz.js +179 -0
- package/dist/client/transport/quicklz.js.map +1 -0
- package/dist/client/transport/traffic.d.ts +43 -0
- package/dist/client/transport/traffic.d.ts.map +1 -0
- package/dist/client/transport/traffic.js +90 -0
- package/dist/client/transport/traffic.js.map +1 -0
- package/dist/client/types.d.ts +382 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +111 -0
- package/dist/client/types.js.map +1 -0
- package/dist/core/api/avatars.d.ts +26 -0
- package/dist/core/api/avatars.d.ts.map +1 -0
- package/dist/core/api/avatars.js +37 -0
- package/dist/core/api/avatars.js.map +1 -0
- package/dist/core/api/channels.d.ts +191 -0
- package/dist/core/api/channels.d.ts.map +1 -0
- package/dist/core/api/channels.js +174 -0
- package/dist/core/api/channels.js.map +1 -0
- package/dist/core/api/clients.d.ts +558 -0
- package/dist/core/api/clients.d.ts.map +1 -0
- package/dist/core/api/clients.js +431 -0
- package/dist/core/api/clients.js.map +1 -0
- package/dist/core/api/command.d.ts +400 -0
- package/dist/core/api/command.d.ts.map +1 -0
- package/dist/core/api/command.js +462 -0
- package/dist/core/api/command.js.map +1 -0
- package/dist/core/api/credentials.d.ts +186 -0
- package/dist/core/api/credentials.d.ts.map +1 -0
- package/dist/core/api/credentials.js +144 -0
- package/dist/core/api/credentials.js.map +1 -0
- package/dist/core/api/files.d.ts +153 -0
- package/dist/core/api/files.d.ts.map +1 -0
- package/dist/core/api/files.js +185 -0
- package/dist/core/api/files.js.map +1 -0
- package/dist/core/api/groups.d.ts +301 -0
- package/dist/core/api/groups.d.ts.map +1 -0
- package/dist/core/api/groups.js +339 -0
- package/dist/core/api/groups.js.map +1 -0
- package/dist/core/api/icons.d.ts +67 -0
- package/dist/core/api/icons.d.ts.map +1 -0
- package/dist/core/api/icons.js +125 -0
- package/dist/core/api/icons.js.map +1 -0
- package/dist/core/api/instance.d.ts +197 -0
- package/dist/core/api/instance.d.ts.map +1 -0
- package/dist/core/api/instance.js +160 -0
- package/dist/core/api/instance.js.map +1 -0
- package/dist/core/api/moderation.d.ts +266 -0
- package/dist/core/api/moderation.d.ts.map +1 -0
- package/dist/core/api/moderation.js +258 -0
- package/dist/core/api/moderation.js.map +1 -0
- package/dist/core/api/parse.d.ts +36 -0
- package/dist/core/api/parse.d.ts.map +1 -0
- package/dist/core/api/parse.js +109 -0
- package/dist/core/api/parse.js.map +1 -0
- package/dist/core/api/server.d.ts +334 -0
- package/dist/core/api/server.d.ts.map +1 -0
- package/dist/core/api/server.js +324 -0
- package/dist/core/api/server.js.map +1 -0
- package/dist/core/command/command.d.ts +20 -0
- package/dist/core/command/command.d.ts.map +1 -0
- package/dist/core/command/command.js +112 -0
- package/dist/core/command/command.js.map +1 -0
- package/dist/core/command/ids.d.ts +131 -0
- package/dist/core/command/ids.d.ts.map +1 -0
- package/dist/core/command/ids.js +87 -0
- package/dist/core/command/ids.js.map +1 -0
- package/dist/core/command/parser.d.ts +17 -0
- package/dist/core/command/parser.d.ts.map +1 -0
- package/dist/core/command/parser.js +65 -0
- package/dist/core/command/parser.js.map +1 -0
- package/dist/core/command/request.d.ts +61 -0
- package/dist/core/command/request.d.ts.map +1 -0
- package/dist/core/command/request.js +64 -0
- package/dist/core/command/request.js.map +1 -0
- package/dist/core/command/responses.d.ts +70 -0
- package/dist/core/command/responses.d.ts.map +1 -0
- package/dist/core/command/responses.js +88 -0
- package/dist/core/command/responses.js.map +1 -0
- package/dist/core/command-name.d.ts +349 -0
- package/dist/core/command-name.d.ts.map +1 -0
- package/dist/core/command-name.js +347 -0
- package/dist/core/command-name.js.map +1 -0
- package/dist/core/enums.d.ts +188 -0
- package/dist/core/enums.d.ts.map +1 -0
- package/dist/core/enums.js +172 -0
- package/dist/core/enums.js.map +1 -0
- package/dist/core/errorcode.d.ts +413 -0
- package/dist/core/errorcode.d.ts.map +1 -0
- package/dist/core/errorcode.js +410 -0
- package/dist/core/errorcode.js.map +1 -0
- package/dist/core/errors.d.ts +119 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +241 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events.d.ts +391 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +6 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/helpers.d.ts +42 -0
- package/dist/core/helpers.d.ts.map +1 -0
- package/dist/core/helpers.js +156 -0
- package/dist/core/helpers.js.map +1 -0
- package/dist/core/index.d.ts +40 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +39 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/internal.d.ts +24 -0
- package/dist/core/internal.d.ts.map +1 -0
- package/dist/core/internal.js +21 -0
- package/dist/core/internal.js.map +1 -0
- package/dist/core/middleware.d.ts +14 -0
- package/dist/core/middleware.d.ts.map +1 -0
- package/dist/core/middleware.js +18 -0
- package/dist/core/middleware.js.map +1 -0
- package/dist/core/notification-name.d.ts +160 -0
- package/dist/core/notification-name.d.ts.map +1 -0
- package/dist/core/notification-name.js +158 -0
- package/dist/core/notification-name.js.map +1 -0
- package/dist/core/notifications.d.ts +93 -0
- package/dist/core/notifications.d.ts.map +1 -0
- package/dist/core/notifications.js +301 -0
- package/dist/core/notifications.js.map +1 -0
- package/dist/core/permission-name.d.ts +1046 -0
- package/dist/core/permission-name.d.ts.map +1 -0
- package/dist/core/permission-name.js +1045 -0
- package/dist/core/permission-name.js.map +1 -0
- package/dist/core/permission.d.ts +31 -0
- package/dist/core/permission.d.ts.map +1 -0
- package/dist/core/permission.js +20 -0
- package/dist/core/permission.js.map +1 -0
- package/dist/core/property-name.d.ts +403 -0
- package/dist/core/property-name.d.ts.map +1 -0
- package/dist/core/property-name.js +405 -0
- package/dist/core/property-name.js.map +1 -0
- package/dist/core/reason.d.ts +39 -0
- package/dist/core/reason.d.ts.map +1 -0
- package/dist/core/reason.js +36 -0
- package/dist/core/reason.js.map +1 -0
- package/dist/core/reconnect.d.ts +59 -0
- package/dist/core/reconnect.d.ts.map +1 -0
- package/dist/core/reconnect.js +55 -0
- package/dist/core/reconnect.js.map +1 -0
- package/dist/core/types.d.ts +122 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +27 -0
- package/dist/core/types.js.map +1 -0
- package/dist/query/client.d.ts +244 -0
- package/dist/query/client.d.ts.map +1 -0
- package/dist/query/client.js +1093 -0
- package/dist/query/client.js.map +1 -0
- package/dist/query/errors.d.ts +61 -0
- package/dist/query/errors.d.ts.map +1 -0
- package/dist/query/errors.js +100 -0
- package/dist/query/errors.js.map +1 -0
- package/dist/query/index.d.ts +36 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +34 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/knownhosts.d.ts +61 -0
- package/dist/query/knownhosts.d.ts.map +1 -0
- package/dist/query/knownhosts.js +223 -0
- package/dist/query/knownhosts.js.map +1 -0
- package/dist/query/lines.d.ts +14 -0
- package/dist/query/lines.d.ts.map +1 -0
- package/dist/query/lines.js +29 -0
- package/dist/query/lines.js.map +1 -0
- package/dist/query/options.d.ts +202 -0
- package/dist/query/options.d.ts.map +1 -0
- package/dist/query/options.js +251 -0
- package/dist/query/options.js.map +1 -0
- package/dist/query/reconnect.d.ts +29 -0
- package/dist/query/reconnect.d.ts.map +1 -0
- package/dist/query/reconnect.js +87 -0
- package/dist/query/reconnect.js.map +1 -0
- package/dist/query/ssh.d.ts +385 -0
- package/dist/query/ssh.d.ts.map +1 -0
- package/dist/query/ssh.js +257 -0
- package/dist/query/ssh.js.map +1 -0
- package/dist/query/stream.d.ts +38 -0
- package/dist/query/stream.d.ts.map +1 -0
- package/dist/query/stream.js +70 -0
- package/dist/query/stream.js.map +1 -0
- package/dist/query/tcp.d.ts +38 -0
- package/dist/query/tcp.d.ts.map +1 -0
- package/dist/query/tcp.js +53 -0
- package/dist/query/tcp.js.map +1 -0
- package/dist/query/transport.d.ts +36 -0
- package/dist/query/transport.d.ts.map +1 -0
- package/dist/query/transport.js +2 -0
- package/dist/query/transport.js.map +1 -0
- package/dist/query/web.d.ts +78 -0
- package/dist/query/web.d.ts.map +1 -0
- package/dist/query/web.js +157 -0
- package/dist/query/web.js.map +1 -0
- package/dist/versions/index.d.ts +3094 -0
- package/dist/versions/index.d.ts.map +1 -0
- package/dist/versions/index.js +9237 -0
- package/dist/versions/index.js.map +1 -0
- package/package.json +119 -4
- package/src/client/abort.ts +24 -0
- package/src/client/address.ts +74 -0
- package/src/client/api/avatars.ts +164 -0
- package/src/client/api/voice.ts +177 -0
- package/src/client/capabilities.ts +106 -0
- package/src/client/client.ts +1942 -0
- package/src/client/commands.ts +201 -0
- package/src/client/connection-info.ts +52 -0
- package/src/client/crypto/crypt-ops.ts +6 -0
- package/src/client/crypto/crypt.ts +275 -0
- package/src/client/crypto/eax.ts +152 -0
- package/src/client/crypto/identity.ts +484 -0
- package/src/client/crypto/index.ts +21 -0
- package/src/client/crypto/primitives.ts +141 -0
- package/src/client/diagnostics.ts +58 -0
- package/src/client/discovery/index.ts +1 -0
- package/src/client/discovery/resolver.ts +325 -0
- package/src/client/errors.ts +217 -0
- package/src/client/events.ts +12 -0
- package/src/client/handshake/crypt-handshake.ts +157 -0
- package/src/client/handshake/crypt-init2.ts +48 -0
- package/src/client/handshake/index.ts +3 -0
- package/src/client/handshake/license.ts +208 -0
- package/src/client/handshake.ts +150 -0
- package/src/client/helpers.ts +10 -0
- package/src/client/hooks.ts +30 -0
- package/src/client/index.ts +95 -0
- package/src/client/reconnect.ts +43 -0
- package/src/client/throttle.ts +92 -0
- package/src/client/trace.ts +237 -0
- package/src/client/transfer.ts +436 -0
- package/src/client/transport/generation-window.ts +108 -0
- package/src/client/transport/handler.ts +1021 -0
- package/src/client/transport/index.ts +14 -0
- package/src/client/transport/packet.ts +69 -0
- package/src/client/transport/quicklz.ts +209 -0
- package/src/client/transport/traffic.ts +116 -0
- package/src/client/types.ts +458 -0
- package/src/core/api/avatars.ts +40 -0
- package/src/core/api/channels.ts +420 -0
- package/src/core/api/clients.ts +1094 -0
- package/src/core/api/command.ts +737 -0
- package/src/core/api/credentials.ts +335 -0
- package/src/core/api/files.ts +411 -0
- package/src/core/api/groups.ts +730 -0
- package/src/core/api/icons.ts +175 -0
- package/src/core/api/instance.ts +369 -0
- package/src/core/api/moderation.ts +632 -0
- package/src/core/api/parse.ts +139 -0
- package/src/core/api/server.ts +769 -0
- package/src/core/command/command.ts +125 -0
- package/src/core/command/ids.ts +153 -0
- package/src/core/command/parser.ts +68 -0
- package/src/core/command/request.ts +119 -0
- package/src/core/command/responses.ts +140 -0
- package/src/core/command-name.ts +350 -0
- package/src/core/enums.ts +215 -0
- package/src/core/errorcode.ts +412 -0
- package/src/core/errors.ts +266 -0
- package/src/core/events.ts +418 -0
- package/src/core/helpers.ts +161 -0
- package/src/core/index.ts +152 -0
- package/src/core/internal.ts +24 -0
- package/src/core/middleware.ts +24 -0
- package/src/core/notification-name.ts +161 -0
- package/src/core/notifications.ts +404 -0
- package/src/core/permission-name.ts +1162 -0
- package/src/core/permission.ts +34 -0
- package/src/core/property-name.ts +411 -0
- package/src/core/reason.ts +38 -0
- package/src/core/reconnect.ts +98 -0
- package/src/core/types.ts +150 -0
- package/src/query/client.ts +1274 -0
- package/src/query/errors.ts +108 -0
- package/src/query/index.ts +66 -0
- package/src/query/knownhosts.ts +257 -0
- package/src/query/lines.ts +28 -0
- package/src/query/options.ts +448 -0
- package/src/query/reconnect.ts +84 -0
- package/src/query/ssh.ts +674 -0
- package/src/query/stream.ts +91 -0
- package/src/query/tcp.ts +85 -0
- package/src/query/transport.ts +35 -0
- package/src/query/web.ts +234 -0
- package/src/versions/index.ts +10774 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** The reason an aborted signal gives, as an error. */
|
|
2
|
+
export declare function abortReason(signal: AbortSignal): unknown;
|
|
3
|
+
/** Settle with `promise`, or reject as soon as `signal` aborts, whichever is first. */
|
|
4
|
+
export declare function abortable<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;
|
|
5
|
+
//# sourceMappingURL=abort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.d.ts","sourceRoot":"","sources":["../../src/client/abort.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAExD;AAED,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,CAiB7F"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** The reason an aborted signal gives, as an error. */
|
|
2
|
+
export function abortReason(signal) {
|
|
3
|
+
return signal.reason ?? new DOMException("This operation was aborted", "AbortError");
|
|
4
|
+
}
|
|
5
|
+
/** Settle with `promise`, or reject as soon as `signal` aborts, whichever is first. */
|
|
6
|
+
export function abortable(promise, signal) {
|
|
7
|
+
if (!signal)
|
|
8
|
+
return promise;
|
|
9
|
+
if (signal.aborted)
|
|
10
|
+
return Promise.reject(abortReason(signal));
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
const onAbort = () => reject(abortReason(signal));
|
|
13
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
14
|
+
promise.then((value) => {
|
|
15
|
+
signal.removeEventListener("abort", onAbort);
|
|
16
|
+
resolve(value);
|
|
17
|
+
}, (error) => {
|
|
18
|
+
signal.removeEventListener("abort", onAbort);
|
|
19
|
+
reject(error);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=abort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.js","sourceRoot":"","sources":["../../src/client/abort.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,OAAO,MAAM,CAAC,MAAM,IAAI,IAAI,YAAY,CAAC,4BAA4B,EAAE,YAAY,CAAC,CAAC;AACvF,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,SAAS,CAAI,OAAmB,EAAE,MAA+B;IAC/E,IAAI,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC;IAC5B,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,MAAM,OAAO,GAAG,GAAS,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QACxD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CACV,CAAC,KAAK,EAAE,EAAE;YACR,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;YACjB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface HostPort {
|
|
2
|
+
host: string;
|
|
3
|
+
port: string;
|
|
4
|
+
}
|
|
5
|
+
/** Parse a TeamSpeak address without confusing an IPv6 colon for a port separator. */
|
|
6
|
+
export declare function splitHostPort(address: string, defaultPort?: string): HostPort;
|
|
7
|
+
/**
|
|
8
|
+
* Parse an address to connect to, and check it can be one: a host, which
|
|
9
|
+
* contains nothing a host name or IP address cannot, and a port from 1 to
|
|
10
|
+
* 65535. Throws an InvalidAddressError otherwise.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseConnectAddress(address: string): HostPort & {
|
|
13
|
+
portNumber: number;
|
|
14
|
+
};
|
|
15
|
+
export declare function joinHostPort(host: string, port: string): string;
|
|
16
|
+
export declare function isIpAddress(host: string): boolean;
|
|
17
|
+
//# sourceMappingURL=address.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../src/client/address.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,SAAS,GAAG,QAAQ,CA0B7E;AAKD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAatF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
2
|
+
import { InvalidAddressError } from "./errors.js";
|
|
3
|
+
/** Parse a TeamSpeak address without confusing an IPv6 colon for a port separator. */
|
|
4
|
+
export function splitHostPort(address, defaultPort = "9987") {
|
|
5
|
+
const input = address.trim();
|
|
6
|
+
if (input.startsWith("[")) {
|
|
7
|
+
const closingBracket = input.indexOf("]");
|
|
8
|
+
if (closingBracket > 0) {
|
|
9
|
+
const host = input.slice(1, closingBracket);
|
|
10
|
+
const suffix = input.slice(closingBracket + 1);
|
|
11
|
+
if (suffix.startsWith(":") && /^\d+$/.test(suffix.slice(1))) {
|
|
12
|
+
return { host, port: suffix.slice(1) };
|
|
13
|
+
}
|
|
14
|
+
if (!suffix)
|
|
15
|
+
return { host, port: defaultPort };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// A raw IPv6 literal has no unambiguous port separator. Internal callers
|
|
19
|
+
// normally use bracket notation, but accepting the literal with the default
|
|
20
|
+
// port prevents a final IPv6 segment from being mistaken for a port.
|
|
21
|
+
if (isIP(input) === 6)
|
|
22
|
+
return { host: input, port: defaultPort };
|
|
23
|
+
const lastColon = input.lastIndexOf(":");
|
|
24
|
+
if (lastColon < 0)
|
|
25
|
+
return { host: input, port: defaultPort };
|
|
26
|
+
const candidatePort = input.slice(lastColon + 1);
|
|
27
|
+
if (/^\d+$/.test(candidatePort) && input.indexOf(":") === lastColon) {
|
|
28
|
+
return { host: input.slice(0, lastColon), port: candidatePort };
|
|
29
|
+
}
|
|
30
|
+
return { host: input, port: defaultPort };
|
|
31
|
+
}
|
|
32
|
+
/** Characters no host name or IP address contains, whitespace among them. */
|
|
33
|
+
const NOT_IN_A_HOST = /[\s\p{Cc}/?#@[\]\\]/u;
|
|
34
|
+
/**
|
|
35
|
+
* Parse an address to connect to, and check it can be one: a host, which
|
|
36
|
+
* contains nothing a host name or IP address cannot, and a port from 1 to
|
|
37
|
+
* 65535. Throws an InvalidAddressError otherwise.
|
|
38
|
+
*/
|
|
39
|
+
export function parseConnectAddress(address) {
|
|
40
|
+
const { host, port } = splitHostPort(address);
|
|
41
|
+
if (host === "")
|
|
42
|
+
throw new InvalidAddressError(address, "no host");
|
|
43
|
+
// A colon is left only in an IPv6 literal; anywhere else it is a port that
|
|
44
|
+
// is not a number, which splitHostPort keeps as part of the host.
|
|
45
|
+
if (NOT_IN_A_HOST.test(host) || (host.includes(":") && isIP(host) !== 6)) {
|
|
46
|
+
throw new InvalidAddressError(address, "not a host name, IP address or host:port");
|
|
47
|
+
}
|
|
48
|
+
const portNumber = Number(port);
|
|
49
|
+
if (!Number.isInteger(portNumber) || portNumber < 1 || portNumber > 65535) {
|
|
50
|
+
throw new InvalidAddressError(address, `port ${port} is not from 1 to 65535`);
|
|
51
|
+
}
|
|
52
|
+
return { host, port, portNumber };
|
|
53
|
+
}
|
|
54
|
+
export function joinHostPort(host, port) {
|
|
55
|
+
const normalizedHost = stripBrackets(host);
|
|
56
|
+
return isIP(normalizedHost) === 6 || normalizedHost.includes(":")
|
|
57
|
+
? `[${normalizedHost}]:${port}`
|
|
58
|
+
: `${normalizedHost}:${port}`;
|
|
59
|
+
}
|
|
60
|
+
export function isIpAddress(host) {
|
|
61
|
+
return isIP(stripBrackets(host)) !== 0;
|
|
62
|
+
}
|
|
63
|
+
function stripBrackets(host) {
|
|
64
|
+
return host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../src/client/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAOlD,sFAAsF;AACtF,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,WAAW,GAAG,MAAM;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;YAC/C,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,CAAC;YACD,IAAI,CAAC,MAAM;gBAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,4EAA4E;IAC5E,qEAAqE;IACrE,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAEjE,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC7D,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACjD,IAAI,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;QACpE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IAClE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AAC5C,CAAC;AAED,6EAA6E;AAC7E,MAAM,aAAa,GAAG,sBAAsB,CAAC;AAE7C;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,EAAE;QAAE,MAAM,IAAI,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACnE,2EAA2E;IAC3E,kEAAkE;IAClE,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,mBAAmB,CAAC,OAAO,EAAE,0CAA0C,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,KAAK,EAAE,CAAC;QAC1E,MAAM,IAAI,mBAAmB,CAAC,OAAO,EAAE,QAAQ,IAAI,yBAAyB,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,IAAY;IACrD,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC/D,CAAC,CAAC,IAAI,cAAc,KAAK,IAAI,EAAE;QAC/B,CAAC,CAAC,GAAG,cAAc,IAAI,IAAI,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/E,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avatars and icons: the file transfers behind them.
|
|
3
|
+
*
|
|
4
|
+
* Both live in channel 0's file area, so each helper negotiates a transfer
|
|
5
|
+
* (`ftinitupload`, `ftinitdownload`) and moves the bytes over the client's own
|
|
6
|
+
* file transfer connection, as `Client.uploadFileData` does.
|
|
7
|
+
*/
|
|
8
|
+
import type { IconID, UID } from "@honeybbq/teamspeak";
|
|
9
|
+
import type { Client } from "../client.js";
|
|
10
|
+
import type { FileTransferOptions } from "../transfer.js";
|
|
11
|
+
/** Options for the avatar and icon transfers. */
|
|
12
|
+
export type AvatarTransferOptions = Pick<FileTransferOptions, "signal" | "trace">;
|
|
13
|
+
/**
|
|
14
|
+
* Upload `data` as this client's avatar and set `client_flag_avatar` to its
|
|
15
|
+
* MD5, so that other clients see the change in a `clientUpdated` event.
|
|
16
|
+
*
|
|
17
|
+
* On the wire: `ftinitupload cid=0 name=/avatar_<md5 hex>` with `overwrite=1`,
|
|
18
|
+
* the bytes over the file transfer port, then
|
|
19
|
+
* `clientupdate client_flag_avatar=<md5>`. The server does not keep the file under the MD5
|
|
20
|
+
* name: it stores it as {@link avatarFileName} of the client's unique id (20
|
|
21
|
+
* bytes of SHA-1 on TeamSpeak 3, 32 of SHA-256 on TeamSpeak 6). Returns the
|
|
22
|
+
* MD5, lower-case hex.
|
|
23
|
+
*
|
|
24
|
+
* The size limit is the permission `i_client_max_avatar_filesize`, 200000
|
|
25
|
+
* bytes for a Server Admin; over it, the negotiation fails with a ServerError
|
|
26
|
+
* 2565 (invalid size) and nothing is sent or changed. A file of exactly the
|
|
27
|
+
* limit passes.
|
|
28
|
+
*/
|
|
29
|
+
export declare function uploadAvatar(client: Client, data: Uint8Array, options?: AvatarTransferOptions): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* The bytes of the avatar of the client with this unique id, or undefined when
|
|
32
|
+
* the server has no avatar file for it (`ftinitdownload cid=0` with the name
|
|
33
|
+
* from {@link avatarFileName}; error 2051 on TeamSpeak 6, 2054 on
|
|
34
|
+
* TeamSpeak 3). Setting the flag empty alone leaves the file in place;
|
|
35
|
+
* `removeAvatar` deletes it.
|
|
36
|
+
*/
|
|
37
|
+
export declare function downloadAvatar(client: Client, uid: UID | string, options?: AvatarTransferOptions): Promise<Uint8Array | undefined>;
|
|
38
|
+
/**
|
|
39
|
+
* Remove this client's own avatar: `ftdeletefile cid=0 name=/avatar_`, which,
|
|
40
|
+
* as measured on both servers, deletes the caller's stored avatar file and
|
|
41
|
+
* empties `client_flag_avatar`. Deleting the file by its stored name was
|
|
42
|
+
* refused with 1540, and TS6's `clientavatardeleted` (given `cluid`) answered
|
|
43
|
+
* OK without removing it; this is the removal that worked.
|
|
44
|
+
* Resolves with true when an avatar was removed, false when there was none
|
|
45
|
+
* (error 2054).
|
|
46
|
+
*/
|
|
47
|
+
export declare function removeAvatar(client: Client, options?: AvatarTransferOptions): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Upload `data` as an icon and return its id, the CRC-32 of the bytes
|
|
50
|
+
* ({@link iconIDOf}).
|
|
51
|
+
*
|
|
52
|
+
* On the wire: `ftinitupload cid=0 name=/icon_<id>` with `overwrite=1`, then
|
|
53
|
+
* the bytes; the server keeps it in channel 0's `icons` directory. The id is
|
|
54
|
+
* not checked by the server against the bytes, and the file does not
|
|
55
|
+
* reference anything by itself: pass the id to `setChannelIcon`, `setServerGroupIcon`,
|
|
56
|
+
* `setChannelGroupIcon`, `setClientIcon` or `setServerIcon`.
|
|
57
|
+
*
|
|
58
|
+
* Needs `b_icon_manage` (error 2568 without it). The size limit is
|
|
59
|
+
* `i_max_icon_filesize`, 8192 bytes for a Server Admin; over it, the
|
|
60
|
+
* negotiation fails with a ServerError 2565 (invalid size).
|
|
61
|
+
*/
|
|
62
|
+
export declare function uploadIcon(client: Client, data: Uint8Array, options?: AvatarTransferOptions): Promise<IconID>;
|
|
63
|
+
/** The bytes of an icon, or undefined when the server has no file for the id. */
|
|
64
|
+
export declare function downloadIcon(client: Client, id: IconID, options?: AvatarTransferOptions): Promise<Uint8Array | undefined>;
|
|
65
|
+
//# sourceMappingURL=avatars.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatars.d.ts","sourceRoot":"","sources":["../../../src/client/api/avatars.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,iDAAiD;AACjD,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,mBAAmB,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC;AAiClF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CASjB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,GAAG,MAAM,EACjB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEjC;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,iFAAiF;AACjF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEjC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avatars and icons: the file transfers behind them.
|
|
3
|
+
*
|
|
4
|
+
* Both live in channel 0's file area, so each helper negotiates a transfer
|
|
5
|
+
* (`ftinitupload`, `ftinitdownload`) and moves the bytes over the client's own
|
|
6
|
+
* file transfer connection, as `Client.uploadFileData` does.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import { Readable, Writable } from "node:stream";
|
|
10
|
+
import { ErrorCode, ServerError, asChannelID, avatarFileName, deleteFile, iconFileName, iconIDOf, initFileDownload, initFileUpload, updateClient, } from "@honeybbq/teamspeak";
|
|
11
|
+
const CHANNEL_ZERO = asChannelID(0n);
|
|
12
|
+
async function download(client, name, options) {
|
|
13
|
+
let info;
|
|
14
|
+
try {
|
|
15
|
+
info = await initFileDownload(client, CHANNEL_ZERO, name, options);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
// TeamSpeak 6 answers 2051 for a file that is not there, TeamSpeak 3 2054.
|
|
19
|
+
if (error instanceof ServerError &&
|
|
20
|
+
(error.code === ErrorCode.FileNotFound || error.code === ErrorCode.FileInvalidPath)) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
const chunks = [];
|
|
26
|
+
const sink = new Writable({
|
|
27
|
+
write(chunk, _encoding, done) {
|
|
28
|
+
chunks.push(chunk);
|
|
29
|
+
done();
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
await client.downloadFileData(client.host, info, sink, options);
|
|
33
|
+
return new Uint8Array(Buffer.concat(chunks));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Upload `data` as this client's avatar and set `client_flag_avatar` to its
|
|
37
|
+
* MD5, so that other clients see the change in a `clientUpdated` event.
|
|
38
|
+
*
|
|
39
|
+
* On the wire: `ftinitupload cid=0 name=/avatar_<md5 hex>` with `overwrite=1`,
|
|
40
|
+
* the bytes over the file transfer port, then
|
|
41
|
+
* `clientupdate client_flag_avatar=<md5>`. The server does not keep the file under the MD5
|
|
42
|
+
* name: it stores it as {@link avatarFileName} of the client's unique id (20
|
|
43
|
+
* bytes of SHA-1 on TeamSpeak 3, 32 of SHA-256 on TeamSpeak 6). Returns the
|
|
44
|
+
* MD5, lower-case hex.
|
|
45
|
+
*
|
|
46
|
+
* The size limit is the permission `i_client_max_avatar_filesize`, 200000
|
|
47
|
+
* bytes for a Server Admin; over it, the negotiation fails with a ServerError
|
|
48
|
+
* 2565 (invalid size) and nothing is sent or changed. A file of exactly the
|
|
49
|
+
* limit passes.
|
|
50
|
+
*/
|
|
51
|
+
export async function uploadAvatar(client, data, options = {}) {
|
|
52
|
+
const md5 = createHash("md5").update(data).digest("hex");
|
|
53
|
+
const info = await initFileUpload(client, CHANNEL_ZERO, `/avatar_${md5}`, BigInt(data.length), {
|
|
54
|
+
overwrite: true,
|
|
55
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
56
|
+
});
|
|
57
|
+
await client.uploadFileData(client.host, info, Readable.from([data]), options);
|
|
58
|
+
await updateClient(client, { avatar: md5 });
|
|
59
|
+
return md5;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The bytes of the avatar of the client with this unique id, or undefined when
|
|
63
|
+
* the server has no avatar file for it (`ftinitdownload cid=0` with the name
|
|
64
|
+
* from {@link avatarFileName}; error 2051 on TeamSpeak 6, 2054 on
|
|
65
|
+
* TeamSpeak 3). Setting the flag empty alone leaves the file in place;
|
|
66
|
+
* `removeAvatar` deletes it.
|
|
67
|
+
*/
|
|
68
|
+
export function downloadAvatar(client, uid, options = {}) {
|
|
69
|
+
return download(client, `/${avatarFileName(uid)}`, options);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Remove this client's own avatar: `ftdeletefile cid=0 name=/avatar_`, which,
|
|
73
|
+
* as measured on both servers, deletes the caller's stored avatar file and
|
|
74
|
+
* empties `client_flag_avatar`. Deleting the file by its stored name was
|
|
75
|
+
* refused with 1540, and TS6's `clientavatardeleted` (given `cluid`) answered
|
|
76
|
+
* OK without removing it; this is the removal that worked.
|
|
77
|
+
* Resolves with true when an avatar was removed, false when there was none
|
|
78
|
+
* (error 2054).
|
|
79
|
+
*/
|
|
80
|
+
export async function removeAvatar(client, options = {}) {
|
|
81
|
+
try {
|
|
82
|
+
await deleteFile(client, CHANNEL_ZERO, "/avatar_", options);
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error instanceof ServerError && error.code === ErrorCode.FileInvalidPath)
|
|
87
|
+
return false;
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Upload `data` as an icon and return its id, the CRC-32 of the bytes
|
|
93
|
+
* ({@link iconIDOf}).
|
|
94
|
+
*
|
|
95
|
+
* On the wire: `ftinitupload cid=0 name=/icon_<id>` with `overwrite=1`, then
|
|
96
|
+
* the bytes; the server keeps it in channel 0's `icons` directory. The id is
|
|
97
|
+
* not checked by the server against the bytes, and the file does not
|
|
98
|
+
* reference anything by itself: pass the id to `setChannelIcon`, `setServerGroupIcon`,
|
|
99
|
+
* `setChannelGroupIcon`, `setClientIcon` or `setServerIcon`.
|
|
100
|
+
*
|
|
101
|
+
* Needs `b_icon_manage` (error 2568 without it). The size limit is
|
|
102
|
+
* `i_max_icon_filesize`, 8192 bytes for a Server Admin; over it, the
|
|
103
|
+
* negotiation fails with a ServerError 2565 (invalid size).
|
|
104
|
+
*/
|
|
105
|
+
export async function uploadIcon(client, data, options = {}) {
|
|
106
|
+
const id = iconIDOf(data);
|
|
107
|
+
const info = await initFileUpload(client, CHANNEL_ZERO, iconFileName(id), BigInt(data.length), {
|
|
108
|
+
overwrite: true,
|
|
109
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
110
|
+
});
|
|
111
|
+
await client.uploadFileData(client.host, info, Readable.from([data]), options);
|
|
112
|
+
return id;
|
|
113
|
+
}
|
|
114
|
+
/** The bytes of an icon, or undefined when the server has no file for the id. */
|
|
115
|
+
export function downloadIcon(client, id, options = {}) {
|
|
116
|
+
return download(client, iconFileName(id), options);
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=avatars.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatars.js","sourceRoot":"","sources":["../../../src/client/api/avatars.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commands only the voice protocol has.
|
|
3
|
+
*
|
|
4
|
+
* ServerQuery has no subscriptions — a query client hears every channel's
|
|
5
|
+
* events once it registers for them — and no `channelgetdescription`, since its
|
|
6
|
+
* `channelinfo` already carries the description. These run on the voice
|
|
7
|
+
* client alone, which is why they take one rather than any CommandExecutor.
|
|
8
|
+
*/
|
|
9
|
+
import type { Client } from "../client.js";
|
|
10
|
+
import type { ChannelID, ClientID, CommandOptions } from "@honeybbq/teamspeak";
|
|
11
|
+
/**
|
|
12
|
+
* The channel's description, which `listChannels` omits for bandwidth. The
|
|
13
|
+
* server answers with a `notifychanneledited` that the client does not report as
|
|
14
|
+
* a `channelEdited` event, since it is no edit.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getChannelDescription(client: Client, cid: ChannelID, options?: CommandOptions): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Subscribe to a channel: receive its clients' events and voice without
|
|
19
|
+
* joining it.
|
|
20
|
+
*/
|
|
21
|
+
export declare function subscribeChannel(client: Client, cid: ChannelID, options?: CommandOptions): Promise<void>;
|
|
22
|
+
/** Stop receiving a subscribed channel's events and voice. */
|
|
23
|
+
export declare function unsubscribeChannel(client: Client, cid: ChannelID, options?: CommandOptions): Promise<void>;
|
|
24
|
+
/** Subscribe to every channel on the server. */
|
|
25
|
+
export declare function subscribeAllChannels(client: Client, options?: CommandOptions): Promise<void>;
|
|
26
|
+
/** Unsubscribe from every channel on the server. */
|
|
27
|
+
export declare function unsubscribeAllChannels(client: Client, options?: CommandOptions): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Whether `password` is the server's password (`verifyserverpassword`),
|
|
30
|
+
* without joining. The password is given in cleartext; the client hashes it
|
|
31
|
+
* on the wire. The server answers a match with plain success and a mismatch
|
|
32
|
+
* with error 1028 (`ErrorCode.ServerInvalidPassword`), which this turns into
|
|
33
|
+
* `false`; any other error is thrown. Measured on TeamSpeak 3 and 6.
|
|
34
|
+
*/
|
|
35
|
+
export declare function verifyServerPassword(client: Client, password: string, options?: CommandOptions): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether `password` is channel `cid`'s password (`verifychannelpassword`),
|
|
38
|
+
* without moving. The password is given in cleartext; the client hashes it
|
|
39
|
+
* on the wire, as `moveClient` does. A mismatch is error 781
|
|
40
|
+
* (`ErrorCode.ChannelInvalidPassword`) and answers `false`; a channel without
|
|
41
|
+
* a password accepts any value and answers `true`; an unknown channel is
|
|
42
|
+
* error 768, thrown. Measured on TeamSpeak 3 and 6.
|
|
43
|
+
*/
|
|
44
|
+
export declare function verifyChannelPassword(client: Client, cid: ChannelID, password: string, options?: CommandOptions): Promise<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* Stop hearing the given clients (`clientmute`): the server no longer forwards
|
|
47
|
+
* their voice to this client. It is per listener, so everyone else still hears
|
|
48
|
+
* them, and it sends no notification and changes no client property. Several
|
|
49
|
+
* clients go in one command. The server accepts this client's own id and ids
|
|
50
|
+
* of clients that are not connected without an error. Undo it with
|
|
51
|
+
* `unmuteClients`. Measured on TeamSpeak 3 and 6.
|
|
52
|
+
*/
|
|
53
|
+
export declare function muteClients(client: Client, clientIDs: readonly ClientID[], options?: CommandOptions): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Hear the given clients again (`clientunmute`): the server resumes forwarding
|
|
56
|
+
* their voice to this client after `muteClients`. Measured on TeamSpeak 3 and 6.
|
|
57
|
+
*/
|
|
58
|
+
export declare function unmuteClients(client: Client, clientIDs: readonly ClientID[], options?: CommandOptions): Promise<void>;
|
|
59
|
+
//# sourceMappingURL=voice.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commands only the voice protocol has.
|
|
3
|
+
*
|
|
4
|
+
* ServerQuery has no subscriptions — a query client hears every channel's
|
|
5
|
+
* events once it registers for them — and no `channelgetdescription`, since its
|
|
6
|
+
* `channelinfo` already carries the description. These run on the voice
|
|
7
|
+
* client alone, which is why they take one rather than any CommandExecutor.
|
|
8
|
+
*/
|
|
9
|
+
import { ErrorCode, ServerError } from "@honeybbq/teamspeak";
|
|
10
|
+
/**
|
|
11
|
+
* The channel's description, which `listChannels` omits for bandwidth. The
|
|
12
|
+
* server answers with a `notifychanneledited` that the client does not report as
|
|
13
|
+
* a `channelEdited` event, since it is no edit.
|
|
14
|
+
*/
|
|
15
|
+
export async function getChannelDescription(client, cid, options) {
|
|
16
|
+
const rows = await client.send({ command: "channelgetdescription", params: [["cid", cid]] }, options);
|
|
17
|
+
// The answer is the row that holds the text. Another `notifychanneledited`
|
|
18
|
+
// can arrive while the command waits, a real edit with other properties,
|
|
19
|
+
// and the first row is then not the answer.
|
|
20
|
+
const answer = rows.find((row) => row["cid"] === String(cid) && "channel_description" in row);
|
|
21
|
+
return answer?.["channel_description"] ?? "";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Subscribe to a channel: receive its clients' events and voice without
|
|
25
|
+
* joining it.
|
|
26
|
+
*/
|
|
27
|
+
export async function subscribeChannel(client, cid, options) {
|
|
28
|
+
await client.send({ command: "channelsubscribe", params: [["cid", cid]] }, options);
|
|
29
|
+
}
|
|
30
|
+
/** Stop receiving a subscribed channel's events and voice. */
|
|
31
|
+
export async function unsubscribeChannel(client, cid, options) {
|
|
32
|
+
await client.send({ command: "channelunsubscribe", params: [["cid", cid]] }, options);
|
|
33
|
+
}
|
|
34
|
+
/** Subscribe to every channel on the server. */
|
|
35
|
+
export async function subscribeAllChannels(client, options) {
|
|
36
|
+
await client.send({ command: "channelsubscribeall" }, options);
|
|
37
|
+
}
|
|
38
|
+
/** Unsubscribe from every channel on the server. */
|
|
39
|
+
export async function unsubscribeAllChannels(client, options) {
|
|
40
|
+
await client.send({ command: "channelunsubscribeall" }, options);
|
|
41
|
+
}
|
|
42
|
+
/** Answers a password check: true for a match, false for the mismatch error, any other error rethrown. */
|
|
43
|
+
async function passwordMatches(run, mismatch) {
|
|
44
|
+
try {
|
|
45
|
+
await run();
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error instanceof ServerError && error.code === mismatch)
|
|
50
|
+
return false;
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Whether `password` is the server's password (`verifyserverpassword`),
|
|
56
|
+
* without joining. The password is given in cleartext; the client hashes it
|
|
57
|
+
* on the wire. The server answers a match with plain success and a mismatch
|
|
58
|
+
* with error 1028 (`ErrorCode.ServerInvalidPassword`), which this turns into
|
|
59
|
+
* `false`; any other error is thrown. Measured on TeamSpeak 3 and 6.
|
|
60
|
+
*/
|
|
61
|
+
export function verifyServerPassword(client, password, options) {
|
|
62
|
+
return passwordMatches(() => client.send({
|
|
63
|
+
command: "verifyserverpassword",
|
|
64
|
+
params: [["password", password]],
|
|
65
|
+
passwords: ["password"],
|
|
66
|
+
}, options), ErrorCode.ServerInvalidPassword);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Whether `password` is channel `cid`'s password (`verifychannelpassword`),
|
|
70
|
+
* without moving. The password is given in cleartext; the client hashes it
|
|
71
|
+
* on the wire, as `moveClient` does. A mismatch is error 781
|
|
72
|
+
* (`ErrorCode.ChannelInvalidPassword`) and answers `false`; a channel without
|
|
73
|
+
* a password accepts any value and answers `true`; an unknown channel is
|
|
74
|
+
* error 768, thrown. Measured on TeamSpeak 3 and 6.
|
|
75
|
+
*/
|
|
76
|
+
export function verifyChannelPassword(client, cid, password, options) {
|
|
77
|
+
return passwordMatches(() => client.send({
|
|
78
|
+
command: "verifychannelpassword",
|
|
79
|
+
params: [
|
|
80
|
+
["cid", cid],
|
|
81
|
+
["password", password],
|
|
82
|
+
],
|
|
83
|
+
passwords: ["password"],
|
|
84
|
+
}, options), ErrorCode.ChannelInvalidPassword);
|
|
85
|
+
}
|
|
86
|
+
/** The clients of a mute, one `clid` row each; an empty list sends nothing. */
|
|
87
|
+
async function sendMute(client, command, clientIDs, options) {
|
|
88
|
+
if (clientIDs.length === 0)
|
|
89
|
+
return;
|
|
90
|
+
await client.send({ command, rows: clientIDs.map((clid) => [["clid", clid]]) }, options);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Stop hearing the given clients (`clientmute`): the server no longer forwards
|
|
94
|
+
* their voice to this client. It is per listener, so everyone else still hears
|
|
95
|
+
* them, and it sends no notification and changes no client property. Several
|
|
96
|
+
* clients go in one command. The server accepts this client's own id and ids
|
|
97
|
+
* of clients that are not connected without an error. Undo it with
|
|
98
|
+
* `unmuteClients`. Measured on TeamSpeak 3 and 6.
|
|
99
|
+
*/
|
|
100
|
+
export function muteClients(client, clientIDs, options) {
|
|
101
|
+
return sendMute(client, "clientmute", clientIDs, options);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Hear the given clients again (`clientunmute`): the server resumes forwarding
|
|
105
|
+
* their voice to this client after `muteClients`. Measured on TeamSpeak 3 and 6.
|
|
106
|
+
*/
|
|
107
|
+
export function unmuteClients(client, clientIDs, options) {
|
|
108
|
+
return sendMute(client, "clientunmute", clientIDs, options);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=voice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice.js","sourceRoot":"","sources":["../../../src/client/api/voice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the connected server is, and what that means for the caller.
|
|
3
|
+
*
|
|
4
|
+
* TS3 and TS6 differ in ways that stay invisible until something breaks. The
|
|
5
|
+
* clearest: the server hashes a client's public key with SHA-1 on TS3 and
|
|
6
|
+
* SHA-256 on TS6, so a client that assumes either one computes a
|
|
7
|
+
* `client_unique_identifier` the other server never sends.
|
|
8
|
+
*
|
|
9
|
+
* Everything below comes from the handshake — `initserver` carries
|
|
10
|
+
* `virtualserver_version`, the one place the server names itself, along with
|
|
11
|
+
* its name, icon, banner and welcome message — so reading it costs no extra
|
|
12
|
+
* round trip.
|
|
13
|
+
*/
|
|
14
|
+
import { type IconID, type ServerFamily, type ServerID } from "@honeybbq/teamspeak";
|
|
15
|
+
import { type UIDAlgorithm } from "./crypto/identity.js";
|
|
16
|
+
/** What a server said about itself in the handshake. */
|
|
17
|
+
export interface ServerCapabilities {
|
|
18
|
+
/** The `virtualserver_version` string, exactly as the server sent it. */
|
|
19
|
+
readonly version: string;
|
|
20
|
+
/** Major version number, or 0 when it could not be parsed. */
|
|
21
|
+
readonly major: number;
|
|
22
|
+
/** Which server generation this is. */
|
|
23
|
+
readonly family: ServerFamily;
|
|
24
|
+
/**
|
|
25
|
+
* The hash the server uses for `client_unique_identifier`.
|
|
26
|
+
*
|
|
27
|
+
* Read from the family rather than offered as a setting: the server decides
|
|
28
|
+
* this, and a client that picks differently never matches.
|
|
29
|
+
*/
|
|
30
|
+
readonly uidAlgorithm: UIDAlgorithm;
|
|
31
|
+
/** The virtual server's name (`virtualserver_name`). */
|
|
32
|
+
readonly name: string;
|
|
33
|
+
/**
|
|
34
|
+
* The server's icon (`virtualserver_icon_id`), or `undefined` for none. The
|
|
35
|
+
* server sends the icon's CRC32, sometimes as a negative 32-bit number; this
|
|
36
|
+
* is the unsigned value, which names the icon file.
|
|
37
|
+
*/
|
|
38
|
+
readonly iconID: IconID | undefined;
|
|
39
|
+
/** The host banner image's URL (`virtualserver_hostbanner_gfx_url`), if one is set. */
|
|
40
|
+
readonly hostBannerImageURL: string | undefined;
|
|
41
|
+
/** The welcome message shown on connecting (`virtualserver_welcomemessage`). */
|
|
42
|
+
readonly welcomeMessage: string;
|
|
43
|
+
/** The virtual server's ID (`virtualserver_id`); 0 when the server did not send it. */
|
|
44
|
+
readonly serverID: ServerID;
|
|
45
|
+
/** The virtual server's unique identifier (`virtualserver_unique_identifier`); empty when not sent. */
|
|
46
|
+
readonly serverUID: string;
|
|
47
|
+
/** The host message (`virtualserver_hostmessage`) the server wants shown on connecting. */
|
|
48
|
+
readonly hostMessage: string;
|
|
49
|
+
/**
|
|
50
|
+
* How the host message is to be shown (`virtualserver_hostmessage_mode`).
|
|
51
|
+
* Compare it with `HostMessageMode`; a server may send a value the table
|
|
52
|
+
* does not name.
|
|
53
|
+
*/
|
|
54
|
+
readonly hostMessageMode: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Read what a server says about itself in `initserver`, or a version string
|
|
58
|
+
* alone, such as "6.0.0-beta13.1 [Build: 1]".
|
|
59
|
+
*/
|
|
60
|
+
export declare function parseServerCapabilities(initserver: string | Readonly<Record<string, string>>): ServerCapabilities;
|
|
61
|
+
/**
|
|
62
|
+
* Capabilities of a server that has not been connected to yet.
|
|
63
|
+
*
|
|
64
|
+
* The family is `unknown` — nothing has said which server this is — and
|
|
65
|
+
* `uidAlgorithm` is SHA-1, the TS3 hash.
|
|
66
|
+
*/
|
|
67
|
+
export declare function unknownServerCapabilities(): ServerCapabilities;
|
|
68
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/client/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAc,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEhG,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEjF,wDAAwD;AACxD,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,uFAAuF;IACvF,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,gFAAgF;IAChF,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,uGAAuG;IACvG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2FAA2F;IAC3F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACpD,kBAAkB,CAyBpB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,kBAAkB,CAE9D"}
|