feat(plugin): gate pages on companion features

This commit is contained in:
npc0-hue
2026-07-29 09:53:39 +08:00
parent 271e1e684f
commit c9494abc48
16 changed files with 300 additions and 61 deletions
+27 -14
View File
@@ -194,21 +194,30 @@ type GameClientBridgeAuditReferenceListResponse struct {
}
type GameClientBridgeProfileDeclarationResponse struct {
PluginID string `json:"pluginId"`
ProfileKey string `json:"profileKey"`
Available bool `json:"available"`
Reason string `json:"reason,omitempty"`
CommandTypes []string `json:"commandTypes"`
SnapshotTypes []string `json:"snapshotTypes"`
QueryTemplateKeys []string `json:"queryTemplateKeys"`
PluginID string `json:"pluginId"`
ProfileKey string `json:"profileKey"`
Available bool `json:"available"`
Reason string `json:"reason,omitempty"`
CommandTypes []string `json:"commandTypes"`
SnapshotTypes []string `json:"snapshotTypes"`
QueryTemplateKeys []string `json:"queryTemplateKeys"`
HandlerTypes []string `json:"handlerTypes"`
EventProducerTypes []string `json:"eventProducerTypes"`
}
type GameClientBridgeFeatureAvailabilityResponse struct {
Key string `json:"key"`
Available bool `json:"available"`
Reason string `json:"reason,omitempty"`
}
type GameClientBridgeStatusResponse struct {
ServerInstanceID string `json:"serverInstanceId"`
PluginID string `json:"pluginId"`
Available bool `json:"available"`
Reason string `json:"reason,omitempty"`
Profiles []GameClientBridgeProfileDeclarationResponse `json:"profiles"`
ServerInstanceID string `json:"serverInstanceId"`
PluginID string `json:"pluginId"`
Available bool `json:"available"`
Reason string `json:"reason,omitempty"`
Profiles []GameClientBridgeProfileDeclarationResponse `json:"profiles"`
Features []GameClientBridgeFeatureAvailabilityResponse `json:"features"`
}
func (request GameClientBridgeQueueRequest) ToDomain(serverID, pluginID string) domain.GameClientBridgeQueueRequest {
@@ -356,9 +365,13 @@ func GameClientBridgeStatusFromDomain(value domain.GameClientBridgeStatus) GameC
value = domain.CopyGameClientBridgeStatus(value)
profiles := make([]GameClientBridgeProfileDeclarationResponse, len(value.Profiles))
for index, profile := range value.Profiles {
profiles[index] = GameClientBridgeProfileDeclarationResponse{PluginID: profile.PluginID, ProfileKey: profile.ProfileKey, Available: profile.Available, Reason: profile.Reason, CommandTypes: nonNilStrings(profile.CommandTypes), SnapshotTypes: nonNilStrings(profile.SnapshotTypes), QueryTemplateKeys: nonNilStrings(profile.QueryTemplateKeys)}
profiles[index] = GameClientBridgeProfileDeclarationResponse{PluginID: profile.PluginID, ProfileKey: profile.ProfileKey, Available: profile.Available, Reason: profile.Reason, CommandTypes: nonNilStrings(profile.CommandTypes), SnapshotTypes: nonNilStrings(profile.SnapshotTypes), QueryTemplateKeys: nonNilStrings(profile.QueryTemplateKeys), HandlerTypes: nonNilStrings(profile.HandlerTypes), EventProducerTypes: nonNilStrings(profile.EventProducerTypes)}
}
return GameClientBridgeStatusResponse{ServerInstanceID: value.ServerInstanceID, PluginID: value.PluginID, Available: value.Available, Reason: value.Reason, Profiles: profiles}
features := make([]GameClientBridgeFeatureAvailabilityResponse, len(value.Features))
for index, feature := range value.Features {
features[index] = GameClientBridgeFeatureAvailabilityResponse{Key: feature.Key, Available: feature.Available, Reason: feature.Reason}
}
return GameClientBridgeStatusResponse{ServerInstanceID: value.ServerInstanceID, PluginID: value.PluginID, Available: value.Available, Reason: value.Reason, Profiles: profiles, Features: features}
}
func gameClientBridgeCommandResultFromDomain(value domain.GameClientBridgeResult) GameClientBridgeCommandResultResponse {
+40 -19
View File
@@ -176,14 +176,15 @@ type PluginLifecycleActionsBody struct {
}
type GamePluginPageBody struct {
Key string `json:"key"`
Title string `json:"title"`
Path string `json:"path"`
BundleKey string `json:"bundleKey"`
BundleVersion string `json:"bundleVersion"`
BundleIntegritySHA256 string `json:"bundleIntegritySha256"`
Permissions []string `json:"permissions,omitempty"`
BridgeActions []string `json:"bridgeActions,omitempty"`
Key string `json:"key"`
Title string `json:"title"`
Path string `json:"path"`
BundleKey string `json:"bundleKey"`
BundleVersion string `json:"bundleVersion"`
BundleIntegritySHA256 string `json:"bundleIntegritySha256"`
Permissions []string `json:"permissions,omitempty"`
BridgeActions []string `json:"bridgeActions,omitempty"`
FeatureKeys []string `json:"featureKeys,omitempty"`
}
type PluginLogicalDirectoryBody struct {
@@ -297,6 +298,15 @@ type GameClientBridgePageContractBody struct {
CommandTypes []string `json:"commandTypes,omitempty"`
SnapshotTypes []string `json:"snapshotTypes,omitempty"`
QueryTemplateKeys []string `json:"queryTemplateKeys,omitempty"`
FeatureKeys []string `json:"featureKeys,omitempty"`
}
type GameClientBridgeFeatureDeclarationBody struct {
Key string `json:"key"`
Title string `json:"title"`
Permission string `json:"permission"`
RequiredHandlers []string `json:"requiredHandlers,omitempty"`
RequiredEventProducers []string `json:"requiredEventProducers,omitempty"`
}
type GameClientBridgeCompanionDeclarationBody struct {
@@ -322,6 +332,7 @@ type GameClientBridgeManifestBody struct {
CommandRetentionSeconds int `json:"commandRetentionSeconds"`
MaxCommands int `json:"maxCommands"`
Pages []GameClientBridgePageContractBody `json:"pages,omitempty"`
Features []GameClientBridgeFeatureDeclarationBody `json:"features,omitempty"`
Companion *GameClientBridgeCompanionDeclarationBody `json:"companion,omitempty"`
}
type GameMapTrajectoryDeclarationBody struct {
@@ -1111,13 +1122,17 @@ func (body GameClientBridgeManifestBody) ToDomain() domain.GameClientBridgeManif
}
pages := make([]domain.GameClientBridgePageContract, len(body.Pages))
for index, page := range body.Pages {
pages[index] = domain.GameClientBridgePageContract{PageKey: page.PageKey, CommandTypes: domain.CopyStringSlice(page.CommandTypes), SnapshotTypes: domain.CopyStringSlice(page.SnapshotTypes), QueryTemplateKeys: domain.CopyStringSlice(page.QueryTemplateKeys)}
pages[index] = domain.GameClientBridgePageContract{PageKey: page.PageKey, CommandTypes: domain.CopyStringSlice(page.CommandTypes), SnapshotTypes: domain.CopyStringSlice(page.SnapshotTypes), QueryTemplateKeys: domain.CopyStringSlice(page.QueryTemplateKeys), FeatureKeys: domain.CopyStringSlice(page.FeatureKeys)}
}
features := make([]domain.GameClientBridgeFeatureDeclaration, len(body.Features))
for index, feature := range body.Features {
features[index] = domain.GameClientBridgeFeatureDeclaration{Key: feature.Key, Title: feature.Title, Permission: feature.Permission, RequiredHandlers: domain.CopyStringSlice(feature.RequiredHandlers), RequiredEventProducers: domain.CopyStringSlice(feature.RequiredEventProducers)}
}
companion := domain.GameClientBridgeCompanionDeclaration{}
if body.Companion != nil {
companion = domain.GameClientBridgeCompanionDeclaration{ProfileKey: body.Companion.ProfileKey, ConfigTemplateKey: body.Companion.ConfigTemplateKey, ConfigSchemaRef: body.Companion.ConfigSchemaRef, ConfigFormat: body.Companion.ConfigFormat, PlatformBaseURLSource: body.Companion.PlatformBaseURLSource, RegistrationProof: body.Companion.RegistrationProof, ProofMaterialSource: body.Companion.ProofMaterialSource, ProofMaterialEnv: body.Companion.ProofMaterialEnv, SessionMode: body.Companion.SessionMode, TLSPolicy: body.Companion.TLSPolicy, HeartbeatIntervalSeconds: body.Companion.HeartbeatIntervalSeconds, CommandPollIntervalSeconds: body.Companion.CommandPollIntervalSeconds, RequestTimeoutSeconds: body.Companion.RequestTimeoutSeconds}
}
return domain.GameClientBridgeManifest{Commands: commands, Snapshots: snapshots, QueryTemplates: queryTemplates, Retention: domain.GameClientBridgeRetention{KeepForSeconds: body.CommandRetentionSeconds, MaxRecords: body.MaxCommands}, Pages: pages, Companion: companion}
return domain.GameClientBridgeManifest{Commands: commands, Snapshots: snapshots, QueryTemplates: queryTemplates, Retention: domain.GameClientBridgeRetention{KeepForSeconds: body.CommandRetentionSeconds, MaxRecords: body.MaxCommands}, Pages: pages, Features: features, Companion: companion}
}
func (actions PluginLifecycleActionsBody) ToDomain() domain.PluginLifecycleActions {
@@ -1524,13 +1539,17 @@ func gameClientBridgeManifestFromDomain(value domain.GameClientBridgeManifest) G
}
pages := make([]GameClientBridgePageContractBody, len(value.Pages))
for index, page := range value.Pages {
pages[index] = GameClientBridgePageContractBody{PageKey: page.PageKey, CommandTypes: page.CommandTypes, SnapshotTypes: page.SnapshotTypes, QueryTemplateKeys: page.QueryTemplateKeys}
pages[index] = GameClientBridgePageContractBody{PageKey: page.PageKey, CommandTypes: page.CommandTypes, SnapshotTypes: page.SnapshotTypes, QueryTemplateKeys: page.QueryTemplateKeys, FeatureKeys: page.FeatureKeys}
}
features := make([]GameClientBridgeFeatureDeclarationBody, len(value.Features))
for index, feature := range value.Features {
features[index] = GameClientBridgeFeatureDeclarationBody{Key: feature.Key, Title: feature.Title, Permission: feature.Permission, RequiredHandlers: feature.RequiredHandlers, RequiredEventProducers: feature.RequiredEventProducers}
}
var companion *GameClientBridgeCompanionDeclarationBody
if value.Companion.ProfileKey != "" {
companion = &GameClientBridgeCompanionDeclarationBody{ProfileKey: value.Companion.ProfileKey, ConfigTemplateKey: value.Companion.ConfigTemplateKey, ConfigSchemaRef: value.Companion.ConfigSchemaRef, ConfigFormat: value.Companion.ConfigFormat, PlatformBaseURLSource: value.Companion.PlatformBaseURLSource, RegistrationProof: value.Companion.RegistrationProof, ProofMaterialSource: value.Companion.ProofMaterialSource, ProofMaterialEnv: value.Companion.ProofMaterialEnv, SessionMode: value.Companion.SessionMode, TLSPolicy: value.Companion.TLSPolicy, HeartbeatIntervalSeconds: value.Companion.HeartbeatIntervalSeconds, CommandPollIntervalSeconds: value.Companion.CommandPollIntervalSeconds, RequestTimeoutSeconds: value.Companion.RequestTimeoutSeconds}
}
return GameClientBridgeManifestBody{Commands: commands, Snapshots: snapshots, QueryTemplates: queryTemplates, CommandRetentionSeconds: value.Retention.KeepForSeconds, MaxCommands: value.Retention.MaxRecords, Pages: pages, Companion: companion}
return GameClientBridgeManifestBody{Commands: commands, Snapshots: snapshots, QueryTemplates: queryTemplates, CommandRetentionSeconds: value.Retention.KeepForSeconds, MaxCommands: value.Retention.MaxRecords, Pages: pages, Features: features, Companion: companion}
}
func MarketplacePluginListFromDomain(plugins []domain.PluginMarketplacePlugin) MarketplacePluginListResponse {
@@ -1886,6 +1905,7 @@ func pagesToDomain(pages []GamePluginPageBody) []domain.GamePluginPage {
Bundle: domain.PluginPageBundle{Key: page.BundleKey, Version: page.BundleVersion, IntegritySHA256: page.BundleIntegritySHA256},
Permissions: domain.CopyStringSlice(page.Permissions),
BridgeActions: domain.CopyStringSlice(page.BridgeActions),
FeatureKeys: domain.CopyStringSlice(page.FeatureKeys),
}
}
return out
@@ -1898,14 +1918,15 @@ func pagesFromDomain(pages []domain.GamePluginPage) []GamePluginPageBody {
out := make([]GamePluginPageBody, len(pages))
for i, page := range pages {
out[i] = GamePluginPageBody{
Key: page.Key,
Title: page.Title,
Path: page.Path,
BundleKey: page.Bundle.Key,
BundleVersion: page.Bundle.Version,
Key: page.Key,
Title: page.Title,
Path: page.Path,
BundleKey: page.Bundle.Key,
BundleVersion: page.Bundle.Version,
BundleIntegritySHA256: page.Bundle.IntegritySHA256,
Permissions: domain.CopyStringSlice(page.Permissions),
BridgeActions: domain.CopyStringSlice(page.BridgeActions),
Permissions: domain.CopyStringSlice(page.Permissions),
BridgeActions: domain.CopyStringSlice(page.BridgeActions),
FeatureKeys: domain.CopyStringSlice(page.FeatureKeys),
}
}
return out