diff --git a/src/Artemis.Core/Models/IPluginFeatureDependent.cs b/src/Artemis.Core/Models/IPluginFeatureDependent.cs
new file mode 100644
index 000000000..a1531bfc5
--- /dev/null
+++ b/src/Artemis.Core/Models/IPluginFeatureDependent.cs
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+
+namespace Artemis.Core;
+
+///
+/// Represents a class that depends on plugin features
+///
+public interface IPluginFeatureDependent
+{
+ ///
+ /// Gets the plugin features this class depends on, may contain the same plugin feature twice if depending on it in multiple ways.
+ ///
+ /// A of this class depends on.
+ public IEnumerable GetFeatureDependencies();
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/AlwaysOnCondition.cs b/src/Artemis.Core/Models/Profile/Conditions/AlwaysOnCondition.cs
index eeeece9c5..b42c1e1fb 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/AlwaysOnCondition.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/AlwaysOnCondition.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
@@ -82,4 +83,14 @@ public class AlwaysOnCondition : ICondition
}
#endregion
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ return [];
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/EventCondition.cs b/src/Artemis.Core/Models/Profile/Conditions/EventCondition.cs
index f198b5397..826634d67 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/EventCondition.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/EventCondition.cs
@@ -325,4 +325,14 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
}
#endregion
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ return Script.GetFeatureDependencies().Concat(EventPath?.GetFeatureDependencies() ?? []);
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/ICondition.cs b/src/Artemis.Core/Models/Profile/Conditions/ICondition.cs
index ef3b17c13..b1d3fa9f4 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/ICondition.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/ICondition.cs
@@ -6,7 +6,7 @@ namespace Artemis.Core;
///
/// Represents a condition applied to a
///
-public interface ICondition : IDisposable, IStorageModel
+public interface ICondition : IDisposable, IStorageModel, IPluginFeatureDependent
{
///
/// Gets the entity used to store this condition
diff --git a/src/Artemis.Core/Models/Profile/Conditions/PlayOnceCondition.cs b/src/Artemis.Core/Models/Profile/Conditions/PlayOnceCondition.cs
index 40178ad6e..4e3ff0ff1 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/PlayOnceCondition.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/PlayOnceCondition.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
@@ -82,4 +83,14 @@ public class PlayOnceCondition : ICondition
}
#endregion
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ return [];
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/StaticCondition.cs b/src/Artemis.Core/Models/Profile/Conditions/StaticCondition.cs
index 5ab81e22c..fddc62306 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/StaticCondition.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/StaticCondition.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
@@ -159,6 +160,16 @@ public class StaticCondition : CorePropertyChanged, INodeScriptCondition
}
#endregion
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ return Script.GetFeatureDependencies();
+ }
+
+ #endregion
}
///
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
index 42b10ccde..9bf8e94e6 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
@@ -243,4 +243,14 @@ public class DataBinding : IDataBinding
}
#endregion
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ return Script.GetFeatureDependencies();
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/IDataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/IDataBinding.cs
index a5856d018..e87868d52 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/IDataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/IDataBinding.cs
@@ -8,7 +8,7 @@ namespace Artemis.Core;
/// Represents a data binding that binds a certain to a value inside a
///
///
-public interface IDataBinding : IStorageModel, IDisposable
+public interface IDataBinding : IStorageModel, IDisposable, IPluginFeatureDependent
{
///
/// Gets the layer property the data binding is applied to
diff --git a/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs b/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs
index 681ddb923..deeff25bc 100644
--- a/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs
+++ b/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs
@@ -11,7 +11,7 @@ namespace Artemis.Core;
///
/// Represents a path that points to a property in data model
///
-public class DataModelPath : IStorageModel, IDisposable
+public class DataModelPath : IStorageModel, IDisposable, IPluginFeatureDependent
{
private readonly LinkedList _segments;
private Expression>? _accessorLambda;
@@ -188,6 +188,14 @@ public class DataModelPath : IStorageModel, IDisposable
return string.IsNullOrWhiteSpace(Path) ? "this" : Path;
}
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ if (Target == null)
+ return [];
+ return [Target.Module];
+ }
+
///
/// Occurs whenever the path becomes invalid
///
diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs
index 2db77c92b..a845bd331 100644
--- a/src/Artemis.Core/Models/Profile/Folder.cs
+++ b/src/Artemis.Core/Models/Profile/Folder.cs
@@ -179,6 +179,14 @@ public sealed class Folder : RenderProfileElement
return $"[Folder] {nameof(Name)}: {Name}, {nameof(Order)}: {Order}";
}
+ ///
+ public override IEnumerable GetFeatureDependencies()
+ {
+ return LayerEffects.SelectMany(e => e.GetFeatureDependencies())
+ .Concat(Children.SelectMany(c => c.GetFeatureDependencies()))
+ .Concat(DisplayCondition.GetFeatureDependencies());
+ }
+
#region Rendering
///
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index 41661290d..2f7de1d48 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -189,6 +189,16 @@ public sealed class Layer : RenderProfileElement
return $"[Layer] {nameof(Name)}: {Name}, {nameof(Order)}: {Order}";
}
+ ///
+ public override IEnumerable GetFeatureDependencies()
+ {
+ return LayerEffects.SelectMany(e => e.GetFeatureDependencies())
+ .Concat(LayerBrush?.GetFeatureDependencies() ?? [])
+ .Concat(General.GetFeatureDependencies())
+ .Concat(Transform.GetFeatureDependencies())
+ .Concat(DisplayCondition.GetFeatureDependencies());
+ }
+
///
/// Occurs when a property affecting the rendering properties of this layer has been updated
///
@@ -768,7 +778,7 @@ public sealed class Layer : RenderProfileElement
if (!_leds.Remove(led))
return;
-
+
CalculateRenderProperties();
}
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs
index a7b5aa8ef..e3d1f11e4 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs
@@ -11,7 +11,7 @@ namespace Artemis.Core;
/// initialize these for you.
///
///
-public interface ILayerProperty : IStorageModel, IDisposable
+public interface ILayerProperty : IStorageModel, IDisposable, IPluginFeatureDependent
{
///
/// Gets the description attribute applied to this property
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
index 5ecfeeca6..85dcba517 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
@@ -54,6 +54,12 @@ public class LayerProperty : CorePropertyChanged, ILayerProperty
return $"{Path} - {CurrentValue} ({PropertyType})";
}
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ return DataBinding.GetFeatureDependencies();
+ }
+
///
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
///
diff --git a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs
index 31b4af879..84de5c444 100644
--- a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs
+++ b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs
@@ -15,7 +15,7 @@ namespace Artemis.Core;
/// initialize these for you.
///
///
-public abstract class LayerPropertyGroup : IDisposable
+public abstract class LayerPropertyGroup : IDisposable, IPluginFeatureDependent
{
private readonly List _layerProperties;
private readonly List _layerPropertyGroups;
@@ -343,4 +343,14 @@ public abstract class LayerPropertyGroup : IDisposable
Dispose(true);
GC.SuppressFinalize(this);
}
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ return LayerProperties.SelectMany(p => p.GetFeatureDependencies()).Concat(LayerPropertyGroups.SelectMany(g => g.GetFeatureDependencies()));
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Profile.cs b/src/Artemis.Core/Models/Profile/Profile.cs
index 2a0d96a23..073afa540 100644
--- a/src/Artemis.Core/Models/Profile/Profile.cs
+++ b/src/Artemis.Core/Models/Profile/Profile.cs
@@ -171,6 +171,12 @@ public sealed class Profile : ProfileElement
return $"[Profile] {nameof(Name)}: {Name}";
}
+ ///
+ public override IEnumerable GetFeatureDependencies()
+ {
+ return GetRootFolder().GetFeatureDependencies().Concat(Scripts.Select(c => c.ScriptingProvider));
+ }
+
///
/// Populates all the LEDs on the elements in this profile
///
diff --git a/src/Artemis.Core/Models/Profile/ProfileElement.cs b/src/Artemis.Core/Models/Profile/ProfileElement.cs
index dbce946a8..921910db5 100644
--- a/src/Artemis.Core/Models/Profile/ProfileElement.cs
+++ b/src/Artemis.Core/Models/Profile/ProfileElement.cs
@@ -9,7 +9,7 @@ namespace Artemis.Core;
///
/// Represents an element of a
///
-public abstract class ProfileElement : BreakableModel, IDisposable
+public abstract class ProfileElement : BreakableModel, IDisposable, IPluginFeatureDependent
{
internal readonly List ChildrenList;
private Guid _entityId;
@@ -122,6 +122,9 @@ public abstract class ProfileElement : BreakableModel, IDisposable
return $"{nameof(EntityId)}: {EntityId}, {nameof(Order)}: {Order}, {nameof(Name)}: {Name}";
}
+ ///
+ public abstract IEnumerable GetFeatureDependencies();
+
///
/// Occurs when a child was added to the list
///
diff --git a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs
index 04f84c8f1..a4c1e89f4 100644
--- a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs
+++ b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs
@@ -9,13 +9,13 @@ namespace Artemis.Core;
///
/// Represents the configuration of a profile, contained in a
///
-public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable
+public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable, IPluginFeatureDependent
{
///
/// Represents an empty profile.
///
public static readonly ProfileConfiguration Empty = new(ProfileCategory.Empty, "Empty", "Empty");
-
+
private ActivationBehaviour _activationBehaviour;
private bool _activationConditionMet;
private ProfileCategory _category;
@@ -146,7 +146,7 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable
get => _activationConditionMet;
private set => SetAndNotify(ref _activationConditionMet, value);
}
-
+
///
/// Gets the profile of this profile configuration
///
@@ -159,8 +159,8 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable
///
/// Gets or sets a boolean indicating whether this profile should fade in and out when enabling or disabling
///
- public bool FadeInAndOut
- {
+ public bool FadeInAndOut
+ {
get => _fadeInAndOut;
set => SetAndNotify(ref _fadeInAndOut, value);
}
@@ -188,7 +188,7 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable
/// alongside any activation requirements of the , if set
///
public NodeScript ActivationCondition { get; }
-
+
///
/// Gets the entity used by this profile config
///
@@ -247,6 +247,19 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable
return $"[ProfileConfiguration] {nameof(Name)}: {Name}";
}
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("ProfileConfiguration");
+ if (Profile == null)
+ throw new InvalidOperationException("Cannot determine feature dependencies when the profile is not loaded.");
+
+ return ActivationCondition.GetFeatureDependencies()
+ .Concat(Profile.GetFeatureDependencies())
+ .Concat(Module != null ? [Module] : []);
+ }
+
internal void LoadModules(List enabledModules)
{
if (_disposed)
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs
index cadbd5e7e..8410012a9 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs
+++ b/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs
@@ -9,7 +9,7 @@ namespace Artemis.Core.LayerBrushes;
///
/// For internal use only, please use or or instead
///
-public abstract class BaseLayerBrush : BreakableModel, IDisposable
+public abstract class BaseLayerBrush : BreakableModel, IDisposable, IPluginFeatureDependent
{
private LayerBrushType _brushType;
private ILayerBrushConfigurationDialog? _configurationDialog;
@@ -199,6 +199,20 @@ public abstract class BaseLayerBrush : BreakableModel, IDisposable
Dispose(true);
GC.SuppressFinalize(this);
}
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ IEnumerable result = [Descriptor.Provider];
+ if (BaseProperties != null)
+ result = result.Concat(BaseProperties.GetFeatureDependencies());
+
+ return result;
+ }
+
+ #endregion
}
///
diff --git a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
index 7d300077f..651df32f9 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Linq;
using Artemis.Storage.Entities.Profile;
using SkiaSharp;
@@ -7,7 +9,7 @@ namespace Artemis.Core.LayerEffects;
///
/// For internal use only, please use instead
///
-public abstract class BaseLayerEffect : BreakableModel, IDisposable, IStorageModel
+public abstract class BaseLayerEffect : BreakableModel, IDisposable, IStorageModel, IPluginFeatureDependent
{
private ILayerEffectConfigurationDialog? _configurationDialog;
private LayerEffectDescriptor _descriptor;
@@ -164,7 +166,7 @@ public abstract class BaseLayerEffect : BreakableModel, IDisposable, IStorageMod
// Not only is this needed to initialize properties on the layer effects, it also prevents implementing anything
// but LayerEffect outside the core
internal abstract void Initialize();
-
+
internal void InternalUpdate(Timeline timeline)
{
BaseProperties?.Update(timeline);
@@ -235,4 +237,18 @@ public abstract class BaseLayerEffect : BreakableModel, IDisposable, IStorageMod
BaseProperties?.ApplyToEntity();
LayerEffectEntity.PropertyGroup = BaseProperties?.PropertyGroupEntity;
}
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ IEnumerable result = [Descriptor.Provider];
+ if (BaseProperties != null)
+ result = result.Concat(BaseProperties.GetFeatureDependencies());
+
+ return result;
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs
index 4ce40a0ab..06c382749 100644
--- a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs
+++ b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs
@@ -8,7 +8,7 @@ namespace Artemis.Core;
///
/// Represents a kind of node inside a
///
-public interface INode : INotifyPropertyChanged, IBreakableModel
+public interface INode : INotifyPropertyChanged, IBreakableModel, IPluginFeatureDependent
{
///
/// Gets or sets the ID of the node.
diff --git a/src/Artemis.Core/VisualScripting/Interfaces/INodeScript.cs b/src/Artemis.Core/VisualScripting/Interfaces/INodeScript.cs
index 456692a4d..7ed23e898 100644
--- a/src/Artemis.Core/VisualScripting/Interfaces/INodeScript.cs
+++ b/src/Artemis.Core/VisualScripting/Interfaces/INodeScript.cs
@@ -8,7 +8,7 @@ namespace Artemis.Core;
///
/// Represents a node script
///
-public interface INodeScript : INotifyPropertyChanged, IDisposable, IStorageModel
+public interface INodeScript : INotifyPropertyChanged, IDisposable, IStorageModel, IPluginFeatureDependent
{
///
/// Gets the name of the node script.
diff --git a/src/Artemis.Core/VisualScripting/NodeScript.cs b/src/Artemis.Core/VisualScripting/NodeScript.cs
index e8ccddd4a..8f281f6c3 100644
--- a/src/Artemis.Core/VisualScripting/NodeScript.cs
+++ b/src/Artemis.Core/VisualScripting/NodeScript.cs
@@ -401,6 +401,16 @@ public abstract class NodeScript : CorePropertyChanged, INodeScript
}
#endregion
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public IEnumerable GetFeatureDependencies()
+ {
+ return Nodes.SelectMany(n => n.GetFeatureDependencies());
+ }
+
+ #endregion
}
///
diff --git a/src/Artemis.Core/VisualScripting/Nodes/Node.cs b/src/Artemis.Core/VisualScripting/Nodes/Node.cs
index 8d4a40d3d..b3c4ad3ee 100644
--- a/src/Artemis.Core/VisualScripting/Nodes/Node.cs
+++ b/src/Artemis.Core/VisualScripting/Nodes/Node.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Artemis.Core.Events;
-using DryIoc;
namespace Artemis.Core;
@@ -404,4 +403,14 @@ public abstract class Node : BreakableModel, INode
}
#endregion
+
+ #region Implementation of IPluginFeatureDependent
+
+ ///
+ public virtual IEnumerable GetFeatureDependencies()
+ {
+ return NodeData == null ? [] : [NodeData.Provider];
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Models/SubmissionWizardState.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Models/SubmissionWizardState.cs
index e06f14ce9..c92f6290b 100644
--- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Models/SubmissionWizardState.cs
+++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Models/SubmissionWizardState.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using Artemis.Core;
using Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.Layout;
using Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.Plugin;
using Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.Profile;
@@ -37,7 +38,7 @@ public class SubmissionWizardState : IDisposable
public List Images { get; set; } = new();
public IEntrySource? EntrySource { get; set; }
-
+
public void ChangeScreen() where TSubmissionViewModel : SubmissionViewModel
{
try
diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs
index d52457a55..4a5b9cae9 100644
--- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs
@@ -65,10 +65,10 @@ public partial class ProfileSelectionStepViewModel : SubmissionViewModel
private void ExecuteContinue()
{
- if (SelectedProfile == null)
+ if (SelectedProfile?.Profile == null)
return;
- State.EntrySource = new ProfileEntrySource(SelectedProfile);
+ State.EntrySource = new ProfileEntrySource(SelectedProfile, SelectedProfile.GetFeatureDependencies().Distinct().ToList());
State.Name = SelectedProfile.Name;
State.Icon = SelectedProfile.Icon.GetIconStream();
diff --git a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntrySource.cs b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntrySource.cs
index 739f8e28f..16235a935 100644
--- a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntrySource.cs
+++ b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntrySource.cs
@@ -4,10 +4,12 @@ namespace Artemis.WebClient.Workshop.Handlers.UploadHandlers;
public class ProfileEntrySource : IEntrySource
{
- public ProfileEntrySource(ProfileConfiguration profileConfiguration)
+ public ProfileEntrySource(ProfileConfiguration profileConfiguration, List dependencies)
{
ProfileConfiguration = profileConfiguration;
+ Dependencies = dependencies;
}
- public ProfileConfiguration ProfileConfiguration { get; set; }
+ public ProfileConfiguration ProfileConfiguration { get; }
+ public List Dependencies { get; }
}
\ No newline at end of file
diff --git a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs
index 012491729..3dbbd68e9 100644
--- a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs
+++ b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs
@@ -31,6 +31,7 @@ public class ProfileEntryUploadHandler : IEntryUploadHandler
MultipartFormDataContent content = new();
StreamContent streamContent = new(archiveStream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
+ content.Add(JsonContent.Create(source.Dependencies.Select(d => new {PluginId = d.Plugin.Guid, FeatureId = d.Id}).ToList()), "ReleaseDependencies");
content.Add(streamContent, "file", "file.zip");
// Submit