package dto import ( "net/url" "path" "browser.local/platform/domain" ) type RuntimeTargetBody struct { OS string `json:"os"` Arch string `json:"arch"` } type RuntimeDiscoveryProbeBody struct { Key string `json:"key"` Kind string `json:"kind"` TargetKey string `json:"targetKey"` Required bool `json:"required,omitempty"` Expected string `json:"expected,omitempty"` Platforms []string `json:"platforms,omitempty"` } type RuntimeLifecycleProfileBody struct { Key string `json:"key"` Mode string `json:"mode"` Capabilities []string `json:"capabilities"` ActionRefs PluginLifecycleActionsBody `json:"actionRefs,omitempty"` TransportKeys []string `json:"transportKeys,omitempty"` ClientManagerRef string `json:"clientManagerRef,omitempty"` DLLExtensionRefs []string `json:"dllExtensionRefs,omitempty"` Platforms []string `json:"platforms,omitempty"` } type RuntimeDependencyProbeBody struct { Key string `json:"key"` Kind string `json:"kind"` TargetKey string `json:"targetKey"` Required bool `json:"required,omitempty"` MinimumVersion string `json:"minimumVersion,omitempty"` Platforms []string `json:"platforms,omitempty"` } type RuntimeInstallStepBody struct { Type string `json:"type"` TargetKey string `json:"targetKey"` PackageManager string `json:"packageManager,omitempty"` PackageName string `json:"packageName,omitempty"` Version string `json:"version,omitempty"` DownloadRef string `json:"downloadRef,omitempty"` Checksum string `json:"checksum,omitempty"` } type RuntimeInstallPlanBody struct { Key string `json:"key"` Title string `json:"title"` Platforms []string `json:"platforms,omitempty"` Steps []RuntimeInstallStepBody `json:"steps"` } type RuntimeServerConfigMappingBody struct { FieldKey string `json:"fieldKey"` ConfigKey string `json:"configKey"` ValueType string `json:"valueType"` Required bool `json:"required,omitempty"` } type RuntimeServerDiscoveryMarkerBody struct { Key string `json:"key"` Kind string `json:"kind"` TargetKey string `json:"targetKey"` Expected string `json:"expected,omitempty"` Required bool `json:"required,omitempty"` } type RuntimeServerVerificationCheckBody struct { Key string `json:"key"` Kind string `json:"kind"` TargetKey string `json:"targetKey"` Required bool `json:"required,omitempty"` } type RuntimeServerDeploymentProfileBody struct { Key string `json:"key"` Version string `json:"version"` SupportedTargets []RuntimeTargetBody `json:"supportedTargets"` SteamAppID string `json:"steamAppId"` ExecutableKey string `json:"executableKey"` InstallRootKey string `json:"installRootKey"` ConfigKey string `json:"configKey"` ConfigFormat string `json:"configFormat"` Prerequisites []RuntimeServerPrerequisiteBody `json:"prerequisites,omitempty"` ConfigMappings []RuntimeServerConfigMappingBody `json:"configMappings"` DiscoveryMarkers []RuntimeServerDiscoveryMarkerBody `json:"discoveryMarkers"` VerificationChecks []RuntimeServerVerificationCheckBody `json:"verificationChecks"` } type RuntimeServerPrerequisiteBody struct { Key string `json:"key"` Kind string `json:"kind"` } type RuntimeLogSourceBody struct { Key string `json:"key"` Kind string `json:"kind"` TargetKey string `json:"targetKey,omitempty"` StreamKey string `json:"streamKey"` CursorKind string `json:"cursorKind,omitempty"` RetentionDays int `json:"retentionDays,omitempty"` } type RuntimeLogEventBody struct { Key string `json:"key"` Title string `json:"title"` SourceKey string `json:"sourceKey"` EventType string `json:"eventType"` Permission string `json:"permission"` SchemaRef string `json:"schemaRef"` RetentionDays int `json:"retentionDays"` Severity string `json:"severity"` } type RuntimeTransportProfileBody struct { Key string `json:"key"` Kind string `json:"kind"` TargetKey string `json:"targetKey,omitempty"` Capabilities []string `json:"capabilities"` } type RuntimeRepositoryBody struct { URL string `json:"url"` RevisionPolicy string `json:"revisionPolicy"` Branch string `json:"branch,omitempty"` Tag string `json:"tag,omitempty"` Revision string `json:"revision,omitempty"` } type RuntimeBuildBody struct { System string `json:"system"` WorkspaceRef string `json:"workspaceRef,omitempty"` EntryRef string `json:"entryRef,omitempty"` } type RuntimeConfigTemplateBody struct { Key string `json:"key"` TemplateRef string `json:"templateRef"` OutputRef string `json:"outputRef"` } type RuntimeClientManagerDeploymentBody struct { Mode string `json:"mode"` ExecutableRef string `json:"executableRef"` Arguments []string `json:"arguments,omitempty"` AutoStart bool `json:"autoStart,omitempty"` RequiredRunCapabilities []string `json:"requiredRunCapabilities"` } type RuntimeClientManagerLifecycleBody struct { Actions []string `json:"actions"` StartupTimeoutSeconds int `json:"startupTimeoutSeconds"` StopTimeoutSeconds int `json:"stopTimeoutSeconds"` } type RuntimeClientManagerHealthBody struct { Mode string `json:"mode"` IntervalSeconds int `json:"intervalSeconds"` DegradedAfterSeconds int `json:"degradedAfterSeconds"` OfflineAfterSeconds int `json:"offlineAfterSeconds"` RequiredCapabilities []string `json:"requiredCapabilities"` } type RuntimeClientManagerCompatibilityBody struct { MinimumVersion string `json:"minimumVersion,omitempty"` MaximumVersion string `json:"maximumVersion,omitempty"` AllowDowngrade bool `json:"allowDowngrade"` } type RuntimeClientManagerUpdatePolicyBody struct { Strategy string `json:"strategy"` RequireApproval bool `json:"requireApproval"` HealthConfirmationSeconds int `json:"healthConfirmationSeconds"` RetainPrevious bool `json:"retainPrevious"` } type RuntimeClientManagerProfileBody struct { Key string `json:"key"` DisplayName string `json:"displayName,omitempty"` Version string `json:"version,omitempty"` Repository RuntimeRepositoryBody `json:"repository"` SupportedTargets []RuntimeTargetBody `json:"supportedTargets"` Build RuntimeBuildBody `json:"build"` ConfigTemplates []RuntimeConfigTemplateBody `json:"configTemplates,omitempty"` OutputArtifacts []string `json:"outputArtifacts"` Deployment RuntimeClientManagerDeploymentBody `json:"deployment,omitempty"` Lifecycle RuntimeClientManagerLifecycleBody `json:"lifecycle,omitempty"` Health RuntimeClientManagerHealthBody `json:"health,omitempty"` Compatibility RuntimeClientManagerCompatibilityBody `json:"compatibility,omitempty"` UpdatePolicy RuntimeClientManagerUpdatePolicyBody `json:"updatePolicy,omitempty"` } type RuntimeDLLExtensionProfileBody struct { Key string `json:"key"` DisplayName string `json:"displayName"` Kind string `json:"kind"` Activation string `json:"activation"` Version string `json:"version"` ReleaseState string `json:"releaseState"` ReleaseURL string `json:"releaseUrl,omitempty"` ReleaseHost string `json:"releaseHost,omitempty"` ReleaseFilename string `json:"releaseFilename,omitempty"` Checksum string `json:"checksum,omitempty"` SizeBytes int64 `json:"sizeBytes,omitempty"` TargetKey string `json:"targetKey"` ModKey string `json:"modKey"` DLLRef string `json:"dllRef"` SCUMExecutableChecksum string `json:"scumExecutableChecksum,omitempty"` UE4SSABI string `json:"ue4ssAbi,omitempty"` SupportedTargets []RuntimeTargetBody `json:"supportedTargets"` UpdateOnStart bool `json:"updateOnStart"` RCONPort int `json:"rconPort"` } // RuntimeDLLExtensionProfileResponseBody is the browser-safe projection of a // declared DLL extension. The immutable deployment path, RCON port, and full // release URL remain internal to the manifest/start-job contracts. type RuntimeDLLExtensionProfileResponseBody struct { Key string `json:"key"` DisplayName string `json:"displayName"` Kind string `json:"kind"` Activation string `json:"activation"` Version string `json:"version"` ReleaseState string `json:"releaseState"` ReleaseHost string `json:"releaseHost,omitempty"` ReleaseFilename string `json:"releaseFilename,omitempty"` Checksum string `json:"checksum,omitempty"` SizeBytes int64 `json:"sizeBytes,omitempty"` SCUMExecutableChecksum string `json:"scumExecutableChecksum,omitempty"` UE4SSABI string `json:"ue4ssAbi,omitempty"` SupportedTargets []RuntimeTargetBody `json:"supportedTargets"` UpdateOnStart bool `json:"updateOnStart"` } type RuntimeDLLExtensionPlanBody struct { Key string `json:"key"` Version string `json:"version"` ReleaseURL string `json:"releaseUrl"` Checksum string `json:"checksum"` SizeBytes int64 `json:"sizeBytes"` TargetKey string `json:"targetKey"` ModKey string `json:"modKey"` DLLRef string `json:"dllRef"` SCUMExecutableChecksum string `json:"scumExecutableChecksum"` UE4SSABI string `json:"ue4ssAbi"` RCONPort int `json:"rconPort"` } type GamePluginRuntimeProfilesBody struct { Discovery []RuntimeDiscoveryProbeBody `json:"discovery,omitempty"` LifecycleProfiles []RuntimeLifecycleProfileBody `json:"lifecycleProfiles,omitempty"` DependencyProbes []RuntimeDependencyProbeBody `json:"dependencyProbes,omitempty"` InstallPlans []RuntimeInstallPlanBody `json:"installPlans,omitempty"` ServerDeployments []RuntimeServerDeploymentProfileBody `json:"serverDeployments,omitempty"` LogSources []RuntimeLogSourceBody `json:"logSources,omitempty"` LogEvents []RuntimeLogEventBody `json:"logEvents,omitempty"` TransportProfiles []RuntimeTransportProfileBody `json:"transportProfiles,omitempty"` ClientManagers []RuntimeClientManagerProfileBody `json:"clientManagers,omitempty"` DLLExtensions []RuntimeDLLExtensionProfileBody `json:"dllExtensions,omitempty"` } // GamePluginRuntimeProfilesResponseBody is intentionally distinct from the // manifest input shape so browser responses cannot accidentally include // machine-local DLL placement or RCON activation details. type GamePluginRuntimeProfilesResponseBody struct { Discovery []RuntimeDiscoveryProbeBody `json:"discovery,omitempty"` LifecycleProfiles []RuntimeLifecycleProfileBody `json:"lifecycleProfiles,omitempty"` DependencyProbes []RuntimeDependencyProbeBody `json:"dependencyProbes,omitempty"` InstallPlans []RuntimeInstallPlanBody `json:"installPlans,omitempty"` ServerDeployments []RuntimeServerDeploymentProfileBody `json:"serverDeployments,omitempty"` LogSources []RuntimeLogSourceBody `json:"logSources,omitempty"` LogEvents []RuntimeLogEventBody `json:"logEvents,omitempty"` TransportProfiles []RuntimeTransportProfileBody `json:"transportProfiles,omitempty"` ClientManagers []RuntimeClientManagerProfileBody `json:"clientManagers,omitempty"` DLLExtensions []RuntimeDLLExtensionProfileResponseBody `json:"dllExtensions,omitempty"` } func (body GamePluginRuntimeProfilesBody) ToDomain() domain.GamePluginRuntimeProfiles { profiles := domain.GamePluginRuntimeProfiles{} for _, item := range body.Discovery { profiles.Discovery = append(profiles.Discovery, domain.RuntimeDiscoveryProbe{Key: item.Key, Kind: item.Kind, TargetKey: item.TargetKey, Required: item.Required, Expected: item.Expected, Platforms: domain.CopyStringSlice(item.Platforms)}) } for _, item := range body.LifecycleProfiles { profiles.LifecycleProfiles = append(profiles.LifecycleProfiles, domain.RuntimeLifecycleProfile{Key: item.Key, Mode: item.Mode, Capabilities: domain.CopyStringSlice(item.Capabilities), ActionRefs: item.ActionRefs.ToDomain(), TransportKeys: domain.CopyStringSlice(item.TransportKeys), ClientManagerRef: item.ClientManagerRef, DLLExtensionRefs: domain.CopyStringSlice(item.DLLExtensionRefs), Platforms: domain.CopyStringSlice(item.Platforms)}) } for _, item := range body.DependencyProbes { profiles.DependencyProbes = append(profiles.DependencyProbes, domain.RuntimeDependencyProbe{Key: item.Key, Kind: item.Kind, TargetKey: item.TargetKey, Required: item.Required, MinimumVersion: item.MinimumVersion, Platforms: domain.CopyStringSlice(item.Platforms)}) } for _, item := range body.InstallPlans { plan := domain.RuntimeInstallPlan{Key: item.Key, Title: item.Title, Platforms: domain.CopyStringSlice(item.Platforms)} for _, step := range item.Steps { plan.Steps = append(plan.Steps, domain.RuntimeInstallStep{Type: step.Type, TargetKey: step.TargetKey, PackageManager: step.PackageManager, PackageName: step.PackageName, Version: step.Version, DownloadRef: step.DownloadRef, Checksum: step.Checksum}) } profiles.InstallPlans = append(profiles.InstallPlans, plan) } for _, item := range body.ServerDeployments { profile := domain.RuntimeServerDeploymentProfile{Key: item.Key, Version: item.Version, SteamAppID: item.SteamAppID, ExecutableKey: item.ExecutableKey, InstallRootKey: item.InstallRootKey, ConfigKey: item.ConfigKey, ConfigFormat: item.ConfigFormat} for _, prerequisite := range item.Prerequisites { profile.Prerequisites = append(profile.Prerequisites, domain.RuntimeServerPrerequisite{Key: prerequisite.Key, Kind: prerequisite.Kind}) } for _, target := range item.SupportedTargets { profile.SupportedTargets = append(profile.SupportedTargets, domain.RuntimeTarget{OS: target.OS, Arch: target.Arch}) } for _, mapping := range item.ConfigMappings { profile.ConfigMappings = append(profile.ConfigMappings, domain.RuntimeServerConfigMapping{FieldKey: mapping.FieldKey, ConfigKey: mapping.ConfigKey, ValueType: mapping.ValueType, Required: mapping.Required}) } for _, marker := range item.DiscoveryMarkers { profile.DiscoveryMarkers = append(profile.DiscoveryMarkers, domain.RuntimeServerDiscoveryMarker{Key: marker.Key, Kind: marker.Kind, TargetKey: marker.TargetKey, Expected: marker.Expected, Required: marker.Required}) } for _, check := range item.VerificationChecks { profile.VerificationChecks = append(profile.VerificationChecks, domain.RuntimeServerVerificationCheck{Key: check.Key, Kind: check.Kind, TargetKey: check.TargetKey, Required: check.Required}) } profiles.ServerDeployments = append(profiles.ServerDeployments, profile) } for _, item := range body.LogSources { profiles.LogSources = append(profiles.LogSources, domain.RuntimeLogSource{Key: item.Key, Kind: item.Kind, TargetKey: item.TargetKey, StreamKey: item.StreamKey, CursorKind: item.CursorKind, RetentionDays: item.RetentionDays}) } for _, item := range body.LogEvents { profiles.LogEvents = append(profiles.LogEvents, domain.RuntimeLogEvent{Key: item.Key, Title: item.Title, SourceKey: item.SourceKey, EventType: item.EventType, Permission: item.Permission, SchemaRef: item.SchemaRef, RetentionDays: item.RetentionDays, Severity: domain.RuntimeLogEventSeverity(item.Severity)}) } for _, item := range body.TransportProfiles { profiles.TransportProfiles = append(profiles.TransportProfiles, domain.RuntimeTransportProfile{Key: item.Key, Kind: item.Kind, TargetKey: item.TargetKey, Capabilities: domain.CopyStringSlice(item.Capabilities)}) } for _, item := range body.ClientManagers { manager := domain.RuntimeClientManagerProfile{ Key: item.Key, DisplayName: item.DisplayName, Version: item.Version, RepositoryURL: item.Repository.URL, RevisionPolicy: item.Repository.RevisionPolicy, Branch: item.Repository.Branch, Tag: item.Repository.Tag, Revision: item.Repository.Revision, BuildSystem: item.Build.System, WorkspaceRef: item.Build.WorkspaceRef, EntryRef: item.Build.EntryRef, OutputArtifacts: domain.CopyStringSlice(item.OutputArtifacts), Deployment: domain.RuntimeClientManagerDeployment{Mode: item.Deployment.Mode, ExecutableRef: item.Deployment.ExecutableRef, Arguments: domain.CopyStringSlice(item.Deployment.Arguments), AutoStart: item.Deployment.AutoStart, RequiredRunCapabilities: domain.CopyStringSlice(item.Deployment.RequiredRunCapabilities)}, Lifecycle: domain.RuntimeClientManagerLifecycle{Actions: domain.CopyStringSlice(item.Lifecycle.Actions), StartupTimeoutSeconds: item.Lifecycle.StartupTimeoutSeconds, StopTimeoutSeconds: item.Lifecycle.StopTimeoutSeconds}, Health: domain.RuntimeClientManagerHealth{Mode: item.Health.Mode, IntervalSeconds: item.Health.IntervalSeconds, DegradedAfterSeconds: item.Health.DegradedAfterSeconds, OfflineAfterSeconds: item.Health.OfflineAfterSeconds, RequiredCapabilities: domain.CopyStringSlice(item.Health.RequiredCapabilities)}, Compatibility: domain.RuntimeClientManagerCompatibility{MinimumVersion: item.Compatibility.MinimumVersion, MaximumVersion: item.Compatibility.MaximumVersion, AllowDowngrade: item.Compatibility.AllowDowngrade}, UpdatePolicy: domain.RuntimeClientManagerUpdatePolicy{Strategy: item.UpdatePolicy.Strategy, RequireApproval: item.UpdatePolicy.RequireApproval, HealthConfirmationSeconds: item.UpdatePolicy.HealthConfirmationSeconds, RetainPrevious: item.UpdatePolicy.RetainPrevious}, } for _, target := range item.SupportedTargets { manager.SupportedTargets = append(manager.SupportedTargets, domain.RuntimeTarget{OS: target.OS, Arch: target.Arch}) } for _, config := range item.ConfigTemplates { manager.ConfigTemplates = append(manager.ConfigTemplates, domain.RuntimeConfigTemplate{Key: config.Key, TemplateRef: config.TemplateRef, OutputRef: config.OutputRef}) } profiles.ClientManagers = append(profiles.ClientManagers, manager) } for _, item := range body.DLLExtensions { extension := domain.RuntimeDLLExtensionProfile{Key: item.Key, DisplayName: item.DisplayName, Kind: item.Kind, Activation: item.Activation, Version: item.Version, ReleaseState: item.ReleaseState, ReleaseURL: item.ReleaseURL, Checksum: item.Checksum, SizeBytes: item.SizeBytes, TargetKey: item.TargetKey, ModKey: item.ModKey, DLLRef: item.DLLRef, SCUMExecutableChecksum: item.SCUMExecutableChecksum, UE4SSABI: item.UE4SSABI, UpdateOnStart: item.UpdateOnStart, RCONPort: item.RCONPort} for _, target := range item.SupportedTargets { extension.SupportedTargets = append(extension.SupportedTargets, domain.RuntimeTarget{OS: target.OS, Arch: target.Arch}) } profiles.DLLExtensions = append(profiles.DLLExtensions, extension) } return profiles } func runtimeProfilesFromDomain(profiles domain.GamePluginRuntimeProfiles) GamePluginRuntimeProfilesResponseBody { profiles = domain.CopyGamePluginRuntimeProfiles(profiles) body := GamePluginRuntimeProfilesResponseBody{} for _, item := range profiles.Discovery { body.Discovery = append(body.Discovery, RuntimeDiscoveryProbeBody{Key: item.Key, Kind: item.Kind, TargetKey: item.TargetKey, Required: item.Required, Expected: item.Expected, Platforms: item.Platforms}) } for _, item := range profiles.LifecycleProfiles { body.LifecycleProfiles = append(body.LifecycleProfiles, RuntimeLifecycleProfileBody{Key: item.Key, Mode: item.Mode, Capabilities: item.Capabilities, ActionRefs: lifecycleActionsFromDomain(item.ActionRefs), TransportKeys: item.TransportKeys, ClientManagerRef: item.ClientManagerRef, DLLExtensionRefs: item.DLLExtensionRefs, Platforms: item.Platforms}) } for _, item := range profiles.DependencyProbes { body.DependencyProbes = append(body.DependencyProbes, RuntimeDependencyProbeBody{Key: item.Key, Kind: item.Kind, TargetKey: item.TargetKey, Required: item.Required, MinimumVersion: item.MinimumVersion, Platforms: item.Platforms}) } for _, item := range profiles.InstallPlans { plan := RuntimeInstallPlanBody{Key: item.Key, Title: item.Title, Platforms: item.Platforms} for _, step := range item.Steps { plan.Steps = append(plan.Steps, RuntimeInstallStepBody{Type: step.Type, TargetKey: step.TargetKey, PackageManager: step.PackageManager, PackageName: step.PackageName, Version: step.Version, DownloadRef: step.DownloadRef, Checksum: step.Checksum}) } body.InstallPlans = append(body.InstallPlans, plan) } for _, item := range profiles.ServerDeployments { bodyProfile := RuntimeServerDeploymentProfileBody{Key: item.Key, Version: item.Version, SteamAppID: item.SteamAppID, ExecutableKey: item.ExecutableKey, InstallRootKey: item.InstallRootKey, ConfigKey: item.ConfigKey, ConfigFormat: item.ConfigFormat} for _, prerequisite := range item.Prerequisites { bodyProfile.Prerequisites = append(bodyProfile.Prerequisites, RuntimeServerPrerequisiteBody{Key: prerequisite.Key, Kind: prerequisite.Kind}) } for _, target := range item.SupportedTargets { bodyProfile.SupportedTargets = append(bodyProfile.SupportedTargets, RuntimeTargetBody{OS: target.OS, Arch: target.Arch}) } for _, mapping := range item.ConfigMappings { bodyProfile.ConfigMappings = append(bodyProfile.ConfigMappings, RuntimeServerConfigMappingBody{FieldKey: mapping.FieldKey, ConfigKey: mapping.ConfigKey, ValueType: mapping.ValueType, Required: mapping.Required}) } for _, marker := range item.DiscoveryMarkers { bodyProfile.DiscoveryMarkers = append(bodyProfile.DiscoveryMarkers, RuntimeServerDiscoveryMarkerBody{Key: marker.Key, Kind: marker.Kind, TargetKey: marker.TargetKey, Expected: marker.Expected, Required: marker.Required}) } for _, check := range item.VerificationChecks { bodyProfile.VerificationChecks = append(bodyProfile.VerificationChecks, RuntimeServerVerificationCheckBody{Key: check.Key, Kind: check.Kind, TargetKey: check.TargetKey, Required: check.Required}) } body.ServerDeployments = append(body.ServerDeployments, bodyProfile) } for _, item := range profiles.LogSources { body.LogSources = append(body.LogSources, RuntimeLogSourceBody{Key: item.Key, Kind: item.Kind, TargetKey: item.TargetKey, StreamKey: item.StreamKey, CursorKind: item.CursorKind, RetentionDays: item.RetentionDays}) } for _, item := range profiles.LogEvents { body.LogEvents = append(body.LogEvents, RuntimeLogEventBody{Key: item.Key, Title: item.Title, SourceKey: item.SourceKey, EventType: item.EventType, Permission: item.Permission, SchemaRef: item.SchemaRef, RetentionDays: item.RetentionDays, Severity: string(item.Severity)}) } for _, item := range profiles.TransportProfiles { body.TransportProfiles = append(body.TransportProfiles, RuntimeTransportProfileBody{Key: item.Key, Kind: item.Kind, TargetKey: item.TargetKey, Capabilities: item.Capabilities}) } for _, item := range profiles.ClientManagers { manager := RuntimeClientManagerProfileBody{ Key: item.Key, DisplayName: item.DisplayName, Version: item.Version, Repository: RuntimeRepositoryBody{URL: item.RepositoryURL, RevisionPolicy: item.RevisionPolicy, Branch: item.Branch, Tag: item.Tag, Revision: item.Revision}, Build: RuntimeBuildBody{System: item.BuildSystem, WorkspaceRef: item.WorkspaceRef, EntryRef: item.EntryRef}, OutputArtifacts: item.OutputArtifacts, Deployment: RuntimeClientManagerDeploymentBody{Mode: item.Deployment.Mode, ExecutableRef: item.Deployment.ExecutableRef, Arguments: item.Deployment.Arguments, AutoStart: item.Deployment.AutoStart, RequiredRunCapabilities: item.Deployment.RequiredRunCapabilities}, Lifecycle: RuntimeClientManagerLifecycleBody{Actions: item.Lifecycle.Actions, StartupTimeoutSeconds: item.Lifecycle.StartupTimeoutSeconds, StopTimeoutSeconds: item.Lifecycle.StopTimeoutSeconds}, Health: RuntimeClientManagerHealthBody{Mode: item.Health.Mode, IntervalSeconds: item.Health.IntervalSeconds, DegradedAfterSeconds: item.Health.DegradedAfterSeconds, OfflineAfterSeconds: item.Health.OfflineAfterSeconds, RequiredCapabilities: item.Health.RequiredCapabilities}, Compatibility: RuntimeClientManagerCompatibilityBody{MinimumVersion: item.Compatibility.MinimumVersion, MaximumVersion: item.Compatibility.MaximumVersion, AllowDowngrade: item.Compatibility.AllowDowngrade}, UpdatePolicy: RuntimeClientManagerUpdatePolicyBody{Strategy: item.UpdatePolicy.Strategy, RequireApproval: item.UpdatePolicy.RequireApproval, HealthConfirmationSeconds: item.UpdatePolicy.HealthConfirmationSeconds, RetainPrevious: item.UpdatePolicy.RetainPrevious}, } for _, target := range item.SupportedTargets { manager.SupportedTargets = append(manager.SupportedTargets, RuntimeTargetBody{OS: target.OS, Arch: target.Arch}) } for _, config := range item.ConfigTemplates { manager.ConfigTemplates = append(manager.ConfigTemplates, RuntimeConfigTemplateBody{Key: config.Key, TemplateRef: config.TemplateRef, OutputRef: config.OutputRef}) } body.ClientManagers = append(body.ClientManagers, manager) } for _, item := range profiles.DLLExtensions { host, filename := safeDLLReleaseLocation(item.ReleaseURL) extension := RuntimeDLLExtensionProfileResponseBody{Key: item.Key, DisplayName: item.DisplayName, Kind: item.Kind, Activation: item.Activation, Version: item.Version, ReleaseState: item.ReleaseState, ReleaseHost: host, ReleaseFilename: filename, Checksum: safeDLLChecksumPrefix(item.Checksum), SizeBytes: item.SizeBytes, SCUMExecutableChecksum: safeDLLChecksumPrefix(item.SCUMExecutableChecksum), UE4SSABI: item.UE4SSABI, UpdateOnStart: item.UpdateOnStart} for _, target := range item.SupportedTargets { extension.SupportedTargets = append(extension.SupportedTargets, RuntimeTargetBody{OS: target.OS, Arch: target.Arch}) } body.DLLExtensions = append(body.DLLExtensions, extension) } return body } func dllExtensionPlansFromDomain(plans []domain.RuntimeDLLExtensionPlan) []RuntimeDLLExtensionPlanBody { items := make([]RuntimeDLLExtensionPlanBody, 0, len(plans)) for _, item := range plans { items = append(items, RuntimeDLLExtensionPlanBody{Key: item.Key, Version: item.Version, ReleaseURL: item.ReleaseURL, Checksum: item.Checksum, SizeBytes: item.SizeBytes, TargetKey: item.TargetKey, ModKey: item.ModKey, DLLRef: item.DLLRef, SCUMExecutableChecksum: item.SCUMExecutableChecksum, UE4SSABI: item.UE4SSABI, RCONPort: item.RCONPort}) } return items } func safeDLLReleaseLocation(value string) (string, string) { parsed, err := url.Parse(value) if err != nil || parsed == nil { return "", "" } return parsed.Hostname(), path.Base(parsed.Path) } func safeDLLChecksumPrefix(value string) string { if len(value) <= len("sha256:")+12 { return value } return value[:len("sha256:")+12] + "…" }