diff --git a/.gitignore b/.gitignore
index 0922ac1a4..a6e8a9467 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@
x64/
x86/
build/
+debug/
bld/
[Bb]in/
[Oo]bj/
@@ -190,4 +191,4 @@ FakesAssemblies/
# Visual Studio 6 workspace options file
*.opt
-*.opendb
+*.opendb
diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index b56f3704b..6ee49f2d7 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -191,9 +191,6 @@
..\packages\MahApps.Metro.1.3.0\lib\net45\MahApps.Metro.dll
True
-
- False
-
..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll
True
@@ -339,11 +336,9 @@
+
-
-
-
@@ -357,6 +352,7 @@
+
@@ -382,6 +378,14 @@
GtaVView.xaml
+
+
+
+
+
+ LightFxView.xaml
+
+
@@ -499,22 +503,25 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -837,6 +844,10 @@
Designer
MSBuild:Compile
+
+ MSBuild:Compile
+ Designer
+
Designer
MSBuild:Compile
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/DAL/ProfileProvider.cs b/Artemis/Artemis/DAL/ProfileProvider.cs
index 1e0a61dca..5b757726e 100644
--- a/Artemis/Artemis/DAL/ProfileProvider.cs
+++ b/Artemis/Artemis/DAL/ProfileProvider.cs
@@ -67,7 +67,7 @@ namespace Artemis.DAL
lock (prof)
{
// Store the file
- if (!(prof.GameName?.Length > 1) || !(prof.KeyboardSlug?.Length > 1) || !(prof.Name?.Length > 1))
+ if (!(prof.GameName?.Length > 1) || !(prof.KeyboardSlug?.Length > 1) || !(prof.Slug?.Length > 1))
throw new ArgumentException("Profile is invalid. Name, GameName and KeyboardSlug are required");
var path = ProfileFolder + $@"\{prof.KeyboardSlug}\{prof.GameName}";
@@ -84,11 +84,11 @@ namespace Artemis.DAL
}
catch (Exception e)
{
- Logger.Error(e, "Couldn't save profile '{0}.json'", prof.Name);
+ Logger.Error(e, "Couldn't save profile '{0}.json'", prof.Slug);
return;
}
- File.WriteAllText(path + $@"\{prof.Name}.json", json);
+ File.WriteAllText(path + $@"\{prof.Slug}.json", json);
Logger.Debug("Saved profile {0}/{1}/{2}", prof.KeyboardSlug, prof.GameName, prof.Name);
}
}
@@ -114,7 +114,7 @@ namespace Artemis.DAL
public static void DeleteProfile(ProfileModel prof)
{
// Remove the file
- var path = ProfileFolder + $@"\{prof.KeyboardSlug}\{prof.GameName}\{prof.Name}.json";
+ var path = ProfileFolder + $@"\{prof.KeyboardSlug}\{prof.GameName}\{prof.Slug}.json";
if (File.Exists(path))
File.Delete(path);
}
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs
index 503c7e16f..908d4ae07 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)
{
@@ -22,7 +22,7 @@ namespace Artemis.DeviceProviders.Corsair
{
CanUse = CanInitializeSdk();
if (CanUse && !CueSDK.IsInitialized)
- CueSDK.Initialize(true);
+ CueSDK.Initialize();
Logger.Debug("Attempted to enable Corsair headset. CanUse: {0}", CanUse);
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs
index 3b8f30b7a..0dd0f2f32 100644
--- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs
+++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs
@@ -1,150 +1,160 @@
-using System;
-using System.Drawing;
-using System.Linq;
-using System.Windows;
-using System.Windows.Forms;
-using Artemis.DeviceProviders.Corsair.Utilities;
-using Artemis.Properties;
-using Artemis.Utilities;
-using CUE.NET;
-using CUE.NET.Brushes;
-using CUE.NET.Devices.Generic;
-using CUE.NET.Devices.Generic.Enums;
-using CUE.NET.Helper;
-using Ninject.Extensions.Logging;
-using Point = System.Drawing.Point;
-
-namespace Artemis.DeviceProviders.Corsair
-{
- public class CorsairKeyboard : KeyboardProvider
- {
- private CUE.NET.Devices.Keyboard.CorsairKeyboard _keyboard;
- private ImageBrush _keyboardBrush;
-
- public CorsairKeyboard(ILogger logger)
- {
- Logger = logger;
- Name = "Corsair RGB Keyboard";
- CantEnableText = "Couldn't connect to your Corsair keyboard.\n" +
- "Please check your cables and/or drivers (could be outdated) and that Corsair Utility Engine is running.\n" +
- "In CUE, make sure \"Enable SDK\" is checked under Global Settings.\n\n" +
- "If needed, you can select a different keyboard in Artemis under settings.";
- }
-
- public ILogger Logger { get; set; }
-
- public override bool CanEnable()
- {
- return CueSDK.IsSDKAvailable(CorsairDeviceType.Keyboard);
- }
-
- ///
- /// Enables the SDK and sets updatemode to manual as well as the color of the background to black.
- ///
- public override void Enable()
- {
- if (!CueSDK.IsInitialized)
- CueSDK.Initialize(true);
-
- CueSDK.UpdateMode = UpdateMode.Manual;
- _keyboard = CueSDK.KeyboardSDK;
- switch (_keyboard.DeviceInfo.Model)
- {
- case "K95 RGB":
- Height = 7;
- Width = 25;
- Slug = "corsair-k95-rgb";
- PreviewSettings = new PreviewSettings(676, 190, new Thickness(0, -15, 0, 0), Resources.k95);
- break;
- case "K70 RGB":
- case "K70 RGB RAPIDFIRE":
- case "K70 LUX RGB":
- Height = 7;
- Width = 21;
- Slug = "corsair-k70-rgb";
- PreviewSettings = new PreviewSettings(676, 210, new Thickness(0, -25, 0, 0), Resources.k70);
- break;
- case "K65 RGB":
- case "CGK65 RGB":
- case "K65 LUX RGB":
- case "K65 RGB RAPIDFIRE":
- Height = 7;
- Width = 18;
- Slug = "corsair-k65-rgb";
- PreviewSettings = new PreviewSettings(610, 240, new Thickness(0, -30, 0, 0), Resources.k65);
- break;
- case "STRAFE RGB":
- Height = 7;
- Width = 22;
- Slug = "corsair-strafe-rgb";
- PreviewSettings = new PreviewSettings(665, 215, new Thickness(0, -5, 0, 0), Resources.strafe);
- break;
- }
-
- Logger.Debug("Corsair SDK reported device as: {0}", _keyboard.DeviceInfo.Model);
- _keyboard.Brush = _keyboardBrush ?? (_keyboardBrush = new ImageBrush());
- }
-
- public override void Disable()
- {
- if (CueSDK.IsInitialized)
- CueSDK.Reinitialize();
- }
-
- ///
- /// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap
- /// size.
- ///
- ///
- public override void DrawBitmap(Bitmap bitmap)
- {
- using (var image = ImageUtilities.ResizeImage(bitmap, Width, Height))
- {
- // For STRAFE, stretch the image on row 2.
- if (_keyboard.DeviceInfo.Model == "STRAFE RGB")
- {
- using (var strafeBitmap = new Bitmap(22, 8))
- {
- using (var g = Graphics.FromImage(strafeBitmap))
- {
- g.DrawImage(image, new Point(0, 0));
- g.DrawImage(image, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7),
- GraphicsUnit.Pixel);
-
- _keyboardBrush.Image = strafeBitmap;
- _keyboard.Update();
- }
- }
- }
- else
- {
- _keyboardBrush.Image = image;
- _keyboard.Update();
- }
- }
- }
-
- public override KeyMatch? GetKeyPosition(Keys keyCode)
- {
- var widthMultiplier = Width/_keyboard.Brush.RenderedRectangle.Width;
- var heightMultiplier = Height/_keyboard.Brush.RenderedRectangle.Height;
-
- CorsairLed cueLed = null;
- try
- {
- cueLed = _keyboard.Leds.FirstOrDefault(k => k.Id.ToString() == keyCode.ToString()) ??
- _keyboard.Leds.FirstOrDefault(k => k.Id == KeyMap.FormsKeys[keyCode]);
- }
- catch (Exception)
- {
- // ignored
- }
-
- if (cueLed == null)
- return null;
-
- var center = cueLed.LedRectangle.GetCenter();
- return new KeyMatch(keyCode, (int) (center.X*widthMultiplier), (int) (center.Y*heightMultiplier));
- }
- }
+using System;
+using System.Drawing;
+using System.Linq;
+using System.Windows;
+using System.Windows.Forms;
+using Artemis.DeviceProviders.Corsair.Utilities;
+using Artemis.Properties;
+using Artemis.Utilities;
+using CUE.NET;
+using CUE.NET.Brushes;
+using CUE.NET.Devices.Generic;
+using CUE.NET.Devices.Generic.Enums;
+using CUE.NET.Exceptions;
+using CUE.NET.Helper;
+using Ninject.Extensions.Logging;
+using Point = System.Drawing.Point;
+
+namespace Artemis.DeviceProviders.Corsair
+{
+ public class CorsairKeyboard : KeyboardProvider
+ {
+ private CUE.NET.Devices.Keyboard.CorsairKeyboard _keyboard;
+ private ImageBrush _keyboardBrush;
+
+ public CorsairKeyboard(ILogger logger)
+ {
+ Logger = logger;
+ Name = "Corsair RGB Keyboard";
+ CantEnableText = "Couldn't connect to your Corsair keyboard.\n" +
+ "Please check your cables and/or drivers (could be outdated) and that Corsair Utility Engine is running.\n" +
+ "In CUE, make sure \"Enable SDK\" is checked under Global Settings.\n\n" +
+ "If needed, you can select a different keyboard in Artemis under settings.";
+ }
+
+ public ILogger Logger { get; set; }
+
+ public override bool CanEnable()
+ {
+ return CueSDK.IsSDKAvailable(CorsairDeviceType.Keyboard);
+ }
+
+ ///
+ /// Enables the SDK and sets updatemode to manual as well as the color of the background to black.
+ ///
+ public override void Enable()
+ {
+ if (!CueSDK.IsInitialized)
+ CueSDK.Initialize();
+
+ CueSDK.UpdateMode = UpdateMode.Manual;
+ _keyboard = CueSDK.KeyboardSDK;
+ switch (_keyboard.DeviceInfo.Model)
+ {
+ case "K95 RGB":
+ Height = 7;
+ Width = 25;
+ Slug = "corsair-k95-rgb";
+ PreviewSettings = new PreviewSettings(676, 190, new Thickness(0, -15, 0, 0), Resources.k95);
+ break;
+ case "K70 RGB":
+ case "K70 RGB RAPIDFIRE":
+ case "K70 LUX RGB":
+ Height = 7;
+ Width = 21;
+ Slug = "corsair-k70-rgb";
+ PreviewSettings = new PreviewSettings(676, 210, new Thickness(0, -25, 0, 0), Resources.k70);
+ break;
+ case "K65 RGB":
+ case "CGK65 RGB":
+ case "K65 LUX RGB":
+ case "K65 RGB RAPIDFIRE":
+ Height = 7;
+ Width = 18;
+ Slug = "corsair-k65-rgb";
+ PreviewSettings = new PreviewSettings(610, 240, new Thickness(0, -30, 0, 0), Resources.k65);
+ break;
+ case "STRAFE RGB":
+ Height = 7;
+ Width = 22;
+ Slug = "corsair-strafe-rgb";
+ PreviewSettings = new PreviewSettings(665, 215, new Thickness(0, -5, 0, 0), Resources.strafe);
+ break;
+ }
+
+ Logger.Debug("Corsair SDK reported device as: {0}", _keyboard.DeviceInfo.Model);
+ _keyboard.Brush = _keyboardBrush ?? (_keyboardBrush = new ImageBrush());
+ }
+
+ public override void Disable()
+ {
+ try
+ {
+ if (CueSDK.IsInitialized)
+ CueSDK.Reinitialize();
+ }
+ catch (WrapperException e)
+ {
+ // This occurs when releasing the SDK after sleep, ignore it
+ if (e.Message != "The previously loaded Keyboard got disconnected.")
+ throw;
+ }
+ }
+
+ ///
+ /// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap
+ /// size.
+ ///
+ ///
+ public override void DrawBitmap(Bitmap bitmap)
+ {
+ using (var image = ImageUtilities.ResizeImage(bitmap, Width, Height))
+ {
+ // For STRAFE, stretch the image on row 2.
+ if (_keyboard.DeviceInfo.Model == "STRAFE RGB")
+ {
+ using (var strafeBitmap = new Bitmap(22, 8))
+ {
+ using (var g = Graphics.FromImage(strafeBitmap))
+ {
+ g.DrawImage(image, new Point(0, 0));
+ g.DrawImage(image, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7),
+ GraphicsUnit.Pixel);
+
+ _keyboardBrush.Image = strafeBitmap;
+ _keyboard.Update();
+ }
+ }
+ }
+ else
+ {
+ _keyboardBrush.Image = image;
+ _keyboard.Update();
+ }
+ }
+ }
+
+ public override KeyMatch? GetKeyPosition(Keys keyCode)
+ {
+ var widthMultiplier = Width/_keyboard.Brush.RenderedRectangle.Width;
+ var heightMultiplier = Height/_keyboard.Brush.RenderedRectangle.Height;
+
+ CorsairLed cueLed = null;
+ try
+ {
+ cueLed = _keyboard.Leds.FirstOrDefault(k => k.Id.ToString() == keyCode.ToString()) ??
+ _keyboard.Leds.FirstOrDefault(k => k.Id == KeyMap.FormsKeys[keyCode]);
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+
+ if (cueLed == null)
+ return null;
+
+ var center = cueLed.LedRectangle.GetCenter();
+ return new KeyMatch(keyCode, (int) (center.X*widthMultiplier), (int) (center.Y*heightMultiplier));
+ }
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs
index c6586ef31..7e18ba746 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)
{
@@ -22,7 +22,7 @@ namespace Artemis.DeviceProviders.Corsair
{
CanUse = CanInitializeSdk();
if (CanUse && !CueSDK.IsInitialized)
- CueSDK.Initialize(true);
+ CueSDK.Initialize();
Logger.Debug("Attempted to enable Corsair mice. CanUse: {0}", CanUse);
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs
index d39f50fe2..3062862d5 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)
{
@@ -22,7 +22,7 @@ namespace Artemis.DeviceProviders.Corsair
{
CanUse = CanInitializeSdk();
if (CanUse && !CueSDK.IsInitialized)
- CueSDK.Initialize(true);
+ CueSDK.Initialize();
Logger.Debug("Attempted to enable Corsair mousemat. CanUse: {0}", CanUse);
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/Managers/EffectManager.cs b/Artemis/Artemis/Managers/EffectManager.cs
index e8ef40679..5936411dd 100644
--- a/Artemis/Artemis/Managers/EffectManager.cs
+++ b/Artemis/Artemis/Managers/EffectManager.cs
@@ -35,8 +35,8 @@ namespace Artemis.Managers
models.AddRange(overlayModels);
// Add games, exclude WoW if needed
models.AddRange(_generalSettings.GamestatePort != 62575
- ? gameModels.Where(e => e.Name != "WoW")
- : gameModels);
+ ? gameModels.Where(e => e.Name != "WoW").Where(e => e.Name != "LightFX")
+ : gameModels.Where(e => e.Name != "LightFX"));
EffectModels = models;
_logger.Info("Intialized EffectManager");
@@ -72,7 +72,7 @@ namespace Artemis.Managers
///
public IEnumerable EnabledGames
{
- get { return EffectModels.OfType().Where(g => g.Enabled); }
+ get { return EffectModels.OfType().Where(g => g.Enabled && g.Settings.Enabled); }
}
public event EventHandler OnEffectChangedEvent;
@@ -138,14 +138,16 @@ namespace Artemis.Managers
{
if (!wasNull)
ActiveEffect.Dispose();
-
- ActiveEffect = effectModel;
- ActiveEffect.Enable();
- if (!ActiveEffect.Initialized)
+ lock (effectModel)
{
- _logger.Debug("Cancelling effect change, couldn't initialize the effect ({0})", effectModel.Name);
- ActiveEffect = null;
- return;
+ ActiveEffect = effectModel;
+ ActiveEffect.Enable();
+ if (!ActiveEffect.Initialized)
+ {
+ _logger.Debug("Cancelling effect change, couldn't initialize the effect ({0})", effectModel.Name);
+ ActiveEffect = null;
+ return;
+ }
}
}
diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs
index a7c8e3ccc..b0aefca54 100644
--- a/Artemis/Artemis/Managers/LoopManager.cs
+++ b/Artemis/Artemis/Managers/LoopManager.cs
@@ -22,7 +22,6 @@ namespace Artemis.Managers
private readonly EffectManager _effectManager;
private readonly ILogger _logger;
private readonly Timer _loopTimer;
- private bool _canShowException;
public LoopManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager,
DebugViewModel debugViewModel)
@@ -31,7 +30,6 @@ namespace Artemis.Managers
_effectManager = effectManager;
_deviceManager = deviceManager;
_debugViewModel = debugViewModel;
- _canShowException = true;
// Setup timers
_loopTimer = new Timer(40);
diff --git a/Artemis/Artemis/Managers/LuaManager.cs b/Artemis/Artemis/Managers/LuaManager.cs
new file mode 100644
index 000000000..fbd499a8b
--- /dev/null
+++ b/Artemis/Artemis/Managers/LuaManager.cs
@@ -0,0 +1,177 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.DeviceProviders;
+using Artemis.Profiles;
+using Artemis.Profiles.Lua;
+using Artemis.Profiles.Lua.Modules;
+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 readonly Script _luaScript;
+ private List _luaModules;
+
+ 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)
+ {
+ _logger.Debug("Setting up LUA for {0}-{1}.", profileModel?.Name, profileModel?.GameName);
+ // 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("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
+ }
+ catch (SyntaxErrorException e)
+ {
+ _logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
+ }
+ catch (ScriptRuntimeException e)
+ {
+ _logger.Error("[{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("");
+ }
+ }
+
+ ///
+ /// Safely call a function on the active script
+ ///
+ ///
+ ///
+ public void Call(DynValue function, DynValue[] args = null)
+ {
+ if (EventsModule == null)
+ return;
+
+ try
+ {
+ lock (EventsModule.InvokeLock)
+ {
+ lock (_luaScript)
+ {
+ if (args != null)
+ _luaScript.Call(function, args);
+ else
+ _luaScript.Call(function);
+ }
+ }
+ }
+ catch (ArgumentException e)
+ {
+ _logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.Message);
+ }
+ catch (InternalErrorException e)
+ {
+ _logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
+ }
+ catch (SyntaxErrorException e)
+ {
+ _logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
+ }
+ catch (ScriptRuntimeException e)
+ {
+ _logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
+ }
+ }
+
+ #region Private lua functions
+
+ private void LuaPrint(string s)
+ {
+ _logger.Info("[{0}-LUA]: {1}", ProfileModel?.Name, s);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Managers/MainManager.cs b/Artemis/Artemis/Managers/MainManager.cs
index f9a8adb04..68a50fd42 100644
--- a/Artemis/Artemis/Managers/MainManager.cs
+++ b/Artemis/Artemis/Managers/MainManager.cs
@@ -1,5 +1,4 @@
using System;
-using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
@@ -10,6 +9,7 @@ using Artemis.Utilities;
using Artemis.Utilities.DataReaders;
using Artemis.Utilities.GameState;
using Artemis.ViewModels;
+using Microsoft.Win32;
using Ninject;
using Ninject.Extensions.Logging;
@@ -51,6 +51,9 @@ namespace Artemis.Managers
var updateTask = new Task(Updater.UpdateApp);
updateTask.Start();
+ // Listen for power mode changes
+ SystemEvents.PowerModeChanged += OnPowerChange;
+
Logger.Info("Intialized MainManager");
Logger.Info($"Artemis version {Assembly.GetExecutingAssembly().GetName().Version} is ready!");
}
@@ -83,6 +86,23 @@ namespace Artemis.Managers
public event EventHandler OnEnabledChangedEvent;
+ ///
+ /// Restarts the loop manager when the system resumes
+ ///
+ ///
+ ///
+ private async void OnPowerChange(object sender, PowerModeChangedEventArgs e)
+ {
+ if (e.Mode != PowerModes.Resume)
+ return;
+
+ Logger.Debug("Restarting for OnPowerChange");
+ DisableProgram();
+ // Wait an extra while for device providers to be fully ready
+ await Task.Delay(2000);
+ EnableProgram();
+ }
+
///
/// Loads the last active effect and starts the program
///
@@ -124,13 +144,11 @@ namespace Artemis.Managers
// If the currently active effect is a no longer running game, get rid of it.
var activeGame = EffectManager.ActiveEffect as GameModel;
if (activeGame != null)
- {
if (!runningProcesses.Any(p => p.ProcessName == activeGame.ProcessName && p.HasExited == false))
{
Logger.Info("Disabling game: {0}", activeGame.Name);
EffectManager.DisableGame(activeGame);
}
- }
// Look for running games, stopping on the first one that's found.
var newGame = EffectManager.EnabledGames
diff --git a/Artemis/Artemis/Models/EffectModel.cs b/Artemis/Artemis/Models/EffectModel.cs
index eb1552d00..a2dd083df 100644
--- a/Artemis/Artemis/Models/EffectModel.cs
+++ b/Artemis/Artemis/Models/EffectModel.cs
@@ -23,26 +23,26 @@ 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;
- // If set, load the last profile from settings
- if (!string.IsNullOrEmpty(Settings?.LastProfile))
- Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, Settings.LastProfile);
-
DeviceManager.OnKeyboardChangedEvent += DeviceManagerOnOnKeyboardChangedEvent;
}
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;
// Used by profile system
public IDataModel DataModel { get; set; }
+
public ProfileModel Profile { get; set; }
[Inject]
@@ -50,17 +50,34 @@ namespace Artemis.Models
public virtual void Dispose()
{
- Profile?.Deactivate();
+ Profile?.Deactivate(LuaManager);
+ Profile = null;
}
private void DeviceManagerOnOnKeyboardChangedEvent(object sender, KeyboardChangedEventArgs args)
{
+ if (!Initialized)
+ return;
+
if (!string.IsNullOrEmpty(Settings?.LastProfile))
Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, Settings.LastProfile);
+ else
+ Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, "Default");
+
+ Profile?.Activate(LuaManager);
}
// Called on creation
- public abstract void Enable();
+ public virtual void Enable()
+ {
+ // If set, load the last profile from settings
+ if (!string.IsNullOrEmpty(Settings?.LastProfile))
+ Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, Settings.LastProfile);
+ else
+ Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, "Default");
+
+ Profile?.Activate(LuaManager);
+ }
// Called every frame
public abstract void Update();
@@ -73,9 +90,9 @@ namespace Artemis.Models
///
public virtual void Render(RenderFrame frame, bool keyboardOnly)
{
- if ((Profile == null) || (DataModel == null) || (DeviceManager.ActiveKeyboard == null))
+ if (Profile == null || DataModel == null || DeviceManager.ActiveKeyboard == null)
return;
-
+
lock (DataModel)
{
lock (Profile)
@@ -85,7 +102,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..6fd367001 100644
--- a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
+++ b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
@@ -1,262 +1,275 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Artemis.DAL;
-using Artemis.Managers;
-using Artemis.Models;
-using Artemis.Profiles.Layers.Models;
-using Artemis.Utilities;
-using Newtonsoft.Json;
-using SpotifyAPI.Local;
-
-namespace Artemis.Modules.Effects.WindowsProfile
-{
- public class WindowsProfileModel : EffectModel
- {
- private List _cores;
- private int _cpuFrames;
- private DateTime _lastMusicUpdate;
- private PerformanceCounter _overallCpu;
- private SpotifyLocalAPI _spotify;
- private bool _spotifySetupBusy;
-
- public WindowsProfileModel(DeviceManager deviceManager)
- : base(deviceManager, SettingsProvider.Load(), new WindowsProfileDataModel())
- {
- _lastMusicUpdate = DateTime.Now;
-
- Name = "WindowsProfile";
- }
-
- public override void Dispose()
- {
- Initialized = false;
- base.Dispose();
- }
-
- public override void Enable()
- {
- SetupCpu();
- SetupSpotify();
-
- Initialized = true;
- }
-
- public override void Update()
- {
- var dataModel = (WindowsProfileDataModel) DataModel;
- UpdateCpu(dataModel);
- UpdateMusicPlayers(dataModel);
- UpdateDay(dataModel);
- UpdateKeyStates(dataModel);
- UpdateActiveWindow(dataModel);
- }
-
- #region Current Time
-
- private void UpdateDay(WindowsProfileDataModel dataModel)
- {
- var now = DateTime.Now;
- dataModel.CurrentTime.Hours24 = int.Parse(now.ToString("HH"));
- dataModel.CurrentTime.Hours12 = int.Parse(now.ToString("hh"));
- dataModel.CurrentTime.Minutes = int.Parse(now.ToString("mm"));
- dataModel.CurrentTime.Seconds = int.Parse(now.ToString("ss"));
- }
-
- #endregion
-
- #region CPU
-
- private void SetupCpu()
- {
- try
- {
- _cores = GetPerformanceCounters();
- var coreCount = _cores.Count;
- while (coreCount < 8)
- {
- _cores.Add(null);
- coreCount++;
- }
- _overallCpu = GetOverallPerformanceCounter();
- }
- catch (InvalidOperationException)
- {
- Logger?.Warn("Failed to setup CPU information, try running \"lodctr /R\" as administrator.");
- }
- }
-
- private void UpdateCpu(WindowsProfileDataModel dataModel)
- {
- if ((_cores == null) || (_overallCpu == null))
- return;
-
- // CPU is only updated every 15 frames, the performance counter gives 0 if updated too often
- _cpuFrames++;
- if (_cpuFrames < 16)
- return;
-
- _cpuFrames = 0;
-
- // Update cores, not ideal but data models don't support lists.
- if (_cores[0] != null)
- dataModel.Cpu.Core1Usage = (int) _cores[0].NextValue();
- if (_cores[1] != null)
- dataModel.Cpu.Core2Usage = (int) _cores[1].NextValue();
- if (_cores[2] != null)
- dataModel.Cpu.Core3Usage = (int) _cores[2].NextValue();
- if (_cores[3] != null)
- dataModel.Cpu.Core4Usage = (int) _cores[3].NextValue();
- if (_cores[4] != null)
- dataModel.Cpu.Core5Usage = (int) _cores[4].NextValue();
- if (_cores[5] != null)
- dataModel.Cpu.Core6Usage = (int) _cores[5].NextValue();
- if (_cores[6] != null)
- dataModel.Cpu.Core7Usage = (int) _cores[6].NextValue();
- if (_cores[7] != null)
- dataModel.Cpu.Core8Usage = (int) _cores[7].NextValue();
-
- //From Ted - Let's get overall RAM and CPU usage here
- dataModel.Cpu.TotalUsage = (int) _overallCpu.NextValue();
-
- var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
- var tot = PerformanceInfo.GetTotalMemoryInMiB();
- var percentFree = phav/(decimal) tot*100;
- var percentOccupied = 100 - percentFree;
-
- dataModel.Performance.RAMUsage = (int) percentOccupied;
- }
-
- public override List GetRenderLayers(bool keyboardOnly)
- {
- return Profile.GetRenderLayers(DataModel, keyboardOnly, false);
- }
-
- public static PerformanceCounter GetOverallPerformanceCounter()
- {
- var cpuCounter = new PerformanceCounter
- {
- CategoryName = "Processor",
- CounterName = "% Processor Time",
- InstanceName = "_Total"
- };
-
- return cpuCounter;
- }
-
- public static List GetPerformanceCounters()
- {
- var performanceCounters = new List();
- var procCount = Environment.ProcessorCount;
- for (var i = 0; i < procCount; i++)
- {
- var pc = new PerformanceCounter("Processor", "% Processor Time", i.ToString());
- performanceCounters.Add(pc);
- }
- return performanceCounters;
- }
-
- #endregion
-
- #region Music
-
- public void SetupSpotify()
- {
- if (_spotifySetupBusy)
- return;
-
- _spotifySetupBusy = true;
- _spotify = new SpotifyLocalAPI();
-
- // Connecting can sometimes use a little bit more conviction
- Task.Factory.StartNew(() =>
- {
- var tryCount = 0;
- while (tryCount <= 10)
- {
- tryCount++;
- var connected = _spotify.Connect();
- if (connected)
- break;
- Thread.Sleep(1000);
- }
- _spotifySetupBusy = false;
- });
- }
-
- public void UpdateMusicPlayers(WindowsProfileDataModel dataModel)
- {
- // This is quite resource hungry so only update it once every two seconds
- if (DateTime.Now - _lastMusicUpdate < TimeSpan.FromSeconds(2))
- return;
- _lastMusicUpdate = DateTime.Now;
-
- UpdateSpotify(dataModel);
- UpdateGooglePlayMusic(dataModel);
- }
-
- private void UpdateSpotify(WindowsProfileDataModel dataModel)
- {
- // Spotify
- if (!dataModel.Spotify.Running && SpotifyLocalAPI.IsSpotifyRunning())
- SetupSpotify();
-
- var status = _spotify.GetStatus();
- if (status == null)
- return;
-
- dataModel.Spotify.Playing = status.Playing;
- dataModel.Spotify.Running = SpotifyLocalAPI.IsSpotifyRunning();
-
- if (status.Track != null)
- {
- dataModel.Spotify.Artist = status.Track.ArtistResource?.Name;
- dataModel.Spotify.SongName = status.Track.TrackResource?.Name;
- dataModel.Spotify.Album = status.Track.AlbumResource?.Name;
- dataModel.Spotify.SongLength = status.Track.Length;
- }
-
- if (dataModel.Spotify.SongLength > 0)
- dataModel.Spotify.SongPercentCompleted =
- (int) (status.PlayingPosition/dataModel.Spotify.SongLength*100.0);
- }
-
- private void UpdateGooglePlayMusic(WindowsProfileDataModel dataModel)
- {
- // Google Play Music
- var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- var json = appData + @"\Google Play Music Desktop Player\json_store\playback.json";
- if (!File.Exists(json))
- return;
-
- dataModel.GooglePlayMusic = JsonConvert.DeserializeObject(File.ReadAllText(json));
- }
-
- #endregion
-
- #region System
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true,
- 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;
- }
-
- private void UpdateActiveWindow(WindowsProfileDataModel dataModel)
- {
- dataModel.ActiveWindow.ProcessName = ActiveWindowHelper.ActiveWindowProcessName;
- dataModel.ActiveWindow.WindowTitle = ActiveWindowHelper.ActiveWindowWindowTitle;
- }
-
- #endregion
- }
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Artemis.DAL;
+using Artemis.Managers;
+using Artemis.Models;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Utilities;
+using Newtonsoft.Json;
+using SpotifyAPI.Local;
+
+namespace Artemis.Modules.Effects.WindowsProfile
+{
+ public class WindowsProfileModel : EffectModel
+ {
+ private List _cores;
+ private int _cpuFrames;
+ private DateTime _lastMusicUpdate;
+ private PerformanceCounter _overallCpu;
+ private SpotifyLocalAPI _spotify;
+ private bool _spotifySetupBusy;
+
+ public WindowsProfileModel(DeviceManager deviceManager, LuaManager luaManager)
+ : base(deviceManager, luaManager, SettingsProvider.Load(),
+ new WindowsProfileDataModel())
+ {
+ _lastMusicUpdate = DateTime.Now;
+
+ Name = "WindowsProfile";
+ }
+
+ public override void Dispose()
+ {
+ Initialized = false;
+ base.Dispose();
+ }
+
+ public override void Enable()
+ {
+ base.Enable();
+
+ SetupCpu();
+ SetupSpotify();
+
+ Initialized = true;
+ }
+
+ public override void Update()
+ {
+ var dataModel = (WindowsProfileDataModel) DataModel;
+ UpdateCpu(dataModel);
+ UpdateMusicPlayers(dataModel);
+ UpdateDay(dataModel);
+ UpdateKeyStates(dataModel);
+ UpdateActiveWindow(dataModel);
+ }
+
+ #region Current Time
+
+ private void UpdateDay(WindowsProfileDataModel dataModel)
+ {
+ var now = DateTime.Now;
+ dataModel.CurrentTime.Hours24 = int.Parse(now.ToString("HH"));
+ dataModel.CurrentTime.Hours12 = int.Parse(now.ToString("hh"));
+ dataModel.CurrentTime.Minutes = int.Parse(now.ToString("mm"));
+ dataModel.CurrentTime.Seconds = int.Parse(now.ToString("ss"));
+ }
+
+ #endregion
+
+ #region CPU
+
+ private void SetupCpu()
+ {
+ try
+ {
+ _cores = GetPerformanceCounters();
+ var coreCount = _cores.Count;
+ while (coreCount < 8)
+ {
+ _cores.Add(null);
+ coreCount++;
+ }
+ _overallCpu = GetOverallPerformanceCounter();
+ }
+ catch (InvalidOperationException)
+ {
+ Logger?.Warn("Failed to setup CPU information, try running \"lodctr /R\" as administrator.");
+ }
+ }
+
+ private void UpdateCpu(WindowsProfileDataModel dataModel)
+ {
+ if ((_cores == null) || (_overallCpu == null))
+ return;
+
+ // CPU is only updated every 15 frames, the performance counter gives 0 if updated too often
+ _cpuFrames++;
+ if (_cpuFrames < 16)
+ return;
+
+ _cpuFrames = 0;
+
+ // Update cores, not ideal but data models don't support lists.
+ if (_cores[0] != null)
+ dataModel.Cpu.Core1Usage = (int) _cores[0].NextValue();
+ if (_cores[1] != null)
+ dataModel.Cpu.Core2Usage = (int) _cores[1].NextValue();
+ if (_cores[2] != null)
+ dataModel.Cpu.Core3Usage = (int) _cores[2].NextValue();
+ if (_cores[3] != null)
+ dataModel.Cpu.Core4Usage = (int) _cores[3].NextValue();
+ if (_cores[4] != null)
+ dataModel.Cpu.Core5Usage = (int) _cores[4].NextValue();
+ if (_cores[5] != null)
+ dataModel.Cpu.Core6Usage = (int) _cores[5].NextValue();
+ if (_cores[6] != null)
+ dataModel.Cpu.Core7Usage = (int) _cores[6].NextValue();
+ if (_cores[7] != null)
+ dataModel.Cpu.Core8Usage = (int) _cores[7].NextValue();
+
+ //From Ted - Let's get overall RAM and CPU usage here
+ dataModel.Cpu.TotalUsage = (int) _overallCpu.NextValue();
+
+ var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
+ var tot = PerformanceInfo.GetTotalMemoryInMiB();
+ var percentFree = phav / (decimal) tot * 100;
+ var percentOccupied = 100 - percentFree;
+
+ dataModel.Performance.RAMUsage = (int) percentOccupied;
+ }
+
+ public override List GetRenderLayers(bool keyboardOnly)
+ {
+ return Profile.GetRenderLayers(DataModel, keyboardOnly, false);
+ }
+
+ public static PerformanceCounter GetOverallPerformanceCounter()
+ {
+ var cpuCounter = new PerformanceCounter
+ {
+ CategoryName = "Processor",
+ CounterName = "% Processor Time",
+ InstanceName = "_Total"
+ };
+
+ return cpuCounter;
+ }
+
+ public static List GetPerformanceCounters()
+ {
+ var performanceCounters = new List();
+ var procCount = Environment.ProcessorCount;
+ for (var i = 0; i < procCount; i++)
+ {
+ var pc = new PerformanceCounter("Processor", "% Processor Time", i.ToString());
+ performanceCounters.Add(pc);
+ }
+ return performanceCounters;
+ }
+
+ #endregion
+
+ #region Music
+
+ public void SetupSpotify()
+ {
+ if (_spotifySetupBusy)
+ return;
+
+ _spotifySetupBusy = true;
+ _spotify = new SpotifyLocalAPI();
+
+ // Connecting can sometimes use a little bit more conviction
+ Task.Factory.StartNew(() =>
+ {
+ var tryCount = 0;
+ while (tryCount <= 10)
+ {
+ // Causes WebException if not internet connection is available
+ try
+ {
+ tryCount++;
+ var connected = _spotify.Connect();
+ if (connected)
+ break;
+ Thread.Sleep(1000);
+ }
+ catch (WebException)
+ {
+ break;
+ }
+
+ }
+ _spotifySetupBusy = false;
+ });
+ }
+
+ public void UpdateMusicPlayers(WindowsProfileDataModel dataModel)
+ {
+ // This is quite resource hungry so only update it once every two seconds
+ if (DateTime.Now - _lastMusicUpdate < TimeSpan.FromSeconds(2))
+ return;
+ _lastMusicUpdate = DateTime.Now;
+
+ UpdateSpotify(dataModel);
+ UpdateGooglePlayMusic(dataModel);
+ }
+
+ private void UpdateSpotify(WindowsProfileDataModel dataModel)
+ {
+ // Spotify
+ if (!dataModel.Spotify.Running && SpotifyLocalAPI.IsSpotifyRunning())
+ SetupSpotify();
+
+ var status = _spotify.GetStatus();
+ if (status == null)
+ return;
+
+ dataModel.Spotify.Playing = status.Playing;
+ dataModel.Spotify.Running = SpotifyLocalAPI.IsSpotifyRunning();
+
+ if (status.Track != null)
+ {
+ dataModel.Spotify.Artist = status.Track.ArtistResource?.Name;
+ dataModel.Spotify.SongName = status.Track.TrackResource?.Name;
+ dataModel.Spotify.Album = status.Track.AlbumResource?.Name;
+ dataModel.Spotify.SongLength = status.Track.Length;
+ }
+
+ if (dataModel.Spotify.SongLength > 0)
+ dataModel.Spotify.SongPercentCompleted =
+ (int) (status.PlayingPosition / dataModel.Spotify.SongLength * 100.0);
+ }
+
+ private void UpdateGooglePlayMusic(WindowsProfileDataModel dataModel)
+ {
+ // Google Play Music
+ var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ var json = appData + @"\Google Play Music Desktop Player\json_store\playback.json";
+ if (!File.Exists(json))
+ return;
+
+ dataModel.GooglePlayMusic = JsonConvert.DeserializeObject(File.ReadAllText(json));
+ }
+
+ #endregion
+
+ #region System
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true,
+ 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;
+ }
+
+ private void UpdateActiveWindow(WindowsProfileDataModel dataModel)
+ {
+ dataModel.ActiveWindow.ProcessName = ActiveWindowHelper.ActiveWindowProcessName;
+ dataModel.ActiveWindow.WindowTitle = ActiveWindowHelper.ActiveWindowWindowTitle;
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileViewModel.cs b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileViewModel.cs
index e39b96325..1f16bd4b4 100644
--- a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileViewModel.cs
+++ b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileViewModel.cs
@@ -22,7 +22,7 @@ namespace Artemis.Modules.Effects.WindowsProfile
IParameter[] args =
{
new ConstructorArgument("mainManager", main),
- new ConstructorArgument("gameModel", (WindowsProfileModel) EffectModel),
+ new ConstructorArgument("effectModel", (WindowsProfileModel) EffectModel),
new ConstructorArgument("lastProfile", ((WindowsProfileSettings) EffectSettings).LastProfile)
};
ProfileEditor = kernel.Get(args);
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
index 452f2d51e..cb4ffe5a4 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;
@@ -51,6 +52,8 @@ namespace Artemis.Modules.Games.CounterStrike
public override void Enable()
{
+ base.Enable();
+
_gameStateWebServer.GameDataReceived += HandleGameData;
Initialized = true;
}
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
index 8029a5da3..f482bc71b 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;
@@ -45,6 +45,8 @@ namespace Artemis.Modules.Games.Dota2
public override void Enable()
{
+ base.Enable();
+
_gameStateWebServer.GameDataReceived += HandleGameData;
Initialized = true;
}
@@ -109,8 +111,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..1a9409b1a 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";
@@ -42,6 +43,8 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
public override void Enable()
{
+ base.Enable();
+
Initialized = true;
}
diff --git a/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs b/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs
index 20c185ee9..1dd4293f2 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";
@@ -27,6 +27,8 @@ namespace Artemis.Modules.Games.GtaV
public override void Enable()
{
+ base.Enable();
+
DllManager.PlaceLogitechDll();
_pipeServer.PipeMessage += PipeServerOnPipeMessage;
Initialized = true;
diff --git a/Artemis/Artemis/Modules/Games/LightFx/Data/LightFxState.cs b/Artemis/Artemis/Modules/Games/LightFx/Data/LightFxState.cs
new file mode 100644
index 000000000..287b8d075
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/LightFx/Data/LightFxState.cs
@@ -0,0 +1,40 @@
+using MoonSharp.Interpreter;
+
+namespace Artemis.Modules.Games.LightFx.Data
+{
+ [MoonSharpUserData]
+ public class LightFxState
+ {
+ public Device[] devices { get; set; }
+ public string game { get; set; }
+ public Mask mask { get; set; }
+ }
+
+ [MoonSharpUserData]
+ public class Device
+ {
+ public Light[] lights { get; set; }
+ }
+
+ [MoonSharpUserData]
+ public class Mask
+ {
+ public Light light { get; set; }
+ public int location { get; set; }
+ }
+
+ [MoonSharpUserData]
+ public class Light
+ {
+ public Color color { get; set; }
+ }
+
+ [MoonSharpUserData]
+ public class Color
+ {
+ public int brightness { get; set; }
+ public int red { get; set; }
+ public int green { get; set; }
+ public int blue { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxDataModel.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxDataModel.cs
new file mode 100644
index 000000000..aa86630e2
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxDataModel.cs
@@ -0,0 +1,19 @@
+using Artemis.Models.Interfaces;
+using Artemis.Modules.Games.LightFx.Data;
+using MoonSharp.Interpreter;
+using Newtonsoft.Json;
+
+namespace Artemis.Modules.Games.LightFx
+{
+ [MoonSharpUserData]
+ public class LightFxDataModel : IDataModel
+ {
+ [JsonProperty(PropertyName = "lightFxState")]
+ public LightFxState LightFxState { get; set; }
+
+ public LightFxDataModel()
+ {
+ LightFxState = new LightFxState();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
new file mode 100644
index 000000000..3d77bc907
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Artemis.DAL;
+using Artemis.Managers;
+using Artemis.Models;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Utilities.DataReaders;
+using Newtonsoft.Json;
+
+namespace Artemis.Modules.Games.LightFx
+{
+ public class LightFxModel : GameModel
+ {
+ public LightFxModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
+ : base(deviceManager, luaManager, SettingsProvider.Load(), new LightFxDataModel())
+ {
+ Name = "LightFX";
+ ProcessName = "LoL";
+ Scale = 4;
+ Enabled = Settings.Enabled;
+ Initialized = false;
+
+ // This model can enable itself by changing its process name to the currently running Light FX game.
+ pipeServer.PipeMessage += PipeServerOnPipeMessage;
+ }
+
+ public int Scale { get; set; }
+
+ private void PipeServerOnPipeMessage(string msg)
+ {
+ // Ensure it's Light FX JSON
+ if (!msg.Contains("lightFxState"))
+ return;
+
+ // Deserialize and data
+ try
+ {
+ JsonConvert.PopulateObject(msg, DataModel);
+ }
+ catch (Exception ex)
+ {
+ Logger?.Error(ex, "Failed to deserialize LightFX JSON");
+ throw;
+ }
+
+ // Setup process name
+ ProcessName = Path.GetFileNameWithoutExtension(((LightFxDataModel) DataModel).LightFxState.game);
+ }
+
+ public override void Dispose()
+ {
+ Initialized = false;
+ base.Dispose();
+ }
+
+ public override void Enable()
+ {
+ base.Enable();
+
+ Initialized = true;
+ }
+
+ public override void Update()
+ {
+ }
+
+ public override List GetRenderLayers(bool keyboardOnly)
+ {
+ return Profile.GetRenderLayers(DataModel, keyboardOnly);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxSettings.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxSettings.cs
new file mode 100644
index 000000000..a1f31124a
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxSettings.cs
@@ -0,0 +1,8 @@
+using Artemis.Settings;
+
+namespace Artemis.Modules.Games.LightFx
+{
+ public class LightFxSettings : GameSettings
+ {
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml b/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml
new file mode 100644
index 000000000..19e045370
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml.cs
new file mode 100644
index 000000000..6adb4506e
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml.cs
@@ -0,0 +1,18 @@
+using System.Windows.Controls;
+using System.Windows.Navigation;
+
+namespace Artemis.Modules.Games.LightFx
+{
+ public partial class LightFxView : UserControl
+ {
+ public LightFxView()
+ {
+ InitializeComponent();
+ }
+
+ private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
+ {
+ System.Diagnostics.Process.Start(e.Uri.ToString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs
new file mode 100644
index 000000000..23ab9c59b
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs
@@ -0,0 +1,16 @@
+using Artemis.Managers;
+using Artemis.Models;
+using Artemis.ViewModels.Abstract;
+using Ninject;
+
+namespace Artemis.Modules.Games.LightFx
+{
+ public sealed class LightFxViewModel : GameViewModel
+ {
+ public LightFxViewModel(MainManager main, IKernel kernel,
+ [Named("LightFxModel")] GameModel model) : base(main, model, kernel)
+ {
+ DisplayName = "Light FX";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
index 7f53834eb..f2d860ca2 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;
@@ -82,6 +82,8 @@ namespace Artemis.Modules.Games.Overwatch
public override void Enable()
{
+ base.Enable();
+
_stickyStatus = new StickyValue(300);
_stickyUltimateReady = new StickyValue(350);
_stickyUltimateUsed = new StickyValue(350);
@@ -240,7 +242,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 +294,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/Data/_pCarsAPIStruct/pCarsAPI-ReadAPI.cs b/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIStruct/pCarsAPI-ReadAPI.cs
index 1a96c74b5..8412d7363 100644
--- a/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIStruct/pCarsAPI-ReadAPI.cs
+++ b/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIStruct/pCarsAPI-ReadAPI.cs
@@ -7,12 +7,10 @@ namespace Artemis.Modules.Games.ProjectCars.Data
{
public class pCarsAPI_GetData
{
- private static pCarsAPIStruct structCurrent = new pCarsAPIStruct();
private static MemoryMappedFile memoryMappedFile;
private static GCHandle handle;
private static int sharedmemorysize;
private static byte[] sharedMemoryReadBuffer;
- private static bool isSharedMemoryInitialised;
private static bool InitialiseSharedMemory()
{
@@ -21,11 +19,10 @@ namespace Artemis.Modules.Games.ProjectCars.Data
memoryMappedFile = MemoryMappedFile.OpenExisting("$pcars$");
sharedmemorysize = Marshal.SizeOf(typeof(pCarsAPIStruct));
sharedMemoryReadBuffer = new byte[sharedmemorysize];
- isSharedMemoryInitialised = true;
return true;
}
- catch (Exception ex)
+ catch (Exception)
{
return false;
}
@@ -42,8 +39,8 @@ namespace Artemis.Modules.Games.ProjectCars.Data
using (var sharedMemoryStreamView = memoryMappedFile.CreateViewStream())
{
- var _SharedMemoryStream = new BinaryReader(sharedMemoryStreamView);
- sharedMemoryReadBuffer = _SharedMemoryStream.ReadBytes(sharedmemorysize);
+ var sharedMemoryStream = new BinaryReader(sharedMemoryStreamView);
+ sharedMemoryReadBuffer = sharedMemoryStream.ReadBytes(sharedmemorysize);
handle = GCHandle.Alloc(sharedMemoryReadBuffer, GCHandleType.Pinned);
_pcarsapistruct =
(pCarsAPIStruct) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(pCarsAPIStruct));
@@ -52,7 +49,7 @@ namespace Artemis.Modules.Games.ProjectCars.Data
return new Tuple(true, _pcarsapistruct);
}
- catch (Exception ex)
+ catch (Exception)
{
//return false in the tuple as the read failed
return new Tuple(false, _pcarsapistruct);
diff --git a/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsModel.cs b/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsModel.cs
index aa82cf26f..c1bb99c98 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";
@@ -39,6 +33,8 @@ namespace Artemis.Modules.Games.ProjectCars
public override void Enable()
{
+ base.Enable();
+
Initialized = true;
}
@@ -49,10 +45,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/ProjectCars/ProjectCarsView.xaml b/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsView.xaml
index 86adeed7d..0fd088dd3 100644
--- a/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsView.xaml
+++ b/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsView.xaml
@@ -16,7 +16,6 @@
-
@@ -32,19 +31,19 @@
- The Euro Truck Simulator 2 module uses code from the
+ The Project CARS module uses code from the
- ETS2 Telemetry Web Server
+ NavigateUri="https://bitbucket.org/MikeyTT/pcars-api-demo">
+ pCars API Demo
- project by Funbit
+ project by MikeyTT
@@ -55,26 +54,11 @@
-
-
-
-
-
-
-
-
-
-
+
-
+