1
0
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:
SpoinkyNL 2021-02-03 19:21:04 +01:00
parent 1c10eb8aa4
commit f343b3d0f8
10 changed files with 134 additions and 14 deletions

View File

@ -96,7 +96,7 @@ namespace Artemis.Core
public override void Reset()
{
DisplayConditionMet = false;
Timeline.JumpToStart();
Timeline.JumpToEnd();
foreach (ProfileElement child in Children)
child.Reset();

View File

@ -183,6 +183,8 @@ namespace Artemis.Core
General.ShapeType.CurrentValueSet += ShapeTypeOnCurrentValueSet;
ApplyShapeType();
ActivateLayerBrush();
Reset();
}
#region Storage
@ -272,7 +274,7 @@ namespace Artemis.Core
public override void Reset()
{
DisplayConditionMet = false;
Timeline.JumpToStart();
Timeline.JumpToEnd();
}
/// <inheritdoc />

View File

@ -168,8 +168,28 @@ namespace Artemis.Core.Services
private void ApplyLoggingLevel()
{
_logger.Information("Setting logging level to {loggingLevel}", _loggingLevel.Value);
LoggerProvider.LoggingLevelSwitch.MinimumLevel = _loggingLevel.Value;
string? argument = StartupArguments.FirstOrDefault(a => a.StartsWith("--logging"));
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)

View File

@ -63,6 +63,13 @@ namespace Artemis.Core.Services
/// <param name="saveState">Whether or not to save the new enabled state</param>
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>
/// Enables the provided plugin feature
/// </summary>

View File

@ -273,7 +273,7 @@ namespace Artemis.Core.Services
FileInfo[] fileInfos = directory.GetFiles();
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);
// Load the plugin, all types implementing Plugin and register them with DI
plugin.PluginLoader = PluginLoader.CreateFromAssemblyFile(mainFile!, configure =>
{
@ -437,6 +437,55 @@ namespace Artemis.Core.Services
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
#region Features

View File

@ -142,6 +142,7 @@
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
<PackageReference Include="Ninject" Version="3.3.4" />
<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="Serilog" Version="2.10.0" />
<PackageReference Include="SkiaSharp.Views.WPF" Version="2.80.2" />

View File

@ -2,7 +2,7 @@
"profiles": {
"Artemis.UI": {
"commandName": "Project",
"commandLineArgs": "--force-elevation"
"commandLineArgs": "--force-elevation --logging=debug"
}
}
}

View File

@ -14,25 +14,35 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Margin="0 15" MaxWidth="800" >
<Grid Margin="0 15" MinWidth="810" Width="{Binding Path=ActualWidth, ElementName=PluginsContainer}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<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>
<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:HintAssist.Hint="Search plugin"
VerticalAlignment="Top"
Margin="5 0"
Text="{Binding SearchPluginInput, Delay=300, UpdateSourceTrigger=PropertyChanged}"/>
Margin="5 0"
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>
<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>
<ItemsPanelTemplate>
<WrapPanel />

View File

@ -2,8 +2,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared.Services;
using Ookii.Dialogs.Wpf;
using Stylet;
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
{
private readonly IPluginManagementService _pluginManagementService;
private readonly IMessageService _messageService;
private readonly ISettingsVmFactory _settingsVmFactory;
private string _searchPluginInput;
private List<PluginSettingsViewModel> _instances;
public PluginSettingsTabViewModel(IPluginManagementService pluginManagementService, ISettingsVmFactory settingsVmFactory)
public PluginSettingsTabViewModel(IPluginManagementService pluginManagementService, IMessageService messageService, ISettingsVmFactory settingsVmFactory)
{
DisplayName = "PLUGINS";
_pluginManagementService = pluginManagementService;
_messageService = messageService;
_settingsVmFactory = settingsVmFactory;
}
@ -63,5 +68,25 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
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}");
}
}
}
}

View File

@ -80,6 +80,12 @@
"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": {
"type": "Direct",
"requested": "[0.0.3, )",