1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Merge pull request #258 from SpoinkyNL/development

1.7.1
This commit is contained in:
Robert Beekman 2017-01-01 11:58:54 +01:00 committed by GitHub
commit e8d83d8c53
111 changed files with 15568 additions and 1938 deletions

3
.gitignore vendored
View File

@ -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

View File

@ -191,9 +191,6 @@
<HintPath>..\packages\MahApps.Metro.1.3.0\lib\net45\MahApps.Metro.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.QualityTools.Testing.Fakes, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
<Private>True</Private>
@ -339,11 +336,9 @@
<Compile Include="Events\EffectChangedEventArgs.cs" />
<Compile Include="Events\EnabledChangedEventArgs.cs" />
<Compile Include="Events\KeyboardChangedEventArgs.cs" />
<Compile Include="Events\ProfileDeviceEventsArg.cs" />
<Compile Include="Events\RazerColorArrayChanged.cs" />
<Compile Include="Events\RazerColorsChangedEventArgs.cs" />
<Compile Include="InjectionModules\DeviceModules.cs" />
<Compile Include="InjectionModules\EffectModules.cs" />
<Compile Include="InjectionModules\ProfileModules.cs" />
<Compile Include="ItemBehaviours\BindableSelectedItemBehavior.cs" />
<Compile Include="DeviceProviders\Corsair\CorsairKeyboard.cs" />
<Compile Include="DeviceProviders\KeyboardProvider.cs" />
@ -357,6 +352,7 @@
<Compile Include="Managers\EffectManager.cs" />
<Compile Include="Managers\DeviceManager.cs" />
<Compile Include="Managers\LoopManager.cs" />
<Compile Include="Managers\LuaManager.cs" />
<Compile Include="Managers\MainManager.cs" />
<Compile Include="Managers\ProfileManager.cs" />
<Compile Include="Models\EffectModel.cs" />
@ -382,6 +378,14 @@
<DependentUpon>GtaVView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Games\GtaV\GtaVViewModel.cs" />
<Compile Include="Modules\Games\LightFx\Data\LightFxState.cs" />
<Compile Include="Modules\Games\LightFx\LightFxDataModel.cs" />
<Compile Include="Modules\Games\LightFx\LightFxModel.cs" />
<Compile Include="Modules\Games\LightFx\LightFxSettings.cs" />
<Compile Include="Modules\Games\LightFx\LightFxView.xaml.cs">
<DependentUpon>LightFxView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Games\LightFx\LightFxViewModel.cs" />
<Compile Include="Modules\Games\ProjectCars\Data\_eNums\eAPIStructLengths.cs" />
<Compile Include="Modules\Games\ProjectCars\Data\_eNums\eCarFlags.cs" />
<Compile Include="Modules\Games\ProjectCars\Data\_eNums\eCrashDamageState.cs" />
@ -499,22 +503,25 @@
</Compile>
<Compile Include="Profiles\Layers\Types\Mousemat\MousematPropertiesViewModel.cs" />
<Compile Include="Profiles\Layers\Types\Mousemat\MousematType.cs" />
<Compile Include="Profiles\LuaMouseWrapper.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaBrush.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaColor.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaLinearGradientBrush.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaRadialGradientBrush.cs" />
<Compile Include="Profiles\Lua\Events\LuaKeyPressEventArgs.cs" />
<Compile Include="Profiles\Lua\Events\LuaDeviceDrawingEventArgs.cs" />
<Compile Include="Profiles\Lua\Events\LuaDeviceUpdatingEventArgs.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaBrushWrapper.cs" />
<Compile Include="Profiles\Lua\LuaDrawWrapper.cs" />
<Compile Include="Profiles\Lua\Events\LuaEventsWrapper.cs" />
<Compile Include="Profiles\Lua\LuaKeyboardWrapper.cs" />
<Compile Include="Profiles\Lua\LuaLayerWrapper.cs" />
<Compile Include="Profiles\Lua\LuaProfileWrapper.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaSolidColorBrush.cs" />
<Compile Include="Profiles\Lua\LuaWrapper.cs" />
<Compile Include="Profiles\Lua\Modules\Brushes\LuaBrush.cs" />
<Compile Include="Profiles\Lua\Modules\Brushes\LuaColor.cs" />
<Compile Include="Profiles\Lua\Modules\Brushes\LuaLinearGradientBrush.cs" />
<Compile Include="Profiles\Lua\Modules\Brushes\LuaRadialGradientBrush.cs" />
<Compile Include="Profiles\Lua\Modules\Events\LuaKeyPressEventArgs.cs" />
<Compile Include="Profiles\Lua\Modules\Events\LuaDeviceDrawingEventArgs.cs" />
<Compile Include="Profiles\Lua\Modules\Events\LuaDeviceUpdatingEventArgs.cs" />
<Compile Include="Profiles\Lua\Modules\LuaEventsModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaBrushesModule.cs" />
<Compile Include="Profiles\Lua\LuaModule.cs" />
<Compile Include="Profiles\Lua\Modules\Brushes\LuaSolidColorBrush.cs" />
<Compile Include="Profiles\Lua\Modules\LuaKeyboardModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaLayerModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaMouseModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaProfileModule.cs" />
<Compile Include="Profiles\Lua\Modules\Timer\LuaTimer.cs" />
<Compile Include="Profiles\Lua\Modules\LuaTimerModule.cs" />
<Compile Include="Profiles\Lua\Wrappers\LuaDrawWrapper.cs" />
<Compile Include="Profiles\Lua\Wrappers\LuaLayerWrapper.cs" />
<Compile Include="Profiles\ProfileModel.cs" />
<Compile Include="Profiles\Layers\Models\SimplePropertiesModel.cs" />
<Compile Include="Profiles\Layers\Types\Keyboard\KeyboardPropertiesModel.cs" />
@ -837,6 +844,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Games\LightFx\LightFxView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Modules\Games\Overwatch\OverwatchView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -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<IWindowManager>().To<WindowManager>().InSingletonScope();
_kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}
/// <summary>
/// Enables the SDK and sets updatemode to manual as well as the color of the background to black.
/// </summary>
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();
}
/// <summary>
/// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap
/// size.
/// </summary>
/// <param name="bitmap"></param>
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);
}
/// <summary>
/// Enables the SDK and sets updatemode to manual as well as the color of the background to black.
/// </summary>
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;
}
}
/// <summary>
/// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap
/// size.
/// </summary>
/// <param name="bitmap"></param>
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));
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -8,7 +8,7 @@ using Artemis.Settings;
namespace Artemis.DeviceProviders.Logitech
{
internal class G810 : LogitechKeyboard
public class G810 : LogitechKeyboard
{
private GeneralSettings _generalSettings;

View File

@ -10,7 +10,7 @@ using Artemis.Settings;
namespace Artemis.DeviceProviders.Logitech
{
internal class G910 : LogitechKeyboard
public class G910 : LogitechKeyboard
{
private readonly GeneralSettings _generalSettings;

View File

@ -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; }
}
}

View File

@ -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<ShellViewModel>().ToSelf().InSingletonScope();
Bind<ProfileViewModel>().ToSelf();
Bind<ProfileEditorViewModel>().ToSelf();
Bind<DebugViewModel>().ToSelf().InSingletonScope();
Bind<BaseViewModel>().To<WelcomeViewModel>();
Bind<BaseViewModel>().To<EffectsViewModel>();
Bind<BaseViewModel>().To<GamesViewModel>();
Bind<BaseViewModel>().To<OverlaysViewModel>();
// Models
Bind<ProfilePreviewModel>().ToSelf().InSingletonScope();
// Services
Bind<MetroDialogService>().ToSelf().InSingletonScope();
Bind<WindowService>().ToSelf().InSingletonScope();
// Servers
Bind<GameStateWebServer>().ToSelf().InSingletonScope();
Bind<PipeServer>().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<ShellViewModel>().ToSelf().InSingletonScope();
Bind<ProfileViewModel>().ToSelf();
Bind<ProfileEditorViewModel>().ToSelf();
Bind<DebugViewModel>().ToSelf().InSingletonScope();
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<BaseViewModel>()
.BindAllBaseClasses());
#endregion
#region Models
Bind<ProfilePreviewModel>().ToSelf().InSingletonScope();
#endregion
#region Services
Bind<MetroDialogService>().ToSelf().InSingletonScope();
Bind<WindowService>().ToSelf().InSingletonScope();
#endregion
#region Servers
Bind<GameStateWebServer>().ToSelf().InSingletonScope();
Bind<PipeServer>().ToSelf().InSingletonScope();
#endregion
#region Devices
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<DeviceProvider>()
.BindAllBaseClasses());
#endregion
#region Effects
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<EffectModel>()
.BindAllBaseClasses()
.Configure((b, c) => b.InSingletonScope().Named(c.Name))
);
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<EffectViewModel>()
.BindBase());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<GameViewModel>()
.BindBase());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<OverlayViewModel>()
.BindBase());
#endregion
#region Profiles
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<ILayerAnimation>()
.BindAllInterfaces());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<ILayerCondition>()
.BindAllInterfaces());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<ILayerType>()
.BindAllInterfaces());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<ILayerType>()
.BindToSelf());
// Type helpers
Bind<AudioCaptureManager>().ToSelf().InSingletonScope();
#endregion
#region Lua
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<LuaModule>()
.BindAllBaseClasses());
#endregion
}
}
}

View File

@ -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<DeviceProvider>().To<NoneKeyboard>().InSingletonScope();
Bind<DeviceProvider>().To<CorsairKeyboard>().InSingletonScope();
Bind<DeviceProvider>().To<G910>().InSingletonScope();
Bind<DeviceProvider>().To<G810>().InSingletonScope();
Bind<DeviceProvider>().To<BlackWidow>().InSingletonScope();
Bind<DeviceProvider>().To<MasterkeysProL>().InSingletonScope();
Bind<DeviceProvider>().To<MasterkeysProS>().InSingletonScope();
// Mice
Bind<DeviceProvider>().To<CorsairMouse>().InSingletonScope();
// Headsets
Bind<DeviceProvider>().To<CorsairHeadset>().InSingletonScope();
// Mousemats
Bind<DeviceProvider>().To<CorsairMousemat>().InSingletonScope();
// Other
Bind<DeviceProvider>().To<LogitechGeneric>().InSingletonScope();
}
}
}

View File

@ -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<EffectModel>()
.BindBase()
.Configure((b, c) => b.InSingletonScope().Named(c.Name));
});
// View models
Kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<EffectViewModel>()
.BindBase();
});
Kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<GameViewModel>()
.BindBase();
});
Kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<OverlayViewModel>()
.BindBase();
});
}
}
}

View File

@ -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<DeviceManager>().ToSelf().InSingletonScope();
Bind<EffectManager>().ToSelf().InSingletonScope();
Bind<ProfileManager>().ToSelf().InSingletonScope();
Bind<LuaManager>().ToSelf().InSingletonScope();
}
}
}

View File

@ -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<ILayerAnimation>().To<NoneAnimation>();
Bind<ILayerAnimation>().To<GrowAnimation>();
Bind<ILayerAnimation>().To<PulseAnimation>();
Bind<ILayerAnimation>().To<SlideDownAnimation>();
Bind<ILayerAnimation>().To<SlideLeftAnimation>();
Bind<ILayerAnimation>().To<SlideRightAnimation>();
Bind<ILayerAnimation>().To<SlideUpAnimation>();
// Conditions
Bind<ILayerCondition>().To<DataModelCondition>();
Bind<ILayerCondition>().To<EventCondition>();
// Types
Bind<ILayerType>().To<FolderType>();
Bind<ILayerType>().To<HeadsetType>();
Bind<ILayerType>().To<KeyboardType>();
Bind<ILayerType>().To<KeyboardGifType>();
Bind<ILayerType>().To<MouseType>();
Bind<ILayerType>().To<MousematType>();
Bind<ILayerType>().To<GenericType>();
Bind<ILayerType>().To<KeyPressType>();
Bind<ILayerType>().To<AudioType>();
Bind<ILayerType>().To<AmbientLightType>();
// Bind some Layer Types to self as well in order to allow JSON.NET injection
Bind<KeyPressType>().ToSelf();
Bind<AudioType>().ToSelf();
Bind<AmbientLightType>().ToSelf();
// Type helpers
Bind<AudioCaptureManager>().ToSelf().InSingletonScope();
}
}
}

View File

@ -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
/// </summary>
public IEnumerable<GameModel> EnabledGames
{
get { return EffectModels.OfType<GameModel>().Where(g => g.Enabled); }
get { return EffectModels.OfType<GameModel>().Where(g => g.Enabled && g.Settings.Enabled); }
}
public event EventHandler<EffectChangedEventArgs> 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;
}
}
}

View File

@ -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);

View File

@ -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<LuaModule> _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<List<LuaModule>>();
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("");
}
}
/// <summary>
/// Safely call a function on the active script
/// </summary>
/// <param name="function"></param>
/// <param name="args"></param>
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
}
}

View File

@ -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<EnabledChangedEventArgs> OnEnabledChangedEvent;
/// <summary>
/// Restarts the loop manager when the system resumes
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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();
}
/// <summary>
/// Loads the last active effect and starts the program
/// </summary>
@ -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

View File

@ -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
/// <param name="keyboardOnly"></param>
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);

View File

@ -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;

View File

@ -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;

View File

@ -15,7 +15,8 @@ namespace Artemis.Modules.Effects.Bubbles
{
#region Constructors
public BubblesModel(DeviceManager deviceManager) : base(deviceManager, SettingsProvider.Load<BubblesSettings>(), null)
public BubblesModel(DeviceManager deviceManager, LuaManager luaManager)
: base(deviceManager, luaManager, SettingsProvider.Load<BubblesSettings>(), 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);

View File

@ -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);

View File

@ -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<PerformanceCounter> _cores;
private int _cpuFrames;
private DateTime _lastMusicUpdate;
private PerformanceCounter _overallCpu;
private SpotifyLocalAPI _spotify;
private bool _spotifySetupBusy;
public WindowsProfileModel(DeviceManager deviceManager)
: base(deviceManager, SettingsProvider.Load<WindowsProfileSettings>(), 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<LayerModel> 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<PerformanceCounter> GetPerformanceCounters()
{
var performanceCounters = new List<PerformanceCounter>();
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<GooglePlayMusic>(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<PerformanceCounter> _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<WindowsProfileSettings>(),
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<LayerModel> 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<PerformanceCounter> GetPerformanceCounters()
{
var performanceCounters = new List<PerformanceCounter>();
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<GooglePlayMusic>(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
}
}

View File

@ -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<ProfileEditorViewModel>(args);

View File

@ -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<CounterStrikeSettings>(), new CounterStrikeDataModel())
public CounterStrikeModel(DeviceManager deviceManager, LuaManager luaManager,
GameStateWebServer gameStateWebServer, MetroDialogService dialogService)
: base(deviceManager, luaManager, SettingsProvider.Load<CounterStrikeSettings>(),
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;
}

View File

@ -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<Dota2Settings>(), new Dota2DataModel())
: base(deviceManager, luaManager, SettingsProvider.Load<Dota2Settings>(), 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)

View File

@ -2,7 +2,7 @@
namespace Artemis.Modules.Games.Dota2
{
internal class Dota2Settings : GameSettings
public class Dota2Settings : GameSettings
{
public string GameDirectory { get; set; }
}

View File

@ -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<Ets2TelemetryStructure> _rawData;
@ -38,7 +38,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
}
}
internal class Ets2Game : IEts2Game
public class Ets2Game : IEts2Game
{
private readonly Box<Ets2TelemetryStructure> _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<Ets2TelemetryStructure> _rawData;
@ -242,7 +242,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
*/
}
internal class Ets2Trailer : IEts2Trailer
public class Ets2Trailer : IEts2Trailer
{
private readonly Box<Ets2TelemetryStructure> _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<Ets2TelemetryStructure> _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<Ets2TelemetryStructure> _rawData;
@ -355,7 +355,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
}
*/
internal class Box<T> where T : struct
public class Box<T> where T : struct
{
public Box(T @struct)
{

View File

@ -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;

View File

@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data.Reader
{
internal class SharedProcessMemory<T> : IDisposable
public class SharedProcessMemory<T> : IDisposable
{
private readonly string _mapName;
private MemoryMappedViewAccessor _memoryMappedAccessor;

View File

@ -18,9 +18,10 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
{
private readonly MetroDialogService _dialogService;
public EurotruckSimulator2Model(DeviceManager deviceManager, MetroDialogService dialogService)
: base(
deviceManager, SettingsProvider.Load<EurotruckSimulator2Settings>(), new EurotruckSimulator2DataModel())
public EurotruckSimulator2Model(DeviceManager deviceManager, LuaManager luaManager,
MetroDialogService dialogService)
: base(deviceManager, luaManager, SettingsProvider.Load<EurotruckSimulator2Settings>(),
new EurotruckSimulator2DataModel())
{
_dialogService = dialogService;
Name = "EurotruckSimulator2";
@ -42,6 +43,8 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
public override void Enable()
{
base.Enable();
Initialized = true;
}

View File

@ -15,8 +15,8 @@ namespace Artemis.Modules.Games.GtaV
{
private readonly PipeServer _pipeServer;
public GtaVModel(DeviceManager deviceManager, PipeServer pipeServer)
: base(deviceManager, SettingsProvider.Load<GtaVSettings>(), new GtaVDataModel())
public GtaVModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
: base(deviceManager, luaManager, SettingsProvider.Load<GtaVSettings>(), 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;

View File

@ -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; }
}
}

View File

@ -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();
}
}
}

View File

@ -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<LightFxSettings>(), 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<LayerModel> GetRenderLayers(bool keyboardOnly)
{
return Profile.GetRenderLayers(DataModel, keyboardOnly);
}
}
}

View File

@ -0,0 +1,8 @@
using Artemis.Settings;
namespace Artemis.Modules.Games.LightFx
{
public class LightFxSettings : GameSettings
{
}
}

View File

@ -0,0 +1,60 @@
<UserControl x:Class="Artemis.Modules.Games.LightFx.LightFxView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="559.725" d:DesignWidth="882.696">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Grid Margin="15,5,5,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap"
Text="Mirrors Light FX lighting to your RGB devices" />
</Label.Content>
</Label>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right">
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
IsChecked="{Binding Path=GameSettings.Enabled, Mode=TwoWay}"
Style="{DynamicResource MetroCircleToggleButtonStyle}"
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
</StackPanel>
</Grid>
<!-- Profile editor -->
<ContentControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-20,0" />
<!-- Buttons -->
<StackPanel Grid.Column="0" Grid.Row="3" Orientation="Horizontal" VerticalAlignment="Bottom">
<Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100"
Style="{DynamicResource SquareButtonStyle}" />
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100"
Margin="10,0,0,0"
Style="{DynamicResource SquareButtonStyle}" />
</StackPanel>
</Grid>
</ScrollViewer>
</UserControl>

View File

@ -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());
}
}
}

View File

@ -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";
}
}
}

View File

@ -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<OverwatchSettings>(), new OverwatchDataModel())
public OverwatchModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer,
MetroDialogService dialogService, DebugViewModel debugViewModel)
: base(deviceManager, luaManager, SettingsProvider.Load<OverwatchSettings>(), new OverwatchDataModel())
{
_pipeServer = pipeServer;
_dialogService = dialogService;
@ -82,6 +82,8 @@ namespace Artemis.Modules.Games.Overwatch
public override void Enable()
{
base.Enable();
_stickyStatus = new StickyValue<OverwatchStatus>(300);
_stickyUltimateReady = new StickyValue<bool>(350);
_stickyUltimateUsed = new StickyValue<bool>(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))

View File

@ -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<bool, pCarsAPIStruct>(true, _pcarsapistruct);
}
catch (Exception ex)
catch (Exception)
{
//return false in the tuple as the read failed
return new Tuple<bool, pCarsAPIStruct>(false, _pcarsapistruct);

View File

@ -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<ProjectCarsSettings>(), new ProjectCarsDataModel())
public ProjectCarsModel(DeviceManager deviceManager, LuaManager luaManager, MetroDialogService dialogService)
: base(deviceManager, luaManager, SettingsProvider.Load<ProjectCarsSettings>(), 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<LayerModel> GetRenderLayers(bool keyboardOnly)

View File

@ -16,7 +16,6 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
@ -32,19 +31,19 @@
<Label Grid.Row="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap"
Text="By default shows indicator lights, speed and engine RPM on the keyboard" />
Text="By default shows.. nothing yet! Default profiles next update :)" />
</Label.Content>
</Label>
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom"
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
TextAlignment="Justify" Margin="5,0,0,10">
The Euro Truck Simulator 2 module uses code from the
The Project CARS module uses code from the
<Hyperlink RequestNavigate="Hyperlink_RequestNavigate"
NavigateUri="https://github.com/Funbit/ets2-telemetry-server">
ETS2 Telemetry Web Server
NavigateUri="https://bitbucket.org/MikeyTT/pcars-api-demo">
pCars API Demo
</Hyperlink>
project by Funbit
project by MikeyTT
</TextBlock>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right">
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
@ -55,26 +54,11 @@
</StackPanel>
</Grid>
<StackPanel Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2" Margin="0,0,1,0">
<Label FontSize="20" HorizontalAlignment="Left" Content="Euro Truck Simulator 2 directory" />
<Grid>
<TextBox x:Name="GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
Text="{Binding Path=GameSettings.GameDirectory, Mode=TwoWay}"
cal:Message.Attach="[Event LostFocus] = [Action PlacePlugin]" />
<Button x:Name="BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
HorizontalAlignment="Right" Width="25"
Style="{DynamicResource SquareButtonStyle}" Height="26" Margin="0,-2,0,0" />
</Grid>
</StackPanel>
<!-- Profile editor -->
<ContentControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-20,0" />
<ContentControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-20,0" />
<!-- Buttons -->
<StackPanel Grid.Column="0" Grid.Row="4" Orientation="Horizontal" VerticalAlignment="Bottom">
<StackPanel Grid.Column="0" Grid.Row="3" Orientation="Horizontal" VerticalAlignment="Bottom">
<Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100"
Style="{DynamicResource SquareButtonStyle}" />
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100"

View File

@ -17,8 +17,7 @@ namespace Artemis.Modules.Games.RocketLeague
private Memory _memory;
private GamePointersCollection _pointer;
public RocketLeagueModel(DeviceManager deviceManager)
: base(deviceManager, SettingsProvider.Load<RocketLeagueSettings>(), new RocketLeagueDataModel())
public RocketLeagueModel(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager, SettingsProvider.Load<RocketLeagueSettings>(), new RocketLeagueDataModel())
{
Name = "RocketLeague";
ProcessName = "RocketLeague";
@ -30,14 +29,14 @@ namespace Artemis.Modules.Games.RocketLeague
//var offset = new GamePointersCollection
//{
// Game = "RocketLeague",
// GameVersion = "1.24",
// GameVersion = "1.26",
// GameAddresses = new List<GamePointer>
// {
// new GamePointer
// {
// Description = "Boost",
// BasePointer = new IntPtr(0x016BBFB4),
// Offsets = new[] { 0xc4, 0x210, 0x320, 0x734, 0x224}
// BasePointer = new IntPtr(0x01666C38),
// Offsets = new[] { 0x58, 0x668, 0x73C, 0x224}
// }
// }
//};
@ -55,8 +54,9 @@ namespace Artemis.Modules.Games.RocketLeague
public override void Enable()
{
Initialized = false;
base.Enable();
Initialized = false;
Updater.GetPointers();
_pointer = SettingsProvider.Load<OffsetSettings>().RocketLeague;

View File

@ -16,8 +16,8 @@ namespace Artemis.Modules.Games.TheDivision
private StickyValue<bool> _stickyAmmo;
private StickyValue<bool> _stickyHp;
public TheDivisionModel(DeviceManager deviceManager, PipeServer pipeServer)
: base(deviceManager, SettingsProvider.Load<TheDivisionSettings>(), new TheDivisionDataModel())
public TheDivisionModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
: base(deviceManager, luaManager, SettingsProvider.Load<TheDivisionSettings>(), new TheDivisionDataModel())
{
_pipeServer = pipeServer;
Name = "TheDivision";
@ -49,8 +49,9 @@ namespace Artemis.Modules.Games.TheDivision
public override void Enable()
{
Initialized = false;
base.Enable();
Initialized = false;
_stickyAmmo = new StickyValue<bool>(200);
_stickyHp = new StickyValue<bool>(200);

View File

@ -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<UnrealTournamentSettings>(), new UnrealTournamentDataModel())
public UnrealTournamentModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer,
MetroDialogService dialogService)
: base(deviceManager, luaManager, SettingsProvider.Load<UnrealTournamentSettings>(),
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();
@ -124,6 +126,8 @@ namespace Artemis.Modules.Games.UnrealTournament
public override void Enable()
{
base.Enable();
_pipeServer.PipeMessage += PipeServerOnPipeMessage;
_killTimer.Start();

View File

@ -17,8 +17,8 @@ namespace Artemis.Modules.Games.Witcher3
private readonly Stopwatch _updateSw;
private string _witcherSettings;
public Witcher3Model(DeviceManager deviceManager)
: base(deviceManager, SettingsProvider.Load<Witcher3Settings>(), new Witcher3DataModel())
public Witcher3Model(DeviceManager deviceManager, LuaManager luaManager)
: base(deviceManager, luaManager, SettingsProvider.Load<Witcher3Settings>(), new Witcher3DataModel())
{
Name = "Witcher3";
ProcessName = "witcher3";
@ -43,8 +43,9 @@ namespace Artemis.Modules.Games.Witcher3
public override void Enable()
{
Initialized = false;
base.Enable();
Initialized = false;
// Ensure the config file is found
var witcherSettings = Environment.GetFolderPath(Environment.SpecialFolder.Personal) +
@"\The Witcher 3\user.settings";

View File

@ -18,8 +18,8 @@ namespace Artemis.Modules.Games.WoW
private readonly GamePointersCollection _pointer;
private ProcessSharp _process;
public WoWModel(DeviceManager deviceManager)
: base(deviceManager, SettingsProvider.Load<WoWSettings>(), new WoWDataModel())
public WoWModel(DeviceManager deviceManager, LuaManager luaManager)
: base(deviceManager, luaManager, SettingsProvider.Load<WoWSettings>(), new WoWDataModel())
{
Name = "WoW";
ProcessName = "Wow-64";
@ -77,6 +77,8 @@ namespace Artemis.Modules.Games.WoW
public override void Enable()
{
base.Enable();
var tempProcess = MemoryHelpers.GetProcessIfRunning(ProcessName);
if (tempProcess == null)
return;

View File

@ -13,7 +13,8 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
{
public class VolumeDisplayModel : OverlayModel
{
public VolumeDisplayModel(DeviceManager deviceManager): base(deviceManager, SettingsProvider.Load<VolumeDisplaySettings>())
public VolumeDisplayModel(DeviceManager deviceManager, LuaManager luaManager)
: base(deviceManager, luaManager, SettingsProvider.Load<VolumeDisplaySettings>())
{
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)
{

View File

@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
@ -11,7 +12,17 @@ namespace Artemis.Profiles.Layers.Conditions
{
lock (layerModel.Properties.Conditions)
{
return layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
switch (layerModel.Properties.ConditionType)
{
case ConditionType.AnyMet:
return layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel));
case ConditionType.AllMet:
return layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
case ConditionType.NoneMet:
return !layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel));
default:
return false;
}
}
}
}

View File

@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
@ -11,7 +12,19 @@ namespace Artemis.Profiles.Layers.Conditions
{
lock (layerModel.Properties.Conditions)
{
var conditionsMet = layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
var conditionsMet = false;
switch (layerModel.Properties.ConditionType)
{
case ConditionType.AnyMet:
conditionsMet = layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel));
break;
case ConditionType.AllMet:
conditionsMet = layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
break;
case ConditionType.NoneMet:
conditionsMet = !layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel));
break;
}
layerModel.EventProperties.Update(layerModel, conditionsMet);
if (conditionsMet && layerModel.EventProperties.CanTrigger)

View File

@ -52,6 +52,9 @@ namespace Artemis.Profiles.Layers.Models
/// <param name="updateAnimations"></param>
public void Update(IDataModel dataModel, bool preview, bool updateAnimations)
{
if (LayerType == null)
return;
LayerType.Update(this, dataModel, preview);
LayerAnimation?.Update(this, updateAnimations);
@ -387,7 +390,7 @@ namespace Artemis.Profiles.Layers.Models
get { return Profile; }
set { Profile = value; }
}
#endregion
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Media;
using Artemis.Utilities.Converters;
@ -24,6 +25,7 @@ namespace Artemis.Profiles.Layers.Models
Opacity = source.Opacity;
AnimationSpeed = source.AnimationSpeed;
Conditions = source.Conditions;
ConditionType = source.ConditionType;
DynamicProperties = source.DynamicProperties;
Brush = source.Brush;
HeightEase = source.HeightEase;
@ -47,6 +49,7 @@ namespace Artemis.Profiles.Layers.Models
public string WidthEase { set; get; }
public string HeightEase { get; set; }
public string OpacityEase { get; set; }
public ConditionType ConditionType { get; set; }
public List<LayerConditionModel> Conditions { get; set; } = new List<LayerConditionModel>();
public List<DynamicPropertiesModel> DynamicProperties { get; set; } = new List<DynamicPropertiesModel>();
@ -80,4 +83,11 @@ namespace Artemis.Profiles.Layers.Models
return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
}
}
public enum ConditionType
{
[Description("All met")] AllMet,
[Description("Any met")] AnyMet,
[Description("None met")] NoneMet
}
}

View File

@ -16,7 +16,7 @@ using Ninject;
namespace Artemis.Profiles.Layers.Types.Audio
{
internal class AudioType : ILayerType
public class AudioType : ILayerType
{
private readonly List<LayerModel> _audioLayers = new List<LayerModel>();
private readonly IKernel _kernel;

View File

@ -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<LayerModel> _keyPressLayers;

View File

@ -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;

View File

@ -1,43 +0,0 @@
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<LuaColor, double> 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<LuaColor, double> 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);
}
}
}

View File

@ -1,99 +0,0 @@
using System;
using System.Windows.Forms;
using System.Windows.Media;
using Artemis.Models.Interfaces;
using MoonSharp.Interpreter;
using NLog;
namespace Artemis.Profiles.Lua.Events
{
[MoonSharpUserData]
public class LuaEventsWrapper
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
public readonly string InvokeLock = string.Empty;
public event EventHandler<LuaDeviceUpdatingEventArgs> DeviceUpdating;
public event EventHandler<LuaDeviceDrawingEventArgs> DeviceDrawing;
public event EventHandler<LuaKeyPressEventArgs> KeyboardKeyPressed;
internal void InvokeDeviceUpdate(ProfileModel profileModel, string deviceType, IDataModel dataModel,
bool preview)
{
try
{
LuaInvoke(profileModel, () => OnDeviceUpdating(new LuaProfileWrapper(profileModel),
new LuaDeviceUpdatingEventArgs(deviceType, dataModel, preview)));
}
catch (Exception)
{
// ignored
}
}
internal void InvokeDeviceDraw(ProfileModel profileModel, string deviceType, IDataModel dataModel, bool preview,
DrawingContext c)
{
try
{
LuaInvoke(profileModel, () => OnDeviceDrawing(new LuaProfileWrapper(profileModel),
new LuaDeviceDrawingEventArgs(deviceType, dataModel, preview, new LuaDrawWrapper(c))));
}
catch (Exception)
{
// ignored
}
}
internal void InvokeKeyPressed(ProfileModel profileModel, LuaKeyboardWrapper keyboard, Keys key, int x, int y)
{
try
{
LuaInvoke(profileModel, () => OnKeyboardKeyPressed(new LuaProfileWrapper(profileModel),
keyboard, new LuaKeyPressEventArgs(key, x, y)));
}
catch (Exception)
{
// ignored
}
}
private void LuaInvoke(ProfileModel profileModel, Action action)
{
lock (InvokeLock)
{
try
{
action.Invoke();
}
catch (InternalErrorException ex)
{
_logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
}
catch (SyntaxErrorException ex)
{
_logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
}
catch (ScriptRuntimeException ex)
{
_logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
}
}
}
protected virtual void OnDeviceUpdating(LuaProfileWrapper profileModel, LuaDeviceUpdatingEventArgs e)
{
DeviceUpdating?.Invoke(profileModel, e);
}
protected virtual void OnDeviceDrawing(LuaProfileWrapper profileModel, LuaDeviceDrawingEventArgs e)
{
DeviceDrawing?.Invoke(profileModel, e);
}
protected virtual void OnKeyboardKeyPressed(LuaProfileWrapper profileModel, LuaKeyboardWrapper keyboard,
LuaKeyPressEventArgs e)
{
KeyboardKeyPressed?.Invoke(profileModel, e);
}
}
}

View File

@ -1,46 +0,0 @@
using System;
using System.Windows.Forms;
using Artemis.DeviceProviders;
using Artemis.Utilities.Keyboard;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua
{
[MoonSharpUserData]
public class LuaKeyboardWrapper : IDisposable
{
private readonly KeyboardProvider _keyboardProvider;
public LuaKeyboardWrapper(KeyboardProvider keyboardProvider)
{
_keyboardProvider = keyboardProvider;
KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
}
public string Name => _keyboardProvider.Name;
public string Slug => _keyboardProvider.Slug;
public int Width => _keyboardProvider.Width;
public int Height => _keyboardProvider.Height;
[MoonSharpVisible(false)]
public void Dispose()
{
KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback;
}
private void KeyboardHookOnKeyDownCallback(KeyEventArgs e)
{
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);
}
}
}

View File

@ -0,0 +1,36 @@
using System;
using Artemis.Managers;
using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua
{
/// <summary>
/// Defines a module which will be accessable in all LUA scripts.
/// </summary>
public abstract class LuaModule : IDisposable
{
public LuaModule(LuaManager luaManager)
{
LuaManager = luaManager;
}
/// <summary>
/// The name under which this module will be accessable in LUA
/// </summary>
public abstract string ModuleName { get; }
/// <summary>
/// The LUA manager containing this module
/// </summary>
[MoonSharpVisible(false)]
public LuaManager LuaManager { get; set; }
/// <summary>
/// Called when the LUA script is restarted
/// </summary>
[MoonSharpVisible(false)]
public virtual void Dispose()
{
}
}
}

View File

@ -1,204 +0,0 @@
using System;
using System.IO;
using System.Text;
using Artemis.DAL;
using Artemis.DeviceProviders;
using Artemis.Profiles.Lua.Brushes;
using Artemis.Profiles.Lua.Events;
using Artemis.Properties;
using Castle.Core.Internal;
using MoonSharp.Interpreter;
using NLog;
namespace Artemis.Profiles.Lua
{
public static class LuaWrapper
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly Script LuaScript = new Script(CoreModules.Preset_SoftSandbox);
private static FileSystemWatcher _watcher;
public static ProfileModel ProfileModel { get; private set; }
public static KeyboardProvider KeyboardProvider { get; private set; }
public static LuaProfileWrapper LuaProfileWrapper { get; private set; }
public static LuaBrushWrapper LuaBrushWrapper { get; private set; }
public static LuaKeyboardWrapper LuaKeyboardWrapper { get; private set; }
public static LuaMouseWrapper LuaMouseWrapper { get; set; }
public static LuaEventsWrapper LuaEventsWrapper { get; private set; }
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);
}
}
#region Private lua functions
private static void LuaPrint(string s)
{
Logger.Debug("[{0}-LUA]: {1}", ProfileModel?.Name, s);
}
#endregion
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 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
}
}

View File

@ -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

View File

@ -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

View File

@ -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
@ -57,7 +57,7 @@ namespace Artemis.Profiles.Lua.Brushes
{
var collection = new GradientStopCollection(gradientColors
.Select(gc => new GradientStop(gc.Key.Color, gc.Value)));
Brush = new LinearGradientBrush(collection, new Point(startX, startY), new Point(endX, endY));
}
}

View File

@ -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

View File

@ -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

View File

@ -1,13 +1,15 @@
using System;
using Artemis.Models.Interfaces;
using Artemis.Profiles.Lua.Wrappers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Events
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;

View File

@ -2,7 +2,7 @@
using Artemis.Models.Interfaces;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Events
namespace Artemis.Profiles.Lua.Modules.Events
{
[MoonSharpUserData]
public class LuaDeviceUpdatingEventArgs : EventArgs

View File

@ -2,7 +2,7 @@
using System.Windows.Forms;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Events
namespace Artemis.Profiles.Lua.Modules.Events
{
[MoonSharpUserData]
public class LuaKeyPressEventArgs : EventArgs

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;
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<LuaColor, double> 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<LuaColor, double> 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);
}
public LuaColor GetRelativeColor(Dictionary<LuaColor, double> gradientColors, double offset)
{
if (offset < 0)
offset = 0;
if (offset > 1)
offset = 1;
var gsc = new GradientStopCollection(gradientColors.Select(gc => new GradientStop(gc.Key.Color, gc.Value)));
var b = gsc.First(w => Math.Abs(w.Offset - gsc.Min(m => m.Offset)) < 0.01);
var a = gsc.First(w => Math.Abs(w.Offset - gsc.Max(m => m.Offset)) < 0.01);
foreach (var gs in gsc)
{
if (gs.Offset < offset && gs.Offset > b.Offset)
b = gs;
if (gs.Offset > offset && gs.Offset < a.Offset)
a = gs;
}
var color = new Color
{
ScA = (float) ((offset - b.Offset) * (a.Color.ScA - b.Color.ScA) / (a.Offset - b.Offset) + b.Color.ScA),
ScR = (float) ((offset - b.Offset) * (a.Color.ScR - b.Color.ScR) / (a.Offset - b.Offset) + b.Color.ScR),
ScG = (float) ((offset - b.Offset) * (a.Color.ScG - b.Color.ScG) / (a.Offset - b.Offset) + b.Color.ScG),
ScB = (float) ((offset - b.Offset) * (a.Color.ScB - b.Color.ScB) / (a.Offset - b.Offset) + b.Color.ScB)
};
return new LuaColor(color);
}
}
}

View File

@ -0,0 +1,126 @@
using System;
using System.Windows.Forms;
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
{
[MoonSharpUserData]
public class LuaEventsModule : LuaModule
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
private readonly ProfileModel _profileModel;
public readonly string InvokeLock = string.Empty;
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<LuaDeviceUpdatingEventArgs> DeviceUpdating;
public event EventHandler<LuaDeviceDrawingEventArgs> DeviceDrawing;
public event EventHandler<LuaKeyPressEventArgs> KeyboardKeyPressed;
private void KeyboardHookOnKeyDownCallback(KeyEventArgs e)
{
try
{
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)
{
// ignored
}
}
private void OnDeviceUpdatedEvent(object sender, ProfileDeviceEventsArg e)
{
try
{
var args = new LuaDeviceUpdatingEventArgs(e.UpdateType, e.DataModel, e.Preview);
LuaInvoke(_profileModel, () => OnDeviceUpdating(LuaManager.ProfileModule, args));
}
catch (Exception)
{
// ignored
}
}
private void OnDeviceDrawnEvent(object sender, ProfileDeviceEventsArg e)
{
try
{
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)
{
// ignored
}
}
private void LuaInvoke(ProfileModel profileModel, Action action)
{
lock (InvokeLock)
{
try
{
action.Invoke();
}
catch (InternalErrorException ex)
{
_logger.Error("[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
}
catch (SyntaxErrorException ex)
{
_logger.Error("[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
}
catch (ScriptRuntimeException ex)
{
_logger.Error("[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
}
}
}
protected virtual void OnDeviceUpdating(LuaProfileModule profileModel, LuaDeviceUpdatingEventArgs e)
{
DeviceUpdating?.Invoke(profileModel, e);
}
protected virtual void OnDeviceDrawing(LuaProfileModule profileModel, LuaDeviceDrawingEventArgs e)
{
DeviceDrawing?.Invoke(profileModel, 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
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.Diagnostics;
using System.Windows.Forms;
using Artemis.DeviceProviders;
using Artemis.Managers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules
{
[MoonSharpUserData]
public class LuaKeyboardModule : LuaModule
{
private readonly KeyboardProvider _keyboardProvider;
public LuaKeyboardModule(LuaManager luaManager) : base(luaManager)
{
_keyboardProvider = luaManager.KeyboardProvider;
// Register the KeyMatch type for usage in GetKeyPosition
UserData.RegisterType(typeof(KeyMatch));
}
public override string ModuleName => "Keyboard";
public string Name => _keyboardProvider.Name;
public string Slug => _keyboardProvider.Slug;
public int Width => _keyboardProvider.Width;
public int Height => _keyboardProvider.Height;
public void PressKeys(string keys)
{
SendKeys.SendWait(keys);
}
public KeyMatch? GetKeyPosition(string 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");
}
}
}
}

View File

@ -0,0 +1,184 @@
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.Modules.Brushes;
using Artemis.Profiles.Lua.Wrappers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules
{
[MoonSharpUserData]
public class LuaLayerModule : LuaModule
{
private readonly LayerModel _layerModel;
public LuaLayerModule(LuaManager luaManager, LayerModel layerModel) : base(luaManager)
{
_layerModel = layerModel;
SavedProperties = new Wrappers.LuaLayerProperties(_layerModel);
// Trigger an update to fill up the Properties
_layerModel.Update(new ProfilePreviewDataModel(), true, false);
}
public override string ModuleName => "Layer";
#region Child methods
public List<LuaLayerWrapper> 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 Wrappers.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; }
}
}
}

View File

@ -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;
}
}
}

View File

@ -1,22 +1,23 @@
using System.Collections.Generic;
using System.Linq;
using Artemis.Managers;
using Artemis.Profiles.Lua.Wrappers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua
namespace Artemis.Profiles.Lua.Modules
{
/// <summary>
/// Serves as a sandboxed wrapper around the ProfileModel
/// </summary>
[MoonSharpUserData]
public class LuaProfileWrapper
public class LuaProfileModule : LuaModule
{
private readonly ProfileModel _profileModel;
public LuaProfileWrapper(ProfileModel profileModel)
public LuaProfileModule(LuaManager luaManager) : base(luaManager)
{
_profileModel = profileModel;
_profileModel = luaManager.ProfileModel;
}
public override string ModuleName => "Profile";
#region General profile properties
public string Name => _profileModel.Name;

View File

@ -0,0 +1,43 @@
using System.Collections.Generic;
using Artemis.Managers;
using Artemis.Profiles.Lua.Modules.Timer;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules
{
[MoonSharpUserData]
public class LuaTimerModule : LuaModule
{
private readonly List<LuaTimer> _timers;
public LuaTimerModule(LuaManager luaManager) : base(luaManager)
{
_timers = new List<LuaTimer>();
}
public override string ModuleName => "Timer";
public override void Dispose()
{
foreach (var luaTimer in _timers)
luaTimer.Dispose();
_timers.Clear();
}
public LuaTimer SetTimer(DynValue function, int interval, int timesToExecute, params DynValue[] args)
{
var luaTimer = new LuaTimer(this, function, interval, timesToExecute, args);
_timers.Add(luaTimer);
return luaTimer;
}
public void RemoveTimer(LuaTimer luaTimer)
{
if (_timers.Contains(luaTimer))
_timers.Remove(luaTimer);
luaTimer.Dispose();
}
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Timers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules.Timer
{
[MoonSharpUserData]
public class LuaTimer : IDisposable
{
private readonly DynValue[] _args;
private readonly DynValue _function;
private readonly System.Timers.Timer _timer;
private readonly LuaTimerModule _timerModule;
private readonly int _timesToExecute;
private int _timesExecuted;
public LuaTimer(LuaTimerModule timerModule, DynValue function, int interval, int timesToExecute,
params DynValue[] args)
{
_timerModule = timerModule;
_function = function;
_timesToExecute = timesToExecute;
_args = args;
_timesExecuted = 0;
// Setup timer
_timer = new System.Timers.Timer(interval);
_timer.Elapsed += TimerOnElapsed;
_timer.Start();
}
public void Dispose()
{
_timer?.Stop();
_timer?.Dispose();
}
public void Stop()
{
_timerModule.RemoveTimer(this);
}
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
{
if (_args != null)
_timerModule.LuaManager.Call(_function, _args);
else
_timerModule.LuaManager.Call(_function);
// Don't keep track of execution if times is set to 0 (infinite)
if (_timesToExecute <= 0)
return;
_timesExecuted++;
if (_timesExecuted >= _timesToExecute)
_timerModule.RemoveTimer(this);
}
}
}

View File

@ -1,19 +1,20 @@
using System;
using System.Drawing.Text;
using System.Globalization;
using System.Linq;
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
namespace Artemis.Profiles.Lua.Wrappers
{
/// <summary>
/// A wrapper that is provided to each OnDraw event to allow drawing in LUA
/// </summary>
[MoonSharpUserData]
public class LuaDrawWrapper
{
private readonly DrawingContext _ctx;
private FontFamily _font;
private readonly FontFamily _font;
public LuaDrawWrapper(DrawingContext ctx)
{
@ -28,7 +29,7 @@ namespace Artemis.Profiles.Lua
height *= 4;
width *= 4;
var center = new Point(x + width/2, y + height/2);
var center = new Point(x + width / 2, y + height / 2);
_ctx.DrawEllipse(luaBrush.Brush, new Pen(), center, width, height);
}
@ -65,7 +66,7 @@ namespace Artemis.Profiles.Lua
fontSize, luaBrush.Brush);
_ctx.DrawText(formatted, new Point(x, y));
return formatted.Width/4;
return formatted.Width / 4;
}
}
}

View File

@ -1,183 +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.Brushes;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua
{
/// <summary>
/// Serves as a sandboxed wrapper around the LayerModel
/// </summary>
[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<LuaLayerWrapper> 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; }
}
}
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
{
/// <summary>
/// Serves as a sandboxed wrapper around the LayerModel
/// </summary>
[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<LuaLayerWrapper> 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; }
}
}
}

View File

@ -1,16 +1,19 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
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;
using Color = System.Windows.Media.Color;
using Point = System.Windows.Point;
using Size = System.Windows.Size;
@ -19,8 +22,11 @@ namespace Artemis.Profiles
{
public class ProfileModel
{
private readonly char[] _invalidFileNameChars;
public ProfileModel()
{
_invalidFileNameChars = Path.GetInvalidFileNameChars();
Layers = new ChildItemCollection<ProfileModel, LayerModel>(this);
}
@ -33,6 +39,12 @@ namespace Artemis.Profiles
public int Height { get; set; }
public string LuaScript { get; set; }
[JsonIgnore]
public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray());
public event EventHandler<ProfileDeviceEventsArg> OnDeviceUpdatedEvent;
public event EventHandler<ProfileDeviceEventsArg> OnDeviceDrawnEvent;
public void FixOrder()
{
Layers.Sort(l => l.Order);
@ -69,12 +81,14 @@ namespace Artemis.Profiles
var layers = new List<LayerModel>();
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));
@ -107,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();
@ -124,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);
}
/// <summary>
/// Looks at all the layers wthin the profile and makes sure they are within boundaries of the given rectangle
/// </summary>
@ -164,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.ProfileModel.LuaScript != LuaScript)
luaManager.SetupLua(this);
}
public void Deactivate()
public void Deactivate(LuaManager luaManager)
{
LuaWrapper.Clear();
luaManager.ClearLua();
}
public LayerModel AddLayer(LayerModel afterLayer)
@ -181,7 +207,9 @@ namespace Artemis.Profiles
var layer = LayerModel.CreateLayer();
if (afterLayer != null)
{
afterLayer.InsertAfter(layer);
}
else
{
Layers.Add(layer);
@ -195,7 +223,7 @@ namespace Artemis.Profiles
protected bool Equals(ProfileModel other)
{
return string.Equals(Name, other.Name) &&
return string.Equals(Slug, other.Slug) &&
string.Equals(KeyboardSlug, other.KeyboardSlug) &&
string.Equals(GameName, other.GameName);
}
@ -212,9 +240,9 @@ namespace Artemis.Profiles
{
unchecked
{
var hashCode = Name?.GetHashCode() ?? 0;
hashCode = (hashCode*397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
hashCode = (hashCode*397) ^ (GameName?.GetHashCode() ?? 0);
var hashCode = Slug?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (GameName?.GetHashCode() ?? 0);
return hashCode;
}
}

View File

@ -53,7 +53,7 @@ using System.Windows;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.7.0.0")]
[assembly: AssemblyFileVersion("1.7.0.0")]
[assembly: AssemblyVersion("1.7.1.0")]
[assembly: AssemblyFileVersion("1.7.1.0")]
[assembly: InternalsVisibleTo("Artemis.Explorables")]

View File

@ -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;

View File

@ -15,6 +15,11 @@
-- This event is raised after every profile update, before drawing.
function updateHandler(profile, eventArgs)
-- Don't do anything when previewing (this means the editor is open)
if eventArgs.Preview then
return
end
-- In this example we only want to update once per frame when the keyboard is
-- updated. If you don't do this the updateHandler will trigger on every
-- device's update.
@ -27,6 +32,11 @@ end
-- This event is raised after every profile draw, after updating.
function drawHandler(profile, eventArgs)
-- Don't do anything when previewing (this means the editor is open)
if eventArgs.Preview then
return
end
-- In this example we only want to draw to the keyboard. Each device has it's
-- own drawing event
if eventArgs.DeviceType != "keyboard" then

View File

@ -21,13 +21,15 @@ namespace Artemis.Utilities
[DllImport("user32.dll")]
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
#endregion
#region Constants
private const uint WINEVENT_OUTOFCONTEXT = 0;
private const uint EVENT_SYSTEM_FOREGROUND = 3;
private const uint WINEVENT_OUTOFCONTEXT = 0x0000;
private const uint EVENT_SYSTEM_FOREGROUND = 0x0003;
private const uint EVENT_OBJECT_NAMECHANGE = 0x800C;
private const uint EVENT_SYSTEM_MINIMIZEEND = 0x0017;
private const int MAX_TITLE_LENGTH = 256;
@ -37,7 +39,15 @@ namespace Artemis.Utilities
// DarthAffe 17.12.2016: We need to keep a reference to this or it might get collected by the garbage collector and cause some random crashes afterwards.
private static WinEventDelegate _activeWindowChangedDelegate;
private static IntPtr _winEventHook;
private static IntPtr _activeWindowEventHook;
private static WinEventDelegate _windowTitleChangedDelegate;
private static IntPtr _windowTitleEventHook;
private static WinEventDelegate _windowMinimizedChangedDelegate;
private static IntPtr _windowMinimizedEventHook;
private static IntPtr _activeWindow;
public static string ActiveWindowProcessName { get; private set; }
public static string ActiveWindowWindowTitle { get; private set; }
@ -49,6 +59,28 @@ namespace Artemis.Utilities
private static void ActiveWindowChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
UpdateForWindow(hwnd);
}
private static void WindowTitleChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
if (_activeWindow == hwnd)
UpdateForWindow(hwnd);
}
private static void WindowMinimizedChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
// DarthAffe 19.12.2016: We expect currently un-minimized windows to be active.
// DarthAffe 19.12.2016: The result of the API-function GetActiveWindow at this moment is 'idle' so we can't use this to validate this estimation.
UpdateForWindow(hwnd);
}
private static void UpdateForWindow(IntPtr hwnd)
{
_activeWindow = hwnd;
ActiveWindowProcessName = GetActiveWindowProcessName(hwnd) ?? string.Empty;
ActiveWindowWindowTitle = GetActiveWindowTitle(hwnd) ?? string.Empty;
}
@ -84,10 +116,23 @@ namespace Artemis.Utilities
{
try
{
if (_winEventHook != IntPtr.Zero) return;
if (_activeWindowEventHook == IntPtr.Zero)
{
_activeWindowChangedDelegate = ActiveWindowChanged;
_activeWindowEventHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, _activeWindowChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
}
_activeWindowChangedDelegate = ActiveWindowChanged;
_winEventHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, _activeWindowChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
if (_windowTitleEventHook == IntPtr.Zero)
{
_windowTitleChangedDelegate = WindowTitleChanged;
_windowTitleEventHook = SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, IntPtr.Zero, _windowTitleChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
}
if (_windowMinimizedEventHook == IntPtr.Zero)
{
_windowMinimizedChangedDelegate = WindowMinimizedChanged;
_windowMinimizedEventHook = SetWinEventHook(EVENT_SYSTEM_MINIMIZEEND, EVENT_SYSTEM_MINIMIZEEND, IntPtr.Zero, _windowMinimizedChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
}
}
catch { /* catch'em all - I don't want it to crash here */ }
}
@ -96,11 +141,26 @@ namespace Artemis.Utilities
{
try
{
if (_winEventHook == IntPtr.Zero) return;
if (_activeWindowEventHook != IntPtr.Zero)
{
UnhookWinEvent(_activeWindowEventHook);
_activeWindowChangedDelegate = null;
_activeWindowEventHook = IntPtr.Zero;
}
UnhookWinEvent(_winEventHook);
_activeWindowChangedDelegate = null;
_winEventHook = IntPtr.Zero;
if (_windowTitleEventHook != IntPtr.Zero)
{
UnhookWinEvent(_windowTitleEventHook);
_windowTitleChangedDelegate = null;
_windowTitleEventHook = IntPtr.Zero;
}
if (_windowMinimizedEventHook != IntPtr.Zero)
{
UnhookWinEvent(_windowMinimizedEventHook);
_windowMinimizedChangedDelegate = null;
_windowMinimizedEventHook = IntPtr.Zero;
}
}
catch { /* catch'em all - I don't want it to crash here */ }
}

View File

@ -7,7 +7,7 @@ using System.Windows.Media.Imaging;
namespace Artemis.Utilities
{
internal class ImageUtilities
public class ImageUtilities
{
/// <summary>
/// Resize the image to the specified width and height.

View File

@ -7,7 +7,7 @@ namespace Artemis.Utilities
/// <summary>
/// A value that only changes it's not changed again within a set time
/// </summary>
internal class StickyValue<T> : IDisposable
public class StickyValue<T> : IDisposable
{
private readonly int _stickyTime;
private readonly BackgroundWorker _updateWorker;

View File

@ -46,7 +46,6 @@ namespace Artemis.Utilities
{
// These exceptions should only really occur when running from VS
Logger.Error(e, "Update check failed");
mgr.Result.Dispose();
}
}
}

View File

@ -26,7 +26,7 @@ namespace Artemis.ViewModels.Abstract
IParameter[] args =
{
new ConstructorArgument("mainManager", mainManager),
new ConstructorArgument("gameModel", gameModel),
new ConstructorArgument("effectModel", gameModel),
new ConstructorArgument("lastProfile", GameSettings.LastProfile)
};
ProfileEditor = kernel.Get<ProfileEditorViewModel>(args);
@ -60,7 +60,7 @@ namespace Artemis.ViewModels.Abstract
}
}
public bool GameEnabled => MainManager.EffectManager.ActiveEffect == GameModel;
public bool GameEnabled => MainManager.EffectManager.ActiveEffect.Name == GameModel.Name;
public void ToggleEffect()
{

View File

@ -27,14 +27,14 @@ namespace Artemis.ViewModels.Profiles
private ILayerType _selectedLayerType;
public LayerEditorViewModel(LayerModel layer, IDataModel dataModel, IEnumerable<ILayerType> types,
List<ILayerAnimation> layerAnimations)
IEnumerable<ILayerAnimation> layerAnimations)
{
Layer = layer;
ProposedLayer = Clone(layer);
ProposedLayer.Children.Clear();
DataModel = DataModel;
LayerTypes = new BindableCollection<ILayerType>(types);
LayerAnimations = layerAnimations;
LayerTypes = new BindableCollection<ILayerType>(types.OrderBy(t => t.Name));
LayerAnimations = layerAnimations.OrderBy(l => l.Name).ToList();
DataModelProps = new BindableCollection<PropertyCollection>(GenerateTypeMap(dataModel));

View File

@ -1,7 +1,9 @@
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
@ -16,11 +18,12 @@ using Artemis.Models;
using Artemis.Profiles;
using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Layers.Types.Folder;
using Artemis.Profiles.Lua;
using Artemis.Properties;
using Artemis.Services;
using Artemis.Styles.DropTargetAdorners;
using Artemis.Utilities;
using Caliburn.Micro;
using Castle.Core.Internal;
using GongSolutions.Wpf.DragDrop;
using MahApps.Metro.Controls.Dialogs;
using Ninject;
@ -37,20 +40,23 @@ namespace Artemis.ViewModels.Profiles
public sealed class ProfileEditorViewModel : Screen, IDropTarget
{
private readonly DeviceManager _deviceManager;
private readonly EffectModel _gameModel;
private readonly EffectModel _effectModel;
private readonly LuaManager _luaManager;
private readonly Timer _saveTimer;
private ImageSource _keyboardPreview;
private ObservableCollection<LayerModel> _layers;
private ObservableCollection<string> _profileNames;
private bool _saving;
private ProfileModel _selectedProfile;
private FileSystemWatcher _watcher;
public ProfileEditorViewModel(DeviceManager deviceManager, EffectModel gameModel,
public ProfileEditorViewModel(DeviceManager deviceManager, LuaManager luaManager, EffectModel effectModel,
ProfileViewModel profileViewModel, MetroDialogService dialogService, WindowService windowService,
string lastProfile)
{
_deviceManager = deviceManager;
_gameModel = gameModel;
_luaManager = luaManager;
_effectModel = effectModel;
ProfileNames = new ObservableCollection<string>();
Layers = new ObservableCollection<LayerModel>();
@ -79,7 +85,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<string> ProfileNames
{
@ -111,7 +117,7 @@ namespace Artemis.ViewModels.Profiles
if (value == SelectedProfile?.Name)
return;
SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _gameModel, value);
SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _effectModel, value);
NotifyOfPropertyChange(() => SelectedProfileName);
}
}
@ -124,12 +130,21 @@ namespace Artemis.ViewModels.Profiles
if (Equals(value, _selectedProfile))
return;
// Deactivate old profile
_selectedProfile?.Deactivate();
// Update the value
_selectedProfile = value;
// Activate new profile
_selectedProfile?.Activate(_deviceManager.ActiveKeyboard);
if (IsActive)
{
// Deactivate old profile
_selectedProfile?.Deactivate(_luaManager);
// Update the value
_selectedProfile = value;
// Activate new profile
_selectedProfile?.Activate(_luaManager);
}
else
{
// Update the value
_selectedProfile = value;
}
NotifyOfPropertyChange(() => SelectedProfile);
NotifyOfPropertyChange(() => SelectedProfileName);
}
@ -149,16 +164,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 +190,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 +211,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 +223,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);
@ -230,6 +245,7 @@ namespace Artemis.ViewModels.Profiles
public void Activate()
{
_selectedProfile?.Activate(_luaManager);
ProfileViewModel.Activate();
_saveTimer.Start();
}
@ -237,7 +253,7 @@ namespace Artemis.ViewModels.Profiles
public void Deactivate()
{
ProfileViewModel.Deactivate();
SelectedProfile?.Deactivate();
SelectedProfile?.Deactivate(_luaManager);
_saveTimer.Stop();
}
@ -246,26 +262,26 @@ namespace Artemis.ViewModels.Profiles
/// </summary>
private void LoadProfiles()
{
ProfileNames.Clear();
if ((_gameModel == null) || (_deviceManager.ActiveKeyboard == null))
return;
ProfileNames.AddRange(ProfileProvider.GetProfileNames(_deviceManager.ActiveKeyboard, _gameModel));
// If a profile name was provided, try to load it
ProfileModel lastProfileModel = null;
if (!string.IsNullOrEmpty(LastProfile))
Execute.OnUIThread(() =>
{
lastProfileModel = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _gameModel, LastProfile);
}
ProfileNames.Clear();
if (_effectModel == null || _deviceManager.ActiveKeyboard == null)
return;
if (lastProfileModel != null)
SelectedProfile = lastProfileModel;
else
{
SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _gameModel,
ProfileNames.FirstOrDefault());
}
ProfileNames.AddRange(ProfileProvider.GetProfileNames(_deviceManager.ActiveKeyboard, _effectModel));
// If a profile name was provided, try to load it
ProfileModel lastProfileModel = null;
if (!string.IsNullOrEmpty(LastProfile))
lastProfileModel = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _effectModel,
LastProfile);
if (lastProfileModel != null)
SelectedProfile = lastProfileModel;
else
SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _effectModel,
ProfileNames.FirstOrDefault());
});
}
@ -297,7 +313,7 @@ namespace Artemis.ViewModels.Profiles
IParameter[] args =
{
new ConstructorArgument("dataModel", _gameModel.DataModel),
new ConstructorArgument("dataModel", _effectModel.DataModel),
new ConstructorArgument("layer", layer)
};
WindowService.ShowDialog<LayerEditorViewModel>(args);
@ -506,7 +522,7 @@ namespace Artemis.ViewModels.Profiles
KeyboardSlug = _deviceManager.ActiveKeyboard.Slug,
Width = _deviceManager.ActiveKeyboard.Width,
Height = _deviceManager.ActiveKeyboard.Height,
GameName = _gameModel.Name
GameName = _effectModel.Name
};
if (!ProfileProvider.IsProfileUnique(profile))
@ -532,7 +548,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 +560,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;
@ -628,10 +644,10 @@ namespace Artemis.ViewModels.Profiles
}
// Verify the game
if (profile.GameName != _gameModel.Name)
if (profile.GameName != _effectModel.Name)
{
DialogService.ShowErrorMessageBox(
$"Oh oops! This profile is ment for {profile.GameName}, not {_gameModel.Name} :c");
$"Oh oops! This profile is ment for {profile.GameName}, not {_effectModel.Name} :c");
return;
}
@ -694,13 +710,12 @@ namespace Artemis.ViewModels.Profiles
return;
try
{
SelectedProfile?.Activate(_deviceManager.ActiveKeyboard);
LuaWrapper.OpenEditor();
OpenEditor();
}
catch (Exception e)
{
DialogService.ShowMessageBox("Couldn't open LUA file",
"Please make sure you have a program such as Notepad associated with the .lua extension.\n\n" +
"Please make sure you have a text editor associated with the .lua extension.\n\n" +
"Windows error message: \n" + e.Message);
}
}
@ -738,7 +753,7 @@ namespace Artemis.ViewModels.Profiles
public void SaveSelectedProfile()
{
if (_saving || (SelectedProfile == null) || _deviceManager.ChangingKeyboard)
if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard)
return;
_saving = true;
@ -752,5 +767,67 @@ namespace Artemis.ViewModels.Profiles
}
_saving = false;
}
#region LUA Editor
public void OpenEditor()
{
if (SelectedProfile == 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 (SelectedProfile.LuaScript.IsNullOrEmpty())
SelectedProfile.LuaScript = Encoding.UTF8.GetString(Resources.lua_placeholder);
File.WriteAllText(Path.GetTempPath() + fileName, SelectedProfile.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 (SelectedProfile == null)
return;
lock (SelectedProfile)
{
using (var fs = new FileStream(args.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var sr = new StreamReader(fs))
{
SelectedProfile.LuaScript = sr.ReadToEnd();
}
}
ProfileProvider.AddOrUpdate(SelectedProfile);
_luaManager.SetupLua(SelectedProfile);
}
}
#endregion
}
}

View File

@ -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;

View File

@ -44,7 +44,6 @@
Style="{StaticResource MahApps.Metro.Styles.ToggleSwitchButton.Win10}"
HorizontalAlignment="Right" />
<!-- Show on startup -->
<Label Grid.Row="2" Grid.Column="0" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Left"
Content="Show on startup:" />

View File

@ -9,8 +9,18 @@
mc:Ignorable="d"
Title="Artemis | Edit Layer" Height="820" Width="630"
xmlns:cal="http://www.caliburnproject.org"
xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
xmlns:models="clr-namespace:Artemis.Profiles.Layers.Models"
GlowBrush="{DynamicResource AccentColorBrush}" Icon="../../Resources/bow.png"
ResizeMode="NoResize">
<controls:MetroWindow.Resources>
<converters:EnumDescriptionConverter x:Key="HEnumDescriptionConverter" />
<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="ConditionTypeValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="models:ConditionType" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</controls:MetroWindow.Resources>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid Margin="10,0">
<Grid.RowDefinitions>
@ -68,7 +78,22 @@
</Grid>
<!-- Condition editor -->
<Label Grid.Row="2" Grid.Column="0" FontSize="20" Content="Display if.." />
<Grid Grid.Row="2" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label FontSize="20" Content="Display if.." Grid.Column="0" />
<ComboBox SelectedItem="{Binding Path=ProposedLayer.Properties.ConditionType}" Grid.Column="1"
ItemsSource="{Binding Source={StaticResource ConditionTypeValues}}" Margin="10,0"
VerticalAlignment="Center" Height="22">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource HEnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
<Border Grid.Row="3" Grid.Column="0" BorderThickness="1" BorderBrush="{StaticResource GrayBrush7}"
Margin="10,0" SnapsToDevicePixels="True">
<ListBox Height="138" x:Name="LayerConditionVms" ScrollViewer.VerticalScrollBarVisibility="Visible">

View File

@ -3,7 +3,7 @@ using Artemis86Wrapper.Intergrations.Skype;
namespace Artemis86Wrapper
{
internal class Program
public class Program
{
private static void Main(string[] args)
{

View File

@ -1,167 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{1A349CF5-2008-41E8-AC13-874CBBCDFA0A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>LightFX2Artemis</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIGHTFX2ARTEMIS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>LightFX2Artemis.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;LIGHTFX2ARTEMIS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>LightFX2Artemis.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIGHTFX2ARTEMIS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>LightFX2Artemis.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;LIGHTFX2ARTEMIS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>LightFX2Artemis.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="LightFX2Artemis.def" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\LogiLed2Artemis\main.cpp" />
<ClCompile Include="LightFxState.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="LightFxState.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{1A349CF5-2008-41E8-AC13-874CBBCDFA0A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>LightFX2Artemis</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="LightFxDevice.cpp" />
<ClCompile Include="LightFxLight.cpp" />
<ClCompile Include="LightFxState.cpp" />
<ClCompile Include="Source.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="LightFxDevice.h" />
<ClInclude Include="LightFxLight.h" />
<ClInclude Include="LightFxState.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -15,15 +15,16 @@
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="LightFX2Artemis.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\LogiLed2Artemis\main.cpp">
<ClCompile Include="LightFxState.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LightFxState.cpp">
<ClCompile Include="LightFxDevice.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LightFxLight.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@ -31,5 +32,11 @@
<ClInclude Include="LightFxState.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LightFxDevice.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LightFxLight.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

Some files were not shown because too many files have changed in this diff Show More