diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index c9451b7ee..057b9d6a7 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -336,11 +336,9 @@
+
-
-
-
@@ -354,6 +352,7 @@
+
@@ -504,23 +503,23 @@
-
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
diff --git a/Artemis/Artemis/ArtemisBootstrapper.cs b/Artemis/Artemis/ArtemisBootstrapper.cs
index 754eed3cc..e15174d44 100644
--- a/Artemis/Artemis/ArtemisBootstrapper.cs
+++ b/Artemis/Artemis/ArtemisBootstrapper.cs
@@ -77,8 +77,7 @@ namespace Artemis
protected override void Configure()
{
- _kernel = new StandardKernel(new BaseModules(), new ManagerModules(), new DeviceModules(),
- new EffectModules(), new ProfileModules());
+ _kernel = new StandardKernel(new BaseModules(), new ManagerModules());
_kernel.Bind().To().InSingletonScope();
_kernel.Bind().To().InSingletonScope();
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs
index 503c7e16f..cde46b320 100644
--- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs
+++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs
@@ -8,7 +8,7 @@ using Ninject.Extensions.Logging;
namespace Artemis.DeviceProviders.Corsair
{
- internal class CorsairHeadset : DeviceProvider
+ public class CorsairHeadset : DeviceProvider
{
public CorsairHeadset(ILogger logger)
{
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs
index c6586ef31..e6dcd60cf 100644
--- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs
+++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs
@@ -8,7 +8,7 @@ using Ninject.Extensions.Logging;
namespace Artemis.DeviceProviders.Corsair
{
- internal class CorsairMouse : DeviceProvider
+ public class CorsairMouse : DeviceProvider
{
public CorsairMouse(ILogger logger)
{
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs
index d39f50fe2..e4e6cc39e 100644
--- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs
+++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs
@@ -8,7 +8,7 @@ using Ninject.Extensions.Logging;
namespace Artemis.DeviceProviders.Corsair
{
- internal class CorsairMousemat : DeviceProvider
+ public class CorsairMousemat : DeviceProvider
{
public CorsairMousemat(ILogger logger)
{
diff --git a/Artemis/Artemis/DeviceProviders/Logitech/G810.cs b/Artemis/Artemis/DeviceProviders/Logitech/G810.cs
index e51e0b9a5..aedb226b2 100644
--- a/Artemis/Artemis/DeviceProviders/Logitech/G810.cs
+++ b/Artemis/Artemis/DeviceProviders/Logitech/G810.cs
@@ -8,7 +8,7 @@ using Artemis.Settings;
namespace Artemis.DeviceProviders.Logitech
{
- internal class G810 : LogitechKeyboard
+ public class G810 : LogitechKeyboard
{
private GeneralSettings _generalSettings;
diff --git a/Artemis/Artemis/DeviceProviders/Logitech/G910.cs b/Artemis/Artemis/DeviceProviders/Logitech/G910.cs
index d79aca306..e6f9ae8ce 100644
--- a/Artemis/Artemis/DeviceProviders/Logitech/G910.cs
+++ b/Artemis/Artemis/DeviceProviders/Logitech/G910.cs
@@ -10,7 +10,7 @@ using Artemis.Settings;
namespace Artemis.DeviceProviders.Logitech
{
- internal class G910 : LogitechKeyboard
+ public class G910 : LogitechKeyboard
{
private readonly GeneralSettings _generalSettings;
diff --git a/Artemis/Artemis/Events/ProfileDeviceEventsArg.cs b/Artemis/Artemis/Events/ProfileDeviceEventsArg.cs
new file mode 100644
index 000000000..6a988f1bd
--- /dev/null
+++ b/Artemis/Artemis/Events/ProfileDeviceEventsArg.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+
+namespace Artemis.Events
+{
+ public class ProfileDeviceEventsArg : EventArgs
+ {
+ public ProfileDeviceEventsArg(string updateType, IDataModel dataModel, bool preview, DrawingContext drawingContext)
+ {
+ UpdateType = updateType;
+ DataModel = dataModel;
+ Preview = preview;
+ DrawingContext = drawingContext;
+ }
+
+ public string UpdateType { get; }
+ public IDataModel DataModel { get; }
+ public bool Preview { get; }
+ public DrawingContext DrawingContext { get; }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/InjectionModules/BaseModules.cs b/Artemis/Artemis/InjectionModules/BaseModules.cs
index cdd51407f..5c975f7f9 100644
--- a/Artemis/Artemis/InjectionModules/BaseModules.cs
+++ b/Artemis/Artemis/InjectionModules/BaseModules.cs
@@ -1,39 +1,135 @@
-using Artemis.Modules.Effects.ProfilePreview;
-using Artemis.Services;
-using Artemis.Utilities.DataReaders;
-using Artemis.Utilities.GameState;
-using Artemis.ViewModels;
-using Artemis.ViewModels.Abstract;
-using Artemis.ViewModels.Profiles;
-using Ninject.Modules;
-
-namespace Artemis.InjectionModules
-{
- internal class BaseModules : NinjectModule
- {
- public override void Load()
- {
- // ViewModels
- Bind().ToSelf().InSingletonScope();
- Bind().ToSelf();
- Bind().ToSelf();
- Bind().ToSelf().InSingletonScope();
-
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
-
- // Models
- Bind().ToSelf().InSingletonScope();
-
- // Services
- Bind().ToSelf().InSingletonScope();
- Bind().ToSelf().InSingletonScope();
-
- // Servers
- Bind().ToSelf().InSingletonScope();
- Bind().ToSelf().InSingletonScope();
- }
- }
+using Artemis.DeviceProviders;
+using Artemis.Models;
+using Artemis.Modules.Effects.ProfilePreview;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Types.AmbientLight;
+using Artemis.Profiles.Layers.Types.Audio;
+using Artemis.Profiles.Layers.Types.Audio.AudioCapturing;
+using Artemis.Profiles.Layers.Types.KeyPress;
+using Artemis.Profiles.Lua;
+using Artemis.Services;
+using Artemis.Utilities.DataReaders;
+using Artemis.Utilities.GameState;
+using Artemis.ViewModels;
+using Artemis.ViewModels.Abstract;
+using Artemis.ViewModels.Profiles;
+using Ninject.Extensions.Conventions;
+using Ninject.Modules;
+
+namespace Artemis.InjectionModules
+{
+ public class BaseModules : NinjectModule
+ {
+ public override void Load()
+ {
+ #region ViewModels
+
+ Bind().ToSelf().InSingletonScope();
+ Bind().ToSelf();
+ Bind().ToSelf();
+ Bind().ToSelf().InSingletonScope();
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindAllBaseClasses());
+
+ #endregion
+
+ #region Models
+
+ Bind().ToSelf().InSingletonScope();
+
+ #endregion
+
+ #region Services
+
+ Bind().ToSelf().InSingletonScope();
+ Bind().ToSelf().InSingletonScope();
+
+ #endregion
+
+ #region Servers
+
+ Bind().ToSelf().InSingletonScope();
+ Bind().ToSelf().InSingletonScope();
+
+ #endregion
+
+ #region Devices
+
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindAllBaseClasses());
+
+ #endregion
+
+ #region Effects
+
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindAllBaseClasses()
+ .Configure((b, c) => b.InSingletonScope().Named(c.Name))
+ );
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindBase());
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindBase());
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindBase());
+
+ #endregion
+
+ #region Profiles
+
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindAllInterfaces());
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindAllInterfaces());
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindAllInterfaces());
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindToSelf());
+
+ // Type helpers
+ Bind().ToSelf().InSingletonScope();
+
+ #endregion
+
+ #region Lua
+
+ Kernel.Bind(x =>
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindAllBaseClasses());
+
+ #endregion
+ }
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/InjectionModules/DeviceModules.cs b/Artemis/Artemis/InjectionModules/DeviceModules.cs
deleted file mode 100644
index de64108ce..000000000
--- a/Artemis/Artemis/InjectionModules/DeviceModules.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Artemis.DeviceProviders;
-using Artemis.DeviceProviders.Artemis;
-using Artemis.DeviceProviders.CoolerMaster;
-using Artemis.DeviceProviders.Corsair;
-using Artemis.DeviceProviders.Logitech;
-using Artemis.DeviceProviders.Razer;
-using Ninject.Modules;
-
-namespace Artemis.InjectionModules
-{
- public class DeviceModules : NinjectModule
- {
- public override void Load()
- {
- // Keyboards
- Bind().To().InSingletonScope();
- Bind().To().InSingletonScope();
- Bind().To().InSingletonScope();
- Bind().To().InSingletonScope();
- Bind().To().InSingletonScope();
- Bind().To().InSingletonScope();
- Bind().To().InSingletonScope();
-
- // Mice
- Bind().To().InSingletonScope();
-
- // Headsets
- Bind().To().InSingletonScope();
-
- // Mousemats
- Bind().To().InSingletonScope();
-
- // Other
- Bind().To().InSingletonScope();
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/InjectionModules/EffectModules.cs b/Artemis/Artemis/InjectionModules/EffectModules.cs
deleted file mode 100644
index 387b85ba7..000000000
--- a/Artemis/Artemis/InjectionModules/EffectModules.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using Artemis.Models;
-using Artemis.ViewModels.Abstract;
-using Ninject.Extensions.Conventions;
-using Ninject.Modules;
-
-namespace Artemis.InjectionModules
-{
- public class EffectModules : NinjectModule
- {
- public override void Load()
- {
- // Effects
- Kernel.Bind(x =>
- {
- x.FromThisAssembly()
- .SelectAllClasses()
- .InheritedFrom()
- .BindBase()
- .Configure((b, c) => b.InSingletonScope().Named(c.Name));
- });
-
- // View models
- Kernel.Bind(x =>
- {
- x.FromThisAssembly()
- .SelectAllClasses()
- .InheritedFrom()
- .BindBase();
- });
-
- Kernel.Bind(x =>
- {
- x.FromThisAssembly()
- .SelectAllClasses()
- .InheritedFrom()
- .BindBase();
- });
- Kernel.Bind(x =>
- {
- x.FromThisAssembly()
- .SelectAllClasses()
- .InheritedFrom()
- .BindBase();
- });
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/InjectionModules/ManagerModules.cs b/Artemis/Artemis/InjectionModules/ManagerModules.cs
index 540e266ef..c90727795 100644
--- a/Artemis/Artemis/InjectionModules/ManagerModules.cs
+++ b/Artemis/Artemis/InjectionModules/ManagerModules.cs
@@ -3,7 +3,7 @@ using Ninject.Modules;
namespace Artemis.InjectionModules
{
- internal class ManagerModules : NinjectModule
+ public class ManagerModules : NinjectModule
{
public override void Load()
{
@@ -12,6 +12,7 @@ namespace Artemis.InjectionModules
Bind().ToSelf().InSingletonScope();
Bind().ToSelf().InSingletonScope();
Bind().ToSelf().InSingletonScope();
+ Bind().ToSelf().InSingletonScope();
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/InjectionModules/ProfileModules.cs b/Artemis/Artemis/InjectionModules/ProfileModules.cs
deleted file mode 100644
index 8e91b68b8..000000000
--- a/Artemis/Artemis/InjectionModules/ProfileModules.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using Artemis.Profiles.Layers.Animations;
-using Artemis.Profiles.Layers.Conditions;
-using Artemis.Profiles.Layers.Interfaces;
-using Artemis.Profiles.Layers.Types.AmbientLight;
-using Artemis.Profiles.Layers.Types.Audio;
-using Artemis.Profiles.Layers.Types.Audio.AudioCapturing;
-using Artemis.Profiles.Layers.Types.Folder;
-using Artemis.Profiles.Layers.Types.Generic;
-using Artemis.Profiles.Layers.Types.Headset;
-using Artemis.Profiles.Layers.Types.Keyboard;
-using Artemis.Profiles.Layers.Types.KeyboardGif;
-using Artemis.Profiles.Layers.Types.KeyPress;
-using Artemis.Profiles.Layers.Types.Mouse;
-using Artemis.Profiles.Layers.Types.Mousemat;
-using Ninject.Modules;
-
-namespace Artemis.InjectionModules
-{
- public class ProfileModules : NinjectModule
- {
- public override void Load()
- {
- // Animations
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
-
- // Conditions
- Bind().To();
- Bind().To();
-
- // Types
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
- Bind().To();
-
- // Bind some Layer Types to self as well in order to allow JSON.NET injection
- Bind().ToSelf();
- Bind().ToSelf();
- Bind().ToSelf();
-
- // Type helpers
- Bind().ToSelf().InSingletonScope();
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/LuaWrapper.cs b/Artemis/Artemis/Managers/LuaManager.cs
similarity index 51%
rename from Artemis/Artemis/Profiles/Lua/LuaWrapper.cs
rename to Artemis/Artemis/Managers/LuaManager.cs
index 0f9a94e3c..d75b73143 100644
--- a/Artemis/Artemis/Profiles/Lua/LuaWrapper.cs
+++ b/Artemis/Artemis/Managers/LuaManager.cs
@@ -1,212 +1,208 @@
-using System;
-using System.IO;
-using System.Text;
-using Artemis.DAL;
-using Artemis.DeviceProviders;
-using Artemis.Profiles.Layers.Models;
-using Artemis.Profiles.Lua.Brushes;
-using Artemis.Profiles.Lua.Modules.Events;
-using Artemis.Properties;
-using Castle.Core.Internal;
-using MoonSharp.Interpreter;
-using Ninject;
-using NLog;
-
-namespace Artemis.Profiles.Lua
-{
- ///
- /// This class is a singleton due to the fact that the LuaScript isn't very memory
- /// friendly when creating new ones over and over.
- ///
- public class LuaWrapper
- {
- private readonly IKernel _kernel;
- private readonly Logger _logger = LogManager.GetCurrentClassLogger();
- private readonly Script _luaScript = new Script(CoreModules.Preset_SoftSandbox);
- private FileSystemWatcher _watcher;
-
- public ProfileModel ProfileModel { get; private set; }
- public KeyboardProvider KeyboardProvider { get; private set; }
- public LayerModel LayerModel { get; set; }
-
- public LuaWrapper(IKernel kernel)
- {
- _kernel = kernel;
- }
-
- public static void SetupLua(ProfileModel profileModel, KeyboardProvider keyboardProvider)
- {
- Clear();
-
- if ((profileModel == null) || (keyboardProvider == null))
- return;
-
- // Setup a new environment
- KeyboardProvider = keyboardProvider;
- ProfileModel = profileModel;
- LuaProfileWrapper = new LuaProfileWrapper(ProfileModel);
- LuaBrushWrapper = new LuaBrushWrapper();
- LuaKeyboardWrapper = new LuaKeyboardWrapper(keyboardProvider);
- LuaMouseWrapper = new LuaMouseWrapper();
- LuaEventsWrapper = new LuaEventsWrapper();
-
- _luaScript.Options.DebugPrint = LuaPrint;
- _luaScript.Globals["Profile"] = LuaProfileWrapper;
- _luaScript.Globals["Events"] = LuaEventsWrapper;
- _luaScript.Globals["Brushes"] = LuaBrushWrapper;
- _luaScript.Globals["Keyboard"] = LuaKeyboardWrapper;
- _luaScript.Globals["Mouse"] = LuaMouseWrapper;
-
- if (ProfileModel == null)
- return;
- if (ProfileModel.LuaScript.IsNullOrEmpty())
- return;
-
- try
- {
- lock (LuaEventsWrapper.InvokeLock)
- {
- lock (_luaScript)
- {
- _luaScript.DoString(ProfileModel.LuaScript);
- }
- }
- }
- catch (InternalErrorException e)
- {
- _logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
- }
- catch (SyntaxErrorException e)
- {
- _logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
- }
- catch (ScriptRuntimeException e)
- {
- _logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
- }
- }
-
- public static void Clear()
- {
- lock (_luaScript)
- {
- // Clear old fields/properties
- KeyboardProvider = null;
- ProfileModel = null;
- LuaProfileWrapper = null;
- LuaBrushWrapper = null;
- LuaKeyboardWrapper?.Dispose();
- LuaKeyboardWrapper = null;
- LuaMouseWrapper = null;
-
- try
- {
- _luaScript.Globals.Clear();
- _luaScript.Registry.Clear();
- _luaScript.Registry.RegisterConstants();
- _luaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
- _luaScript.Globals.RegisterConstants();
- _luaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
- }
- catch (NullReferenceException)
- {
- // TODO: Ask MoonSharp folks why this is happening
- }
-
- if (LuaEventsWrapper != null)
- {
- lock (LuaEventsWrapper.InvokeLock)
- {
- lock (_luaScript)
- {
- _luaScript.DoString("");
- }
- }
- }
- else
- {
- lock (_luaScript)
- {
- _luaScript.DoString("");
- }
- }
-
-
- LuaEventsWrapper = null;
- }
- }
-
- #region Private lua functions
-
- private static void LuaPrint(string s)
- {
- _logger.Debug("[{0}-LUA]: {1}", ProfileModel?.Name, s);
- }
-
- #endregion
-
- #region Editor
-
- public static void OpenEditor()
- {
- if (ProfileModel == null)
- return;
-
- // Create a temp file
- var fileName = Guid.NewGuid() + ".lua";
- var file = File.Create(Path.GetTempPath() + fileName);
- file.Dispose();
-
- // Add instructions to LUA script if it's a new file
- if (ProfileModel.LuaScript.IsNullOrEmpty())
- ProfileModel.LuaScript = Encoding.UTF8.GetString(Resources.lua_placeholder);
- File.WriteAllText(Path.GetTempPath() + fileName, ProfileModel.LuaScript);
-
- // Watch the file for changes
- SetupWatcher(Path.GetTempPath(), fileName);
-
- // Open the temp file with the default editor
- System.Diagnostics.Process.Start(Path.GetTempPath() + fileName);
- }
-
- private static void SetupWatcher(string path, string fileName)
- {
- if (_watcher == null)
- {
- _watcher = new FileSystemWatcher(Path.GetTempPath(), fileName);
- _watcher.Changed += LuaFileChanged;
- _watcher.EnableRaisingEvents = true;
- }
-
- _watcher.Path = path;
- _watcher.Filter = fileName;
- }
-
- private static void LuaFileChanged(object sender, FileSystemEventArgs args)
- {
- if (args.ChangeType != WatcherChangeTypes.Changed)
- return;
-
- if (ProfileModel == null)
- return;
-
- lock (ProfileModel)
- {
- using (var fs = new FileStream(args.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
- {
- using (var sr = new StreamReader(fs))
- {
- ProfileModel.LuaScript = sr.ReadToEnd();
- }
- }
-
- ProfileProvider.AddOrUpdate(ProfileModel);
-
- if (KeyboardProvider != null)
- SetupLua(ProfileModel, KeyboardProvider);
- }
- }
-
- #endregion
- }
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Artemis.DAL;
+using Artemis.DeviceProviders;
+using Artemis.Profiles;
+using Artemis.Profiles.Lua;
+using Artemis.Profiles.Lua.Modules;
+using Artemis.Properties;
+using Castle.Core.Internal;
+using MoonSharp.Interpreter;
+using Ninject;
+using Ninject.Extensions.Logging;
+
+namespace Artemis.Managers
+{
+ public class LuaManager
+ {
+ private readonly DeviceManager _deviceManager;
+ private readonly IKernel _kernel;
+ private readonly ILogger _logger;
+ private List _luaModules;
+ private readonly Script _luaScript;
+ private FileSystemWatcher _watcher;
+
+ public LuaManager(IKernel kernel, ILogger logger, DeviceManager deviceManager)
+ {
+ _kernel = kernel;
+ _logger = logger;
+ _deviceManager = deviceManager;
+ _luaScript = new Script(CoreModules.Preset_SoftSandbox);
+ }
+
+ public ProfileModel ProfileModel { get; private set; }
+ public KeyboardProvider KeyboardProvider { get; private set; }
+ public LuaProfileModule ProfileModule { get; private set; }
+ public LuaEventsModule EventsModule { get; private set; }
+
+ public void SetupLua(ProfileModel profileModel)
+ {
+ // Clear old state
+ ClearLua();
+
+ // Stop after that if no model provided/there is no keyboard
+ if (profileModel == null || _deviceManager.ActiveKeyboard == null)
+ return;
+
+ ProfileModel = profileModel;
+ KeyboardProvider = _deviceManager.ActiveKeyboard;
+
+ // Get new instances of all modules
+ _luaModules = _kernel.Get>();
+ ProfileModule = (LuaProfileModule)_luaModules.First(m => m.ModuleName == "Profile");
+ EventsModule = (LuaEventsModule)_luaModules.First(m => m.ModuleName == "Events");
+
+ // Setup new state
+ _luaScript.Options.DebugPrint = LuaPrint;
+
+ // Insert each module into the script's globals
+ foreach (var luaModule in _luaModules)
+ {
+ _luaScript.Globals[luaModule.ModuleName] = luaModule;
+ }
+
+ // If there is no LUA script, don't bother executing the string
+ if (ProfileModel.LuaScript.IsNullOrEmpty())
+ return;
+
+ try
+ {
+ lock (EventsModule.InvokeLock)
+ {
+ lock (_luaScript)
+ {
+ _luaScript.DoString(ProfileModel.LuaScript);
+ }
+ }
+ }
+ catch (InternalErrorException e)
+ {
+ _logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
+ }
+ catch (SyntaxErrorException e)
+ {
+ _logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
+ }
+ catch (ScriptRuntimeException e)
+ {
+ _logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
+ }
+ }
+
+ public void ClearLua()
+ {
+ if (_luaModules != null)
+ {
+ foreach (var luaModule in _luaModules)
+ luaModule.Dispose();
+ _luaModules.Clear();
+ }
+
+ try
+ {
+ _luaScript.Globals.Clear();
+ _luaScript.Registry.Clear();
+ _luaScript.Registry.RegisterConstants();
+ _luaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
+ _luaScript.Globals.RegisterConstants();
+ _luaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
+ }
+ catch (NullReferenceException)
+ {
+ // TODO: Ask MoonSharp folks why this is happening
+ }
+
+ if (EventsModule != null)
+ {
+ lock (EventsModule.InvokeLock)
+ {
+ lock (_luaScript)
+ {
+ _luaScript.DoString("");
+ }
+ }
+ }
+ else
+ {
+ lock (_luaScript)
+ {
+ _luaScript.DoString("");
+ }
+ }
+ }
+
+ #region Private lua functions
+
+ private void LuaPrint(string s)
+ {
+ _logger.Info("[{0}-LUA]: {1}", ProfileModel?.Name, s);
+ }
+
+ #endregion
+
+ #region Editor
+
+ public void OpenEditor()
+ {
+ if (ProfileModel == null)
+ return;
+
+ // Create a temp file
+ var fileName = Guid.NewGuid() + ".lua";
+ var file = File.Create(Path.GetTempPath() + fileName);
+ file.Dispose();
+
+ // Add instructions to LUA script if it's a new file
+ if (ProfileModel.LuaScript.IsNullOrEmpty())
+ ProfileModel.LuaScript = Encoding.UTF8.GetString(Resources.lua_placeholder);
+ File.WriteAllText(Path.GetTempPath() + fileName, ProfileModel.LuaScript);
+
+ // Watch the file for changes
+ SetupWatcher(Path.GetTempPath(), fileName);
+
+ // Open the temp file with the default editor
+ System.Diagnostics.Process.Start(Path.GetTempPath() + fileName);
+ }
+
+ private void SetupWatcher(string path, string fileName)
+ {
+ if (_watcher == null)
+ {
+ _watcher = new FileSystemWatcher(Path.GetTempPath(), fileName);
+ _watcher.Changed += LuaFileChanged;
+ _watcher.EnableRaisingEvents = true;
+ }
+
+ _watcher.Path = path;
+ _watcher.Filter = fileName;
+ }
+
+ private void LuaFileChanged(object sender, FileSystemEventArgs args)
+ {
+ if (args.ChangeType != WatcherChangeTypes.Changed)
+ return;
+
+ if (ProfileModel == null)
+ return;
+
+ lock (ProfileModel)
+ {
+ using (var fs = new FileStream(args.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ {
+ using (var sr = new StreamReader(fs))
+ {
+ ProfileModel.LuaScript = sr.ReadToEnd();
+ }
+ }
+
+ ProfileProvider.AddOrUpdate(ProfileModel);
+ SetupLua(ProfileModel);
+ }
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/EffectModel.cs b/Artemis/Artemis/Models/EffectModel.cs
index eb1552d00..17a26a56c 100644
--- a/Artemis/Artemis/Models/EffectModel.cs
+++ b/Artemis/Artemis/Models/EffectModel.cs
@@ -23,9 +23,10 @@ namespace Artemis.Models
protected DateTime LastTrace;
- protected EffectModel(DeviceManager deviceManager, EffectSettings settings, IDataModel dataModel)
+ protected EffectModel(DeviceManager deviceManager, LuaManager luaManager, EffectSettings settings, IDataModel dataModel)
{
DeviceManager = deviceManager;
+ LuaManager = luaManager;
Settings = settings;
DataModel = dataModel;
@@ -38,6 +39,7 @@ namespace Artemis.Models
public bool Initialized { get; set; }
public DeviceManager DeviceManager { get; set; }
+ public LuaManager LuaManager { get; }
public EffectSettings Settings { get; set; }
public string Name { get; set; }
public int KeyboardScale { get; set; } = 4;
@@ -50,7 +52,7 @@ namespace Artemis.Models
public virtual void Dispose()
{
- Profile?.Deactivate();
+ Profile?.Deactivate(LuaManager);
}
private void DeviceManagerOnOnKeyboardChangedEvent(object sender, KeyboardChangedEventArgs args)
@@ -85,7 +87,7 @@ namespace Artemis.Models
// If the profile has no active LUA wrapper, create one
if (!string.IsNullOrEmpty(Profile.LuaScript))
- Profile.Activate(DeviceManager.ActiveKeyboard);
+ Profile.Activate(LuaManager);
// Render the keyboard layer-by-layer
var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
diff --git a/Artemis/Artemis/Models/GameModel.cs b/Artemis/Artemis/Models/GameModel.cs
index 3d9d02204..402669db8 100644
--- a/Artemis/Artemis/Models/GameModel.cs
+++ b/Artemis/Artemis/Models/GameModel.cs
@@ -6,7 +6,8 @@ namespace Artemis.Models
{
public abstract class GameModel : EffectModel
{
- protected GameModel(DeviceManager deviceManager, GameSettings settings, IDataModel dataModel): base(deviceManager, settings, dataModel)
+ protected GameModel(DeviceManager deviceManager, LuaManager luaManager, GameSettings settings,
+ IDataModel dataModel) : base(deviceManager, luaManager, settings, dataModel)
{
// Override settings to the GameSettings type
Settings = settings;
diff --git a/Artemis/Artemis/Models/OverlayModel.cs b/Artemis/Artemis/Models/OverlayModel.cs
index 3e7d4aba8..9935ab89b 100644
--- a/Artemis/Artemis/Models/OverlayModel.cs
+++ b/Artemis/Artemis/Models/OverlayModel.cs
@@ -8,7 +8,8 @@ namespace Artemis.Models
private bool _enabled;
public string ProcessName;
- protected OverlayModel(DeviceManager deviceManager, OverlaySettings settings) : base(deviceManager, settings, null)
+ protected OverlayModel(DeviceManager deviceManager, LuaManager luaManager, OverlaySettings settings)
+ : base(deviceManager, luaManager, settings, null)
{
Settings = settings;
Enabled = settings.Enabled;
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs
index fbbfcb1d2..3eb0f1e43 100644
--- a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs
@@ -15,7 +15,8 @@ namespace Artemis.Modules.Effects.Bubbles
{
#region Constructors
- public BubblesModel(DeviceManager deviceManager) : base(deviceManager, SettingsProvider.Load(), null)
+ public BubblesModel(DeviceManager deviceManager, LuaManager luaManager)
+ : base(deviceManager, luaManager, SettingsProvider.Load(), null)
{
Name = "Bubbles";
Initialized = false;
@@ -41,7 +42,7 @@ namespace Artemis.Modules.Effects.Bubbles
KeyboardScale = Settings.Smoothness;
var rect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
- var scaleFactor = Settings.Smoothness/25.0;
+ var scaleFactor = Settings.Smoothness / 25.0;
for (var i = 0; i < Settings.BubbleCount; i++)
{
@@ -49,16 +50,18 @@ namespace Artemis.Modules.Effects.Bubbles
? ColorHelpers.GetRandomRainbowColor()
: ColorHelpers.ToDrawingColor(Settings.BubbleColor);
// -Settings.MoveSpeed because we want to spawn at least one move away from borders
- var initialPositionX = (rect.Width - Settings.BubbleSize*scaleFactor*2 - Settings.MoveSpeed*scaleFactor)*
- _random.NextDouble() + Settings.BubbleSize*scaleFactor;
- var initialPositionY = (rect.Height - Settings.BubbleSize*scaleFactor*2 - Settings.MoveSpeed*scaleFactor)*
- _random.NextDouble() + Settings.BubbleSize*scaleFactor;
- var initialDirectionX = Settings.MoveSpeed*scaleFactor*_random.NextDouble()*
+ var initialPositionX = (rect.Width - Settings.BubbleSize * scaleFactor * 2 -
+ Settings.MoveSpeed * scaleFactor) *
+ _random.NextDouble() + Settings.BubbleSize * scaleFactor;
+ var initialPositionY = (rect.Height - Settings.BubbleSize * scaleFactor * 2 -
+ Settings.MoveSpeed * scaleFactor) *
+ _random.NextDouble() + Settings.BubbleSize * scaleFactor;
+ var initialDirectionX = Settings.MoveSpeed * scaleFactor * _random.NextDouble() *
(_random.Next(1) == 0 ? -1 : 1);
- var initialDirectionY = (Settings.MoveSpeed*scaleFactor - Math.Abs(initialDirectionX))*
+ var initialDirectionY = (Settings.MoveSpeed * scaleFactor - Math.Abs(initialDirectionX)) *
(_random.Next(1) == 0 ? -1 : 1);
- _bubbles.Add(new Bubble(color, (int) Math.Round(Settings.BubbleSize*scaleFactor),
+ _bubbles.Add(new Bubble(color, (int) Math.Round(Settings.BubbleSize * scaleFactor),
new Point(initialPositionX, initialPositionY), new Vector(initialDirectionX, initialDirectionY)));
}
@@ -79,7 +82,7 @@ namespace Artemis.Modules.Effects.Bubbles
if (Settings.IsShiftColors)
bubble.Color = ColorHelpers.ShiftColor(bubble.Color,
Settings.IsRandomColors
- ? (int) Math.Round(Settings.ShiftColorSpeed*_random.NextDouble())
+ ? (int) Math.Round(Settings.ShiftColorSpeed * _random.NextDouble())
: Settings.ShiftColorSpeed);
bubble.CheckCollision(keyboardRectangle);
diff --git a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
index 0b258f5fe..d30118099 100644
--- a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
+++ b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
@@ -16,8 +16,7 @@ namespace Artemis.Modules.Effects.ProfilePreview
{
public class ProfilePreviewModel : EffectModel
{
- public ProfilePreviewModel(DeviceManager deviceManager)
- : base(deviceManager, null, new ProfilePreviewDataModel())
+ public ProfilePreviewModel(DeviceManager deviceManager, LuaManager luaManager): base(deviceManager, luaManager, null, new ProfilePreviewDataModel())
{
Name = "Profile Preview";
}
@@ -55,8 +54,8 @@ namespace Artemis.Modules.Effects.ProfilePreview
var renderLayers = GetRenderLayers(keyboardOnly);
// If the profile has no active LUA wrapper, create one
- if (!Equals(LuaWrapper.ProfileModel, Profile))
- Profile.Activate(DeviceManager.ActiveKeyboard);
+ if (!Equals(LuaManager.ProfileModel, Profile))
+ Profile.Activate(LuaManager);
// Render the keyboard layer-by-layer
var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
diff --git a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
index 7a5607c43..22ab35e8d 100644
--- a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
+++ b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
@@ -24,8 +24,9 @@ namespace Artemis.Modules.Effects.WindowsProfile
private SpotifyLocalAPI _spotify;
private bool _spotifySetupBusy;
- public WindowsProfileModel(DeviceManager deviceManager)
- : base(deviceManager, SettingsProvider.Load(), new WindowsProfileDataModel())
+ public WindowsProfileModel(DeviceManager deviceManager, LuaManager luaManager)
+ : base(deviceManager, luaManager, SettingsProvider.Load(),
+ new WindowsProfileDataModel())
{
_lastMusicUpdate = DateTime.Now;
@@ -125,7 +126,7 @@ namespace Artemis.Modules.Effects.WindowsProfile
var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
var tot = PerformanceInfo.GetTotalMemoryInMiB();
- var percentFree = phav/(decimal) tot*100;
+ var percentFree = phav / (decimal) tot * 100;
var percentOccupied = 100 - percentFree;
dataModel.Performance.RAMUsage = (int) percentOccupied;
@@ -222,7 +223,7 @@ namespace Artemis.Modules.Effects.WindowsProfile
if (dataModel.Spotify.SongLength > 0)
dataModel.Spotify.SongPercentCompleted =
- (int) (status.PlayingPosition/dataModel.Spotify.SongLength*100.0);
+ (int) (status.PlayingPosition / dataModel.Spotify.SongLength * 100.0);
}
private void UpdateGooglePlayMusic(WindowsProfileDataModel dataModel)
@@ -241,14 +242,14 @@ namespace Artemis.Modules.Effects.WindowsProfile
#region System
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true,
- CallingConvention = CallingConvention.Winapi)]
+ CallingConvention = CallingConvention.Winapi)]
public static extern short GetKeyState(int keyCode);
private void UpdateKeyStates(WindowsProfileDataModel dataModel)
{
- dataModel.Keyboard.NumLock = ((ushort)GetKeyState(0x90) & 0xffff) != 0;
- dataModel.Keyboard.CapsLock = ((ushort)GetKeyState(0x14) & 0xffff) != 0;
- dataModel.Keyboard.ScrollLock = ((ushort)GetKeyState(0x91) & 0xffff) != 0;
+ dataModel.Keyboard.NumLock = ((ushort) GetKeyState(0x90) & 0xffff) != 0;
+ dataModel.Keyboard.CapsLock = ((ushort) GetKeyState(0x14) & 0xffff) != 0;
+ dataModel.Keyboard.ScrollLock = ((ushort) GetKeyState(0x91) & 0xffff) != 0;
}
private void UpdateActiveWindow(WindowsProfileDataModel dataModel)
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
index 452f2d51e..321614b5b 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
@@ -22,9 +22,10 @@ namespace Artemis.Modules.Games.CounterStrike
private DateTime _lastKill;
private int _lastKills;
- public CounterStrikeModel(DeviceManager deviceManager, GameStateWebServer gameStateWebServer,
- MetroDialogService dialogService)
- : base(deviceManager, SettingsProvider.Load(), new CounterStrikeDataModel())
+ public CounterStrikeModel(DeviceManager deviceManager, LuaManager luaManager,
+ GameStateWebServer gameStateWebServer, MetroDialogService dialogService)
+ : base(deviceManager, luaManager, SettingsProvider.Load(),
+ new CounterStrikeDataModel())
{
_gameStateWebServer = gameStateWebServer;
_dialogService = dialogService;
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
index 8029a5da3..2f1a61c23 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
@@ -17,9 +17,9 @@ namespace Artemis.Modules.Games.Dota2
private readonly MetroDialogService _dialogService;
private readonly GameStateWebServer _gameStateWebServer;
- public Dota2Model(DeviceManager deviceManager, GameStateWebServer gameStateWebServer,
+ public Dota2Model(DeviceManager deviceManager, LuaManager luaManager, GameStateWebServer gameStateWebServer,
MetroDialogService dialogService)
- : base(deviceManager, SettingsProvider.Load(), new Dota2DataModel())
+ : base(deviceManager, luaManager, SettingsProvider.Load(), new Dota2DataModel())
{
_gameStateWebServer = gameStateWebServer;
_dialogService = dialogService;
@@ -109,8 +109,8 @@ namespace Artemis.Modules.Games.Dota2
if (dataModel?.map?.daytime == null)
return;
- var timeLeft = 240 - dataModel.map.clock_time%240;
- dataModel.map.dayCyclePercentage = (int) (100.00/240*timeLeft);
+ var timeLeft = 240 - dataModel.map.clock_time % 240;
+ dataModel.map.dayCyclePercentage = (int) (100.00 / 240 * timeLeft);
}
public void HandleGameData(object sender, GameDataReceivedEventArgs e)
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2Settings.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2Settings.cs
index 771460b2a..af00d84e0 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2Settings.cs
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2Settings.cs
@@ -2,7 +2,7 @@
namespace Artemis.Modules.Games.Dota2
{
- internal class Dota2Settings : GameSettings
+ public class Dota2Settings : GameSettings
{
public string GameDirectory { get; set; }
}
diff --git a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Ets2TelemetryData.cs b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Ets2TelemetryData.cs
index a98f267cd..307f1b246 100644
--- a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Ets2TelemetryData.cs
+++ b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Ets2TelemetryData.cs
@@ -4,7 +4,7 @@ using Artemis.Modules.Games.EurotruckSimulator2.Data.Reader;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data
{
- internal class Ets2TelemetryData : IEts2TelemetryData
+ public class Ets2TelemetryData : IEts2TelemetryData
{
private Box _rawData;
@@ -38,7 +38,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
}
}
- internal class Ets2Game : IEts2Game
+ public class Ets2Game : IEts2Game
{
private readonly Box _rawData;
@@ -55,7 +55,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
public string TelemetryPluginVersion => _rawData.Struct.ets2_telemetry_plugin_revision.ToString();
}
- internal class Ets2Vector : IEts2Vector
+ public class Ets2Vector : IEts2Vector
{
public Ets2Vector(float x, float y, float z)
{
@@ -69,7 +69,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
public float Z { get; }
}
- internal class Ets2Placement : IEts2Placement
+ public class Ets2Placement : IEts2Placement
{
public Ets2Placement(float x, float y, float z,
float heading, float pitch, float roll)
@@ -90,7 +90,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
public float Roll { get; }
}
- internal class Ets2Truck : IEts2Truck
+ public class Ets2Truck : IEts2Truck
{
private readonly Box _rawData;
@@ -242,7 +242,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
*/
}
- internal class Ets2Trailer : IEts2Trailer
+ public class Ets2Trailer : IEts2Trailer
{
private readonly Box _rawData;
@@ -271,7 +271,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
_rawData.Struct.trailerRotationZ);
}
- internal class Ets2Navigation : IEts2Navigation
+ public class Ets2Navigation : IEts2Navigation
{
private readonly Box _rawData;
@@ -288,7 +288,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
_rawData.Struct.navigationSpeedLimit > 0 ? (int) Math.Round(_rawData.Struct.navigationSpeedLimit*3.6f) : 0;
}
- internal class Ets2Job : IEts2Job
+ public class Ets2Job : IEts2Job
{
private readonly Box _rawData;
@@ -355,7 +355,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
}
*/
- internal class Box where T : struct
+ public class Box where T : struct
{
public Box(T @struct)
{
diff --git a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Reader/Ets2TelemetryStructure.cs b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Reader/Ets2TelemetryStructure.cs
index 89f1edaff..c80678afa 100644
--- a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Reader/Ets2TelemetryStructure.cs
+++ b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Reader/Ets2TelemetryStructure.cs
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data.Reader
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
- internal struct Ets2TelemetryStructure
+ public struct Ets2TelemetryStructure
{
private const int GeneralStringSize = 64;
diff --git a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Reader/SharedProcessMemory.cs b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Reader/SharedProcessMemory.cs
index 6de2569a4..1bd0ab7b2 100644
--- a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Reader/SharedProcessMemory.cs
+++ b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/Data/Reader/SharedProcessMemory.cs
@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data.Reader
{
- internal class SharedProcessMemory : IDisposable
+ public class SharedProcessMemory : IDisposable
{
private readonly string _mapName;
private MemoryMappedViewAccessor _memoryMappedAccessor;
diff --git a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2Model.cs b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2Model.cs
index 2df7313e9..5ff1873f6 100644
--- a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2Model.cs
+++ b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2Model.cs
@@ -18,9 +18,10 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
{
private readonly MetroDialogService _dialogService;
- public EurotruckSimulator2Model(DeviceManager deviceManager, MetroDialogService dialogService)
- : base(
- deviceManager, SettingsProvider.Load(), new EurotruckSimulator2DataModel())
+ public EurotruckSimulator2Model(DeviceManager deviceManager, LuaManager luaManager,
+ MetroDialogService dialogService)
+ : base(deviceManager, luaManager, SettingsProvider.Load(),
+ new EurotruckSimulator2DataModel())
{
_dialogService = dialogService;
Name = "EurotruckSimulator2";
diff --git a/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs b/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs
index 20c185ee9..b8e031572 100644
--- a/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs
+++ b/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs
@@ -15,8 +15,8 @@ namespace Artemis.Modules.Games.GtaV
{
private readonly PipeServer _pipeServer;
- public GtaVModel(DeviceManager deviceManager, PipeServer pipeServer)
- : base(deviceManager, SettingsProvider.Load(), new GtaVDataModel())
+ public GtaVModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
+ : base(deviceManager, luaManager, SettingsProvider.Load(), new GtaVDataModel())
{
_pipeServer = pipeServer;
Name = "GTAV";
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
index 143c5eb34..d0271d8f7 100644
--- a/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
@@ -6,15 +6,14 @@ using Artemis.Managers;
using Artemis.Models;
using Artemis.Profiles.Layers.Models;
using Artemis.Utilities.DataReaders;
-using Artemis.Utilities.GameState;
using Newtonsoft.Json;
namespace Artemis.Modules.Games.LightFx
{
public class LightFxModel : GameModel
{
- public LightFxModel(DeviceManager deviceManager, PipeServer pipeServer)
- : base(deviceManager, SettingsProvider.Load(), new LightFxDataModel())
+ public LightFxModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
+ : base(deviceManager, luaManager, SettingsProvider.Load(), new LightFxDataModel())
{
Name = "LightFX";
ProcessName = "LoL";
@@ -26,6 +25,8 @@ namespace Artemis.Modules.Games.LightFx
pipeServer.PipeMessage += PipeServerOnPipeMessage;
}
+ public int Scale { get; set; }
+
private void PipeServerOnPipeMessage(string msg)
{
// Ensure it's Light FX JSON
@@ -44,11 +45,9 @@ namespace Artemis.Modules.Games.LightFx
}
// Setup process name
- ProcessName = Path.GetFileNameWithoutExtension(((LightFxDataModel)DataModel).LightFxState.game);
+ ProcessName = Path.GetFileNameWithoutExtension(((LightFxDataModel) DataModel).LightFxState.game);
}
- public int Scale { get; set; }
-
public override void Dispose()
{
Initialized = false;
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
index 7f53834eb..20a87d9b5 100644
--- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
@@ -29,9 +29,9 @@ namespace Artemis.Modules.Games.Overwatch
private DateTime _ultimateReady;
private DateTime _ultimateUsed;
- public OverwatchModel(DeviceManager deviceManager, PipeServer pipeServer, MetroDialogService dialogService,
- DebugViewModel debugViewModel)
- : base(deviceManager, SettingsProvider.Load(), new OverwatchDataModel())
+ public OverwatchModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer,
+ MetroDialogService dialogService, DebugViewModel debugViewModel)
+ : base(deviceManager, luaManager, SettingsProvider.Load(), new OverwatchDataModel())
{
_pipeServer = pipeServer;
_dialogService = dialogService;
@@ -240,7 +240,8 @@ namespace Artemis.Modules.Games.Overwatch
// Ultimate is ready when Q is blinking
var charCol = characterMatch.Value.Color;
- var backlidColor = Color.FromRgb((byte) (charCol.R*0.25), (byte) (charCol.G*0.25), (byte) (charCol.B*0.25));
+ var backlidColor = Color.FromRgb((byte) (charCol.R * 0.25), (byte) (charCol.G * 0.25),
+ (byte) (charCol.B * 0.25));
var ultReady = !backlidColor.Equals(colors[2, 2]);
if (_ultimateUsed.AddSeconds(15) <= DateTime.Now)
@@ -291,7 +292,7 @@ namespace Artemis.Modules.Games.Overwatch
return;
var key = Registry.LocalMachine.OpenSubKey(
- @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Overwatch");
+ @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Overwatch");
var path = key?.GetValue("DisplayIcon")?.ToString();
if (string.IsNullOrEmpty(path) || !File.Exists(path))
diff --git a/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsModel.cs b/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsModel.cs
index aa82cf26f..145bb6591 100644
--- a/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsModel.cs
+++ b/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsModel.cs
@@ -1,16 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
+using System.Collections.Generic;
using Artemis.DAL;
using Artemis.Managers;
using Artemis.Models;
using Artemis.Modules.Games.ProjectCars.Data;
using Artemis.Profiles.Layers.Models;
-using Artemis.Properties;
using Artemis.Services;
-using Artemis.Settings;
-using Artemis.Utilities;
-using Ninject.Extensions.Logging;
namespace Artemis.Modules.Games.ProjectCars
{
@@ -18,8 +12,8 @@ namespace Artemis.Modules.Games.ProjectCars
{
private readonly MetroDialogService _dialogService;
- public ProjectCarsModel(DeviceManager deviceManager, MetroDialogService dialogService)
- : base(deviceManager, SettingsProvider.Load(), new ProjectCarsDataModel())
+ public ProjectCarsModel(DeviceManager deviceManager, LuaManager luaManager, MetroDialogService dialogService)
+ : base(deviceManager, luaManager, SettingsProvider.Load(), new ProjectCarsDataModel())
{
_dialogService = dialogService;
Name = "ProjectCars";
@@ -49,10 +43,7 @@ namespace Artemis.Modules.Games.ProjectCars
// item1 is the true/false indicating a good read or not
if (returnTuple.Item1)
- {
- // map the data that's read from the struct and map it to the class
dataModel.GameData = dataModel.GameData.MapStructToClass(returnTuple.Item2, dataModel.GameData);
- }
}
public override List GetRenderLayers(bool keyboardOnly)
diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
index c926298bd..8e8673508 100644
--- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
+++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
@@ -17,8 +17,7 @@ namespace Artemis.Modules.Games.RocketLeague
private Memory _memory;
private GamePointersCollection _pointer;
- public RocketLeagueModel(DeviceManager deviceManager)
- : base(deviceManager, SettingsProvider.Load(), new RocketLeagueDataModel())
+ public RocketLeagueModel(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager, SettingsProvider.Load(), new RocketLeagueDataModel())
{
Name = "RocketLeague";
ProcessName = "RocketLeague";
diff --git a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
index 59c039431..5365aacd4 100644
--- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
+++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
@@ -16,8 +16,8 @@ namespace Artemis.Modules.Games.TheDivision
private StickyValue _stickyAmmo;
private StickyValue _stickyHp;
- public TheDivisionModel(DeviceManager deviceManager, PipeServer pipeServer)
- : base(deviceManager, SettingsProvider.Load(), new TheDivisionDataModel())
+ public TheDivisionModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
+ : base(deviceManager, luaManager, SettingsProvider.Load(), new TheDivisionDataModel())
{
_pipeServer = pipeServer;
Name = "TheDivision";
diff --git a/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentModel.cs b/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentModel.cs
index bb4e0234b..ee48801a8 100644
--- a/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentModel.cs
+++ b/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentModel.cs
@@ -25,8 +25,10 @@ namespace Artemis.Modules.Games.UnrealTournament
private Timer _killTimer;
private int _lastScore;
- public UnrealTournamentModel(DeviceManager deviceManager, PipeServer pipeServer, MetroDialogService dialogService)
- : base(deviceManager, SettingsProvider.Load(), new UnrealTournamentDataModel())
+ public UnrealTournamentModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer,
+ MetroDialogService dialogService)
+ : base(deviceManager, luaManager, SettingsProvider.Load(),
+ new UnrealTournamentDataModel())
{
_pipeServer = pipeServer;
_dialogService = dialogService;
@@ -44,7 +46,7 @@ namespace Artemis.Modules.Games.UnrealTournament
public void FindGame()
{
- var gameSettings = (UnrealTournamentSettings)Settings;
+ var gameSettings = (UnrealTournamentSettings) Settings;
// If already propertly set up, don't do anything
if ((gameSettings.GameDirectory != null) &&
File.Exists(gameSettings.GameDirectory + "UE4-Win64-Shipping.exe"))
@@ -77,13 +79,13 @@ namespace Artemis.Modules.Games.UnrealTournament
public void PlaceFiles()
{
- var gameSettings = (UnrealTournamentSettings)Settings;
+ var gameSettings = (UnrealTournamentSettings) Settings;
var path = gameSettings.GameDirectory;
if (!File.Exists(path + @"\UE4-Win64-Shipping.exe"))
{
_dialogService.ShowErrorMessageBox("Please select a valid Unreal Tournament directory\n\n" +
- @"By default Unreal Tournament is in C:\Program Files\Epic Games\UnrealTournament");
+ @"By default Unreal Tournament is in C:\Program Files\Epic Games\UnrealTournament");
gameSettings.GameDirectory = string.Empty;
gameSettings.Save();
diff --git a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs
index 65b1a4a51..76070e6eb 100644
--- a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs
+++ b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs
@@ -17,8 +17,8 @@ namespace Artemis.Modules.Games.Witcher3
private readonly Stopwatch _updateSw;
private string _witcherSettings;
- public Witcher3Model(DeviceManager deviceManager)
- : base(deviceManager, SettingsProvider.Load(), new Witcher3DataModel())
+ public Witcher3Model(DeviceManager deviceManager, LuaManager luaManager)
+ : base(deviceManager, luaManager, SettingsProvider.Load(), new Witcher3DataModel())
{
Name = "Witcher3";
ProcessName = "witcher3";
diff --git a/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs b/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs
index 3386027dd..666aa5ca1 100644
--- a/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs
+++ b/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs
@@ -18,8 +18,8 @@ namespace Artemis.Modules.Games.WoW
private readonly GamePointersCollection _pointer;
private ProcessSharp _process;
- public WoWModel(DeviceManager deviceManager)
- : base(deviceManager, SettingsProvider.Load(), new WoWDataModel())
+ public WoWModel(DeviceManager deviceManager, LuaManager luaManager)
+ : base(deviceManager, luaManager, SettingsProvider.Load(), new WoWDataModel())
{
Name = "WoW";
ProcessName = "Wow-64";
diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
index c6c511b4e..e43097b6c 100644
--- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
+++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
@@ -13,7 +13,8 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
{
public class VolumeDisplayModel : OverlayModel
{
- public VolumeDisplayModel(DeviceManager deviceManager): base(deviceManager, SettingsProvider.Load())
+ public VolumeDisplayModel(DeviceManager deviceManager, LuaManager luaManager)
+ : base(deviceManager, luaManager, SettingsProvider.Load())
{
Name = "VolumeDisplay";
Settings = (VolumeDisplaySettings) base.Settings;
@@ -44,7 +45,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
if (VolumeDisplay.Ttl < 1)
return;
- var decreaseAmount = 500/fps;
+ var decreaseAmount = 500 / fps;
VolumeDisplay.Ttl = VolumeDisplay.Ttl - decreaseAmount;
if (VolumeDisplay.Ttl < 128)
VolumeDisplay.Transparancy = (byte) (VolumeDisplay.Transparancy - 20);
@@ -55,7 +56,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
var volumeFloat =
enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console)
.AudioEndpointVolume.MasterVolumeLevelScalar;
- VolumeDisplay.Volume = (int) (volumeFloat*100);
+ VolumeDisplay.Volume = (int) (volumeFloat * 100);
}
catch (COMException)
{
diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
index 5870cdb19..826d78250 100644
--- a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
@@ -52,6 +52,9 @@ namespace Artemis.Profiles.Layers.Models
///
public void Update(IDataModel dataModel, bool preview, bool updateAnimations)
{
+ if (LayerType == null)
+ return;
+
LayerType.Update(this, dataModel, preview);
LayerAnimation?.Update(this, updateAnimations);
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs
index 02e0ec205..8aa99cefd 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs
@@ -16,7 +16,7 @@ using Ninject;
namespace Artemis.Profiles.Layers.Types.Audio
{
- internal class AudioType : ILayerType
+ public class AudioType : ILayerType
{
private readonly List _audioLayers = new List();
private readonly IKernel _kernel;
diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs
index f8a31e27a..6c3628cd6 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs
@@ -17,7 +17,7 @@ using Artemis.ViewModels.Profiles;
namespace Artemis.Profiles.Layers.Types.KeyPress
{
- internal class KeyPressType : ILayerType
+ public class KeyPressType : ILayerType
{
private readonly DeviceManager _deviceManager;
private List _keyPressLayers;
diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs
index d2edb9451..4245d5350 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs
@@ -13,7 +13,7 @@ using Artemis.ViewModels.Profiles;
namespace Artemis.Profiles.Layers.Types.KeyboardGif
{
- internal class KeyboardGifType : ILayerType
+ public class KeyboardGifType : ILayerType
{
public string Name => "Keyboard - GIF";
public bool ShowInEdtor => true;
diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaModule.cs b/Artemis/Artemis/Profiles/Lua/LuaModule.cs
similarity index 52%
rename from Artemis/Artemis/Profiles/Lua/Modules/LuaModule.cs
rename to Artemis/Artemis/Profiles/Lua/LuaModule.cs
index 68841aa77..f7859a4ca 100644
--- a/Artemis/Artemis/Profiles/Lua/Modules/LuaModule.cs
+++ b/Artemis/Artemis/Profiles/Lua/LuaModule.cs
@@ -1,30 +1,36 @@
using System;
-using MoonSharp.Interpreter;
+using Artemis.Managers;
using MoonSharp.Interpreter.Interop;
-namespace Artemis.Profiles.Lua.Modules
+namespace Artemis.Profiles.Lua
{
///
/// Defines a module which will be accessable in all LUA scripts.
///
- [MoonSharpUserData]
public abstract class LuaModule : IDisposable
{
- public LuaModule(LuaWrapper luaWrapper)
+ public LuaModule(LuaManager luaManager)
{
- LuaWrapper = luaWrapper;
+ LuaManager = luaManager;
}
///
/// The name under which this module will be accessable in LUA
///
- [MoonSharpVisible(false)]
public abstract string ModuleName { get; }
+ ///
+ /// The LUA manager containing this module
+ ///
[MoonSharpVisible(false)]
- public LuaWrapper LuaWrapper { get; set; }
+ public LuaManager LuaManager { get; set; }
+ ///
+ /// Called when the LUA script is restarted
+ ///
[MoonSharpVisible(false)]
- public abstract void Dispose();
+ public virtual void Dispose()
+ {
+ }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaBrush.cs b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaBrush.cs
similarity index 90%
rename from Artemis/Artemis/Profiles/Lua/Brushes/LuaBrush.cs
rename to Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaBrush.cs
index 497f9616b..179fc2130 100644
--- a/Artemis/Artemis/Profiles/Lua/Brushes/LuaBrush.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaBrush.cs
@@ -2,7 +2,7 @@
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
-namespace Artemis.Profiles.Lua.Brushes
+namespace Artemis.Profiles.Lua.Modules.Brushes
{
[MoonSharpUserData]
public abstract class LuaBrush
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaColor.cs b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaColor.cs
similarity index 96%
rename from Artemis/Artemis/Profiles/Lua/Brushes/LuaColor.cs
rename to Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaColor.cs
index 25e9a67cd..f4ff1ea6d 100644
--- a/Artemis/Artemis/Profiles/Lua/Brushes/LuaColor.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaColor.cs
@@ -3,7 +3,7 @@ using Artemis.Utilities;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
-namespace Artemis.Profiles.Lua.Brushes
+namespace Artemis.Profiles.Lua.Modules.Brushes
{
[MoonSharpUserData]
public class LuaColor
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaLinearGradientBrush.cs b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaLinearGradientBrush.cs
similarity index 97%
rename from Artemis/Artemis/Profiles/Lua/Brushes/LuaLinearGradientBrush.cs
rename to Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaLinearGradientBrush.cs
index 2f62d030a..3336119e4 100644
--- a/Artemis/Artemis/Profiles/Lua/Brushes/LuaLinearGradientBrush.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaLinearGradientBrush.cs
@@ -5,7 +5,7 @@ using System.Windows;
using System.Windows.Media;
using MoonSharp.Interpreter;
-namespace Artemis.Profiles.Lua.Brushes
+namespace Artemis.Profiles.Lua.Modules.Brushes
{
[MoonSharpUserData]
public class LuaLinearGradientBrush : LuaBrush
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaRadialGradientBrush.cs b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaRadialGradientBrush.cs
similarity index 98%
rename from Artemis/Artemis/Profiles/Lua/Brushes/LuaRadialGradientBrush.cs
rename to Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaRadialGradientBrush.cs
index d1300784a..422064001 100644
--- a/Artemis/Artemis/Profiles/Lua/Brushes/LuaRadialGradientBrush.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaRadialGradientBrush.cs
@@ -5,7 +5,7 @@ using System.Windows;
using System.Windows.Media;
using MoonSharp.Interpreter;
-namespace Artemis.Profiles.Lua.Brushes
+namespace Artemis.Profiles.Lua.Modules.Brushes
{
[MoonSharpUserData]
public class LuaRadialGradientBrush : LuaBrush
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaSolidColorBrush.cs b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaSolidColorBrush.cs
similarity index 93%
rename from Artemis/Artemis/Profiles/Lua/Brushes/LuaSolidColorBrush.cs
rename to Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaSolidColorBrush.cs
index ed4163cf1..cdf11a038 100644
--- a/Artemis/Artemis/Profiles/Lua/Brushes/LuaSolidColorBrush.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/Brushes/LuaSolidColorBrush.cs
@@ -2,7 +2,7 @@
using System.Windows.Media;
using MoonSharp.Interpreter;
-namespace Artemis.Profiles.Lua.Brushes
+namespace Artemis.Profiles.Lua.Modules.Brushes
{
[MoonSharpUserData]
public class LuaSolidColorBrush : LuaBrush
diff --git a/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceDrawingEventArgs.cs b/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceDrawingEventArgs.cs
index 7f12c88b5..3c5681a4d 100644
--- a/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceDrawingEventArgs.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceDrawingEventArgs.cs
@@ -8,7 +8,8 @@ namespace Artemis.Profiles.Lua.Modules.Events
[MoonSharpUserData]
public class LuaDeviceDrawingEventArgs : EventArgs
{
- public LuaDeviceDrawingEventArgs(string deviceType, IDataModel dataModel, bool preview, LuaDrawWrapper luaDrawWrapper)
+ public LuaDeviceDrawingEventArgs(string deviceType, IDataModel dataModel, bool preview,
+ LuaDrawWrapper luaDrawWrapper)
{
DeviceType = deviceType;
DataModel = dataModel;
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaBrushWrapper.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaBrushesModule.cs
similarity index 78%
rename from Artemis/Artemis/Profiles/Lua/Brushes/LuaBrushWrapper.cs
rename to Artemis/Artemis/Profiles/Lua/Modules/LuaBrushesModule.cs
index 0d183e290..8a944dd59 100644
--- a/Artemis/Artemis/Profiles/Lua/Brushes/LuaBrushWrapper.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaBrushesModule.cs
@@ -1,43 +1,51 @@
-using System.Collections.Generic;
-using Artemis.Utilities;
-using MoonSharp.Interpreter;
-
-namespace Artemis.Profiles.Lua.Brushes
-{
- [MoonSharpUserData]
- public class LuaBrushWrapper
- {
- public LuaColor GetColor(string hexCode)
- {
- return new LuaColor(hexCode);
- }
-
- public LuaColor GetColor(byte a, byte r, byte g, byte b)
- {
- return new LuaColor(a, r, g, b);
- }
-
- public LuaColor GetRandomColor()
- {
- return new LuaColor(ColorHelpers.GetRandomRainbowMediaColor());
- }
-
- public LuaSolidColorBrush GetSolidColorBrush(LuaColor color)
- {
- return new LuaSolidColorBrush(color);
- }
-
- public LuaLinearGradientBrush GetLinearGradientBrush(Dictionary gradientColors,
- double startX = 0.5, double startY = 0.0, double endX = 0.5, double endY = 1.0)
- {
- return new LuaLinearGradientBrush(gradientColors, startX, startY, endX, endY);
- }
-
- // TODO: Check default values
- public LuaRadialGradientBrush GetRadialGradientBrush(Dictionary gradientColors,
- double centerX = 0.5, double centerY = 0.5, double originX = 0.5, double originY = 0.5)
- {
- return new LuaRadialGradientBrush(gradientColors, centerX, centerY, originX, originY);
- }
- }
+using System.Collections.Generic;
+using Artemis.Managers;
+using Artemis.Profiles.Lua.Modules.Brushes;
+using Artemis.Utilities;
+using MoonSharp.Interpreter;
+
+namespace Artemis.Profiles.Lua.Modules
+{
+ [MoonSharpUserData]
+ public class LuaBrushesModule : LuaModule
+ {
+ public LuaBrushesModule(LuaManager luaManager) : base(luaManager)
+ {
+ }
+
+ public override string ModuleName => "Brushes";
+
+ public LuaColor GetColor(string hexCode)
+ {
+ return new LuaColor(hexCode);
+ }
+
+ public LuaColor GetColor(byte a, byte r, byte g, byte b)
+ {
+ return new LuaColor(a, r, g, b);
+ }
+
+ public LuaColor GetRandomColor()
+ {
+ return new LuaColor(ColorHelpers.GetRandomRainbowMediaColor());
+ }
+
+ public LuaSolidColorBrush GetSolidColorBrush(LuaColor color)
+ {
+ return new LuaSolidColorBrush(color);
+ }
+
+ public LuaLinearGradientBrush GetLinearGradientBrush(Dictionary gradientColors,
+ double startX = 0.5, double startY = 0.0, double endX = 0.5, double endY = 1.0)
+ {
+ return new LuaLinearGradientBrush(gradientColors, startX, startY, endX, endY);
+ }
+
+ // TODO: Check default values
+ public LuaRadialGradientBrush GetRadialGradientBrush(Dictionary gradientColors,
+ double centerX = 0.5, double centerY = 0.5, double originX = 0.5, double originY = 0.5)
+ {
+ return new LuaRadialGradientBrush(gradientColors, centerX, centerY, originX, originY);
+ }
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaEventsModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs
similarity index 50%
rename from Artemis/Artemis/Profiles/Lua/Modules/Events/LuaEventsModule.cs
rename to Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs
index 8f25d2c46..1e406b540 100644
--- a/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaEventsModule.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs
@@ -1,34 +1,44 @@
using System;
using System.Windows.Forms;
-using System.Windows.Media;
-using Artemis.Models.Interfaces;
+using Artemis.DeviceProviders;
+using Artemis.Events;
+using Artemis.Managers;
+using Artemis.Profiles.Lua.Modules.Events;
using Artemis.Profiles.Lua.Wrappers;
+using Artemis.Utilities.Keyboard;
using MoonSharp.Interpreter;
using NLog;
-namespace Artemis.Profiles.Lua.Modules.Events
+namespace Artemis.Profiles.Lua.Modules
{
+ [MoonSharpUserData]
public class LuaEventsModule : LuaModule
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
+ private readonly ProfileModel _profileModel;
public readonly string InvokeLock = string.Empty;
- public LuaEventsModule(LuaWrapper luaWrapper) : base(luaWrapper)
+ public LuaEventsModule(LuaManager luaManager) : base(luaManager)
{
+ _profileModel = luaManager.ProfileModel;
+ _profileModel.OnDeviceUpdatedEvent += OnDeviceUpdatedEvent;
+ _profileModel.OnDeviceDrawnEvent += OnDeviceDrawnEvent;
+ KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
}
public override string ModuleName => "Events";
+
public event EventHandler DeviceUpdating;
public event EventHandler DeviceDrawing;
public event EventHandler KeyboardKeyPressed;
- internal void InvokeDeviceUpdate(ProfileModel profileModel, string deviceType, IDataModel dataModel,
- bool preview)
+ private void KeyboardHookOnKeyDownCallback(KeyEventArgs e)
{
try
{
- LuaInvoke(profileModel, () => OnDeviceUpdating(new LuaProfileWrapper(profileModel),
- new LuaDeviceUpdatingEventArgs(deviceType, dataModel, preview)));
+ var keyMatch = LuaManager.KeyboardProvider.GetKeyPosition(e.KeyCode) ?? new KeyMatch(e.KeyCode, 0, 0);
+ var args = new LuaKeyPressEventArgs(e.KeyCode, keyMatch.X, keyMatch.Y);
+ LuaInvoke(_profileModel, () => OnKeyboardKeyPressed(LuaManager.ProfileModule, args));
}
catch (Exception)
{
@@ -36,13 +46,12 @@ namespace Artemis.Profiles.Lua.Modules.Events
}
}
- internal void InvokeDeviceDraw(ProfileModel profileModel, string deviceType, IDataModel dataModel, bool preview,
- DrawingContext c)
+ private void OnDeviceUpdatedEvent(object sender, ProfileDeviceEventsArg e)
{
try
{
- LuaInvoke(profileModel, () => OnDeviceDrawing(new LuaProfileWrapper(profileModel),
- new LuaDeviceDrawingEventArgs(deviceType, dataModel, preview, new LuaDrawWrapper(c))));
+ var args = new LuaDeviceUpdatingEventArgs(e.UpdateType, e.DataModel, e.Preview);
+ LuaInvoke(_profileModel, () => OnDeviceUpdating(LuaManager.ProfileModule, args));
}
catch (Exception)
{
@@ -50,12 +59,13 @@ namespace Artemis.Profiles.Lua.Modules.Events
}
}
- internal void InvokeKeyPressed(ProfileModel profileModel, LuaKeyboardModule keyboard, Keys key, int x, int y)
+ private void OnDeviceDrawnEvent(object sender, ProfileDeviceEventsArg e)
{
try
{
- LuaInvoke(profileModel, () => OnKeyboardKeyPressed(new LuaProfileWrapper(profileModel),
- keyboard, new LuaKeyPressEventArgs(key, x, y)));
+ var wrapper = new LuaDrawWrapper(e.DrawingContext);
+ var args = new LuaDeviceDrawingEventArgs(e.UpdateType, e.DataModel, e.Preview, wrapper);
+ LuaInvoke(_profileModel, () => OnDeviceDrawing(LuaManager.ProfileModule, args));
}
catch (Exception)
{
@@ -86,26 +96,29 @@ namespace Artemis.Profiles.Lua.Modules.Events
}
}
- protected virtual void OnDeviceUpdating(LuaProfileWrapper profileModel, LuaDeviceUpdatingEventArgs e)
+ protected virtual void OnDeviceUpdating(LuaProfileModule profileModel, LuaDeviceUpdatingEventArgs e)
{
DeviceUpdating?.Invoke(profileModel, e);
}
- protected virtual void OnDeviceDrawing(LuaProfileWrapper profileModel, LuaDeviceDrawingEventArgs e)
+ protected virtual void OnDeviceDrawing(LuaProfileModule profileModel, LuaDeviceDrawingEventArgs e)
{
DeviceDrawing?.Invoke(profileModel, e);
}
- protected virtual void OnKeyboardKeyPressed(LuaProfileWrapper profileModel, LuaKeyboardModule keyboard,
- LuaKeyPressEventArgs e)
+ protected virtual void OnKeyboardKeyPressed(LuaProfileModule profileModel, LuaKeyPressEventArgs e)
{
KeyboardKeyPressed?.Invoke(profileModel, e);
}
#region Overriding members
+
public override void Dispose()
{
+ _profileModel.OnDeviceUpdatedEvent -= OnDeviceUpdatedEvent;
+ _profileModel.OnDeviceDrawnEvent -= OnDeviceDrawnEvent;
+ KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback;
}
#endregion
diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaKeyboardModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaKeyboardModule.cs
index 7a2f29b7c..b964a8c5a 100644
--- a/Artemis/Artemis/Profiles/Lua/Modules/LuaKeyboardModule.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaKeyboardModule.cs
@@ -1,6 +1,8 @@
-using System.Windows.Forms;
+using System;
+using System.Diagnostics;
+using System.Windows.Forms;
using Artemis.DeviceProviders;
-using Artemis.Utilities.Keyboard;
+using Artemis.Managers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules
@@ -10,13 +12,14 @@ namespace Artemis.Profiles.Lua.Modules
{
private readonly KeyboardProvider _keyboardProvider;
- public LuaKeyboardModule(LuaWrapper luaWrapper) : base(luaWrapper)
+ public LuaKeyboardModule(LuaManager luaManager) : base(luaManager)
{
- _keyboardProvider = luaWrapper.KeyboardProvider;
- KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
+ _keyboardProvider = luaManager.KeyboardProvider;
+
+ // Register the KeyMatch type for usage in GetKeyPosition
+ UserData.RegisterType(typeof(KeyMatch));
}
- // TODO: Visible in LUA? Decladed as invisile in base class
public override string ModuleName => "Keyboard";
public string Name => _keyboardProvider.Name;
@@ -24,32 +27,23 @@ namespace Artemis.Profiles.Lua.Modules
public int Width => _keyboardProvider.Width;
public int Height => _keyboardProvider.Height;
- #region Overriding members
-
- public override void Dispose()
- {
- KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback;
- }
-
- #endregion
-
- private void KeyboardHookOnKeyDownCallback(KeyEventArgs e)
- {
- // TODO
- //var keyMatch = _keyboardProvider.GetKeyPosition(e.KeyCode);
- //if (keyMatch != null)
- // LuaWrapper.LuaEventsWrapper.InvokeKeyPressed(LuaWrapper.ProfileModel, this, keyMatch.Value.KeyCode,
- // keyMatch.Value.X, keyMatch.Value.Y);
- }
-
public void PressKeys(string keys)
{
SendKeys.SendWait(keys);
}
- public void GetKeyPosition(Keys key)
+ public KeyMatch? GetKeyPosition(string key)
{
- _keyboardProvider.GetKeyPosition(key);
+ // Convert string to Keys enum, I'm not sure if built-in enums can be converted automatically
+ try
+ {
+ var keyEnum = (Keys)Enum.Parse(typeof(Keys), key);
+ return _keyboardProvider.GetKeyPosition(keyEnum);
+ }
+ catch (ArgumentException)
+ {
+ throw new ScriptRuntimeException($"Key '{key}' not found");
+ }
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs
index d95c2a615..aca0bb2c8 100644
--- a/Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs
@@ -1,9 +1,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;
+using Artemis.Managers;
using Artemis.Modules.Effects.ProfilePreview;
using Artemis.Profiles.Layers.Models;
-using Artemis.Profiles.Lua.Brushes;
+using Artemis.Profiles.Lua.Modules.Brushes;
+using Artemis.Profiles.Lua.Wrappers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules
@@ -13,10 +15,10 @@ namespace Artemis.Profiles.Lua.Modules
{
private readonly LayerModel _layerModel;
- public LuaLayerModule(LuaWrapper luaWrapper) : base(luaWrapper)
+ public LuaLayerModule(LuaManager luaManager, LayerModel layerModel) : base(luaManager)
{
- _layerModel = luaWrapper.LayerModel;
- SavedProperties = new Lua.LuaLayerProperties(_layerModel);
+ _layerModel = layerModel;
+ SavedProperties = new Wrappers.LuaLayerProperties(_layerModel);
// Triger an update to fill up the Properties
_layerModel.Update(new ProfilePreviewDataModel(), true, false);
@@ -24,14 +26,6 @@ namespace Artemis.Profiles.Lua.Modules
public override string ModuleName => "Layer";
- #region Overriding members
-
- public override void Dispose()
- {
- }
-
- #endregion
-
#region Child methods
public List GetChildren()
@@ -113,7 +107,7 @@ namespace Artemis.Profiles.Lua.Modules
#region Advanced layer properties
- public Lua.LuaLayerProperties SavedProperties { get; set; }
+ public Wrappers.LuaLayerProperties SavedProperties { get; set; }
public string BrushType => _layerModel.Properties.Brush?.GetType().Name;
diff --git a/Artemis/Artemis/Profiles/LuaMouseWrapper.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaMouseModule.cs
similarity index 72%
rename from Artemis/Artemis/Profiles/LuaMouseWrapper.cs
rename to Artemis/Artemis/Profiles/Lua/Modules/LuaMouseModule.cs
index acc0fdc81..063e970bd 100644
--- a/Artemis/Artemis/Profiles/LuaMouseWrapper.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaMouseModule.cs
@@ -1,33 +1,39 @@
-using System.Runtime.InteropServices;
-using System.Windows;
-using MoonSharp.Interpreter;
-
-namespace Artemis.Profiles
-{
- [MoonSharpUserData]
- public class LuaMouseWrapper
- {
- public int Y => (int) GetMousePosition().Y;
-
- public int X => (int) GetMousePosition().X;
-
-
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool GetCursorPos(ref Win32Point pt);
-
- public static Point GetMousePosition()
- {
- var w32Mouse = new Win32Point();
- GetCursorPos(ref w32Mouse);
- return new Point(w32Mouse.X, w32Mouse.Y);
- }
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct Win32Point
- {
- public int X;
- public int Y;
- }
- }
+using System.Runtime.InteropServices;
+using System.Windows;
+using Artemis.Managers;
+using MoonSharp.Interpreter;
+
+namespace Artemis.Profiles.Lua.Modules
+{
+ [MoonSharpUserData]
+ public class LuaMouseModule : LuaModule
+ {
+ public LuaMouseModule(LuaManager luaManager) : base(luaManager)
+ {
+ }
+
+ public override string ModuleName => "Mouse";
+
+ public int Y => (int) GetMousePosition().Y;
+
+ public int X => (int) GetMousePosition().X;
+
+ [DllImport("user32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static extern bool GetCursorPos(ref Win32Point pt);
+
+ public static Point GetMousePosition()
+ {
+ var w32Mouse = new Win32Point();
+ GetCursorPos(ref w32Mouse);
+ return new Point(w32Mouse.X, w32Mouse.Y);
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct Win32Point
+ {
+ public int X;
+ public int Y;
+ }
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaProfileModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaProfileModule.cs
index f3a1b5617..9de14efb8 100644
--- a/Artemis/Artemis/Profiles/Lua/Modules/LuaProfileModule.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaProfileModule.cs
@@ -1,15 +1,19 @@
using System.Collections.Generic;
using System.Linq;
+using Artemis.Managers;
+using Artemis.Profiles.Lua.Wrappers;
+using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules
{
+ [MoonSharpUserData]
public class LuaProfileModule : LuaModule
{
private readonly ProfileModel _profileModel;
- public LuaProfileModule(LuaWrapper luaWrapper) : base(luaWrapper)
+ public LuaProfileModule(LuaManager luaManager) : base(luaManager)
{
- _profileModel = luaWrapper.ProfileModel;
+ _profileModel = luaManager.ProfileModel;
}
public override string ModuleName => "Profile";
@@ -20,14 +24,6 @@ namespace Artemis.Profiles.Lua.Modules
#endregion
- #region Overriding members
-
- public override void Dispose()
- {
- }
-
- #endregion
-
#region Layer methods
public List GetLayers()
diff --git a/Artemis/Artemis/Profiles/Lua/Wrappers/LuaDrawWrapper.cs b/Artemis/Artemis/Profiles/Lua/Wrappers/LuaDrawWrapper.cs
index 7fefa6300..baecf2913 100644
--- a/Artemis/Artemis/Profiles/Lua/Wrappers/LuaDrawWrapper.cs
+++ b/Artemis/Artemis/Profiles/Lua/Wrappers/LuaDrawWrapper.cs
@@ -2,13 +2,13 @@
using System.Globalization;
using System.Windows;
using System.Windows.Media;
-using Artemis.Profiles.Lua.Brushes;
+using Artemis.Profiles.Lua.Modules.Brushes;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Wrappers
{
///
- /// A wrapper that is provided to each OnDraw event to allow drawing in LUA
+ /// A wrapper that is provided to each OnDraw event to allow drawing in LUA
///
[MoonSharpUserData]
public class LuaDrawWrapper
diff --git a/Artemis/Artemis/Profiles/Lua/Wrappers/LuaLayerWrapper.cs b/Artemis/Artemis/Profiles/Lua/Wrappers/LuaLayerWrapper.cs
new file mode 100644
index 000000000..25a44a777
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Lua/Wrappers/LuaLayerWrapper.cs
@@ -0,0 +1,183 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Media;
+using Artemis.Modules.Effects.ProfilePreview;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Lua.Modules.Brushes;
+using MoonSharp.Interpreter;
+
+namespace Artemis.Profiles.Lua.Wrappers
+{
+ ///
+ /// Serves as a sandboxed wrapper around the LayerModel
+ ///
+ [MoonSharpUserData]
+ public class LuaLayerWrapper
+ {
+ private readonly LayerModel _layerModel;
+
+ public LuaLayerWrapper(LayerModel layerModel)
+ {
+ _layerModel = layerModel;
+ SavedProperties = new LuaLayerProperties(layerModel);
+
+ // Triger an update to fill up the Properties
+ _layerModel.Update(new ProfilePreviewDataModel(), true, false);
+ }
+
+ #region Child methods
+
+ public List GetChildren()
+ {
+ return _layerModel.Children.Select(l => new LuaLayerWrapper(l)).ToList();
+ }
+
+ public LuaLayerWrapper GetChildByName(string name)
+ {
+ var layer = _layerModel.Children.FirstOrDefault(l => l.Name == name);
+ return layer == null ? null : new LuaLayerWrapper(layer);
+ }
+
+ #endregion
+
+ #region General layer properties
+
+ public string Name
+ {
+ get { return _layerModel.Name; }
+ set { _layerModel.Name = value; }
+ }
+
+ public bool Enabled
+ {
+ get { return _layerModel.Enabled; }
+ set { _layerModel.Enabled = value; }
+ }
+
+ public bool IsEvent
+ {
+ get { return _layerModel.IsEvent; }
+ set { _layerModel.IsEvent = value; }
+ }
+
+ public LuaLayerWrapper Parent => new LuaLayerWrapper(_layerModel.Parent);
+
+ #endregion
+
+ #region Render layer properties
+
+ public double X
+ {
+ get { return _layerModel.X; }
+ set { _layerModel.X = value; }
+ }
+
+ public double Y
+ {
+ get { return _layerModel.Y; }
+ set { _layerModel.Y = value; }
+ }
+
+ public double Width
+ {
+ get { return _layerModel.Width; }
+ set { _layerModel.Width = value; }
+ }
+
+ public double Height
+ {
+ get { return _layerModel.Height; }
+ set { _layerModel.Height = value; }
+ }
+
+ public double Opacity
+ {
+ get { return _layerModel.Opacity; }
+ set { _layerModel.Opacity = value; }
+ }
+
+ public double AnimationProgress
+ {
+ get { return _layerModel.AnimationProgress; }
+ set { _layerModel.AnimationProgress = value; }
+ }
+
+ #endregion
+
+ #region Advanced layer properties
+
+ public LuaLayerProperties SavedProperties { get; set; }
+
+ public string BrushType => _layerModel.Properties.Brush?.GetType().Name;
+
+ public LuaBrush Brush
+ {
+ get
+ {
+ if (_layerModel.Properties.Brush is SolidColorBrush)
+ return new LuaSolidColorBrush(_layerModel.Properties.Brush);
+ if (_layerModel.Properties.Brush is LinearGradientBrush)
+ return new LuaLinearGradientBrush(_layerModel.Properties.Brush);
+ if (_layerModel.Properties.Brush is RadialGradientBrush)
+ return new LuaRadialGradientBrush(_layerModel.Properties.Brush);
+ return null;
+ }
+ set { _layerModel.Properties.Brush = value?.Brush; }
+ }
+
+ #endregion
+ }
+
+ [MoonSharpUserData]
+ public class LuaLayerProperties
+ {
+ private readonly LayerModel _layerModel;
+
+ public LuaLayerProperties(LayerModel layerModel)
+ {
+ _layerModel = layerModel;
+ }
+
+ public double X
+ {
+ get { return _layerModel.Properties.X; }
+ set { _layerModel.Properties.X = value; }
+ }
+
+ public double Y
+ {
+ get { return _layerModel.Properties.Y; }
+ set { _layerModel.Properties.Y = value; }
+ }
+
+ public double Width
+ {
+ get { return _layerModel.Properties.Width; }
+ set { _layerModel.Properties.Width = value; }
+ }
+
+ public double Height
+ {
+ get { return _layerModel.Properties.Height; }
+ set { _layerModel.Properties.Height = value; }
+ }
+
+ public bool Contain
+ {
+ get { return _layerModel.Properties.Contain; }
+ set { _layerModel.Properties.Contain = value; }
+ }
+
+ public double Opacity
+ {
+ get { return _layerModel.Properties.Opacity; }
+ set { _layerModel.Properties.Opacity = value; }
+ }
+
+ public double AnimationSpeed
+ {
+ get { return _layerModel.Properties.AnimationSpeed; }
+ set { _layerModel.Properties.AnimationSpeed = value; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs
index 7ec550697..d191f30c4 100644
--- a/Artemis/Artemis/Profiles/ProfileModel.cs
+++ b/Artemis/Artemis/Profiles/ProfileModel.cs
@@ -6,10 +6,11 @@ using System.Linq;
using System.Windows;
using System.Windows.Media;
using Artemis.DeviceProviders;
+using Artemis.Events;
+using Artemis.Managers;
using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
-using Artemis.Profiles.Lua;
using Artemis.Utilities;
using Artemis.Utilities.ParentChild;
using Newtonsoft.Json;
@@ -41,6 +42,9 @@ namespace Artemis.Profiles
[JsonIgnore]
public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray());
+ public event EventHandler OnDeviceUpdatedEvent;
+ public event EventHandler OnDeviceDrawnEvent;
+
public void FixOrder()
{
Layers.Sort(l => l.Order);
@@ -77,12 +81,14 @@ namespace Artemis.Profiles
var layers = new List();
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
{
- if (!layerModel.Enabled || (keyboardOnly && (layerModel.LayerType.DrawType != DrawType.Keyboard)))
+ if (!layerModel.Enabled || keyboardOnly && layerModel.LayerType.DrawType != DrawType.Keyboard)
continue;
if (!ignoreConditions)
+ {
if (!layerModel.ConditionsMet(dataModel))
continue;
+ }
layers.Add(layerModel);
layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions));
@@ -115,12 +121,12 @@ namespace Artemis.Profiles
// Update the layers
foreach (var layerModel in layerModels)
layerModel.Update(dataModel, preview, updateAnimations);
- LuaWrapper.LuaEventsWrapper?.InvokeDeviceUpdate(this, updateType, dataModel, preview);
+ RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(updateType, dataModel, preview, null));
// Draw the layers
foreach (var layerModel in layerModels)
layerModel.Draw(dataModel, c, preview, updateAnimations);
- LuaWrapper.LuaEventsWrapper?.InvokeDeviceDraw(this, updateType, dataModel, preview, c);
+ RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(updateType, dataModel, preview, c));
// Remove the clip
c.Pop();
@@ -132,6 +138,18 @@ namespace Artemis.Profiles
}
}
+ private void RaiseDeviceUpdatedEvent(ProfileDeviceEventsArg e)
+ {
+ var handler = OnDeviceUpdatedEvent;
+ handler?.Invoke(this, e);
+ }
+
+ public void RaiseDeviceDrawnEvent(ProfileDeviceEventsArg e)
+ {
+ var handler = OnDeviceDrawnEvent;
+ handler?.Invoke(this, e);
+ }
+
///
/// Looks at all the layers wthin the profile and makes sure they are within boundaries of the given rectangle
///
@@ -172,15 +190,15 @@ namespace Artemis.Profiles
}
}
- public void Activate(KeyboardProvider keyboard)
+ public void Activate(LuaManager luaManager)
{
- if (!Equals(LuaWrapper.ProfileModel, this))
- LuaWrapper.SetupLua(this, keyboard);
+ if (!Equals(luaManager.ProfileModel, this))
+ luaManager.SetupLua(this);
}
- public void Deactivate()
+ public void Deactivate(LuaManager luaManager)
{
- LuaWrapper.Clear();
+ luaManager.ClearLua();
}
public LayerModel AddLayer(LayerModel afterLayer)
@@ -189,7 +207,9 @@ namespace Artemis.Profiles
var layer = LayerModel.CreateLayer();
if (afterLayer != null)
+ {
afterLayer.InsertAfter(layer);
+ }
else
{
Layers.Add(layer);
@@ -221,8 +241,8 @@ namespace Artemis.Profiles
unchecked
{
var hashCode = Slug?.GetHashCode() ?? 0;
- hashCode = (hashCode*397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
- hashCode = (hashCode*397) ^ (GameName?.GetHashCode() ?? 0);
+ hashCode = (hashCode * 397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
+ hashCode = (hashCode * 397) ^ (GameName?.GetHashCode() ?? 0);
return hashCode;
}
}
diff --git a/Artemis/Artemis/Properties/Resources.Designer.cs b/Artemis/Artemis/Properties/Resources.Designer.cs
index 467d52c81..a77b26a2d 100644
--- a/Artemis/Artemis/Properties/Resources.Designer.cs
+++ b/Artemis/Artemis/Properties/Resources.Designer.cs
@@ -22,7 +22,7 @@ namespace Artemis.Properties {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
+ public class Resources {
private static global::System.Resources.ResourceManager resourceMan;
diff --git a/Artemis/Artemis/Utilities/ImageUtilities.cs b/Artemis/Artemis/Utilities/ImageUtilities.cs
index f9a3f1ae9..51fc2f66f 100644
--- a/Artemis/Artemis/Utilities/ImageUtilities.cs
+++ b/Artemis/Artemis/Utilities/ImageUtilities.cs
@@ -7,7 +7,7 @@ using System.Windows.Media.Imaging;
namespace Artemis.Utilities
{
- internal class ImageUtilities
+ public class ImageUtilities
{
///
/// Resize the image to the specified width and height.
diff --git a/Artemis/Artemis/Utilities/StickyValue.cs b/Artemis/Artemis/Utilities/StickyValue.cs
index 7df32ae79..065b4eba3 100644
--- a/Artemis/Artemis/Utilities/StickyValue.cs
+++ b/Artemis/Artemis/Utilities/StickyValue.cs
@@ -7,7 +7,7 @@ namespace Artemis.Utilities
///
/// A value that only changes it's not changed again within a set time
///
- internal class StickyValue : IDisposable
+ public class StickyValue : IDisposable
{
private readonly int _stickyTime;
private readonly BackgroundWorker _updateWorker;
diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs
index 55b12d98a..edea36331 100644
--- a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs
@@ -27,14 +27,14 @@ namespace Artemis.ViewModels.Profiles
private ILayerType _selectedLayerType;
public LayerEditorViewModel(LayerModel layer, IDataModel dataModel, IEnumerable types,
- List layerAnimations)
+ IEnumerable layerAnimations)
{
Layer = layer;
ProposedLayer = Clone(layer);
ProposedLayer.Children.Clear();
DataModel = DataModel;
- LayerTypes = new BindableCollection(types);
- LayerAnimations = layerAnimations;
+ LayerTypes = new BindableCollection(types.OrderBy(t => t.Name));
+ LayerAnimations = layerAnimations.OrderBy(l => l.Name).ToList();
DataModelProps = new BindableCollection(GenerateTypeMap(dataModel));
@@ -118,7 +118,7 @@ namespace Artemis.ViewModels.Profiles
NotifyOfPropertyChange(() => SelectedLayerType);
}
}
-
+
public void PreSelect()
{
SelectedLayerType = LayerTypes.FirstOrDefault(t => t.Name == ProposedLayer.LayerType.Name);
diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
index 02576c557..88918413a 100644
--- a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
@@ -16,11 +16,9 @@ using Artemis.Models;
using Artemis.Profiles;
using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Layers.Types.Folder;
-using Artemis.Profiles.Lua;
using Artemis.Services;
using Artemis.Styles.DropTargetAdorners;
using Artemis.Utilities;
-using Caliburn.Micro;
using GongSolutions.Wpf.DragDrop;
using MahApps.Metro.Controls.Dialogs;
using Ninject;
@@ -38,6 +36,7 @@ namespace Artemis.ViewModels.Profiles
{
private readonly DeviceManager _deviceManager;
private readonly EffectModel _gameModel;
+ private readonly LuaManager _luaManager;
private readonly Timer _saveTimer;
private ImageSource _keyboardPreview;
private ObservableCollection _layers;
@@ -45,11 +44,12 @@ namespace Artemis.ViewModels.Profiles
private bool _saving;
private ProfileModel _selectedProfile;
- public ProfileEditorViewModel(DeviceManager deviceManager, EffectModel gameModel,
+ public ProfileEditorViewModel(DeviceManager deviceManager, LuaManager luaManager, EffectModel gameModel,
ProfileViewModel profileViewModel, MetroDialogService dialogService, WindowService windowService,
string lastProfile)
{
_deviceManager = deviceManager;
+ _luaManager = luaManager;
_gameModel = gameModel;
ProfileNames = new ObservableCollection();
@@ -79,7 +79,7 @@ namespace Artemis.ViewModels.Profiles
public ProfileViewModel ProfileViewModel { get; set; }
public bool EditorEnabled
- => (SelectedProfile != null) && !SelectedProfile.IsDefault && (_deviceManager.ActiveKeyboard != null);
+ => SelectedProfile != null && !SelectedProfile.IsDefault && _deviceManager.ActiveKeyboard != null;
public ObservableCollection ProfileNames
{
@@ -125,11 +125,11 @@ namespace Artemis.ViewModels.Profiles
return;
// Deactivate old profile
- _selectedProfile?.Deactivate();
+ _selectedProfile?.Deactivate(_luaManager);
// Update the value
_selectedProfile = value;
// Activate new profile
- _selectedProfile?.Activate(_deviceManager.ActiveKeyboard);
+ _selectedProfile?.Activate(_luaManager);
NotifyOfPropertyChange(() => SelectedProfile);
NotifyOfPropertyChange(() => SelectedProfileName);
}
@@ -149,16 +149,16 @@ namespace Artemis.ViewModels.Profiles
public PreviewSettings? PreviewSettings => _deviceManager.ActiveKeyboard?.PreviewSettings;
public bool ProfileSelected => SelectedProfile != null;
- public bool LayerSelected => (SelectedProfile != null) && (ProfileViewModel.SelectedLayer != null);
+ public bool LayerSelected => SelectedProfile != null && ProfileViewModel.SelectedLayer != null;
public void DragOver(IDropInfo dropInfo)
{
var source = dropInfo.Data as LayerModel;
var target = dropInfo.TargetItem as LayerModel;
- if ((source == null) || (target == null) || (source == target))
+ if (source == null || target == null || source == target)
return;
- if ((dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter) &&
+ if (dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter &&
target.LayerType is FolderType)
{
dropInfo.DropTargetAdorner = typeof(DropTargetMetroHighlightAdorner);
@@ -175,7 +175,7 @@ namespace Artemis.ViewModels.Profiles
{
var source = dropInfo.Data as LayerModel;
var target = dropInfo.TargetItem as LayerModel;
- if ((source == null) || (target == null) || (source == target))
+ if (source == null || target == null || source == target)
return;
// Don't allow a folder to become it's own child, that's just weird
@@ -196,7 +196,7 @@ namespace Artemis.ViewModels.Profiles
parent.FixOrder();
}
- if ((dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter) &&
+ if (dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter &&
target.LayerType is FolderType)
{
// Insert into folder
@@ -208,9 +208,9 @@ namespace Artemis.ViewModels.Profiles
else
{
// Insert the source into it's new profile/parent and update the order
- if ((dropInfo.InsertPosition == RelativeInsertPosition.AfterTargetItem) ||
- (dropInfo.InsertPosition ==
- (RelativeInsertPosition.TargetItemCenter | RelativeInsertPosition.AfterTargetItem)))
+ if (dropInfo.InsertPosition == RelativeInsertPosition.AfterTargetItem ||
+ dropInfo.InsertPosition ==
+ (RelativeInsertPosition.TargetItemCenter | RelativeInsertPosition.AfterTargetItem))
target.InsertAfter(source);
else
target.InsertBefore(source);
@@ -237,7 +237,7 @@ namespace Artemis.ViewModels.Profiles
public void Deactivate()
{
ProfileViewModel.Deactivate();
- SelectedProfile?.Deactivate();
+ SelectedProfile?.Deactivate(_luaManager);
_saveTimer.Stop();
}
@@ -247,7 +247,7 @@ namespace Artemis.ViewModels.Profiles
private void LoadProfiles()
{
ProfileNames.Clear();
- if ((_gameModel == null) || (_deviceManager.ActiveKeyboard == null))
+ if (_gameModel == null || _deviceManager.ActiveKeyboard == null)
return;
ProfileNames.AddRange(ProfileProvider.GetProfileNames(_deviceManager.ActiveKeyboard, _gameModel));
@@ -255,17 +255,13 @@ namespace Artemis.ViewModels.Profiles
// If a profile name was provided, try to load it
ProfileModel lastProfileModel = null;
if (!string.IsNullOrEmpty(LastProfile))
- {
lastProfileModel = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _gameModel, LastProfile);
- }
if (lastProfileModel != null)
SelectedProfile = lastProfileModel;
else
- {
SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _gameModel,
ProfileNames.FirstOrDefault());
- }
}
@@ -532,7 +528,7 @@ namespace Artemis.ViewModels.Profiles
var name = await DialogService.ShowInputDialog("Rename profile", "Please enter a unique new profile name");
// Null when the user cancelled
- if (string.IsNullOrEmpty(name) || (name.Length < 2))
+ if (string.IsNullOrEmpty(name) || name.Length < 2)
return;
SelectedProfile.Name = name;
@@ -544,7 +540,7 @@ namespace Artemis.ViewModels.Profiles
.ShowInputDialog("Name already in use", "Please enter a unique new profile name");
// Null when the user cancelled
- if (string.IsNullOrEmpty(name) || (name.Length < 2))
+ if (string.IsNullOrEmpty(name) || name.Length < 2)
{
SelectedProfile.Name = oldName;
return;
@@ -694,8 +690,8 @@ namespace Artemis.ViewModels.Profiles
return;
try
{
- SelectedProfile?.Activate(_deviceManager.ActiveKeyboard);
- LuaWrapper.OpenEditor();
+ SelectedProfile?.Activate(_luaManager);
+ _luaManager.OpenEditor();
}
catch (Exception e)
{
@@ -738,7 +734,7 @@ namespace Artemis.ViewModels.Profiles
public void SaveSelectedProfile()
{
- if (_saving || (SelectedProfile == null) || _deviceManager.ChangingKeyboard)
+ if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard)
return;
_saving = true;
diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs
index 6dce58e43..219136b0e 100644
--- a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs
@@ -11,7 +11,6 @@ using Artemis.Modules.Effects.ProfilePreview;
using Artemis.Profiles;
using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Layers.Types.Folder;
-using Artemis.Profiles.Lua;
using Artemis.Properties;
using Artemis.Utilities;
using Caliburn.Micro;
@@ -103,10 +102,11 @@ namespace Artemis.ViewModels.Profiles
if (_blurProgress > 2)
_blurProgress = 0;
_blurProgress = _blurProgress + 0.025;
- BlurRadius = (Math.Sin(_blurProgress*Math.PI) + 1)*10 + 10;
+ BlurRadius = (Math.Sin(_blurProgress * Math.PI) + 1) * 10 + 10;
// Besides the usual checks, also check if the ActiveKeyboard isn't the NoneKeyboard
- if (SelectedProfile == null || _deviceManager.ActiveKeyboard == null || _deviceManager.ActiveKeyboard.Slug == "none")
+ if (SelectedProfile == null || _deviceManager.ActiveKeyboard == null ||
+ _deviceManager.ActiveKeyboard.Slug == "none")
{
var preview = new DrawingImage();
preview.Freeze();
@@ -166,8 +166,8 @@ namespace Artemis.ViewModels.Profiles
new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 0.7));
}
- LuaWrapper.LuaEventsWrapper?.InvokeDeviceDraw(SelectedProfile, "preview", new ProfilePreviewDataModel(),
- true, drawingContext);
+ SelectedProfile.RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg("preview",
+ new ProfilePreviewDataModel(), true, drawingContext));
// Remove the clip
drawingContext.Pop();
@@ -223,8 +223,8 @@ namespace Artemis.ViewModels.Profiles
var keyboard = _deviceManager.ActiveKeyboard;
var pos = e.GetPosition((Image) e.OriginalSource);
- var x = pos.X/((double) keyboard.PreviewSettings.Width/keyboard.Width);
- var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height);
+ var x = pos.X / ((double) keyboard.PreviewSettings.Width / keyboard.Width);
+ var y = pos.Y / ((double) keyboard.PreviewSettings.Height / keyboard.Height);
var hoverLayer = GetLayers().Where(l => l.MustDraw())
.FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
@@ -244,8 +244,8 @@ namespace Artemis.ViewModels.Profiles
var pos = e.GetPosition((Image) e.OriginalSource);
var keyboard = _deviceManager.ActiveKeyboard;
- var x = pos.X/((double) keyboard.PreviewSettings.Width/keyboard.Width);
- var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height);
+ var x = pos.X / ((double) keyboard.PreviewSettings.Width / keyboard.Width);
+ var y = pos.Y / ((double) keyboard.PreviewSettings.Height / keyboard.Height);
var hoverLayer = GetLayers().Where(l => l.MustDraw())
.FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
@@ -267,7 +267,9 @@ namespace Artemis.ViewModels.Profiles
: Cursors.SizeAll;
}
else
+ {
KeyboardPreviewCursor = Cursors.Hand;
+ }
}
public Cursor KeyboardPreviewCursor
@@ -292,14 +294,14 @@ namespace Artemis.ViewModels.Profiles
{
// Reset the dragging state on mouse release
if (e.LeftButton == MouseButtonState.Released ||
- (_draggingLayer != null && SelectedLayer != _draggingLayer))
+ _draggingLayer != null && SelectedLayer != _draggingLayer)
{
_draggingLayerOffset = null;
_draggingLayer = null;
return;
}
- if (SelectedLayer == null || (SelectedLayer.LayerType != null && !SelectedLayer.LayerType.ShowInEdtor))
+ if (SelectedLayer == null || SelectedLayer.LayerType != null && !SelectedLayer.LayerType.ShowInEdtor)
return;
// Setup the dragging state on mouse press
@@ -314,7 +316,7 @@ namespace Artemis.ViewModels.Profiles
Math.Pow(y - layerRect.BottomRight.Y, 2)) < 0.6;
}
- if (_draggingLayerOffset == null || _draggingLayer == null || (_draggingLayer != SelectedLayer))
+ if (_draggingLayerOffset == null || _draggingLayer == null || _draggingLayer != SelectedLayer)
return;
var draggingProps = _draggingLayer.Properties;
diff --git a/Artemis/Artemis86Wrapper/Program.cs b/Artemis/Artemis86Wrapper/Program.cs
index 779c38c3c..e831a0f04 100644
--- a/Artemis/Artemis86Wrapper/Program.cs
+++ b/Artemis/Artemis86Wrapper/Program.cs
@@ -3,7 +3,7 @@ using Artemis86Wrapper.Intergrations.Skype;
namespace Artemis86Wrapper
{
- internal class Program
+ public class Program
{
private static void Main(string[] args)
{