@quenty/studio-bridge 0.21.0 → 0.22.0
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/CHANGELOG.md +12 -0
- package/README.md +109 -17
- package/build-scripts/transform-add-session-attribute.lua +1 -0
- package/deploy.nevermore.json +10 -0
- package/dist/src/bridge/bridge-connection.d.ts +26 -2
- package/dist/src/bridge/bridge-connection.d.ts.map +1 -1
- package/dist/src/bridge/bridge-connection.js +159 -14
- package/dist/src/bridge/bridge-connection.js.map +1 -1
- package/dist/src/bridge/bridge-connection.test.js +81 -0
- package/dist/src/bridge/bridge-connection.test.js.map +1 -1
- package/dist/src/bridge/bridge-session.d.ts +35 -2
- package/dist/src/bridge/bridge-session.d.ts.map +1 -1
- package/dist/src/bridge/bridge-session.js +185 -28
- package/dist/src/bridge/bridge-session.js.map +1 -1
- package/dist/src/bridge/bridge-session.test.js +6 -4
- package/dist/src/bridge/bridge-session.test.js.map +1 -1
- package/dist/src/bridge/index.d.ts +1 -1
- package/dist/src/bridge/index.d.ts.map +1 -1
- package/dist/src/bridge/index.js.map +1 -1
- package/dist/src/bridge/internal/bridge-client.d.ts +4 -0
- package/dist/src/bridge/internal/bridge-client.d.ts.map +1 -1
- package/dist/src/bridge/internal/bridge-client.js +20 -7
- package/dist/src/bridge/internal/bridge-client.js.map +1 -1
- package/dist/src/bridge/internal/bridge-client.test.js +18 -0
- package/dist/src/bridge/internal/bridge-client.test.js.map +1 -1
- package/dist/src/bridge/internal/bridge-host.d.ts +13 -1
- package/dist/src/bridge/internal/bridge-host.d.ts.map +1 -1
- package/dist/src/bridge/internal/bridge-host.js +35 -0
- package/dist/src/bridge/internal/bridge-host.js.map +1 -1
- package/dist/src/bridge/internal/bridge-host.test.js +31 -0
- package/dist/src/bridge/internal/bridge-host.test.js.map +1 -1
- package/dist/src/bridge/internal/hand-off.d.ts.map +1 -1
- package/dist/src/bridge/internal/hand-off.js +4 -1
- package/dist/src/bridge/internal/hand-off.js.map +1 -1
- package/dist/src/bridge/internal/host-protocol.d.ts +8 -0
- package/dist/src/bridge/internal/host-protocol.d.ts.map +1 -1
- package/dist/src/bridge/internal/host-protocol.js +120 -13
- package/dist/src/bridge/internal/host-protocol.js.map +1 -1
- package/dist/src/bridge/internal/host-protocol.test.js +13 -0
- package/dist/src/bridge/internal/host-protocol.test.js.map +1 -1
- package/dist/src/bridge/internal/instance-state.d.ts +9 -0
- package/dist/src/bridge/internal/instance-state.d.ts.map +1 -0
- package/dist/src/bridge/internal/instance-state.js +28 -0
- package/dist/src/bridge/internal/instance-state.js.map +1 -0
- package/dist/src/bridge/internal/transport-client.d.ts.map +1 -1
- package/dist/src/bridge/internal/transport-client.js +2 -1
- package/dist/src/bridge/internal/transport-client.js.map +1 -1
- package/dist/src/bridge/internal/transport-server.d.ts.map +1 -1
- package/dist/src/bridge/internal/transport-server.js +5 -1
- package/dist/src/bridge/internal/transport-server.js.map +1 -1
- package/dist/src/bridge/types.d.ts +43 -4
- package/dist/src/bridge/types.d.ts.map +1 -1
- package/dist/src/bridge/types.js.map +1 -1
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.js +24 -0
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.js.map +1 -1
- package/dist/src/cli/adapters/cli-command-adapter.d.ts +6 -0
- package/dist/src/cli/adapters/cli-command-adapter.d.ts.map +1 -1
- package/dist/src/cli/adapters/cli-command-adapter.js +107 -11
- package/dist/src/cli/adapters/cli-command-adapter.js.map +1 -1
- package/dist/src/cli/adapters/group-builder.d.ts +3 -0
- package/dist/src/cli/adapters/group-builder.d.ts.map +1 -1
- package/dist/src/cli/adapters/group-builder.js +34 -15
- package/dist/src/cli/adapters/group-builder.js.map +1 -1
- package/dist/src/cli/adapters/group-builder.test.js +26 -2
- package/dist/src/cli/adapters/group-builder.test.js.map +1 -1
- package/dist/src/cli/adapters/help-formatter.d.ts.map +1 -1
- package/dist/src/cli/adapters/help-formatter.js +4 -3
- package/dist/src/cli/adapters/help-formatter.js.map +1 -1
- package/dist/src/cli/adapters/help-formatter.test.js +1 -1
- package/dist/src/cli/adapters/help-formatter.test.js.map +1 -1
- package/dist/src/cli/adapters/playtest-edit-guard.test.d.ts +2 -0
- package/dist/src/cli/adapters/playtest-edit-guard.test.d.ts.map +1 -0
- package/dist/src/cli/adapters/playtest-edit-guard.test.js +28 -0
- package/dist/src/cli/adapters/playtest-edit-guard.test.js.map +1 -0
- package/dist/src/cli/args/global-args.d.ts +1 -1
- package/dist/src/cli/args/global-args.d.ts.map +1 -1
- package/dist/src/cli/cli-output-context.d.ts +14 -0
- package/dist/src/cli/cli-output-context.d.ts.map +1 -0
- package/dist/src/cli/cli-output-context.js +39 -0
- package/dist/src/cli/cli-output-context.js.map +1 -0
- package/dist/src/cli/cli-output-context.test.d.ts +2 -0
- package/dist/src/cli/cli-output-context.test.d.ts.map +1 -0
- package/dist/src/cli/cli-output-context.test.js +38 -0
- package/dist/src/cli/cli-output-context.test.js.map +1 -0
- package/dist/src/cli/cli.js +40 -17
- package/dist/src/cli/cli.js.map +1 -1
- package/dist/src/cli/managed-studio-run.d.ts +21 -0
- package/dist/src/cli/managed-studio-run.d.ts.map +1 -0
- package/dist/src/cli/managed-studio-run.js +75 -0
- package/dist/src/cli/managed-studio-run.js.map +1 -0
- package/dist/src/cli/managed-studio-run.test.d.ts +2 -0
- package/dist/src/cli/managed-studio-run.test.d.ts.map +1 -0
- package/dist/src/cli/managed-studio-run.test.js +52 -0
- package/dist/src/cli/managed-studio-run.test.js.map +1 -0
- package/dist/src/cli/resolve-session.js +1 -1
- package/dist/src/cli/resolve-session.js.map +1 -1
- package/dist/src/cli/resolve-session.test.js +1 -1
- package/dist/src/cli/resolve-session.test.js.map +1 -1
- package/dist/src/cli/script-executor.d.ts +13 -1
- package/dist/src/cli/script-executor.d.ts.map +1 -1
- package/dist/src/cli/script-executor.js +77 -47
- package/dist/src/cli/script-executor.js.map +1 -1
- package/dist/src/commands/console/exec/exec.d.ts +17 -0
- package/dist/src/commands/console/exec/exec.d.ts.map +1 -1
- package/dist/src/commands/console/exec/exec.js +39 -7
- package/dist/src/commands/console/exec/exec.js.map +1 -1
- package/dist/src/commands/console/exec/exec.test.js +62 -3
- package/dist/src/commands/console/exec/exec.test.js.map +1 -1
- package/dist/src/commands/console/logs/logs.d.ts +30 -2
- package/dist/src/commands/console/logs/logs.d.ts.map +1 -1
- package/dist/src/commands/console/logs/logs.js +82 -7
- package/dist/src/commands/console/logs/logs.js.map +1 -1
- package/dist/src/commands/console/logs/logs.test.js +63 -4
- package/dist/src/commands/console/logs/logs.test.js.map +1 -1
- package/dist/src/commands/explorer/export/export.d.ts +19 -0
- package/dist/src/commands/explorer/export/export.d.ts.map +1 -0
- package/dist/src/commands/explorer/export/export.js +37 -0
- package/dist/src/commands/explorer/export/export.js.map +1 -0
- package/dist/src/commands/explorer/export/export.test.d.ts +2 -0
- package/dist/src/commands/explorer/export/export.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/export/export.test.js +25 -0
- package/dist/src/commands/explorer/export/export.test.js.map +1 -0
- package/dist/src/commands/explorer/find/find.d.ts +28 -0
- package/dist/src/commands/explorer/find/find.d.ts.map +1 -0
- package/dist/src/commands/explorer/find/find.js +75 -0
- package/dist/src/commands/explorer/find/find.js.map +1 -0
- package/dist/src/commands/explorer/find/find.test.d.ts +2 -0
- package/dist/src/commands/explorer/find/find.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/find/find.test.js +44 -0
- package/dist/src/commands/explorer/find/find.test.js.map +1 -0
- package/dist/src/commands/explorer/grep/grep.d.ts +24 -0
- package/dist/src/commands/explorer/grep/grep.d.ts.map +1 -0
- package/dist/src/commands/explorer/grep/grep.js +63 -0
- package/dist/src/commands/explorer/grep/grep.js.map +1 -0
- package/dist/src/commands/explorer/grep/grep.test.d.ts +2 -0
- package/dist/src/commands/explorer/grep/grep.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/grep/grep.test.js +42 -0
- package/dist/src/commands/explorer/grep/grep.test.js.map +1 -0
- package/dist/src/commands/explorer/import/import.d.ts +21 -0
- package/dist/src/commands/explorer/import/import.d.ts.map +1 -0
- package/dist/src/commands/explorer/import/import.js +37 -0
- package/dist/src/commands/explorer/import/import.js.map +1 -0
- package/dist/src/commands/explorer/import/import.test.d.ts +2 -0
- package/dist/src/commands/explorer/import/import.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/import/import.test.js +45 -0
- package/dist/src/commands/explorer/import/import.test.js.map +1 -0
- package/dist/src/commands/formatters.test.js +7 -1
- package/dist/src/commands/formatters.test.js.map +1 -1
- package/dist/src/commands/framework/action-loader.d.ts +5 -1
- package/dist/src/commands/framework/action-loader.d.ts.map +1 -1
- package/dist/src/commands/framework/action-loader.js +9 -2
- package/dist/src/commands/framework/action-loader.js.map +1 -1
- package/dist/src/commands/framework/action-loader.test.js +23 -0
- package/dist/src/commands/framework/action-loader.test.js.map +1 -1
- package/dist/src/commands/framework/arg-builder.d.ts +15 -2
- package/dist/src/commands/framework/arg-builder.d.ts.map +1 -1
- package/dist/src/commands/framework/arg-builder.js +22 -2
- package/dist/src/commands/framework/arg-builder.js.map +1 -1
- package/dist/src/commands/framework/define-command.d.ts +19 -3
- package/dist/src/commands/framework/define-command.d.ts.map +1 -1
- package/dist/src/commands/framework/define-command.js.map +1 -1
- package/dist/src/commands/framework/index.d.ts +1 -1
- package/dist/src/commands/framework/index.d.ts.map +1 -1
- package/dist/src/commands/framework/index.js.map +1 -1
- package/dist/src/commands/index.d.ts +11 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +11 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/linux/inject-credentials/inject-credentials.d.ts.map +1 -1
- package/dist/src/commands/linux/inject-credentials/inject-credentials.js +1 -3
- package/dist/src/commands/linux/inject-credentials/inject-credentials.js.map +1 -1
- package/dist/src/commands/linux/setup/setup.d.ts.map +1 -1
- package/dist/src/commands/linux/setup/setup.js +1 -3
- package/dist/src/commands/linux/setup/setup.js.map +1 -1
- package/dist/src/commands/linux/status/status.d.ts +9 -1
- package/dist/src/commands/linux/status/status.d.ts.map +1 -1
- package/dist/src/commands/linux/status/status.js +66 -86
- package/dist/src/commands/linux/status/status.js.map +1 -1
- package/dist/src/commands/playtest/player/add/add.d.ts +17 -0
- package/dist/src/commands/playtest/player/add/add.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/add/add.js +45 -0
- package/dist/src/commands/playtest/player/add/add.js.map +1 -0
- package/dist/src/commands/playtest/player/list/list.d.ts +13 -0
- package/dist/src/commands/playtest/player/list/list.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/list/list.js +33 -0
- package/dist/src/commands/playtest/player/list/list.js.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.d.ts +36 -0
- package/dist/src/commands/playtest/player/playtest-players.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.js +187 -0
- package/dist/src/commands/playtest/player/playtest-players.js.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.test.d.ts +2 -0
- package/dist/src/commands/playtest/player/playtest-players.test.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.test.js +89 -0
- package/dist/src/commands/playtest/player/playtest-players.test.js.map +1 -0
- package/dist/src/commands/playtest/player/remove/remove.d.ts +17 -0
- package/dist/src/commands/playtest/player/remove/remove.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/remove/remove.js +42 -0
- package/dist/src/commands/playtest/player/remove/remove.js.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.d.ts +49 -0
- package/dist/src/commands/playtest/playtest-sessions.d.ts.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.js +283 -0
- package/dist/src/commands/playtest/playtest-sessions.js.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.test.d.ts +2 -0
- package/dist/src/commands/playtest/playtest-sessions.test.d.ts.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.test.js +87 -0
- package/dist/src/commands/playtest/playtest-sessions.test.js.map +1 -0
- package/dist/src/commands/playtest/restart/restart.d.ts +23 -0
- package/dist/src/commands/playtest/restart/restart.d.ts.map +1 -0
- package/dist/src/commands/playtest/restart/restart.js +105 -0
- package/dist/src/commands/playtest/restart/restart.js.map +1 -0
- package/dist/src/commands/playtest/run/run.d.ts +47 -0
- package/dist/src/commands/playtest/run/run.d.ts.map +1 -0
- package/dist/src/commands/playtest/run/run.js +137 -0
- package/dist/src/commands/playtest/run/run.js.map +1 -0
- package/dist/src/commands/playtest/start/start.d.ts +42 -0
- package/dist/src/commands/playtest/start/start.d.ts.map +1 -0
- package/dist/src/commands/playtest/start/start.js +70 -0
- package/dist/src/commands/playtest/start/start.js.map +1 -0
- package/dist/src/commands/playtest/stop/stop.d.ts +15 -0
- package/dist/src/commands/playtest/stop/stop.d.ts.map +1 -0
- package/dist/src/commands/playtest/stop/stop.js +24 -0
- package/dist/src/commands/playtest/stop/stop.js.map +1 -0
- package/dist/src/commands/process/close/close.d.ts +19 -10
- package/dist/src/commands/process/close/close.d.ts.map +1 -1
- package/dist/src/commands/process/close/close.js +118 -15
- package/dist/src/commands/process/close/close.js.map +1 -1
- package/dist/src/commands/process/close/close.test.d.ts +2 -0
- package/dist/src/commands/process/close/close.test.d.ts.map +1 -0
- package/dist/src/commands/process/close/close.test.js +190 -0
- package/dist/src/commands/process/close/close.test.js.map +1 -0
- package/dist/src/commands/process/info/info.d.ts +45 -5
- package/dist/src/commands/process/info/info.d.ts.map +1 -1
- package/dist/src/commands/process/info/info.js +117 -13
- package/dist/src/commands/process/info/info.js.map +1 -1
- package/dist/src/commands/process/info/info.test.js +140 -38
- package/dist/src/commands/process/info/info.test.js.map +1 -1
- package/dist/src/commands/process/launch/launch.d.ts +11 -1
- package/dist/src/commands/process/launch/launch.d.ts.map +1 -1
- package/dist/src/commands/process/launch/launch.js +37 -7
- package/dist/src/commands/process/launch/launch.js.map +1 -1
- package/dist/src/commands/process/launch/launch.test.js +99 -20
- package/dist/src/commands/process/launch/launch.test.js.map +1 -1
- package/dist/src/commands/process/list/list.d.ts +2 -1
- package/dist/src/commands/process/list/list.d.ts.map +1 -1
- package/dist/src/commands/process/list/list.js +9 -6
- package/dist/src/commands/process/list/list.js.map +1 -1
- package/dist/src/commands/process/list/list.test.js +1 -0
- package/dist/src/commands/process/list/list.test.js.map +1 -1
- package/dist/src/commands/process/run/run.d.ts +9 -0
- package/dist/src/commands/process/run/run.d.ts.map +1 -1
- package/dist/src/commands/process/run/run.js +15 -5
- package/dist/src/commands/process/run/run.js.map +1 -1
- package/dist/src/commands/serve/serve.d.ts +2 -0
- package/dist/src/commands/serve/serve.d.ts.map +1 -1
- package/dist/src/commands/serve/serve.js +17 -4
- package/dist/src/commands/serve/serve.js.map +1 -1
- package/dist/src/commands/serve/serve.test.js +9 -2
- package/dist/src/commands/serve/serve.test.js.map +1 -1
- package/dist/src/commands/viewport/screenshot/screenshot.d.ts.map +1 -1
- package/dist/src/commands/viewport/screenshot/screenshot.js +4 -1
- package/dist/src/commands/viewport/screenshot/screenshot.js.map +1 -1
- package/dist/src/commands/viewport/screenshot/screenshot.test.js +5 -9
- package/dist/src/commands/viewport/screenshot/screenshot.test.js.map +1 -1
- package/dist/src/deploy/deploy-places.d.ts +39 -0
- package/dist/src/deploy/deploy-places.d.ts.map +1 -0
- package/dist/src/deploy/deploy-places.js +162 -0
- package/dist/src/deploy/deploy-places.js.map +1 -0
- package/dist/src/deploy/deploy-places.test.d.ts +2 -0
- package/dist/src/deploy/deploy-places.test.d.ts.map +1 -0
- package/dist/src/deploy/deploy-places.test.js +96 -0
- package/dist/src/deploy/deploy-places.test.js.map +1 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/linux/linux-studio-launcher.d.ts.map +1 -1
- package/dist/src/linux/linux-studio-launcher.js +10 -0
- package/dist/src/linux/linux-studio-launcher.js.map +1 -1
- package/dist/src/linux/linux-studio-launcher.test.d.ts +2 -0
- package/dist/src/linux/linux-studio-launcher.test.d.ts.map +1 -0
- package/dist/src/linux/linux-studio-launcher.test.js +68 -0
- package/dist/src/linux/linux-studio-launcher.test.js.map +1 -0
- package/dist/src/plugin/persistent-plugin-installer.d.ts.map +1 -1
- package/dist/src/plugin/persistent-plugin-installer.js +2 -1
- package/dist/src/plugin/persistent-plugin-installer.js.map +1 -1
- package/dist/src/plugin/persistent-plugin-installer.test.js +3 -0
- package/dist/src/plugin/persistent-plugin-installer.test.js.map +1 -1
- package/dist/src/plugin/plugin-build-version.d.ts +7 -0
- package/dist/src/plugin/plugin-build-version.d.ts.map +1 -0
- package/dist/src/plugin/plugin-build-version.js +42 -0
- package/dist/src/plugin/plugin-build-version.js.map +1 -0
- package/dist/src/plugin/plugin-build-version.test.d.ts +2 -0
- package/dist/src/plugin/plugin-build-version.test.d.ts.map +1 -0
- package/dist/src/plugin/plugin-build-version.test.js +41 -0
- package/dist/src/plugin/plugin-build-version.test.js.map +1 -0
- package/dist/src/plugin/plugin-injector.d.ts.map +1 -1
- package/dist/src/plugin/plugin-injector.js +7 -1
- package/dist/src/plugin/plugin-injector.js.map +1 -1
- package/dist/src/process/studio-process-closer.d.ts +35 -0
- package/dist/src/process/studio-process-closer.d.ts.map +1 -0
- package/dist/src/process/studio-process-closer.js +129 -0
- package/dist/src/process/studio-process-closer.js.map +1 -0
- package/dist/src/process/studio-process-closer.test.d.ts +2 -0
- package/dist/src/process/studio-process-closer.test.d.ts.map +1 -0
- package/dist/src/process/studio-process-closer.test.js +80 -0
- package/dist/src/process/studio-process-closer.test.js.map +1 -0
- package/dist/src/process/studio-settings.d.ts +14 -0
- package/dist/src/process/studio-settings.d.ts.map +1 -0
- package/dist/src/process/studio-settings.js +50 -0
- package/dist/src/process/studio-settings.js.map +1 -0
- package/dist/src/process/studio-settings.test.d.ts +2 -0
- package/dist/src/process/studio-settings.test.d.ts.map +1 -0
- package/dist/src/process/studio-settings.test.js +16 -0
- package/dist/src/process/studio-settings.test.js.map +1 -0
- package/dist/src/process/studio-window-state.d.ts +13 -0
- package/dist/src/process/studio-window-state.d.ts.map +1 -0
- package/dist/src/process/studio-window-state.js +48 -0
- package/dist/src/process/studio-window-state.js.map +1 -0
- package/dist/src/server/studio-bridge-server.d.ts +3 -1
- package/dist/src/server/studio-bridge-server.d.ts.map +1 -1
- package/dist/src/server/studio-bridge-server.js +12 -4
- package/dist/src/server/studio-bridge-server.js.map +1 -1
- package/dist/src/server/web-socket-protocol.d.ts +173 -6
- package/dist/src/server/web-socket-protocol.d.ts.map +1 -1
- package/dist/src/server/web-socket-protocol.js +244 -1
- package/dist/src/server/web-socket-protocol.js.map +1 -1
- package/dist/src/server/web-socket-protocol.test.js +48 -0
- package/dist/src/server/web-socket-protocol.test.js.map +1 -1
- package/dist/src/test/e2e/persistent-session.test.js +121 -0
- package/dist/src/test/e2e/persistent-session.test.js.map +1 -1
- package/dist/src/test/e2e/split-server.test.d.ts +3 -5
- package/dist/src/test/e2e/split-server.test.d.ts.map +1 -1
- package/dist/src/test/e2e/split-server.test.js +3 -5
- package/dist/src/test/e2e/split-server.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docker/Dockerfile +3 -0
- package/package.json +8 -6
- package/src/bridge/bridge-connection.test.ts +126 -0
- package/src/bridge/bridge-connection.ts +217 -22
- package/src/bridge/bridge-session.test.ts +6 -4
- package/src/bridge/bridge-session.ts +273 -28
- package/src/bridge/index.ts +3 -0
- package/src/bridge/internal/bridge-client.test.ts +23 -0
- package/src/bridge/internal/bridge-client.ts +25 -7
- package/src/bridge/internal/bridge-host.test.ts +38 -0
- package/src/bridge/internal/bridge-host.ts +47 -0
- package/src/bridge/internal/hand-off.ts +4 -1
- package/src/bridge/internal/host-protocol.test.ts +15 -0
- package/src/bridge/internal/host-protocol.ts +148 -37
- package/src/bridge/internal/instance-state.ts +34 -0
- package/src/bridge/internal/transport-client.ts +2 -1
- package/src/bridge/internal/transport-server.ts +5 -1
- package/src/bridge/types.ts +47 -2
- package/src/cli/adapters/cli-command-adapter-handler.test.ts +28 -0
- package/src/cli/adapters/cli-command-adapter.ts +150 -18
- package/src/cli/adapters/group-builder.test.ts +34 -2
- package/src/cli/adapters/group-builder.ts +52 -20
- package/src/cli/adapters/help-formatter.test.ts +1 -1
- package/src/cli/adapters/help-formatter.ts +4 -3
- package/src/cli/adapters/playtest-edit-guard.test.ts +54 -0
- package/src/cli/args/global-args.ts +1 -1
- package/src/cli/cli-output-context.test.ts +55 -0
- package/src/cli/cli-output-context.ts +50 -0
- package/src/cli/cli.ts +49 -17
- package/src/cli/managed-studio-run.test.ts +71 -0
- package/src/cli/managed-studio-run.ts +135 -0
- package/src/cli/resolve-session.test.ts +1 -1
- package/src/cli/resolve-session.ts +1 -1
- package/src/cli/script-executor.ts +99 -51
- package/src/commands/console/exec/exec.test.ts +96 -3
- package/src/commands/console/exec/exec.ts +59 -6
- package/src/commands/console/exec/execute.lua +356 -240
- package/src/commands/console/exec/execute.spec.lua +286 -0
- package/src/commands/console/logs/logs.test.ts +76 -4
- package/src/commands/console/logs/logs.ts +132 -17
- package/src/commands/console/logs/query-logs.lua +85 -52
- package/src/commands/console/logs/query-logs.spec.lua +132 -0
- package/src/commands/explorer/export/export-instances.lua +108 -0
- package/src/commands/explorer/export/export-instances.spec.lua +87 -0
- package/src/commands/explorer/export/export.test.ts +27 -0
- package/src/commands/explorer/export/export.ts +60 -0
- package/src/commands/explorer/find/find-instances.lua +174 -0
- package/src/commands/explorer/find/find-instances.spec.lua +122 -0
- package/src/commands/explorer/find/find.test.ts +53 -0
- package/src/commands/explorer/find/find.ts +113 -0
- package/src/commands/explorer/grep/grep-scripts.lua +214 -0
- package/src/commands/explorer/grep/grep-scripts.spec.lua +130 -0
- package/src/commands/explorer/grep/grep.test.ts +45 -0
- package/src/commands/explorer/grep/grep.ts +93 -0
- package/src/commands/explorer/import/import-instances.lua +106 -0
- package/src/commands/explorer/import/import-instances.spec.lua +84 -0
- package/src/commands/explorer/import/import.test.ts +60 -0
- package/src/commands/explorer/import/import.ts +66 -0
- package/src/commands/explorer/query/query-data-model.lua +124 -152
- package/src/commands/explorer/query/query-data-model.spec.lua +150 -0
- package/src/commands/formatters.test.ts +7 -1
- package/src/commands/framework/action-loader.test.ts +28 -0
- package/src/commands/framework/action-loader.ts +10 -2
- package/src/commands/framework/arg-builder.ts +26 -3
- package/src/commands/framework/define-command.ts +32 -3
- package/src/commands/framework/index.ts +1 -0
- package/src/commands/index.ts +50 -0
- package/src/commands/linux/inject-credentials/inject-credentials.ts +1 -3
- package/src/commands/linux/setup/setup.ts +1 -3
- package/src/commands/linux/status/status.ts +105 -98
- package/src/commands/playtest/player/add/add.ts +85 -0
- package/src/commands/playtest/player/list/list.ts +57 -0
- package/src/commands/playtest/player/playtest-players.test.ts +146 -0
- package/src/commands/playtest/player/playtest-players.ts +270 -0
- package/src/commands/playtest/player/remove/remove.ts +78 -0
- package/src/commands/playtest/playtest-sessions.test.ts +143 -0
- package/src/commands/playtest/playtest-sessions.ts +417 -0
- package/src/commands/playtest/restart/restart.ts +199 -0
- package/src/commands/playtest/run/playtest-runner.luau +264 -0
- package/src/commands/playtest/run/playtest-runner.spec.lua +71 -0
- package/src/commands/playtest/run/run-playtest-script.lua +139 -0
- package/src/commands/playtest/run/run-playtest-script.spec.lua +43 -0
- package/src/commands/playtest/run/run.ts +239 -0
- package/src/commands/playtest/start/start-playtest.lua +108 -0
- package/src/commands/playtest/start/start.ts +138 -0
- package/src/commands/playtest/stop/end-playtest.lua +47 -0
- package/src/commands/playtest/stop/stop.ts +51 -0
- package/src/commands/process/close/close.test.ts +250 -0
- package/src/commands/process/close/close.ts +183 -17
- package/src/commands/process/info/info.test.ts +198 -44
- package/src/commands/process/info/info.ts +204 -15
- package/src/commands/process/info/query-state.lua +42 -29
- package/src/commands/process/info/query-state.spec.lua +39 -0
- package/src/commands/process/launch/launch.test.ts +138 -21
- package/src/commands/process/launch/launch.ts +69 -9
- package/src/commands/process/list/list.test.ts +1 -0
- package/src/commands/process/list/list.ts +14 -6
- package/src/commands/process/run/run.ts +26 -5
- package/src/commands/serve/serve.test.ts +17 -2
- package/src/commands/serve/serve.ts +25 -6
- package/src/commands/viewport/screenshot/capture-screenshot.lua +175 -182
- package/src/commands/viewport/screenshot/capture-screenshot.spec.lua +129 -0
- package/src/commands/viewport/screenshot/screenshot.test.ts +7 -10
- package/src/commands/viewport/screenshot/screenshot.ts +6 -1
- package/src/deploy/deploy-places.test.ts +127 -0
- package/src/deploy/deploy-places.ts +229 -0
- package/src/index.ts +11 -0
- package/src/linux/linux-studio-launcher.test.ts +89 -0
- package/src/linux/linux-studio-launcher.ts +11 -0
- package/src/plugin/persistent-plugin-installer.test.ts +4 -0
- package/src/plugin/persistent-plugin-installer.ts +2 -1
- package/src/plugin/plugin-build-version.test.ts +55 -0
- package/src/plugin/plugin-build-version.ts +53 -0
- package/src/plugin/plugin-injector.ts +7 -1
- package/src/process/studio-process-closer.test.ts +107 -0
- package/src/process/studio-process-closer.ts +187 -0
- package/src/process/studio-settings.test.ts +18 -0
- package/src/process/studio-settings.ts +61 -0
- package/src/process/studio-window-state.ts +65 -0
- package/src/server/studio-bridge-server.ts +15 -4
- package/src/server/web-socket-protocol.test.ts +55 -0
- package/src/server/web-socket-protocol.ts +468 -8
- package/src/test/e2e/persistent-session.test.ts +137 -0
- package/src/test/e2e/split-server.test.ts +3 -5
- package/templates/studio-bridge-plugin/default.project.json +3 -0
- package/templates/studio-bridge-plugin/src/Shared/ActionRouter.lua +208 -159
- package/templates/studio-bridge-plugin/src/Shared/ActionRouter.spec.lua +418 -0
- package/templates/studio-bridge-plugin/src/Shared/BuiltInActions.lua +94 -0
- package/templates/studio-bridge-plugin/src/Shared/BuiltInActions.spec.lua +166 -0
- package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.lua +118 -137
- package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.spec.lua +228 -0
- package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.lua +80 -109
- package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.spec.lua +116 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeConnection.lua +233 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeConnection.spec.lua +239 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeLogUtils.lua +53 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeLogUtils.spec.lua +27 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeSessionUtils.lua +164 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeSessionUtils.spec.lua +159 -0
- package/templates/studio-bridge-plugin/src/StudioBridgePlugin.server.lua +266 -368
- package/templates/studio-bridge-plugin/src/Vendor/png.lua +8 -2
- package/test/default.project.json +41 -0
- package/test/jest.config.lua +3 -0
- package/test/scripts/Server/ServerMain.server.lua +10 -0
- package/tsconfig.json +1 -0
- package/templates/studio-bridge-plugin/src/Shared/Protocol.lua +0 -132
- package/templates/studio-bridge-plugin-test/test/actions.test.lua +0 -580
- package/templates/studio-bridge-plugin-test/test/discovery.test.lua +0 -622
- package/templates/studio-bridge-plugin-test/test/execute-handler.test.lua +0 -517
- package/templates/studio-bridge-plugin-test/test/hash-lifecycle.test.lua +0 -814
- package/templates/studio-bridge-plugin-test/test/integration.test.lua +0 -1020
- package/templates/studio-bridge-plugin-test/test/new-actions.test.lua +0 -339
- package/templates/studio-bridge-plugin-test/test/plugin-entry.test.lua +0 -493
- package/templates/studio-bridge-plugin-test/test/protocol.test.lua +0 -506
- package/templates/studio-bridge-plugin-test/test/roblox-mocks.lua +0 -108
- package/templates/studio-bridge-plugin-test/test/test-runner.lua +0 -112
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `playtest run` — start a playtest, execute Luau inside it, then stop it.
|
|
3
|
+
*
|
|
4
|
+
* The code runs in the playtest's server by default, or its client with
|
|
5
|
+
* `--context client`. Its output and return values come back the same way as
|
|
6
|
+
* `console exec`.
|
|
7
|
+
*
|
|
8
|
+
* In the server, the edit session plants a runner script in the playtest
|
|
9
|
+
* (playtest-runner.luau), so this works even when Studio does not load user
|
|
10
|
+
* plugins into playtests. The client has no such path: it needs the
|
|
11
|
+
* playtest's client session, so it needs that Studio setting on.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import * as fs from 'fs/promises';
|
|
15
|
+
import { resolvePackagePath } from '@quenty/nevermore-template-helpers';
|
|
16
|
+
import { defineCommand } from '../../framework/define-command.js';
|
|
17
|
+
import { arg } from '../../framework/arg-builder.js';
|
|
18
|
+
import { resolveScriptContentAsync } from '../../../cli/resolve-script-content.js';
|
|
19
|
+
import {
|
|
20
|
+
execHandlerAsync,
|
|
21
|
+
formatExecText,
|
|
22
|
+
type ExecResult as CommandExecResult,
|
|
23
|
+
} from '../../console/exec/exec.js';
|
|
24
|
+
import type {
|
|
25
|
+
BridgeConnection,
|
|
26
|
+
BridgeSession,
|
|
27
|
+
ExecResult,
|
|
28
|
+
PlaytestMode,
|
|
29
|
+
SessionContext,
|
|
30
|
+
} from '../../../bridge/index.js';
|
|
31
|
+
import type { SerializedReturnValue } from '../../../server/web-socket-protocol.js';
|
|
32
|
+
import {
|
|
33
|
+
endPlaytestAsync,
|
|
34
|
+
getPlaytestContexts,
|
|
35
|
+
startPlaytestAsync,
|
|
36
|
+
} from '../playtest-sessions.js';
|
|
37
|
+
|
|
38
|
+
export interface PlaytestRunOptions {
|
|
39
|
+
scriptContent: string;
|
|
40
|
+
mode: PlaytestMode;
|
|
41
|
+
/** Which playtest DataModel runs the code. */
|
|
42
|
+
context: SessionContext;
|
|
43
|
+
/** Picks the edit session to start the playtest from. */
|
|
44
|
+
target?: string;
|
|
45
|
+
timeout?: number;
|
|
46
|
+
/** Passed to the script as `...`. */
|
|
47
|
+
args?: string[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Matches `console exec`'s default execution timeout. */
|
|
51
|
+
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
52
|
+
|
|
53
|
+
export interface PlaytestRunResult {
|
|
54
|
+
success: boolean;
|
|
55
|
+
/** Absent when the script ran through the planted runner. */
|
|
56
|
+
playtestId?: string;
|
|
57
|
+
output: string[];
|
|
58
|
+
error?: string;
|
|
59
|
+
returnValues?: SerializedReturnValue[];
|
|
60
|
+
/** Set when the script ran but the playtest could not be stopped. */
|
|
61
|
+
stopError?: string;
|
|
62
|
+
summary: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface PlaytestRunArgs {
|
|
66
|
+
code?: string;
|
|
67
|
+
file?: string;
|
|
68
|
+
mode?: PlaytestMode;
|
|
69
|
+
timeout?: number;
|
|
70
|
+
scriptArgs?: string[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function playtestRunHandlerAsync(
|
|
74
|
+
connection: BridgeConnection,
|
|
75
|
+
options: PlaytestRunOptions
|
|
76
|
+
): Promise<PlaytestRunResult> {
|
|
77
|
+
if (!getPlaytestContexts(options.mode).includes(options.context)) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`A ${options.mode} mode playtest has no ${options.context} session to run code in`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const editSession = await connection.resolveSessionAsync(
|
|
84
|
+
options.target,
|
|
85
|
+
'edit'
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
if (options.context === 'server') {
|
|
89
|
+
return runWithPlantedRunnerAsync(editSession, options);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const playtest = await startPlaytestAsync(
|
|
93
|
+
connection,
|
|
94
|
+
editSession,
|
|
95
|
+
options.mode
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
let result: PlaytestRunResult;
|
|
99
|
+
try {
|
|
100
|
+
const session = playtest.sessions[options.context];
|
|
101
|
+
if (!session) {
|
|
102
|
+
throw new Error(`Playtest has no ${options.context} session`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
result = {
|
|
106
|
+
...(await execHandlerAsync(session, {
|
|
107
|
+
scriptContent: options.scriptContent,
|
|
108
|
+
timeout: options.timeout,
|
|
109
|
+
args: options.args,
|
|
110
|
+
})),
|
|
111
|
+
playtestId: playtest.playtestId,
|
|
112
|
+
};
|
|
113
|
+
} catch (err) {
|
|
114
|
+
await tryEndPlaytestAsync(connection, playtest.sessions.server);
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// A playtest left running keeps the script's result worth reporting
|
|
119
|
+
const stopError = await tryEndPlaytestAsync(
|
|
120
|
+
connection,
|
|
121
|
+
playtest.sessions.server
|
|
122
|
+
);
|
|
123
|
+
return stopError ? { ...result, stopError } : result;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function runWithPlantedRunnerAsync(
|
|
127
|
+
editSession: BridgeSession,
|
|
128
|
+
options: PlaytestRunOptions
|
|
129
|
+
): Promise<PlaytestRunResult> {
|
|
130
|
+
const runnerSource = await fs.readFile(
|
|
131
|
+
resolvePackagePath(
|
|
132
|
+
import.meta.url,
|
|
133
|
+
'src',
|
|
134
|
+
'commands',
|
|
135
|
+
'playtest',
|
|
136
|
+
'run',
|
|
137
|
+
'playtest-runner.luau'
|
|
138
|
+
),
|
|
139
|
+
'utf-8'
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const result = await editSession.runPlaytestScriptAsync({
|
|
143
|
+
mode: options.mode,
|
|
144
|
+
script: options.scriptContent,
|
|
145
|
+
runnerSource,
|
|
146
|
+
timeoutSec: (options.timeout ?? DEFAULT_TIMEOUT_MS) / 1000,
|
|
147
|
+
args: options.args,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return toCommandResult(result);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Shapes a bridge ExecResult the way `console exec` reports it. */
|
|
154
|
+
function toCommandResult(result: ExecResult): CommandExecResult {
|
|
155
|
+
return {
|
|
156
|
+
success: result.success,
|
|
157
|
+
output: result.output.map((entry) => entry.body),
|
|
158
|
+
error: result.error,
|
|
159
|
+
returnValues: result.returnValues,
|
|
160
|
+
summary: result.success
|
|
161
|
+
? 'Script executed successfully'
|
|
162
|
+
: `Script failed: ${result.error}`,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Ends the playtest, returning why it could not instead of throwing. */
|
|
167
|
+
async function tryEndPlaytestAsync(
|
|
168
|
+
connection: BridgeConnection,
|
|
169
|
+
serverSession: BridgeSession | undefined
|
|
170
|
+
): Promise<string | undefined> {
|
|
171
|
+
// The script may have ended the playtest itself
|
|
172
|
+
if (!serverSession?.isConnected) {
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
await endPlaytestAsync(connection, serverSession);
|
|
178
|
+
return undefined;
|
|
179
|
+
} catch (err) {
|
|
180
|
+
return err instanceof Error ? err.message : String(err);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export const playtestRunCommand = defineCommand<
|
|
185
|
+
PlaytestRunArgs,
|
|
186
|
+
PlaytestRunResult
|
|
187
|
+
>({
|
|
188
|
+
group: 'playtest',
|
|
189
|
+
name: 'run',
|
|
190
|
+
description:
|
|
191
|
+
'Start a playtest, execute Luau in it, then stop it (--context picks server or client)',
|
|
192
|
+
category: 'execution',
|
|
193
|
+
safety: 'mutate',
|
|
194
|
+
scope: 'connection',
|
|
195
|
+
args: {
|
|
196
|
+
code: arg.positional({
|
|
197
|
+
description: 'Inline Luau code to execute',
|
|
198
|
+
required: false,
|
|
199
|
+
}),
|
|
200
|
+
file: arg.option({
|
|
201
|
+
description: 'Path to a Luau script file to execute',
|
|
202
|
+
alias: 'f',
|
|
203
|
+
}),
|
|
204
|
+
mode: arg.option({
|
|
205
|
+
description:
|
|
206
|
+
'play runs a server and a client with a player, run runs only the server',
|
|
207
|
+
choices: ['play', 'run'],
|
|
208
|
+
default: 'play',
|
|
209
|
+
}),
|
|
210
|
+
timeout: arg.option({
|
|
211
|
+
description: 'Execution timeout in milliseconds',
|
|
212
|
+
type: 'number',
|
|
213
|
+
}),
|
|
214
|
+
scriptArgs: arg.passthrough({
|
|
215
|
+
description:
|
|
216
|
+
'Arguments after --, passed to the script as ... (all strings)',
|
|
217
|
+
}),
|
|
218
|
+
},
|
|
219
|
+
cli: {
|
|
220
|
+
format: (result) =>
|
|
221
|
+
result.stopError
|
|
222
|
+
? `${formatExecText(result)}\nPlaytest is still running: ${
|
|
223
|
+
result.stopError
|
|
224
|
+
}`
|
|
225
|
+
: formatExecText(result),
|
|
226
|
+
},
|
|
227
|
+
handler: async (connection, args, targeting) => {
|
|
228
|
+
const { scriptContent } = await resolveScriptContentAsync(args);
|
|
229
|
+
|
|
230
|
+
return playtestRunHandlerAsync(connection, {
|
|
231
|
+
scriptContent,
|
|
232
|
+
mode: args.mode ?? 'play',
|
|
233
|
+
context: targeting.context ?? 'server',
|
|
234
|
+
target: targeting.target,
|
|
235
|
+
timeout: args.timeout,
|
|
236
|
+
args: args.scriptArgs,
|
|
237
|
+
});
|
|
238
|
+
},
|
|
239
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[=[
|
|
3
|
+
Action that starts a Studio playtest through StudioTestService, answering with
|
|
4
|
+
`playtestEnded` once the playtest is over.
|
|
5
|
+
|
|
6
|
+
- ExecutePlayModeAsync and ExecuteRunModeAsync yield until the playtest ends,
|
|
7
|
+
so the reply comes at the end, not the start. The bridge learns the
|
|
8
|
+
playtest started from its server session connecting.
|
|
9
|
+
- A playtest already in progress fails the call only after it yields, so a
|
|
10
|
+
refusal also arrives as a `playtestEnded` reply, with `success = false`.
|
|
11
|
+
- With `players`, it starts a multiplayer test instead: a server and a
|
|
12
|
+
client per player, each in its own Studio process.
|
|
13
|
+
- The playtest id, bridge port and edit instance id ride along as the test
|
|
14
|
+
args. The playtest's DataModels cannot make the HTTP requests port
|
|
15
|
+
discovery needs, so the plugin in each connects straight to that port,
|
|
16
|
+
registers under the edit session's instance, and answers with the
|
|
17
|
+
playtest id when asked which playtest it belongs to.
|
|
18
|
+
|
|
19
|
+
Request: `{ type: "startPlaytest", payload: { mode: "play" | "run", playtestId, bridgePort, instanceId, players? } }`
|
|
20
|
+
Response: `{ type: "playtestEnded", payload: { playtestId, success, error? } }`
|
|
21
|
+
|
|
22
|
+
@class StartPlaytestAction
|
|
23
|
+
]=]
|
|
24
|
+
|
|
25
|
+
local StartPlaytestAction = {}
|
|
26
|
+
|
|
27
|
+
type SendMessage = (message: { [string]: any }) -> ()
|
|
28
|
+
|
|
29
|
+
--[=[
|
|
30
|
+
Registers the `startPlaytest` handler. The reply waits for the playtest to
|
|
31
|
+
end, so it needs `sendMessage`.
|
|
32
|
+
]=]
|
|
33
|
+
function StartPlaytestAction.register(router: any, sendMessage: SendMessage?)
|
|
34
|
+
router:setResponseType("startPlaytest", "playtestEnded")
|
|
35
|
+
router:register(
|
|
36
|
+
"startPlaytest",
|
|
37
|
+
function(payload: { [string]: any }, requestId: string, sessionId: string): { [string]: any }?
|
|
38
|
+
local mode = payload.mode
|
|
39
|
+
if mode ~= "play" and mode ~= "run" then
|
|
40
|
+
error(`Unknown playtest mode: {tostring(mode)}`)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
local playtestId = payload.playtestId
|
|
44
|
+
local bridgePort = payload.bridgePort
|
|
45
|
+
local instanceId = payload.instanceId
|
|
46
|
+
if type(playtestId) ~= "string" or type(bridgePort) ~= "number" or type(instanceId) ~= "string" then
|
|
47
|
+
error("Missing playtestId, bridgePort or instanceId in startPlaytest request")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if not sendMessage then
|
|
51
|
+
error("Starting a playtest requires a sendMessage callback")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
local players = payload.players
|
|
55
|
+
if players ~= nil and (type(players) ~= "number" or players < 1) then
|
|
56
|
+
error(`Invalid player count: {tostring(players)}`)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
local testArgs = {
|
|
60
|
+
studioBridgePlaytestId = playtestId,
|
|
61
|
+
studioBridgePort = bridgePort,
|
|
62
|
+
studioBridgeInstanceId = instanceId,
|
|
63
|
+
studioBridgePlayers = players,
|
|
64
|
+
}
|
|
65
|
+
task.spawn(StartPlaytestAction._runAsync, sendMessage, mode, testArgs, requestId, sessionId)
|
|
66
|
+
|
|
67
|
+
-- Replied through sendMessage, so the router must not reply as well
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
function StartPlaytestAction._runAsync(
|
|
74
|
+
sendMessage: SendMessage,
|
|
75
|
+
mode: string,
|
|
76
|
+
testArgs: {
|
|
77
|
+
studioBridgePlaytestId: string,
|
|
78
|
+
studioBridgePort: number,
|
|
79
|
+
studioBridgeInstanceId: string,
|
|
80
|
+
studioBridgePlayers: number?,
|
|
81
|
+
},
|
|
82
|
+
requestId: string,
|
|
83
|
+
sessionId: string
|
|
84
|
+
)
|
|
85
|
+
local ok, err = pcall(function()
|
|
86
|
+
local studioTestService = game:GetService("StudioTestService") :: any
|
|
87
|
+
if testArgs.studioBridgePlayers then
|
|
88
|
+
studioTestService:ExecuteMultiplayerTestAsync(testArgs.studioBridgePlayers, testArgs)
|
|
89
|
+
elseif mode == "play" then
|
|
90
|
+
studioTestService:ExecutePlayModeAsync(testArgs)
|
|
91
|
+
else
|
|
92
|
+
studioTestService:ExecuteRunModeAsync(testArgs)
|
|
93
|
+
end
|
|
94
|
+
end)
|
|
95
|
+
|
|
96
|
+
sendMessage({
|
|
97
|
+
type = "playtestEnded",
|
|
98
|
+
sessionId = sessionId,
|
|
99
|
+
requestId = if requestId ~= "" then requestId else nil,
|
|
100
|
+
payload = {
|
|
101
|
+
playtestId = testArgs.studioBridgePlaytestId,
|
|
102
|
+
success = ok,
|
|
103
|
+
error = if ok then nil else tostring(err),
|
|
104
|
+
},
|
|
105
|
+
})
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
return StartPlaytestAction
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `playtest start` — start a StudioTestService playtest and leave it running.
|
|
3
|
+
*
|
|
4
|
+
* Resolves once the playtest's sessions connect, so the next command can
|
|
5
|
+
* target them with `--context server` or `--context client`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { defineCommand } from '../../framework/define-command.js';
|
|
9
|
+
import { arg } from '../../framework/arg-builder.js';
|
|
10
|
+
import type {
|
|
11
|
+
BridgeConnection,
|
|
12
|
+
PlaytestMode,
|
|
13
|
+
SessionContext,
|
|
14
|
+
} from '../../../bridge/index.js';
|
|
15
|
+
import {
|
|
16
|
+
startPlaytestAsync,
|
|
17
|
+
type StartedPlaytest,
|
|
18
|
+
} from '../playtest-sessions.js';
|
|
19
|
+
|
|
20
|
+
export interface PlaytestStartOptions {
|
|
21
|
+
mode: PlaytestMode;
|
|
22
|
+
/** Starts a multiplayer test with this many players. */
|
|
23
|
+
players?: number;
|
|
24
|
+
target?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface PlaytestStartResult {
|
|
28
|
+
playtestId: string;
|
|
29
|
+
mode: PlaytestMode;
|
|
30
|
+
/** How many players a multiplayer test started with. */
|
|
31
|
+
playerCount?: number;
|
|
32
|
+
sessions: Array<{
|
|
33
|
+
sessionId: string;
|
|
34
|
+
context: SessionContext;
|
|
35
|
+
playerName?: string;
|
|
36
|
+
}>;
|
|
37
|
+
summary: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface PlaytestStartArgs {
|
|
41
|
+
mode?: PlaytestMode;
|
|
42
|
+
players?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function playtestStartHandlerAsync(
|
|
46
|
+
connection: BridgeConnection,
|
|
47
|
+
options: PlaytestStartOptions
|
|
48
|
+
): Promise<PlaytestStartResult> {
|
|
49
|
+
const editSession = await connection.resolveSessionAsync(
|
|
50
|
+
options.target,
|
|
51
|
+
'edit'
|
|
52
|
+
);
|
|
53
|
+
const playtest = await startPlaytestAsync(
|
|
54
|
+
connection,
|
|
55
|
+
editSession,
|
|
56
|
+
options.mode,
|
|
57
|
+
options.players
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return toPlaytestStartResult(
|
|
61
|
+
playtest,
|
|
62
|
+
`Playtest started (${describePlaytest(playtest)})`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** `play mode`, `run mode`, or `3 players` for a multiplayer test. */
|
|
67
|
+
export function describePlaytest(playtest: {
|
|
68
|
+
mode: PlaytestMode;
|
|
69
|
+
players?: number;
|
|
70
|
+
}): string {
|
|
71
|
+
return playtest.players !== undefined
|
|
72
|
+
? `${playtest.players} player${playtest.players === 1 ? '' : 's'}`
|
|
73
|
+
: `${playtest.mode} mode`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Report a started playtest and the sessions it opened. */
|
|
77
|
+
export function toPlaytestStartResult(
|
|
78
|
+
playtest: StartedPlaytest,
|
|
79
|
+
summary: string
|
|
80
|
+
): PlaytestStartResult {
|
|
81
|
+
return {
|
|
82
|
+
playtestId: playtest.playtestId,
|
|
83
|
+
mode: playtest.mode,
|
|
84
|
+
playerCount: playtest.players,
|
|
85
|
+
sessions: [playtest.sessions.server, ...playtest.clients]
|
|
86
|
+
.filter((session) => session !== undefined)
|
|
87
|
+
.map((session) => ({
|
|
88
|
+
sessionId: session.info.sessionId,
|
|
89
|
+
context: session.context,
|
|
90
|
+
playerName: session.info.playerName,
|
|
91
|
+
})),
|
|
92
|
+
summary,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function formatPlaytestStartText(result: PlaytestStartResult): string {
|
|
97
|
+
return [
|
|
98
|
+
result.summary,
|
|
99
|
+
...result.sessions.map(
|
|
100
|
+
(session) => ` ${session.context.padEnd(7)}${session.sessionId}`
|
|
101
|
+
),
|
|
102
|
+
].join('\n');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const playtestStartCommand = defineCommand<
|
|
106
|
+
PlaytestStartArgs,
|
|
107
|
+
PlaytestStartResult
|
|
108
|
+
>({
|
|
109
|
+
group: 'playtest',
|
|
110
|
+
name: 'start',
|
|
111
|
+
description:
|
|
112
|
+
'Start a playtest and leave it running (--target picks the edit session)',
|
|
113
|
+
category: 'execution',
|
|
114
|
+
safety: 'mutate',
|
|
115
|
+
scope: 'connection',
|
|
116
|
+
args: {
|
|
117
|
+
mode: arg.option({
|
|
118
|
+
description:
|
|
119
|
+
'play runs a server and a client with a player, run runs only the server',
|
|
120
|
+
choices: ['play', 'run'],
|
|
121
|
+
default: 'play',
|
|
122
|
+
}),
|
|
123
|
+
players: arg.option({
|
|
124
|
+
description:
|
|
125
|
+
'Start a multiplayer test: a server and a client per player, each in its own Studio window',
|
|
126
|
+
type: 'number',
|
|
127
|
+
}),
|
|
128
|
+
},
|
|
129
|
+
cli: {
|
|
130
|
+
format: formatPlaytestStartText,
|
|
131
|
+
},
|
|
132
|
+
handler: async (connection, args, targeting) =>
|
|
133
|
+
playtestStartHandlerAsync(connection, {
|
|
134
|
+
mode: args.mode ?? 'play',
|
|
135
|
+
players: args.players,
|
|
136
|
+
target: targeting.target,
|
|
137
|
+
}),
|
|
138
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[=[
|
|
3
|
+
Action that ends the playtest the session belongs to, answering with the
|
|
4
|
+
playtest id studio-bridge started it under and the mode it runs in, so the
|
|
5
|
+
playtest can be restarted the same way.
|
|
6
|
+
|
|
7
|
+
StudioTestService only allows `EndTest` in the server DataModel of a running
|
|
8
|
+
playtest, so this must target the server session. The playtest stops after
|
|
9
|
+
the reply is sent, since stopping tears down the DataModel answering.
|
|
10
|
+
|
|
11
|
+
Request: `{ type: "endPlaytest", payload: {} }`
|
|
12
|
+
Response: `{ type: "endPlaytestResult", payload: { playtestId?, mode, players? } }`
|
|
13
|
+
|
|
14
|
+
@class EndPlaytestAction
|
|
15
|
+
]=]
|
|
16
|
+
|
|
17
|
+
local EndPlaytestAction = {}
|
|
18
|
+
|
|
19
|
+
--[=[
|
|
20
|
+
Registers the `endPlaytest` handler.
|
|
21
|
+
]=]
|
|
22
|
+
function EndPlaytestAction.register(router: any)
|
|
23
|
+
router:setResponseType("endPlaytest", "endPlaytestResult")
|
|
24
|
+
router:register("endPlaytest", function(_payload: { [string]: any }, _requestId: string, _sessionId: string)
|
|
25
|
+
local runService = game:GetService("RunService")
|
|
26
|
+
if not (runService:IsRunning() and runService:IsServer()) then
|
|
27
|
+
error("Only the server session of a running playtest can end it")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
local studioTestService = game:GetService("StudioTestService") :: any
|
|
31
|
+
local testArgs = studioTestService:GetTestArgs()
|
|
32
|
+
|
|
33
|
+
-- EndTest rejects nil; the value goes unused, since the bridge reads results through execute
|
|
34
|
+
task.defer(function()
|
|
35
|
+
studioTestService:EndTest(true)
|
|
36
|
+
end)
|
|
37
|
+
|
|
38
|
+
local isStudioBridgeTest = type(testArgs) == "table"
|
|
39
|
+
return {
|
|
40
|
+
playtestId = if isStudioBridgeTest then testArgs.studioBridgePlaytestId else nil,
|
|
41
|
+
mode = if runService:IsRunMode() then "run" else "play",
|
|
42
|
+
players = if isStudioBridgeTest then testArgs.studioBridgePlayers else nil,
|
|
43
|
+
}
|
|
44
|
+
end)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
return EndPlaytestAction
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `playtest stop` — end a running playtest from its server session.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { defineCommand } from '../../framework/define-command.js';
|
|
6
|
+
import type { BridgeConnection } from '../../../bridge/index.js';
|
|
7
|
+
import {
|
|
8
|
+
endPlaytestAsync,
|
|
9
|
+
resolvePlaytestServerSessionAsync,
|
|
10
|
+
} from '../playtest-sessions.js';
|
|
11
|
+
|
|
12
|
+
export interface PlaytestStopOptions {
|
|
13
|
+
target?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface PlaytestStopResult {
|
|
17
|
+
/** Absent when the playtest was not started by studio-bridge. */
|
|
18
|
+
playtestId?: string;
|
|
19
|
+
summary: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function playtestStopHandlerAsync(
|
|
23
|
+
connection: BridgeConnection,
|
|
24
|
+
options: PlaytestStopOptions = {}
|
|
25
|
+
): Promise<PlaytestStopResult> {
|
|
26
|
+
const serverSession = await resolvePlaytestServerSessionAsync(
|
|
27
|
+
connection,
|
|
28
|
+
options.target
|
|
29
|
+
);
|
|
30
|
+
const { playtestId } = await endPlaytestAsync(connection, serverSession);
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
playtestId,
|
|
34
|
+
summary: 'Playtest stopped',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const playtestStopCommand = defineCommand<
|
|
39
|
+
Record<string, never>,
|
|
40
|
+
PlaytestStopResult
|
|
41
|
+
>({
|
|
42
|
+
group: 'playtest',
|
|
43
|
+
name: 'stop',
|
|
44
|
+
description: 'Stop the running playtest (--target picks its server session)',
|
|
45
|
+
category: 'execution',
|
|
46
|
+
safety: 'mutate',
|
|
47
|
+
scope: 'connection',
|
|
48
|
+
args: {},
|
|
49
|
+
handler: async (connection, _args, targeting) =>
|
|
50
|
+
playtestStopHandlerAsync(connection, { target: targeting.target }),
|
|
51
|
+
});
|