mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Profiles - Fixed conditions triggering on profile load, closes #520
UI - Added logging startup argument, closes #532 Plugins - Added import button, closes #521
This commit is contained in:
parent
1c10eb8aa4
commit
f343b3d0f8
@ -96,7 +96,7 @@ namespace Artemis.Core
|
|||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
DisplayConditionMet = false;
|
DisplayConditionMet = false;
|
||||||
Timeline.JumpToStart();
|
Timeline.JumpToEnd();
|
||||||
|
|
||||||
foreach (ProfileElement child in Children)
|
foreach (ProfileElement child in Children)
|
||||||
child.Reset();
|
child.Reset();
|
||||||
|
|||||||
@ -183,6 +183,8 @@ namespace Artemis.Core
|
|||||||
General.ShapeType.CurrentValueSet += ShapeTypeOnCurrentValueSet;
|
General.ShapeType.CurrentValueSet += ShapeTypeOnCurrentValueSet;
|
||||||
ApplyShapeType();
|
ApplyShapeType();
|
||||||
ActivateLayerBrush();
|
ActivateLayerBrush();
|
||||||
|
|
||||||
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Storage
|
#region Storage
|
||||||
@ -272,7 +274,7 @@ namespace Artemis.Core
|
|||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
DisplayConditionMet = false;
|
DisplayConditionMet = false;
|
||||||
Timeline.JumpToStart();
|
Timeline.JumpToEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@ -168,8 +168,28 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
private void ApplyLoggingLevel()
|
private void ApplyLoggingLevel()
|
||||||
{
|
{
|
||||||
_logger.Information("Setting logging level to {loggingLevel}", _loggingLevel.Value);
|
string? argument = StartupArguments.FirstOrDefault(a => a.StartsWith("--logging"));
|
||||||
LoggerProvider.LoggingLevelSwitch.MinimumLevel = _loggingLevel.Value;
|
if (argument != null)
|
||||||
|
{
|
||||||
|
// Parse the provided log level
|
||||||
|
string[] parts = argument.Split('=');
|
||||||
|
if (parts.Length == 2 && Enum.TryParse(typeof(LogEventLevel), parts[1], true, out object? logLevelArgument))
|
||||||
|
{
|
||||||
|
_logger.Information("Setting logging level to {loggingLevel} from startup argument", (LogEventLevel) logLevelArgument!);
|
||||||
|
LoggerProvider.LoggingLevelSwitch.MinimumLevel = (LogEventLevel) logLevelArgument;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Warning("Failed to set log level from startup argument {argument}", argument);
|
||||||
|
_logger.Information("Setting logging level to {loggingLevel}", _loggingLevel.Value);
|
||||||
|
LoggerProvider.LoggingLevelSwitch.MinimumLevel = _loggingLevel.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Information("Setting logging level to {loggingLevel}", _loggingLevel.Value);
|
||||||
|
LoggerProvider.LoggingLevelSwitch.MinimumLevel = _loggingLevel.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SurfaceOnUpdating(UpdatingEventArgs args)
|
private void SurfaceOnUpdating(UpdatingEventArgs args)
|
||||||
|
|||||||
@ -63,6 +63,13 @@ namespace Artemis.Core.Services
|
|||||||
/// <param name="saveState">Whether or not to save the new enabled state</param>
|
/// <param name="saveState">Whether or not to save the new enabled state</param>
|
||||||
void DisablePlugin(Plugin plugin, bool saveState);
|
void DisablePlugin(Plugin plugin, bool saveState);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Imports the plugin contained in the provided ZIP file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The full path to the ZIP file that contains the plugin</param>
|
||||||
|
/// <returns>The resulting plugin</returns>
|
||||||
|
Plugin ImportPlugin(string fileName);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables the provided plugin feature
|
/// Enables the provided plugin feature
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -273,7 +273,7 @@ namespace Artemis.Core.Services
|
|||||||
FileInfo[] fileInfos = directory.GetFiles();
|
FileInfo[] fileInfos = directory.GetFiles();
|
||||||
if (!fileInfos.Any(f => string.Equals(f.Name, plugin.Info.Main, StringComparison.InvariantCulture)))
|
if (!fileInfos.Any(f => string.Equals(f.Name, plugin.Info.Main, StringComparison.InvariantCulture)))
|
||||||
throw new ArtemisPluginException(plugin, "Plugin main entry casing mismatch at " + plugin.Info.Main);
|
throw new ArtemisPluginException(plugin, "Plugin main entry casing mismatch at " + plugin.Info.Main);
|
||||||
|
|
||||||
// Load the plugin, all types implementing Plugin and register them with DI
|
// Load the plugin, all types implementing Plugin and register them with DI
|
||||||
plugin.PluginLoader = PluginLoader.CreateFromAssemblyFile(mainFile!, configure =>
|
plugin.PluginLoader = PluginLoader.CreateFromAssemblyFile(mainFile!, configure =>
|
||||||
{
|
{
|
||||||
@ -437,6 +437,55 @@ namespace Artemis.Core.Services
|
|||||||
OnPluginDisabled(new PluginEventArgs(plugin));
|
OnPluginDisabled(new PluginEventArgs(plugin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Plugin ImportPlugin(string fileName)
|
||||||
|
{
|
||||||
|
DirectoryInfo pluginDirectory = new(Path.Combine(Constants.DataFolder, "plugins"));
|
||||||
|
|
||||||
|
// Find the metadata file in the zip
|
||||||
|
using ZipArchive archive = ZipFile.OpenRead(fileName);
|
||||||
|
ZipArchiveEntry? metaDataFileEntry = archive.Entries.FirstOrDefault(e => e.Name == "plugin.json");
|
||||||
|
if (metaDataFileEntry == null)
|
||||||
|
throw new ArtemisPluginException("Couldn't find a plugin.json in " + fileName);
|
||||||
|
|
||||||
|
|
||||||
|
using StreamReader reader = new(metaDataFileEntry.Open());
|
||||||
|
PluginInfo pluginInfo = CoreJson.DeserializeObject<PluginInfo>(reader.ReadToEnd())!;
|
||||||
|
if (!pluginInfo.Main.EndsWith(".dll"))
|
||||||
|
throw new ArtemisPluginException("Main entry in plugin.json must point to a .dll file" + fileName);
|
||||||
|
|
||||||
|
Plugin? existing = _plugins.FirstOrDefault(p => p.Guid == pluginInfo.Guid);
|
||||||
|
if (existing != null)
|
||||||
|
throw new ArtemisPluginException($"A plugin with the same GUID is already loaded: {existing.Info}");
|
||||||
|
|
||||||
|
string targetDirectory = pluginInfo.Main.Split(".dll")[0].Replace("/", "").Replace("\\", "");
|
||||||
|
string uniqueTargetDirectory = targetDirectory;
|
||||||
|
int attempt = 2;
|
||||||
|
|
||||||
|
// Find a unique folder
|
||||||
|
while (pluginDirectory.EnumerateDirectories().Any(d => d.Name == uniqueTargetDirectory))
|
||||||
|
{
|
||||||
|
uniqueTargetDirectory = targetDirectory + "-" + attempt;
|
||||||
|
attempt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract everything in the same archive directory to the unique plugin directory
|
||||||
|
DirectoryInfo directoryInfo = new(Path.Combine(pluginDirectory.FullName, uniqueTargetDirectory));
|
||||||
|
Directory.CreateDirectory(directoryInfo.FullName);
|
||||||
|
string metaDataDirectory = metaDataFileEntry.FullName.Replace(metaDataFileEntry.Name, "");
|
||||||
|
foreach (ZipArchiveEntry zipArchiveEntry in archive.Entries)
|
||||||
|
{
|
||||||
|
if (zipArchiveEntry.FullName.StartsWith(metaDataDirectory))
|
||||||
|
{
|
||||||
|
string target = Path.Combine(directoryInfo.FullName, zipArchiveEntry.FullName.Remove(0, metaDataDirectory.Length));
|
||||||
|
zipArchiveEntry.ExtractToFile(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the newly extracted plugin and return the result
|
||||||
|
return LoadPlugin(directoryInfo);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Features
|
#region Features
|
||||||
|
|||||||
@ -142,6 +142,7 @@
|
|||||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
|
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
|
||||||
<PackageReference Include="Ninject" Version="3.3.4" />
|
<PackageReference Include="Ninject" Version="3.3.4" />
|
||||||
<PackageReference Include="Ninject.Extensions.Conventions" Version="3.3.0" />
|
<PackageReference Include="Ninject.Extensions.Conventions" Version="3.3.0" />
|
||||||
|
<PackageReference Include="Ookii.Dialogs.Wpf" Version="3.1.0" />
|
||||||
<PackageReference Include="RawInput.Sharp" Version="0.0.3" />
|
<PackageReference Include="RawInput.Sharp" Version="0.0.3" />
|
||||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||||
<PackageReference Include="SkiaSharp.Views.WPF" Version="2.80.2" />
|
<PackageReference Include="SkiaSharp.Views.WPF" Version="2.80.2" />
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"profiles": {
|
"profiles": {
|
||||||
"Artemis.UI": {
|
"Artemis.UI": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "--force-elevation"
|
"commandLineArgs": "--force-elevation --logging=debug"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14,25 +14,35 @@
|
|||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid Margin="0 15" MaxWidth="800" >
|
<Grid Margin="0 15" MinWidth="810" Width="{Binding Path=ActualWidth, ElementName=PluginsContainer}">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="200" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBlock Grid.Column="0" TextWrapping="Wrap">
|
<TextBlock Grid.Column="0" TextWrapping="Wrap">
|
||||||
The list below shows all loaded plugins. If you're missing something, view your logs folder.
|
The list below shows all loaded plugins. <LineBreak />
|
||||||
|
If you're missing something, view your logs folder.
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<materialDesign:PackIcon Grid.Column="1" Kind="Search" VerticalAlignment="Top" Margin="15 5 0 0" />
|
<materialDesign:PackIcon Grid.Column="1" Kind="Search" VerticalAlignment="Top" Margin="15 5 0 0" />
|
||||||
<TextBox Grid.Column="2"
|
<TextBox Grid.Column="2"
|
||||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||||
materialDesign:HintAssist.Hint="Search plugin"
|
materialDesign:HintAssist.Hint="Search plugin"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
Margin="5 0"
|
Margin="5 0"
|
||||||
Text="{Binding SearchPluginInput, Delay=300, UpdateSourceTrigger=PropertyChanged}"/>
|
Text="{Binding SearchPluginInput, Delay=300, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
|
||||||
|
<Button Grid.Column="3"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Style="{StaticResource MaterialDesignRaisedButton}"
|
||||||
|
Command="{s:Action ImportPlugin}"
|
||||||
|
Margin="15 0">
|
||||||
|
IMPORT PLUGIN
|
||||||
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
||||||
<ItemsControl ItemsSource="{Binding Items}" Margin="15 0 15 15" HorizontalAlignment="Center" MaxWidth="1700">
|
<ItemsControl ItemsSource="{Binding Items}" Margin="15 0 15 15" HorizontalAlignment="Center" MaxWidth="1700" x:Name="PluginsContainer">
|
||||||
<ItemsControl.ItemsPanel>
|
<ItemsControl.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<WrapPanel />
|
<WrapPanel />
|
||||||
|
|||||||
@ -2,8 +2,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Ninject.Factories;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Ookii.Dialogs.Wpf;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||||
@ -11,15 +14,17 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
public class PluginSettingsTabViewModel : Conductor<PluginSettingsViewModel>.Collection.AllActive
|
public class PluginSettingsTabViewModel : Conductor<PluginSettingsViewModel>.Collection.AllActive
|
||||||
{
|
{
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
|
private readonly IMessageService _messageService;
|
||||||
private readonly ISettingsVmFactory _settingsVmFactory;
|
private readonly ISettingsVmFactory _settingsVmFactory;
|
||||||
private string _searchPluginInput;
|
private string _searchPluginInput;
|
||||||
private List<PluginSettingsViewModel> _instances;
|
private List<PluginSettingsViewModel> _instances;
|
||||||
|
|
||||||
public PluginSettingsTabViewModel(IPluginManagementService pluginManagementService, ISettingsVmFactory settingsVmFactory)
|
public PluginSettingsTabViewModel(IPluginManagementService pluginManagementService, IMessageService messageService, ISettingsVmFactory settingsVmFactory)
|
||||||
{
|
{
|
||||||
DisplayName = "PLUGINS";
|
DisplayName = "PLUGINS";
|
||||||
|
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
|
_messageService = messageService;
|
||||||
_settingsVmFactory = settingsVmFactory;
|
_settingsVmFactory = settingsVmFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,5 +68,25 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
|
|
||||||
base.OnActivate();
|
base.OnActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ImportPlugin()
|
||||||
|
{
|
||||||
|
VistaOpenFileDialog dialog = new();
|
||||||
|
dialog.Filter = "ZIP files (*.zip)|*.zip";
|
||||||
|
dialog.Title = "Import Artemis plugin";
|
||||||
|
bool? result = dialog.ShowDialog();
|
||||||
|
if (result == true)
|
||||||
|
{
|
||||||
|
Plugin plugin = _pluginManagementService.ImportPlugin(dialog.FileName);
|
||||||
|
|
||||||
|
_instances = _pluginManagementService.GetAllPlugins()
|
||||||
|
.Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p))
|
||||||
|
.OrderBy(i => i.Plugin.Info.Name)
|
||||||
|
.ToList();
|
||||||
|
SearchPluginInput = plugin.Info.Name;
|
||||||
|
|
||||||
|
_messageService.ShowMessage($"Imported plugin: {plugin.Info.Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,6 +80,12 @@
|
|||||||
"Ninject.Extensions.Factory": "3.3.2"
|
"Ninject.Extensions.Factory": "3.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Ookii.Dialogs.Wpf": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[3.1.0, )",
|
||||||
|
"resolved": "3.1.0",
|
||||||
|
"contentHash": "EpUWoSLLO1aVkUmo2dPE4xO+zQZRxbp13agbbQzGBL1ACALgCD69cTwdLdPdg2LIsPcZ4uA3iID+YaazdZxyww=="
|
||||||
|
},
|
||||||
"RawInput.Sharp": {
|
"RawInput.Sharp": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[0.0.3, )",
|
"requested": "[0.0.3, )",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user