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

Merge pull request #258 from SpoinkyNL/development

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

3
.gitignore vendored
View File

@ -15,6 +15,7 @@
x64/ x64/
x86/ x86/
build/ build/
debug/
bld/ bld/
[Bb]in/ [Bb]in/
[Oo]bj/ [Oo]bj/
@ -190,4 +191,4 @@ FakesAssemblies/
# Visual Studio 6 workspace options file # Visual Studio 6 workspace options file
*.opt *.opt
*.opendb *.opendb

View File

@ -191,9 +191,6 @@
<HintPath>..\packages\MahApps.Metro.1.3.0\lib\net45\MahApps.Metro.dll</HintPath> <HintPath>..\packages\MahApps.Metro.1.3.0\lib\net45\MahApps.Metro.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </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"> <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> <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@ -339,11 +336,9 @@
<Compile Include="Events\EffectChangedEventArgs.cs" /> <Compile Include="Events\EffectChangedEventArgs.cs" />
<Compile Include="Events\EnabledChangedEventArgs.cs" /> <Compile Include="Events\EnabledChangedEventArgs.cs" />
<Compile Include="Events\KeyboardChangedEventArgs.cs" /> <Compile Include="Events\KeyboardChangedEventArgs.cs" />
<Compile Include="Events\ProfileDeviceEventsArg.cs" />
<Compile Include="Events\RazerColorArrayChanged.cs" /> <Compile Include="Events\RazerColorArrayChanged.cs" />
<Compile Include="Events\RazerColorsChangedEventArgs.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="ItemBehaviours\BindableSelectedItemBehavior.cs" />
<Compile Include="DeviceProviders\Corsair\CorsairKeyboard.cs" /> <Compile Include="DeviceProviders\Corsair\CorsairKeyboard.cs" />
<Compile Include="DeviceProviders\KeyboardProvider.cs" /> <Compile Include="DeviceProviders\KeyboardProvider.cs" />
@ -357,6 +352,7 @@
<Compile Include="Managers\EffectManager.cs" /> <Compile Include="Managers\EffectManager.cs" />
<Compile Include="Managers\DeviceManager.cs" /> <Compile Include="Managers\DeviceManager.cs" />
<Compile Include="Managers\LoopManager.cs" /> <Compile Include="Managers\LoopManager.cs" />
<Compile Include="Managers\LuaManager.cs" />
<Compile Include="Managers\MainManager.cs" /> <Compile Include="Managers\MainManager.cs" />
<Compile Include="Managers\ProfileManager.cs" /> <Compile Include="Managers\ProfileManager.cs" />
<Compile Include="Models\EffectModel.cs" /> <Compile Include="Models\EffectModel.cs" />
@ -382,6 +378,14 @@
<DependentUpon>GtaVView.xaml</DependentUpon> <DependentUpon>GtaVView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Modules\Games\GtaV\GtaVViewModel.cs" /> <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\eAPIStructLengths.cs" />
<Compile Include="Modules\Games\ProjectCars\Data\_eNums\eCarFlags.cs" /> <Compile Include="Modules\Games\ProjectCars\Data\_eNums\eCarFlags.cs" />
<Compile Include="Modules\Games\ProjectCars\Data\_eNums\eCrashDamageState.cs" /> <Compile Include="Modules\Games\ProjectCars\Data\_eNums\eCrashDamageState.cs" />
@ -499,22 +503,25 @@
</Compile> </Compile>
<Compile Include="Profiles\Layers\Types\Mousemat\MousematPropertiesViewModel.cs" /> <Compile Include="Profiles\Layers\Types\Mousemat\MousematPropertiesViewModel.cs" />
<Compile Include="Profiles\Layers\Types\Mousemat\MousematType.cs" /> <Compile Include="Profiles\Layers\Types\Mousemat\MousematType.cs" />
<Compile Include="Profiles\LuaMouseWrapper.cs" /> <Compile Include="Profiles\Lua\Modules\Brushes\LuaBrush.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaBrush.cs" /> <Compile Include="Profiles\Lua\Modules\Brushes\LuaColor.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaColor.cs" /> <Compile Include="Profiles\Lua\Modules\Brushes\LuaLinearGradientBrush.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaLinearGradientBrush.cs" /> <Compile Include="Profiles\Lua\Modules\Brushes\LuaRadialGradientBrush.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaRadialGradientBrush.cs" /> <Compile Include="Profiles\Lua\Modules\Events\LuaKeyPressEventArgs.cs" />
<Compile Include="Profiles\Lua\Events\LuaKeyPressEventArgs.cs" /> <Compile Include="Profiles\Lua\Modules\Events\LuaDeviceDrawingEventArgs.cs" />
<Compile Include="Profiles\Lua\Events\LuaDeviceDrawingEventArgs.cs" /> <Compile Include="Profiles\Lua\Modules\Events\LuaDeviceUpdatingEventArgs.cs" />
<Compile Include="Profiles\Lua\Events\LuaDeviceUpdatingEventArgs.cs" /> <Compile Include="Profiles\Lua\Modules\LuaEventsModule.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaBrushWrapper.cs" /> <Compile Include="Profiles\Lua\Modules\LuaBrushesModule.cs" />
<Compile Include="Profiles\Lua\LuaDrawWrapper.cs" /> <Compile Include="Profiles\Lua\LuaModule.cs" />
<Compile Include="Profiles\Lua\Events\LuaEventsWrapper.cs" /> <Compile Include="Profiles\Lua\Modules\Brushes\LuaSolidColorBrush.cs" />
<Compile Include="Profiles\Lua\LuaKeyboardWrapper.cs" /> <Compile Include="Profiles\Lua\Modules\LuaKeyboardModule.cs" />
<Compile Include="Profiles\Lua\LuaLayerWrapper.cs" /> <Compile Include="Profiles\Lua\Modules\LuaLayerModule.cs" />
<Compile Include="Profiles\Lua\LuaProfileWrapper.cs" /> <Compile Include="Profiles\Lua\Modules\LuaMouseModule.cs" />
<Compile Include="Profiles\Lua\Brushes\LuaSolidColorBrush.cs" /> <Compile Include="Profiles\Lua\Modules\LuaProfileModule.cs" />
<Compile Include="Profiles\Lua\LuaWrapper.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\ProfileModel.cs" />
<Compile Include="Profiles\Layers\Models\SimplePropertiesModel.cs" /> <Compile Include="Profiles\Layers\Models\SimplePropertiesModel.cs" />
<Compile Include="Profiles\Layers\Types\Keyboard\KeyboardPropertiesModel.cs" /> <Compile Include="Profiles\Layers\Types\Keyboard\KeyboardPropertiesModel.cs" />
@ -837,6 +844,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Modules\Games\LightFx\LightFxView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Modules\Games\Overwatch\OverwatchView.xaml"> <Page Include="Modules\Games\Overwatch\OverwatchView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@ -77,8 +77,7 @@ namespace Artemis
protected override void Configure() protected override void Configure()
{ {
_kernel = new StandardKernel(new BaseModules(), new ManagerModules(), new DeviceModules(), _kernel = new StandardKernel(new BaseModules(), new ManagerModules());
new EffectModules(), new ProfileModules());
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope(); _kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
_kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope(); _kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();

View File

@ -67,7 +67,7 @@ namespace Artemis.DAL
lock (prof) lock (prof)
{ {
// Store the file // 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"); throw new ArgumentException("Profile is invalid. Name, GameName and KeyboardSlug are required");
var path = ProfileFolder + $@"\{prof.KeyboardSlug}\{prof.GameName}"; var path = ProfileFolder + $@"\{prof.KeyboardSlug}\{prof.GameName}";
@ -84,11 +84,11 @@ namespace Artemis.DAL
} }
catch (Exception e) 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; 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); 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) public static void DeleteProfile(ProfileModel prof)
{ {
// Remove the file // 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)) if (File.Exists(path))
File.Delete(path); File.Delete(path);
} }

View File

@ -8,7 +8,7 @@ using Ninject.Extensions.Logging;
namespace Artemis.DeviceProviders.Corsair namespace Artemis.DeviceProviders.Corsair
{ {
internal class CorsairHeadset : DeviceProvider public class CorsairHeadset : DeviceProvider
{ {
public CorsairHeadset(ILogger logger) public CorsairHeadset(ILogger logger)
{ {
@ -22,7 +22,7 @@ namespace Artemis.DeviceProviders.Corsair
{ {
CanUse = CanInitializeSdk(); CanUse = CanInitializeSdk();
if (CanUse && !CueSDK.IsInitialized) if (CanUse && !CueSDK.IsInitialized)
CueSDK.Initialize(true); CueSDK.Initialize();
Logger.Debug("Attempted to enable Corsair headset. CanUse: {0}", CanUse); Logger.Debug("Attempted to enable Corsair headset. CanUse: {0}", CanUse);

View File

@ -1,150 +1,160 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Forms; using System.Windows.Forms;
using Artemis.DeviceProviders.Corsair.Utilities; using Artemis.DeviceProviders.Corsair.Utilities;
using Artemis.Properties; using Artemis.Properties;
using Artemis.Utilities; using Artemis.Utilities;
using CUE.NET; using CUE.NET;
using CUE.NET.Brushes; using CUE.NET.Brushes;
using CUE.NET.Devices.Generic; using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Helper; using CUE.NET.Exceptions;
using Ninject.Extensions.Logging; using CUE.NET.Helper;
using Point = System.Drawing.Point; using Ninject.Extensions.Logging;
using Point = System.Drawing.Point;
namespace Artemis.DeviceProviders.Corsair
{ namespace Artemis.DeviceProviders.Corsair
public class CorsairKeyboard : KeyboardProvider {
{ public class CorsairKeyboard : KeyboardProvider
private CUE.NET.Devices.Keyboard.CorsairKeyboard _keyboard; {
private ImageBrush _keyboardBrush; private CUE.NET.Devices.Keyboard.CorsairKeyboard _keyboard;
private ImageBrush _keyboardBrush;
public CorsairKeyboard(ILogger logger)
{ public CorsairKeyboard(ILogger logger)
Logger = logger; {
Name = "Corsair RGB Keyboard"; Logger = logger;
CantEnableText = "Couldn't connect to your Corsair keyboard.\n" + Name = "Corsair RGB Keyboard";
"Please check your cables and/or drivers (could be outdated) and that Corsair Utility Engine is running.\n" + CantEnableText = "Couldn't connect to your Corsair keyboard.\n" +
"In CUE, make sure \"Enable SDK\" is checked under Global Settings.\n\n" + "Please check your cables and/or drivers (could be outdated) and that Corsair Utility Engine is running.\n" +
"If needed, you can select a different keyboard in Artemis under settings."; "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 ILogger Logger { get; set; }
public override bool CanEnable()
{ public override bool CanEnable()
return CueSDK.IsSDKAvailable(CorsairDeviceType.Keyboard); {
} 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>
/// </summary> /// Enables the SDK and sets updatemode to manual as well as the color of the background to black.
public override void Enable() /// </summary>
{ public override void Enable()
if (!CueSDK.IsInitialized) {
CueSDK.Initialize(true); if (!CueSDK.IsInitialized)
CueSDK.Initialize();
CueSDK.UpdateMode = UpdateMode.Manual;
_keyboard = CueSDK.KeyboardSDK; CueSDK.UpdateMode = UpdateMode.Manual;
switch (_keyboard.DeviceInfo.Model) _keyboard = CueSDK.KeyboardSDK;
{ switch (_keyboard.DeviceInfo.Model)
case "K95 RGB": {
Height = 7; case "K95 RGB":
Width = 25; Height = 7;
Slug = "corsair-k95-rgb"; Width = 25;
PreviewSettings = new PreviewSettings(676, 190, new Thickness(0, -15, 0, 0), Resources.k95); Slug = "corsair-k95-rgb";
break; PreviewSettings = new PreviewSettings(676, 190, new Thickness(0, -15, 0, 0), Resources.k95);
case "K70 RGB": break;
case "K70 RGB RAPIDFIRE": case "K70 RGB":
case "K70 LUX RGB": case "K70 RGB RAPIDFIRE":
Height = 7; case "K70 LUX RGB":
Width = 21; Height = 7;
Slug = "corsair-k70-rgb"; Width = 21;
PreviewSettings = new PreviewSettings(676, 210, new Thickness(0, -25, 0, 0), Resources.k70); Slug = "corsair-k70-rgb";
break; PreviewSettings = new PreviewSettings(676, 210, new Thickness(0, -25, 0, 0), Resources.k70);
case "K65 RGB": break;
case "CGK65 RGB": case "K65 RGB":
case "K65 LUX RGB": case "CGK65 RGB":
case "K65 RGB RAPIDFIRE": case "K65 LUX RGB":
Height = 7; case "K65 RGB RAPIDFIRE":
Width = 18; Height = 7;
Slug = "corsair-k65-rgb"; Width = 18;
PreviewSettings = new PreviewSettings(610, 240, new Thickness(0, -30, 0, 0), Resources.k65); Slug = "corsair-k65-rgb";
break; PreviewSettings = new PreviewSettings(610, 240, new Thickness(0, -30, 0, 0), Resources.k65);
case "STRAFE RGB": break;
Height = 7; case "STRAFE RGB":
Width = 22; Height = 7;
Slug = "corsair-strafe-rgb"; Width = 22;
PreviewSettings = new PreviewSettings(665, 215, new Thickness(0, -5, 0, 0), Resources.strafe); Slug = "corsair-strafe-rgb";
break; 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()); Logger.Debug("Corsair SDK reported device as: {0}", _keyboard.DeviceInfo.Model);
} _keyboard.Brush = _keyboardBrush ?? (_keyboardBrush = new ImageBrush());
}
public override void Disable()
{ public override void Disable()
if (CueSDK.IsInitialized) {
CueSDK.Reinitialize(); try
} {
if (CueSDK.IsInitialized)
/// <summary> CueSDK.Reinitialize();
/// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap }
/// size. catch (WrapperException e)
/// </summary> {
/// <param name="bitmap"></param> // This occurs when releasing the SDK after sleep, ignore it
public override void DrawBitmap(Bitmap bitmap) if (e.Message != "The previously loaded Keyboard got disconnected.")
{ throw;
using (var image = ImageUtilities.ResizeImage(bitmap, Width, Height)) }
{ }
// For STRAFE, stretch the image on row 2.
if (_keyboard.DeviceInfo.Model == "STRAFE RGB") /// <summary>
{ /// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap
using (var strafeBitmap = new Bitmap(22, 8)) /// size.
{ /// </summary>
using (var g = Graphics.FromImage(strafeBitmap)) /// <param name="bitmap"></param>
{ public override void DrawBitmap(Bitmap bitmap)
g.DrawImage(image, new Point(0, 0)); {
g.DrawImage(image, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7), using (var image = ImageUtilities.ResizeImage(bitmap, Width, Height))
GraphicsUnit.Pixel); {
// For STRAFE, stretch the image on row 2.
_keyboardBrush.Image = strafeBitmap; if (_keyboard.DeviceInfo.Model == "STRAFE RGB")
_keyboard.Update(); {
} using (var strafeBitmap = new Bitmap(22, 8))
} {
} using (var g = Graphics.FromImage(strafeBitmap))
else {
{ g.DrawImage(image, new Point(0, 0));
_keyboardBrush.Image = image; g.DrawImage(image, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7),
_keyboard.Update(); GraphicsUnit.Pixel);
}
} _keyboardBrush.Image = strafeBitmap;
} _keyboard.Update();
}
public override KeyMatch? GetKeyPosition(Keys keyCode) }
{ }
var widthMultiplier = Width/_keyboard.Brush.RenderedRectangle.Width; else
var heightMultiplier = Height/_keyboard.Brush.RenderedRectangle.Height; {
_keyboardBrush.Image = image;
CorsairLed cueLed = null; _keyboard.Update();
try }
{ }
cueLed = _keyboard.Leds.FirstOrDefault(k => k.Id.ToString() == keyCode.ToString()) ?? }
_keyboard.Leds.FirstOrDefault(k => k.Id == KeyMap.FormsKeys[keyCode]);
} public override KeyMatch? GetKeyPosition(Keys keyCode)
catch (Exception) {
{ var widthMultiplier = Width/_keyboard.Brush.RenderedRectangle.Width;
// ignored var heightMultiplier = Height/_keyboard.Brush.RenderedRectangle.Height;
}
CorsairLed cueLed = null;
if (cueLed == null) try
return null; {
cueLed = _keyboard.Leds.FirstOrDefault(k => k.Id.ToString() == keyCode.ToString()) ??
var center = cueLed.LedRectangle.GetCenter(); _keyboard.Leds.FirstOrDefault(k => k.Id == KeyMap.FormsKeys[keyCode]);
return new KeyMatch(keyCode, (int) (center.X*widthMultiplier), (int) (center.Y*heightMultiplier)); }
} catch (Exception)
} {
// ignored
}
if (cueLed == null)
return null;
var center = cueLed.LedRectangle.GetCenter();
return new KeyMatch(keyCode, (int) (center.X*widthMultiplier), (int) (center.Y*heightMultiplier));
}
}
} }

View File

@ -8,7 +8,7 @@ using Ninject.Extensions.Logging;
namespace Artemis.DeviceProviders.Corsair namespace Artemis.DeviceProviders.Corsair
{ {
internal class CorsairMouse : DeviceProvider public class CorsairMouse : DeviceProvider
{ {
public CorsairMouse(ILogger logger) public CorsairMouse(ILogger logger)
{ {
@ -22,7 +22,7 @@ namespace Artemis.DeviceProviders.Corsair
{ {
CanUse = CanInitializeSdk(); CanUse = CanInitializeSdk();
if (CanUse && !CueSDK.IsInitialized) if (CanUse && !CueSDK.IsInitialized)
CueSDK.Initialize(true); CueSDK.Initialize();
Logger.Debug("Attempted to enable Corsair mice. CanUse: {0}", CanUse); Logger.Debug("Attempted to enable Corsair mice. CanUse: {0}", CanUse);

View File

@ -8,7 +8,7 @@ using Ninject.Extensions.Logging;
namespace Artemis.DeviceProviders.Corsair namespace Artemis.DeviceProviders.Corsair
{ {
internal class CorsairMousemat : DeviceProvider public class CorsairMousemat : DeviceProvider
{ {
public CorsairMousemat(ILogger logger) public CorsairMousemat(ILogger logger)
{ {
@ -22,7 +22,7 @@ namespace Artemis.DeviceProviders.Corsair
{ {
CanUse = CanInitializeSdk(); CanUse = CanInitializeSdk();
if (CanUse && !CueSDK.IsInitialized) if (CanUse && !CueSDK.IsInitialized)
CueSDK.Initialize(true); CueSDK.Initialize();
Logger.Debug("Attempted to enable Corsair mousemat. CanUse: {0}", CanUse); Logger.Debug("Attempted to enable Corsair mousemat. CanUse: {0}", CanUse);

View File

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

View File

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

View File

@ -0,0 +1,22 @@
using System;
using System.Windows.Media;
using Artemis.Models.Interfaces;
namespace Artemis.Events
{
public class ProfileDeviceEventsArg : EventArgs
{
public ProfileDeviceEventsArg(string updateType, IDataModel dataModel, bool preview, DrawingContext drawingContext)
{
UpdateType = updateType;
DataModel = dataModel;
Preview = preview;
DrawingContext = drawingContext;
}
public string UpdateType { get; }
public IDataModel DataModel { get; }
public bool Preview { get; }
public DrawingContext DrawingContext { get; }
}
}

View File

@ -1,39 +1,135 @@
using Artemis.Modules.Effects.ProfilePreview; using Artemis.DeviceProviders;
using Artemis.Services; using Artemis.Models;
using Artemis.Utilities.DataReaders; using Artemis.Modules.Effects.ProfilePreview;
using Artemis.Utilities.GameState; using Artemis.Profiles.Layers.Interfaces;
using Artemis.ViewModels; using Artemis.Profiles.Layers.Types.AmbientLight;
using Artemis.ViewModels.Abstract; using Artemis.Profiles.Layers.Types.Audio;
using Artemis.ViewModels.Profiles; using Artemis.Profiles.Layers.Types.Audio.AudioCapturing;
using Ninject.Modules; using Artemis.Profiles.Layers.Types.KeyPress;
using Artemis.Profiles.Lua;
namespace Artemis.InjectionModules using Artemis.Services;
{ using Artemis.Utilities.DataReaders;
internal class BaseModules : NinjectModule using Artemis.Utilities.GameState;
{ using Artemis.ViewModels;
public override void Load() using Artemis.ViewModels.Abstract;
{ using Artemis.ViewModels.Profiles;
// ViewModels using Ninject.Extensions.Conventions;
Bind<ShellViewModel>().ToSelf().InSingletonScope(); using Ninject.Modules;
Bind<ProfileViewModel>().ToSelf();
Bind<ProfileEditorViewModel>().ToSelf(); namespace Artemis.InjectionModules
Bind<DebugViewModel>().ToSelf().InSingletonScope(); {
public class BaseModules : NinjectModule
Bind<BaseViewModel>().To<WelcomeViewModel>(); {
Bind<BaseViewModel>().To<EffectsViewModel>(); public override void Load()
Bind<BaseViewModel>().To<GamesViewModel>(); {
Bind<BaseViewModel>().To<OverlaysViewModel>(); #region ViewModels
// Models Bind<ShellViewModel>().ToSelf().InSingletonScope();
Bind<ProfilePreviewModel>().ToSelf().InSingletonScope(); Bind<ProfileViewModel>().ToSelf();
Bind<ProfileEditorViewModel>().ToSelf();
// Services Bind<DebugViewModel>().ToSelf().InSingletonScope();
Bind<MetroDialogService>().ToSelf().InSingletonScope(); Kernel.Bind(x =>
Bind<WindowService>().ToSelf().InSingletonScope(); x.FromThisAssembly()
.SelectAllClasses()
// Servers .InheritedFrom<BaseViewModel>()
Bind<GameStateWebServer>().ToSelf().InSingletonScope(); .BindAllBaseClasses());
Bind<PipeServer>().ToSelf().InSingletonScope();
} #endregion
}
#region Models
Bind<ProfilePreviewModel>().ToSelf().InSingletonScope();
#endregion
#region Services
Bind<MetroDialogService>().ToSelf().InSingletonScope();
Bind<WindowService>().ToSelf().InSingletonScope();
#endregion
#region Servers
Bind<GameStateWebServer>().ToSelf().InSingletonScope();
Bind<PipeServer>().ToSelf().InSingletonScope();
#endregion
#region Devices
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<DeviceProvider>()
.BindAllBaseClasses());
#endregion
#region Effects
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<EffectModel>()
.BindAllBaseClasses()
.Configure((b, c) => b.InSingletonScope().Named(c.Name))
);
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<EffectViewModel>()
.BindBase());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<GameViewModel>()
.BindBase());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<OverlayViewModel>()
.BindBase());
#endregion
#region Profiles
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<ILayerAnimation>()
.BindAllInterfaces());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<ILayerCondition>()
.BindAllInterfaces());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<ILayerType>()
.BindAllInterfaces());
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<ILayerType>()
.BindToSelf());
// Type helpers
Bind<AudioCaptureManager>().ToSelf().InSingletonScope();
#endregion
#region Lua
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<LuaModule>()
.BindAllBaseClasses());
#endregion
}
}
} }

View File

@ -1,37 +0,0 @@
using Artemis.DeviceProviders;
using Artemis.DeviceProviders.Artemis;
using Artemis.DeviceProviders.CoolerMaster;
using Artemis.DeviceProviders.Corsair;
using Artemis.DeviceProviders.Logitech;
using Artemis.DeviceProviders.Razer;
using Ninject.Modules;
namespace Artemis.InjectionModules
{
public class DeviceModules : NinjectModule
{
public override void Load()
{
// Keyboards
Bind<DeviceProvider>().To<NoneKeyboard>().InSingletonScope();
Bind<DeviceProvider>().To<CorsairKeyboard>().InSingletonScope();
Bind<DeviceProvider>().To<G910>().InSingletonScope();
Bind<DeviceProvider>().To<G810>().InSingletonScope();
Bind<DeviceProvider>().To<BlackWidow>().InSingletonScope();
Bind<DeviceProvider>().To<MasterkeysProL>().InSingletonScope();
Bind<DeviceProvider>().To<MasterkeysProS>().InSingletonScope();
// Mice
Bind<DeviceProvider>().To<CorsairMouse>().InSingletonScope();
// Headsets
Bind<DeviceProvider>().To<CorsairHeadset>().InSingletonScope();
// Mousemats
Bind<DeviceProvider>().To<CorsairMousemat>().InSingletonScope();
// Other
Bind<DeviceProvider>().To<LogitechGeneric>().InSingletonScope();
}
}
}

View File

@ -1,47 +0,0 @@
using Artemis.Models;
using Artemis.ViewModels.Abstract;
using Ninject.Extensions.Conventions;
using Ninject.Modules;
namespace Artemis.InjectionModules
{
public class EffectModules : NinjectModule
{
public override void Load()
{
// Effects
Kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<EffectModel>()
.BindBase()
.Configure((b, c) => b.InSingletonScope().Named(c.Name));
});
// View models
Kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<EffectViewModel>()
.BindBase();
});
Kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<GameViewModel>()
.BindBase();
});
Kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<OverlayViewModel>()
.BindBase();
});
}
}
}

View File

@ -3,7 +3,7 @@ using Ninject.Modules;
namespace Artemis.InjectionModules namespace Artemis.InjectionModules
{ {
internal class ManagerModules : NinjectModule public class ManagerModules : NinjectModule
{ {
public override void Load() public override void Load()
{ {
@ -12,6 +12,7 @@ namespace Artemis.InjectionModules
Bind<DeviceManager>().ToSelf().InSingletonScope(); Bind<DeviceManager>().ToSelf().InSingletonScope();
Bind<EffectManager>().ToSelf().InSingletonScope(); Bind<EffectManager>().ToSelf().InSingletonScope();
Bind<ProfileManager>().ToSelf().InSingletonScope(); Bind<ProfileManager>().ToSelf().InSingletonScope();
Bind<LuaManager>().ToSelf().InSingletonScope();
} }
} }
} }

View File

@ -1,57 +0,0 @@
using Artemis.Profiles.Layers.Animations;
using Artemis.Profiles.Layers.Conditions;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Types.AmbientLight;
using Artemis.Profiles.Layers.Types.Audio;
using Artemis.Profiles.Layers.Types.Audio.AudioCapturing;
using Artemis.Profiles.Layers.Types.Folder;
using Artemis.Profiles.Layers.Types.Generic;
using Artemis.Profiles.Layers.Types.Headset;
using Artemis.Profiles.Layers.Types.Keyboard;
using Artemis.Profiles.Layers.Types.KeyboardGif;
using Artemis.Profiles.Layers.Types.KeyPress;
using Artemis.Profiles.Layers.Types.Mouse;
using Artemis.Profiles.Layers.Types.Mousemat;
using Ninject.Modules;
namespace Artemis.InjectionModules
{
public class ProfileModules : NinjectModule
{
public override void Load()
{
// Animations
Bind<ILayerAnimation>().To<NoneAnimation>();
Bind<ILayerAnimation>().To<GrowAnimation>();
Bind<ILayerAnimation>().To<PulseAnimation>();
Bind<ILayerAnimation>().To<SlideDownAnimation>();
Bind<ILayerAnimation>().To<SlideLeftAnimation>();
Bind<ILayerAnimation>().To<SlideRightAnimation>();
Bind<ILayerAnimation>().To<SlideUpAnimation>();
// Conditions
Bind<ILayerCondition>().To<DataModelCondition>();
Bind<ILayerCondition>().To<EventCondition>();
// Types
Bind<ILayerType>().To<FolderType>();
Bind<ILayerType>().To<HeadsetType>();
Bind<ILayerType>().To<KeyboardType>();
Bind<ILayerType>().To<KeyboardGifType>();
Bind<ILayerType>().To<MouseType>();
Bind<ILayerType>().To<MousematType>();
Bind<ILayerType>().To<GenericType>();
Bind<ILayerType>().To<KeyPressType>();
Bind<ILayerType>().To<AudioType>();
Bind<ILayerType>().To<AmbientLightType>();
// Bind some Layer Types to self as well in order to allow JSON.NET injection
Bind<KeyPressType>().ToSelf();
Bind<AudioType>().ToSelf();
Bind<AmbientLightType>().ToSelf();
// Type helpers
Bind<AudioCaptureManager>().ToSelf().InSingletonScope();
}
}
}

View File

@ -35,8 +35,8 @@ namespace Artemis.Managers
models.AddRange(overlayModels); models.AddRange(overlayModels);
// Add games, exclude WoW if needed // Add games, exclude WoW if needed
models.AddRange(_generalSettings.GamestatePort != 62575 models.AddRange(_generalSettings.GamestatePort != 62575
? gameModels.Where(e => e.Name != "WoW") ? gameModels.Where(e => e.Name != "WoW").Where(e => e.Name != "LightFX")
: gameModels); : gameModels.Where(e => e.Name != "LightFX"));
EffectModels = models; EffectModels = models;
_logger.Info("Intialized EffectManager"); _logger.Info("Intialized EffectManager");
@ -72,7 +72,7 @@ namespace Artemis.Managers
/// </summary> /// </summary>
public IEnumerable<GameModel> EnabledGames 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; public event EventHandler<EffectChangedEventArgs> OnEffectChangedEvent;
@ -138,14 +138,16 @@ namespace Artemis.Managers
{ {
if (!wasNull) if (!wasNull)
ActiveEffect.Dispose(); ActiveEffect.Dispose();
lock (effectModel)
ActiveEffect = effectModel;
ActiveEffect.Enable();
if (!ActiveEffect.Initialized)
{ {
_logger.Debug("Cancelling effect change, couldn't initialize the effect ({0})", effectModel.Name); ActiveEffect = effectModel;
ActiveEffect = null; ActiveEffect.Enable();
return; if (!ActiveEffect.Initialized)
{
_logger.Debug("Cancelling effect change, couldn't initialize the effect ({0})", effectModel.Name);
ActiveEffect = null;
return;
}
} }
} }

View File

@ -22,7 +22,6 @@ namespace Artemis.Managers
private readonly EffectManager _effectManager; private readonly EffectManager _effectManager;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly Timer _loopTimer; private readonly Timer _loopTimer;
private bool _canShowException;
public LoopManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager, public LoopManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager,
DebugViewModel debugViewModel) DebugViewModel debugViewModel)
@ -31,7 +30,6 @@ namespace Artemis.Managers
_effectManager = effectManager; _effectManager = effectManager;
_deviceManager = deviceManager; _deviceManager = deviceManager;
_debugViewModel = debugViewModel; _debugViewModel = debugViewModel;
_canShowException = true;
// Setup timers // Setup timers
_loopTimer = new Timer(40); _loopTimer = new Timer(40);

View File

@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Artemis.DeviceProviders;
using Artemis.Profiles;
using Artemis.Profiles.Lua;
using Artemis.Profiles.Lua.Modules;
using Castle.Core.Internal;
using MoonSharp.Interpreter;
using Ninject;
using Ninject.Extensions.Logging;
namespace Artemis.Managers
{
public class LuaManager
{
private readonly DeviceManager _deviceManager;
private readonly IKernel _kernel;
private readonly ILogger _logger;
private readonly Script _luaScript;
private List<LuaModule> _luaModules;
public LuaManager(IKernel kernel, ILogger logger, DeviceManager deviceManager)
{
_kernel = kernel;
_logger = logger;
_deviceManager = deviceManager;
_luaScript = new Script(CoreModules.Preset_SoftSandbox);
}
public ProfileModel ProfileModel { get; private set; }
public KeyboardProvider KeyboardProvider { get; private set; }
public LuaProfileModule ProfileModule { get; private set; }
public LuaEventsModule EventsModule { get; private set; }
public void SetupLua(ProfileModel profileModel)
{
_logger.Debug("Setting up LUA for {0}-{1}.", profileModel?.Name, profileModel?.GameName);
// Clear old state
ClearLua();
// Stop after that if no model provided/there is no keyboard
if (profileModel == null || _deviceManager.ActiveKeyboard == null)
return;
ProfileModel = profileModel;
KeyboardProvider = _deviceManager.ActiveKeyboard;
// Get new instances of all modules
_luaModules = _kernel.Get<List<LuaModule>>();
ProfileModule = (LuaProfileModule) _luaModules.First(m => m.ModuleName == "Profile");
EventsModule = (LuaEventsModule) _luaModules.First(m => m.ModuleName == "Events");
// Setup new state
_luaScript.Options.DebugPrint = LuaPrint;
// Insert each module into the script's globals
foreach (var luaModule in _luaModules)
_luaScript.Globals[luaModule.ModuleName] = luaModule;
// If there is no LUA script, don't bother executing the string
if (ProfileModel.LuaScript.IsNullOrEmpty())
return;
try
{
lock (EventsModule.InvokeLock)
{
lock (_luaScript)
{
_luaScript.DoString(ProfileModel.LuaScript);
}
}
}
catch (InternalErrorException e)
{
_logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
catch (SyntaxErrorException e)
{
_logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
catch (ScriptRuntimeException e)
{
_logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
}
public void ClearLua()
{
if (_luaModules != null)
{
foreach (var luaModule in _luaModules)
luaModule.Dispose();
_luaModules.Clear();
}
try
{
_luaScript.Globals.Clear();
_luaScript.Registry.Clear();
_luaScript.Registry.RegisterConstants();
_luaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
_luaScript.Globals.RegisterConstants();
_luaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
}
catch (NullReferenceException)
{
// TODO: Ask MoonSharp folks why this is happening
}
if (EventsModule != null)
lock (EventsModule.InvokeLock)
{
lock (_luaScript)
{
_luaScript.DoString("");
}
}
else
lock (_luaScript)
{
_luaScript.DoString("");
}
}
/// <summary>
/// Safely call a function on the active script
/// </summary>
/// <param name="function"></param>
/// <param name="args"></param>
public void Call(DynValue function, DynValue[] args = null)
{
if (EventsModule == null)
return;
try
{
lock (EventsModule.InvokeLock)
{
lock (_luaScript)
{
if (args != null)
_luaScript.Call(function, args);
else
_luaScript.Call(function);
}
}
}
catch (ArgumentException e)
{
_logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.Message);
}
catch (InternalErrorException e)
{
_logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
catch (SyntaxErrorException e)
{
_logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
catch (ScriptRuntimeException e)
{
_logger.Error("[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
}
#region Private lua functions
private void LuaPrint(string s)
{
_logger.Info("[{0}-LUA]: {1}", ProfileModel?.Name, s);
}
#endregion
}
}

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -10,6 +9,7 @@ using Artemis.Utilities;
using Artemis.Utilities.DataReaders; using Artemis.Utilities.DataReaders;
using Artemis.Utilities.GameState; using Artemis.Utilities.GameState;
using Artemis.ViewModels; using Artemis.ViewModels;
using Microsoft.Win32;
using Ninject; using Ninject;
using Ninject.Extensions.Logging; using Ninject.Extensions.Logging;
@ -51,6 +51,9 @@ namespace Artemis.Managers
var updateTask = new Task(Updater.UpdateApp); var updateTask = new Task(Updater.UpdateApp);
updateTask.Start(); updateTask.Start();
// Listen for power mode changes
SystemEvents.PowerModeChanged += OnPowerChange;
Logger.Info("Intialized MainManager"); Logger.Info("Intialized MainManager");
Logger.Info($"Artemis version {Assembly.GetExecutingAssembly().GetName().Version} is ready!"); Logger.Info($"Artemis version {Assembly.GetExecutingAssembly().GetName().Version} is ready!");
} }
@ -83,6 +86,23 @@ namespace Artemis.Managers
public event EventHandler<EnabledChangedEventArgs> OnEnabledChangedEvent; 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> /// <summary>
/// Loads the last active effect and starts the program /// Loads the last active effect and starts the program
/// </summary> /// </summary>
@ -124,13 +144,11 @@ namespace Artemis.Managers
// If the currently active effect is a no longer running game, get rid of it. // If the currently active effect is a no longer running game, get rid of it.
var activeGame = EffectManager.ActiveEffect as GameModel; var activeGame = EffectManager.ActiveEffect as GameModel;
if (activeGame != null) if (activeGame != null)
{
if (!runningProcesses.Any(p => p.ProcessName == activeGame.ProcessName && p.HasExited == false)) if (!runningProcesses.Any(p => p.ProcessName == activeGame.ProcessName && p.HasExited == false))
{ {
Logger.Info("Disabling game: {0}", activeGame.Name); Logger.Info("Disabling game: {0}", activeGame.Name);
EffectManager.DisableGame(activeGame); EffectManager.DisableGame(activeGame);
} }
}
// Look for running games, stopping on the first one that's found. // Look for running games, stopping on the first one that's found.
var newGame = EffectManager.EnabledGames var newGame = EffectManager.EnabledGames

View File

@ -23,26 +23,26 @@ namespace Artemis.Models
protected DateTime LastTrace; protected DateTime LastTrace;
protected EffectModel(DeviceManager deviceManager, EffectSettings settings, IDataModel dataModel) protected EffectModel(DeviceManager deviceManager, LuaManager luaManager, EffectSettings settings,
IDataModel dataModel)
{ {
DeviceManager = deviceManager; DeviceManager = deviceManager;
LuaManager = luaManager;
Settings = settings; Settings = settings;
DataModel = dataModel; 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; DeviceManager.OnKeyboardChangedEvent += DeviceManagerOnOnKeyboardChangedEvent;
} }
public bool Initialized { get; set; } public bool Initialized { get; set; }
public DeviceManager DeviceManager { get; set; } public DeviceManager DeviceManager { get; set; }
public LuaManager LuaManager { get; }
public EffectSettings Settings { get; set; } public EffectSettings Settings { get; set; }
public string Name { get; set; } public string Name { get; set; }
public int KeyboardScale { get; set; } = 4; public int KeyboardScale { get; set; } = 4;
// Used by profile system // Used by profile system
public IDataModel DataModel { get; set; } public IDataModel DataModel { get; set; }
public ProfileModel Profile { get; set; } public ProfileModel Profile { get; set; }
[Inject] [Inject]
@ -50,17 +50,34 @@ namespace Artemis.Models
public virtual void Dispose() public virtual void Dispose()
{ {
Profile?.Deactivate(); Profile?.Deactivate(LuaManager);
Profile = null;
} }
private void DeviceManagerOnOnKeyboardChangedEvent(object sender, KeyboardChangedEventArgs args) private void DeviceManagerOnOnKeyboardChangedEvent(object sender, KeyboardChangedEventArgs args)
{ {
if (!Initialized)
return;
if (!string.IsNullOrEmpty(Settings?.LastProfile)) if (!string.IsNullOrEmpty(Settings?.LastProfile))
Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, Settings.LastProfile); Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, Settings.LastProfile);
else
Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, "Default");
Profile?.Activate(LuaManager);
} }
// Called on creation // 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 // Called every frame
public abstract void Update(); public abstract void Update();
@ -73,9 +90,9 @@ namespace Artemis.Models
/// <param name="keyboardOnly"></param> /// <param name="keyboardOnly"></param>
public virtual void Render(RenderFrame frame, bool keyboardOnly) 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; return;
lock (DataModel) lock (DataModel)
{ {
lock (Profile) lock (Profile)
@ -85,7 +102,7 @@ namespace Artemis.Models
// If the profile has no active LUA wrapper, create one // If the profile has no active LUA wrapper, create one
if (!string.IsNullOrEmpty(Profile.LuaScript)) if (!string.IsNullOrEmpty(Profile.LuaScript))
Profile.Activate(DeviceManager.ActiveKeyboard); Profile.Activate(LuaManager);
// Render the keyboard layer-by-layer // Render the keyboard layer-by-layer
var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale); var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);

View File

@ -6,7 +6,8 @@ namespace Artemis.Models
{ {
public abstract class GameModel : EffectModel 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 // Override settings to the GameSettings type
Settings = settings; Settings = settings;

View File

@ -8,7 +8,8 @@ namespace Artemis.Models
private bool _enabled; private bool _enabled;
public string ProcessName; 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; Settings = settings;
Enabled = settings.Enabled; Enabled = settings.Enabled;

View File

@ -15,7 +15,8 @@ namespace Artemis.Modules.Effects.Bubbles
{ {
#region Constructors #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"; Name = "Bubbles";
Initialized = false; Initialized = false;
@ -41,7 +42,7 @@ namespace Artemis.Modules.Effects.Bubbles
KeyboardScale = Settings.Smoothness; KeyboardScale = Settings.Smoothness;
var rect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale); 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++) for (var i = 0; i < Settings.BubbleCount; i++)
{ {
@ -49,16 +50,18 @@ namespace Artemis.Modules.Effects.Bubbles
? ColorHelpers.GetRandomRainbowColor() ? ColorHelpers.GetRandomRainbowColor()
: ColorHelpers.ToDrawingColor(Settings.BubbleColor); : ColorHelpers.ToDrawingColor(Settings.BubbleColor);
// -Settings.MoveSpeed because we want to spawn at least one move away from borders // -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)* var initialPositionX = (rect.Width - Settings.BubbleSize * scaleFactor * 2 -
_random.NextDouble() + Settings.BubbleSize*scaleFactor; Settings.MoveSpeed * scaleFactor) *
var initialPositionY = (rect.Height - Settings.BubbleSize*scaleFactor*2 - Settings.MoveSpeed*scaleFactor)* _random.NextDouble() + Settings.BubbleSize * scaleFactor;
_random.NextDouble() + Settings.BubbleSize*scaleFactor; var initialPositionY = (rect.Height - Settings.BubbleSize * scaleFactor * 2 -
var initialDirectionX = Settings.MoveSpeed*scaleFactor*_random.NextDouble()* Settings.MoveSpeed * scaleFactor) *
_random.NextDouble() + Settings.BubbleSize * scaleFactor;
var initialDirectionX = Settings.MoveSpeed * scaleFactor * _random.NextDouble() *
(_random.Next(1) == 0 ? -1 : 1); (_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); (_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))); new Point(initialPositionX, initialPositionY), new Vector(initialDirectionX, initialDirectionY)));
} }
@ -79,7 +82,7 @@ namespace Artemis.Modules.Effects.Bubbles
if (Settings.IsShiftColors) if (Settings.IsShiftColors)
bubble.Color = ColorHelpers.ShiftColor(bubble.Color, bubble.Color = ColorHelpers.ShiftColor(bubble.Color,
Settings.IsRandomColors Settings.IsRandomColors
? (int) Math.Round(Settings.ShiftColorSpeed*_random.NextDouble()) ? (int) Math.Round(Settings.ShiftColorSpeed * _random.NextDouble())
: Settings.ShiftColorSpeed); : Settings.ShiftColorSpeed);
bubble.CheckCollision(keyboardRectangle); bubble.CheckCollision(keyboardRectangle);

View File

@ -16,8 +16,7 @@ namespace Artemis.Modules.Effects.ProfilePreview
{ {
public class ProfilePreviewModel : EffectModel public class ProfilePreviewModel : EffectModel
{ {
public ProfilePreviewModel(DeviceManager deviceManager) public ProfilePreviewModel(DeviceManager deviceManager, LuaManager luaManager): base(deviceManager, luaManager, null, new ProfilePreviewDataModel())
: base(deviceManager, null, new ProfilePreviewDataModel())
{ {
Name = "Profile Preview"; Name = "Profile Preview";
} }
@ -55,8 +54,8 @@ namespace Artemis.Modules.Effects.ProfilePreview
var renderLayers = GetRenderLayers(keyboardOnly); var renderLayers = GetRenderLayers(keyboardOnly);
// If the profile has no active LUA wrapper, create one // If the profile has no active LUA wrapper, create one
if (!Equals(LuaWrapper.ProfileModel, Profile)) if (!Equals(LuaManager.ProfileModel, Profile))
Profile.Activate(DeviceManager.ActiveKeyboard); Profile.Activate(LuaManager);
// Render the keyboard layer-by-layer // Render the keyboard layer-by-layer
var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale); var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);

View File

@ -1,262 +1,275 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Net;
using System.Threading; using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading;
using Artemis.DAL; using System.Threading.Tasks;
using Artemis.Managers; using Artemis.DAL;
using Artemis.Models; using Artemis.Managers;
using Artemis.Profiles.Layers.Models; using Artemis.Models;
using Artemis.Utilities; using Artemis.Profiles.Layers.Models;
using Newtonsoft.Json; using Artemis.Utilities;
using SpotifyAPI.Local; using Newtonsoft.Json;
using SpotifyAPI.Local;
namespace Artemis.Modules.Effects.WindowsProfile
{ namespace Artemis.Modules.Effects.WindowsProfile
public class WindowsProfileModel : EffectModel {
{ public class WindowsProfileModel : EffectModel
private List<PerformanceCounter> _cores; {
private int _cpuFrames; private List<PerformanceCounter> _cores;
private DateTime _lastMusicUpdate; private int _cpuFrames;
private PerformanceCounter _overallCpu; private DateTime _lastMusicUpdate;
private SpotifyLocalAPI _spotify; private PerformanceCounter _overallCpu;
private bool _spotifySetupBusy; private SpotifyLocalAPI _spotify;
private bool _spotifySetupBusy;
public WindowsProfileModel(DeviceManager deviceManager)
: base(deviceManager, SettingsProvider.Load<WindowsProfileSettings>(), new WindowsProfileDataModel()) public WindowsProfileModel(DeviceManager deviceManager, LuaManager luaManager)
{ : base(deviceManager, luaManager, SettingsProvider.Load<WindowsProfileSettings>(),
_lastMusicUpdate = DateTime.Now; new WindowsProfileDataModel())
{
Name = "WindowsProfile"; _lastMusicUpdate = DateTime.Now;
}
Name = "WindowsProfile";
public override void Dispose() }
{
Initialized = false; public override void Dispose()
base.Dispose(); {
} Initialized = false;
base.Dispose();
public override void Enable() }
{
SetupCpu(); public override void Enable()
SetupSpotify(); {
base.Enable();
Initialized = true;
} SetupCpu();
SetupSpotify();
public override void Update()
{ Initialized = true;
var dataModel = (WindowsProfileDataModel) DataModel; }
UpdateCpu(dataModel);
UpdateMusicPlayers(dataModel); public override void Update()
UpdateDay(dataModel); {
UpdateKeyStates(dataModel); var dataModel = (WindowsProfileDataModel) DataModel;
UpdateActiveWindow(dataModel); UpdateCpu(dataModel);
} UpdateMusicPlayers(dataModel);
UpdateDay(dataModel);
#region Current Time UpdateKeyStates(dataModel);
UpdateActiveWindow(dataModel);
private void UpdateDay(WindowsProfileDataModel dataModel) }
{
var now = DateTime.Now; #region Current Time
dataModel.CurrentTime.Hours24 = int.Parse(now.ToString("HH"));
dataModel.CurrentTime.Hours12 = int.Parse(now.ToString("hh")); private void UpdateDay(WindowsProfileDataModel dataModel)
dataModel.CurrentTime.Minutes = int.Parse(now.ToString("mm")); {
dataModel.CurrentTime.Seconds = int.Parse(now.ToString("ss")); var now = DateTime.Now;
} dataModel.CurrentTime.Hours24 = int.Parse(now.ToString("HH"));
dataModel.CurrentTime.Hours12 = int.Parse(now.ToString("hh"));
#endregion dataModel.CurrentTime.Minutes = int.Parse(now.ToString("mm"));
dataModel.CurrentTime.Seconds = int.Parse(now.ToString("ss"));
#region CPU }
private void SetupCpu() #endregion
{
try #region CPU
{
_cores = GetPerformanceCounters(); private void SetupCpu()
var coreCount = _cores.Count; {
while (coreCount < 8) try
{ {
_cores.Add(null); _cores = GetPerformanceCounters();
coreCount++; var coreCount = _cores.Count;
} while (coreCount < 8)
_overallCpu = GetOverallPerformanceCounter(); {
} _cores.Add(null);
catch (InvalidOperationException) coreCount++;
{ }
Logger?.Warn("Failed to setup CPU information, try running \"lodctr /R\" as administrator."); _overallCpu = GetOverallPerformanceCounter();
} }
} catch (InvalidOperationException)
{
private void UpdateCpu(WindowsProfileDataModel dataModel) Logger?.Warn("Failed to setup CPU information, try running \"lodctr /R\" as administrator.");
{ }
if ((_cores == null) || (_overallCpu == null)) }
return;
private void UpdateCpu(WindowsProfileDataModel dataModel)
// CPU is only updated every 15 frames, the performance counter gives 0 if updated too often {
_cpuFrames++; if ((_cores == null) || (_overallCpu == null))
if (_cpuFrames < 16) return;
return;
// CPU is only updated every 15 frames, the performance counter gives 0 if updated too often
_cpuFrames = 0; _cpuFrames++;
if (_cpuFrames < 16)
// Update cores, not ideal but data models don't support lists. return;
if (_cores[0] != null)
dataModel.Cpu.Core1Usage = (int) _cores[0].NextValue(); _cpuFrames = 0;
if (_cores[1] != null)
dataModel.Cpu.Core2Usage = (int) _cores[1].NextValue(); // Update cores, not ideal but data models don't support lists.
if (_cores[2] != null) if (_cores[0] != null)
dataModel.Cpu.Core3Usage = (int) _cores[2].NextValue(); dataModel.Cpu.Core1Usage = (int) _cores[0].NextValue();
if (_cores[3] != null) if (_cores[1] != null)
dataModel.Cpu.Core4Usage = (int) _cores[3].NextValue(); dataModel.Cpu.Core2Usage = (int) _cores[1].NextValue();
if (_cores[4] != null) if (_cores[2] != null)
dataModel.Cpu.Core5Usage = (int) _cores[4].NextValue(); dataModel.Cpu.Core3Usage = (int) _cores[2].NextValue();
if (_cores[5] != null) if (_cores[3] != null)
dataModel.Cpu.Core6Usage = (int) _cores[5].NextValue(); dataModel.Cpu.Core4Usage = (int) _cores[3].NextValue();
if (_cores[6] != null) if (_cores[4] != null)
dataModel.Cpu.Core7Usage = (int) _cores[6].NextValue(); dataModel.Cpu.Core5Usage = (int) _cores[4].NextValue();
if (_cores[7] != null) if (_cores[5] != null)
dataModel.Cpu.Core8Usage = (int) _cores[7].NextValue(); dataModel.Cpu.Core6Usage = (int) _cores[5].NextValue();
if (_cores[6] != null)
//From Ted - Let's get overall RAM and CPU usage here dataModel.Cpu.Core7Usage = (int) _cores[6].NextValue();
dataModel.Cpu.TotalUsage = (int) _overallCpu.NextValue(); if (_cores[7] != null)
dataModel.Cpu.Core8Usage = (int) _cores[7].NextValue();
var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
var tot = PerformanceInfo.GetTotalMemoryInMiB(); //From Ted - Let's get overall RAM and CPU usage here
var percentFree = phav/(decimal) tot*100; dataModel.Cpu.TotalUsage = (int) _overallCpu.NextValue();
var percentOccupied = 100 - percentFree;
var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
dataModel.Performance.RAMUsage = (int) percentOccupied; var tot = PerformanceInfo.GetTotalMemoryInMiB();
} var percentFree = phav / (decimal) tot * 100;
var percentOccupied = 100 - percentFree;
public override List<LayerModel> GetRenderLayers(bool keyboardOnly)
{ dataModel.Performance.RAMUsage = (int) percentOccupied;
return Profile.GetRenderLayers(DataModel, keyboardOnly, false); }
}
public override List<LayerModel> GetRenderLayers(bool keyboardOnly)
public static PerformanceCounter GetOverallPerformanceCounter() {
{ return Profile.GetRenderLayers(DataModel, keyboardOnly, false);
var cpuCounter = new PerformanceCounter }
{
CategoryName = "Processor", public static PerformanceCounter GetOverallPerformanceCounter()
CounterName = "% Processor Time", {
InstanceName = "_Total" var cpuCounter = new PerformanceCounter
}; {
CategoryName = "Processor",
return cpuCounter; CounterName = "% Processor Time",
} InstanceName = "_Total"
};
public static List<PerformanceCounter> GetPerformanceCounters()
{ return cpuCounter;
var performanceCounters = new List<PerformanceCounter>(); }
var procCount = Environment.ProcessorCount;
for (var i = 0; i < procCount; i++) public static List<PerformanceCounter> GetPerformanceCounters()
{ {
var pc = new PerformanceCounter("Processor", "% Processor Time", i.ToString()); var performanceCounters = new List<PerformanceCounter>();
performanceCounters.Add(pc); var procCount = Environment.ProcessorCount;
} for (var i = 0; i < procCount; i++)
return performanceCounters; {
} var pc = new PerformanceCounter("Processor", "% Processor Time", i.ToString());
performanceCounters.Add(pc);
#endregion }
return performanceCounters;
#region Music }
public void SetupSpotify() #endregion
{
if (_spotifySetupBusy) #region Music
return;
public void SetupSpotify()
_spotifySetupBusy = true; {
_spotify = new SpotifyLocalAPI(); if (_spotifySetupBusy)
return;
// Connecting can sometimes use a little bit more conviction
Task.Factory.StartNew(() => _spotifySetupBusy = true;
{ _spotify = new SpotifyLocalAPI();
var tryCount = 0;
while (tryCount <= 10) // Connecting can sometimes use a little bit more conviction
{ Task.Factory.StartNew(() =>
tryCount++; {
var connected = _spotify.Connect(); var tryCount = 0;
if (connected) while (tryCount <= 10)
break; {
Thread.Sleep(1000); // Causes WebException if not internet connection is available
} try
_spotifySetupBusy = false; {
}); tryCount++;
} var connected = _spotify.Connect();
if (connected)
public void UpdateMusicPlayers(WindowsProfileDataModel dataModel) break;
{ Thread.Sleep(1000);
// This is quite resource hungry so only update it once every two seconds }
if (DateTime.Now - _lastMusicUpdate < TimeSpan.FromSeconds(2)) catch (WebException)
return; {
_lastMusicUpdate = DateTime.Now; break;
}
UpdateSpotify(dataModel);
UpdateGooglePlayMusic(dataModel); }
} _spotifySetupBusy = false;
});
private void UpdateSpotify(WindowsProfileDataModel dataModel) }
{
// Spotify public void UpdateMusicPlayers(WindowsProfileDataModel dataModel)
if (!dataModel.Spotify.Running && SpotifyLocalAPI.IsSpotifyRunning()) {
SetupSpotify(); // This is quite resource hungry so only update it once every two seconds
if (DateTime.Now - _lastMusicUpdate < TimeSpan.FromSeconds(2))
var status = _spotify.GetStatus(); return;
if (status == null) _lastMusicUpdate = DateTime.Now;
return;
UpdateSpotify(dataModel);
dataModel.Spotify.Playing = status.Playing; UpdateGooglePlayMusic(dataModel);
dataModel.Spotify.Running = SpotifyLocalAPI.IsSpotifyRunning(); }
if (status.Track != null) private void UpdateSpotify(WindowsProfileDataModel dataModel)
{ {
dataModel.Spotify.Artist = status.Track.ArtistResource?.Name; // Spotify
dataModel.Spotify.SongName = status.Track.TrackResource?.Name; if (!dataModel.Spotify.Running && SpotifyLocalAPI.IsSpotifyRunning())
dataModel.Spotify.Album = status.Track.AlbumResource?.Name; SetupSpotify();
dataModel.Spotify.SongLength = status.Track.Length;
} var status = _spotify.GetStatus();
if (status == null)
if (dataModel.Spotify.SongLength > 0) return;
dataModel.Spotify.SongPercentCompleted =
(int) (status.PlayingPosition/dataModel.Spotify.SongLength*100.0); dataModel.Spotify.Playing = status.Playing;
} dataModel.Spotify.Running = SpotifyLocalAPI.IsSpotifyRunning();
private void UpdateGooglePlayMusic(WindowsProfileDataModel dataModel) if (status.Track != null)
{ {
// Google Play Music dataModel.Spotify.Artist = status.Track.ArtistResource?.Name;
var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); dataModel.Spotify.SongName = status.Track.TrackResource?.Name;
var json = appData + @"\Google Play Music Desktop Player\json_store\playback.json"; dataModel.Spotify.Album = status.Track.AlbumResource?.Name;
if (!File.Exists(json)) dataModel.Spotify.SongLength = status.Track.Length;
return; }
dataModel.GooglePlayMusic = JsonConvert.DeserializeObject<GooglePlayMusic>(File.ReadAllText(json)); if (dataModel.Spotify.SongLength > 0)
} dataModel.Spotify.SongPercentCompleted =
(int) (status.PlayingPosition / dataModel.Spotify.SongLength * 100.0);
#endregion }
#region System private void UpdateGooglePlayMusic(WindowsProfileDataModel dataModel)
{
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, // Google Play Music
CallingConvention = CallingConvention.Winapi)] var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
public static extern short GetKeyState(int keyCode); var json = appData + @"\Google Play Music Desktop Player\json_store\playback.json";
if (!File.Exists(json))
private void UpdateKeyStates(WindowsProfileDataModel dataModel) return;
{
dataModel.Keyboard.NumLock = ((ushort)GetKeyState(0x90) & 0xffff) != 0; dataModel.GooglePlayMusic = JsonConvert.DeserializeObject<GooglePlayMusic>(File.ReadAllText(json));
dataModel.Keyboard.CapsLock = ((ushort)GetKeyState(0x14) & 0xffff) != 0; }
dataModel.Keyboard.ScrollLock = ((ushort)GetKeyState(0x91) & 0xffff) != 0;
} #endregion
private void UpdateActiveWindow(WindowsProfileDataModel dataModel) #region System
{
dataModel.ActiveWindow.ProcessName = ActiveWindowHelper.ActiveWindowProcessName; [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true,
dataModel.ActiveWindow.WindowTitle = ActiveWindowHelper.ActiveWindowWindowTitle; CallingConvention = CallingConvention.Winapi)]
} public static extern short GetKeyState(int keyCode);
#endregion private void UpdateKeyStates(WindowsProfileDataModel dataModel)
} {
dataModel.Keyboard.NumLock = ((ushort) GetKeyState(0x90) & 0xffff) != 0;
dataModel.Keyboard.CapsLock = ((ushort) GetKeyState(0x14) & 0xffff) != 0;
dataModel.Keyboard.ScrollLock = ((ushort) GetKeyState(0x91) & 0xffff) != 0;
}
private void UpdateActiveWindow(WindowsProfileDataModel dataModel)
{
dataModel.ActiveWindow.ProcessName = ActiveWindowHelper.ActiveWindowProcessName;
dataModel.ActiveWindow.WindowTitle = ActiveWindowHelper.ActiveWindowWindowTitle;
}
#endregion
}
} }

View File

@ -22,7 +22,7 @@ namespace Artemis.Modules.Effects.WindowsProfile
IParameter[] args = IParameter[] args =
{ {
new ConstructorArgument("mainManager", main), new ConstructorArgument("mainManager", main),
new ConstructorArgument("gameModel", (WindowsProfileModel) EffectModel), new ConstructorArgument("effectModel", (WindowsProfileModel) EffectModel),
new ConstructorArgument("lastProfile", ((WindowsProfileSettings) EffectSettings).LastProfile) new ConstructorArgument("lastProfile", ((WindowsProfileSettings) EffectSettings).LastProfile)
}; };
ProfileEditor = kernel.Get<ProfileEditorViewModel>(args); ProfileEditor = kernel.Get<ProfileEditorViewModel>(args);

View File

@ -22,9 +22,10 @@ namespace Artemis.Modules.Games.CounterStrike
private DateTime _lastKill; private DateTime _lastKill;
private int _lastKills; private int _lastKills;
public CounterStrikeModel(DeviceManager deviceManager, GameStateWebServer gameStateWebServer, public CounterStrikeModel(DeviceManager deviceManager, LuaManager luaManager,
MetroDialogService dialogService) GameStateWebServer gameStateWebServer, MetroDialogService dialogService)
: base(deviceManager, SettingsProvider.Load<CounterStrikeSettings>(), new CounterStrikeDataModel()) : base(deviceManager, luaManager, SettingsProvider.Load<CounterStrikeSettings>(),
new CounterStrikeDataModel())
{ {
_gameStateWebServer = gameStateWebServer; _gameStateWebServer = gameStateWebServer;
_dialogService = dialogService; _dialogService = dialogService;
@ -51,6 +52,8 @@ namespace Artemis.Modules.Games.CounterStrike
public override void Enable() public override void Enable()
{ {
base.Enable();
_gameStateWebServer.GameDataReceived += HandleGameData; _gameStateWebServer.GameDataReceived += HandleGameData;
Initialized = true; Initialized = true;
} }

View File

@ -17,9 +17,9 @@ namespace Artemis.Modules.Games.Dota2
private readonly MetroDialogService _dialogService; private readonly MetroDialogService _dialogService;
private readonly GameStateWebServer _gameStateWebServer; private readonly GameStateWebServer _gameStateWebServer;
public Dota2Model(DeviceManager deviceManager, GameStateWebServer gameStateWebServer, public Dota2Model(DeviceManager deviceManager, LuaManager luaManager, GameStateWebServer gameStateWebServer,
MetroDialogService dialogService) MetroDialogService dialogService)
: base(deviceManager, SettingsProvider.Load<Dota2Settings>(), new Dota2DataModel()) : base(deviceManager, luaManager, SettingsProvider.Load<Dota2Settings>(), new Dota2DataModel())
{ {
_gameStateWebServer = gameStateWebServer; _gameStateWebServer = gameStateWebServer;
_dialogService = dialogService; _dialogService = dialogService;
@ -45,6 +45,8 @@ namespace Artemis.Modules.Games.Dota2
public override void Enable() public override void Enable()
{ {
base.Enable();
_gameStateWebServer.GameDataReceived += HandleGameData; _gameStateWebServer.GameDataReceived += HandleGameData;
Initialized = true; Initialized = true;
} }
@ -109,8 +111,8 @@ namespace Artemis.Modules.Games.Dota2
if (dataModel?.map?.daytime == null) if (dataModel?.map?.daytime == null)
return; return;
var timeLeft = 240 - dataModel.map.clock_time%240; var timeLeft = 240 - dataModel.map.clock_time % 240;
dataModel.map.dayCyclePercentage = (int) (100.00/240*timeLeft); dataModel.map.dayCyclePercentage = (int) (100.00 / 240 * timeLeft);
} }
public void HandleGameData(object sender, GameDataReceivedEventArgs e) public void HandleGameData(object sender, GameDataReceivedEventArgs e)

View File

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

View File

@ -4,7 +4,7 @@ using Artemis.Modules.Games.EurotruckSimulator2.Data.Reader;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data namespace Artemis.Modules.Games.EurotruckSimulator2.Data
{ {
internal class Ets2TelemetryData : IEts2TelemetryData public class Ets2TelemetryData : IEts2TelemetryData
{ {
private Box<Ets2TelemetryStructure> _rawData; 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; 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(); 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) public Ets2Vector(float x, float y, float z)
{ {
@ -69,7 +69,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
public float Z { get; } public float Z { get; }
} }
internal class Ets2Placement : IEts2Placement public class Ets2Placement : IEts2Placement
{ {
public Ets2Placement(float x, float y, float z, public Ets2Placement(float x, float y, float z,
float heading, float pitch, float roll) float heading, float pitch, float roll)
@ -90,7 +90,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
public float Roll { get; } public float Roll { get; }
} }
internal class Ets2Truck : IEts2Truck public class Ets2Truck : IEts2Truck
{ {
private readonly Box<Ets2TelemetryStructure> _rawData; 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; private readonly Box<Ets2TelemetryStructure> _rawData;
@ -271,7 +271,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2.Data
_rawData.Struct.trailerRotationZ); _rawData.Struct.trailerRotationZ);
} }
internal class Ets2Navigation : IEts2Navigation public class Ets2Navigation : IEts2Navigation
{ {
private readonly Box<Ets2TelemetryStructure> _rawData; 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; _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; 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) public Box(T @struct)
{ {

View File

@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data.Reader namespace Artemis.Modules.Games.EurotruckSimulator2.Data.Reader
{ {
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal struct Ets2TelemetryStructure public struct Ets2TelemetryStructure
{ {
private const int GeneralStringSize = 64; private const int GeneralStringSize = 64;

View File

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

View File

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

View File

@ -15,8 +15,8 @@ namespace Artemis.Modules.Games.GtaV
{ {
private readonly PipeServer _pipeServer; private readonly PipeServer _pipeServer;
public GtaVModel(DeviceManager deviceManager, PipeServer pipeServer) public GtaVModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
: base(deviceManager, SettingsProvider.Load<GtaVSettings>(), new GtaVDataModel()) : base(deviceManager, luaManager, SettingsProvider.Load<GtaVSettings>(), new GtaVDataModel())
{ {
_pipeServer = pipeServer; _pipeServer = pipeServer;
Name = "GTAV"; Name = "GTAV";
@ -27,6 +27,8 @@ namespace Artemis.Modules.Games.GtaV
public override void Enable() public override void Enable()
{ {
base.Enable();
DllManager.PlaceLogitechDll(); DllManager.PlaceLogitechDll();
_pipeServer.PipeMessage += PipeServerOnPipeMessage; _pipeServer.PipeMessage += PipeServerOnPipeMessage;
Initialized = true; Initialized = true;

View File

@ -0,0 +1,40 @@
using MoonSharp.Interpreter;
namespace Artemis.Modules.Games.LightFx.Data
{
[MoonSharpUserData]
public class LightFxState
{
public Device[] devices { get; set; }
public string game { get; set; }
public Mask mask { get; set; }
}
[MoonSharpUserData]
public class Device
{
public Light[] lights { get; set; }
}
[MoonSharpUserData]
public class Mask
{
public Light light { get; set; }
public int location { get; set; }
}
[MoonSharpUserData]
public class Light
{
public Color color { get; set; }
}
[MoonSharpUserData]
public class Color
{
public int brightness { get; set; }
public int red { get; set; }
public int green { get; set; }
public int blue { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using Artemis.Models.Interfaces;
using Artemis.Modules.Games.LightFx.Data;
using MoonSharp.Interpreter;
using Newtonsoft.Json;
namespace Artemis.Modules.Games.LightFx
{
[MoonSharpUserData]
public class LightFxDataModel : IDataModel
{
[JsonProperty(PropertyName = "lightFxState")]
public LightFxState LightFxState { get; set; }
public LightFxDataModel()
{
LightFxState = new LightFxState();
}
}
}

View File

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.IO;
using Artemis.DAL;
using Artemis.Managers;
using Artemis.Models;
using Artemis.Profiles.Layers.Models;
using Artemis.Utilities.DataReaders;
using Newtonsoft.Json;
namespace Artemis.Modules.Games.LightFx
{
public class LightFxModel : GameModel
{
public LightFxModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
: base(deviceManager, luaManager, SettingsProvider.Load<LightFxSettings>(), new LightFxDataModel())
{
Name = "LightFX";
ProcessName = "LoL";
Scale = 4;
Enabled = Settings.Enabled;
Initialized = false;
// This model can enable itself by changing its process name to the currently running Light FX game.
pipeServer.PipeMessage += PipeServerOnPipeMessage;
}
public int Scale { get; set; }
private void PipeServerOnPipeMessage(string msg)
{
// Ensure it's Light FX JSON
if (!msg.Contains("lightFxState"))
return;
// Deserialize and data
try
{
JsonConvert.PopulateObject(msg, DataModel);
}
catch (Exception ex)
{
Logger?.Error(ex, "Failed to deserialize LightFX JSON");
throw;
}
// Setup process name
ProcessName = Path.GetFileNameWithoutExtension(((LightFxDataModel) DataModel).LightFxState.game);
}
public override void Dispose()
{
Initialized = false;
base.Dispose();
}
public override void Enable()
{
base.Enable();
Initialized = true;
}
public override void Update()
{
}
public override List<LayerModel> GetRenderLayers(bool keyboardOnly)
{
return Profile.GetRenderLayers(DataModel, keyboardOnly);
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,18 @@
using System.Windows.Controls;
using System.Windows.Navigation;
namespace Artemis.Modules.Games.LightFx
{
public partial class LightFxView : UserControl
{
public LightFxView()
{
InitializeComponent();
}
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(e.Uri.ToString());
}
}
}

View File

@ -0,0 +1,16 @@
using Artemis.Managers;
using Artemis.Models;
using Artemis.ViewModels.Abstract;
using Ninject;
namespace Artemis.Modules.Games.LightFx
{
public sealed class LightFxViewModel : GameViewModel
{
public LightFxViewModel(MainManager main, IKernel kernel,
[Named("LightFxModel")] GameModel model) : base(main, model, kernel)
{
DisplayName = "Light FX";
}
}
}

View File

@ -29,9 +29,9 @@ namespace Artemis.Modules.Games.Overwatch
private DateTime _ultimateReady; private DateTime _ultimateReady;
private DateTime _ultimateUsed; private DateTime _ultimateUsed;
public OverwatchModel(DeviceManager deviceManager, PipeServer pipeServer, MetroDialogService dialogService, public OverwatchModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer,
DebugViewModel debugViewModel) MetroDialogService dialogService, DebugViewModel debugViewModel)
: base(deviceManager, SettingsProvider.Load<OverwatchSettings>(), new OverwatchDataModel()) : base(deviceManager, luaManager, SettingsProvider.Load<OverwatchSettings>(), new OverwatchDataModel())
{ {
_pipeServer = pipeServer; _pipeServer = pipeServer;
_dialogService = dialogService; _dialogService = dialogService;
@ -82,6 +82,8 @@ namespace Artemis.Modules.Games.Overwatch
public override void Enable() public override void Enable()
{ {
base.Enable();
_stickyStatus = new StickyValue<OverwatchStatus>(300); _stickyStatus = new StickyValue<OverwatchStatus>(300);
_stickyUltimateReady = new StickyValue<bool>(350); _stickyUltimateReady = new StickyValue<bool>(350);
_stickyUltimateUsed = 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 // Ultimate is ready when Q is blinking
var charCol = characterMatch.Value.Color; 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]); var ultReady = !backlidColor.Equals(colors[2, 2]);
if (_ultimateUsed.AddSeconds(15) <= DateTime.Now) if (_ultimateUsed.AddSeconds(15) <= DateTime.Now)
@ -291,7 +294,7 @@ namespace Artemis.Modules.Games.Overwatch
return; return;
var key = Registry.LocalMachine.OpenSubKey( 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(); var path = key?.GetValue("DisplayIcon")?.ToString();
if (string.IsNullOrEmpty(path) || !File.Exists(path)) if (string.IsNullOrEmpty(path) || !File.Exists(path))

View File

@ -7,12 +7,10 @@ namespace Artemis.Modules.Games.ProjectCars.Data
{ {
public class pCarsAPI_GetData public class pCarsAPI_GetData
{ {
private static pCarsAPIStruct structCurrent = new pCarsAPIStruct();
private static MemoryMappedFile memoryMappedFile; private static MemoryMappedFile memoryMappedFile;
private static GCHandle handle; private static GCHandle handle;
private static int sharedmemorysize; private static int sharedmemorysize;
private static byte[] sharedMemoryReadBuffer; private static byte[] sharedMemoryReadBuffer;
private static bool isSharedMemoryInitialised;
private static bool InitialiseSharedMemory() private static bool InitialiseSharedMemory()
{ {
@ -21,11 +19,10 @@ namespace Artemis.Modules.Games.ProjectCars.Data
memoryMappedFile = MemoryMappedFile.OpenExisting("$pcars$"); memoryMappedFile = MemoryMappedFile.OpenExisting("$pcars$");
sharedmemorysize = Marshal.SizeOf(typeof(pCarsAPIStruct)); sharedmemorysize = Marshal.SizeOf(typeof(pCarsAPIStruct));
sharedMemoryReadBuffer = new byte[sharedmemorysize]; sharedMemoryReadBuffer = new byte[sharedmemorysize];
isSharedMemoryInitialised = true;
return true; return true;
} }
catch (Exception ex) catch (Exception)
{ {
return false; return false;
} }
@ -42,8 +39,8 @@ namespace Artemis.Modules.Games.ProjectCars.Data
using (var sharedMemoryStreamView = memoryMappedFile.CreateViewStream()) using (var sharedMemoryStreamView = memoryMappedFile.CreateViewStream())
{ {
var _SharedMemoryStream = new BinaryReader(sharedMemoryStreamView); var sharedMemoryStream = new BinaryReader(sharedMemoryStreamView);
sharedMemoryReadBuffer = _SharedMemoryStream.ReadBytes(sharedmemorysize); sharedMemoryReadBuffer = sharedMemoryStream.ReadBytes(sharedmemorysize);
handle = GCHandle.Alloc(sharedMemoryReadBuffer, GCHandleType.Pinned); handle = GCHandle.Alloc(sharedMemoryReadBuffer, GCHandleType.Pinned);
_pcarsapistruct = _pcarsapistruct =
(pCarsAPIStruct) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(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); return new Tuple<bool, pCarsAPIStruct>(true, _pcarsapistruct);
} }
catch (Exception ex) catch (Exception)
{ {
//return false in the tuple as the read failed //return false in the tuple as the read failed
return new Tuple<bool, pCarsAPIStruct>(false, _pcarsapistruct); return new Tuple<bool, pCarsAPIStruct>(false, _pcarsapistruct);

View File

@ -1,16 +1,10 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using Artemis.DAL; using Artemis.DAL;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Models; using Artemis.Models;
using Artemis.Modules.Games.ProjectCars.Data; using Artemis.Modules.Games.ProjectCars.Data;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
using Artemis.Properties;
using Artemis.Services; using Artemis.Services;
using Artemis.Settings;
using Artemis.Utilities;
using Ninject.Extensions.Logging;
namespace Artemis.Modules.Games.ProjectCars namespace Artemis.Modules.Games.ProjectCars
{ {
@ -18,8 +12,8 @@ namespace Artemis.Modules.Games.ProjectCars
{ {
private readonly MetroDialogService _dialogService; private readonly MetroDialogService _dialogService;
public ProjectCarsModel(DeviceManager deviceManager, MetroDialogService dialogService) public ProjectCarsModel(DeviceManager deviceManager, LuaManager luaManager, MetroDialogService dialogService)
: base(deviceManager, SettingsProvider.Load<ProjectCarsSettings>(), new ProjectCarsDataModel()) : base(deviceManager, luaManager, SettingsProvider.Load<ProjectCarsSettings>(), new ProjectCarsDataModel())
{ {
_dialogService = dialogService; _dialogService = dialogService;
Name = "ProjectCars"; Name = "ProjectCars";
@ -39,6 +33,8 @@ namespace Artemis.Modules.Games.ProjectCars
public override void Enable() public override void Enable()
{ {
base.Enable();
Initialized = true; Initialized = true;
} }
@ -49,10 +45,7 @@ namespace Artemis.Modules.Games.ProjectCars
// item1 is the true/false indicating a good read or not // item1 is the true/false indicating a good read or not
if (returnTuple.Item1) 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); dataModel.GameData = dataModel.GameData.MapStructToClass(returnTuple.Item2, dataModel.GameData);
}
} }
public override List<LayerModel> GetRenderLayers(bool keyboardOnly) public override List<LayerModel> GetRenderLayers(bool keyboardOnly)

View File

@ -16,7 +16,6 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
@ -32,19 +31,19 @@
<Label Grid.Row="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left"> <Label Grid.Row="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left">
<Label.Content> <Label.Content>
<AccessText TextWrapping="Wrap" <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.Content>
</Label> </Label>
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom" <TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom"
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold" TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
TextAlignment="Justify" Margin="5,0,0,10"> 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" <Hyperlink RequestNavigate="Hyperlink_RequestNavigate"
NavigateUri="https://github.com/Funbit/ets2-telemetry-server"> NavigateUri="https://bitbucket.org/MikeyTT/pcars-api-demo">
ETS2 Telemetry Web Server pCars API Demo
</Hyperlink> </Hyperlink>
project by Funbit project by MikeyTT
</TextBlock> </TextBlock>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right">
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" /> <Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
@ -55,26 +54,11 @@
</StackPanel> </StackPanel>
</Grid> </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 --> <!-- 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 --> <!-- 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" <Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100"
Style="{DynamicResource SquareButtonStyle}" /> Style="{DynamicResource SquareButtonStyle}" />
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100" <Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100"

View File

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

View File

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

View File

@ -25,8 +25,10 @@ namespace Artemis.Modules.Games.UnrealTournament
private Timer _killTimer; private Timer _killTimer;
private int _lastScore; private int _lastScore;
public UnrealTournamentModel(DeviceManager deviceManager, PipeServer pipeServer, MetroDialogService dialogService) public UnrealTournamentModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer,
: base(deviceManager, SettingsProvider.Load<UnrealTournamentSettings>(), new UnrealTournamentDataModel()) MetroDialogService dialogService)
: base(deviceManager, luaManager, SettingsProvider.Load<UnrealTournamentSettings>(),
new UnrealTournamentDataModel())
{ {
_pipeServer = pipeServer; _pipeServer = pipeServer;
_dialogService = dialogService; _dialogService = dialogService;
@ -44,7 +46,7 @@ namespace Artemis.Modules.Games.UnrealTournament
public void FindGame() public void FindGame()
{ {
var gameSettings = (UnrealTournamentSettings)Settings; var gameSettings = (UnrealTournamentSettings) Settings;
// If already propertly set up, don't do anything // If already propertly set up, don't do anything
if ((gameSettings.GameDirectory != null) && if ((gameSettings.GameDirectory != null) &&
File.Exists(gameSettings.GameDirectory + "UE4-Win64-Shipping.exe")) File.Exists(gameSettings.GameDirectory + "UE4-Win64-Shipping.exe"))
@ -77,13 +79,13 @@ namespace Artemis.Modules.Games.UnrealTournament
public void PlaceFiles() public void PlaceFiles()
{ {
var gameSettings = (UnrealTournamentSettings)Settings; var gameSettings = (UnrealTournamentSettings) Settings;
var path = gameSettings.GameDirectory; var path = gameSettings.GameDirectory;
if (!File.Exists(path + @"\UE4-Win64-Shipping.exe")) if (!File.Exists(path + @"\UE4-Win64-Shipping.exe"))
{ {
_dialogService.ShowErrorMessageBox("Please select a valid Unreal Tournament directory\n\n" + _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.GameDirectory = string.Empty;
gameSettings.Save(); gameSettings.Save();
@ -124,6 +126,8 @@ namespace Artemis.Modules.Games.UnrealTournament
public override void Enable() public override void Enable()
{ {
base.Enable();
_pipeServer.PipeMessage += PipeServerOnPipeMessage; _pipeServer.PipeMessage += PipeServerOnPipeMessage;
_killTimer.Start(); _killTimer.Start();

View File

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

View File

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

View File

@ -13,7 +13,8 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
{ {
public class VolumeDisplayModel : OverlayModel 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"; Name = "VolumeDisplay";
Settings = (VolumeDisplaySettings) base.Settings; Settings = (VolumeDisplaySettings) base.Settings;
@ -44,7 +45,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
if (VolumeDisplay.Ttl < 1) if (VolumeDisplay.Ttl < 1)
return; return;
var decreaseAmount = 500/fps; var decreaseAmount = 500 / fps;
VolumeDisplay.Ttl = VolumeDisplay.Ttl - decreaseAmount; VolumeDisplay.Ttl = VolumeDisplay.Ttl - decreaseAmount;
if (VolumeDisplay.Ttl < 128) if (VolumeDisplay.Ttl < 128)
VolumeDisplay.Transparancy = (byte) (VolumeDisplay.Transparancy - 20); VolumeDisplay.Transparancy = (byte) (VolumeDisplay.Transparancy - 20);
@ -55,7 +56,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
var volumeFloat = var volumeFloat =
enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console) enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console)
.AudioEndpointVolume.MasterVolumeLevelScalar; .AudioEndpointVolume.MasterVolumeLevelScalar;
VolumeDisplay.Volume = (int) (volumeFloat*100); VolumeDisplay.Volume = (int) (volumeFloat * 100);
} }
catch (COMException) catch (COMException)
{ {

View File

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

View File

@ -1,4 +1,5 @@
using System.Linq; using System;
using System.Linq;
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
@ -11,7 +12,19 @@ namespace Artemis.Profiles.Layers.Conditions
{ {
lock (layerModel.Properties.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); layerModel.EventProperties.Update(layerModel, conditionsMet);
if (conditionsMet && layerModel.EventProperties.CanTrigger) if (conditionsMet && layerModel.EventProperties.CanTrigger)

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@ using Artemis.ViewModels.Profiles;
namespace Artemis.Profiles.Layers.Types.KeyPress namespace Artemis.Profiles.Layers.Types.KeyPress
{ {
internal class KeyPressType : ILayerType public class KeyPressType : ILayerType
{ {
private readonly DeviceManager _deviceManager; private readonly DeviceManager _deviceManager;
private List<LayerModel> _keyPressLayers; private List<LayerModel> _keyPressLayers;

View File

@ -13,7 +13,7 @@ using Artemis.ViewModels.Profiles;
namespace Artemis.Profiles.Layers.Types.KeyboardGif namespace Artemis.Profiles.Layers.Types.KeyboardGif
{ {
internal class KeyboardGifType : ILayerType public class KeyboardGifType : ILayerType
{ {
public string Name => "Keyboard - GIF"; public string Name => "Keyboard - GIF";
public bool ShowInEdtor => true; public bool ShowInEdtor => true;

View File

@ -1,43 +0,0 @@
using System.Collections.Generic;
using Artemis.Utilities;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Brushes
{
[MoonSharpUserData]
public class LuaBrushWrapper
{
public LuaColor GetColor(string hexCode)
{
return new LuaColor(hexCode);
}
public LuaColor GetColor(byte a, byte r, byte g, byte b)
{
return new LuaColor(a, r, g, b);
}
public LuaColor GetRandomColor()
{
return new LuaColor(ColorHelpers.GetRandomRainbowMediaColor());
}
public LuaSolidColorBrush GetSolidColorBrush(LuaColor color)
{
return new LuaSolidColorBrush(color);
}
public LuaLinearGradientBrush GetLinearGradientBrush(Dictionary<LuaColor, double> gradientColors,
double startX = 0.5, double startY = 0.0, double endX = 0.5, double endY = 1.0)
{
return new LuaLinearGradientBrush(gradientColors, startX, startY, endX, endY);
}
// TODO: Check default values
public LuaRadialGradientBrush GetRadialGradientBrush(Dictionary<LuaColor, double> gradientColors,
double centerX = 0.5, double centerY = 0.5, double originX = 0.5, double originY = 0.5)
{
return new LuaRadialGradientBrush(gradientColors, centerX, centerY, originX, originY);
}
}
}

View File

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

View File

@ -1,46 +0,0 @@
using System;
using System.Windows.Forms;
using Artemis.DeviceProviders;
using Artemis.Utilities.Keyboard;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua
{
[MoonSharpUserData]
public class LuaKeyboardWrapper : IDisposable
{
private readonly KeyboardProvider _keyboardProvider;
public LuaKeyboardWrapper(KeyboardProvider keyboardProvider)
{
_keyboardProvider = keyboardProvider;
KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
}
public string Name => _keyboardProvider.Name;
public string Slug => _keyboardProvider.Slug;
public int Width => _keyboardProvider.Width;
public int Height => _keyboardProvider.Height;
[MoonSharpVisible(false)]
public void Dispose()
{
KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback;
}
private void KeyboardHookOnKeyDownCallback(KeyEventArgs e)
{
var keyMatch = _keyboardProvider.GetKeyPosition(e.KeyCode);
if (keyMatch != null)
LuaWrapper.LuaEventsWrapper.InvokeKeyPressed(LuaWrapper.ProfileModel, this, keyMatch.Value.KeyCode,
keyMatch.Value.X, keyMatch.Value.Y);
}
public void PressKeys(string keys)
{
SendKeys.SendWait(keys);
}
}
}

View File

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

View File

@ -1,204 +0,0 @@
using System;
using System.IO;
using System.Text;
using Artemis.DAL;
using Artemis.DeviceProviders;
using Artemis.Profiles.Lua.Brushes;
using Artemis.Profiles.Lua.Events;
using Artemis.Properties;
using Castle.Core.Internal;
using MoonSharp.Interpreter;
using NLog;
namespace Artemis.Profiles.Lua
{
public static class LuaWrapper
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly Script LuaScript = new Script(CoreModules.Preset_SoftSandbox);
private static FileSystemWatcher _watcher;
public static ProfileModel ProfileModel { get; private set; }
public static KeyboardProvider KeyboardProvider { get; private set; }
public static LuaProfileWrapper LuaProfileWrapper { get; private set; }
public static LuaBrushWrapper LuaBrushWrapper { get; private set; }
public static LuaKeyboardWrapper LuaKeyboardWrapper { get; private set; }
public static LuaMouseWrapper LuaMouseWrapper { get; set; }
public static LuaEventsWrapper LuaEventsWrapper { get; private set; }
public static void SetupLua(ProfileModel profileModel, KeyboardProvider keyboardProvider)
{
Clear();
if ((profileModel == null) || (keyboardProvider == null))
return;
// Setup a new environment
KeyboardProvider = keyboardProvider;
ProfileModel = profileModel;
LuaProfileWrapper = new LuaProfileWrapper(ProfileModel);
LuaBrushWrapper = new LuaBrushWrapper();
LuaKeyboardWrapper = new LuaKeyboardWrapper(keyboardProvider);
LuaMouseWrapper = new LuaMouseWrapper();
LuaEventsWrapper = new LuaEventsWrapper();
LuaScript.Options.DebugPrint = LuaPrint;
LuaScript.Globals["Profile"] = LuaProfileWrapper;
LuaScript.Globals["Events"] = LuaEventsWrapper;
LuaScript.Globals["Brushes"] = LuaBrushWrapper;
LuaScript.Globals["Keyboard"] = LuaKeyboardWrapper;
LuaScript.Globals["Mouse"] = LuaMouseWrapper;
if (ProfileModel == null)
return;
if (ProfileModel.LuaScript.IsNullOrEmpty())
return;
try
{
lock (LuaEventsWrapper.InvokeLock)
{
lock (LuaScript)
{
LuaScript.DoString(ProfileModel.LuaScript);
}
}
}
catch (InternalErrorException e)
{
Logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
catch (SyntaxErrorException e)
{
Logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
catch (ScriptRuntimeException e)
{
Logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
}
#region Private lua functions
private static void LuaPrint(string s)
{
Logger.Debug("[{0}-LUA]: {1}", ProfileModel?.Name, s);
}
#endregion
public static void Clear()
{
lock (LuaScript)
{
// Clear old fields/properties
KeyboardProvider = null;
ProfileModel = null;
LuaProfileWrapper = null;
LuaBrushWrapper = null;
LuaKeyboardWrapper?.Dispose();
LuaKeyboardWrapper = null;
LuaMouseWrapper = null;
try
{
LuaScript.Globals.Clear();
LuaScript.Registry.Clear();
LuaScript.Registry.RegisterConstants();
LuaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
LuaScript.Globals.RegisterConstants();
LuaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
}
catch (NullReferenceException)
{
// TODO: Ask MoonSharp folks why this is happening
}
if (LuaEventsWrapper != null)
{
lock (LuaEventsWrapper.InvokeLock)
{
lock (LuaScript)
{
LuaScript.DoString("");
}
}
}
else
{
lock (LuaScript)
{
LuaScript.DoString("");
}
}
LuaEventsWrapper = null;
}
}
#region Editor
public static void OpenEditor()
{
if (ProfileModel == null)
return;
// Create a temp file
var fileName = Guid.NewGuid() + ".lua";
var file = File.Create(Path.GetTempPath() + fileName);
file.Dispose();
// Add instructions to LUA script if it's a new file
if (ProfileModel.LuaScript.IsNullOrEmpty())
ProfileModel.LuaScript = Encoding.UTF8.GetString(Resources.lua_placeholder);
File.WriteAllText(Path.GetTempPath() + fileName, ProfileModel.LuaScript);
// Watch the file for changes
SetupWatcher(Path.GetTempPath(), fileName);
// Open the temp file with the default editor
System.Diagnostics.Process.Start(Path.GetTempPath() + fileName);
}
private static void SetupWatcher(string path, string fileName)
{
if (_watcher == null)
{
_watcher = new FileSystemWatcher(Path.GetTempPath(), fileName);
_watcher.Changed += LuaFileChanged;
_watcher.EnableRaisingEvents = true;
}
_watcher.Path = path;
_watcher.Filter = fileName;
}
private static void LuaFileChanged(object sender, FileSystemEventArgs args)
{
if (args.ChangeType != WatcherChangeTypes.Changed)
return;
if (ProfileModel == null)
return;
lock (ProfileModel)
{
using (var fs = new FileStream(args.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var sr = new StreamReader(fs))
{
ProfileModel.LuaScript = sr.ReadToEnd();
}
}
ProfileProvider.AddOrUpdate(ProfileModel);
if (KeyboardProvider != null)
SetupLua(ProfileModel, KeyboardProvider);
}
}
#endregion
}
}

View File

@ -2,7 +2,7 @@
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop; using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua.Brushes namespace Artemis.Profiles.Lua.Modules.Brushes
{ {
[MoonSharpUserData] [MoonSharpUserData]
public abstract class LuaBrush public abstract class LuaBrush

View File

@ -3,7 +3,7 @@ using Artemis.Utilities;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop; using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua.Brushes namespace Artemis.Profiles.Lua.Modules.Brushes
{ {
[MoonSharpUserData] [MoonSharpUserData]
public class LuaColor public class LuaColor

View File

@ -5,7 +5,7 @@ using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Brushes namespace Artemis.Profiles.Lua.Modules.Brushes
{ {
[MoonSharpUserData] [MoonSharpUserData]
public class LuaLinearGradientBrush : LuaBrush public class LuaLinearGradientBrush : LuaBrush
@ -57,7 +57,7 @@ namespace Artemis.Profiles.Lua.Brushes
{ {
var collection = new GradientStopCollection(gradientColors var collection = new GradientStopCollection(gradientColors
.Select(gc => new GradientStop(gc.Key.Color, gc.Value))); .Select(gc => new GradientStop(gc.Key.Color, gc.Value)));
Brush = new LinearGradientBrush(collection, new Point(startX, startY), new Point(endX, endY)); Brush = new LinearGradientBrush(collection, new Point(startX, startY), new Point(endX, endY));
} }
} }

View File

@ -5,7 +5,7 @@ using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Brushes namespace Artemis.Profiles.Lua.Modules.Brushes
{ {
[MoonSharpUserData] [MoonSharpUserData]
public class LuaRadialGradientBrush : LuaBrush public class LuaRadialGradientBrush : LuaBrush

View File

@ -2,7 +2,7 @@
using System.Windows.Media; using System.Windows.Media;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Brushes namespace Artemis.Profiles.Lua.Modules.Brushes
{ {
[MoonSharpUserData] [MoonSharpUserData]
public class LuaSolidColorBrush : LuaBrush public class LuaSolidColorBrush : LuaBrush

View File

@ -1,13 +1,15 @@
using System; using System;
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
using Artemis.Profiles.Lua.Wrappers;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Events namespace Artemis.Profiles.Lua.Modules.Events
{ {
[MoonSharpUserData] [MoonSharpUserData]
public class LuaDeviceDrawingEventArgs : EventArgs 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; DeviceType = deviceType;
DataModel = dataModel; DataModel = dataModel;

View File

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

View File

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

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;
using Artemis.Managers;
using Artemis.Profiles.Lua.Modules.Brushes;
using Artemis.Utilities;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules
{
[MoonSharpUserData]
public class LuaBrushesModule : LuaModule
{
public LuaBrushesModule(LuaManager luaManager) : base(luaManager)
{
}
public override string ModuleName => "Brushes";
public LuaColor GetColor(string hexCode)
{
return new LuaColor(hexCode);
}
public LuaColor GetColor(byte a, byte r, byte g, byte b)
{
return new LuaColor(a, r, g, b);
}
public LuaColor GetRandomColor()
{
return new LuaColor(ColorHelpers.GetRandomRainbowMediaColor());
}
public LuaSolidColorBrush GetSolidColorBrush(LuaColor color)
{
return new LuaSolidColorBrush(color);
}
public LuaLinearGradientBrush GetLinearGradientBrush(Dictionary<LuaColor, double> gradientColors,
double startX = 0.5, double startY = 0.0, double endX = 0.5, double endY = 1.0)
{
return new LuaLinearGradientBrush(gradientColors, startX, startY, endX, endY);
}
// TODO: Check default values
public LuaRadialGradientBrush GetRadialGradientBrush(Dictionary<LuaColor, double> gradientColors,
double centerX = 0.5, double centerY = 0.5, double originX = 0.5, double originY = 0.5)
{
return new LuaRadialGradientBrush(gradientColors, centerX, centerY, originX, originY);
}
public LuaColor GetRelativeColor(Dictionary<LuaColor, double> gradientColors, double offset)
{
if (offset < 0)
offset = 0;
if (offset > 1)
offset = 1;
var gsc = new GradientStopCollection(gradientColors.Select(gc => new GradientStop(gc.Key.Color, gc.Value)));
var b = gsc.First(w => Math.Abs(w.Offset - gsc.Min(m => m.Offset)) < 0.01);
var a = gsc.First(w => Math.Abs(w.Offset - gsc.Max(m => m.Offset)) < 0.01);
foreach (var gs in gsc)
{
if (gs.Offset < offset && gs.Offset > b.Offset)
b = gs;
if (gs.Offset > offset && gs.Offset < a.Offset)
a = gs;
}
var color = new Color
{
ScA = (float) ((offset - b.Offset) * (a.Color.ScA - b.Color.ScA) / (a.Offset - b.Offset) + b.Color.ScA),
ScR = (float) ((offset - b.Offset) * (a.Color.ScR - b.Color.ScR) / (a.Offset - b.Offset) + b.Color.ScR),
ScG = (float) ((offset - b.Offset) * (a.Color.ScG - b.Color.ScG) / (a.Offset - b.Offset) + b.Color.ScG),
ScB = (float) ((offset - b.Offset) * (a.Color.ScB - b.Color.ScB) / (a.Offset - b.Offset) + b.Color.ScB)
};
return new LuaColor(color);
}
}
}

View File

@ -0,0 +1,126 @@
using System;
using System.Windows.Forms;
using Artemis.DeviceProviders;
using Artemis.Events;
using Artemis.Managers;
using Artemis.Profiles.Lua.Modules.Events;
using Artemis.Profiles.Lua.Wrappers;
using Artemis.Utilities.Keyboard;
using MoonSharp.Interpreter;
using NLog;
namespace Artemis.Profiles.Lua.Modules
{
[MoonSharpUserData]
public class LuaEventsModule : LuaModule
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
private readonly ProfileModel _profileModel;
public readonly string InvokeLock = string.Empty;
public LuaEventsModule(LuaManager luaManager) : base(luaManager)
{
_profileModel = luaManager.ProfileModel;
_profileModel.OnDeviceUpdatedEvent += OnDeviceUpdatedEvent;
_profileModel.OnDeviceDrawnEvent += OnDeviceDrawnEvent;
KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
}
public override string ModuleName => "Events";
public event EventHandler<LuaDeviceUpdatingEventArgs> DeviceUpdating;
public event EventHandler<LuaDeviceDrawingEventArgs> DeviceDrawing;
public event EventHandler<LuaKeyPressEventArgs> KeyboardKeyPressed;
private void KeyboardHookOnKeyDownCallback(KeyEventArgs e)
{
try
{
var keyMatch = LuaManager.KeyboardProvider.GetKeyPosition(e.KeyCode) ?? new KeyMatch(e.KeyCode, 0, 0);
var args = new LuaKeyPressEventArgs(e.KeyCode, keyMatch.X, keyMatch.Y);
LuaInvoke(_profileModel, () => OnKeyboardKeyPressed(LuaManager.ProfileModule, args));
}
catch (Exception)
{
// ignored
}
}
private void OnDeviceUpdatedEvent(object sender, ProfileDeviceEventsArg e)
{
try
{
var args = new LuaDeviceUpdatingEventArgs(e.UpdateType, e.DataModel, e.Preview);
LuaInvoke(_profileModel, () => OnDeviceUpdating(LuaManager.ProfileModule, args));
}
catch (Exception)
{
// ignored
}
}
private void OnDeviceDrawnEvent(object sender, ProfileDeviceEventsArg e)
{
try
{
var wrapper = new LuaDrawWrapper(e.DrawingContext);
var args = new LuaDeviceDrawingEventArgs(e.UpdateType, e.DataModel, e.Preview, wrapper);
LuaInvoke(_profileModel, () => OnDeviceDrawing(LuaManager.ProfileModule, args));
}
catch (Exception)
{
// ignored
}
}
private void LuaInvoke(ProfileModel profileModel, Action action)
{
lock (InvokeLock)
{
try
{
action.Invoke();
}
catch (InternalErrorException ex)
{
_logger.Error("[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
}
catch (SyntaxErrorException ex)
{
_logger.Error("[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
}
catch (ScriptRuntimeException ex)
{
_logger.Error("[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
}
}
}
protected virtual void OnDeviceUpdating(LuaProfileModule profileModel, LuaDeviceUpdatingEventArgs e)
{
DeviceUpdating?.Invoke(profileModel, e);
}
protected virtual void OnDeviceDrawing(LuaProfileModule profileModel, LuaDeviceDrawingEventArgs e)
{
DeviceDrawing?.Invoke(profileModel, e);
}
protected virtual void OnKeyboardKeyPressed(LuaProfileModule profileModel, LuaKeyPressEventArgs e)
{
KeyboardKeyPressed?.Invoke(profileModel, e);
}
#region Overriding members
public override void Dispose()
{
_profileModel.OnDeviceUpdatedEvent -= OnDeviceUpdatedEvent;
_profileModel.OnDeviceDrawnEvent -= OnDeviceDrawnEvent;
KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback;
}
#endregion
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.Diagnostics;
using System.Windows.Forms;
using Artemis.DeviceProviders;
using Artemis.Managers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules
{
[MoonSharpUserData]
public class LuaKeyboardModule : LuaModule
{
private readonly KeyboardProvider _keyboardProvider;
public LuaKeyboardModule(LuaManager luaManager) : base(luaManager)
{
_keyboardProvider = luaManager.KeyboardProvider;
// Register the KeyMatch type for usage in GetKeyPosition
UserData.RegisterType(typeof(KeyMatch));
}
public override string ModuleName => "Keyboard";
public string Name => _keyboardProvider.Name;
public string Slug => _keyboardProvider.Slug;
public int Width => _keyboardProvider.Width;
public int Height => _keyboardProvider.Height;
public void PressKeys(string keys)
{
SendKeys.SendWait(keys);
}
public KeyMatch? GetKeyPosition(string key)
{
// Convert string to Keys enum, I'm not sure if built-in enums can be converted automatically
try
{
var keyEnum = (Keys)Enum.Parse(typeof(Keys), key);
return _keyboardProvider.GetKeyPosition(keyEnum);
}
catch (ArgumentException)
{
throw new ScriptRuntimeException($"Key '{key}' not found");
}
}
}
}

View File

@ -0,0 +1,184 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;
using Artemis.Managers;
using Artemis.Modules.Effects.ProfilePreview;
using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Lua.Modules.Brushes;
using Artemis.Profiles.Lua.Wrappers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules
{
[MoonSharpUserData]
public class LuaLayerModule : LuaModule
{
private readonly LayerModel _layerModel;
public LuaLayerModule(LuaManager luaManager, LayerModel layerModel) : base(luaManager)
{
_layerModel = layerModel;
SavedProperties = new Wrappers.LuaLayerProperties(_layerModel);
// Trigger an update to fill up the Properties
_layerModel.Update(new ProfilePreviewDataModel(), true, false);
}
public override string ModuleName => "Layer";
#region Child methods
public List<LuaLayerWrapper> GetChildren()
{
return _layerModel.Children.Select(l => new LuaLayerWrapper(l)).ToList();
}
public LuaLayerWrapper GetChildByName(string name)
{
var layer = _layerModel.Children.FirstOrDefault(l => l.Name == name);
return layer == null ? null : new LuaLayerWrapper(layer);
}
#endregion
#region General layer properties
public string Name
{
get { return _layerModel.Name; }
set { _layerModel.Name = value; }
}
public bool Enabled
{
get { return _layerModel.Enabled; }
set { _layerModel.Enabled = value; }
}
public bool IsEvent
{
get { return _layerModel.IsEvent; }
set { _layerModel.IsEvent = value; }
}
public LuaLayerWrapper Parent => new LuaLayerWrapper(_layerModel.Parent);
#endregion
#region Render layer properties
public double X
{
get { return _layerModel.X; }
set { _layerModel.X = value; }
}
public double Y
{
get { return _layerModel.Y; }
set { _layerModel.Y = value; }
}
public double Width
{
get { return _layerModel.Width; }
set { _layerModel.Width = value; }
}
public double Height
{
get { return _layerModel.Height; }
set { _layerModel.Height = value; }
}
public double Opacity
{
get { return _layerModel.Opacity; }
set { _layerModel.Opacity = value; }
}
public double AnimationProgress
{
get { return _layerModel.AnimationProgress; }
set { _layerModel.AnimationProgress = value; }
}
#endregion
#region Advanced layer properties
public Wrappers.LuaLayerProperties SavedProperties { get; set; }
public string BrushType => _layerModel.Properties.Brush?.GetType().Name;
public LuaBrush Brush
{
get
{
if (_layerModel.Properties.Brush is SolidColorBrush)
return new LuaSolidColorBrush(_layerModel.Properties.Brush);
if (_layerModel.Properties.Brush is LinearGradientBrush)
return new LuaLinearGradientBrush(_layerModel.Properties.Brush);
if (_layerModel.Properties.Brush is RadialGradientBrush)
return new LuaRadialGradientBrush(_layerModel.Properties.Brush);
return null;
}
set { _layerModel.Properties.Brush = value?.Brush; }
}
#endregion
}
[MoonSharpUserData]
public class LuaLayerProperties
{
private readonly LayerModel _layerModel;
public LuaLayerProperties(LayerModel layerModel)
{
_layerModel = layerModel;
}
public double X
{
get { return _layerModel.Properties.X; }
set { _layerModel.Properties.X = value; }
}
public double Y
{
get { return _layerModel.Properties.Y; }
set { _layerModel.Properties.Y = value; }
}
public double Width
{
get { return _layerModel.Properties.Width; }
set { _layerModel.Properties.Width = value; }
}
public double Height
{
get { return _layerModel.Properties.Height; }
set { _layerModel.Properties.Height = value; }
}
public bool Contain
{
get { return _layerModel.Properties.Contain; }
set { _layerModel.Properties.Contain = value; }
}
public double Opacity
{
get { return _layerModel.Properties.Opacity; }
set { _layerModel.Properties.Opacity = value; }
}
public double AnimationSpeed
{
get { return _layerModel.Properties.AnimationSpeed; }
set { _layerModel.Properties.AnimationSpeed = value; }
}
}
}

View File

@ -1,33 +1,39 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using MoonSharp.Interpreter; using Artemis.Managers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles
{ namespace Artemis.Profiles.Lua.Modules
[MoonSharpUserData] {
public class LuaMouseWrapper [MoonSharpUserData]
{ public class LuaMouseModule : LuaModule
public int Y => (int) GetMousePosition().Y; {
public LuaMouseModule(LuaManager luaManager) : base(luaManager)
public int X => (int) GetMousePosition().X; {
}
[DllImport("user32.dll")] public override string ModuleName => "Mouse";
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt); public int Y => (int) GetMousePosition().Y;
public static Point GetMousePosition() public int X => (int) GetMousePosition().X;
{
var w32Mouse = new Win32Point(); [DllImport("user32.dll")]
GetCursorPos(ref w32Mouse); [return: MarshalAs(UnmanagedType.Bool)]
return new Point(w32Mouse.X, w32Mouse.Y); internal static extern bool GetCursorPos(ref Win32Point pt);
}
public static Point GetMousePosition()
[StructLayout(LayoutKind.Sequential)] {
internal struct Win32Point var w32Mouse = new Win32Point();
{ GetCursorPos(ref w32Mouse);
public int X; return new Point(w32Mouse.X, w32Mouse.Y);
public int Y; }
}
} [StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
public int X;
public int Y;
}
}
} }

View File

@ -1,22 +1,23 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Artemis.Managers;
using Artemis.Profiles.Lua.Wrappers;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua namespace Artemis.Profiles.Lua.Modules
{ {
/// <summary>
/// Serves as a sandboxed wrapper around the ProfileModel
/// </summary>
[MoonSharpUserData] [MoonSharpUserData]
public class LuaProfileWrapper public class LuaProfileModule : LuaModule
{ {
private readonly ProfileModel _profileModel; 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 #region General profile properties
public string Name => _profileModel.Name; public string Name => _profileModel.Name;

View File

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

View File

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

View File

@ -1,19 +1,20 @@
using System; using System;
using System.Drawing.Text;
using System.Globalization; using System.Globalization;
using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Profiles.Lua.Brushes; using Artemis.Profiles.Lua.Modules.Brushes;
using MoonSharp.Interpreter; 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] [MoonSharpUserData]
public class LuaDrawWrapper public class LuaDrawWrapper
{ {
private readonly DrawingContext _ctx; private readonly DrawingContext _ctx;
private FontFamily _font; private readonly FontFamily _font;
public LuaDrawWrapper(DrawingContext ctx) public LuaDrawWrapper(DrawingContext ctx)
{ {
@ -28,7 +29,7 @@ namespace Artemis.Profiles.Lua
height *= 4; height *= 4;
width *= 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); _ctx.DrawEllipse(luaBrush.Brush, new Pen(), center, width, height);
} }
@ -65,7 +66,7 @@ namespace Artemis.Profiles.Lua
fontSize, luaBrush.Brush); fontSize, luaBrush.Brush);
_ctx.DrawText(formatted, new Point(x, y)); _ctx.DrawText(formatted, new Point(x, y));
return formatted.Width/4; return formatted.Width / 4;
} }
} }
} }

View File

@ -1,183 +1,183 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Modules.Effects.ProfilePreview; using Artemis.Modules.Effects.ProfilePreview;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Lua.Brushes; using Artemis.Profiles.Lua.Modules.Brushes;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua namespace Artemis.Profiles.Lua.Wrappers
{ {
/// <summary> /// <summary>
/// Serves as a sandboxed wrapper around the LayerModel /// Serves as a sandboxed wrapper around the LayerModel
/// </summary> /// </summary>
[MoonSharpUserData] [MoonSharpUserData]
public class LuaLayerWrapper public class LuaLayerWrapper
{ {
private readonly LayerModel _layerModel; private readonly LayerModel _layerModel;
public LuaLayerWrapper(LayerModel layerModel) public LuaLayerWrapper(LayerModel layerModel)
{ {
_layerModel = layerModel; _layerModel = layerModel;
SavedProperties = new LuaLayerProperties(layerModel); SavedProperties = new LuaLayerProperties(layerModel);
// Triger an update to fill up the Properties // Triger an update to fill up the Properties
_layerModel.Update(new ProfilePreviewDataModel(), true, false); _layerModel.Update(new ProfilePreviewDataModel(), true, false);
} }
#region Child methods #region Child methods
public List<LuaLayerWrapper> GetChildren() public List<LuaLayerWrapper> GetChildren()
{ {
return _layerModel.Children.Select(l => new LuaLayerWrapper(l)).ToList(); return _layerModel.Children.Select(l => new LuaLayerWrapper(l)).ToList();
} }
public LuaLayerWrapper GetChildByName(string name) public LuaLayerWrapper GetChildByName(string name)
{ {
var layer = _layerModel.Children.FirstOrDefault(l => l.Name == name); var layer = _layerModel.Children.FirstOrDefault(l => l.Name == name);
return layer == null ? null : new LuaLayerWrapper(layer); return layer == null ? null : new LuaLayerWrapper(layer);
} }
#endregion #endregion
#region General layer properties #region General layer properties
public string Name public string Name
{ {
get { return _layerModel.Name; } get { return _layerModel.Name; }
set { _layerModel.Name = value; } set { _layerModel.Name = value; }
} }
public bool Enabled public bool Enabled
{ {
get { return _layerModel.Enabled; } get { return _layerModel.Enabled; }
set { _layerModel.Enabled = value; } set { _layerModel.Enabled = value; }
} }
public bool IsEvent public bool IsEvent
{ {
get { return _layerModel.IsEvent; } get { return _layerModel.IsEvent; }
set { _layerModel.IsEvent = value; } set { _layerModel.IsEvent = value; }
} }
public LuaLayerWrapper Parent => new LuaLayerWrapper(_layerModel.Parent); public LuaLayerWrapper Parent => new LuaLayerWrapper(_layerModel.Parent);
#endregion #endregion
#region Render layer properties #region Render layer properties
public double X public double X
{ {
get { return _layerModel.X; } get { return _layerModel.X; }
set { _layerModel.X = value; } set { _layerModel.X = value; }
} }
public double Y public double Y
{ {
get { return _layerModel.Y; } get { return _layerModel.Y; }
set { _layerModel.Y = value; } set { _layerModel.Y = value; }
} }
public double Width public double Width
{ {
get { return _layerModel.Width; } get { return _layerModel.Width; }
set { _layerModel.Width = value; } set { _layerModel.Width = value; }
} }
public double Height public double Height
{ {
get { return _layerModel.Height; } get { return _layerModel.Height; }
set { _layerModel.Height = value; } set { _layerModel.Height = value; }
} }
public double Opacity public double Opacity
{ {
get { return _layerModel.Opacity; } get { return _layerModel.Opacity; }
set { _layerModel.Opacity = value; } set { _layerModel.Opacity = value; }
} }
public double AnimationProgress public double AnimationProgress
{ {
get { return _layerModel.AnimationProgress; } get { return _layerModel.AnimationProgress; }
set { _layerModel.AnimationProgress = value; } set { _layerModel.AnimationProgress = value; }
} }
#endregion #endregion
#region Advanced layer properties #region Advanced layer properties
public LuaLayerProperties SavedProperties { get; set; } public LuaLayerProperties SavedProperties { get; set; }
public string BrushType => _layerModel.Properties.Brush?.GetType().Name; public string BrushType => _layerModel.Properties.Brush?.GetType().Name;
public LuaBrush Brush public LuaBrush Brush
{ {
get get
{ {
if (_layerModel.Properties.Brush is SolidColorBrush) if (_layerModel.Properties.Brush is SolidColorBrush)
return new LuaSolidColorBrush(_layerModel.Properties.Brush); return new LuaSolidColorBrush(_layerModel.Properties.Brush);
if (_layerModel.Properties.Brush is LinearGradientBrush) if (_layerModel.Properties.Brush is LinearGradientBrush)
return new LuaLinearGradientBrush(_layerModel.Properties.Brush); return new LuaLinearGradientBrush(_layerModel.Properties.Brush);
if (_layerModel.Properties.Brush is RadialGradientBrush) if (_layerModel.Properties.Brush is RadialGradientBrush)
return new LuaRadialGradientBrush(_layerModel.Properties.Brush); return new LuaRadialGradientBrush(_layerModel.Properties.Brush);
return null; return null;
} }
set { _layerModel.Properties.Brush = value?.Brush; } set { _layerModel.Properties.Brush = value?.Brush; }
} }
#endregion #endregion
} }
[MoonSharpUserData] [MoonSharpUserData]
public class LuaLayerProperties public class LuaLayerProperties
{ {
private readonly LayerModel _layerModel; private readonly LayerModel _layerModel;
public LuaLayerProperties(LayerModel layerModel) public LuaLayerProperties(LayerModel layerModel)
{ {
_layerModel = layerModel; _layerModel = layerModel;
} }
public double X public double X
{ {
get { return _layerModel.Properties.X; } get { return _layerModel.Properties.X; }
set { _layerModel.Properties.X = value; } set { _layerModel.Properties.X = value; }
} }
public double Y public double Y
{ {
get { return _layerModel.Properties.Y; } get { return _layerModel.Properties.Y; }
set { _layerModel.Properties.Y = value; } set { _layerModel.Properties.Y = value; }
} }
public double Width public double Width
{ {
get { return _layerModel.Properties.Width; } get { return _layerModel.Properties.Width; }
set { _layerModel.Properties.Width = value; } set { _layerModel.Properties.Width = value; }
} }
public double Height public double Height
{ {
get { return _layerModel.Properties.Height; } get { return _layerModel.Properties.Height; }
set { _layerModel.Properties.Height = value; } set { _layerModel.Properties.Height = value; }
} }
public bool Contain public bool Contain
{ {
get { return _layerModel.Properties.Contain; } get { return _layerModel.Properties.Contain; }
set { _layerModel.Properties.Contain = value; } set { _layerModel.Properties.Contain = value; }
} }
public double Opacity public double Opacity
{ {
get { return _layerModel.Properties.Opacity; } get { return _layerModel.Properties.Opacity; }
set { _layerModel.Properties.Opacity = value; } set { _layerModel.Properties.Opacity = value; }
} }
public double AnimationSpeed public double AnimationSpeed
{ {
get { return _layerModel.Properties.AnimationSpeed; } get { return _layerModel.Properties.AnimationSpeed; }
set { _layerModel.Properties.AnimationSpeed = value; } set { _layerModel.Properties.AnimationSpeed = value; }
} }
} }
} }

View File

@ -1,16 +1,19 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using Artemis.DeviceProviders; using Artemis.DeviceProviders;
using Artemis.Events;
using Artemis.Managers;
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Lua;
using Artemis.Utilities; using Artemis.Utilities;
using Artemis.Utilities.ParentChild; using Artemis.Utilities.ParentChild;
using Newtonsoft.Json;
using Color = System.Windows.Media.Color; using Color = System.Windows.Media.Color;
using Point = System.Windows.Point; using Point = System.Windows.Point;
using Size = System.Windows.Size; using Size = System.Windows.Size;
@ -19,8 +22,11 @@ namespace Artemis.Profiles
{ {
public class ProfileModel public class ProfileModel
{ {
private readonly char[] _invalidFileNameChars;
public ProfileModel() public ProfileModel()
{ {
_invalidFileNameChars = Path.GetInvalidFileNameChars();
Layers = new ChildItemCollection<ProfileModel, LayerModel>(this); Layers = new ChildItemCollection<ProfileModel, LayerModel>(this);
} }
@ -33,6 +39,12 @@ namespace Artemis.Profiles
public int Height { get; set; } public int Height { get; set; }
public string LuaScript { 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() public void FixOrder()
{ {
Layers.Sort(l => l.Order); Layers.Sort(l => l.Order);
@ -69,12 +81,14 @@ namespace Artemis.Profiles
var layers = new List<LayerModel>(); var layers = new List<LayerModel>();
foreach (var layerModel in Layers.OrderByDescending(l => l.Order)) 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; continue;
if (!ignoreConditions) if (!ignoreConditions)
{
if (!layerModel.ConditionsMet(dataModel)) if (!layerModel.ConditionsMet(dataModel))
continue; continue;
}
layers.Add(layerModel); layers.Add(layerModel);
layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions)); layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions));
@ -107,12 +121,12 @@ namespace Artemis.Profiles
// Update the layers // Update the layers
foreach (var layerModel in layerModels) foreach (var layerModel in layerModels)
layerModel.Update(dataModel, preview, updateAnimations); layerModel.Update(dataModel, preview, updateAnimations);
LuaWrapper.LuaEventsWrapper?.InvokeDeviceUpdate(this, updateType, dataModel, preview); RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(updateType, dataModel, preview, null));
// Draw the layers // Draw the layers
foreach (var layerModel in layerModels) foreach (var layerModel in layerModels)
layerModel.Draw(dataModel, c, preview, updateAnimations); layerModel.Draw(dataModel, c, preview, updateAnimations);
LuaWrapper.LuaEventsWrapper?.InvokeDeviceDraw(this, updateType, dataModel, preview, c); RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(updateType, dataModel, preview, c));
// Remove the clip // Remove the clip
c.Pop(); 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> /// <summary>
/// Looks at all the layers wthin the profile and makes sure they are within boundaries of the given rectangle /// Looks at all the layers wthin the profile and makes sure they are within boundaries of the given rectangle
/// </summary> /// </summary>
@ -164,15 +190,15 @@ namespace Artemis.Profiles
} }
} }
public void Activate(KeyboardProvider keyboard) public void Activate(LuaManager luaManager)
{ {
if (!Equals(LuaWrapper.ProfileModel, this)) if (!Equals(luaManager.ProfileModel, this) || luaManager.ProfileModel.LuaScript != LuaScript)
LuaWrapper.SetupLua(this, keyboard); luaManager.SetupLua(this);
} }
public void Deactivate() public void Deactivate(LuaManager luaManager)
{ {
LuaWrapper.Clear(); luaManager.ClearLua();
} }
public LayerModel AddLayer(LayerModel afterLayer) public LayerModel AddLayer(LayerModel afterLayer)
@ -181,7 +207,9 @@ namespace Artemis.Profiles
var layer = LayerModel.CreateLayer(); var layer = LayerModel.CreateLayer();
if (afterLayer != null) if (afterLayer != null)
{
afterLayer.InsertAfter(layer); afterLayer.InsertAfter(layer);
}
else else
{ {
Layers.Add(layer); Layers.Add(layer);
@ -195,7 +223,7 @@ namespace Artemis.Profiles
protected bool Equals(ProfileModel other) protected bool Equals(ProfileModel other)
{ {
return string.Equals(Name, other.Name) && return string.Equals(Slug, other.Slug) &&
string.Equals(KeyboardSlug, other.KeyboardSlug) && string.Equals(KeyboardSlug, other.KeyboardSlug) &&
string.Equals(GameName, other.GameName); string.Equals(GameName, other.GameName);
} }
@ -212,9 +240,9 @@ namespace Artemis.Profiles
{ {
unchecked unchecked
{ {
var hashCode = Name?.GetHashCode() ?? 0; var hashCode = Slug?.GetHashCode() ?? 0;
hashCode = (hashCode*397) ^ (KeyboardSlug?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
hashCode = (hashCode*397) ^ (GameName?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (GameName?.GetHashCode() ?? 0);
return hashCode; return hashCode;
} }
} }

View File

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

View File

@ -22,7 +22,7 @@ namespace Artemis.Properties {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources { public class Resources {
private static global::System.Resources.ResourceManager resourceMan; private static global::System.Resources.ResourceManager resourceMan;

View File

@ -15,6 +15,11 @@
-- This event is raised after every profile update, before drawing. -- This event is raised after every profile update, before drawing.
function updateHandler(profile, eventArgs) 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 -- 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 -- updated. If you don't do this the updateHandler will trigger on every
-- device's update. -- device's update.
@ -27,6 +32,11 @@ end
-- This event is raised after every profile draw, after updating. -- This event is raised after every profile draw, after updating.
function drawHandler(profile, eventArgs) 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 -- In this example we only want to draw to the keyboard. Each device has it's
-- own drawing event -- own drawing event
if eventArgs.DeviceType != "keyboard" then if eventArgs.DeviceType != "keyboard" then

View File

@ -21,13 +21,15 @@ namespace Artemis.Utilities
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint processId); private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
#endregion #endregion
#region Constants #region Constants
private const uint WINEVENT_OUTOFCONTEXT = 0; private const uint WINEVENT_OUTOFCONTEXT = 0x0000;
private const uint EVENT_SYSTEM_FOREGROUND = 3; 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; 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. // 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 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 ActiveWindowProcessName { get; private set; }
public static string ActiveWindowWindowTitle { 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, private static void ActiveWindowChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) 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; ActiveWindowProcessName = GetActiveWindowProcessName(hwnd) ?? string.Empty;
ActiveWindowWindowTitle = GetActiveWindowTitle(hwnd) ?? string.Empty; ActiveWindowWindowTitle = GetActiveWindowTitle(hwnd) ?? string.Empty;
} }
@ -84,10 +116,23 @@ namespace Artemis.Utilities
{ {
try 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; if (_windowTitleEventHook == IntPtr.Zero)
_winEventHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, _activeWindowChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT); {
_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 */ } catch { /* catch'em all - I don't want it to crash here */ }
} }
@ -96,11 +141,26 @@ namespace Artemis.Utilities
{ {
try try
{ {
if (_winEventHook == IntPtr.Zero) return; if (_activeWindowEventHook != IntPtr.Zero)
{
UnhookWinEvent(_activeWindowEventHook);
_activeWindowChangedDelegate = null;
_activeWindowEventHook = IntPtr.Zero;
}
UnhookWinEvent(_winEventHook); if (_windowTitleEventHook != IntPtr.Zero)
_activeWindowChangedDelegate = null; {
_winEventHook = 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 */ } catch { /* catch'em all - I don't want it to crash here */ }
} }

View File

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

View File

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

View File

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

View File

@ -26,7 +26,7 @@ namespace Artemis.ViewModels.Abstract
IParameter[] args = IParameter[] args =
{ {
new ConstructorArgument("mainManager", mainManager), new ConstructorArgument("mainManager", mainManager),
new ConstructorArgument("gameModel", gameModel), new ConstructorArgument("effectModel", gameModel),
new ConstructorArgument("lastProfile", GameSettings.LastProfile) new ConstructorArgument("lastProfile", GameSettings.LastProfile)
}; };
ProfileEditor = kernel.Get<ProfileEditorViewModel>(args); 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() public void ToggleEffect()
{ {

View File

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

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Timers; using System.Timers;
@ -16,11 +18,12 @@ using Artemis.Models;
using Artemis.Profiles; using Artemis.Profiles;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Layers.Types.Folder; using Artemis.Profiles.Layers.Types.Folder;
using Artemis.Profiles.Lua; using Artemis.Properties;
using Artemis.Services; using Artemis.Services;
using Artemis.Styles.DropTargetAdorners; using Artemis.Styles.DropTargetAdorners;
using Artemis.Utilities; using Artemis.Utilities;
using Caliburn.Micro; using Caliburn.Micro;
using Castle.Core.Internal;
using GongSolutions.Wpf.DragDrop; using GongSolutions.Wpf.DragDrop;
using MahApps.Metro.Controls.Dialogs; using MahApps.Metro.Controls.Dialogs;
using Ninject; using Ninject;
@ -37,20 +40,23 @@ namespace Artemis.ViewModels.Profiles
public sealed class ProfileEditorViewModel : Screen, IDropTarget public sealed class ProfileEditorViewModel : Screen, IDropTarget
{ {
private readonly DeviceManager _deviceManager; private readonly DeviceManager _deviceManager;
private readonly EffectModel _gameModel; private readonly EffectModel _effectModel;
private readonly LuaManager _luaManager;
private readonly Timer _saveTimer; private readonly Timer _saveTimer;
private ImageSource _keyboardPreview; private ImageSource _keyboardPreview;
private ObservableCollection<LayerModel> _layers; private ObservableCollection<LayerModel> _layers;
private ObservableCollection<string> _profileNames; private ObservableCollection<string> _profileNames;
private bool _saving; private bool _saving;
private ProfileModel _selectedProfile; 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, ProfileViewModel profileViewModel, MetroDialogService dialogService, WindowService windowService,
string lastProfile) string lastProfile)
{ {
_deviceManager = deviceManager; _deviceManager = deviceManager;
_gameModel = gameModel; _luaManager = luaManager;
_effectModel = effectModel;
ProfileNames = new ObservableCollection<string>(); ProfileNames = new ObservableCollection<string>();
Layers = new ObservableCollection<LayerModel>(); Layers = new ObservableCollection<LayerModel>();
@ -79,7 +85,7 @@ namespace Artemis.ViewModels.Profiles
public ProfileViewModel ProfileViewModel { get; set; } public ProfileViewModel ProfileViewModel { get; set; }
public bool EditorEnabled public bool EditorEnabled
=> (SelectedProfile != null) && !SelectedProfile.IsDefault && (_deviceManager.ActiveKeyboard != null); => SelectedProfile != null && !SelectedProfile.IsDefault && _deviceManager.ActiveKeyboard != null;
public ObservableCollection<string> ProfileNames public ObservableCollection<string> ProfileNames
{ {
@ -111,7 +117,7 @@ namespace Artemis.ViewModels.Profiles
if (value == SelectedProfile?.Name) if (value == SelectedProfile?.Name)
return; return;
SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _gameModel, value); SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _effectModel, value);
NotifyOfPropertyChange(() => SelectedProfileName); NotifyOfPropertyChange(() => SelectedProfileName);
} }
} }
@ -124,12 +130,21 @@ namespace Artemis.ViewModels.Profiles
if (Equals(value, _selectedProfile)) if (Equals(value, _selectedProfile))
return; return;
// Deactivate old profile if (IsActive)
_selectedProfile?.Deactivate(); {
// Update the value // Deactivate old profile
_selectedProfile = value; _selectedProfile?.Deactivate(_luaManager);
// Activate new profile // Update the value
_selectedProfile?.Activate(_deviceManager.ActiveKeyboard); _selectedProfile = value;
// Activate new profile
_selectedProfile?.Activate(_luaManager);
}
else
{
// Update the value
_selectedProfile = value;
}
NotifyOfPropertyChange(() => SelectedProfile); NotifyOfPropertyChange(() => SelectedProfile);
NotifyOfPropertyChange(() => SelectedProfileName); NotifyOfPropertyChange(() => SelectedProfileName);
} }
@ -149,16 +164,16 @@ namespace Artemis.ViewModels.Profiles
public PreviewSettings? PreviewSettings => _deviceManager.ActiveKeyboard?.PreviewSettings; public PreviewSettings? PreviewSettings => _deviceManager.ActiveKeyboard?.PreviewSettings;
public bool ProfileSelected => SelectedProfile != null; 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) public void DragOver(IDropInfo dropInfo)
{ {
var source = dropInfo.Data as LayerModel; var source = dropInfo.Data as LayerModel;
var target = dropInfo.TargetItem as LayerModel; var target = dropInfo.TargetItem as LayerModel;
if ((source == null) || (target == null) || (source == target)) if (source == null || target == null || source == target)
return; return;
if ((dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter) && if (dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter &&
target.LayerType is FolderType) target.LayerType is FolderType)
{ {
dropInfo.DropTargetAdorner = typeof(DropTargetMetroHighlightAdorner); dropInfo.DropTargetAdorner = typeof(DropTargetMetroHighlightAdorner);
@ -175,7 +190,7 @@ namespace Artemis.ViewModels.Profiles
{ {
var source = dropInfo.Data as LayerModel; var source = dropInfo.Data as LayerModel;
var target = dropInfo.TargetItem as LayerModel; var target = dropInfo.TargetItem as LayerModel;
if ((source == null) || (target == null) || (source == target)) if (source == null || target == null || source == target)
return; return;
// Don't allow a folder to become it's own child, that's just weird // 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(); parent.FixOrder();
} }
if ((dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter) && if (dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter &&
target.LayerType is FolderType) target.LayerType is FolderType)
{ {
// Insert into folder // Insert into folder
@ -208,9 +223,9 @@ namespace Artemis.ViewModels.Profiles
else else
{ {
// Insert the source into it's new profile/parent and update the order // Insert the source into it's new profile/parent and update the order
if ((dropInfo.InsertPosition == RelativeInsertPosition.AfterTargetItem) || if (dropInfo.InsertPosition == RelativeInsertPosition.AfterTargetItem ||
(dropInfo.InsertPosition == dropInfo.InsertPosition ==
(RelativeInsertPosition.TargetItemCenter | RelativeInsertPosition.AfterTargetItem))) (RelativeInsertPosition.TargetItemCenter | RelativeInsertPosition.AfterTargetItem))
target.InsertAfter(source); target.InsertAfter(source);
else else
target.InsertBefore(source); target.InsertBefore(source);
@ -230,6 +245,7 @@ namespace Artemis.ViewModels.Profiles
public void Activate() public void Activate()
{ {
_selectedProfile?.Activate(_luaManager);
ProfileViewModel.Activate(); ProfileViewModel.Activate();
_saveTimer.Start(); _saveTimer.Start();
} }
@ -237,7 +253,7 @@ namespace Artemis.ViewModels.Profiles
public void Deactivate() public void Deactivate()
{ {
ProfileViewModel.Deactivate(); ProfileViewModel.Deactivate();
SelectedProfile?.Deactivate(); SelectedProfile?.Deactivate(_luaManager);
_saveTimer.Stop(); _saveTimer.Stop();
} }
@ -246,26 +262,26 @@ namespace Artemis.ViewModels.Profiles
/// </summary> /// </summary>
private void LoadProfiles() private void LoadProfiles()
{ {
ProfileNames.Clear(); Execute.OnUIThread(() =>
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))
{ {
lastProfileModel = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _gameModel, LastProfile); ProfileNames.Clear();
} if (_effectModel == null || _deviceManager.ActiveKeyboard == null)
return;
if (lastProfileModel != null) ProfileNames.AddRange(ProfileProvider.GetProfileNames(_deviceManager.ActiveKeyboard, _effectModel));
SelectedProfile = lastProfileModel;
else // If a profile name was provided, try to load it
{ ProfileModel lastProfileModel = null;
SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _gameModel, if (!string.IsNullOrEmpty(LastProfile))
ProfileNames.FirstOrDefault()); 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 = IParameter[] args =
{ {
new ConstructorArgument("dataModel", _gameModel.DataModel), new ConstructorArgument("dataModel", _effectModel.DataModel),
new ConstructorArgument("layer", layer) new ConstructorArgument("layer", layer)
}; };
WindowService.ShowDialog<LayerEditorViewModel>(args); WindowService.ShowDialog<LayerEditorViewModel>(args);
@ -506,7 +522,7 @@ namespace Artemis.ViewModels.Profiles
KeyboardSlug = _deviceManager.ActiveKeyboard.Slug, KeyboardSlug = _deviceManager.ActiveKeyboard.Slug,
Width = _deviceManager.ActiveKeyboard.Width, Width = _deviceManager.ActiveKeyboard.Width,
Height = _deviceManager.ActiveKeyboard.Height, Height = _deviceManager.ActiveKeyboard.Height,
GameName = _gameModel.Name GameName = _effectModel.Name
}; };
if (!ProfileProvider.IsProfileUnique(profile)) 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"); var name = await DialogService.ShowInputDialog("Rename profile", "Please enter a unique new profile name");
// Null when the user cancelled // Null when the user cancelled
if (string.IsNullOrEmpty(name) || (name.Length < 2)) if (string.IsNullOrEmpty(name) || name.Length < 2)
return; return;
SelectedProfile.Name = name; SelectedProfile.Name = name;
@ -544,7 +560,7 @@ namespace Artemis.ViewModels.Profiles
.ShowInputDialog("Name already in use", "Please enter a unique new profile name"); .ShowInputDialog("Name already in use", "Please enter a unique new profile name");
// Null when the user cancelled // Null when the user cancelled
if (string.IsNullOrEmpty(name) || (name.Length < 2)) if (string.IsNullOrEmpty(name) || name.Length < 2)
{ {
SelectedProfile.Name = oldName; SelectedProfile.Name = oldName;
return; return;
@ -628,10 +644,10 @@ namespace Artemis.ViewModels.Profiles
} }
// Verify the game // Verify the game
if (profile.GameName != _gameModel.Name) if (profile.GameName != _effectModel.Name)
{ {
DialogService.ShowErrorMessageBox( 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; return;
} }
@ -694,13 +710,12 @@ namespace Artemis.ViewModels.Profiles
return; return;
try try
{ {
SelectedProfile?.Activate(_deviceManager.ActiveKeyboard); OpenEditor();
LuaWrapper.OpenEditor();
} }
catch (Exception e) catch (Exception e)
{ {
DialogService.ShowMessageBox("Couldn't open LUA file", 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); "Windows error message: \n" + e.Message);
} }
} }
@ -738,7 +753,7 @@ namespace Artemis.ViewModels.Profiles
public void SaveSelectedProfile() public void SaveSelectedProfile()
{ {
if (_saving || (SelectedProfile == null) || _deviceManager.ChangingKeyboard) if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard)
return; return;
_saving = true; _saving = true;
@ -752,5 +767,67 @@ namespace Artemis.ViewModels.Profiles
} }
_saving = false; _saving = false;
} }
#region LUA Editor
public void OpenEditor()
{
if (SelectedProfile == null)
return;
// Create a temp file
var fileName = Guid.NewGuid() + ".lua";
var file = File.Create(Path.GetTempPath() + fileName);
file.Dispose();
// Add instructions to LUA script if it's a new file
if (SelectedProfile.LuaScript.IsNullOrEmpty())
SelectedProfile.LuaScript = Encoding.UTF8.GetString(Resources.lua_placeholder);
File.WriteAllText(Path.GetTempPath() + fileName, SelectedProfile.LuaScript);
// Watch the file for changes
SetupWatcher(Path.GetTempPath(), fileName);
// Open the temp file with the default editor
System.Diagnostics.Process.Start(Path.GetTempPath() + fileName);
}
private void SetupWatcher(string path, string fileName)
{
if (_watcher == null)
{
_watcher = new FileSystemWatcher(Path.GetTempPath(), fileName);
_watcher.Changed += LuaFileChanged;
_watcher.EnableRaisingEvents = true;
}
_watcher.Path = path;
_watcher.Filter = fileName;
}
private void LuaFileChanged(object sender, FileSystemEventArgs args)
{
if (args.ChangeType != WatcherChangeTypes.Changed)
return;
if (SelectedProfile == null)
return;
lock (SelectedProfile)
{
using (var fs = new FileStream(args.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var sr = new StreamReader(fs))
{
SelectedProfile.LuaScript = sr.ReadToEnd();
}
}
ProfileProvider.AddOrUpdate(SelectedProfile);
_luaManager.SetupLua(SelectedProfile);
}
}
#endregion
} }
} }

View File

@ -11,7 +11,6 @@ using Artemis.Modules.Effects.ProfilePreview;
using Artemis.Profiles; using Artemis.Profiles;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Layers.Types.Folder; using Artemis.Profiles.Layers.Types.Folder;
using Artemis.Profiles.Lua;
using Artemis.Properties; using Artemis.Properties;
using Artemis.Utilities; using Artemis.Utilities;
using Caliburn.Micro; using Caliburn.Micro;
@ -103,10 +102,11 @@ namespace Artemis.ViewModels.Profiles
if (_blurProgress > 2) if (_blurProgress > 2)
_blurProgress = 0; _blurProgress = 0;
_blurProgress = _blurProgress + 0.025; _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 // 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(); var preview = new DrawingImage();
preview.Freeze(); preview.Freeze();
@ -166,8 +166,8 @@ namespace Artemis.ViewModels.Profiles
new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 0.7)); new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 0.7));
} }
LuaWrapper.LuaEventsWrapper?.InvokeDeviceDraw(SelectedProfile, "preview", new ProfilePreviewDataModel(), SelectedProfile.RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg("preview",
true, drawingContext); new ProfilePreviewDataModel(), true, drawingContext));
// Remove the clip // Remove the clip
drawingContext.Pop(); drawingContext.Pop();
@ -223,8 +223,8 @@ namespace Artemis.ViewModels.Profiles
var keyboard = _deviceManager.ActiveKeyboard; var keyboard = _deviceManager.ActiveKeyboard;
var pos = e.GetPosition((Image) e.OriginalSource); var pos = e.GetPosition((Image) e.OriginalSource);
var x = pos.X/((double) keyboard.PreviewSettings.Width/keyboard.Width); var x = pos.X / ((double) keyboard.PreviewSettings.Width / keyboard.Width);
var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height); var y = pos.Y / ((double) keyboard.PreviewSettings.Height / keyboard.Height);
var hoverLayer = GetLayers().Where(l => l.MustDraw()) var hoverLayer = GetLayers().Where(l => l.MustDraw())
.FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y)); .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 pos = e.GetPosition((Image) e.OriginalSource);
var keyboard = _deviceManager.ActiveKeyboard; var keyboard = _deviceManager.ActiveKeyboard;
var x = pos.X/((double) keyboard.PreviewSettings.Width/keyboard.Width); var x = pos.X / ((double) keyboard.PreviewSettings.Width / keyboard.Width);
var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height); var y = pos.Y / ((double) keyboard.PreviewSettings.Height / keyboard.Height);
var hoverLayer = GetLayers().Where(l => l.MustDraw()) var hoverLayer = GetLayers().Where(l => l.MustDraw())
.FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y)); .FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
@ -267,7 +267,9 @@ namespace Artemis.ViewModels.Profiles
: Cursors.SizeAll; : Cursors.SizeAll;
} }
else else
{
KeyboardPreviewCursor = Cursors.Hand; KeyboardPreviewCursor = Cursors.Hand;
}
} }
public Cursor KeyboardPreviewCursor public Cursor KeyboardPreviewCursor
@ -292,14 +294,14 @@ namespace Artemis.ViewModels.Profiles
{ {
// Reset the dragging state on mouse release // Reset the dragging state on mouse release
if (e.LeftButton == MouseButtonState.Released || if (e.LeftButton == MouseButtonState.Released ||
(_draggingLayer != null && SelectedLayer != _draggingLayer)) _draggingLayer != null && SelectedLayer != _draggingLayer)
{ {
_draggingLayerOffset = null; _draggingLayerOffset = null;
_draggingLayer = null; _draggingLayer = null;
return; return;
} }
if (SelectedLayer == null || (SelectedLayer.LayerType != null && !SelectedLayer.LayerType.ShowInEdtor)) if (SelectedLayer == null || SelectedLayer.LayerType != null && !SelectedLayer.LayerType.ShowInEdtor)
return; return;
// Setup the dragging state on mouse press // Setup the dragging state on mouse press
@ -314,7 +316,7 @@ namespace Artemis.ViewModels.Profiles
Math.Pow(y - layerRect.BottomRight.Y, 2)) < 0.6; Math.Pow(y - layerRect.BottomRight.Y, 2)) < 0.6;
} }
if (_draggingLayerOffset == null || _draggingLayer == null || (_draggingLayer != SelectedLayer)) if (_draggingLayerOffset == null || _draggingLayer == null || _draggingLayer != SelectedLayer)
return; return;
var draggingProps = _draggingLayer.Properties; var draggingProps = _draggingLayer.Properties;

View File

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

View File

@ -9,8 +9,18 @@
mc:Ignorable="d" mc:Ignorable="d"
Title="Artemis | Edit Layer" Height="820" Width="630" Title="Artemis | Edit Layer" Height="820" Width="630"
xmlns:cal="http://www.caliburnproject.org" 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" GlowBrush="{DynamicResource AccentColorBrush}" Icon="../../Resources/bow.png"
ResizeMode="NoResize"> 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"> <ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid Margin="10,0"> <Grid Margin="10,0">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@ -68,7 +78,22 @@
</Grid> </Grid>
<!-- Condition editor --> <!-- 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}" <Border Grid.Row="3" Grid.Column="0" BorderThickness="1" BorderBrush="{StaticResource GrayBrush7}"
Margin="10,0" SnapsToDevicePixels="True"> Margin="10,0" SnapsToDevicePixels="True">
<ListBox Height="138" x:Name="LayerConditionVms" ScrollViewer.VerticalScrollBarVisibility="Visible"> <ListBox Height="138" x:Name="LayerConditionVms" ScrollViewer.VerticalScrollBarVisibility="Visible">

View File

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

View File

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

View File

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

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