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()
|
||||
{
|
||||
DisplayConditionMet = false;
|
||||
Timeline.JumpToStart();
|
||||
Timeline.JumpToEnd();
|
||||
|
||||
foreach (ProfileElement child in Children)
|
||||
child.Reset();
|
||||
|
||||
@ -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 />
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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" />
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"profiles": {
|
||||
"Artemis.UI": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "--force-elevation"
|
||||
"commandLineArgs": "--force-elevation --logging=debug"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 />
|
||||
|
||||
@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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, )",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user