diff --git a/README.md b/README.md
index ee5173e..915a611 100644
--- a/README.md
+++ b/README.md
@@ -6,10 +6,11 @@
## 开发构建
+外部 PowerShell 终端从 `go` 目录执行 `. .\env.ps1`,将当前终端的 Go 缓存设为 `go/.cache/go-build`,不修改用户级 Go 配置。VS Code 可在工作区 `terminal.integrated.env.windows` 和 `go.toolsEnvVars` 中配置同一路径,让本项目的新终端自动生效。
+
```powershell
# Go
Push-Location .\go
-$env:GOCACHE = (Join-Path $PWD '.cache\go-build')
go test ./...
go build .\cmd\bd2server
go build .\cmd\bd2client
@@ -19,17 +20,17 @@ Pop-Location
开发时在两个终端中分别从 `go` 目录运行:
```powershell
-$env:GOCACHE = (Join-Path $PWD '.cache\go-build')
go run .\cmd\bd2server --dev run
```
```powershell
-$env:GOCACHE = (Join-Path $PWD '.cache\go-build')
go run .\cmd\bd2client --dev run
```
服务端开发入口会自动使用仓库根目录的版本、认证、资源、数据和存档配置;客户端开发入口会直接使用仓库版本清单和插件产物,并从本机开发配置读取游戏目录,随后用 SDK 内嵌的当前版本名字表增量构建两个客户端插件,无需提供官方映射文件。首次开发前创建该配置:
+客户端窗口在插件准备完成后打开。首次生成完整游戏源码或 SDK/游戏更新后可能等待数分钟,终端会实时显示构建和反编译进度;后续启动复用共享缓存。
+
```powershell
Copy-Item .\go\config.example.json .\go\config.json
```
diff --git a/go/cmd/bd2client/dev_command.go b/go/cmd/bd2client/dev_command.go
index 0a739b8..32f275d 100644
--- a/go/cmd/bd2client/dev_command.go
+++ b/go/cmd/bd2client/dev_command.go
@@ -3,6 +3,7 @@
package main
import (
+ "bytes"
"encoding/json"
"errors"
"fmt"
@@ -177,6 +178,7 @@ func buildDevelopmentPlugins(root, gameDir string) error {
filepath.Join(root, "plugins", "LoginUI", "LoginUI.csproj"),
}
for _, project := range projects {
+ fmt.Fprintf(os.Stderr, "bd2client: preparing development plugin %s; first-time game source generation may take several minutes\n", filepath.Base(project))
command := exec.Command(
"dotnet", "build", project, "-c", "Release",
"-p:GameDir="+filepath.Clean(gameDir),
@@ -185,9 +187,15 @@ func buildDevelopmentPlugins(root, gameDir string) error {
"--nologo",
)
command.Dir = root
- output, err := command.CombinedOutput()
+ // SDK preparation can decompile the entire game before the window opens.
+ // Stream progress immediately, while retaining diagnostics for failures.
+ var output bytes.Buffer
+ writer := io.MultiWriter(os.Stderr, &output)
+ command.Stdout = writer
+ command.Stderr = writer
+ err := command.Run()
if err != nil {
- message := strings.TrimSpace(string(output))
+ message := strings.TrimSpace(output.String())
if message == "" {
message = err.Error()
}
diff --git a/go/env.ps1 b/go/env.ps1
new file mode 100644
index 0000000..f194ee1
--- /dev/null
+++ b/go/env.ps1
@@ -0,0 +1,3 @@
+# Dot-source in an external PowerShell terminal: . .\env.ps1
+# Applies only to this terminal and child processes; no user-level Go settings.
+$env:GOCACHE = Join-Path $PSScriptRoot '.cache\go-build'
diff --git a/plugins/GameSdk.NavigationTests/GameSdk.NavigationTests.csproj b/plugins/GameSdk.NavigationTests/GameSdk.NavigationTests.csproj
deleted file mode 100644
index ccd6560..0000000
--- a/plugins/GameSdk.NavigationTests/GameSdk.NavigationTests.csproj
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- Exe
- net8.0
- enable
- enable
- false
-
-
-
-
-
-
diff --git a/plugins/GameSdk.NavigationTests/Program.cs b/plugins/GameSdk.NavigationTests/Program.cs
deleted file mode 100644
index c48ec77..0000000
--- a/plugins/GameSdk.NavigationTests/Program.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using System.Reflection;
-using System.Text.Json;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.Host.Mef;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-
-if (args.Length == 0)
- throw new ArgumentException("Usage: GameSdk.NavigationTests [game-managed-directory] [--embedded-only]");
-
-var hiddenSources = new List<(string Original, string Hidden)>();
-try
-{
- // Missing local source proves that navigation uses the embedded documents.
- if (args.Contains("--embedded-only"))
- {
- using var manifest = JsonDocument.Parse(File.ReadAllText(Path.Combine(args[0], "navigation.json")));
- string root = manifest.RootElement.GetProperty("SourceRoot").GetString()!;
- string fixtures = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, ".build", "game-sdk-tests")) + Path.DirectorySeparatorChar;
- if (!Path.GetFullPath(root).StartsWith(fixtures, StringComparison.OrdinalIgnoreCase))
- throw new InvalidOperationException("Embedded-only tests may only move generated synthetic fixture sources.");
- foreach (string source in Directory.GetFiles(root, "*.cs", SearchOption.AllDirectories))
- {
- string hidden = source + ".embedded-test";
- File.Move(source, hidden);
- hiddenSources.Add((source, hidden));
- }
- }
-
- // Reflection accesses Visual Studio's internal Roslyn service. A mock would
- // miss the reference-assembly lookup and embedded-document loader failures.
- var features = Assembly.Load("Microsoft.CodeAnalysis.Features");
- var host = MefHostServices.Create(MefHostServices.DefaultAssemblies
- .Add(features).Add(Assembly.Load("Microsoft.CodeAnalysis.CSharp.Features")));
- var exportProvider = host.GetType().GetInterfaces().Single(t => t.Name == "IMefHostExportProvider");
- var getExports = exportProvider.GetMethods().Single(m => m.Name == "GetExports" && m.GetGenericArguments().Length == 1);
- var contract = features.GetType("Microsoft.CodeAnalysis.MetadataAsSource.IMetadataAsSourceFileService")!;
- var exports = (System.Collections.IEnumerable)getExports.MakeGenericMethod(contract).Invoke(host, null)!;
- object export = exports.Cast