@honeybbq/teamspeak 0.0.1 → 1.0.0-beta.11
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 +235 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +1666 -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 +28 -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 +402 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +113 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/view.d.ts +162 -0
- package/dist/client/view.d.ts.map +1 -0
- package/dist/client/view.js +228 -0
- package/dist/client/view.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 +562 -0
- package/dist/core/api/clients.d.ts.map +1 -0
- package/dist/core/api/clients.js +435 -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/channel-tree.d.ts +87 -0
- package/dist/core/channel-tree.d.ts.map +1 -0
- package/dist/core/channel-tree.js +378 -0
- package/dist/core/channel-tree.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 +73 -0
- package/dist/core/command/responses.d.ts.map +1 -0
- package/dist/core/command/responses.js +97 -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 +404 -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 +41 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +40 -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 +1122 -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 +206 -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 +1976 -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 +97 -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 +478 -0
- package/src/client/view.ts +372 -0
- package/src/core/api/avatars.ts +40 -0
- package/src/core/api/channels.ts +420 -0
- package/src/core/api/clients.ts +1098 -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/channel-tree.ts +398 -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 +152 -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 +431 -0
- package/src/core/helpers.ts +161 -0
- package/src/core/index.ts +153 -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 +1303 -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 +452 -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,68 @@
|
|
|
1
|
+
import { unescape } from "./command.js";
|
|
2
|
+
import type { Command } from "./command.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Whether a token is a command name.
|
|
6
|
+
*
|
|
7
|
+
* A command name is a run of ASCII alphanumerics — the rule tsproto-packets
|
|
8
|
+
* uses (CommandParser::new). Everything that splits or parses a line asks this
|
|
9
|
+
* one function, so the parser and the row splitter cannot disagree about where
|
|
10
|
+
* a command's data begins.
|
|
11
|
+
*/
|
|
12
|
+
export function isCommandName(token: string): boolean {
|
|
13
|
+
return /^[A-Za-z0-9]+$/.test(token);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Parse one command line, or one row of it. Returns null for an empty line.
|
|
18
|
+
* A line whose first token is not a command name is a data row, with `name`
|
|
19
|
+
* `""`.
|
|
20
|
+
*/
|
|
21
|
+
export function parseCommand(s: string): Command | null {
|
|
22
|
+
if (s === "") return null;
|
|
23
|
+
|
|
24
|
+
// Skip leading non-printable bytes (< 0x20 or > 0x7E)
|
|
25
|
+
let startIndex = 0;
|
|
26
|
+
for (let i = 0; i < s.length; i++) {
|
|
27
|
+
const code = s.charCodeAt(i);
|
|
28
|
+
if (code >= 32 && code <= 126) {
|
|
29
|
+
startIndex = i;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (startIndex > 0) {
|
|
34
|
+
s = s.slice(startIndex);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const parts = s.split(" ");
|
|
38
|
+
if (parts.length === 0) return null;
|
|
39
|
+
|
|
40
|
+
// A command name is a run of alphanumerics followed by a space — the rule
|
|
41
|
+
// tsproto-packets uses (CommandParser::new). Anything else means the line is
|
|
42
|
+
// not a command at all: response rows carry no name ("clid=6 cid=2 ..."),
|
|
43
|
+
// and negative feedback is "-1 id=2 ...", naming the *rejected* command id
|
|
44
|
+
// rather than a command of its own. Returning those as a nameless row keeps
|
|
45
|
+
// the data intact instead of folding the first field into a name, which is
|
|
46
|
+
// how a clientlist row used to arrive as name="clid=6" and lose its clid.
|
|
47
|
+
const first = parts[0] ?? "";
|
|
48
|
+
if (first === "") return null;
|
|
49
|
+
|
|
50
|
+
// No prototype: a key is whatever the line says, and one named __proto__
|
|
51
|
+
// must be stored, not swallowed by Object.prototype's setter.
|
|
52
|
+
const params: Record<string, string> = Object.create(null) as Record<string, string>;
|
|
53
|
+
const name = isCommandName(first) ? first : "";
|
|
54
|
+
const start = name === "" ? 0 : 1;
|
|
55
|
+
|
|
56
|
+
for (let i = start; i < parts.length; i++) {
|
|
57
|
+
const p = parts[i];
|
|
58
|
+
if (p === undefined || p === "") continue;
|
|
59
|
+
const eqIdx = p.indexOf("=");
|
|
60
|
+
if (eqIdx >= 0) {
|
|
61
|
+
params[unescape(p.slice(0, eqIdx))] = unescape(p.slice(eqIdx + 1));
|
|
62
|
+
} else {
|
|
63
|
+
params[unescape(p)] = "";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return { name, params };
|
|
68
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A command as the typed layer describes it, before a transport encodes it.
|
|
3
|
+
*
|
|
4
|
+
* The typed commands run on any connection that can execute a command — the
|
|
5
|
+
* voice client today, ServerQuery later — and the two disagree about how some
|
|
6
|
+
* values go on the wire. A channel password is the case that matters: the
|
|
7
|
+
* voice protocol expects `base64(sha1(password))`, while ServerQuery takes the
|
|
8
|
+
* password itself and hashes it server-side. So a request says *which*
|
|
9
|
+
* parameters are passwords and leaves their encoding to the transport.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { CommandName } from "../command-name.js";
|
|
13
|
+
import { buildCommandOrdered } from "./command.js";
|
|
14
|
+
|
|
15
|
+
/** A parameter value as a caller may supply it. */
|
|
16
|
+
export type ParamValue = string | number | bigint | boolean | undefined;
|
|
17
|
+
|
|
18
|
+
/** A command and its parameters, in the order they are sent. */
|
|
19
|
+
export interface CommandRequest {
|
|
20
|
+
/** The command's name, such as `clientlist`; {@link CommandName} lists the known ones. */
|
|
21
|
+
readonly command: CommandName | (string & {});
|
|
22
|
+
/**
|
|
23
|
+
* Its parameters, as wire name and value pairs, in the order they are sent;
|
|
24
|
+
* an undefined value is omitted.
|
|
25
|
+
*/
|
|
26
|
+
readonly params?: ReadonlyArray<readonly [string, ParamValue]> | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Further rows, for a command that takes a list: each is a group of
|
|
29
|
+
* parameters sent after a `|`, as `ftdeletefile cid=1 cpw= name=/a|name=/b`
|
|
30
|
+
* sends two names. The first row's parameters follow `params`.
|
|
31
|
+
*/
|
|
32
|
+
readonly rows?: ReadonlyArray<ReadonlyArray<readonly [string, ParamValue]>> | undefined;
|
|
33
|
+
/** Names of the parameters that carry a channel password. */
|
|
34
|
+
readonly passwords?: readonly string[] | undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** How long a command may take, and how to abandon it. */
|
|
38
|
+
export interface CommandOptions {
|
|
39
|
+
/** Abandons the command; it then rejects with the signal's reason. */
|
|
40
|
+
readonly signal?: AbortSignal | undefined;
|
|
41
|
+
/** Milliseconds to wait for the answer before failing with a CommandTimeoutError. */
|
|
42
|
+
readonly timeoutMs?: number | undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A connection the typed commands can run on.
|
|
47
|
+
*
|
|
48
|
+
* It is deliberately this narrow. A caller implements it to run the typed
|
|
49
|
+
* commands over a transport of their own, and `CommandMiddleware` wraps its
|
|
50
|
+
* `send`, so a method added here would break every implementation and every
|
|
51
|
+
* middleware along with it: this interface gains no methods in a minor
|
|
52
|
+
* release. A new capability arrives as an interface, a function or an option
|
|
53
|
+
* of its own instead, and an implementer or a middleware author may rely on
|
|
54
|
+
* that.
|
|
55
|
+
*/
|
|
56
|
+
export interface CommandExecutor {
|
|
57
|
+
/** Send a command and return the rows that answer it. */
|
|
58
|
+
// oxlint-disable-next-line typescript/array-type -- the public API report spells this `[]`; respelling it changes the report
|
|
59
|
+
send(request: CommandRequest, options?: CommandOptions): Promise<Record<string, string>[]>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Turn a value into its wire form.
|
|
64
|
+
*
|
|
65
|
+
* Returns undefined for values that should be omitted entirely — an unset
|
|
66
|
+
* optional field — because sending `foo=` is not the same as not sending it:
|
|
67
|
+
* for `channel_password` the first clears the password and the second leaves it
|
|
68
|
+
* alone. Callers distinguish "unset" from "empty string" by passing undefined
|
|
69
|
+
* versus "".
|
|
70
|
+
*/
|
|
71
|
+
function encodeValue(value: ParamValue): string | undefined {
|
|
72
|
+
if (value === undefined) return undefined;
|
|
73
|
+
if (typeof value === "boolean") return value ? "1" : "0";
|
|
74
|
+
return String(value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Render a request as a command line.
|
|
79
|
+
*
|
|
80
|
+
* `encodePassword` is the transport's rule for password parameters. An empty
|
|
81
|
+
* password is sent as is: it means "no password", in every encoding.
|
|
82
|
+
*/
|
|
83
|
+
export function encodeRequest(
|
|
84
|
+
request: CommandRequest,
|
|
85
|
+
encodePassword: (password: string) => string,
|
|
86
|
+
): string {
|
|
87
|
+
const passwords = request.passwords ?? [];
|
|
88
|
+
const encode = (params: ReadonlyArray<readonly [string, ParamValue]>) =>
|
|
89
|
+
encodeParams(params, passwords, encodePassword);
|
|
90
|
+
const [first = [], ...rest] = request.rows ?? [];
|
|
91
|
+
const line = buildCommandOrdered(request.command, [
|
|
92
|
+
...encode(request.params ?? []),
|
|
93
|
+
...encode(first),
|
|
94
|
+
]);
|
|
95
|
+
// A row is the parameters alone, with no command name before them.
|
|
96
|
+
return [line, ...rest.map((row) => buildCommandOrdered("", encode(row)).slice(1))].join("|");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function encodeParams(
|
|
100
|
+
params: ReadonlyArray<readonly [string, ParamValue]>,
|
|
101
|
+
passwords: readonly string[],
|
|
102
|
+
encodePassword: (password: string) => string,
|
|
103
|
+
): Array<readonly [string, string]> {
|
|
104
|
+
const out: Array<readonly [string, string]> = [];
|
|
105
|
+
for (const [key, value] of params) {
|
|
106
|
+
// Flags (`-uid`) are switches: present when true, absent otherwise.
|
|
107
|
+
if (key.startsWith("-")) {
|
|
108
|
+
if (value === true) out.push([key, ""]);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (passwords.includes(key) && typeof value === "string" && value !== "") {
|
|
112
|
+
out.push([key, encodePassword(value)]);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const encoded = encodeValue(value);
|
|
116
|
+
if (encoded !== undefined) out.push([key, encoded]);
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where each command's answer actually arrives.
|
|
3
|
+
*
|
|
4
|
+
* ServerQuery answers a query with nameless rows followed by `error`. The voice
|
|
5
|
+
* protocol often does not: it answers `servergrouplist` with a named
|
|
6
|
+
* `notifyservergrouplist` command, `clientgetuidfromclid` with
|
|
7
|
+
* `notifyclientuidfromclid`, and so on. A client that only collects nameless
|
|
8
|
+
* rows reports an empty success for every one of those — which this SDK did,
|
|
9
|
+
* and documented as a property of the protocol.
|
|
10
|
+
*
|
|
11
|
+
* Notifications carry no return_code, so nothing on the wire ties one to the
|
|
12
|
+
* command that caused it. The pairing is a property of the command, and this
|
|
13
|
+
* table is where it lives. It was measured command by command
|
|
14
|
+
* against TS3 3.13.8 and TS6 6.0.0-beta13.1, which answer identically — see
|
|
15
|
+
* scripts/probe-response-shapes.mts to re-run that measurement.
|
|
16
|
+
*
|
|
17
|
+
* Commands not listed answer with nameless rows, or with nothing.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** How the voice protocol delivers one command's data. */
|
|
21
|
+
export interface ResponseSpec {
|
|
22
|
+
/**
|
|
23
|
+
* Notifications carrying the data, sent before the command's `error`.
|
|
24
|
+
*
|
|
25
|
+
* Rows of these are attributed to the command whose `error` follows them.
|
|
26
|
+
* The same notification can also arrive unprompted — `notifyservergrouplist`
|
|
27
|
+
* after someone else edits a group — so they are still dispatched as events.
|
|
28
|
+
*/
|
|
29
|
+
readonly notifications?: readonly string[];
|
|
30
|
+
/**
|
|
31
|
+
* Keep only rows whose `invokerid` is the client itself.
|
|
32
|
+
*
|
|
33
|
+
* `notifychannelcreated` is broadcast for every channel anyone creates; the
|
|
34
|
+
* one answering our `channelcreate` is the one we invoked.
|
|
35
|
+
*/
|
|
36
|
+
readonly ownRowsOnly?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The request parameter the answer echoes back, to tell the row that answers
|
|
39
|
+
* from the same notification sent for someone else.
|
|
40
|
+
*
|
|
41
|
+
* `notifyclientupdated` goes out whenever any client changes, and
|
|
42
|
+
* `notifychanneledited` whenever any channel does, so the row answering
|
|
43
|
+
* `clientgetvariables clid=7` is the one with `clid=7`. A row that names
|
|
44
|
+
* another value is no answer; one that does not carry the key is taken, as is
|
|
45
|
+
* every row when the request did not carry it.
|
|
46
|
+
*/
|
|
47
|
+
readonly echoKey?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Notifications that answer a command wherever they fall against its
|
|
50
|
+
* `error`, matched on a request field. A row that arrived before the `error`
|
|
51
|
+
* counts; if none has, the command waits for one, until its timeout or
|
|
52
|
+
* signal gives up.
|
|
53
|
+
*
|
|
54
|
+
* File transfer negotiation reports its key once the command has already
|
|
55
|
+
* succeeded, echoing the `clientftfid` the request carried; that echo is the
|
|
56
|
+
* only link between the two.
|
|
57
|
+
*/
|
|
58
|
+
readonly correlated?: {
|
|
59
|
+
readonly notifications: readonly string[];
|
|
60
|
+
/** Request parameter the answer echoes back. */
|
|
61
|
+
readonly key: string;
|
|
62
|
+
/**
|
|
63
|
+
* A notification that reports failure rather than data. Its `status` is an
|
|
64
|
+
* ordinary server error id: an `ftinitupload` refused for permissions
|
|
65
|
+
* answers `error id=0` and then this with `status=2568`.
|
|
66
|
+
*/
|
|
67
|
+
readonly failure?: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const inline = (...notifications: string[]): ResponseSpec => ({ notifications });
|
|
72
|
+
|
|
73
|
+
/** An inline answer that is also sent unprompted, for any `key` the request names. */
|
|
74
|
+
const echoing = (notification: string, key: string): ResponseSpec => ({
|
|
75
|
+
notifications: [notification],
|
|
76
|
+
echoKey: key,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const fileTransfer = (answer: string): ResponseSpec => ({
|
|
80
|
+
correlated: {
|
|
81
|
+
notifications: [answer, "notifystatusfiletransfer"],
|
|
82
|
+
key: "clientftfid",
|
|
83
|
+
failure: "notifystatusfiletransfer",
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
/** The table behind {@link responseSpec}, by command name; exported for the tests that check it against the name tables. */
|
|
88
|
+
export const RESPONSES: Readonly<Record<string, ResponseSpec>> = {
|
|
89
|
+
apikeyadd: inline("notifyapikeyadd"),
|
|
90
|
+
apikeylist: inline("notifyapikeylist"),
|
|
91
|
+
banlist: inline("notifybanlist"),
|
|
92
|
+
channelclientpermlist: inline("notifychannelclientpermlist"),
|
|
93
|
+
channelcreate: { notifications: ["notifychannelcreated"], ownRowsOnly: true },
|
|
94
|
+
channelgetdescription: echoing("notifychanneledited", "cid"),
|
|
95
|
+
channelgroupadd: inline("notifychannelgrouplist"),
|
|
96
|
+
channelgroupclientlist: inline("notifychannelgroupclientlist"),
|
|
97
|
+
channelgroupcopy: inline("notifychannelgrouplist"),
|
|
98
|
+
channelgrouplist: inline("notifychannelgrouplist"),
|
|
99
|
+
channelgrouppermlist: inline("notifychannelgrouppermlist"),
|
|
100
|
+
channelpermlist: inline("notifychannelpermlist"),
|
|
101
|
+
clientdbfind: inline("notifyclientdbfind"),
|
|
102
|
+
clientdblist: inline("notifyclientdblist"),
|
|
103
|
+
clientgetdbidfromuid: inline("notifyclientdbidfromuid"),
|
|
104
|
+
clientgetids: inline("notifyclientids"),
|
|
105
|
+
clientgetnamefromdbid: inline("notifyclientnamefromdbid"),
|
|
106
|
+
clientgetnamefromuid: inline("notifyclientnamefromuid"),
|
|
107
|
+
clientgetuidfromclid: inline("notifyclientuidfromclid"),
|
|
108
|
+
clientgetvariables: echoing("notifyclientupdated", "clid"),
|
|
109
|
+
clientsetserverquerylogin: inline("notifyclientserverqueryloginpassword"),
|
|
110
|
+
clientpermlist: inline("notifyclientpermlist"),
|
|
111
|
+
complainlist: inline("notifycomplainlist"),
|
|
112
|
+
// Matched on the echoed `clid`, wherever the row falls against the `error`:
|
|
113
|
+
// TeamSpeak 6 sent `error id=0` ahead of the `notifyconnectioninfo` row in
|
|
114
|
+
// about 3% of the commands (6 of 240) when four were in flight at once, never
|
|
115
|
+
// with one at a time (over 800 sequential commands, both servers); TeamSpeak
|
|
116
|
+
// 3 never did. Rows for the same client also arrive unprompted, when the
|
|
117
|
+
// target answers the server's `notifyconnectioninforequest`, so a row's
|
|
118
|
+
// position says nothing about which command it answers; the echo does.
|
|
119
|
+
getconnectioninfo: {
|
|
120
|
+
correlated: { notifications: ["notifyconnectioninfo"], key: "clid" },
|
|
121
|
+
},
|
|
122
|
+
ftgetfileinfo: inline("notifyfileinfo"),
|
|
123
|
+
ftgetfilelist: inline("notifyfilelist"),
|
|
124
|
+
ftinitdownload: fileTransfer("notifystartdownload"),
|
|
125
|
+
ftinitupload: fileTransfer("notifystartupload"),
|
|
126
|
+
ftlist: inline("notifyfiletransferlist"),
|
|
127
|
+
logview: inline("notifyserverlog"),
|
|
128
|
+
messageget: inline("notifymessage"),
|
|
129
|
+
messagelist: inline("notifymessagelist"),
|
|
130
|
+
permfind: inline("notifypermfind"),
|
|
131
|
+
permget: inline("notifypermget"),
|
|
132
|
+
permissionlist: inline("notifypermissionlist"),
|
|
133
|
+
permoverview: inline("notifypermoverview"),
|
|
134
|
+
privilegekeyadd: inline("notifytokenadd"),
|
|
135
|
+
privilegekeylist: inline("notifytokenlist"),
|
|
136
|
+
servergetvariables: inline("notifyserverupdated"),
|
|
137
|
+
servergroupadd: inline("notifyservergrouplist"),
|
|
138
|
+
servergroupclientlist: inline("notifyservergroupclientlist"),
|
|
139
|
+
servergroupcopy: inline("notifyservergrouplist"),
|
|
140
|
+
servergrouplist: inline("notifyservergrouplist"),
|
|
141
|
+
servergrouppermlist: inline("notifyservergrouppermlist"),
|
|
142
|
+
servergroupsbyclientid: inline("notifyservergroupsbyclientid"),
|
|
143
|
+
serverrequestconnectioninfo: inline("notifyserverconnectioninfo"),
|
|
144
|
+
servertemppasswordlist: inline("notifyservertemppasswordlist"),
|
|
145
|
+
tokenadd: inline("notifytokenadd"),
|
|
146
|
+
tokenlist: inline("notifytokenlist"),
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/** The response shape of a command, or undefined for plain rows. */
|
|
150
|
+
export function responseSpec(command: string): ResponseSpec | undefined {
|
|
151
|
+
return Object.hasOwn(RESPONSES, command) ? RESPONSES[command] : undefined;
|
|
152
|
+
}
|