windows-development-sandbox 1.17.3 → 1.18.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/README.md +1 -1
- package/config.example.json +97 -4
- package/dist/app/features/accounts/accounts.def.d.ts +116 -2
- package/dist/app/features/accounts/accounts.def.js +80 -12
- package/dist/app/features/accounts/accounts.run.d.ts +29 -0
- package/dist/app/features/accounts/accounts.run.js +36 -6
- package/dist/app/features/accounts/index.d.ts +2 -0
- package/dist/app/features/accounts/index.js +4 -1
- package/dist/app/features/accounts/services.def.d.ts +111 -0
- package/dist/app/features/accounts/services.def.js +187 -0
- package/dist/app/features/accounts/services.run.d.ts +65 -0
- package/dist/app/features/accounts/services.run.js +212 -0
- package/dist/app/features/defs.d.ts +112 -1
- package/dist/app/features/defs.js +5 -0
- package/dist/app/features/settings/categories.def.js +21 -4
- package/dist/app/registry.js +5 -1
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-QLGGAG3D.js → chunk-BKF43GJ3.js} +51 -16
- package/dist/bin/{chunk-REE3EMHD.js → chunk-YD3A67RS.js} +3812 -1702
- package/dist/bin/{chunk-XYUVIVJT.js → chunk-Z5D32FN3.js} +1 -1
- package/dist/bin/claude-host.js +2 -2
- package/dist/bin/claude-sbx.js +2 -2
- package/dist/bin/codex-sbx.js +2 -2
- package/dist/bin/gemini-sbx.js +2 -2
- package/dist/bin/sandbox.js +2 -2
- package/dist/bin/sbx-hide.js +2 -2
- package/dist/bin/sbx-show.js +2 -2
- package/dist/cli/commands/launch/launch.js +30 -1
- package/dist/cli/manifest.d.ts +93 -65
- package/dist/cli/manifest.js +23 -5
- package/dist/cli/menu/pages/accounts-page.js +31 -16
- package/dist/cli/services/accounts-service.d.ts +14 -4
- package/dist/cli/services/accounts-service.js +19 -6
- package/dist/cli/services/data-collect.js +26 -1
- package/dist/core/config/defaults.js +47 -4
- package/dist/core/detect/toolchains.d.ts +15 -1
- package/dist/core/detect/toolchains.js +45 -12
- package/dist/core/local-config/overrides.js +6 -0
- package/dist/core/schema/accounts.d.ts +27 -0
- package/dist/core/schema/accounts.js +32 -0
- package/dist/core/schema/config.d.ts +239 -0
- package/dist/core/schema/config.js +6 -0
- package/dist/core/schema/pc-installs.d.ts +7 -0
- package/dist/core/schema/pc-installs.js +17 -0
- package/dist/core/schema/toolchains.d.ts +61 -0
- package/dist/core/schema/toolchains.js +106 -0
- package/dist/core/types.d.ts +18 -0
- package/dist/guest/accounts/adapter.d.ts +25 -0
- package/dist/guest/accounts/adapter.js +21 -0
- package/dist/guest/accounts/adapters.d.ts +5 -0
- package/dist/guest/accounts/adapters.js +18 -0
- package/dist/guest/accounts/apply.d.ts +41 -0
- package/dist/guest/accounts/apply.js +47 -0
- package/dist/guest/accounts/kinds/appstore.d.ts +2 -0
- package/dist/guest/accounts/kinds/appstore.js +7 -0
- package/dist/guest/accounts/kinds/cfx.d.ts +2 -0
- package/dist/guest/accounts/kinds/cfx.js +7 -0
- package/dist/guest/accounts/kinds/epic.d.ts +2 -0
- package/dist/guest/accounts/kinds/epic.js +26 -0
- package/dist/guest/accounts/kinds/expo.d.ts +2 -0
- package/dist/guest/accounts/kinds/expo.js +7 -0
- package/dist/guest/accounts/kinds/keystore.d.ts +2 -0
- package/dist/guest/accounts/kinds/keystore.js +7 -0
- package/dist/guest/accounts/kinds/play.d.ts +2 -0
- package/dist/guest/accounts/kinds/play.js +7 -0
- package/dist/guest/accounts/kinds/steam.d.ts +4 -0
- package/dist/guest/accounts/kinds/steam.js +17 -0
- package/dist/guest/accounts/kinds/unity.d.ts +2 -0
- package/dist/guest/accounts/kinds/unity.js +7 -0
- package/dist/guest/accounts/watch.d.ts +28 -0
- package/dist/guest/accounts/watch.js +78 -0
- package/dist/guest/apps/resolvers-gamedev.d.ts +2 -0
- package/dist/guest/apps/resolvers-gamedev.js +1 -0
- package/dist/guest/apps/resolvers-mobile.d.ts +2 -0
- package/dist/guest/apps/resolvers-mobile.js +1 -0
- package/dist/guest/apps/resolvers.js +4 -0
- package/dist/guest/boot/boot.d.ts +5 -0
- package/dist/guest/boot/boot.js +35 -1
- package/dist/guest/daemon/accounts.d.ts +3 -0
- package/dist/guest/daemon/accounts.js +25 -0
- package/dist/guest/daemon/daemon.js +2 -0
- package/dist/guest/daemon/idle-shutdown.js +3 -1
- package/dist/guest/daemon/sessions.js +2 -0
- package/dist/guest/devtools/android.d.ts +2 -0
- package/dist/guest/devtools/android.js +7 -0
- package/dist/guest/devtools/devtool.d.ts +9 -0
- package/dist/guest/devtools/devtool.js +5 -0
- package/dist/guest/devtools/fivem.d.ts +2 -0
- package/dist/guest/devtools/fivem.js +7 -0
- package/dist/guest/devtools/registry.d.ts +6 -0
- package/dist/guest/devtools/registry.js +12 -0
- package/dist/guest/devtools/steam.d.ts +2 -0
- package/dist/guest/devtools/steam.js +228 -0
- package/dist/guest/devtools/unity.d.ts +2 -0
- package/dist/guest/devtools/unity.js +7 -0
- package/dist/guest/entries/daemon.js +2 -0
- package/dist/guest/entries/tool.d.ts +1 -0
- package/dist/guest/entries/tool.js +17 -0
- package/dist/guest/toolchains/engines/godot.d.ts +4 -0
- package/dist/guest/toolchains/engines/godot.js +4 -0
- package/dist/guest/toolchains/engines/unity-release.d.ts +15 -0
- package/dist/guest/toolchains/engines/unity-release.js +6 -0
- package/dist/guest/toolchains/engines/unity.d.ts +4 -0
- package/dist/guest/toolchains/engines/unity.js +4 -0
- package/dist/guest/toolchains/engines/unreal-engines.d.ts +4 -0
- package/dist/guest/toolchains/engines/unreal-engines.js +4 -0
- package/dist/guest/toolchains/fivem/artifacts.d.ts +6 -0
- package/dist/guest/toolchains/fivem/artifacts.js +7 -0
- package/dist/guest/toolchains/fivem/fivem.d.ts +4 -0
- package/dist/guest/toolchains/fivem/fivem.js +4 -0
- package/dist/guest/toolchains/installers.d.ts +12 -0
- package/dist/guest/toolchains/installers.js +39 -0
- package/dist/guest/toolchains/languages/java.js +1 -1
- package/dist/guest/toolchains/languages/kotlin.d.ts +3 -0
- package/dist/guest/toolchains/languages/kotlin.js +6 -0
- package/dist/guest/toolchains/mobile/android-repo.d.ts +11 -0
- package/dist/guest/toolchains/mobile/android-repo.js +10 -0
- package/dist/guest/toolchains/mobile/android.d.ts +17 -0
- package/dist/guest/toolchains/mobile/android.js +16 -0
- package/dist/guest/toolchains/mobile/dart.d.ts +4 -0
- package/dist/guest/toolchains/mobile/dart.js +4 -0
- package/dist/guest/toolchains/mobile/flutter.d.ts +4 -0
- package/dist/guest/toolchains/mobile/flutter.js +4 -0
- package/dist/guest/toolchains/mobile/react-native.d.ts +4 -0
- package/dist/guest/toolchains/mobile/react-native.js +4 -0
- package/dist/guest/toolchains/native/unreal.d.ts +3 -7
- package/dist/guest/toolchains/native/unreal.js +16 -167
- package/dist/guest/toolchains/native/visual-studio.d.ts +15 -0
- package/dist/guest/toolchains/native/visual-studio.js +159 -0
- package/dist/guest/toolchains/native/vs-request.d.ts +19 -0
- package/dist/guest/toolchains/native/vs-request.js +46 -0
- package/dist/guest/toolchains/not-yet.d.ts +2 -0
- package/dist/guest/toolchains/not-yet.js +6 -0
- package/dist/guest/toolchains/persisted.d.ts +48 -0
- package/dist/guest/toolchains/persisted.js +159 -0
- package/dist/guest/toolchains/plan.js +80 -4
- package/dist/guest/toolchains/steam/apps.d.ts +27 -0
- package/dist/guest/toolchains/steam/apps.js +112 -0
- package/dist/guest/toolchains/steam/client.d.ts +5 -0
- package/dist/guest/toolchains/steam/client.js +67 -0
- package/dist/guest/toolchains/steam/commands.d.ts +58 -0
- package/dist/guest/toolchains/steam/commands.js +155 -0
- package/dist/guest/toolchains/steam/steam.d.ts +4 -0
- package/dist/guest/toolchains/steam/steam.js +61 -0
- package/dist/guest/toolchains/steam/steamcmd-install.d.ts +29 -0
- package/dist/guest/toolchains/steam/steamcmd-install.js +177 -0
- package/dist/guest/toolchains/steam/steamcmd.d.ts +6 -0
- package/dist/guest/toolchains/steam/steamcmd.js +23 -0
- package/dist/guest/toolchains/step.d.ts +10 -0
- package/dist/host/accounts/deliver.d.ts +26 -0
- package/dist/host/accounts/deliver.js +80 -0
- package/dist/host/accounts/handoff.d.ts +17 -0
- package/dist/host/accounts/handoff.js +110 -0
- package/dist/host/accounts/index.d.ts +6 -0
- package/dist/host/accounts/index.js +8 -0
- package/dist/host/accounts/kinds/appstore.d.ts +2 -0
- package/dist/host/accounts/kinds/appstore.js +10 -0
- package/dist/host/accounts/kinds/cfx.d.ts +2 -0
- package/dist/host/accounts/kinds/cfx.js +7 -0
- package/dist/host/accounts/kinds/epic.d.ts +2 -0
- package/dist/host/accounts/kinds/epic.js +15 -0
- package/dist/host/accounts/kinds/expo.d.ts +2 -0
- package/dist/host/accounts/kinds/expo.js +7 -0
- package/dist/host/accounts/kinds/keystore.d.ts +2 -0
- package/dist/host/accounts/kinds/keystore.js +7 -0
- package/dist/host/accounts/kinds/play.d.ts +2 -0
- package/dist/host/accounts/kinds/play.js +7 -0
- package/dist/host/accounts/kinds/steam.d.ts +6 -0
- package/dist/host/accounts/kinds/steam.js +31 -0
- package/dist/host/accounts/kinds/unity.d.ts +2 -0
- package/dist/host/accounts/kinds/unity.js +13 -0
- package/dist/host/accounts/leases.d.ts +40 -0
- package/dist/host/accounts/leases.js +62 -0
- package/dist/host/accounts/source.d.ts +21 -0
- package/dist/host/accounts/source.js +15 -0
- package/dist/host/accounts/sources.d.ts +5 -0
- package/dist/host/accounts/sources.js +18 -0
- package/dist/host/accounts/store.d.ts +23 -0
- package/dist/host/accounts/store.js +74 -0
- package/dist/host/audit/log.d.ts +1 -1
- package/dist/host/launch/generate.d.ts +2 -0
- package/dist/host/launch/generate.js +16 -1
- package/dist/host/launch/hints/android.d.ts +3 -0
- package/dist/host/launch/hints/android.js +3 -0
- package/dist/host/launch/hints/engines.d.ts +3 -0
- package/dist/host/launch/hints/engines.js +3 -0
- package/dist/host/launch/hints/fivem.d.ts +3 -0
- package/dist/host/launch/hints/fivem.js +3 -0
- package/dist/host/launch/hints/hint.d.ts +2 -0
- package/dist/host/launch/hints/hint.js +1 -0
- package/dist/host/launch/hints/index.d.ts +5 -0
- package/dist/host/launch/hints/index.js +29 -0
- package/dist/host/launch/hints/mobile.d.ts +3 -0
- package/dist/host/launch/hints/mobile.js +3 -0
- package/dist/host/launch/hints/steam.d.ts +7 -0
- package/dist/host/launch/hints/steam.js +59 -0
- package/dist/host/launch/index.d.ts +2 -2
- package/dist/host/launch/index.js +2 -2
- package/dist/host/launch/mappings.js +2 -0
- package/dist/host/launch/session-file.js +2 -0
- package/dist/host/launch/stage.js +10 -1
- package/dist/host/launch/toolchains.d.ts +7 -0
- package/dist/host/launch/toolchains.js +11 -0
- package/dist/host/pc-installs/discover.d.ts +19 -0
- package/dist/host/pc-installs/discover.js +59 -0
- package/dist/host/pc-installs/epic.d.ts +2 -0
- package/dist/host/pc-installs/epic.js +7 -0
- package/dist/host/pc-installs/index.d.ts +3 -0
- package/dist/host/pc-installs/index.js +2 -0
- package/dist/host/pc-installs/source.d.ts +9 -0
- package/dist/host/pc-installs/source.js +1 -0
- package/dist/host/pc-installs/steam.d.ts +16 -0
- package/dist/host/pc-installs/steam.js +143 -0
- package/dist/host/pc-installs/unity.d.ts +2 -0
- package/dist/host/pc-installs/unity.js +7 -0
- package/dist/host/pc-installs/unreal.d.ts +2 -0
- package/dist/host/pc-installs/unreal.js +7 -0
- package/dist/host/profile/accounts.d.ts +21 -6
- package/dist/host/profile/accounts.js +108 -28
- package/dist/host/profile/claude-login.d.ts +32 -2
- package/dist/host/profile/claude-login.js +100 -8
- package/dist/host/profile/index.d.ts +1 -1
- package/dist/host/profile/index.js +1 -1
- package/dist/host/secrets/launch-secrets.js +1 -0
- package/dist/runtime/agent.js +321 -9
- package/dist/runtime/daemon.js +1987 -604
- package/dist/runtime/db.js +334 -11
- package/dist/runtime/main.js +2519 -723
- package/dist/runtime/netproxy.js +321 -9
- package/dist/runtime/tool.js +28549 -0
- package/dist/runtime/view.js +321 -9
- package/dist/selftest/accounts.test.js +172 -1
- package/dist/selftest/agent-paths.test.js +1 -0
- package/dist/selftest/android.test.d.ts +2 -0
- package/dist/selftest/android.test.js +7 -0
- package/dist/selftest/app.test.js +1 -1
- package/dist/selftest/engines.test.d.ts +2 -0
- package/dist/selftest/engines.test.js +7 -0
- package/dist/selftest/fivem.test.d.ts +2 -0
- package/dist/selftest/fivem.test.js +7 -0
- package/dist/selftest/generate.test.js +1 -1
- package/dist/selftest/index.js +18 -0
- package/dist/selftest/menu-screens.js +1 -0
- package/dist/selftest/menu.test.js +2 -1
- package/dist/selftest/mobile.test.d.ts +2 -0
- package/dist/selftest/mobile.test.js +7 -0
- package/dist/selftest/pc-installs.test.d.ts +2 -0
- package/dist/selftest/pc-installs.test.js +111 -0
- package/dist/selftest/persisted-installs.test.d.ts +2 -0
- package/dist/selftest/persisted-installs.test.js +107 -0
- package/dist/selftest/projects.test.js +6 -4
- package/dist/selftest/service-accounts.test.d.ts +2 -0
- package/dist/selftest/service-accounts.test.js +320 -0
- package/dist/selftest/steam.test.d.ts +2 -0
- package/dist/selftest/steam.test.js +316 -0
- package/dist/selftest/storage-helper.test.js +31 -8
- package/dist/selftest/support/engine-golden.js +3 -0
- package/dist/selftest/support/fixtures.d.ts +87 -0
- package/dist/selftest/support/fixtures.js +4 -3
- package/dist/selftest/support/pc-memory.d.ts +2 -0
- package/dist/selftest/support/pc-memory.js +17 -0
- package/dist/selftest/support/web-preview.js +20 -1
- package/dist/selftest/unity.test.d.ts +2 -0
- package/dist/selftest/unity.test.js +7 -0
- package/dist/shared/accounts/fingerprint.d.ts +1 -0
- package/dist/shared/accounts/fingerprint.js +20 -0
- package/dist/shared/accounts/index.d.ts +5 -0
- package/dist/shared/accounts/index.js +7 -0
- package/dist/shared/accounts/kinds/epic.d.ts +10 -0
- package/dist/shared/accounts/kinds/epic.js +56 -0
- package/dist/shared/accounts/kinds/steam.d.ts +28 -0
- package/dist/shared/accounts/kinds/steam.js +99 -0
- package/dist/shared/accounts/kinds.d.ts +41 -0
- package/dist/shared/accounts/kinds.js +154 -0
- package/dist/shared/accounts/payloads.d.ts +151 -0
- package/dist/shared/accounts/payloads.js +128 -0
- package/dist/shared/apps/catalogue-gamedev.d.ts +2 -0
- package/dist/shared/apps/catalogue-gamedev.js +1 -0
- package/dist/shared/apps/catalogue-mobile.d.ts +2 -0
- package/dist/shared/apps/catalogue-mobile.js +1 -0
- package/dist/shared/apps/catalogue-modding.d.ts +2 -0
- package/dist/shared/apps/catalogue-modding.js +1 -0
- package/dist/shared/apps/catalogue.d.ts +1 -0
- package/dist/shared/apps/catalogue.js +6 -1
- package/dist/shared/channel/schema.d.ts +183 -0
- package/dist/shared/channel/secrets.d.ts +42 -0
- package/dist/shared/channel/secrets.js +3 -0
- package/dist/shared/download/downloader.d.ts +7 -0
- package/dist/shared/download/downloader.js +10 -3
- package/dist/shared/installs.d.ts +19 -0
- package/dist/shared/installs.js +13 -0
- package/dist/shared/io/bounded.d.ts +6 -0
- package/dist/shared/io/bounded.js +38 -0
- package/dist/shared/io/index.d.ts +2 -0
- package/dist/shared/io/index.js +2 -0
- package/dist/shared/io/text.d.ts +9 -0
- package/dist/shared/io/text.js +18 -0
- package/dist/shared/paths/guest-paths.js +1 -1
- package/dist/shared/paths/index.d.ts +1 -0
- package/dist/shared/paths/index.js +1 -0
- package/dist/shared/paths/pc-installs.d.ts +20 -0
- package/dist/shared/paths/pc-installs.js +19 -0
- package/dist/shared/vdf.d.ts +25 -0
- package/dist/shared/vdf.js +151 -0
- package/dist/sync/sync-cycle.js +9 -0
- package/dist/web/index.html +1 -1
- package/dist/web/{main-JTH3FT4O.js → main-CWIF4VQI.js} +63 -61
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/package.json +1 -1
- package/sandbox/scripts/add-firewall-port.ps1 +13 -0
- package/sandbox/templates/fivem/README.txt +2 -0
- package/schemas/config.schema.json +485 -0
- package/schemas/sandbox-config.schema.json +416 -0
|
@@ -1,163 +1,26 @@
|
|
|
1
|
-
// Unreal Engine development (toolchains.unreal):
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// (tools\visualstudio\layout) spares later boots the download. The engine itself comes from the Epic Games Launcher.
|
|
6
|
-
import fs from 'node:fs';
|
|
1
|
+
// Unreal Engine development (toolchains.unreal): the DirectX End-User Runtime the engine lists (a real installer: it
|
|
2
|
+
// runs every boot), then the engines (engines/unreal-engines.ts: the launcher's install folder on the data disk, PC
|
|
3
|
+
// engines from pcInstalls, the derived data cache). Visual Studio Community with the C++ game workload is its own step
|
|
4
|
+
// (visual-studio.ts), which the plan runs first. The engine itself comes from the Epic Games Launcher or its source.
|
|
7
5
|
import os from 'node:os';
|
|
8
6
|
import path from 'node:path';
|
|
9
|
-
import { z } from 'zod';
|
|
10
7
|
import { spawnAsync } from '../../../shared/download/index.js';
|
|
11
|
-
import { writeJsonAtomic } from '../../../shared/io/json.js';
|
|
12
8
|
import { safeRemove } from '../../../shared/io/safe-remove.js';
|
|
13
9
|
import { dryRun } from '../../runtime/paths.js';
|
|
14
|
-
import { execOutput } from '../../runtime/process.js';
|
|
15
10
|
import { exists, mkdirp } from '../../runtime/fs.js';
|
|
16
|
-
import { log
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
11
|
+
import { log } from '../../runtime/log.js';
|
|
12
|
+
import { setupUnrealEngines } from '../engines/unreal-engines.js';
|
|
13
|
+
import { SIGNERS, signedInstaller } from '../installers.js';
|
|
19
14
|
import { tool } from '../tool-env.js';
|
|
20
|
-
import {
|
|
21
|
-
|
|
15
|
+
import { installedVs } from './visual-studio.js';
|
|
16
|
+
export { UNREAL_COMPONENTS } from './vs-request.js';
|
|
22
17
|
const DIRECTX_URL = 'https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe';
|
|
23
|
-
/**
|
|
24
|
-
* What Epic lists for Unreal Engine 5 with Visual Studio 2022: the game workload, MSVC v143, a Windows SDK of
|
|
25
|
-
* 10.0.18362 or newer, the C++ profiling tools, the .NET Framework targeting packs some engine tools build against,
|
|
26
|
-
* Visual Studio's Unreal support and the Unreal Engine installer (the Epic Games Launcher).
|
|
27
|
-
*/
|
|
28
|
-
export const UNREAL_COMPONENTS = [
|
|
29
|
-
'Microsoft.VisualStudio.Workload.NativeGame',
|
|
30
|
-
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
|
|
31
|
-
'Microsoft.VisualStudio.Component.Windows11SDK.22621',
|
|
32
|
-
'Microsoft.VisualStudio.Component.VC.DiagnosticTools',
|
|
33
|
-
'Microsoft.Net.Component.4.6.2.TargetingPack',
|
|
34
|
-
'Microsoft.Net.Component.4.8.SDK',
|
|
35
|
-
'Component.Unreal.Ide',
|
|
36
|
-
'Component.Unreal',
|
|
37
|
-
];
|
|
38
|
-
/** Visual Studio installer exit codes that mean installed: 0, and 3010 (a restart would finish it, not needed here). */
|
|
39
|
-
const OK_EXIT_CODES = [0, 3010];
|
|
40
|
-
/** Free room the offline copy needs before it is made (it grows to about 10 GB). */
|
|
41
|
-
const LAYOUT_ROOM_BYTES = 15 * 1024 ** 3;
|
|
42
|
-
/**
|
|
43
|
-
* Free room on the sandbox's own disk before Visual Studio goes on it: it takes about 7 GB, and the disk (about 40 GB)
|
|
44
|
-
* also holds the paging file and every build, so it is installed only when about 13 GB stay free after it.
|
|
45
|
-
*/
|
|
46
|
-
const INSTALL_ROOM_BYTES = 20 * 1024 ** 3;
|
|
47
|
-
const ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
|
|
48
|
-
const VS_DIR = tool('visualstudio');
|
|
49
|
-
const BOOTSTRAPPER = path.join(VS_DIR, 'vs_community.exe');
|
|
50
|
-
const LAYOUT = path.join(VS_DIR, 'layout');
|
|
51
|
-
const LAYOUT_MARKER = path.join(LAYOUT, '.complete.json');
|
|
52
|
-
const LayoutSchema = z.object({ components: z.array(z.string()) });
|
|
53
|
-
const VSWHERE = path.join(process.env['ProgramFiles(x86)'] ?? 'C:\\Program Files (x86)', 'Microsoft Visual Studio', 'Installer', 'vswhere.exe');
|
|
54
|
-
/** The newest Visual Studio with the C++ compiler: its folder and version, or null. */
|
|
55
|
-
function installedVs() {
|
|
56
|
-
if (!exists(VSWHERE))
|
|
57
|
-
return null;
|
|
58
|
-
const ask = (property) => execOutput(VSWHERE, [
|
|
59
|
-
'-latest',
|
|
60
|
-
'-products',
|
|
61
|
-
'*',
|
|
62
|
-
'-requires',
|
|
63
|
-
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
|
|
64
|
-
'-property',
|
|
65
|
-
property,
|
|
66
|
-
]);
|
|
67
|
-
const at = ask('installationPath');
|
|
68
|
-
return at ? { path: at, version: ask('installationVersion') || 'installed' } : null;
|
|
69
|
-
}
|
|
70
|
-
/** A Microsoft-signed installer kept in tools\ (downloaded once); a file with a bad signature is deleted. */
|
|
71
|
-
async function signedInstaller(url, file, what) {
|
|
72
|
-
if (!exists(file)) {
|
|
73
|
-
log('Downloading ' + what + ' ...');
|
|
74
|
-
mkdirp(path.dirname(file));
|
|
75
|
-
await downloadFile(url, file);
|
|
76
|
-
}
|
|
77
|
-
if (signerOf(file) !== MICROSOFT_SIGNER) {
|
|
78
|
-
fs.rmSync(file, { force: true });
|
|
79
|
-
throw new Error(path.basename(file) + ' is not signed by Microsoft; deleted it (it is downloaded again next boot)');
|
|
80
|
-
}
|
|
81
|
-
return file;
|
|
82
|
-
}
|
|
83
|
-
function freeBytes(dir) {
|
|
84
|
-
try {
|
|
85
|
-
const s = fs.statfsSync(dir);
|
|
86
|
-
return s.bavail * s.bsize;
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
return 0;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
/** The offline copy's installer when it holds every component; made or completed when there is room. */
|
|
93
|
-
async function layoutInstaller(bootstrapper, ids) {
|
|
94
|
-
const installer = path.join(LAYOUT, 'vs_community.exe');
|
|
95
|
-
const has = () => {
|
|
96
|
-
if (!exists(LAYOUT_MARKER) || !exists(installer))
|
|
97
|
-
return false;
|
|
98
|
-
try {
|
|
99
|
-
const done = LayoutSchema.parse(JSON.parse(fs.readFileSync(LAYOUT_MARKER, 'utf8')));
|
|
100
|
-
return ids.every((id) => done.components.includes(id));
|
|
101
|
-
}
|
|
102
|
-
catch {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
if (has())
|
|
107
|
-
return installer;
|
|
108
|
-
if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
|
|
109
|
-
warn('unreal: not keeping the install files (less than 15 GB free in ' + VS_DIR + '); downloading this boot');
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
log('Saving the Visual Studio install files for later boots (~10 GB, once) ...');
|
|
113
|
-
fs.rmSync(LAYOUT_MARKER, { force: true });
|
|
114
|
-
const code = await spawnAsync(bootstrapper, [
|
|
115
|
-
'--layout',
|
|
116
|
-
LAYOUT,
|
|
117
|
-
'--lang',
|
|
118
|
-
'en-US',
|
|
119
|
-
'--quiet',
|
|
120
|
-
'--wait',
|
|
121
|
-
...ids.flatMap((id) => ['--add', id]),
|
|
122
|
-
]);
|
|
123
|
-
if (!OK_EXIT_CODES.includes(code) || !exists(installer)) {
|
|
124
|
-
warn('unreal: saving the install files failed (exit ' + code + '); downloading this boot');
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
writeJsonAtomic(LAYOUT_MARKER, { components: [...ids] });
|
|
128
|
-
return installer;
|
|
129
|
-
}
|
|
130
|
-
async function installVisualStudio(config, ids) {
|
|
131
|
-
const bootstrapper = await signedInstaller(BOOTSTRAPPER_URL, BOOTSTRAPPER, 'the Visual Studio installer');
|
|
132
|
-
let installer = null;
|
|
133
|
-
if (config.keepInstallFiles) {
|
|
134
|
-
try {
|
|
135
|
-
installer = await layoutInstaller(bootstrapper, ids);
|
|
136
|
-
}
|
|
137
|
-
catch (e) {
|
|
138
|
-
warn('unreal: the offline copy failed (' + errMsg(e) + '); downloading this boot');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
log('Installing Visual Studio Community 2022 with the C++ game workload' +
|
|
142
|
-
(installer ? ' from the saved install files' : ' (downloads ~5-8 GB)') +
|
|
143
|
-
' ...');
|
|
144
|
-
const code = await spawnAsync(installer ?? bootstrapper, [
|
|
145
|
-
'--quiet',
|
|
146
|
-
'--wait',
|
|
147
|
-
'--norestart',
|
|
148
|
-
'--nocache',
|
|
149
|
-
...(installer ? ['--noWeb'] : []),
|
|
150
|
-
...ids.flatMap((id) => ['--add', id]),
|
|
151
|
-
]);
|
|
152
|
-
if (!OK_EXIT_CODES.includes(code) || !installedVs())
|
|
153
|
-
throw new Error('the Visual Studio installer failed (exit ' + code + '); its logs are the dd_*.log files in ' + os.tmpdir());
|
|
154
|
-
}
|
|
155
18
|
/** The June 2010 DirectX End-User Runtime (D3DX, XAudio 2.7, XInput 1.3), which Epic lists for the engine. */
|
|
156
19
|
async function installDirectX() {
|
|
157
20
|
const system32 = path.join(process.env.WINDIR ?? 'C:\\Windows', 'System32');
|
|
158
21
|
if (exists(path.join(system32, 'd3dx9_43.dll')) && exists(path.join(system32, 'XAudio2_7.dll')))
|
|
159
22
|
return;
|
|
160
|
-
const redist = await signedInstaller(DIRECTX_URL, path.join(
|
|
23
|
+
const redist = await signedInstaller(DIRECTX_URL, path.join(tool('visualstudio'), 'directx_Jun2010_redist.exe'), 'the DirectX End-User Runtime (~95 MB once)', SIGNERS.microsoft);
|
|
161
24
|
const unpacked = path.join(os.tmpdir(), 'directx-redist');
|
|
162
25
|
safeRemove(unpacked, os.tmpdir());
|
|
163
26
|
mkdirp(unpacked);
|
|
@@ -168,31 +31,17 @@ async function installDirectX() {
|
|
|
168
31
|
if (code !== 0)
|
|
169
32
|
throw new Error('the DirectX End-User Runtime installer failed (exit ' + code + ')');
|
|
170
33
|
}
|
|
171
|
-
export async function setupUnreal(env, config) {
|
|
34
|
+
export async function setupUnreal(env, config, ctx) {
|
|
172
35
|
if (!config.acceptLicense)
|
|
173
36
|
throw new Error('Unreal tools are installed only with toolchains.unreal.acceptLicense = true: Visual Studio Community and the DirectX End-User Runtime come under Microsoft licence terms (https://visualstudio.microsoft.com/license-terms/)');
|
|
174
|
-
const bad = config.components.find((id) => !ID.test(id));
|
|
175
|
-
if (bad)
|
|
176
|
-
throw new Error('toolchains.unreal.components: "' + bad + '" is not a Visual Studio component ID');
|
|
177
|
-
const ids = [...new Set([...UNREAL_COMPONENTS, ...config.components])];
|
|
178
37
|
if (dryRun) {
|
|
179
|
-
log('(dry run) would install
|
|
38
|
+
log('(dry run) would install the DirectX End-User Runtime and set up the Unreal engines');
|
|
180
39
|
return;
|
|
181
40
|
}
|
|
182
|
-
if (!installedVs()) {
|
|
183
|
-
const programFiles = process.env.ProgramFiles ?? 'C:\\Program Files';
|
|
184
|
-
const free = freeBytes(programFiles);
|
|
185
|
-
if (free < INSTALL_ROOM_BYTES)
|
|
186
|
-
throw new Error('not installing Visual Studio: the sandbox disk has ' +
|
|
187
|
-
(free / 1024 ** 3).toFixed(1) +
|
|
188
|
-
' GB free and it needs 20 GB (7 GB for Visual Studio, the rest for builds and the paging file)');
|
|
189
|
-
await installVisualStudio(config, ids);
|
|
190
|
-
}
|
|
191
41
|
await installDirectX();
|
|
42
|
+
await setupUnrealEngines(env, config, ctx);
|
|
192
43
|
const vs = installedVs();
|
|
193
|
-
env.summary.push('unreal:
|
|
194
|
-
vs.version +
|
|
195
|
-
'
|
|
196
|
-
vs.path +
|
|
197
|
-
'; DirectX End-User Runtime; get the engine from the Epic Games Launcher (Start menu)');
|
|
44
|
+
env.summary.push('unreal: ' +
|
|
45
|
+
(vs ? 'Visual Studio ' + vs.version + ' (C++ game workload, Windows 11 SDK, Unreal support); ' : '') +
|
|
46
|
+
'DirectX End-User Runtime; get the engine from the Epic Games Launcher (Start menu)');
|
|
198
47
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ToolEnv } from '../tool-env.js';
|
|
2
|
+
import type { VsRequest } from './vs-request.js';
|
|
3
|
+
export { BUILD_TOOLS_COMPONENTS, UNREAL_COMPONENTS, visualStudioWanted, type VsRequest } from './vs-request.js';
|
|
4
|
+
/** The newest Visual Studio (or Build Tools) with the C++ compiler: its folder and version, or null. */
|
|
5
|
+
export declare function installedVs(): {
|
|
6
|
+
path: string;
|
|
7
|
+
version: string;
|
|
8
|
+
} | null;
|
|
9
|
+
/** Visual Studio as asked for: installed at boot when it is not there yet; its folder and version. */
|
|
10
|
+
export declare function ensureVisualStudio(env: ToolEnv, req: VsRequest, o: {
|
|
11
|
+
keepInstallFiles: boolean;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
path: string;
|
|
14
|
+
version: string;
|
|
15
|
+
}>;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// Visual Studio for the toolchains that need the real one (vs-request.ts says which): Community with the C++ game
|
|
2
|
+
// workload for Unreal (its build tool finds Visual Studio through the Setup API, so the portable MSVC does not do), or
|
|
3
|
+
// the Build Tools' C++ parts for Flutter desktop and Unity IL2CPP. A real installer: it runs every boot, on the
|
|
4
|
+
// sandbox's own disk, and never while sessions run (they would need a restart). The bootstrapper is kept in tools\
|
|
5
|
+
// and run only when Microsoft's signature checks out; with keepInstallFiles an offline copy of the install files
|
|
6
|
+
// (tools\visualstudio\layout) spares later boots the download.
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import os from 'node:os';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { spawnAsync } from '../../../shared/download/index.js';
|
|
12
|
+
import { writeJsonAtomic } from '../../../shared/io/json.js';
|
|
13
|
+
import { execOutput } from '../../runtime/process.js';
|
|
14
|
+
import { exists, mkdirp } from '../../runtime/fs.js';
|
|
15
|
+
import { log, warn } from '../../runtime/log.js';
|
|
16
|
+
import { duringSession } from '../../runtime/project-context.js';
|
|
17
|
+
import { errMsg } from '../../../core/util/errors.js';
|
|
18
|
+
import { SIGNERS, signedInstaller } from '../installers.js';
|
|
19
|
+
import { assertLocalRoom, freeBytes } from '../persisted.js';
|
|
20
|
+
import { tool } from '../tool-env.js';
|
|
21
|
+
export { BUILD_TOOLS_COMPONENTS, UNREAL_COMPONENTS, visualStudioWanted } from './vs-request.js';
|
|
22
|
+
const BOOTSTRAPPERS = {
|
|
23
|
+
community: {
|
|
24
|
+
url: 'https://aka.ms/vs/17/release/vs_community.exe',
|
|
25
|
+
file: 'vs_community.exe',
|
|
26
|
+
name: 'Visual Studio Community 2022',
|
|
27
|
+
},
|
|
28
|
+
buildtools: {
|
|
29
|
+
url: 'https://aka.ms/vs/17/release/vs_buildtools.exe',
|
|
30
|
+
file: 'vs_buildtools.exe',
|
|
31
|
+
name: 'Visual Studio Build Tools 2022',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
/** What each takes on the sandbox's own disk (13 GB more must stay free: assertLocalRoom). */
|
|
35
|
+
const INSTALL_BYTES = {
|
|
36
|
+
community: 7 * 1024 ** 3,
|
|
37
|
+
buildtools: 5 * 1024 ** 3,
|
|
38
|
+
};
|
|
39
|
+
/** Visual Studio installer exit codes that mean installed: 0, and 3010 (a restart would finish it, not needed here). */
|
|
40
|
+
const OK_EXIT_CODES = [0, 3010];
|
|
41
|
+
/** Free room the offline copy needs before it is made (it grows to about 10 GB). */
|
|
42
|
+
const LAYOUT_ROOM_BYTES = 15 * 1024 ** 3;
|
|
43
|
+
const ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
|
|
44
|
+
const VS_DIR = tool('visualstudio');
|
|
45
|
+
const LayoutSchema = z.object({ components: z.array(z.string()) });
|
|
46
|
+
const VSWHERE = path.join(process.env['ProgramFiles(x86)'] ?? 'C:\\Program Files (x86)', 'Microsoft Visual Studio', 'Installer', 'vswhere.exe');
|
|
47
|
+
/** The newest Visual Studio (or Build Tools) with the C++ compiler: its folder and version, or null. */
|
|
48
|
+
export function installedVs() {
|
|
49
|
+
if (!exists(VSWHERE))
|
|
50
|
+
return null;
|
|
51
|
+
const ask = (property) => execOutput(VSWHERE, [
|
|
52
|
+
'-latest',
|
|
53
|
+
'-products',
|
|
54
|
+
'*',
|
|
55
|
+
'-requires',
|
|
56
|
+
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
|
|
57
|
+
'-property',
|
|
58
|
+
property,
|
|
59
|
+
]);
|
|
60
|
+
const at = ask('installationPath');
|
|
61
|
+
return at ? { path: at, version: ask('installationVersion') || 'installed' } : null;
|
|
62
|
+
}
|
|
63
|
+
function layoutDir(product) {
|
|
64
|
+
return path.join(VS_DIR, product === 'community' ? 'layout' : 'layout-buildtools');
|
|
65
|
+
}
|
|
66
|
+
/** The offline copy's installer when it holds every component; made or completed when there is room. */
|
|
67
|
+
async function layoutInstaller(req, bootstrapper) {
|
|
68
|
+
const layout = layoutDir(req.product);
|
|
69
|
+
const marker = path.join(layout, '.complete.json');
|
|
70
|
+
const installer = path.join(layout, BOOTSTRAPPERS[req.product].file);
|
|
71
|
+
const has = () => {
|
|
72
|
+
if (!exists(marker) || !exists(installer))
|
|
73
|
+
return false;
|
|
74
|
+
try {
|
|
75
|
+
const done = LayoutSchema.parse(JSON.parse(fs.readFileSync(marker, 'utf8')));
|
|
76
|
+
return req.components.every((id) => done.components.includes(id));
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
if (has())
|
|
83
|
+
return installer;
|
|
84
|
+
if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
|
|
85
|
+
warn('Visual Studio: not keeping the install files (less than 15 GB free in ' + VS_DIR + '); downloading this boot');
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
log('Saving the Visual Studio install files for later boots (~10 GB, once) ...');
|
|
89
|
+
fs.rmSync(marker, { force: true });
|
|
90
|
+
const code = await spawnAsync(bootstrapper, [
|
|
91
|
+
'--layout',
|
|
92
|
+
layout,
|
|
93
|
+
'--lang',
|
|
94
|
+
'en-US',
|
|
95
|
+
'--quiet',
|
|
96
|
+
'--wait',
|
|
97
|
+
...req.components.flatMap((id) => ['--add', id]),
|
|
98
|
+
]);
|
|
99
|
+
if (!OK_EXIT_CODES.includes(code) || !exists(installer)) {
|
|
100
|
+
warn('Visual Studio: saving the install files failed (exit ' + code + '); downloading this boot');
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
writeJsonAtomic(marker, { components: [...req.components] });
|
|
104
|
+
return installer;
|
|
105
|
+
}
|
|
106
|
+
async function install(req, keepInstallFiles) {
|
|
107
|
+
const boot = BOOTSTRAPPERS[req.product];
|
|
108
|
+
const bootstrapper = await signedInstaller(boot.url, path.join(VS_DIR, boot.file), 'the ' + boot.name + ' installer', SIGNERS.microsoft);
|
|
109
|
+
let installer = null;
|
|
110
|
+
if (keepInstallFiles) {
|
|
111
|
+
try {
|
|
112
|
+
installer = await layoutInstaller(req, bootstrapper);
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
warn('Visual Studio: the offline copy failed (' + errMsg(e) + '); downloading this boot');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
log('Installing ' + boot.name + (installer ? ' from the saved install files' : ' (downloads ~5-8 GB)') + ' ...');
|
|
119
|
+
const code = await spawnAsync(installer ?? bootstrapper, [
|
|
120
|
+
'--quiet',
|
|
121
|
+
'--wait',
|
|
122
|
+
'--norestart',
|
|
123
|
+
'--nocache',
|
|
124
|
+
...(installer ? ['--noWeb'] : []),
|
|
125
|
+
...req.components.flatMap((id) => ['--add', id]),
|
|
126
|
+
]);
|
|
127
|
+
if (!OK_EXIT_CODES.includes(code) || !installedVs())
|
|
128
|
+
throw new Error('the Visual Studio installer failed (exit ' + code + '); its logs are the dd_*.log files in ' + os.tmpdir());
|
|
129
|
+
}
|
|
130
|
+
/** Visual Studio as asked for: installed at boot when it is not there yet; its folder and version. */
|
|
131
|
+
export async function ensureVisualStudio(env, req, o) {
|
|
132
|
+
if (!req.accepted)
|
|
133
|
+
throw new Error('Visual Studio (for ' +
|
|
134
|
+
req.for.join(', ') +
|
|
135
|
+
') is installed only with ' +
|
|
136
|
+
req.licence +
|
|
137
|
+
' = true: it comes under Microsoft licence terms (https://visualstudio.microsoft.com/license-terms/)');
|
|
138
|
+
const bad = req.components.find((id) => !ID.test(id));
|
|
139
|
+
if (bad)
|
|
140
|
+
throw new Error('"' + bad + '" is not a Visual Studio component ID');
|
|
141
|
+
const have = installedVs();
|
|
142
|
+
if (have)
|
|
143
|
+
return have;
|
|
144
|
+
if (duringSession())
|
|
145
|
+
throw new Error('Visual Studio is installed when the sandbox starts: restart it (sandbox restart) to get it');
|
|
146
|
+
assertLocalRoom(INSTALL_BYTES[req.product], BOOTSTRAPPERS[req.product].name);
|
|
147
|
+
await install(req, o.keepInstallFiles);
|
|
148
|
+
const vs = installedVs();
|
|
149
|
+
env.summary.push('visual studio: ' +
|
|
150
|
+
BOOTSTRAPPERS[req.product].name +
|
|
151
|
+
' ' +
|
|
152
|
+
vs.version +
|
|
153
|
+
' at ' +
|
|
154
|
+
vs.path +
|
|
155
|
+
' (for ' +
|
|
156
|
+
req.for.join(', ') +
|
|
157
|
+
')');
|
|
158
|
+
return vs;
|
|
159
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Toolchains } from '../../../core/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* What Epic lists for Unreal Engine 5 with Visual Studio 2022: the game workload, MSVC v143, a Windows SDK of
|
|
4
|
+
* 10.0.18362 or newer, the C++ profiling tools, the .NET Framework targeting packs some engine tools build against,
|
|
5
|
+
* Visual Studio's Unreal support and the Unreal Engine installer (the Epic Games Launcher).
|
|
6
|
+
*/
|
|
7
|
+
export declare const UNREAL_COMPONENTS: readonly ["Microsoft.VisualStudio.Workload.NativeGame", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "Microsoft.VisualStudio.Component.Windows11SDK.22621", "Microsoft.VisualStudio.Component.VC.DiagnosticTools", "Microsoft.Net.Component.4.6.2.TargetingPack", "Microsoft.Net.Component.4.8.SDK", "Component.Unreal.Ide", "Component.Unreal"];
|
|
8
|
+
/** The Build Tools' C++ desktop parts: MSVC v143 and a Windows 11 SDK (Flutter desktop, Unity IL2CPP). */
|
|
9
|
+
export declare const BUILD_TOOLS_COMPONENTS: readonly ["Microsoft.VisualStudio.Workload.VCTools", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "Microsoft.VisualStudio.Component.Windows11SDK.22621"];
|
|
10
|
+
export interface VsRequest {
|
|
11
|
+
readonly product: 'community' | 'buildtools';
|
|
12
|
+
readonly components: readonly string[];
|
|
13
|
+
/** Who asks for it (for messages): unreal, flutter, unity. */
|
|
14
|
+
readonly for: readonly string[];
|
|
15
|
+
/** The licence setting that must be on (toolchains.unreal.acceptLicense or toolchains.msvc.acceptLicense). */
|
|
16
|
+
readonly licence: string;
|
|
17
|
+
readonly accepted: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function visualStudioWanted(t: Toolchains, on?: (setting: boolean | 'auto', name: string) => boolean): VsRequest | null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What Epic lists for Unreal Engine 5 with Visual Studio 2022: the game workload, MSVC v143, a Windows SDK of
|
|
3
|
+
* 10.0.18362 or newer, the C++ profiling tools, the .NET Framework targeting packs some engine tools build against,
|
|
4
|
+
* Visual Studio's Unreal support and the Unreal Engine installer (the Epic Games Launcher).
|
|
5
|
+
*/
|
|
6
|
+
export const UNREAL_COMPONENTS = [
|
|
7
|
+
'Microsoft.VisualStudio.Workload.NativeGame',
|
|
8
|
+
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
|
|
9
|
+
'Microsoft.VisualStudio.Component.Windows11SDK.22621',
|
|
10
|
+
'Microsoft.VisualStudio.Component.VC.DiagnosticTools',
|
|
11
|
+
'Microsoft.Net.Component.4.6.2.TargetingPack',
|
|
12
|
+
'Microsoft.Net.Component.4.8.SDK',
|
|
13
|
+
'Component.Unreal.Ide',
|
|
14
|
+
'Component.Unreal',
|
|
15
|
+
];
|
|
16
|
+
/** The Build Tools' C++ desktop parts: MSVC v143 and a Windows 11 SDK (Flutter desktop, Unity IL2CPP). */
|
|
17
|
+
export const BUILD_TOOLS_COMPONENTS = [
|
|
18
|
+
'Microsoft.VisualStudio.Workload.VCTools',
|
|
19
|
+
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
|
|
20
|
+
'Microsoft.VisualStudio.Component.Windows11SDK.22621',
|
|
21
|
+
];
|
|
22
|
+
/** Whether a toolchain is on (the host resolved "auto"; a session file that still says "auto" counts as off). */
|
|
23
|
+
const isOn = (setting) => setting === true;
|
|
24
|
+
export function visualStudioWanted(t, on = isOn) {
|
|
25
|
+
const unreal = on(t.unreal.enabled, 'unreal');
|
|
26
|
+
const flutter = on(t.flutter.enabled, 'flutter') && t.flutter.windowsDesktop;
|
|
27
|
+
const unity = on(t.unity.enabled, 'unity') && t.unity.modules.includes('windows-il2cpp');
|
|
28
|
+
const users = [...(unreal ? ['unreal'] : []), ...(flutter ? ['flutter'] : []), ...(unity ? ['unity'] : [])];
|
|
29
|
+
if (!users.length)
|
|
30
|
+
return null;
|
|
31
|
+
if (unreal)
|
|
32
|
+
return {
|
|
33
|
+
product: 'community',
|
|
34
|
+
components: [...new Set([...UNREAL_COMPONENTS, ...t.unreal.components])],
|
|
35
|
+
for: users,
|
|
36
|
+
licence: 'toolchains.unreal.acceptLicense',
|
|
37
|
+
accepted: t.unreal.acceptLicense,
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
product: 'buildtools',
|
|
41
|
+
components: [...BUILD_TOOLS_COMPONENTS],
|
|
42
|
+
for: users,
|
|
43
|
+
licence: 'toolchains.msvc.acceptLicense',
|
|
44
|
+
accepted: t.msvc.acceptLicense,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// What a toolchain step whose module is not written yet does: says so in the log and the summary, installs nothing.
|
|
2
|
+
import { log } from '../runtime/log.js';
|
|
3
|
+
export function notAvailableYet(env, what) {
|
|
4
|
+
log(what + ': not available yet (nothing installed)');
|
|
5
|
+
env.summary.push(what + ': not available yet');
|
|
6
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type InstallRecord } from '../../shared/installs.js';
|
|
2
|
+
/** What stays free on the sandbox's own disk after a real installer: the paging file and every build need it. */
|
|
3
|
+
export declare const LOCAL_RESERVE_BYTES: number;
|
|
4
|
+
export interface InstallSpec {
|
|
5
|
+
/** The tools\ folder of the tool: unity, godot, fivem\artifacts ... (letters, digits, . _ - and one /). */
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly version: string;
|
|
8
|
+
/** Room it needs while installing (download, unpacked copy). */
|
|
9
|
+
readonly needBytes: number;
|
|
10
|
+
/** A file (relative to the version folder) that only a finished install has: Editor\Unity.exe. */
|
|
11
|
+
readonly marker: string;
|
|
12
|
+
/** What it is, for messages: "Unity 6000.0.32f1". */
|
|
13
|
+
readonly what: string;
|
|
14
|
+
/** How many versions of this tool to keep (default: all). */
|
|
15
|
+
readonly keepVersions?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface Installed {
|
|
18
|
+
readonly dir: string;
|
|
19
|
+
/** Installed now (false: it was there). */
|
|
20
|
+
readonly fresh: boolean;
|
|
21
|
+
readonly sizeBytes: number | null;
|
|
22
|
+
}
|
|
23
|
+
export { InstallRecordsSchema, type InstallRecord } from '../../shared/installs.js';
|
|
24
|
+
export interface PersistedDeps {
|
|
25
|
+
/** C:\AgentData\tools (the self-test passes its own folder). */
|
|
26
|
+
readonly toolsDir?: string;
|
|
27
|
+
/** The sandbox's own disk, for real installers. */
|
|
28
|
+
readonly localDir?: string;
|
|
29
|
+
readonly statfs?: (dir: string) => {
|
|
30
|
+
bavail: number;
|
|
31
|
+
bsize: number;
|
|
32
|
+
};
|
|
33
|
+
readonly log?: (line: string) => void;
|
|
34
|
+
}
|
|
35
|
+
/** Free bytes for this user on the disk holding `dir` (0 when it cannot be told). */
|
|
36
|
+
export declare function freeBytes(dir: string, deps?: PersistedDeps): number;
|
|
37
|
+
/** Throws (with the fix) when the disk holding `dir` has less than `needBytes` free. */
|
|
38
|
+
export declare function assertRoom(dir: string, needBytes: number, what: string, fix: string, deps?: PersistedDeps): void;
|
|
39
|
+
/** A real installer on the sandbox's own disk (C:): its size plus 13 GB must stay free (paging file, builds). */
|
|
40
|
+
export declare function assertLocalRoom(needBytes: number, what: string, deps?: PersistedDeps): void;
|
|
41
|
+
export declare function installRecords(deps?: PersistedDeps): readonly InstallRecord[];
|
|
42
|
+
/** Notes that a version was used now (it is kept over ones used longer ago). */
|
|
43
|
+
export declare function recordUse(name: string, version: string, deps?: PersistedDeps): void;
|
|
44
|
+
/**
|
|
45
|
+
* The version's folder, installed by `install(staging, temp)` when it is not there yet. The installer puts the
|
|
46
|
+
* version's files in `staging` and its temporary files in `temp` (inside staging); a failed install leaves nothing.
|
|
47
|
+
*/
|
|
48
|
+
export declare function ensurePersisted(spec: InstallSpec, install: (staging: string, temp: string) => Promise<void>, deps?: PersistedDeps): Promise<Installed>;
|