mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
commit
e8d83d8c53
3
.gitignore
vendored
3
.gitignore
vendored
@ -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
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ using Artemis.Settings;
|
||||
|
||||
namespace Artemis.DeviceProviders.Logitech
|
||||
{
|
||||
internal class G810 : LogitechKeyboard
|
||||
public class G810 : LogitechKeyboard
|
||||
{
|
||||
private GeneralSettings _generalSettings;
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ using Artemis.Settings;
|
||||
|
||||
namespace Artemis.DeviceProviders.Logitech
|
||||
{
|
||||
internal class G910 : LogitechKeyboard
|
||||
public class G910 : LogitechKeyboard
|
||||
{
|
||||
private readonly GeneralSettings _generalSettings;
|
||||
|
||||
|
||||
22
Artemis/Artemis/Events/ProfileDeviceEventsArg.cs
Normal file
22
Artemis/Artemis/Events/ProfileDeviceEventsArg.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
177
Artemis/Artemis/Managers/LuaManager.cs
Normal file
177
Artemis/Artemis/Managers/LuaManager.cs
Normal 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
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Artemis.Modules.Games.Dota2
|
||||
{
|
||||
internal class Dota2Settings : GameSettings
|
||||
public class Dota2Settings : GameSettings
|
||||
{
|
||||
public string GameDirectory { get; set; }
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
40
Artemis/Artemis/Modules/Games/LightFx/Data/LightFxState.cs
Normal file
40
Artemis/Artemis/Modules/Games/LightFx/Data/LightFxState.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
19
Artemis/Artemis/Modules/Games/LightFx/LightFxDataModel.cs
Normal file
19
Artemis/Artemis/Modules/Games/LightFx/LightFxDataModel.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
73
Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
Normal file
73
Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Artemis/Artemis/Modules/Games/LightFx/LightFxSettings.cs
Normal file
8
Artemis/Artemis/Modules/Games/LightFx/LightFxSettings.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using Artemis.Settings;
|
||||
|
||||
namespace Artemis.Modules.Games.LightFx
|
||||
{
|
||||
public class LightFxSettings : GameSettings
|
||||
{
|
||||
}
|
||||
}
|
||||
60
Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml
Normal file
60
Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml
Normal 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>
|
||||
18
Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml.cs
Normal file
18
Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml.cs
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs
Normal file
16
Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs
Normal 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";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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))
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Artemis/Artemis/Profiles/Lua/LuaModule.cs
Normal file
36
Artemis/Artemis/Profiles/Lua/LuaModule.cs
Normal 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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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;
|
||||
@ -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
|
||||
@ -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
|
||||
84
Artemis/Artemis/Profiles/Lua/Modules/LuaBrushesModule.cs
Normal file
84
Artemis/Artemis/Profiles/Lua/Modules/LuaBrushesModule.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
126
Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs
Normal file
126
Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs
Normal 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
|
||||
}
|
||||
}
|
||||
49
Artemis/Artemis/Profiles/Lua/Modules/LuaKeyboardModule.cs
Normal file
49
Artemis/Artemis/Profiles/Lua/Modules/LuaKeyboardModule.cs
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
184
Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs
Normal file
184
Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
43
Artemis/Artemis/Profiles/Lua/Modules/LuaTimerModule.cs
Normal file
43
Artemis/Artemis/Profiles/Lua/Modules/LuaTimerModule.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
59
Artemis/Artemis/Profiles/Lua/Modules/Timer/LuaTimer.cs
Normal file
59
Artemis/Artemis/Profiles/Lua/Modules/Timer/LuaTimer.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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")]
|
||||
|
||||
|
||||
2
Artemis/Artemis/Properties/Resources.Designer.cs
generated
2
Artemis/Artemis/Properties/Resources.Designer.cs
generated
@ -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;
|
||||
|
||||
|
||||
Binary file not shown.
@ -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
|
||||
|
||||
@ -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 */ }
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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:" />
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -3,7 +3,7 @@ using Artemis86Wrapper.Intergrations.Skype;
|
||||
|
||||
namespace Artemis86Wrapper
|
||||
{
|
||||
internal class Program
|
||||
public class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
|
||||
@ -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>
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user