Fix SCUM config manifest refresh

This commit is contained in:
npc0-hue
2026-09-25 00:25:00 +08:00
parent 2f9b4b3780
commit abc392d22c
4 changed files with 38 additions and 5 deletions
+7 -3
View File
@@ -812,10 +812,14 @@ func (svc *CoreService) upsertLatestGamePlugin(plugin domain.GamePlugin) (domain
} }
} }
if current.ID != "" && !domain.GamePluginIsNewer(plugin, current) { if current.ID != "" && !domain.GamePluginIsNewer(plugin, current) {
if err := svc.pruneOlderGamePluginVersions(current, matched); err != nil { // Re-registering the same stable manifest ID must refresh its declarative
return domain.GamePlugin{}, err // contract; file targets and action assets can be corrected in place.
if current.ID != plugin.ID || domain.CompareGamePluginVersions(plugin.Version, current.Version) != 0 {
if err := svc.pruneOlderGamePluginVersions(current, matched); err != nil {
return domain.GamePlugin{}, err
}
return domain.CopyGamePlugin(current), nil
} }
return domain.CopyGamePlugin(current), nil
} }
if _, err := svc.store.GamePlugins().Get(plugin.ID); err == nil { if _, err := svc.store.GamePlugins().Get(plugin.ID); err == nil {
+29
View File
@@ -2011,6 +2011,35 @@ func TestCoreServiceUpsertsDuplicateGamePluginManifest(t *testing.T) {
} }
} }
func TestCoreServiceRefreshesSameVersionPluginManifestDeclarations(t *testing.T) {
svc := newTestCoreService()
registration := validPluginManifestRegistration()
registration.Manifest.FileWorkspace = domain.PluginFileWorkspace{
DefaultDirectoryKey: "config",
Directories: []domain.PluginLogicalDirectory{{Key: "config", Label: "配置", Scope: "config"}},
Files: []domain.PluginLogicalFile{{Key: "settings", DirectoryKey: "config", Label: "Settings.ini", Kind: "config", Editable: true}},
}
if _, err := svc.RegisterGamePluginManifest(registration); err != nil {
t.Fatalf("register legacy manifest: %v", err)
}
registration.Manifest.FileWorkspace.Files[0].TargetKey = "SCUM/Saved/Config/WindowsServer/ServerSettings.ini"
refreshed, err := svc.RegisterGamePluginManifest(registration)
if err != nil {
t.Fatalf("refresh same-version manifest: %v", err)
}
if len(refreshed.FileWorkspace.Files) != 1 || refreshed.FileWorkspace.Files[0].TargetKey != "SCUM/Saved/Config/WindowsServer/ServerSettings.ini" {
t.Fatalf("expected same-version manifest declaration to refresh, got %+v", refreshed.FileWorkspace)
}
stored, err := svc.store.GamePlugins().Get(registration.Manifest.ID)
if err != nil {
t.Fatalf("load refreshed manifest: %v", err)
}
if stored.FileWorkspace.Files[0].TargetKey != refreshed.FileWorkspace.Files[0].TargetKey {
t.Fatalf("expected stored manifest target to refresh, stored=%+v refreshed=%+v", stored.FileWorkspace, refreshed.FileWorkspace)
}
}
func TestCoreServiceKeepsOnlyLatestPluginVersionAndMigratesReferences(t *testing.T) { func TestCoreServiceKeepsOnlyLatestPluginVersionAndMigratesReferences(t *testing.T) {
svc := newTestCoreService() svc := newTestCoreService()
stale := validPluginManifestRegistration() stale := validPluginManifestRegistration()
@@ -3,7 +3,7 @@
"id": "game.scum", "id": "game.scum",
"name": "SCUM Server", "name": "SCUM Server",
"description": "First-party SCUM game server operations plugin with platform-mediated lifecycle and plugin-owned RCON data flows.", "description": "First-party SCUM game server operations plugin with platform-mediated lifecycle and plugin-owned RCON data flows.",
"version": "0.1.26", "version": "0.1.27",
"kind": "game-plugin", "kind": "game-plugin",
"tags": [ "tags": [
"scum", "scum",
+1 -1
View File
@@ -357,7 +357,7 @@ describe("plugin manifest validation", () => {
const serialized = JSON.stringify(manifest).toLowerCase(); const serialized = JSON.stringify(manifest).toLowerCase();
expect(serialized).not.toContain("local-proof"); expect(serialized).not.toContain("local-proof");
expect(manifest.version).toBe("0.1.26"); expect(manifest.version).toBe("0.1.27");
expect(installAction.environment?.SERVER_TEMPLATE).toBe("scum-server"); expect(installAction.environment?.SERVER_TEMPLATE).toBe("scum-server");
expect(manifest.permissions).toEqual(expect.arrayContaining(["server.game-client.read", "server.game-client.command", "server.game-client.maintenance"])); expect(manifest.permissions).toEqual(expect.arrayContaining(["server.game-client.read", "server.game-client.command", "server.game-client.maintenance"]));
expect(manifest.gameClientBridge.commands.map((command) => command.type)).toEqual(expect.arrayContaining([ expect(manifest.gameClientBridge.commands.map((command) => command.type)).toEqual(expect.arrayContaining([