mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 17:53:32 +00:00
Merge pull request #99 from SpoinkyNL/development
Update 1.1.0 - Profiles
This commit is contained in:
commit
b11317050a
@ -5,6 +5,8 @@ VisualStudioVersion = 14.0.25123.0
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis", "Artemis\Artemis.csproj", "{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis", "Artemis\Artemis.csproj", "{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Razer2Artemis", "Razer2Artemis\Razer2Artemis.vcxproj", "{39711909-C1D5-46CE-A9EA-2D561692EA47}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
CD_ROM|Any CPU = CD_ROM|Any CPU
|
CD_ROM|Any CPU = CD_ROM|Any CPU
|
||||||
@ -54,6 +56,34 @@ Global
|
|||||||
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.SingleImage|x64.Build.0 = Release|x64
|
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.SingleImage|x64.Build.0 = Release|x64
|
||||||
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.SingleImage|x86.ActiveCfg = Release|x86
|
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.SingleImage|x86.ActiveCfg = Release|x86
|
||||||
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.SingleImage|x86.Build.0 = Release|x86
|
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.SingleImage|x86.Build.0 = Release|x86
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.CD_ROM|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.CD_ROM|Any CPU.Build.0 = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.CD_ROM|x64.ActiveCfg = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.CD_ROM|x64.Build.0 = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.CD_ROM|x86.ActiveCfg = Release|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.CD_ROM|x86.Build.0 = Release|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.DVD-5|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.DVD-5|Any CPU.Build.0 = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.DVD-5|x64.ActiveCfg = Debug|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.DVD-5|x64.Build.0 = Debug|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.DVD-5|x86.ActiveCfg = Debug|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.DVD-5|x86.Build.0 = Debug|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Release|x64.Build.0 = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.SingleImage|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.SingleImage|Any CPU.Build.0 = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.SingleImage|x64.ActiveCfg = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.SingleImage|x64.Build.0 = Release|x64
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.SingleImage|x86.ActiveCfg = Release|Win32
|
||||||
|
{39711909-C1D5-46CE-A9EA-2D561692EA47}.SingleImage|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@ -4,6 +4,12 @@
|
|||||||
<configSections>
|
<configSections>
|
||||||
<sectionGroup name="userSettings"
|
<sectionGroup name="userSettings"
|
||||||
type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<section name="Artemis.Modules.Effects.WindowsProfile.WindowsProfile"
|
||||||
|
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
|
||||||
|
allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||||
|
<section name="Artemis.Modules.Games.Overwatch.Overwatch"
|
||||||
|
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
|
||||||
|
allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||||
<section name="Artemis.Modules.Games.TheDivision.TheDivision"
|
<section name="Artemis.Modules.Games.TheDivision.TheDivision"
|
||||||
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
|
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
|
||||||
allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||||
@ -53,6 +59,22 @@
|
|||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||||
</startup>
|
</startup>
|
||||||
<userSettings>
|
<userSettings>
|
||||||
|
<Artemis.Modules.Effects.WindowsProfile.WindowsProfile>
|
||||||
|
<setting name="LastProfile" serializeAs="String">
|
||||||
|
<value>Demo (Duplicate to keep changes)</value>
|
||||||
|
</setting>
|
||||||
|
</Artemis.Modules.Effects.WindowsProfile.WindowsProfile>
|
||||||
|
<Artemis.Modules.Games.Overwatch.Overwatch>
|
||||||
|
<setting name="Enabled" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="LastProfile" serializeAs="String">
|
||||||
|
<value>Default</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="GameDirectory" serializeAs="String">
|
||||||
|
<value />
|
||||||
|
</setting>
|
||||||
|
</Artemis.Modules.Games.Overwatch.Overwatch>
|
||||||
<Artemis.Modules.Games.TheDivision.TheDivision>
|
<Artemis.Modules.Games.TheDivision.TheDivision>
|
||||||
<setting name="Enabled" serializeAs="String">
|
<setting name="Enabled" serializeAs="String">
|
||||||
<value>True</value>
|
<value>True</value>
|
||||||
@ -111,14 +133,8 @@
|
|||||||
<setting name="Enabled" serializeAs="String">
|
<setting name="Enabled" serializeAs="String">
|
||||||
<value>True</value>
|
<value>True</value>
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="MainColor" serializeAs="String">
|
<setting name="LastProfile" serializeAs="String">
|
||||||
<value>#FFFF5000</value>
|
<value>Default</value>
|
||||||
</setting>
|
|
||||||
<setting name="SecondaryColor" serializeAs="String">
|
|
||||||
<value>#FFFF0000</value>
|
|
||||||
</setting>
|
|
||||||
<setting name="ContextualColor" serializeAs="String">
|
|
||||||
<value>False</value>
|
|
||||||
</setting>
|
</setting>
|
||||||
</Artemis.Modules.Games.RocketLeague.RocketLeague>
|
</Artemis.Modules.Games.RocketLeague.RocketLeague>
|
||||||
<Artemis.Settings.Offsets>
|
<Artemis.Settings.Offsets>
|
||||||
@ -185,6 +201,9 @@
|
|||||||
<setting name="LowHpEnabled" serializeAs="String">
|
<setting name="LowHpEnabled" serializeAs="String">
|
||||||
<value>True</value>
|
<value>True</value>
|
||||||
</setting>
|
</setting>
|
||||||
|
<setting name="LastProfile" serializeAs="String">
|
||||||
|
<value>Default</value>
|
||||||
|
</setting>
|
||||||
</Artemis.Modules.Games.CounterStrike.CounterStrike>
|
</Artemis.Modules.Games.CounterStrike.CounterStrike>
|
||||||
<Artemis.Settings.CounterStrike>
|
<Artemis.Settings.CounterStrike>
|
||||||
<setting name="GameDirectory" serializeAs="String">
|
<setting name="GameDirectory" serializeAs="String">
|
||||||
@ -293,6 +312,9 @@
|
|||||||
<setting name="CheckForUpdates" serializeAs="String">
|
<setting name="CheckForUpdates" serializeAs="String">
|
||||||
<value>True</value>
|
<value>True</value>
|
||||||
</setting>
|
</setting>
|
||||||
|
<setting name="Theme" serializeAs="String">
|
||||||
|
<value>Light</value>
|
||||||
|
</setting>
|
||||||
</Artemis.Settings.General>
|
</Artemis.Settings.General>
|
||||||
</userSettings>
|
</userSettings>
|
||||||
<runtime>
|
<runtime>
|
||||||
@ -321,6 +343,10 @@
|
|||||||
<assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
|
<assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-3.0.2.0" newVersion="3.0.2.0" />
|
<bindingRedirect oldVersion="0.0.0.0-3.0.2.0" newVersion="3.0.2.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.3.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Security.Principal;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using Artemis.Utilities;
|
using NLog;
|
||||||
using WpfExceptionViewer;
|
using WpfExceptionViewer;
|
||||||
|
|
||||||
namespace Artemis
|
namespace Artemis
|
||||||
@ -13,14 +14,22 @@ namespace Artemis
|
|||||||
{
|
{
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
if (!GeneralHelpers.IsRunAsAdministrator())
|
//if (!IsRunAsAdministrator())
|
||||||
GeneralHelpers.RunAsAdministrator();
|
// GeneralHelpers.RunAsAdministrator();
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DoHandle { get; set; }
|
public bool DoHandle { get; set; }
|
||||||
|
|
||||||
|
private static bool IsRunAsAdministrator()
|
||||||
|
{
|
||||||
|
var wi = WindowsIdentity.GetCurrent();
|
||||||
|
var wp = new WindowsPrincipal(wi);
|
||||||
|
|
||||||
|
return wp.IsInRole(WindowsBuiltInRole.Administrator);
|
||||||
|
}
|
||||||
|
|
||||||
private void Application_Startup(object sender, StartupEventArgs e)
|
private void Application_Startup(object sender, StartupEventArgs e)
|
||||||
{
|
{
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||||
@ -40,7 +49,6 @@ namespace Artemis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
var ex = e.ExceptionObject as Exception;
|
var ex = e.ExceptionObject as Exception;
|
||||||
@ -49,6 +57,8 @@ namespace Artemis
|
|||||||
|
|
||||||
private static ExceptionViewer GetArtemisExceptionViewer(Exception e)
|
private static ExceptionViewer GetArtemisExceptionViewer(Exception e)
|
||||||
{
|
{
|
||||||
|
var logger = LogManager.GetCurrentClassLogger();
|
||||||
|
logger.Fatal(e, "Unhandled exception, showing dialog and shutting down.");
|
||||||
return new ExceptionViewer("An unexpected error occurred in Artemis.", e)
|
return new ExceptionViewer("An unexpected error occurred in Artemis.", e)
|
||||||
{
|
{
|
||||||
Title = "Artemis - Exception :c",
|
Title = "Artemis - Exception :c",
|
||||||
|
|||||||
BIN
Artemis/Artemis/Artemis base layout.png
Normal file
BIN
Artemis/Artemis/Artemis base layout.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
@ -120,20 +120,20 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Autofac, Version=4.0.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
<Reference Include="Caliburn.Micro, Version=3.0.1.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Autofac.4.0.0-rc1-177\lib\net45\Autofac.dll</HintPath>
|
<HintPath>..\packages\Caliburn.Micro.Core.3.0.1\lib\net45\Caliburn.Micro.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Caliburn.Micro, Version=2.0.2.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
|
<Reference Include="Caliburn.Micro.Platform, Version=3.0.1.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Caliburn.Micro.Core.2.0.2\lib\net45\Caliburn.Micro.dll</HintPath>
|
<HintPath>..\packages\Caliburn.Micro.3.0.1\lib\net45\Caliburn.Micro.Platform.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Caliburn.Micro.Autofac, Version=2.0.9.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Caliburn.Micro.Platform.Core, Version=3.0.1.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Caliburn.Micro.AutofacBootstrap.2.0.9-beta\lib\net40\Caliburn.Micro.Autofac.dll</HintPath>
|
<HintPath>..\packages\Caliburn.Micro.3.0.1\lib\net45\Caliburn.Micro.Platform.Core.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Caliburn.Micro.Platform, Version=2.0.2.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
|
<Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Caliburn.Micro.2.0.2\lib\net45\Caliburn.Micro.Platform.dll</HintPath>
|
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="ColorBox, Version=1.1.0.0, Culture=neutral, PublicKeyToken=f971124b2576acfc, processorArchitecture=MSIL">
|
<Reference Include="ColorBox, Version=1.1.0.0, Culture=neutral, PublicKeyToken=f971124b2576acfc, processorArchitecture=MSIL">
|
||||||
@ -144,8 +144,12 @@
|
|||||||
<HintPath>..\packages\Colore.4.0.0\lib\net35\Corale.Colore.dll</HintPath>
|
<HintPath>..\packages\Colore.4.0.0\lib\net35\Corale.Colore.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="CUE.NET, Version=1.0.2.2, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="CUE.NET, Version=1.0.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\CUE.NET.1.0.2.2\lib\net45\CUE.NET.dll</HintPath>
|
<HintPath>..\packages\CUE.NET.1.0.3\lib\net45\CUE.NET.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="GongSolutions.Wpf.DragDrop, Version=0.1.4.3, Culture=neutral, PublicKeyToken=d19974ea350ccea1, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\gong-wpf-dragdrop.0.1.4.3\lib\net40\GongSolutions.Wpf.DragDrop.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Hardcodet.Wpf.TaskbarNotification, Version=1.0.5.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Hardcodet.Wpf.TaskbarNotification, Version=1.0.5.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
@ -175,8 +179,24 @@
|
|||||||
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Ninject, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Ninject.3.2.2.0\lib\net45-full\Ninject.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Ninject.Extensions.Factory, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Ninject.Extensions.Factory.3.2.1.0\lib\net45-full\Ninject.Extensions.Factory.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Ninject.Extensions.Logging, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Ninject.Extensions.Logging.3.2.3.0\lib\net45-full\Ninject.Extensions.Logging.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Ninject.Extensions.Logging.NLog4, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Ninject.Extensions.Logging.nlog4.3.2.3.0\lib\net45-full\Ninject.Extensions.Logging.NLog4.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.4.3.2\lib\net45\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.3.4\lib\net45\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="SharpDX, Version=3.0.2.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
|
<Reference Include="SharpDX, Version=3.0.2.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
|
||||||
@ -191,10 +211,16 @@
|
|||||||
<HintPath>..\packages\SharpDX.DXGI.3.0.2\lib\net45\SharpDX.DXGI.dll</HintPath>
|
<HintPath>..\packages\SharpDX.DXGI.3.0.2\lib\net45\SharpDX.DXGI.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="SpotifyAPI, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\SpotifyAPI-NET.2.9.0\lib\SpotifyAPI.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.IO.Compression" />
|
||||||
|
<Reference Include="System.IO.Compression.FileSystem" />
|
||||||
<Reference Include="System.Linq.Dynamic, Version=1.0.5840.25917, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="System.Linq.Dynamic, Version=1.0.5840.25917, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\System.Linq.Dynamic.1.0.6\lib\net40\System.Linq.Dynamic.dll</HintPath>
|
<HintPath>..\packages\System.Linq.Dynamic.1.0.6\lib\net40\System.Linq.Dynamic.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
@ -202,7 +228,10 @@
|
|||||||
<Reference Include="System.Runtime.Serialization" />
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
<Reference Include="System.Web" />
|
<Reference Include="System.Web" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Caliburn.Micro.3.0.1\lib\net45\System.Windows.Interactivity.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
@ -259,34 +288,44 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="ArtemisBootstrapper.cs" />
|
<Compile Include="ArtemisBootstrapper.cs" />
|
||||||
<Compile Include="DAL\ProfileProvider.cs" />
|
<Compile Include="DAL\ProfileProvider.cs" />
|
||||||
|
<Compile Include="DeviceProviders\Corsair\CorsairMice.cs" />
|
||||||
|
<Compile Include="DeviceProviders\Corsair\CorsairHeadsets.cs" />
|
||||||
|
<Compile Include="DeviceProviders\DeviceProvider.cs" />
|
||||||
<Compile Include="Events\ActiveKeyboardChanged.cs" />
|
<Compile Include="Events\ActiveKeyboardChanged.cs" />
|
||||||
<Compile Include="Events\ToggleEnabled.cs" />
|
<Compile Include="Events\ToggleEnabled.cs" />
|
||||||
<Compile Include="Events\ActiveEffectChanged.cs" />
|
<Compile Include="Events\ActiveEffectChanged.cs" />
|
||||||
<Compile Include="Events\ChangeBitmap.cs" />
|
<Compile Include="Events\ChangeBitmap.cs" />
|
||||||
|
<Compile Include="InjectionFactories\ILayerEditorVmFactory.cs" />
|
||||||
|
<Compile Include="InjectionFactories\IProfileEditorVmFactory.cs" />
|
||||||
<Compile Include="ItemBehaviours\BindableSelectedItemBehavior.cs" />
|
<Compile Include="ItemBehaviours\BindableSelectedItemBehavior.cs" />
|
||||||
<Compile Include="KeyboardProviders\Corsair\CorsairRGB.cs" />
|
<Compile Include="DeviceProviders\Corsair\CorsairRGB.cs" />
|
||||||
<Compile Include="KeyboardProviders\KeyboardProvider.cs" />
|
<Compile Include="DeviceProviders\KeyboardProvider.cs" />
|
||||||
<Compile Include="KeyboardProviders\KeyboardRegion.cs" />
|
<Compile Include="DeviceProviders\Logitech\Orion.cs" />
|
||||||
<Compile Include="KeyboardProviders\Logitech\Orion.cs" />
|
<Compile Include="DeviceProviders\Logitech\Utilities\KeyboardNames.cs" />
|
||||||
<Compile Include="KeyboardProviders\Logitech\Utilities\KeyboardNames.cs" />
|
<Compile Include="DeviceProviders\Logitech\Utilities\KeyMap.cs" />
|
||||||
<Compile Include="KeyboardProviders\Logitech\Utilities\KeyMap.cs" />
|
<Compile Include="DeviceProviders\Logitech\Utilities\LogitechGSDK.cs" />
|
||||||
<Compile Include="KeyboardProviders\Logitech\Utilities\LogitechGSDK.cs" />
|
<Compile Include="DeviceProviders\Logitech\Utilities\OrionUtilities.cs" />
|
||||||
<Compile Include="KeyboardProviders\Logitech\Utilities\OrionUtilities.cs" />
|
<Compile Include="DeviceProviders\Razer\BlackWidow.cs" />
|
||||||
<Compile Include="KeyboardProviders\ProviderHelper.cs" />
|
<Compile Include="DeviceProviders\Razer\Utilities\RazerUtilities.cs" />
|
||||||
<Compile Include="KeyboardProviders\Razer\BlackWidow.cs" />
|
|
||||||
<Compile Include="KeyboardProviders\Razer\Utilities\RazerUtilities.cs" />
|
|
||||||
<Compile Include="Managers\EffectManager.cs" />
|
<Compile Include="Managers\EffectManager.cs" />
|
||||||
<Compile Include="Managers\KeyboardManager.cs" />
|
<Compile Include="Managers\DeviceManager.cs" />
|
||||||
|
<Compile Include="Managers\LoopManager.cs" />
|
||||||
<Compile Include="Managers\MainManager.cs" />
|
<Compile Include="Managers\MainManager.cs" />
|
||||||
|
<Compile Include="Managers\ProfileManager.cs" />
|
||||||
<Compile Include="Models\EffectModel.cs" />
|
<Compile Include="Models\EffectModel.cs" />
|
||||||
<Compile Include="Models\EffectSettings.cs" />
|
<Compile Include="Models\EffectSettings.cs" />
|
||||||
<Compile Include="Models\GameSettings.cs" />
|
<Compile Include="Models\GameSettings.cs" />
|
||||||
<Compile Include="Models\Interfaces\GameDataModel.cs" />
|
<Compile Include="Models\Interfaces\GameDataModel.cs" />
|
||||||
|
<Compile Include="Models\OverlaySettings.cs" />
|
||||||
<Compile Include="Models\Profiles\LayerConditionModel.cs" />
|
<Compile Include="Models\Profiles\LayerConditionModel.cs" />
|
||||||
<Compile Include="Models\Profiles\LayerModel.cs" />
|
<Compile Include="Models\Profiles\LayerModel.cs" />
|
||||||
<Compile Include="Models\Profiles\LayerDynamicPropertiesModel.cs" />
|
|
||||||
<Compile Include="Models\Profiles\LayerPropertiesModel.cs" />
|
|
||||||
<Compile Include="Models\Profiles\ProfileModel.cs" />
|
<Compile Include="Models\Profiles\ProfileModel.cs" />
|
||||||
|
<Compile Include="Models\Profiles\Properties\DynamicPropertiesModel.cs" />
|
||||||
|
<Compile Include="Models\Profiles\Properties\HeadsetPropertiesModel.cs" />
|
||||||
|
<Compile Include="Models\Profiles\Properties\KeyboardPropertiesModel.cs" />
|
||||||
|
<Compile Include="Models\Profiles\Properties\LayerPropertiesModel.cs" />
|
||||||
|
<Compile Include="Models\Profiles\Properties\FolderPropertiesModel.cs" />
|
||||||
|
<Compile Include="Models\Profiles\Properties\MousePropertiesModel.cs" />
|
||||||
<Compile Include="Modules\Effects\AmbientLightning\AmbientLightningEffectModel.cs" />
|
<Compile Include="Modules\Effects\AmbientLightning\AmbientLightningEffectModel.cs" />
|
||||||
<Compile Include="Modules\Effects\AmbientLightning\AmbientLightningEffectSettings.cs" />
|
<Compile Include="Modules\Effects\AmbientLightning\AmbientLightningEffectSettings.cs" />
|
||||||
<Compile Include="Modules\Effects\AmbientLightning\AmbientLightningEffectView.xaml.cs">
|
<Compile Include="Modules\Effects\AmbientLightning\AmbientLightningEffectView.xaml.cs">
|
||||||
@ -302,9 +341,19 @@
|
|||||||
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerModel.cs" />
|
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerModel.cs" />
|
||||||
<Compile Include="Modules\Effects\AudioVisualizer\Utilities\FftEventArgs.cs" />
|
<Compile Include="Modules\Effects\AudioVisualizer\Utilities\FftEventArgs.cs" />
|
||||||
<Compile Include="Modules\Effects\AudioVisualizer\Utilities\SampleAggregator.cs" />
|
<Compile Include="Modules\Effects\AudioVisualizer\Utilities\SampleAggregator.cs" />
|
||||||
<Compile Include="Modules\Effects\Debug\DebugEffectModel.cs" />
|
<Compile Include="Modules\Effects\WindowsProfile\WindowsProfile.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
<DependentUpon>WindowsProfile.settings</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Modules\Effects\WindowsProfile\WindowsProfileSettings.cs" />
|
||||||
|
<Compile Include="Modules\Effects\WindowsProfile\WindowsProfileView.xaml.cs">
|
||||||
|
<DependentUpon>WindowsProfileView.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Modules\Effects\WindowsProfile\WindowsProfileViewModel.cs" />
|
||||||
|
<Compile Include="Modules\Effects\WindowsProfile\WindowsProfileDataModel.cs" />
|
||||||
|
<Compile Include="Modules\Effects\WindowsProfile\WindowsProfileModel.cs" />
|
||||||
<Compile Include="Modules\Effects\ProfilePreview\ProfilePreviewModel.cs" />
|
<Compile Include="Modules\Effects\ProfilePreview\ProfilePreviewModel.cs" />
|
||||||
<Compile Include="Modules\Effects\TypeHole\TypeHoleModel.cs" />
|
|
||||||
<Compile Include="Modules\Effects\TypeWave\TypeWave.Designer.cs">
|
<Compile Include="Modules\Effects\TypeWave\TypeWave.Designer.cs">
|
||||||
<DependentUpon>TypeWave.settings</DependentUpon>
|
<DependentUpon>TypeWave.settings</DependentUpon>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
@ -328,6 +377,9 @@
|
|||||||
<Compile Include="Modules\Games\Dota2\Dota2DataModel.cs" />
|
<Compile Include="Modules\Games\Dota2\Dota2DataModel.cs" />
|
||||||
<Compile Include="Modules\Games\Dota2\Dota2Model.cs" />
|
<Compile Include="Modules\Games\Dota2\Dota2Model.cs" />
|
||||||
<Compile Include="Modules\Games\Dota2\Dota2Settings.cs" />
|
<Compile Include="Modules\Games\Dota2\Dota2Settings.cs" />
|
||||||
|
<Compile Include="Modules\Games\Overwatch\OverwatchView.xaml.cs">
|
||||||
|
<DependentUpon>OverwatchView.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Modules\Games\RocketLeague\RocketLeague.Designer.cs">
|
<Compile Include="Modules\Games\RocketLeague\RocketLeague.Designer.cs">
|
||||||
<DependentUpon>RocketLeague.settings</DependentUpon>
|
<DependentUpon>RocketLeague.settings</DependentUpon>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
@ -347,6 +399,16 @@
|
|||||||
<DependentUpon>TheDivisionView.xaml</DependentUpon>
|
<DependentUpon>TheDivisionView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Modules\Games\TheDivision\TheDivisionViewModel.cs" />
|
<Compile Include="Modules\Games\TheDivision\TheDivisionViewModel.cs" />
|
||||||
|
<Compile Include="Modules\Games\Overwatch\OverwatchDataModel.cs" />
|
||||||
|
<Compile Include="Modules\Games\Overwatch\Overwatch.Designer.cs">
|
||||||
|
<DependentUpon>Overwatch.settings</DependentUpon>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Modules\Games\Overwatch\OverwatchModel.cs" />
|
||||||
|
<Compile Include="Modules\Games\Overwatch\OverwatchSettings.cs" />
|
||||||
|
<Compile Include="Modules\Games\Overwatch\OverwatchViewModel.cs" />
|
||||||
|
<Compile Include="Modules\Games\Witcher3\Witcher3DataModel.cs" />
|
||||||
<Compile Include="Modules\Games\Witcher3\Witcher3Settings.cs" />
|
<Compile Include="Modules\Games\Witcher3\Witcher3Settings.cs" />
|
||||||
<Compile Include="Modules\Games\Witcher3\Witcher3.Designer.cs">
|
<Compile Include="Modules\Games\Witcher3\Witcher3.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
@ -363,10 +425,12 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayModel.cs" />
|
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayModel.cs" />
|
||||||
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerSettings.cs" />
|
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerSettings.cs" />
|
||||||
<Compile Include="Modules\Effects\Debug\DebugEffectSettings.cs" />
|
|
||||||
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplaySettings.cs" />
|
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplaySettings.cs" />
|
||||||
<Compile Include="Modules\Games\RocketLeague\RocketLeagueSettings.cs" />
|
<Compile Include="Modules\Games\RocketLeague\RocketLeagueSettings.cs" />
|
||||||
<Compile Include="Modules\Effects\TypeWave\TypeWaveSettings.cs" />
|
<Compile Include="Modules\Effects\TypeWave\TypeWaveSettings.cs" />
|
||||||
|
<Compile Include="InjectionModules\ArtemisModules.cs" />
|
||||||
|
<Compile Include="InjectionModules\BaseModules.cs" />
|
||||||
|
<Compile Include="InjectionModules\ManagerModules.cs" />
|
||||||
<Compile Include="Properties\Annotations.cs" />
|
<Compile Include="Properties\Annotations.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
@ -386,14 +450,19 @@
|
|||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
<DependentUpon>Offsets.settings</DependentUpon>
|
<DependentUpon>Offsets.settings</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroHighlightAdorner.cs" />
|
||||||
|
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroInsertionAdorner.cs" />
|
||||||
<Compile Include="Utilities\ColorHelpers.cs" />
|
<Compile Include="Utilities\ColorHelpers.cs" />
|
||||||
|
<Compile Include="Utilities\DataReaders\MmfReader.cs" />
|
||||||
<Compile Include="Utilities\ExtensionMethods.cs" />
|
<Compile Include="Utilities\ExtensionMethods.cs" />
|
||||||
<Compile Include="Utilities\GameState\GameDataReceivedEventArgs.cs" />
|
<Compile Include="Utilities\GameState\GameDataReceivedEventArgs.cs" />
|
||||||
<Compile Include="Utilities\GameState\GameStateWebServer.cs" />
|
<Compile Include="Utilities\GameState\GameStateWebServer.cs" />
|
||||||
<Compile Include="Utilities\GeneralHelpers.cs" />
|
<Compile Include="Utilities\GeneralHelpers.cs" />
|
||||||
|
<Compile Include="Utilities\GifImage.cs" />
|
||||||
<Compile Include="Utilities\ImageUtilities.cs" />
|
<Compile Include="Utilities\ImageUtilities.cs" />
|
||||||
<Compile Include="Utilities\Keyboard\KeyboardHook.cs" />
|
<Compile Include="Utilities\Keyboard\KeyboardHook.cs" />
|
||||||
<Compile Include="Utilities\LayerDrawer.cs" />
|
<Compile Include="Utilities\Layers\AnimationUpdater.cs" />
|
||||||
|
<Compile Include="Utilities\Layers\Drawer.cs" />
|
||||||
<Compile Include="Utilities\LogitechDll\DllManager.cs" />
|
<Compile Include="Utilities\LogitechDll\DllManager.cs" />
|
||||||
<Compile Include="Utilities\LogitechDll\NamedPipeServer.cs" />
|
<Compile Include="Utilities\LogitechDll\NamedPipeServer.cs" />
|
||||||
<Compile Include="Utilities\LogitechDll\PipeServer.cs" />
|
<Compile Include="Utilities\LogitechDll\PipeServer.cs" />
|
||||||
@ -409,12 +478,12 @@
|
|||||||
<Compile Include="Utilities\StickyValue.cs" />
|
<Compile Include="Utilities\StickyValue.cs" />
|
||||||
<Compile Include="Utilities\Updater.cs" />
|
<Compile Include="Utilities\Updater.cs" />
|
||||||
<Compile Include="Utilities\ValueConverters.cs" />
|
<Compile Include="Utilities\ValueConverters.cs" />
|
||||||
|
<Compile Include="ViewModels\Abstract\BaseViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\Abstract\OverlayViewModel.cs" />
|
||||||
<Compile Include="ViewModels\Abstract\EffectViewModel.cs" />
|
<Compile Include="ViewModels\Abstract\EffectViewModel.cs" />
|
||||||
<Compile Include="ViewModels\Abstract\GameViewModel.cs" />
|
<Compile Include="ViewModels\Abstract\GameViewModel.cs" />
|
||||||
<Compile Include="ViewModels\EffectsViewModel.cs" />
|
<Compile Include="ViewModels\EffectsViewModel.cs" />
|
||||||
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerViewModel.cs" />
|
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerViewModel.cs" />
|
||||||
<Compile Include="Modules\Effects\Debug\DebugEffectViewModel.cs" />
|
|
||||||
<Compile Include="Modules\Effects\TypeHole\TypeHoleViewModel.cs" />
|
|
||||||
<Compile Include="Modules\Effects\TypeWave\TypeWaveViewModel.cs" />
|
<Compile Include="Modules\Effects\TypeWave\TypeWaveViewModel.cs" />
|
||||||
<Compile Include="ViewModels\FlyoutBaseViewModel.cs" />
|
<Compile Include="ViewModels\FlyoutBaseViewModel.cs" />
|
||||||
<Compile Include="ViewModels\Flyouts\FlyoutSettingsViewModel.cs" />
|
<Compile Include="ViewModels\Flyouts\FlyoutSettingsViewModel.cs" />
|
||||||
@ -423,12 +492,18 @@
|
|||||||
<Compile Include="Modules\Games\Dota2\Dota2ViewModel.cs" />
|
<Compile Include="Modules\Games\Dota2\Dota2ViewModel.cs" />
|
||||||
<Compile Include="Modules\Games\RocketLeague\RocketLeagueViewModel.cs" />
|
<Compile Include="Modules\Games\RocketLeague\RocketLeagueViewModel.cs" />
|
||||||
<Compile Include="Modules\Games\Witcher3\Witcher3ViewModel.cs" />
|
<Compile Include="Modules\Games\Witcher3\Witcher3ViewModel.cs" />
|
||||||
<Compile Include="ViewModels\LayerEditor\LayerConditionViewModel.cs" />
|
<Compile Include="ViewModels\Profiles\ProfileViewModel.cs" />
|
||||||
<Compile Include="ViewModels\LayerEditor\LayerDynamicPropertiesViewModel.cs" />
|
<Compile Include="ViewModels\Profiles\Properties\KeyboardPropertiesViewModel.cs" />
|
||||||
<Compile Include="ViewModels\LayerEditor\LayerEditorViewModel.cs" />
|
<Compile Include="ViewModels\Profiles\LayerConditionViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\Profiles\LayerDynamicPropertiesViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\Profiles\LayerEditorViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\Profiles\Properties\LayerPropertiesViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\Profiles\Properties\HeadsetPropertiesViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\Profiles\Properties\FolderPropertiesViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\Profiles\Properties\MousePropertiesViewModel.cs" />
|
||||||
<Compile Include="ViewModels\OverlaysViewModel.cs" />
|
<Compile Include="ViewModels\OverlaysViewModel.cs" />
|
||||||
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayViewModel.cs" />
|
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayViewModel.cs" />
|
||||||
<Compile Include="ViewModels\ProfileEditorViewModel.cs" />
|
<Compile Include="ViewModels\Profiles\ProfileEditorViewModel.cs" />
|
||||||
<Compile Include="ViewModels\ShellViewModel.cs" />
|
<Compile Include="ViewModels\ShellViewModel.cs" />
|
||||||
<Compile Include="ViewModels\SystemTrayViewModel.cs" />
|
<Compile Include="ViewModels\SystemTrayViewModel.cs" />
|
||||||
<Compile Include="ViewModels\WelcomeViewModel.cs" />
|
<Compile Include="ViewModels\WelcomeViewModel.cs" />
|
||||||
@ -438,15 +513,9 @@
|
|||||||
<Compile Include="Views\Flyouts\FlyoutSettingsView.xaml.cs">
|
<Compile Include="Views\Flyouts\FlyoutSettingsView.xaml.cs">
|
||||||
<DependentUpon>FlyoutSettingsView.xaml</DependentUpon>
|
<DependentUpon>FlyoutSettingsView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Modules\Effects\Debug\DebugEffectView.xaml.cs">
|
|
||||||
<DependentUpon>DebugEffectView.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerView.xaml.cs">
|
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerView.xaml.cs">
|
||||||
<DependentUpon>AudioVisualizerView.xaml</DependentUpon>
|
<DependentUpon>AudioVisualizerView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Modules\Effects\TypeHole\TypeHoleView.xaml.cs">
|
|
||||||
<DependentUpon>TypeHoleView.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Modules\Effects\TypeWave\TypeWaveView.xaml.cs">
|
<Compile Include="Modules\Effects\TypeWave\TypeWaveView.xaml.cs">
|
||||||
<DependentUpon>TypeWaveView.xaml</DependentUpon>
|
<DependentUpon>TypeWaveView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -465,22 +534,34 @@
|
|||||||
<Compile Include="Modules\Games\Witcher3\Witcher3View.xaml.cs">
|
<Compile Include="Modules\Games\Witcher3\Witcher3View.xaml.cs">
|
||||||
<DependentUpon>Witcher3View.xaml</DependentUpon>
|
<DependentUpon>Witcher3View.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Views\LayerEditor\LayerConditionView.xaml.cs">
|
<Compile Include="Views\Profiles\Properties\FolderPropertiesView.xaml.cs">
|
||||||
|
<DependentUpon>FolderPropertiesView.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Views\Profiles\Properties\HeadsetPropertiesView.xaml.cs">
|
||||||
|
<DependentUpon>HeadsetPropertiesView.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Views\Profiles\Properties\KeyboardPropertiesView.xaml.cs">
|
||||||
|
<DependentUpon>KeyboardPropertiesView.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Views\Profiles\LayerConditionView.xaml.cs">
|
||||||
<DependentUpon>LayerConditionView.xaml</DependentUpon>
|
<DependentUpon>LayerConditionView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Views\LayerEditor\LayerDynamicPropertiesView.xaml.cs">
|
<Compile Include="Views\Profiles\LayerDynamicPropertiesView.xaml.cs">
|
||||||
<DependentUpon>LayerDynamicPropertiesView.xaml</DependentUpon>
|
<DependentUpon>LayerDynamicPropertiesView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Views\LayerEditor\LayerEditorView.xaml.cs">
|
<Compile Include="Views\Profiles\LayerEditorView.xaml.cs">
|
||||||
<DependentUpon>LayerEditorView.xaml</DependentUpon>
|
<DependentUpon>LayerEditorView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Views\Profiles\Properties\MousePropertiesView.xaml.cs">
|
||||||
|
<DependentUpon>MousePropertiesView.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Views\OverlaysView.xaml.cs">
|
<Compile Include="Views\OverlaysView.xaml.cs">
|
||||||
<DependentUpon>OverlaysView.xaml</DependentUpon>
|
<DependentUpon>OverlaysView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayView.xaml.cs">
|
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayView.xaml.cs">
|
||||||
<DependentUpon>VolumeDisplayView.xaml</DependentUpon>
|
<DependentUpon>VolumeDisplayView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Views\ProfileEditorView.xaml.cs">
|
<Compile Include="Views\Profiles\ProfileEditorView.xaml.cs">
|
||||||
<DependentUpon>ProfileEditorView.xaml</DependentUpon>
|
<DependentUpon>ProfileEditorView.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Views\ShellView.xaml.cs">
|
<Compile Include="Views\ShellView.xaml.cs">
|
||||||
@ -510,6 +591,10 @@
|
|||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>TypeWave.Designer.cs</LastGenOutput>
|
<LastGenOutput>TypeWave.Designer.cs</LastGenOutput>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Modules\Effects\WindowsProfile\WindowsProfile.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>WindowsProfile.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
<None Include="Modules\Games\CounterStrike\CounterStrike.settings">
|
<None Include="Modules\Games\CounterStrike\CounterStrike.settings">
|
||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>CounterStrike.Designer.cs</LastGenOutput>
|
<LastGenOutput>CounterStrike.Designer.cs</LastGenOutput>
|
||||||
@ -526,6 +611,10 @@
|
|||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>TheDivision.Designer.cs</LastGenOutput>
|
<LastGenOutput>TheDivision.Designer.cs</LastGenOutput>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Modules\Games\Overwatch\Overwatch.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Overwatch.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
<None Include="Modules\Games\Witcher3\Witcher3.settings">
|
<None Include="Modules\Games\Witcher3\Witcher3.settings">
|
||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>Witcher3.Designer.cs</LastGenOutput>
|
<LastGenOutput>Witcher3.Designer.cs</LastGenOutput>
|
||||||
@ -540,7 +629,9 @@
|
|||||||
<None Include="NLog.xsd">
|
<None Include="NLog.xsd">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</None>
|
</None>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</None>
|
||||||
<AppDesigner Include="Properties\" />
|
<AppDesigner Include="Properties\" />
|
||||||
<Resource Include="Resources\bow.png" />
|
<Resource Include="Resources\bow.png" />
|
||||||
<Content Include="logo.ico">
|
<Content Include="logo.ico">
|
||||||
@ -550,15 +641,23 @@
|
|||||||
<Resource Include="Resources\logo-disabled.ico" />
|
<Resource Include="Resources\logo-disabled.ico" />
|
||||||
<Resource Include="Resources\Dota2\dotaGamestateConfiguration.txt" />
|
<Resource Include="Resources\Dota2\dotaGamestateConfiguration.txt" />
|
||||||
<Resource Include="Resources\Entypo.ttf" />
|
<Resource Include="Resources\Entypo.ttf" />
|
||||||
|
<EmbeddedResource Include="Resources\Keyboards\default-profiles.zip" />
|
||||||
<None Include="Resources\LogitechLED.dll" />
|
<None Include="Resources\LogitechLED.dll" />
|
||||||
<None Include="Resources\folder.png" />
|
|
||||||
<Resource Include="Resources\Keyboards\k65.png" />
|
<Resource Include="Resources\Keyboards\k65.png" />
|
||||||
<Resource Include="Resources\Keyboards\k70.png" />
|
<Resource Include="Resources\Keyboards\k70.png" />
|
||||||
<Resource Include="Resources\Keyboards\k95.png" />
|
<Resource Include="Resources\Keyboards\k95.png" />
|
||||||
<Resource Include="Resources\Keyboards\strafe.png" />
|
<Resource Include="Resources\Keyboards\strafe.png" />
|
||||||
<Resource Include="Resources\Keyboards\g910.png" />
|
<Resource Include="Resources\Keyboards\g910.png" />
|
||||||
|
<None Include="Resources\folder.png" />
|
||||||
|
<None Include="Resources\headset.png" />
|
||||||
|
<None Include="Resources\mouse.png" />
|
||||||
|
<None Include="Resources\gif.png" />
|
||||||
<Resource Include="Resources\WindowsIcons-license.txt" />
|
<Resource Include="Resources\WindowsIcons-license.txt" />
|
||||||
<Resource Include="Resources\Entypo-license.txt" />
|
<Resource Include="Resources\Entypo-license.txt" />
|
||||||
|
<None Include="Resources\RzChromaSDK64.dll" />
|
||||||
|
<Resource Include="Resources\Keyboards\blackwidow.png" />
|
||||||
|
<None Include="Resources\Keyboards\none.png" />
|
||||||
|
<None Include="Resources\Keyboards\demo-gif.gif" />
|
||||||
<Content Include="Resources\Witcher3\playerWitcher.txt" />
|
<Content Include="Resources\Witcher3\playerWitcher.txt" />
|
||||||
<Content Include="Resources\Witcher3\artemis.txt" />
|
<Content Include="Resources\Witcher3\artemis.txt" />
|
||||||
<None Include="Settings\Offsets.settings">
|
<None Include="Settings\Offsets.settings">
|
||||||
@ -578,6 +677,14 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Modules\Effects\WindowsProfile\WindowsProfileView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Modules\Games\Overwatch\OverwatchView.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Modules\Games\TheDivision\TheDivisionView.xaml">
|
<Page Include="Modules\Games\TheDivision\TheDivisionView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@ -586,10 +693,14 @@
|
|||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Styles\Accents\CorsairYellow.xaml">
|
<Page Include="Resources\IconsNonShared.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Resource Include="Styles\Accents\CorsairYellow.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Resource>
|
||||||
<Page Include="Styles\ColorBox.xaml">
|
<Page Include="Styles\ColorBox.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@ -598,18 +709,10 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Modules\Effects\Debug\DebugEffectView.xaml">
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
</Page>
|
|
||||||
<Page Include="Modules\Effects\AudioVisualizer\AudioVisualizerView.xaml">
|
<Page Include="Modules\Effects\AudioVisualizer\AudioVisualizerView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Modules\Effects\TypeHole\TypeHoleView.xaml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
<Page Include="Modules\Effects\TypeWave\TypeWaveView.xaml">
|
<Page Include="Modules\Effects\TypeWave\TypeWaveView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@ -638,18 +741,34 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Views\LayerEditor\LayerConditionView.xaml">
|
<Page Include="Views\Profiles\Properties\FolderPropertiesView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Views\LayerEditor\LayerDynamicPropertiesView.xaml">
|
<Page Include="Views\Profiles\Properties\HeadsetPropertiesView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Views\LayerEditor\LayerEditorView.xaml">
|
<Page Include="Views\Profiles\Properties\KeyboardPropertiesView.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Views\Profiles\LayerConditionView.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Views\Profiles\LayerDynamicPropertiesView.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Views\Profiles\LayerEditorView.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Views\Profiles\Properties\MousePropertiesView.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Views\OverlaysView.xaml">
|
<Page Include="Views\OverlaysView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@ -658,7 +777,7 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Views\ProfileEditorView.xaml">
|
<Page Include="Views\Profiles\ProfileEditorView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
@ -695,12 +814,12 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="..\packages\CUE.NET.1.0.2.2\build\net45\CUE.NET.targets" Condition="Exists('..\packages\CUE.NET.1.0.2.2\build\net45\CUE.NET.targets')" />
|
<Import Project="..\packages\CUE.NET.1.0.3\build\net45\CUE.NET.targets" Condition="Exists('..\packages\CUE.NET.1.0.3\build\net45\CUE.NET.targets')" />
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Error Condition="!Exists('..\packages\CUE.NET.1.0.2.2\build\net45\CUE.NET.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CUE.NET.1.0.2.2\build\net45\CUE.NET.targets'))" />
|
<Error Condition="!Exists('..\packages\CUE.NET.1.0.3\build\net45\CUE.NET.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CUE.NET.1.0.3\build\net45\CUE.NET.targets'))" />
|
||||||
</Target>
|
</Target>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|||||||
@ -1,27 +1,34 @@
|
|||||||
using System.Diagnostics;
|
using System;
|
||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Threading;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Artemis.InjectionModules;
|
||||||
using Artemis.ViewModels;
|
using Artemis.ViewModels;
|
||||||
using Autofac;
|
|
||||||
using Caliburn.Micro;
|
using Caliburn.Micro;
|
||||||
using Caliburn.Micro.Autofac;
|
using Ninject;
|
||||||
using Application = System.Windows.Application;
|
using Application = System.Windows.Application;
|
||||||
using MessageBox = System.Windows.Forms.MessageBox;
|
using MessageBox = System.Windows.Forms.MessageBox;
|
||||||
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
||||||
|
|
||||||
namespace Artemis
|
namespace Artemis
|
||||||
{
|
{
|
||||||
public class ArtemisBootstrapper : AutofacBootstrapper<SystemTrayViewModel>
|
public class ArtemisBootstrapper : BootstrapperBase
|
||||||
{
|
{
|
||||||
|
private IKernel _kernel;
|
||||||
|
|
||||||
public ArtemisBootstrapper()
|
public ArtemisBootstrapper()
|
||||||
{
|
{
|
||||||
CheckDuplicateInstances();
|
CheckDuplicateInstances();
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
|
BindSpecialValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mutex Mutex { get; set; }
|
||||||
|
|
||||||
|
private void BindSpecialValues()
|
||||||
|
{
|
||||||
MessageBinder.SpecialValues.Add("$scaledmousex", ctx =>
|
MessageBinder.SpecialValues.Add("$scaledmousex", ctx =>
|
||||||
{
|
{
|
||||||
var img = ctx.Source as Image;
|
var img = ctx.Source as Image;
|
||||||
@ -64,14 +71,35 @@ namespace Artemis
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ConfigureContainer(ContainerBuilder builder)
|
protected override void Configure()
|
||||||
{
|
{
|
||||||
base.ConfigureContainer(builder);
|
_kernel = new StandardKernel(new BaseModules(), new ArtemisModules(), new ManagerModules());
|
||||||
|
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
|
||||||
|
_kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
|
||||||
|
}
|
||||||
|
|
||||||
// create a window manager instance to be used by everyone asking for one (including Caliburn.Micro)
|
protected override void OnExit(object sender, EventArgs e)
|
||||||
builder.RegisterInstance<IWindowManager>(new WindowManager());
|
{
|
||||||
builder.RegisterType<SystemTrayViewModel>();
|
_kernel.Dispose();
|
||||||
builder.RegisterType<ShellViewModel>();
|
base.OnExit(sender, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override object GetInstance(Type service, string key)
|
||||||
|
{
|
||||||
|
if (service == null)
|
||||||
|
throw new ArgumentNullException(nameof(service));
|
||||||
|
|
||||||
|
return _kernel.Get(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<object> GetAllInstances(Type service)
|
||||||
|
{
|
||||||
|
return _kernel.GetAll(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void BuildUp(object instance)
|
||||||
|
{
|
||||||
|
_kernel.Inject(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStartup(object sender, StartupEventArgs e)
|
protected override void OnStartup(object sender, StartupEventArgs e)
|
||||||
@ -81,8 +109,9 @@ namespace Artemis
|
|||||||
|
|
||||||
private void CheckDuplicateInstances()
|
private void CheckDuplicateInstances()
|
||||||
{
|
{
|
||||||
if (Process.GetProcesses().Count(p => p.ProcessName.Contains(Assembly.GetExecutingAssembly()
|
bool aIsNewInstance;
|
||||||
.FullName.Split(',')[0]) && !p.Modules[0].FileName.Contains("vshost")) < 2)
|
Mutex = new Mutex(true, "ArtemisMutex", out aIsNewInstance);
|
||||||
|
if (aIsNewInstance)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MessageBox.Show("An instance of Artemis is already running (check your system tray).",
|
MessageBox.Show("An instance of Artemis is already running (check your system tray).",
|
||||||
|
|||||||
@ -1,18 +1,28 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
|
using Artemis.DeviceProviders;
|
||||||
using Artemis.Models;
|
using Artemis.Models;
|
||||||
using Artemis.Models.Profiles;
|
using Artemis.Models.Profiles;
|
||||||
|
using Artemis.Models.Profiles.Properties;
|
||||||
|
using Artemis.Properties;
|
||||||
|
using Artemis.Utilities;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
namespace Artemis.DAL
|
namespace Artemis.DAL
|
||||||
{
|
{
|
||||||
public static class ProfileProvider
|
public static class ProfileProvider
|
||||||
{
|
{
|
||||||
private static readonly string ProfileFolder =
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\profiles";
|
|
||||||
|
private static readonly string ProfileFolder = Environment
|
||||||
|
.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\profiles";
|
||||||
|
|
||||||
|
private static bool _installedDefaults;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get all profiles
|
/// Get all profiles
|
||||||
@ -27,10 +37,16 @@ namespace Artemis.DAL
|
|||||||
/// Get all profiles matching the provided game
|
/// Get all profiles matching the provided game
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="game">The game to match</param>
|
/// <param name="game">The game to match</param>
|
||||||
|
/// <param name="keyboard">The keyboard to match</param>
|
||||||
/// <returns>All profiles matching the provided game</returns>
|
/// <returns>All profiles matching the provided game</returns>
|
||||||
public static List<ProfileModel> GetAll(GameModel game)
|
public static List<ProfileModel> GetAll(EffectModel game, KeyboardProvider keyboard)
|
||||||
{
|
{
|
||||||
return GetAll().Where(g => g.GameName.Equals(game.Name)).ToList();
|
if (game == null)
|
||||||
|
throw new ArgumentNullException(nameof(game));
|
||||||
|
if (keyboard == null)
|
||||||
|
throw new ArgumentNullException(nameof(keyboard));
|
||||||
|
|
||||||
|
return GetAll().Where(g => g.GameName.Equals(game.Name) && g.KeyboardSlug.Equals(keyboard.Slug)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -40,44 +56,100 @@ namespace Artemis.DAL
|
|||||||
/// <param name="prof">The profile to add or update</param>
|
/// <param name="prof">The profile to add or update</param>
|
||||||
public static void AddOrUpdate(ProfileModel prof)
|
public static void AddOrUpdate(ProfileModel prof)
|
||||||
{
|
{
|
||||||
if (!(prof.GameName?.Length > 1) || !(prof.KeyboardName?.Length > 1) || !(prof.Name?.Length > 1))
|
if (prof == null)
|
||||||
throw new ArgumentException("Profile is invalid. Name, GameName and KeyboardName are required");
|
throw new ArgumentNullException(nameof(prof));
|
||||||
|
if (!(prof.GameName?.Length > 1) || !(prof.KeyboardSlug?.Length > 1) || !(prof.Name?.Length > 1))
|
||||||
|
throw new ArgumentException("Profile is invalid. Name, GameName and KeyboardSlug are required");
|
||||||
|
|
||||||
var path = ProfileFolder + $@"\{prof.KeyboardName}\{prof.GameName}";
|
var path = ProfileFolder + $@"\{prof.KeyboardSlug}\{prof.GameName}";
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
|
|
||||||
var serializer = new XmlSerializer(typeof (ProfileModel));
|
var serializer = new XmlSerializer(typeof(ProfileModel));
|
||||||
using (var file = new StreamWriter(path + $@"\{prof.Name}.xml"))
|
|
||||||
|
// Could use a StreamWriter but should serializing fail this method doesn't ruin the existing XML file
|
||||||
|
using (var xml = new StringWriter())
|
||||||
{
|
{
|
||||||
serializer.Serialize(file, prof);
|
serializer.Serialize(xml, prof);
|
||||||
|
File.WriteAllText(path + $@"\{prof.Name}.xml", xml.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<ProfileModel> ReadProfiles()
|
private static List<ProfileModel> ReadProfiles()
|
||||||
{
|
{
|
||||||
CheckProfiles();
|
CheckProfiles();
|
||||||
|
InstallDefaults();
|
||||||
var profiles = new List<ProfileModel>();
|
var profiles = new List<ProfileModel>();
|
||||||
|
|
||||||
// Create the directory structure
|
// Create the directory structure
|
||||||
var profilePaths = Directory.GetFiles(ProfileFolder, "*.xml", SearchOption.AllDirectories);
|
var profilePaths = Directory.GetFiles(ProfileFolder, "*.xml", SearchOption.AllDirectories);
|
||||||
|
|
||||||
// Parse the JSON files into objects and add them if they are valid
|
// Parse the JSON files into objects and add them if they are valid
|
||||||
// TODO: Invalid file handling
|
var deserializer = new XmlSerializer(typeof(ProfileModel));
|
||||||
var deserializer = new XmlSerializer(typeof (ProfileModel));
|
|
||||||
foreach (var path in profilePaths)
|
foreach (var path in profilePaths)
|
||||||
{
|
{
|
||||||
using (var file = new StreamReader(path))
|
try
|
||||||
{
|
{
|
||||||
var prof = (ProfileModel) deserializer.Deserialize(file);
|
using (var file = new StreamReader(path))
|
||||||
if (prof.GameName?.Length > 1 && prof.KeyboardName?.Length > 1 && prof.Name?.Length > 1)
|
{
|
||||||
profiles.Add(prof);
|
var prof = (ProfileModel) deserializer.Deserialize(file);
|
||||||
|
if (prof.GameName?.Length > 1 && prof.KeyboardSlug?.Length > 1 && prof.Name?.Length > 1)
|
||||||
|
profiles.Add(prof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException e)
|
||||||
|
{
|
||||||
|
Logger.Error("Failed to load profile: {0} - {1}", path, e.InnerException.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return profiles;
|
return profiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unpacks the default profiles into the profile directory
|
||||||
|
/// </summary>
|
||||||
|
private static void InstallDefaults()
|
||||||
|
{
|
||||||
|
// Only install the defaults once per session
|
||||||
|
if (_installedDefaults)
|
||||||
|
return;
|
||||||
|
_installedDefaults = true;
|
||||||
|
|
||||||
|
// Load the ZIP from resources
|
||||||
|
var stream = Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceStream("Artemis.Resources.Keyboards.default-profiles.zip");
|
||||||
|
|
||||||
|
// Extract it over the old defaults in case one was updated
|
||||||
|
if (stream == null)
|
||||||
|
return;
|
||||||
|
var archive = new ZipArchive(stream);
|
||||||
|
archive.ExtractToDirectory(ProfileFolder, true);
|
||||||
|
|
||||||
|
// Extract the demo GIF file
|
||||||
|
var gifPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\demo-gif.gif";
|
||||||
|
Resources.demo_gif.Save(gifPath);
|
||||||
|
|
||||||
|
// Set the GIF path on each demo profile
|
||||||
|
var demoProfiles = GetAll().Where(d => d.Name == "Demo (Duplicate to keep changes)");
|
||||||
|
foreach (var demoProfile in demoProfiles)
|
||||||
|
{
|
||||||
|
var gifLayer = demoProfile
|
||||||
|
.Layers.FirstOrDefault(l => l.Name == "Demo - GIFs")?
|
||||||
|
.Children.FirstOrDefault(c => c.Name == "GIF");
|
||||||
|
|
||||||
|
if (gifLayer == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
((KeyboardPropertiesModel) gifLayer.Properties).GifFile = gifPath;
|
||||||
|
AddOrUpdate(demoProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes sure the profile directory structure is in order and places default profiles
|
||||||
|
/// </summary>
|
||||||
private static void CheckProfiles()
|
private static void CheckProfiles()
|
||||||
{
|
{
|
||||||
// Create the directory structure
|
// Create the directory structure
|
||||||
@ -85,7 +157,72 @@ namespace Artemis.DAL
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Directory.CreateDirectory(ProfileFolder);
|
Directory.CreateDirectory(ProfileFolder);
|
||||||
Debug.WriteLine("Place presets");
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to load a profile from a given path
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The absolute path to load the profile from</param>
|
||||||
|
/// <returns>The loaded profile, or null if invalid</returns>
|
||||||
|
public static ProfileModel LoadProfileIfValid(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var deserializer = new XmlSerializer(typeof(ProfileModel));
|
||||||
|
using (var file = new StreamReader(path))
|
||||||
|
{
|
||||||
|
var prof = (ProfileModel) deserializer.Deserialize(file);
|
||||||
|
if (!(prof.GameName?.Length > 1) || !(prof.KeyboardSlug?.Length > 1) || !(prof.Name?.Length > 1))
|
||||||
|
return null;
|
||||||
|
return prof;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exports the given profile to the provided path in XML
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="selectedProfile">The profile to export</param>
|
||||||
|
/// <param name="path">The path to save the profile to</param>
|
||||||
|
public static void ExportProfile(ProfileModel selectedProfile, string path)
|
||||||
|
{
|
||||||
|
var serializer = new XmlSerializer(typeof(ProfileModel));
|
||||||
|
using (var file = new StreamWriter(path))
|
||||||
|
{
|
||||||
|
serializer.Serialize(file, selectedProfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Renames the profile on the model and filesystem
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="profile">The profile to rename</param>
|
||||||
|
/// <param name="name">The new name</param>
|
||||||
|
public static void RenameProfile(ProfileModel profile, string name)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove the old file
|
||||||
|
var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.xml";
|
||||||
|
if (File.Exists(path))
|
||||||
|
File.Delete(path);
|
||||||
|
|
||||||
|
// Update the profile, creating a new file
|
||||||
|
profile.Name = name;
|
||||||
|
AddOrUpdate(profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteProfile(ProfileModel profile)
|
||||||
|
{
|
||||||
|
// Remove the file
|
||||||
|
var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.xml";
|
||||||
|
if (File.Exists(path))
|
||||||
|
File.Delete(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
80
Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs
Normal file
80
Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using Artemis.Utilities;
|
||||||
|
using CUE.NET;
|
||||||
|
using CUE.NET.Devices.Generic.Enums;
|
||||||
|
using Ninject.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Artemis.DeviceProviders.Corsair
|
||||||
|
{
|
||||||
|
internal class CorsairHeadsets : DeviceProvider
|
||||||
|
{
|
||||||
|
public CorsairHeadsets(ILogger logger)
|
||||||
|
{
|
||||||
|
Logger = logger;
|
||||||
|
Type = DeviceType.Headset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
public override bool TryEnable()
|
||||||
|
{
|
||||||
|
CanUse = CanInitializeSdk();
|
||||||
|
if (CanUse && !CueSDK.IsInitialized)
|
||||||
|
CueSDK.Initialize();
|
||||||
|
|
||||||
|
Logger.Debug("Attempted to enable Corsair headset. CanUse: {0}", CanUse);
|
||||||
|
return CanUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Disable()
|
||||||
|
{
|
||||||
|
if (CueSDK.IsInitialized)
|
||||||
|
CueSDK.Reinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateDevice(Brush brush)
|
||||||
|
{
|
||||||
|
if (!CanUse || brush == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var leds = CueSDK.HeadsetSDK.Leds.Count();
|
||||||
|
var rect = new Rect(new Size(leds*20, leds*20));
|
||||||
|
|
||||||
|
var visual = new DrawingVisual();
|
||||||
|
using (var c = visual.RenderOpen())
|
||||||
|
c.DrawRectangle(brush, null, rect);
|
||||||
|
var img = ImageUtilities.DrawinVisualToBitmap(visual, rect);
|
||||||
|
|
||||||
|
var ledIndex = 0;
|
||||||
|
// Color each LED according to one of the pixels
|
||||||
|
foreach (var corsairLed in CueSDK.HeadsetSDK.Leds)
|
||||||
|
{
|
||||||
|
corsairLed.Color = ledIndex == 0
|
||||||
|
? img.GetPixel(0, 0)
|
||||||
|
: img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
|
||||||
|
ledIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush is required for headset to work reliably on CUE2 for some reason
|
||||||
|
CueSDK.HeadsetSDK.Update(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool CanInitializeSdk()
|
||||||
|
{
|
||||||
|
// This will skip the check-loop if the SDK is initialized
|
||||||
|
if (CueSDK.IsInitialized)
|
||||||
|
return CueSDK.IsSDKAvailable(CorsairDeviceType.Headset);
|
||||||
|
|
||||||
|
for (var tries = 0; tries < 9; tries++)
|
||||||
|
{
|
||||||
|
if (CueSDK.IsSDKAvailable(CorsairDeviceType.Headset))
|
||||||
|
return true;
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
79
Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs
Normal file
79
Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using Artemis.Utilities;
|
||||||
|
using CUE.NET;
|
||||||
|
using CUE.NET.Devices.Generic.Enums;
|
||||||
|
using Ninject.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Artemis.DeviceProviders.Corsair
|
||||||
|
{
|
||||||
|
internal class CorsairMice : DeviceProvider
|
||||||
|
{
|
||||||
|
public CorsairMice(ILogger logger)
|
||||||
|
{
|
||||||
|
Logger = logger;
|
||||||
|
Type = DeviceType.Mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
public override bool TryEnable()
|
||||||
|
{
|
||||||
|
CanUse = CanInitializeSdk();
|
||||||
|
if (CanUse && !CueSDK.IsInitialized)
|
||||||
|
CueSDK.Initialize();
|
||||||
|
|
||||||
|
Logger.Debug("Attempted to enable Corsair mice. CanUse: {0}", CanUse);
|
||||||
|
return CanUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Disable()
|
||||||
|
{
|
||||||
|
if (CueSDK.IsInitialized)
|
||||||
|
CueSDK.Reinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateDevice(Brush brush)
|
||||||
|
{
|
||||||
|
if (!CanUse || brush == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var leds = CueSDK.MouseSDK.Leds.Count();
|
||||||
|
var rect = new Rect(new Size(leds*20, leds*20));
|
||||||
|
|
||||||
|
var visual = new DrawingVisual();
|
||||||
|
using (var c = visual.RenderOpen())
|
||||||
|
c.DrawRectangle(brush, null, rect);
|
||||||
|
var img = ImageUtilities.DrawinVisualToBitmap(visual, rect);
|
||||||
|
|
||||||
|
var ledIndex = 0;
|
||||||
|
// Color each LED according to one of the pixels
|
||||||
|
foreach (var corsairLed in CueSDK.MouseSDK.Leds)
|
||||||
|
{
|
||||||
|
corsairLed.Color = ledIndex == 0
|
||||||
|
? img.GetPixel(0, 0)
|
||||||
|
: img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
|
||||||
|
ledIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
CueSDK.MouseSDK.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool CanInitializeSdk()
|
||||||
|
{
|
||||||
|
// This will skip the check-loop if the SDK is initialized
|
||||||
|
if (CueSDK.IsInitialized)
|
||||||
|
return CueSDK.IsSDKAvailable(CorsairDeviceType.Mouse);
|
||||||
|
|
||||||
|
for (var tries = 0; tries < 9; tries++)
|
||||||
|
{
|
||||||
|
if (CueSDK.IsSDKAvailable(CorsairDeviceType.Mouse))
|
||||||
|
return true;
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
111
Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs
Normal file
111
Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows;
|
||||||
|
using Artemis.Properties;
|
||||||
|
using Artemis.Utilities;
|
||||||
|
using CUE.NET;
|
||||||
|
using CUE.NET.Brushes;
|
||||||
|
using CUE.NET.Devices.Generic.Enums;
|
||||||
|
using CUE.NET.Devices.Keyboard;
|
||||||
|
using Point = System.Drawing.Point;
|
||||||
|
|
||||||
|
namespace Artemis.DeviceProviders.Corsair
|
||||||
|
{
|
||||||
|
public class CorsairRGB : KeyboardProvider
|
||||||
|
{
|
||||||
|
private CorsairKeyboard _keyboard;
|
||||||
|
private ImageBrush _keyboardBrush;
|
||||||
|
|
||||||
|
public CorsairRGB()
|
||||||
|
{
|
||||||
|
Name = "Corsair RGB Keyboards";
|
||||||
|
CantEnableText = "Couldn't connect to your Corsair keyboard.\n" +
|
||||||
|
"Please check your cables and/or drivers (could be outdated) and that Corsair Utility Engine is running.\n" +
|
||||||
|
"In CUE, make sure \"Enable SDK\" is checked under Settings > Program.\n\n" +
|
||||||
|
"If needed, you can select a different keyboard in Artemis under settings.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanEnable()
|
||||||
|
{
|
||||||
|
// This will skip the check-loop if the SDK is initialized
|
||||||
|
if (CueSDK.IsInitialized)
|
||||||
|
return CueSDK.IsSDKAvailable(CorsairDeviceType.Keyboard);
|
||||||
|
|
||||||
|
for (var tries = 0; tries < 9; tries++)
|
||||||
|
{
|
||||||
|
if (CueSDK.IsSDKAvailable(CorsairDeviceType.Keyboard))
|
||||||
|
return true;
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the SDK and sets updatemode to manual as well as the color of the background to black.
|
||||||
|
/// </summary>
|
||||||
|
public override void Enable()
|
||||||
|
{
|
||||||
|
if (!CueSDK.IsInitialized)
|
||||||
|
CueSDK.Initialize();
|
||||||
|
|
||||||
|
_keyboard = CueSDK.KeyboardSDK;
|
||||||
|
switch (_keyboard.DeviceInfo.Model)
|
||||||
|
{
|
||||||
|
case "K95 RGB":
|
||||||
|
Height = 7;
|
||||||
|
Width = 25;
|
||||||
|
PreviewSettings = new PreviewSettings(676, 190, new Thickness(0, -15, 0, 0), Resources.k95);
|
||||||
|
break;
|
||||||
|
case "K70 RGB":
|
||||||
|
Height = 7;
|
||||||
|
Width = 21;
|
||||||
|
PreviewSettings = new PreviewSettings(676, 210, new Thickness(0, -25, 0, 0), Resources.k70);
|
||||||
|
break;
|
||||||
|
case "K65 RGB":
|
||||||
|
Height = 7;
|
||||||
|
Width = 18;
|
||||||
|
PreviewSettings = new PreviewSettings(610, 240, new Thickness(0, -30, 0, 0), Resources.k65);
|
||||||
|
break;
|
||||||
|
case "STRAFE RGB":
|
||||||
|
Height = 7;
|
||||||
|
Width = 22;
|
||||||
|
PreviewSettings = new PreviewSettings(665, 215, new Thickness(0, -5, 0, 0), Resources.strafe);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Slug = "corsair-" + _keyboard.DeviceInfo.Model.Replace(' ', '-').ToLower();
|
||||||
|
_keyboard.Brush = _keyboardBrush ?? (_keyboardBrush = new ImageBrush());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Disable()
|
||||||
|
{
|
||||||
|
if (CueSDK.IsInitialized)
|
||||||
|
CueSDK.Reinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap
|
||||||
|
/// size.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bitmap"></param>
|
||||||
|
public override void DrawBitmap(Bitmap bitmap)
|
||||||
|
{
|
||||||
|
var image = ImageUtilities.ResizeImage(bitmap, Width, Height);
|
||||||
|
|
||||||
|
// For STRAFE, stretch the image on row 2.
|
||||||
|
if (_keyboard.DeviceInfo.Model == "STRAFE RGB")
|
||||||
|
{
|
||||||
|
var strafeBitmap = new Bitmap(22, 8);
|
||||||
|
using (var g = Graphics.FromImage(strafeBitmap))
|
||||||
|
{
|
||||||
|
g.DrawImage(image, new Point(0, 0));
|
||||||
|
g.DrawImage(image, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7), GraphicsUnit.Pixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
image = strafeBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
_keyboardBrush.Image = image;
|
||||||
|
_keyboard.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Artemis/Artemis/DeviceProviders/DeviceProvider.cs
Normal file
40
Artemis/Artemis/DeviceProviders/DeviceProvider.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace Artemis.DeviceProviders
|
||||||
|
{
|
||||||
|
public abstract class DeviceProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates the device type
|
||||||
|
/// </summary>
|
||||||
|
public DeviceType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether or not the device can be updated
|
||||||
|
/// </summary>
|
||||||
|
public bool CanUse { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates a non-keyboard to take the colours of the provided brush
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="brush"></param>
|
||||||
|
public abstract void UpdateDevice(Brush brush);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to enable the device and updates CanUse accordingly
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool TryEnable();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disables the device
|
||||||
|
/// </summary>
|
||||||
|
public abstract void Disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DeviceType
|
||||||
|
{
|
||||||
|
Keyboard,
|
||||||
|
Mouse,
|
||||||
|
Headset
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,24 +1,28 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
using Size = System.Windows.Size;
|
using Size = System.Windows.Size;
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders
|
namespace Artemis.DeviceProviders
|
||||||
{
|
{
|
||||||
public abstract class KeyboardProvider
|
public abstract class KeyboardProvider : DeviceProvider
|
||||||
{
|
{
|
||||||
|
protected KeyboardProvider()
|
||||||
|
{
|
||||||
|
Type = DeviceType.Keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
public string Slug { get; set; }
|
||||||
public int Height { get; set; }
|
public int Height { get; set; }
|
||||||
public int Width { get; set; }
|
public int Width { get; set; }
|
||||||
public string CantEnableText { get; set; }
|
public string CantEnableText { get; set; }
|
||||||
|
|
||||||
public List<KeyboardRegion> KeyboardRegions { get; set; }
|
|
||||||
|
|
||||||
public PreviewSettings PreviewSettings { get; set; }
|
public PreviewSettings PreviewSettings { get; set; }
|
||||||
|
|
||||||
public abstract bool CanEnable();
|
public abstract bool CanEnable();
|
||||||
public abstract void Enable();
|
public abstract void Enable();
|
||||||
public abstract void Disable();
|
|
||||||
public abstract void DrawBitmap(Bitmap bitmap);
|
public abstract void DrawBitmap(Bitmap bitmap);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -34,6 +38,16 @@ namespace Artemis.KeyboardProviders
|
|||||||
public Bitmap KeyboardBitmap(int scale) => new Bitmap(Width*scale, Height*scale);
|
public Bitmap KeyboardBitmap(int scale) => new Bitmap(Width*scale, Height*scale);
|
||||||
|
|
||||||
public Rect KeyboardRectangle(int scale) => new Rect(new Size(Width*scale, Height*scale));
|
public Rect KeyboardRectangle(int scale) => new Rect(new Size(Width*scale, Height*scale));
|
||||||
|
|
||||||
|
public override void UpdateDevice(Brush brush)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("KeyboardProvider doesn't implement UpdateDevice, use DrawBitmap instead.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool TryEnable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("KeyboardProvider doesn't implement TryEnable, use CanEnable instead.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct PreviewSettings
|
public struct PreviewSettings
|
||||||
@ -1,38 +1,46 @@
|
|||||||
using System.Collections.Generic;
|
using System.Drawing;
|
||||||
using System.Drawing;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Artemis.KeyboardProviders.Logitech.Utilities;
|
using Artemis.DeviceProviders.Logitech.Utilities;
|
||||||
using Artemis.Properties;
|
using Artemis.Properties;
|
||||||
using Artemis.Utilities;
|
using Artemis.Utilities;
|
||||||
using Point = System.Drawing.Point;
|
using Artemis.Utilities.LogitechDll;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders.Logitech
|
namespace Artemis.DeviceProviders.Logitech
|
||||||
{
|
{
|
||||||
internal class Orion : KeyboardProvider
|
internal class Orion : KeyboardProvider
|
||||||
{
|
{
|
||||||
public Orion()
|
public Orion()
|
||||||
{
|
{
|
||||||
Name = "Logitech G910 RGB";
|
Name = "Logitech G910 RGB";
|
||||||
|
Slug = "logitech-g910";
|
||||||
CantEnableText = "Couldn't connect to your Logitech G910.\n" +
|
CantEnableText = "Couldn't connect to your Logitech G910.\n" +
|
||||||
"Please check your cables and updating the Logitech Gaming Software\n" +
|
"Please check your cables and updating the Logitech Gaming Software\n" +
|
||||||
"A minimum version of 8.81.15 is required.\n\n" +
|
"A minimum version of 8.81.15 is required.\n\n" +
|
||||||
"If needed, you can select a different keyboard in Artemis under settings.";
|
"If needed, you can select a different keyboard in Artemis under settings.";
|
||||||
Height = 6;
|
Height = 6;
|
||||||
Width = 21;
|
Width = 21;
|
||||||
PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.g910);
|
PreviewSettings = new PreviewSettings(540, 154, new Thickness(25, -80, 0, 0), Resources.g910);
|
||||||
KeyboardRegions = new List<KeyboardRegion>
|
|
||||||
{
|
|
||||||
new KeyboardRegion("TopRow", new Point(0, 0), new Point(18, 0)),
|
|
||||||
new KeyboardRegion("NumPad", new Point(17, 1), new Point(21, 6)),
|
|
||||||
new KeyboardRegion("QWER", new Point(2, 2), new Point(5, 2))
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanEnable()
|
public override bool CanEnable()
|
||||||
{
|
{
|
||||||
//if (DllManager.RestoreDll())
|
//Check to see if VC++ 2012 x64 is installed.
|
||||||
// RestoreDll();
|
|
||||||
|
if (Registry.LocalMachine.OpenSubKey(
|
||||||
|
@"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}") == null)
|
||||||
|
{
|
||||||
|
CantEnableText = "Couldn't connect to your Logitech G910.\n" +
|
||||||
|
"The Visual C 2012 Redistributable could not be found, which is required.\n" +
|
||||||
|
"Please download it by going to the following URL:\n\n" +
|
||||||
|
"https://www.microsoft.com/download/confirmation.aspx?id=30679";
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DllManager.RestoreDll())
|
||||||
|
RestoreDll();
|
||||||
int majorNum = 0, minorNum = 0, buildNum = 0;
|
int majorNum = 0, minorNum = 0, buildNum = 0;
|
||||||
|
|
||||||
LogitechGSDK.LogiLedInit();
|
LogitechGSDK.LogiLedInit();
|
||||||
@ -2,7 +2,7 @@
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Artemis.Utilities.Keyboard;
|
using Artemis.Utilities.Keyboard;
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders.Logitech.Utilities
|
namespace Artemis.DeviceProviders.Logitech.Utilities
|
||||||
{
|
{
|
||||||
public static class KeyMap
|
public static class KeyMap
|
||||||
{
|
{
|
||||||
@ -1,4 +1,4 @@
|
|||||||
namespace Artemis.KeyboardProviders.Logitech.Utilities
|
namespace Artemis.DeviceProviders.Logitech.Utilities
|
||||||
{
|
{
|
||||||
public enum KeyboardNames
|
public enum KeyboardNames
|
||||||
{
|
{
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders.Logitech.Utilities
|
namespace Artemis.DeviceProviders.Logitech.Utilities
|
||||||
{
|
{
|
||||||
public class LogitechGSDK
|
public class LogitechGSDK
|
||||||
{
|
{
|
||||||
@ -3,7 +3,7 @@ using System.Drawing.Drawing2D;
|
|||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders.Logitech.Utilities
|
namespace Artemis.DeviceProviders.Logitech.Utilities
|
||||||
{
|
{
|
||||||
public static class OrionUtilities
|
public static class OrionUtilities
|
||||||
{
|
{
|
||||||
@ -1,19 +1,26 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using Artemis.KeyboardProviders.Razer.Utilities;
|
using System.Windows;
|
||||||
|
using Artemis.DeviceProviders.Razer.Utilities;
|
||||||
|
using Artemis.Properties;
|
||||||
using Corale.Colore.Core;
|
using Corale.Colore.Core;
|
||||||
using Corale.Colore.Razer;
|
using Corale.Colore.Razer;
|
||||||
using Constants = Corale.Colore.Razer.Keyboard.Constants;
|
using Constants = Corale.Colore.Razer.Keyboard.Constants;
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders.Razer
|
namespace Artemis.DeviceProviders.Razer
|
||||||
{
|
{
|
||||||
public class BlackWidow : KeyboardProvider
|
public class BlackWidow : KeyboardProvider
|
||||||
{
|
{
|
||||||
public BlackWidow()
|
public BlackWidow()
|
||||||
{
|
{
|
||||||
Name = "Razer BlackWidow Chroma";
|
Name = "Razer BlackWidow Chroma";
|
||||||
|
Slug = "razer-blackwidow-chroma";
|
||||||
CantEnableText = "Couldn't connect to your Razer BlackWidow Chroma.\n" +
|
CantEnableText = "Couldn't connect to your Razer BlackWidow Chroma.\n" +
|
||||||
"Please check your cables and try updating Razer Synapse.\n\n" +
|
"Please check your cables and try updating Razer Synapse.\n\n" +
|
||||||
"If needed, you can select a different keyboard in Artemis under settings.";
|
"If needed, you can select a different keyboard in Artemis under settings.";
|
||||||
|
|
||||||
|
Height = Constants.MaxRows;
|
||||||
|
Width = Constants.MaxColumns;
|
||||||
|
PreviewSettings = new PreviewSettings(665, 175, new Thickness(0, -15, 0, 0), Resources.blackwidow);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanEnable()
|
public override bool CanEnable()
|
||||||
@ -30,12 +37,6 @@ namespace Artemis.KeyboardProviders.Razer
|
|||||||
public override void Enable()
|
public override void Enable()
|
||||||
{
|
{
|
||||||
Chroma.Instance.Initialize();
|
Chroma.Instance.Initialize();
|
||||||
Height = Constants.MaxRows;
|
|
||||||
Width = Constants.MaxColumns;
|
|
||||||
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 0), new Point(19, 0)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(20, 1), new Point(23, 6)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(2, 2), new Point(5, 2)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Disable()
|
public override void Disable()
|
||||||
@ -46,7 +47,6 @@ namespace Artemis.KeyboardProviders.Razer
|
|||||||
public override void DrawBitmap(Bitmap bitmap)
|
public override void DrawBitmap(Bitmap bitmap)
|
||||||
{
|
{
|
||||||
var razerArray = RazerUtilities.BitmapColorArray(bitmap, Height, Width);
|
var razerArray = RazerUtilities.BitmapColorArray(bitmap, Height, Width);
|
||||||
|
|
||||||
Chroma.Instance.Keyboard.SetCustom(razerArray);
|
Chroma.Instance.Keyboard.SetCustom(razerArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
using Artemis.Utilities;
|
using Artemis.Utilities;
|
||||||
using Corale.Colore.Razer.Keyboard.Effects;
|
using Corale.Colore.Razer.Keyboard.Effects;
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders.Razer.Utilities
|
namespace Artemis.DeviceProviders.Razer.Utilities
|
||||||
{
|
{
|
||||||
public static class RazerUtilities
|
public static class RazerUtilities
|
||||||
{
|
{
|
||||||
@ -1,12 +1,16 @@
|
|||||||
namespace Artemis.Events
|
using Artemis.DeviceProviders;
|
||||||
|
|
||||||
|
namespace Artemis.Events
|
||||||
{
|
{
|
||||||
public class ActiveKeyboardChanged
|
public class ActiveKeyboardChanged
|
||||||
{
|
{
|
||||||
public ActiveKeyboardChanged(string activeKeyboard)
|
public ActiveKeyboardChanged(KeyboardProvider oldKeyboard, KeyboardProvider newKeyboard)
|
||||||
{
|
{
|
||||||
ActiveKeyboard = activeKeyboard;
|
OldKeyboard = oldKeyboard;
|
||||||
|
NewKeyboard = newKeyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ActiveKeyboard { get; set; }
|
public KeyboardProvider OldKeyboard { get; set; }
|
||||||
|
public KeyboardProvider NewKeyboard { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
11
Artemis/Artemis/InjectionFactories/ILayerEditorVmFactory.cs
Normal file
11
Artemis/Artemis/InjectionFactories/ILayerEditorVmFactory.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
using Artemis.Models.Profiles;
|
||||||
|
using Artemis.ViewModels.Profiles;
|
||||||
|
|
||||||
|
namespace Artemis.InjectionFactories
|
||||||
|
{
|
||||||
|
public interface ILayerEditorVmFactory
|
||||||
|
{
|
||||||
|
LayerEditorViewModel CreateLayerEditorVm(IDataModel dataModel, LayerModel layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
using Artemis.Managers;
|
||||||
|
using Artemis.Models;
|
||||||
|
using Artemis.ViewModels.Profiles;
|
||||||
|
using Caliburn.Micro;
|
||||||
|
|
||||||
|
namespace Artemis.InjectionFactories
|
||||||
|
{
|
||||||
|
public interface IProfileEditorVmFactory
|
||||||
|
{
|
||||||
|
ProfileEditorViewModel CreateProfileEditorVm(IEventAggregator events, MainManager mainManager,
|
||||||
|
EffectModel gameModel, string lastProfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
59
Artemis/Artemis/InjectionModules/ArtemisModules.cs
Normal file
59
Artemis/Artemis/InjectionModules/ArtemisModules.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
using Artemis.DeviceProviders;
|
||||||
|
using Artemis.DeviceProviders.Corsair;
|
||||||
|
using Artemis.DeviceProviders.Logitech;
|
||||||
|
using Artemis.DeviceProviders.Razer;
|
||||||
|
using Artemis.Modules.Effects.AudioVisualizer;
|
||||||
|
using Artemis.Modules.Effects.TypeWave;
|
||||||
|
using Artemis.Modules.Effects.WindowsProfile;
|
||||||
|
using Artemis.Modules.Games.CounterStrike;
|
||||||
|
using Artemis.Modules.Games.Dota2;
|
||||||
|
using Artemis.Modules.Games.Overwatch;
|
||||||
|
using Artemis.Modules.Games.RocketLeague;
|
||||||
|
using Artemis.Modules.Games.TheDivision;
|
||||||
|
using Artemis.Modules.Games.Witcher3;
|
||||||
|
using Artemis.Modules.Overlays.VolumeDisplay;
|
||||||
|
using Artemis.ViewModels.Abstract;
|
||||||
|
using Ninject.Modules;
|
||||||
|
|
||||||
|
namespace Artemis.InjectionModules
|
||||||
|
{
|
||||||
|
public class ArtemisModules : NinjectModule
|
||||||
|
{
|
||||||
|
public override void Load()
|
||||||
|
{
|
||||||
|
#region Modules
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
Bind<EffectViewModel>().To<AudioVisualizerViewModel>().InSingletonScope();
|
||||||
|
Bind<EffectViewModel>().To<TypeWaveViewModel>().InSingletonScope();
|
||||||
|
Bind<EffectViewModel>().To<WindowsProfileViewModel>().InSingletonScope();
|
||||||
|
//Bind<EffectViewModel>().To<AmbientLightningEffectViewModel>().InSingletonScope();
|
||||||
|
|
||||||
|
// Games
|
||||||
|
Bind<GameViewModel>().To<CounterStrikeViewModel>().InSingletonScope();
|
||||||
|
Bind<GameViewModel>().To<Dota2ViewModel>().InSingletonScope();
|
||||||
|
Bind<GameViewModel>().To<RocketLeagueViewModel>().InSingletonScope();
|
||||||
|
Bind<GameViewModel>().To<TheDivisionViewModel>().InSingletonScope();
|
||||||
|
Bind<GameViewModel>().To<Witcher3ViewModel>().InSingletonScope();
|
||||||
|
Bind<GameViewModel>().To<OverwatchViewModel>().InSingletonScope();
|
||||||
|
|
||||||
|
// Overlays
|
||||||
|
Bind<OverlayViewModel>().To<VolumeDisplayViewModel>().InSingletonScope();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Devices
|
||||||
|
|
||||||
|
// Keyboards
|
||||||
|
Bind<DeviceProvider>().To<CorsairRGB>().InSingletonScope();
|
||||||
|
Bind<DeviceProvider>().To<Orion>().InSingletonScope();
|
||||||
|
Bind<DeviceProvider>().To<BlackWidow>().InSingletonScope();
|
||||||
|
// Mice
|
||||||
|
Bind<DeviceProvider>().To<CorsairMice>().InSingletonScope();
|
||||||
|
// Headsets
|
||||||
|
Bind<DeviceProvider>().To<CorsairHeadsets>().InSingletonScope();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
Artemis/Artemis/InjectionModules/BaseModules.cs
Normal file
35
Artemis/Artemis/InjectionModules/BaseModules.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using Artemis.InjectionFactories;
|
||||||
|
using Artemis.Modules.Effects.ProfilePreview;
|
||||||
|
using Artemis.Services;
|
||||||
|
using Artemis.ViewModels;
|
||||||
|
using Artemis.ViewModels.Abstract;
|
||||||
|
using Artemis.ViewModels.Profiles;
|
||||||
|
using Caliburn.Micro;
|
||||||
|
using Ninject.Extensions.Factory;
|
||||||
|
using Ninject.Modules;
|
||||||
|
|
||||||
|
namespace Artemis.InjectionModules
|
||||||
|
{
|
||||||
|
internal class BaseModules : NinjectModule
|
||||||
|
{
|
||||||
|
public override void Load()
|
||||||
|
{
|
||||||
|
// ViewModels
|
||||||
|
Bind<IScreen>().To<ShellViewModel>().InSingletonScope();
|
||||||
|
Bind<IProfileEditorVmFactory>().ToFactory();
|
||||||
|
Bind<ILayerEditorVmFactory>().ToFactory();
|
||||||
|
Bind<ProfileViewModel>().ToSelf();
|
||||||
|
|
||||||
|
Bind<BaseViewModel>().To<WelcomeViewModel>().InSingletonScope();
|
||||||
|
Bind<BaseViewModel>().To<EffectsViewModel>().InSingletonScope();
|
||||||
|
Bind<BaseViewModel>().To<GamesViewModel>().InSingletonScope();
|
||||||
|
Bind<BaseViewModel>().To<OverlaysViewModel>().InSingletonScope();
|
||||||
|
|
||||||
|
// Models
|
||||||
|
Bind<ProfilePreviewModel>().ToSelf().InSingletonScope();
|
||||||
|
|
||||||
|
// Services
|
||||||
|
Bind<MetroDialogService>().ToSelf().InSingletonScope();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
Artemis/Artemis/InjectionModules/ManagerModules.cs
Normal file
17
Artemis/Artemis/InjectionModules/ManagerModules.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Artemis.Managers;
|
||||||
|
using Ninject.Modules;
|
||||||
|
|
||||||
|
namespace Artemis.InjectionModules
|
||||||
|
{
|
||||||
|
internal class ManagerModules : NinjectModule
|
||||||
|
{
|
||||||
|
public override void Load()
|
||||||
|
{
|
||||||
|
Bind<MainManager>().ToSelf().InSingletonScope();
|
||||||
|
Bind<LoopManager>().ToSelf().InSingletonScope();
|
||||||
|
Bind<DeviceManager>().ToSelf().InSingletonScope();
|
||||||
|
Bind<EffectManager>().ToSelf().InSingletonScope();
|
||||||
|
Bind<ProfileManager>().ToSelf().InSingletonScope();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Interactivity;
|
using System.Windows.Interactivity;
|
||||||
@ -6,21 +7,19 @@ using System.Windows.Interactivity;
|
|||||||
namespace Artemis.ItemBehaviours
|
namespace Artemis.ItemBehaviours
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Steve Greatrex - http://stackoverflow.com/a/5118406/5015269
|
/// Chaitanya Kadamati - http://stackoverflow.com/a/33233162/5015269
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BindableSelectedItemBehavior : Behavior<TreeView>
|
public class BindableSelectedItemBehavior : Behavior<TreeView>
|
||||||
{
|
{
|
||||||
protected override void OnAttached()
|
protected override void OnAttached()
|
||||||
{
|
{
|
||||||
base.OnAttached();
|
base.OnAttached();
|
||||||
|
|
||||||
AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
|
AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDetaching()
|
protected override void OnDetaching()
|
||||||
{
|
{
|
||||||
base.OnDetaching();
|
base.OnDetaching();
|
||||||
|
|
||||||
if (AssociatedObject != null)
|
if (AssociatedObject != null)
|
||||||
AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
|
AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
|
||||||
}
|
}
|
||||||
@ -38,49 +37,59 @@ namespace Artemis.ItemBehaviours
|
|||||||
set { SetValue(SelectedItemProperty, value); }
|
set { SetValue(SelectedItemProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem",
|
public static readonly DependencyProperty SelectedItemProperty =
|
||||||
typeof (object), typeof (BindableSelectedItemBehavior), new UIPropertyMetadata(null, OnSelectedItemChanged));
|
DependencyProperty.Register("SelectedItem", typeof(object), typeof(BindableSelectedItemBehavior),
|
||||||
|
new UIPropertyMetadata(null, OnSelectedItemChanged));
|
||||||
|
|
||||||
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var item = ((BindableSelectedItemBehavior) sender).AssociatedObject
|
var behavior = sender as BindableSelectedItemBehavior;
|
||||||
.ItemContainerGenerator.ContainerFromItem(e.NewValue) as TreeViewItem;
|
var tree = behavior?.AssociatedObject;
|
||||||
if (item != null)
|
if (tree == null)
|
||||||
item.SetValue(TreeViewItem.IsSelectedProperty, true);
|
|
||||||
else
|
|
||||||
ClearTreeViewSelection(((BindableSelectedItemBehavior) sender).AssociatedObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clears a TreeView's selected item recursively
|
|
||||||
/// Tom Wright - http://stackoverflow.com/a/1406116/5015269
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tv"></param>
|
|
||||||
public static void ClearTreeViewSelection(TreeView tv)
|
|
||||||
{
|
|
||||||
if (tv != null)
|
|
||||||
ClearTreeViewItemsControlSelection(tv.Items, tv.ItemContainerGenerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clears a TreeView's selected item recursively
|
|
||||||
/// Tom Wright - http://stackoverflow.com/a/1406116/5015269
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ic"></param>
|
|
||||||
/// <param name="icg"></param>
|
|
||||||
private static void ClearTreeViewItemsControlSelection(ICollection ic, ItemContainerGenerator icg)
|
|
||||||
{
|
|
||||||
if ((ic == null) || (icg == null))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (var i = 0; i < ic.Count; i++)
|
if (e.NewValue == null)
|
||||||
{
|
{
|
||||||
var tvi = icg.ContainerFromIndex(i) as TreeViewItem;
|
foreach (var item in tree.Items.OfType<TreeViewItem>())
|
||||||
if (tvi == null)
|
item.SetValue(TreeViewItem.IsSelectedProperty, false);
|
||||||
continue;
|
|
||||||
ClearTreeViewItemsControlSelection(tvi.Items, tvi.ItemContainerGenerator);
|
|
||||||
tvi.IsSelected = false;
|
|
||||||
}
|
}
|
||||||
|
var treeViewItem = e.NewValue as TreeViewItem;
|
||||||
|
if (treeViewItem != null)
|
||||||
|
treeViewItem.SetValue(TreeViewItem.IsSelectedProperty, true);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var itemsHostProperty = tree.GetType()
|
||||||
|
.GetProperty("ItemsHost", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
var itemsHost = itemsHostProperty?.GetValue(tree, null) as Panel;
|
||||||
|
if (itemsHost == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var item in itemsHost.Children.OfType<TreeViewItem>())
|
||||||
|
{
|
||||||
|
if (WalkTreeViewItem(item, e.NewValue))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool WalkTreeViewItem(TreeViewItem treeViewItem, object selectedValue)
|
||||||
|
{
|
||||||
|
if (treeViewItem.DataContext == selectedValue)
|
||||||
|
{
|
||||||
|
treeViewItem.SetValue(TreeViewItem.IsSelectedProperty, true);
|
||||||
|
treeViewItem.Focus();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var itemsHostProperty = treeViewItem.GetType()
|
||||||
|
.GetProperty("ItemsHost", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
var itemsHost = itemsHostProperty?.GetValue(treeViewItem, null) as Panel;
|
||||||
|
if (itemsHost == null) return false;
|
||||||
|
foreach (var item in itemsHost.Children.OfType<TreeViewItem>())
|
||||||
|
{
|
||||||
|
if (WalkTreeViewItem(item, selectedValue))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -1,140 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Windows;
|
|
||||||
using Artemis.Properties;
|
|
||||||
using Artemis.Utilities;
|
|
||||||
using CUE.NET;
|
|
||||||
using CUE.NET.Brushes;
|
|
||||||
using CUE.NET.Devices.Generic.Enums;
|
|
||||||
using CUE.NET.Devices.Keyboard;
|
|
||||||
using CUE.NET.Exceptions;
|
|
||||||
using Point = System.Drawing.Point;
|
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders.Corsair
|
|
||||||
{
|
|
||||||
internal class CorsairRGB : KeyboardProvider
|
|
||||||
{
|
|
||||||
private CorsairKeyboard _keyboard;
|
|
||||||
|
|
||||||
public CorsairRGB()
|
|
||||||
{
|
|
||||||
Name = "Corsair RGB Keyboards";
|
|
||||||
CantEnableText = "Couldn't connect to your Corsair keyboard.\n" +
|
|
||||||
"Please check your cables and/or drivers (could be outdated) and that Corsair Utility Engine is running.\n\n" +
|
|
||||||
"If needed, you can select a different keyboard in Artemis under settings.";
|
|
||||||
KeyboardRegions = new List<KeyboardRegion>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanEnable()
|
|
||||||
{
|
|
||||||
// Try for about 10 seconds, in case CUE isn't started yet
|
|
||||||
var tries = 0;
|
|
||||||
while (tries < 9)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CueSDK.Initialize();
|
|
||||||
}
|
|
||||||
catch (CUEException e)
|
|
||||||
{
|
|
||||||
if (e.Error == CorsairError.ServerNotFound)
|
|
||||||
{
|
|
||||||
tries++;
|
|
||||||
Thread.Sleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (WrapperException)
|
|
||||||
{
|
|
||||||
CueSDK.Reinitialize();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enables the SDK and sets updatemode to manual as well as the color of the background to black.
|
|
||||||
/// </summary>
|
|
||||||
public override void Enable()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CueSDK.Initialize();
|
|
||||||
}
|
|
||||||
catch (WrapperException)
|
|
||||||
{
|
|
||||||
/*CUE is already initialized*/
|
|
||||||
}
|
|
||||||
_keyboard = CueSDK.KeyboardSDK;
|
|
||||||
switch (_keyboard.DeviceInfo.Model)
|
|
||||||
{
|
|
||||||
case "K95 RGB":
|
|
||||||
Height = 7;
|
|
||||||
Width = 25;
|
|
||||||
PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.k95);
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(20, 1)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(21, 2), new Point(25, 7)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(5, 3), new Point(8, 3)));
|
|
||||||
break;
|
|
||||||
case "K70 RGB":
|
|
||||||
Height = 7;
|
|
||||||
Width = 21;
|
|
||||||
PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.k70);
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(18, 1)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(17, 2), new Point(21, 7)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(2, 3), new Point(5, 3)));
|
|
||||||
break;
|
|
||||||
case "K65 RGB":
|
|
||||||
Height = 7;
|
|
||||||
Width = 18;
|
|
||||||
PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.k65);
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(18, 1)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(17, 2), new Point(20, 7)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(2, 3), new Point(5, 3)));
|
|
||||||
break;
|
|
||||||
case "STRAFE RGB":
|
|
||||||
Height = 6;
|
|
||||||
Width = 22;
|
|
||||||
PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.strafe);
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(18, 1)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(18, 2), new Point(22, 7)));
|
|
||||||
KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(1, 3), new Point(4, 3)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Disable()
|
|
||||||
{
|
|
||||||
CueSDK.Reinitialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap
|
|
||||||
/// size.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bitmap"></param>
|
|
||||||
public override void DrawBitmap(Bitmap bitmap)
|
|
||||||
{
|
|
||||||
var fixedBmp = new Bitmap(bitmap.Width, bitmap.Height);
|
|
||||||
using (var g = Graphics.FromImage(fixedBmp))
|
|
||||||
{
|
|
||||||
g.Clear(Color.Black);
|
|
||||||
g.DrawImage(bitmap, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
var fixedImage = ImageUtilities.ResizeImage(fixedBmp, Width, Height);
|
|
||||||
var brush = new ImageBrush
|
|
||||||
{
|
|
||||||
Image = fixedImage
|
|
||||||
};
|
|
||||||
|
|
||||||
_keyboard.Brush = brush;
|
|
||||||
_keyboard.Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders
|
|
||||||
{
|
|
||||||
public class KeyboardRegion
|
|
||||||
{
|
|
||||||
public KeyboardRegion(string regionName, Point topLeft, Point bottomRight)
|
|
||||||
{
|
|
||||||
RegionName = regionName;
|
|
||||||
TopLeft = topLeft;
|
|
||||||
BottomRight = bottomRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string RegionName { get; set; }
|
|
||||||
public Point TopLeft { get; set; }
|
|
||||||
public Point BottomRight { get; set; }
|
|
||||||
|
|
||||||
public Rectangle GetRectangle()
|
|
||||||
=> new Rectangle(TopLeft.X, TopLeft.Y, BottomRight.X - TopLeft.X, BottomRight.Y - TopLeft.Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.KeyboardProviders.Corsair;
|
|
||||||
using Artemis.KeyboardProviders.Logitech;
|
|
||||||
using Artemis.KeyboardProviders.Razer;
|
|
||||||
|
|
||||||
namespace Artemis.KeyboardProviders
|
|
||||||
{
|
|
||||||
public static class ProviderHelper
|
|
||||||
{
|
|
||||||
public static List<KeyboardProvider> GetKeyboardProviders()
|
|
||||||
{
|
|
||||||
return new List<KeyboardProvider>
|
|
||||||
{
|
|
||||||
new CorsairRGB(),
|
|
||||||
new Orion(),
|
|
||||||
new BlackWidow()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
160
Artemis/Artemis/Managers/DeviceManager.cs
Normal file
160
Artemis/Artemis/Managers/DeviceManager.cs
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Artemis.DeviceProviders;
|
||||||
|
using Artemis.Events;
|
||||||
|
using Artemis.Services;
|
||||||
|
using Artemis.Settings;
|
||||||
|
using Caliburn.Micro;
|
||||||
|
using Ninject;
|
||||||
|
using Ninject.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Artemis.Managers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the keyboard providers
|
||||||
|
/// </summary>
|
||||||
|
public class DeviceManager
|
||||||
|
{
|
||||||
|
private readonly IEventAggregator _events;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public DeviceManager(IEventAggregator events, ILogger logger, List<DeviceProvider> deviceProviders)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_logger.Info("Intializing DeviceManager");
|
||||||
|
|
||||||
|
_events = events;
|
||||||
|
|
||||||
|
KeyboardProviders = deviceProviders.Where(d => d.Type == DeviceType.Keyboard)
|
||||||
|
.Cast<KeyboardProvider>().ToList();
|
||||||
|
MiceProviders = deviceProviders.Where(d => d.Type == DeviceType.Mouse).ToList();
|
||||||
|
HeadsetProviders = deviceProviders.Where(d => d.Type == DeviceType.Headset).ToList();
|
||||||
|
|
||||||
|
_logger.Info("Intialized DeviceManager");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DeviceProvider> HeadsetProviders { get; set; }
|
||||||
|
|
||||||
|
public List<DeviceProvider> MiceProviders { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
public MetroDialogService DialogService { get; set; }
|
||||||
|
|
||||||
|
public List<KeyboardProvider> KeyboardProviders { get; set; }
|
||||||
|
|
||||||
|
public KeyboardProvider ActiveKeyboard { get; set; }
|
||||||
|
|
||||||
|
public bool ChangingKeyboard { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the last keyboard according to the settings file
|
||||||
|
/// </summary>
|
||||||
|
public void EnableLastKeyboard()
|
||||||
|
{
|
||||||
|
_logger.Debug("Getting last keyboard: {0}", General.Default.LastKeyboard);
|
||||||
|
if (string.IsNullOrEmpty(General.Default.LastKeyboard))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var keyboard = KeyboardProviders.FirstOrDefault(k => k.Name == General.Default.LastKeyboard);
|
||||||
|
EnableKeyboard(keyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the given keyboard
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="keyboardProvider"></param>
|
||||||
|
public void EnableKeyboard(KeyboardProvider keyboardProvider)
|
||||||
|
{
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
ChangingKeyboard = true;
|
||||||
|
|
||||||
|
if (keyboardProvider == null)
|
||||||
|
throw new ArgumentNullException(nameof(keyboardProvider));
|
||||||
|
|
||||||
|
if (ActiveKeyboard?.Name == keyboardProvider.Name)
|
||||||
|
{
|
||||||
|
ChangingKeyboard = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the old keyboard so it can be used in the event we're raising later
|
||||||
|
var oldKeyboard = ActiveKeyboard;
|
||||||
|
|
||||||
|
var wasNull = false;
|
||||||
|
if (ActiveKeyboard == null)
|
||||||
|
{
|
||||||
|
wasNull = true;
|
||||||
|
ActiveKeyboard = keyboardProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("Enabling keyboard: {0}", keyboardProvider.Name);
|
||||||
|
|
||||||
|
if (!wasNull)
|
||||||
|
ReleaseActiveKeyboard();
|
||||||
|
|
||||||
|
// Disable everything if there's no active keyboard found
|
||||||
|
if (!keyboardProvider.CanEnable())
|
||||||
|
{
|
||||||
|
DialogService.ShowErrorMessageBox(keyboardProvider.CantEnableText);
|
||||||
|
ActiveKeyboard = null;
|
||||||
|
General.Default.LastKeyboard = null;
|
||||||
|
General.Default.Save();
|
||||||
|
_logger.Warn("Failed enabling keyboard: {0}", keyboardProvider.Name);
|
||||||
|
ChangingKeyboard = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActiveKeyboard = keyboardProvider;
|
||||||
|
ActiveKeyboard.Enable();
|
||||||
|
|
||||||
|
General.Default.LastKeyboard = ActiveKeyboard.Name;
|
||||||
|
General.Default.Save();
|
||||||
|
|
||||||
|
EnableUsableDevices();
|
||||||
|
|
||||||
|
ChangingKeyboard = false;
|
||||||
|
_events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, ActiveKeyboard));
|
||||||
|
_logger.Debug("Enabled keyboard: {0}", keyboardProvider.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnableUsableDevices()
|
||||||
|
{
|
||||||
|
foreach (var mouseProvider in MiceProviders)
|
||||||
|
mouseProvider.TryEnable();
|
||||||
|
foreach (var headsetProvider in HeadsetProviders)
|
||||||
|
headsetProvider.TryEnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases the active keyboard
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="save">Whether to save the LastKeyboard (making it null)</param>
|
||||||
|
public void ReleaseActiveKeyboard(bool save = false)
|
||||||
|
{
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
if (ActiveKeyboard == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Store the old keyboard so it can be used in the event we're raising later
|
||||||
|
var oldKeyboard = ActiveKeyboard;
|
||||||
|
|
||||||
|
var releaseName = ActiveKeyboard.Name;
|
||||||
|
ActiveKeyboard.Disable();
|
||||||
|
ActiveKeyboard = null;
|
||||||
|
|
||||||
|
if (save)
|
||||||
|
{
|
||||||
|
General.Default.LastKeyboard = null;
|
||||||
|
General.Default.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
_events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, null));
|
||||||
|
_logger.Debug("Released keyboard: {0}", releaseName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,41 +1,38 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
|
||||||
using Artemis.Events;
|
using Artemis.Events;
|
||||||
using Artemis.Models;
|
using Artemis.Models;
|
||||||
using Artemis.Modules.Effects.ProfilePreview;
|
using Artemis.Modules.Effects.ProfilePreview;
|
||||||
using Artemis.Settings;
|
using Artemis.Settings;
|
||||||
using Caliburn.Micro;
|
using Caliburn.Micro;
|
||||||
using NLog;
|
using Ninject.Extensions.Logging;
|
||||||
using LogManager = NLog.LogManager;
|
|
||||||
|
|
||||||
namespace Artemis.Managers
|
namespace Artemis.Managers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the effects
|
||||||
|
/// </summary>
|
||||||
public class EffectManager
|
public class EffectManager
|
||||||
{
|
{
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private readonly DeviceManager _deviceManager;
|
||||||
private readonly IEventAggregator _events;
|
private readonly IEventAggregator _events;
|
||||||
private readonly MainManager _mainManager;
|
private readonly ILogger _logger;
|
||||||
private EffectModel _activeEffect;
|
private EffectModel _activeEffect;
|
||||||
private bool _clearing;
|
|
||||||
|
|
||||||
public EffectManager(MainManager mainManager, IEventAggregator events)
|
public EffectManager(ILogger logger, IEventAggregator events, DeviceManager deviceManager)
|
||||||
{
|
{
|
||||||
Logger.Info("Intializing EffectManager");
|
_logger = logger;
|
||||||
_mainManager = mainManager;
|
_logger.Info("Intializing EffectManager");
|
||||||
|
|
||||||
_events = events;
|
_events = events;
|
||||||
|
_deviceManager = deviceManager;
|
||||||
|
|
||||||
EffectModels = new List<EffectModel>();
|
EffectModels = new List<EffectModel>();
|
||||||
ProfilePreviewModel = new ProfilePreviewModel(_mainManager);
|
|
||||||
Logger.Info("Intialized EffectManager");
|
_logger.Info("Intialized EffectManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
public EffectModel PauseEffect { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Used by ViewModels to show a preview of the profile currently being edited
|
|
||||||
/// </summary>
|
|
||||||
public ProfilePreviewModel ProfilePreviewModel { get; set; }
|
public ProfilePreviewModel ProfilePreviewModel { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -75,134 +72,101 @@ namespace Artemis.Managers
|
|||||||
/// <returns>Whether enabling was successful or not.</returns>
|
/// <returns>Whether enabling was successful or not.</returns>
|
||||||
public EffectModel GetLastEffect()
|
public EffectModel GetLastEffect()
|
||||||
{
|
{
|
||||||
Logger.Debug("Getting last effect: {0}", General.Default.LastEffect);
|
_logger.Debug("Getting last effect: {0}", General.Default.LastEffect);
|
||||||
if (General.Default.LastEffect == null)
|
return General.Default.LastEffect == null
|
||||||
return null;
|
? null
|
||||||
|
: EffectModels.FirstOrDefault(e => e.Name == General.Default.LastEffect);
|
||||||
var effect = EffectModels.FirstOrDefault(e => e.Name == General.Default.LastEffect);
|
|
||||||
|
|
||||||
// Fall back to the first effect found, in case settings are messed up
|
|
||||||
return effect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disables the current effect and changes it to the provided effect.
|
/// Disables the current effect and changes it to the provided effect.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="effectModel"></param>
|
/// <param name="effectModel">The effect to activate</param>
|
||||||
/// <param name="force">Changes the effect, even if it's already running (effectively restarting it)</param>
|
/// <param name="loopManager">Optionally pass the LoopManager to automatically start it, if it's not running.</param>
|
||||||
public void ChangeEffect(EffectModel effectModel, bool force = false)
|
public void ChangeEffect(EffectModel effectModel, LoopManager loopManager = null)
|
||||||
{
|
{
|
||||||
|
if (effectModel == null)
|
||||||
|
throw new ArgumentNullException(nameof(effectModel));
|
||||||
if (effectModel is OverlayModel)
|
if (effectModel is OverlayModel)
|
||||||
throw new ArgumentException("Can't set an Overlay effect as the active effect");
|
throw new ArgumentException("Can't set an Overlay effect as the active effect");
|
||||||
|
|
||||||
|
if (_deviceManager.ActiveKeyboard == null)
|
||||||
|
_deviceManager.EnableLastKeyboard();
|
||||||
|
// If still null, no last keyboard, so stop.
|
||||||
|
if (_deviceManager.ActiveKeyboard == null)
|
||||||
|
{
|
||||||
|
_logger.Debug("Cancelling effect change, no LastKeyboard");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Game models are only used if they are enabled
|
// Game models are only used if they are enabled
|
||||||
var gameModel = effectModel as GameModel;
|
var gameModel = effectModel as GameModel;
|
||||||
if (gameModel != null)
|
if (gameModel != null)
|
||||||
if (!gameModel.Enabled)
|
if (!gameModel.Enabled)
|
||||||
|
{
|
||||||
|
_logger.Debug("Cancelling effect change, provided game not enabled");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ActiveEffect != null)
|
|
||||||
if (effectModel.Name == ActiveEffect.Name && !force)
|
var wasNull = false;
|
||||||
|
if (ActiveEffect == null)
|
||||||
|
{
|
||||||
|
wasNull = true;
|
||||||
|
ActiveEffect = effectModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (ActiveEffect)
|
||||||
|
{
|
||||||
|
if (!wasNull)
|
||||||
|
ActiveEffect.Dispose();
|
||||||
|
|
||||||
|
ActiveEffect = effectModel;
|
||||||
|
ActiveEffect.Enable();
|
||||||
|
if (!ActiveEffect.Initialized)
|
||||||
|
{
|
||||||
|
_logger.Debug("Cancelling effect change, couldn't initialize the effect ({0})", effectModel.Name);
|
||||||
|
ActiveEffect = null;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
Logger.Debug("Changing effect to: {0}, force: {1}", effectModel?.Name, force);
|
|
||||||
// If the main manager is running, pause it and safely change the effect
|
|
||||||
if (_mainManager.Running)
|
|
||||||
{
|
|
||||||
ChangeEffectWithPause(effectModel);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's not running start it, and let the next recursion handle changing the effect
|
if (loopManager != null && !loopManager.Running)
|
||||||
_mainManager.Start(effectModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ChangeEffectWithPause(EffectModel effectModel)
|
|
||||||
{
|
|
||||||
var tryCount = 0;
|
|
||||||
while (PauseEffect != null)
|
|
||||||
{
|
{
|
||||||
Thread.Sleep(500);
|
_logger.Debug("Starting LoopManager for effect change");
|
||||||
tryCount++;
|
loopManager.Start();
|
||||||
if (tryCount > 20)
|
|
||||||
throw new Exception("Couldn't change effect before the time expired");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't interrupt an ongoing effect change
|
_logger.Debug("Changed active effect to: {0}", effectModel.Name);
|
||||||
if (PauseEffect != null)
|
|
||||||
{
|
|
||||||
Logger.Debug("Change effect with pause cancelled");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Logger.Debug("Changing effect with pause: {0}", effectModel?.Name);
|
|
||||||
|
|
||||||
PauseEffect = effectModel;
|
|
||||||
_mainManager.Pause();
|
|
||||||
_mainManager.PauseCallback += ChangeEffectPauseCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ChangeEffectPauseCallback()
|
|
||||||
{
|
|
||||||
_mainManager.PauseCallback -= ChangeEffectPauseCallback;
|
|
||||||
|
|
||||||
// Change effect logic
|
|
||||||
ActiveEffect?.Dispose();
|
|
||||||
|
|
||||||
ActiveEffect = PauseEffect;
|
|
||||||
ActiveEffect.Enable();
|
|
||||||
|
|
||||||
_mainManager.Unpause();
|
|
||||||
PauseEffect = null;
|
|
||||||
|
|
||||||
Logger.Debug("Finishing change effect with pause");
|
|
||||||
if (ActiveEffect is GameModel || ActiveEffect is ProfilePreviewModel)
|
if (ActiveEffect is GameModel || ActiveEffect is ProfilePreviewModel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Non-game effects are stored as the new LastEffect.
|
// Non-game effects are stored as the new LastEffect.
|
||||||
General.Default.LastEffect = ActiveEffect.Name;
|
General.Default.LastEffect = ActiveEffect?.Name;
|
||||||
General.Default.Save();
|
General.Default.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears the current effect
|
/// Clears the current effect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ClearEffect()
|
public void ClearEffect()
|
||||||
{
|
{
|
||||||
if (_clearing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Don't mess with the ActiveEffect if in the process of changing the effect.
|
|
||||||
if (PauseEffect != null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ActiveEffect == null)
|
if (ActiveEffect == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_clearing = true;
|
lock (ActiveEffect)
|
||||||
Logger.Debug("Clearing active effect");
|
|
||||||
_mainManager.Pause();
|
|
||||||
_mainManager.PauseCallback += ClearEffectPauseCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClearEffectPauseCallback()
|
|
||||||
{
|
|
||||||
_mainManager.PauseCallback -= ClearEffectPauseCallback;
|
|
||||||
if (PauseEffect != null)
|
|
||||||
{
|
{
|
||||||
Logger.Debug("Cancelling clearing effect");
|
ActiveEffect.Dispose();
|
||||||
return;
|
ActiveEffect = null;
|
||||||
|
|
||||||
|
General.Default.LastEffect = null;
|
||||||
|
General.Default.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
ActiveEffect.Dispose();
|
|
||||||
ActiveEffect = null;
|
|
||||||
|
|
||||||
General.Default.LastEffect = null;
|
_logger.Debug("Cleared active effect");
|
||||||
General.Default.Save();
|
|
||||||
|
|
||||||
_clearing = false;
|
|
||||||
|
|
||||||
Logger.Debug("Finishing clearing active effect");
|
|
||||||
_mainManager.Unpause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -211,7 +175,7 @@ namespace Artemis.Managers
|
|||||||
/// <param name="activeEffect"></param>
|
/// <param name="activeEffect"></param>
|
||||||
public void DisableGame(EffectModel activeEffect)
|
public void DisableGame(EffectModel activeEffect)
|
||||||
{
|
{
|
||||||
Logger.Debug("Disabling game: {0}", activeEffect?.Name);
|
_logger.Debug("Disabling game: {0}", activeEffect?.Name);
|
||||||
if (GetLastEffect() == null)
|
if (GetLastEffect() == null)
|
||||||
ClearEffect();
|
ClearEffect();
|
||||||
else
|
else
|
||||||
|
|||||||
@ -1,122 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Artemis.Events;
|
|
||||||
using Artemis.KeyboardProviders;
|
|
||||||
using Artemis.Settings;
|
|
||||||
using Caliburn.Micro;
|
|
||||||
using NLog;
|
|
||||||
using LogManager = NLog.LogManager;
|
|
||||||
|
|
||||||
namespace Artemis.Managers
|
|
||||||
{
|
|
||||||
public class KeyboardManager
|
|
||||||
{
|
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
|
||||||
private readonly IEventAggregator _events;
|
|
||||||
private readonly MainManager _mainManager;
|
|
||||||
private KeyboardProvider _activeKeyboard;
|
|
||||||
|
|
||||||
public KeyboardManager(MainManager mainManager, IEventAggregator events)
|
|
||||||
{
|
|
||||||
Logger.Info("Intializing KeyboardManager");
|
|
||||||
_mainManager = mainManager;
|
|
||||||
_events = events;
|
|
||||||
KeyboardProviders = ProviderHelper.GetKeyboardProviders();
|
|
||||||
Logger.Info("Intialized KeyboardManager");
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<KeyboardProvider> KeyboardProviders { get; set; }
|
|
||||||
|
|
||||||
public KeyboardProvider ActiveKeyboard
|
|
||||||
{
|
|
||||||
get { return _activeKeyboard; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_activeKeyboard = value;
|
|
||||||
// Let the ViewModels know
|
|
||||||
_events.PublishOnUIThread(new ActiveKeyboardChanged(value?.Name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanDisable { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enables the last keyboard according to the settings file
|
|
||||||
/// </summary>
|
|
||||||
public void EnableLastKeyboard()
|
|
||||||
{
|
|
||||||
Logger.Debug("Enabling last keyboard: {0}", General.Default.LastKeyboard);
|
|
||||||
if (General.Default.LastKeyboard == null)
|
|
||||||
return;
|
|
||||||
if (General.Default.LastKeyboard == "")
|
|
||||||
return;
|
|
||||||
|
|
||||||
var keyboard = KeyboardProviders.FirstOrDefault(k => k.Name == General.Default.LastKeyboard);
|
|
||||||
EnableKeyboard(keyboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enables the given keyboard
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="keyboardProvider"></param>
|
|
||||||
public void EnableKeyboard(KeyboardProvider keyboardProvider)
|
|
||||||
{
|
|
||||||
Logger.Debug("Enabling keyboard: {0}", keyboardProvider?.Name);
|
|
||||||
ReleaseActiveKeyboard();
|
|
||||||
|
|
||||||
if (keyboardProvider == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ActiveKeyboard != null)
|
|
||||||
if (keyboardProvider.Name == ActiveKeyboard.Name)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Disable everything if there's no active keyboard found
|
|
||||||
if (!keyboardProvider.CanEnable())
|
|
||||||
{
|
|
||||||
_mainManager.DialogService.ShowErrorMessageBox(keyboardProvider.CantEnableText);
|
|
||||||
General.Default.LastKeyboard = null;
|
|
||||||
General.Default.Save();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CanDisable = false;
|
|
||||||
ActiveKeyboard = keyboardProvider;
|
|
||||||
keyboardProvider.Enable();
|
|
||||||
|
|
||||||
General.Default.LastKeyboard = ActiveKeyboard.Name;
|
|
||||||
General.Default.Save();
|
|
||||||
CanDisable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Releases the active keyboard, if CanDisable is true
|
|
||||||
/// </summary>
|
|
||||||
public void ReleaseActiveKeyboard()
|
|
||||||
{
|
|
||||||
if (ActiveKeyboard == null || !CanDisable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ActiveKeyboard.Disable();
|
|
||||||
Logger.Debug("Released keyboard: {0}", ActiveKeyboard?.Name);
|
|
||||||
ActiveKeyboard = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Changes the active keyboard
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="keyboardProvider"></param>
|
|
||||||
public void ChangeKeyboard(KeyboardProvider keyboardProvider)
|
|
||||||
{
|
|
||||||
Logger.Debug("Changing active keyboard");
|
|
||||||
if (keyboardProvider == ActiveKeyboard)
|
|
||||||
return;
|
|
||||||
|
|
||||||
General.Default.LastKeyboard = keyboardProvider?.Name;
|
|
||||||
General.Default.Save();
|
|
||||||
|
|
||||||
Logger.Debug("Restarting for keyboard change");
|
|
||||||
_mainManager.Restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
161
Artemis/Artemis/Managers/LoopManager.cs
Normal file
161
Artemis/Artemis/Managers/LoopManager.cs
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Timers;
|
||||||
|
using Ninject.Extensions.Logging;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
|
|
||||||
|
namespace Artemis.Managers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the main programn loop
|
||||||
|
/// </summary>
|
||||||
|
public class LoopManager : IDisposable
|
||||||
|
{
|
||||||
|
private readonly DeviceManager _deviceManager;
|
||||||
|
private readonly EffectManager _effectManager;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly Timer _loopTimer;
|
||||||
|
|
||||||
|
public LoopManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_effectManager = effectManager;
|
||||||
|
_deviceManager = deviceManager;
|
||||||
|
|
||||||
|
// Setup timers
|
||||||
|
_loopTimer = new Timer(40);
|
||||||
|
_loopTimer.Elapsed += Render;
|
||||||
|
_loopTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether the loop is running
|
||||||
|
/// </summary>
|
||||||
|
public bool Running { get; private set; }
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_loopTimer.Stop();
|
||||||
|
_loopTimer.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
if (Running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_logger.Debug("Starting LoopManager");
|
||||||
|
|
||||||
|
if (_deviceManager.ActiveKeyboard == null)
|
||||||
|
_deviceManager.EnableLastKeyboard();
|
||||||
|
// If still null, no last keyboard, so stop.
|
||||||
|
if (_deviceManager.ActiveKeyboard == null)
|
||||||
|
{
|
||||||
|
_logger.Debug("Cancel LoopManager start, no keyboard");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_effectManager.ActiveEffect == null)
|
||||||
|
{
|
||||||
|
var lastEffect = _effectManager.GetLastEffect();
|
||||||
|
if (lastEffect == null)
|
||||||
|
{
|
||||||
|
_logger.Debug("Cancel LoopManager start, no effect");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_effectManager.ChangeEffect(lastEffect);
|
||||||
|
}
|
||||||
|
|
||||||
|
Running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
if (!Running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_logger.Debug("Stopping LoopManager");
|
||||||
|
Running = false;
|
||||||
|
|
||||||
|
_deviceManager.ReleaseActiveKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Render(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!Running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Stop if no active effect
|
||||||
|
if (_effectManager.ActiveEffect == null)
|
||||||
|
{
|
||||||
|
_logger.Debug("No active effect, stopping");
|
||||||
|
Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var renderEffect = _effectManager.ActiveEffect;
|
||||||
|
|
||||||
|
if (_deviceManager.ChangingKeyboard)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Stop if no active keyboard
|
||||||
|
if (_deviceManager.ActiveKeyboard == null)
|
||||||
|
{
|
||||||
|
_logger.Debug("No active keyboard, stopping");
|
||||||
|
Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (_deviceManager.ActiveKeyboard)
|
||||||
|
{
|
||||||
|
// Skip frame if effect is still initializing
|
||||||
|
if (renderEffect.Initialized == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// ApplyProperties the current effect
|
||||||
|
if (renderEffect.Initialized)
|
||||||
|
renderEffect.Update();
|
||||||
|
|
||||||
|
// Get ActiveEffect's bitmap
|
||||||
|
Bitmap bitmap = null;
|
||||||
|
Brush mouseBrush = null;
|
||||||
|
Brush headsetBrush = null;
|
||||||
|
var mice = _deviceManager.MiceProviders.Where(m => m.CanUse).ToList();
|
||||||
|
var headsets = _deviceManager.HeadsetProviders.Where(m => m.CanUse).ToList();
|
||||||
|
|
||||||
|
if (renderEffect.Initialized)
|
||||||
|
renderEffect.Render(out bitmap, out mouseBrush, out headsetBrush, mice.Any(), headsets.Any());
|
||||||
|
|
||||||
|
// Draw enabled overlays on top of the renderEffect
|
||||||
|
foreach (var overlayModel in _effectManager.EnabledOverlays)
|
||||||
|
{
|
||||||
|
overlayModel.Update();
|
||||||
|
overlayModel.RenderOverlay(ref bitmap, ref mouseBrush, ref headsetBrush, mice.Any(), headsets.Any());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update mice and headsets
|
||||||
|
foreach (var mouse in mice)
|
||||||
|
mouse.UpdateDevice(mouseBrush);
|
||||||
|
foreach (var headset in headsets)
|
||||||
|
headset.UpdateDevice(headsetBrush);
|
||||||
|
|
||||||
|
// If no bitmap was generated this frame is done
|
||||||
|
if (bitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
|
||||||
|
var fixedBmp = new Bitmap(bitmap.Width, bitmap.Height);
|
||||||
|
using (var g = Graphics.FromImage(fixedBmp))
|
||||||
|
{
|
||||||
|
g.Clear(Color.Black);
|
||||||
|
g.DrawImage(bitmap, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap = fixedBmp;
|
||||||
|
|
||||||
|
// Update the keyboard
|
||||||
|
_deviceManager.ActiveKeyboard?.DrawBitmap(bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,56 +1,55 @@
|
|||||||
using System.ComponentModel;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Timers;
|
||||||
using Artemis.Events;
|
using Artemis.Events;
|
||||||
using Artemis.Models;
|
using Artemis.Models;
|
||||||
using Artemis.Services;
|
using Artemis.Modules.Effects.ProfilePreview;
|
||||||
using Artemis.Utilities.GameState;
|
using Artemis.Utilities.GameState;
|
||||||
using Artemis.Utilities.Keyboard;
|
using Artemis.Utilities.Keyboard;
|
||||||
using Artemis.Utilities.LogitechDll;
|
using Artemis.Utilities.LogitechDll;
|
||||||
|
using Artemis.ViewModels;
|
||||||
using Caliburn.Micro;
|
using Caliburn.Micro;
|
||||||
using NLog;
|
using Ninject;
|
||||||
using LogManager = NLog.LogManager;
|
using Ninject.Extensions.Logging;
|
||||||
|
|
||||||
namespace Artemis.Managers
|
namespace Artemis.Managers
|
||||||
{
|
{
|
||||||
public class MainManager
|
/// <summary>
|
||||||
|
/// Contains all the other managers and non-loop related components
|
||||||
|
/// </summary>
|
||||||
|
public class MainManager : IDisposable
|
||||||
{
|
{
|
||||||
public delegate void PauseCallbackHandler();
|
public delegate void PauseCallbackHandler();
|
||||||
|
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private readonly IEventAggregator _events;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly Timer _processTimer;
|
||||||
|
|
||||||
private readonly int _fps;
|
public MainManager(IEventAggregator events, ILogger logger, LoopManager loopManager,
|
||||||
private bool _paused;
|
DeviceManager deviceManager, EffectManager effectManager, ProfileManager profileManager)
|
||||||
private bool _restarting;
|
|
||||||
|
|
||||||
public MainManager(IEventAggregator events, MetroDialogService dialogService)
|
|
||||||
{
|
{
|
||||||
Logger.Info("Intializing MainManager");
|
_logger = logger;
|
||||||
|
LoopManager = loopManager;
|
||||||
|
DeviceManager = deviceManager;
|
||||||
|
EffectManager = effectManager;
|
||||||
|
ProfileManager = profileManager;
|
||||||
|
|
||||||
Events = events;
|
_logger.Info("Intializing MainManager");
|
||||||
DialogService = dialogService;
|
|
||||||
|
|
||||||
KeyboardManager = new KeyboardManager(this, Events);
|
_events = events;
|
||||||
EffectManager = new EffectManager(this, Events);
|
|
||||||
KeyboardHook = new KeyboardHook();
|
|
||||||
|
|
||||||
_fps = 25;
|
_processTimer = new Timer(1000);
|
||||||
UpdateWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
|
_processTimer.Elapsed += ScanProcesses;
|
||||||
ProcessWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
|
_processTimer.Start();
|
||||||
|
|
||||||
UpdateWorker.DoWork += UpdateWorker_DoWork;
|
|
||||||
UpdateWorker.RunWorkerCompleted += BackgroundWorkerExceptionCatcher;
|
|
||||||
|
|
||||||
ProcessWorker.DoWork += ProcessWorker_DoWork;
|
|
||||||
ProcessWorker.RunWorkerCompleted += BackgroundWorkerExceptionCatcher;
|
|
||||||
|
|
||||||
// Process worker will always run (and just do nothing when ProgramEnabled is false)
|
|
||||||
ProcessWorker.RunWorkerAsync();
|
|
||||||
|
|
||||||
ProgramEnabled = false;
|
ProgramEnabled = false;
|
||||||
Running = false;
|
Running = false;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Dependency inject utilities?
|
||||||
|
KeyboardHook = new KeyboardHook();
|
||||||
|
|
||||||
// Create and start the web server
|
// Create and start the web server
|
||||||
GameStateWebServer = new GameStateWebServer();
|
GameStateWebServer = new GameStateWebServer();
|
||||||
GameStateWebServer.Start();
|
GameStateWebServer.Start();
|
||||||
@ -59,141 +58,44 @@ namespace Artemis.Managers
|
|||||||
PipeServer = new PipeServer();
|
PipeServer = new PipeServer();
|
||||||
PipeServer.Start("artemis");
|
PipeServer.Start("artemis");
|
||||||
|
|
||||||
Logger.Info("Intialized MainManager");
|
_logger.Info("Intialized MainManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
public Lazy<ShellViewModel> ShellViewModel { get; set; }
|
||||||
|
|
||||||
|
public LoopManager LoopManager { get; }
|
||||||
|
public DeviceManager DeviceManager { get; set; }
|
||||||
|
public EffectManager EffectManager { get; set; }
|
||||||
|
public ProfileManager ProfileManager { get; set; }
|
||||||
|
|
||||||
public PipeServer PipeServer { get; set; }
|
public PipeServer PipeServer { get; set; }
|
||||||
public BackgroundWorker UpdateWorker { get; set; }
|
|
||||||
public BackgroundWorker ProcessWorker { get; set; }
|
|
||||||
|
|
||||||
public KeyboardManager KeyboardManager { get; set; }
|
|
||||||
public EffectManager EffectManager { get; set; }
|
|
||||||
|
|
||||||
public KeyboardHook KeyboardHook { get; set; }
|
public KeyboardHook KeyboardHook { get; set; }
|
||||||
|
|
||||||
public GameStateWebServer GameStateWebServer { get; set; }
|
public GameStateWebServer GameStateWebServer { get; set; }
|
||||||
public IEventAggregator Events { get; set; }
|
|
||||||
public MetroDialogService DialogService { get; set; }
|
|
||||||
|
|
||||||
public bool ProgramEnabled { get; private set; }
|
public bool ProgramEnabled { get; private set; }
|
||||||
public bool Suspended { get; set; }
|
|
||||||
|
|
||||||
public bool Running { get; private set; }
|
public bool Running { get; private set; }
|
||||||
|
|
||||||
public event PauseCallbackHandler PauseCallback;
|
public void Dispose()
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Take control of the keyboard and start sending data to it
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Whether starting was successful or not</returns>
|
|
||||||
public bool Start(EffectModel effect = null)
|
|
||||||
{
|
{
|
||||||
Logger.Debug("Starting MainManager");
|
_logger.Debug("Shutting down MainManager");
|
||||||
// Can't take control when not enabled
|
|
||||||
if (!ProgramEnabled || UpdateWorker.CancellationPending || UpdateWorker.IsBusy || _paused)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Do nothing if already running
|
_processTimer.Stop();
|
||||||
if (Running)
|
_processTimer.Dispose();
|
||||||
return true;
|
LoopManager.Stop();
|
||||||
|
EffectManager.ActiveEffect.Dispose();
|
||||||
// Only continue if a keyboard was loaded
|
|
||||||
KeyboardManager.EnableLastKeyboard();
|
|
||||||
if (KeyboardManager.ActiveKeyboard == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Running = true;
|
|
||||||
if (effect != null)
|
|
||||||
EffectManager.ChangeEffect(effect);
|
|
||||||
|
|
||||||
// Start the update worker
|
|
||||||
if (!UpdateWorker.IsBusy)
|
|
||||||
UpdateWorker.RunWorkerAsync();
|
|
||||||
|
|
||||||
return Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Releases control of the keyboard and stop sending data to it
|
|
||||||
/// </summary>
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
Logger.Debug("Stopping MainManager");
|
|
||||||
if (!Running || UpdateWorker.CancellationPending || _paused)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Stop the update worker
|
|
||||||
UpdateWorker.CancelAsync();
|
|
||||||
UpdateWorker.RunWorkerCompleted += FinishStop;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FinishStop(object sender, RunWorkerCompletedEventArgs e)
|
|
||||||
{
|
|
||||||
UpdateWorker.RunWorkerCompleted -= FinishStop;
|
|
||||||
KeyboardManager.ReleaseActiveKeyboard();
|
|
||||||
Running = false;
|
|
||||||
|
|
||||||
Logger.Debug("Stopped MainManager");
|
|
||||||
if (e.Error != null || !_restarting)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Start();
|
|
||||||
_restarting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Pause()
|
|
||||||
{
|
|
||||||
if (!Running || UpdateWorker.CancellationPending || _paused)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Logger.Debug("Pausing MainManager");
|
|
||||||
_paused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Unpause()
|
|
||||||
{
|
|
||||||
if (!_paused)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Logger.Debug("Unpausing MainManager");
|
|
||||||
_paused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Shutdown()
|
|
||||||
{
|
|
||||||
Logger.Debug("Shutting down MainManager");
|
|
||||||
Stop();
|
|
||||||
ProcessWorker.CancelAsync();
|
|
||||||
ProcessWorker.CancelAsync();
|
|
||||||
GameStateWebServer.Stop();
|
GameStateWebServer.Stop();
|
||||||
PipeServer.Stop();
|
PipeServer.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Restart()
|
|
||||||
{
|
|
||||||
if (_restarting)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Logger.Debug("Restarting MainManager");
|
|
||||||
if (!Running)
|
|
||||||
{
|
|
||||||
Start();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_restarting = true;
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the last active effect and starts the program
|
/// Loads the last active effect and starts the program
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void EnableProgram()
|
public void EnableProgram()
|
||||||
{
|
{
|
||||||
Logger.Debug("Enabling program");
|
_logger.Debug("Enabling program");
|
||||||
ProgramEnabled = true;
|
ProgramEnabled = true;
|
||||||
Start(EffectManager.GetLastEffect());
|
LoopManager.Start();
|
||||||
Events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
|
_events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -201,129 +103,52 @@ namespace Artemis.Managers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void DisableProgram()
|
public void DisableProgram()
|
||||||
{
|
{
|
||||||
Logger.Debug("Disabling program");
|
_logger.Debug("Disabling program");
|
||||||
Stop();
|
LoopManager.Stop();
|
||||||
ProgramEnabled = false;
|
ProgramEnabled = false;
|
||||||
Events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
|
_events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Workers
|
/// <summary>
|
||||||
|
/// Manages active games by keeping an eye on their processes
|
||||||
private void UpdateWorker_DoWork(object sender, DoWorkEventArgs e)
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void ScanProcesses(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
if (!ProgramEnabled)
|
||||||
while (!UpdateWorker.CancellationPending)
|
|
||||||
{
|
|
||||||
// Skip frame when paused
|
|
||||||
if (_paused)
|
|
||||||
{
|
|
||||||
PauseCallback?.Invoke();
|
|
||||||
Thread.Sleep(1000/_fps);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop if no keyboard/effect are present
|
|
||||||
if (KeyboardManager.ActiveKeyboard == null || EffectManager.ActiveEffect == null)
|
|
||||||
{
|
|
||||||
Thread.Sleep(1000/_fps);
|
|
||||||
Logger.Debug("No active effect/keyboard, stopping");
|
|
||||||
|
|
||||||
if (EffectManager.PauseEffect != null)
|
|
||||||
{
|
|
||||||
PauseCallback?.Invoke();
|
|
||||||
Thread.Sleep(1000/_fps);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Stop();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't stop when the effect is still initialized, just skip this frame
|
|
||||||
if (!EffectManager.ActiveEffect.Initialized)
|
|
||||||
{
|
|
||||||
Thread.Sleep(1000/_fps);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sw.Start();
|
|
||||||
|
|
||||||
// Update the current effect
|
|
||||||
if (EffectManager.ActiveEffect.Initialized)
|
|
||||||
EffectManager.ActiveEffect.Update();
|
|
||||||
|
|
||||||
// Get ActiveEffect's bitmap
|
|
||||||
var bitmap = EffectManager.ActiveEffect.Initialized
|
|
||||||
? EffectManager.ActiveEffect.GenerateBitmap()
|
|
||||||
: null;
|
|
||||||
|
|
||||||
// Draw enabled overlays on top
|
|
||||||
foreach (var overlayModel in EffectManager.EnabledOverlays)
|
|
||||||
{
|
|
||||||
overlayModel.Update();
|
|
||||||
bitmap = bitmap != null ? overlayModel.GenerateBitmap(bitmap) : overlayModel.GenerateBitmap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it exists, send bitmap to the device
|
|
||||||
if (bitmap != null && KeyboardManager.ActiveKeyboard != null)
|
|
||||||
{
|
|
||||||
KeyboardManager.ActiveKeyboard.DrawBitmap(bitmap);
|
|
||||||
|
|
||||||
// debugging TODO: Disable when window isn't shown
|
|
||||||
Events.PublishOnUIThread(new ChangeBitmap(bitmap));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sleep according to time left this frame
|
|
||||||
var sleep = (int) (1000/_fps - sw.ElapsedMilliseconds);
|
|
||||||
if (sleep > 0)
|
|
||||||
Thread.Sleep(sleep);
|
|
||||||
sw.Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BackgroundWorkerExceptionCatcher(object sender, RunWorkerCompletedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Error == null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Logger.Error(e.Error, "Exception in the BackgroundWorker");
|
var runningProcesses = Process.GetProcesses();
|
||||||
throw e.Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessWorker_DoWork(object sender, DoWorkEventArgs e)
|
// If the currently active effect is a disabled game, get rid of it.
|
||||||
{
|
if (EffectManager.ActiveEffect != null)
|
||||||
while (!ProcessWorker.CancellationPending)
|
EffectManager.DisableInactiveGame();
|
||||||
|
|
||||||
|
if (EffectManager.ActiveEffect is ProfilePreviewModel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If the currently active effect is a no longer running game, get rid of it.
|
||||||
|
var activeGame = EffectManager.ActiveEffect as GameModel;
|
||||||
|
if (activeGame != null)
|
||||||
{
|
{
|
||||||
if (!ProgramEnabled)
|
if (!runningProcesses.Any(p => p.ProcessName == activeGame.ProcessName && p.HasExited == false))
|
||||||
{
|
{
|
||||||
Thread.Sleep(1000);
|
_logger.Info("Disabling game: {0}", activeGame.Name);
|
||||||
continue;
|
EffectManager.DisableGame(activeGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
var runningProcesses = Process.GetProcesses();
|
|
||||||
|
|
||||||
// If the currently active effect is a disabled game, get rid of it.
|
|
||||||
if (EffectManager.ActiveEffect != null)
|
|
||||||
EffectManager.DisableInactiveGame();
|
|
||||||
|
|
||||||
// If the currently active effect is a no longer running game, get rid of it.
|
|
||||||
var activeGame = EffectManager.ActiveEffect as GameModel;
|
|
||||||
if (activeGame != null)
|
|
||||||
if (!runningProcesses.Any(p => p.ProcessName == activeGame.ProcessName && p.HasExited == false))
|
|
||||||
EffectManager.DisableGame(activeGame);
|
|
||||||
|
|
||||||
// Look for running games, stopping on the first one that's found.
|
|
||||||
var newGame = EffectManager.EnabledGames
|
|
||||||
.FirstOrDefault(
|
|
||||||
g => runningProcesses.Any(p => p.ProcessName == g.ProcessName && p.HasExited == false));
|
|
||||||
|
|
||||||
// If it's not already enabled, do so.
|
|
||||||
if (newGame != null && EffectManager.ActiveEffect != newGame)
|
|
||||||
EffectManager.ChangeEffect(newGame);
|
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
// Look for running games, stopping on the first one that's found.
|
||||||
|
var newGame = EffectManager.EnabledGames
|
||||||
|
.FirstOrDefault(g => runningProcesses
|
||||||
|
.Any(p => p.ProcessName == g.ProcessName && p.HasExited == false));
|
||||||
|
|
||||||
|
if (newGame == null || EffectManager.ActiveEffect == newGame)
|
||||||
|
return;
|
||||||
|
// If it's not already enabled, do so.
|
||||||
|
_logger.Info("Detected and enabling game: {0}", newGame.Name);
|
||||||
|
EffectManager.ChangeEffect(newGame, LoopManager);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
78
Artemis/Artemis/Managers/ProfileManager.cs
Normal file
78
Artemis/Artemis/Managers/ProfileManager.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Timers;
|
||||||
|
using Artemis.Modules.Effects.ProfilePreview;
|
||||||
|
using Artemis.Settings;
|
||||||
|
using Artemis.ViewModels.Abstract;
|
||||||
|
using Ninject.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Artemis.Managers
|
||||||
|
{
|
||||||
|
public class ProfileManager
|
||||||
|
{
|
||||||
|
private readonly DeviceManager _deviceManager;
|
||||||
|
private readonly EffectManager _effectManager;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly LoopManager _loopManager;
|
||||||
|
|
||||||
|
public ProfileManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager,
|
||||||
|
LoopManager loopManager)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_effectManager = effectManager;
|
||||||
|
_deviceManager = deviceManager;
|
||||||
|
_loopManager = loopManager;
|
||||||
|
|
||||||
|
GameViewModels = new List<GameViewModel>();
|
||||||
|
|
||||||
|
var profilePreviewTimer = new Timer(500);
|
||||||
|
profilePreviewTimer.Elapsed += SetupProfilePreview;
|
||||||
|
profilePreviewTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfilePreviewModel ProfilePreviewModel { get; set; }
|
||||||
|
|
||||||
|
public List<GameViewModel> GameViewModels { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Keeps track of profiles being previewed and sets up the active efffect accordingly
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void SetupProfilePreview(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(General.Default.LastKeyboard) || _deviceManager.ChangingKeyboard ||
|
||||||
|
ProfilePreviewModel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var activePreview = GameViewModels.FirstOrDefault(vm => vm.IsActive);
|
||||||
|
if (activePreview == null)
|
||||||
|
{
|
||||||
|
// Should not be active if no selected profile is set
|
||||||
|
if (_effectManager.ActiveEffect != ProfilePreviewModel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_logger.Debug("Loading last effect after profile preview");
|
||||||
|
var lastEffect = _effectManager.GetLastEffect();
|
||||||
|
if (lastEffect != null)
|
||||||
|
_effectManager.ChangeEffect(lastEffect);
|
||||||
|
else
|
||||||
|
_effectManager.ClearEffect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_effectManager.ActiveEffect != ProfilePreviewModel)
|
||||||
|
{
|
||||||
|
_logger.Debug("Activate profile preview");
|
||||||
|
_effectManager.ChangeEffect(ProfilePreviewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoopManager might be running, this method won't do any harm in that case.
|
||||||
|
_loopManager.Start();
|
||||||
|
|
||||||
|
if (!ReferenceEquals(ProfilePreviewModel.Profile, activePreview.ProfileEditor.SelectedProfile))
|
||||||
|
ProfilePreviewModel.Profile = activePreview.ProfileEditor.SelectedProfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
using Artemis.Models.Profiles;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
|
|
||||||
namespace Artemis.Models
|
namespace Artemis.Models
|
||||||
{
|
{
|
||||||
@ -9,24 +14,50 @@ namespace Artemis.Models
|
|||||||
public delegate void SettingsUpdateHandler(EffectSettings settings);
|
public delegate void SettingsUpdateHandler(EffectSettings settings);
|
||||||
|
|
||||||
public bool Initialized;
|
public bool Initialized;
|
||||||
|
|
||||||
public MainManager MainManager;
|
public MainManager MainManager;
|
||||||
public string Name;
|
public string Name;
|
||||||
|
|
||||||
protected EffectModel(MainManager mainManager)
|
protected EffectModel(MainManager mainManager, IDataModel dataModel)
|
||||||
{
|
{
|
||||||
MainManager = mainManager;
|
MainManager = mainManager;
|
||||||
|
DataModel = dataModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used by profile system
|
||||||
|
public IDataModel DataModel { get; set; }
|
||||||
|
public ProfileModel Profile { get; set; }
|
||||||
|
|
||||||
public abstract void Dispose();
|
public abstract void Dispose();
|
||||||
|
|
||||||
// Called on creation
|
// Called on creation
|
||||||
public abstract void Enable();
|
public abstract void Enable();
|
||||||
|
|
||||||
// Called every iteration
|
// Called every frame
|
||||||
public abstract void Update();
|
public abstract void Update();
|
||||||
|
|
||||||
// Called after every update
|
// Called after every update
|
||||||
public abstract Bitmap GenerateBitmap();
|
public virtual void Render(out Bitmap keyboard, out Brush mouse, out Brush headset, bool renderMice,
|
||||||
|
bool renderHeadsets)
|
||||||
|
{
|
||||||
|
keyboard = null;
|
||||||
|
mouse = null;
|
||||||
|
headset = null;
|
||||||
|
|
||||||
|
if (Profile == null || DataModel == null || MainManager.DeviceManager.ActiveKeyboard == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get all enabled layers who's conditions are met
|
||||||
|
var renderLayers = GetRenderLayers(renderMice, renderHeadsets);
|
||||||
|
|
||||||
|
// Render the keyboard layer-by-layer
|
||||||
|
keyboard = Profile.GenerateBitmap(renderLayers, DataModel,
|
||||||
|
MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(4), false, true);
|
||||||
|
// Render the first enabled mouse (will default to null if renderMice was false)
|
||||||
|
mouse = Profile.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Mouse), DataModel);
|
||||||
|
// Render the first enabled headset (will default to null if renderHeadsets was false)
|
||||||
|
headset = Profile.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Headset), DataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,12 +1,12 @@
|
|||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
using Artemis.Models.Interfaces;
|
using Artemis.Models.Interfaces;
|
||||||
using Artemis.Models.Profiles;
|
|
||||||
|
|
||||||
namespace Artemis.Models
|
namespace Artemis.Models
|
||||||
{
|
{
|
||||||
public abstract class GameModel : EffectModel
|
public abstract class GameModel : EffectModel
|
||||||
{
|
{
|
||||||
protected GameModel(MainManager mainManager, GameSettings settings) : base(mainManager)
|
protected GameModel(MainManager mainManager, GameSettings settings, IDataModel dataModel)
|
||||||
|
: base(mainManager, dataModel)
|
||||||
{
|
{
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
}
|
}
|
||||||
@ -14,7 +14,5 @@ namespace Artemis.Models
|
|||||||
public GameSettings Settings { get; set; }
|
public GameSettings Settings { get; set; }
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
public string ProcessName { get; set; }
|
public string ProcessName { get; set; }
|
||||||
public IGameDataModel GameDataModel { get; set; }
|
|
||||||
public ProfileModel Profile { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,5 +3,6 @@
|
|||||||
public abstract class GameSettings : EffectSettings
|
public abstract class GameSettings : EffectSettings
|
||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
public string LastProfile { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Models.Interfaces
|
namespace Artemis.Models.Interfaces
|
||||||
{
|
{
|
||||||
public interface IGameDataModel
|
public interface IDataModel
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
|
|
||||||
namespace Artemis.Models
|
namespace Artemis.Models
|
||||||
{
|
{
|
||||||
@ -8,7 +9,7 @@ namespace Artemis.Models
|
|||||||
private bool _enabled;
|
private bool _enabled;
|
||||||
public string ProcessName;
|
public string ProcessName;
|
||||||
|
|
||||||
protected OverlayModel(MainManager mainManager) : base(mainManager)
|
protected OverlayModel(MainManager mainManager) : base(mainManager, null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,19 +29,7 @@ namespace Artemis.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetEnabled(bool enabled)
|
public abstract void RenderOverlay(ref Bitmap keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
|
||||||
{
|
bool renderHeadsets);
|
||||||
if (Enabled == enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (enabled)
|
|
||||||
Enable();
|
|
||||||
else
|
|
||||||
Dispose();
|
|
||||||
|
|
||||||
Enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract Bitmap GenerateBitmap(Bitmap bitmap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
7
Artemis/Artemis/Models/OverlaySettings.cs
Normal file
7
Artemis/Artemis/Models/OverlaySettings.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Artemis.Models
|
||||||
|
{
|
||||||
|
public abstract class OverlaySettings : EffectSettings
|
||||||
|
{
|
||||||
|
public bool Enabled { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ namespace Artemis.Models.Profiles
|
|||||||
public string Operator { get; set; }
|
public string Operator { get; set; }
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
|
|
||||||
public bool ConditionMet<T>(IGameDataModel subject)
|
public bool ConditionMet<T>(IDataModel subject)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Type))
|
if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Type))
|
||||||
return false;
|
return false;
|
||||||
@ -23,9 +23,13 @@ namespace Artemis.Models.Profiles
|
|||||||
|
|
||||||
// Put the subject in a list, allowing Dynamic Linq to be used.
|
// Put the subject in a list, allowing Dynamic Linq to be used.
|
||||||
var subjectList = new List<T> {(T) subject};
|
var subjectList = new List<T> {(T) subject};
|
||||||
var res = Type == "String"
|
bool res;
|
||||||
? subjectList.Where($"{Field}.ToLower() {Operator} @0", Value.ToLower()).Any()
|
if (Type == "String")
|
||||||
: subjectList.Where($"{Field} {Operator} {Value}").Any();
|
res = subjectList.Where($"{Field}.ToLower() {Operator} @0", Value.ToLower()).Any();
|
||||||
|
else if (Type == "Enum")
|
||||||
|
res = subjectList.Where($"{Field} {Operator} \"{Value}\"").Any();
|
||||||
|
else
|
||||||
|
res = subjectList.Where($"{Field} {Operator} {Value}").Any();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,79 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using Artemis.Models.Interfaces;
|
|
||||||
using Artemis.Utilities;
|
|
||||||
using static System.Decimal;
|
|
||||||
|
|
||||||
namespace Artemis.Models.Profiles
|
|
||||||
{
|
|
||||||
public class LayerDynamicPropertiesModel
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Property this dynamic property applies on
|
|
||||||
/// </summary>
|
|
||||||
public string LayerProperty { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Property to base the percentage upon
|
|
||||||
/// </summary>
|
|
||||||
public string GameProperty { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Percentage source, the number that defines 100%
|
|
||||||
/// </summary>
|
|
||||||
public string PercentageSource { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Type of property
|
|
||||||
/// </summary>
|
|
||||||
public LayerPropertyType LayerPropertyType { get; set; }
|
|
||||||
|
|
||||||
internal void ApplyProperty<T>(IGameDataModel data, LayerPropertiesModel userProps, LayerPropertiesModel props)
|
|
||||||
{
|
|
||||||
if (LayerPropertyType == LayerPropertyType.PercentageOf)
|
|
||||||
Apply(props, userProps, data, int.Parse(PercentageSource));
|
|
||||||
if (LayerPropertyType == LayerPropertyType.PercentageOfProperty)
|
|
||||||
ApplyProp(props, userProps, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Apply(LayerPropertiesModel props, LayerPropertiesModel userProps, IGameDataModel data,
|
|
||||||
int percentageSource)
|
|
||||||
{
|
|
||||||
// Property to apply on
|
|
||||||
var layerProp = props.GetType().GetProperty(LayerProperty);
|
|
||||||
// User's settings
|
|
||||||
var userProp = userProps.GetType().GetProperty(LayerProperty);
|
|
||||||
// Property to base the percentage upon
|
|
||||||
var gameProperty = data.GetPropValue<int>(GameProperty);
|
|
||||||
if (layerProp == null || userProp == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var percentage = ToDouble(gameProperty) / percentageSource;
|
|
||||||
|
|
||||||
// Opacity requires some special treatment as it causes an exception if it's < 0.0 or > 1.0
|
|
||||||
if (LayerProperty == "Opacity")
|
|
||||||
{
|
|
||||||
var opacity = percentage*(double) userProp.GetValue(userProps, null);
|
|
||||||
if (opacity < 0.0)
|
|
||||||
opacity = 0.0;
|
|
||||||
if (opacity > 1.0)
|
|
||||||
opacity = 1.0;
|
|
||||||
layerProp.SetValue(props, opacity);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
layerProp.SetValue(props, (int) (percentage*(int) userProp.GetValue(userProps, null)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyProp(LayerPropertiesModel props, LayerPropertiesModel userProps, IGameDataModel data)
|
|
||||||
{
|
|
||||||
var value = data.GetPropValue<int>(PercentageSource);
|
|
||||||
Apply(props, userProps, data, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum LayerPropertyType
|
|
||||||
{
|
|
||||||
[Description("None")] None,
|
|
||||||
[Description("% of")] PercentageOf,
|
|
||||||
[Description("% of property")] PercentageOfProperty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,142 +4,262 @@ using System.Linq;
|
|||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using Artemis.Models.Interfaces;
|
using Artemis.Models.Interfaces;
|
||||||
|
using Artemis.Models.Profiles.Properties;
|
||||||
using Artemis.Utilities;
|
using Artemis.Utilities;
|
||||||
|
using Artemis.Utilities.Layers;
|
||||||
using Artemis.Utilities.ParentChild;
|
using Artemis.Utilities.ParentChild;
|
||||||
|
|
||||||
namespace Artemis.Models.Profiles
|
namespace Artemis.Models.Profiles
|
||||||
{
|
{
|
||||||
public class LayerModel : IChildItem<LayerModel>, IChildItem<ProfileModel>
|
public class LayerModel : IChildItem<LayerModel>, IChildItem<ProfileModel>
|
||||||
{
|
{
|
||||||
[XmlIgnore] private readonly LayerDrawer _drawer;
|
|
||||||
[XmlIgnore] private bool _mustDraw;
|
|
||||||
|
|
||||||
public LayerModel()
|
public LayerModel()
|
||||||
{
|
{
|
||||||
UserProps = new LayerPropertiesModel();
|
|
||||||
CalcProps = new LayerPropertiesModel();
|
|
||||||
|
|
||||||
Children = new ChildItemCollection<LayerModel, LayerModel>(this);
|
Children = new ChildItemCollection<LayerModel, LayerModel>(this);
|
||||||
LayerConditions = new List<LayerConditionModel>();
|
|
||||||
LayerProperties = new List<LayerDynamicPropertiesModel>();
|
|
||||||
|
|
||||||
_mustDraw = true;
|
|
||||||
_drawer = new LayerDrawer(this, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
public int Order { get; set; }
|
||||||
public LayerType LayerType { get; set; }
|
public LayerType LayerType { get; set; }
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
public int Order { get; set; }
|
public bool Expanded { get; set; }
|
||||||
public LayerPropertiesModel UserProps { get; set; }
|
public LayerPropertiesModel Properties { get; set; }
|
||||||
|
|
||||||
public ChildItemCollection<LayerModel, LayerModel> Children { get; }
|
public ChildItemCollection<LayerModel, LayerModel> Children { get; }
|
||||||
public List<LayerConditionModel> LayerConditions { get; set; }
|
|
||||||
public List<LayerDynamicPropertiesModel> LayerProperties { get; set; }
|
|
||||||
|
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public LayerPropertiesModel CalcProps { get; set; }
|
public ImageSource LayerImage => Drawer.DrawThumbnail(this);
|
||||||
|
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public ImageSource LayerImage => _drawer.GetThumbnail();
|
public LayerModel Parent { get; internal set; }
|
||||||
|
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public LayerModel ParentLayer { get; internal set; }
|
public ProfileModel Profile { get; internal set; }
|
||||||
|
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public ProfileModel ParentProfile { get; internal set; }
|
public GifImage GifImage { get; set; }
|
||||||
|
|
||||||
public bool ConditionsMet<T>(IGameDataModel dataModel)
|
public bool ConditionsMet<T>(IDataModel dataModel)
|
||||||
{
|
{
|
||||||
return Enabled && LayerConditions.All(cm => cm.ConditionMet<T>(dataModel));
|
return Enabled && Properties.Conditions.All(cm => cm.ConditionMet<T>(dataModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawPreview(DrawingContext c)
|
public void Draw(IDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
|
||||||
{
|
{
|
||||||
GeneralHelpers.CopyProperties(CalcProps, UserProps);
|
if (LayerType != LayerType.Keyboard && LayerType != LayerType.KeyboardGif)
|
||||||
if (LayerType == LayerType.Keyboard || LayerType == LayerType.Keyboard)
|
return;
|
||||||
_drawer.Draw(c, _mustDraw);
|
|
||||||
|
// Preview simply shows the properties as they are. When not previewing they are applied
|
||||||
|
var appliedProperties = !preview
|
||||||
|
? Properties.GetAppliedProperties(dataModel)
|
||||||
|
: Properties.GetAppliedProperties(dataModel, true);
|
||||||
|
|
||||||
|
// Update animations
|
||||||
|
AnimationUpdater.UpdateAnimation((KeyboardPropertiesModel) Properties, updateAnimations);
|
||||||
|
|
||||||
|
if (LayerType == LayerType.Keyboard)
|
||||||
|
Drawer.Draw(c, (KeyboardPropertiesModel) Properties, appliedProperties);
|
||||||
else if (LayerType == LayerType.KeyboardGif)
|
else if (LayerType == LayerType.KeyboardGif)
|
||||||
_drawer.DrawGif(c);
|
GifImage = Drawer.DrawGif(c, (KeyboardPropertiesModel) Properties, appliedProperties, GifImage);
|
||||||
_mustDraw = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw<T>(IGameDataModel dataModel, DrawingContext c, bool preview = false)
|
public Brush GenerateBrush<T>(LayerType type, IDataModel dataModel, bool preview, bool updateAnimations)
|
||||||
{
|
{
|
||||||
// Conditions aren't checked during a preview because there is no game data to base them on
|
if (!Enabled)
|
||||||
|
return null;
|
||||||
|
if (LayerType != LayerType.Folder && LayerType != type)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Preview simply shows the properties as they are. When not previewing they are applied
|
||||||
|
AppliedProperties appliedProperties;
|
||||||
if (!preview)
|
if (!preview)
|
||||||
if (!ConditionsMet<T>(dataModel))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (LayerType == LayerType.Folder)
|
|
||||||
foreach (var layerModel in Children.OrderByDescending(l => l.Order))
|
|
||||||
layerModel.Draw<T>(dataModel, c);
|
|
||||||
else if (LayerType == LayerType.Keyboard || LayerType == LayerType.Keyboard)
|
|
||||||
_drawer.Draw(c);
|
|
||||||
else if (LayerType == LayerType.KeyboardGif)
|
|
||||||
_drawer.DrawGif(c);
|
|
||||||
else if (LayerType == LayerType.Mouse)
|
|
||||||
_drawer.UpdateMouse();
|
|
||||||
else if (LayerType == LayerType.Headset)
|
|
||||||
_drawer.UpdateHeadset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update<T>(IGameDataModel dataModel, bool preview = false)
|
|
||||||
{
|
|
||||||
if (LayerType == LayerType.Folder)
|
|
||||||
{
|
{
|
||||||
foreach (var layerModel in Children)
|
if (!ConditionsMet<T>(dataModel))
|
||||||
layerModel.Update<T>(dataModel);
|
return null; // Return null when not previewing and the conditions arent met
|
||||||
return;
|
appliedProperties = Properties.GetAppliedProperties(dataModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneralHelpers.CopyProperties(CalcProps, UserProps);
|
|
||||||
|
|
||||||
// Dynamic properties aren't applied during preview because there is no game data to base them on
|
|
||||||
if (preview)
|
|
||||||
return;
|
|
||||||
foreach (var dynamicProperty in LayerProperties)
|
|
||||||
dynamicProperty.ApplyProperty<T>(dataModel, UserProps, CalcProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reorder(LayerModel selectedLayer, bool moveUp)
|
|
||||||
{
|
|
||||||
// Fix the sorting just in case
|
|
||||||
FixOrder();
|
|
||||||
|
|
||||||
int newOrder;
|
|
||||||
if (moveUp)
|
|
||||||
newOrder = selectedLayer.Order - 1;
|
|
||||||
else
|
else
|
||||||
newOrder = selectedLayer.Order + 1;
|
appliedProperties = Properties.GetAppliedProperties(dataModel, true);
|
||||||
|
|
||||||
var target = Children.FirstOrDefault(l => l.Order == newOrder);
|
// TODO: Mouse/headset animations
|
||||||
if (target == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.Order = selectedLayer.Order;
|
if (LayerType != LayerType.Folder)
|
||||||
selectedLayer.Order = newOrder;
|
return appliedProperties.Brush;
|
||||||
|
|
||||||
|
Brush res = null;
|
||||||
|
foreach (var layerModel in Children.OrderByDescending(l => l.Order))
|
||||||
|
{
|
||||||
|
var brush = layerModel.GenerateBrush<T>(type, dataModel, preview, updateAnimations);
|
||||||
|
if (brush != null)
|
||||||
|
res = brush;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FixOrder()
|
public void SetupProperties()
|
||||||
|
{
|
||||||
|
if ((LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif) &&
|
||||||
|
!(Properties is KeyboardPropertiesModel))
|
||||||
|
{
|
||||||
|
Properties = new KeyboardPropertiesModel
|
||||||
|
{
|
||||||
|
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
|
||||||
|
Animation = LayerAnimation.None,
|
||||||
|
Height = 1,
|
||||||
|
Width = 1,
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Opacity = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (LayerType == LayerType.Mouse && !(Properties is MousePropertiesModel))
|
||||||
|
Properties = new MousePropertiesModel
|
||||||
|
{
|
||||||
|
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor())
|
||||||
|
};
|
||||||
|
else if (LayerType == LayerType.Headset && !(Properties is HeadsetPropertiesModel))
|
||||||
|
Properties = new HeadsetPropertiesModel
|
||||||
|
{
|
||||||
|
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FixOrder()
|
||||||
{
|
{
|
||||||
Children.Sort(l => l.Order);
|
Children.Sort(l => l.Order);
|
||||||
for (var i = 0; i < Children.Count; i++)
|
for (var i = 0; i < Children.Count; i++)
|
||||||
Children[i].Order = i;
|
Children[i].Order = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether the layer meets the requirements to be drawn
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool MustDraw()
|
||||||
|
{
|
||||||
|
// If any of the parents are disabled, this layer must not be drawn
|
||||||
|
var parent = Parent;
|
||||||
|
while (parent != null)
|
||||||
|
{
|
||||||
|
if (!parent.Enabled)
|
||||||
|
return false;
|
||||||
|
parent = parent.Parent;
|
||||||
|
}
|
||||||
|
return Enabled && (LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<LayerModel> GetLayers()
|
||||||
|
{
|
||||||
|
var layers = new List<LayerModel>();
|
||||||
|
foreach (var layerModel in Children)
|
||||||
|
{
|
||||||
|
layers.Add(layerModel);
|
||||||
|
layers.AddRange(layerModel.GetLayers());
|
||||||
|
}
|
||||||
|
|
||||||
|
return layers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LayerModel CreateLayer()
|
||||||
|
{
|
||||||
|
return new LayerModel
|
||||||
|
{
|
||||||
|
Name = "New layer",
|
||||||
|
Enabled = true,
|
||||||
|
Order = -1,
|
||||||
|
LayerType = LayerType.Keyboard,
|
||||||
|
Properties = new KeyboardPropertiesModel
|
||||||
|
{
|
||||||
|
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
|
||||||
|
Animation = LayerAnimation.None,
|
||||||
|
Height = 1,
|
||||||
|
Width = 1,
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Opacity = 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InsertBefore(LayerModel source)
|
||||||
|
{
|
||||||
|
source.Order = Order;
|
||||||
|
Insert(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InsertAfter(LayerModel source)
|
||||||
|
{
|
||||||
|
source.Order = Order + 1;
|
||||||
|
Insert(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Insert(LayerModel source)
|
||||||
|
{
|
||||||
|
if (Parent != null)
|
||||||
|
{
|
||||||
|
foreach (var child in Parent.Children.OrderBy(c => c.Order))
|
||||||
|
{
|
||||||
|
if (child.Order >= source.Order)
|
||||||
|
child.Order++;
|
||||||
|
}
|
||||||
|
Parent.Children.Add(source);
|
||||||
|
}
|
||||||
|
else if (Profile != null)
|
||||||
|
{
|
||||||
|
foreach (var layer in Profile.Layers.OrderBy(l => l.Order))
|
||||||
|
{
|
||||||
|
if (layer.Order >= source.Order)
|
||||||
|
layer.Order++;
|
||||||
|
}
|
||||||
|
Profile.Layers.Add(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a flat list containing all layers that must be rendered on the keyboard,
|
||||||
|
/// the first mouse layer to be rendered and the first headset layer to be rendered
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The game data model to base the conditions on</typeparam>
|
||||||
|
/// <param name="dataModel">Instance of said game data model</param>
|
||||||
|
/// <param name="includeMice">Whether or not to include mice in the list</param>
|
||||||
|
/// <param name="includeHeadsets">Whether or not to include headsets in the list</param>
|
||||||
|
/// <param name="ignoreConditions"></param>
|
||||||
|
/// <returns>A flat list containing all layers that must be rendered</returns>
|
||||||
|
public List<LayerModel> GetRenderLayers<T>(IDataModel dataModel, bool includeMice, bool includeHeadsets,
|
||||||
|
bool ignoreConditions = false)
|
||||||
|
{
|
||||||
|
var layers = new List<LayerModel>();
|
||||||
|
foreach (var layerModel in Children.OrderByDescending(c => c.Order))
|
||||||
|
{
|
||||||
|
if (!layerModel.Enabled ||
|
||||||
|
!includeMice && layerModel.LayerType == LayerType.Mouse ||
|
||||||
|
!includeHeadsets && layerModel.LayerType == LayerType.Headset)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ignoreConditions)
|
||||||
|
{
|
||||||
|
if (!layerModel.ConditionsMet<T>(dataModel))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
layers.Add(layerModel);
|
||||||
|
layers.AddRange(layerModel.GetRenderLayers<T>(dataModel, includeMice, includeHeadsets, ignoreConditions));
|
||||||
|
}
|
||||||
|
|
||||||
|
return layers;
|
||||||
|
}
|
||||||
|
|
||||||
#region IChildItem<Parent> Members
|
#region IChildItem<Parent> Members
|
||||||
|
|
||||||
LayerModel IChildItem<LayerModel>.Parent
|
LayerModel IChildItem<LayerModel>.Parent
|
||||||
{
|
{
|
||||||
get { return ParentLayer; }
|
get { return Parent; }
|
||||||
set { ParentLayer = value; }
|
set { Parent = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileModel IChildItem<ProfileModel>.Parent
|
ProfileModel IChildItem<ProfileModel>.Parent
|
||||||
{
|
{
|
||||||
get { return ParentProfile; }
|
get { return Profile; }
|
||||||
set { ParentProfile = value; }
|
set { Profile = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Xml.Serialization;
|
|
||||||
|
|
||||||
namespace Artemis.Models.Profiles
|
|
||||||
{
|
|
||||||
[XmlInclude(typeof (SolidColorBrush))]
|
|
||||||
[XmlInclude(typeof (LinearGradientBrush))]
|
|
||||||
[XmlInclude(typeof (RadialGradientBrush))]
|
|
||||||
[XmlInclude(typeof (MatrixTransform))]
|
|
||||||
public class LayerPropertiesModel
|
|
||||||
{
|
|
||||||
public int X { get; set; }
|
|
||||||
public int Y { get; set; }
|
|
||||||
public int Width { get; set; }
|
|
||||||
public int Height { get; set; }
|
|
||||||
public double Opacity { get; set; }
|
|
||||||
public bool ContainedBrush { get; set; }
|
|
||||||
public LayerAnimation Animation { get; set; }
|
|
||||||
public double AnimationSpeed { get; set; }
|
|
||||||
public Brush Brush { get; set; }
|
|
||||||
|
|
||||||
public Rect GetRect(int scale = 4)
|
|
||||||
{
|
|
||||||
return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum LayerAnimation
|
|
||||||
{
|
|
||||||
[Description("None")] None,
|
|
||||||
[Description("Slide left")] SlideLeft,
|
|
||||||
[Description("Slide right")] SlideRight,
|
|
||||||
[Description("Slide up")] SlideUp,
|
|
||||||
[Description("Slide down")] SlideDown,
|
|
||||||
[Description("Grow")] Grow,
|
|
||||||
[Description("Pulse")] Pulse
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +1,17 @@
|
|||||||
using System.Drawing;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using System.Xml.Serialization;
|
||||||
using Artemis.Models.Interfaces;
|
using Artemis.Models.Interfaces;
|
||||||
|
using Artemis.Models.Profiles.Properties;
|
||||||
using Artemis.Utilities;
|
using Artemis.Utilities;
|
||||||
using Artemis.Utilities.ParentChild;
|
using Artemis.Utilities.ParentChild;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
using Color = System.Windows.Media.Color;
|
using Color = System.Windows.Media.Color;
|
||||||
|
using Point = System.Windows.Point;
|
||||||
|
using Size = System.Windows.Size;
|
||||||
|
|
||||||
namespace Artemis.Models.Profiles
|
namespace Artemis.Models.Profiles
|
||||||
{
|
{
|
||||||
@ -20,14 +26,17 @@ namespace Artemis.Models.Profiles
|
|||||||
public ChildItemCollection<ProfileModel, LayerModel> Layers { get; }
|
public ChildItemCollection<ProfileModel, LayerModel> Layers { get; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string KeyboardName { get; set; }
|
public bool IsDefault { get; set; }
|
||||||
|
public string KeyboardSlug { get; set; }
|
||||||
public string GameName { get; set; }
|
public string GameName { get; set; }
|
||||||
public DrawingVisual DrawingVisual { get; set; }
|
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public DrawingVisual DrawingVisual { get; set; }
|
||||||
|
|
||||||
protected bool Equals(ProfileModel other)
|
protected bool Equals(ProfileModel other)
|
||||||
{
|
{
|
||||||
return string.Equals(Name, other.Name) && string.Equals(KeyboardName, other.KeyboardName) &&
|
return string.Equals(Name, other.Name) &&
|
||||||
|
string.Equals(KeyboardSlug, other.KeyboardSlug) &&
|
||||||
string.Equals(GameName, other.GameName);
|
string.Equals(GameName, other.GameName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,61 +53,12 @@ namespace Artemis.Models.Profiles
|
|||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
var hashCode = Name?.GetHashCode() ?? 0;
|
var hashCode = Name?.GetHashCode() ?? 0;
|
||||||
hashCode = (hashCode*397) ^ (KeyboardName?.GetHashCode() ?? 0);
|
hashCode = (hashCode*397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
|
||||||
hashCode = (hashCode*397) ^ (GameName?.GetHashCode() ?? 0);
|
hashCode = (hashCode*397) ^ (GameName?.GetHashCode() ?? 0);
|
||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a new layer with default settings to the profile
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The newly added layer</returns>
|
|
||||||
public LayerModel AddLayer()
|
|
||||||
{
|
|
||||||
var layer = new LayerModel
|
|
||||||
{
|
|
||||||
Name = "New layer",
|
|
||||||
Enabled = true,
|
|
||||||
Order = -1,
|
|
||||||
LayerType = LayerType.Keyboard,
|
|
||||||
UserProps = new LayerPropertiesModel
|
|
||||||
{
|
|
||||||
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
|
|
||||||
Animation = LayerAnimation.None,
|
|
||||||
Height = 1,
|
|
||||||
Width = 1,
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Opacity = 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Layers.Add(layer);
|
|
||||||
FixOrder();
|
|
||||||
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reorder(LayerModel selectedLayer, bool moveUp)
|
|
||||||
{
|
|
||||||
// Fix the sorting just in case
|
|
||||||
FixOrder();
|
|
||||||
|
|
||||||
int newOrder;
|
|
||||||
if (moveUp)
|
|
||||||
newOrder = selectedLayer.Order - 1;
|
|
||||||
else
|
|
||||||
newOrder = selectedLayer.Order + 1;
|
|
||||||
|
|
||||||
var target = Layers.FirstOrDefault(l => l.Order == newOrder);
|
|
||||||
if (target == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.Order = selectedLayer.Order;
|
|
||||||
selectedLayer.Order = newOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FixOrder()
|
public void FixOrder()
|
||||||
{
|
{
|
||||||
Layers.Sort(l => l.Order);
|
Layers.Sort(l => l.Order);
|
||||||
@ -106,29 +66,156 @@ namespace Artemis.Models.Profiles
|
|||||||
Layers[i].Order = i;
|
Layers[i].Order = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap GenerateBitmap<T>(Rect keyboardRect, IGameDataModel gameDataModel, bool preview = false)
|
public Bitmap GenerateBitmap<T>(Rect keyboardRect, IDataModel dataModel, bool preview,
|
||||||
|
bool updateAnimations)
|
||||||
{
|
{
|
||||||
Bitmap bitmap = null;
|
var visual = new DrawingVisual();
|
||||||
DrawingVisual.Dispatcher.Invoke(delegate
|
using (var c = visual.RenderOpen())
|
||||||
{
|
{
|
||||||
var visual = new DrawingVisual();
|
// Setup the DrawingVisual's size
|
||||||
using (var c = visual.RenderOpen())
|
c.PushClip(new RectangleGeometry(keyboardRect));
|
||||||
|
c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
|
||||||
|
|
||||||
|
// Draw the layers
|
||||||
|
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
||||||
|
layerModel.Draw(dataModel, c, preview, updateAnimations);
|
||||||
|
|
||||||
|
// Remove the clip
|
||||||
|
c.Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Brush GenerateBrush<T>(IDataModel dataModel, LayerType type, bool preview, bool updateAnimations)
|
||||||
|
{
|
||||||
|
Brush result = null;
|
||||||
|
// Draw the layers
|
||||||
|
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
||||||
|
{
|
||||||
|
var generated = layerModel.GenerateBrush<T>(type, dataModel, preview, updateAnimations);
|
||||||
|
if (generated != null)
|
||||||
|
result = generated;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gives all the layers and their children in a flat list
|
||||||
|
/// </summary>
|
||||||
|
public List<LayerModel> GetLayers()
|
||||||
|
{
|
||||||
|
var layers = new List<LayerModel>();
|
||||||
|
foreach (var layerModel in Layers)
|
||||||
|
{
|
||||||
|
layers.Add(layerModel);
|
||||||
|
layers.AddRange(layerModel.GetLayers());
|
||||||
|
}
|
||||||
|
|
||||||
|
return layers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a flat list containing all layers that must be rendered on the keyboard,
|
||||||
|
/// the first mouse layer to be rendered and the first headset layer to be rendered
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The game data model to base the conditions on</typeparam>
|
||||||
|
/// <param name="dataModel">Instance of said game data model</param>
|
||||||
|
/// <param name="includeMice">Whether or not to include mice in the list</param>
|
||||||
|
/// <param name="includeHeadsets">Whether or not to include headsets in the list</param>
|
||||||
|
/// <param name="ignoreConditions"></param>
|
||||||
|
/// <returns>A flat list containing all layers that must be rendered</returns>
|
||||||
|
public List<LayerModel> GetRenderLayers<T>(IDataModel dataModel, bool includeMice, bool includeHeadsets,
|
||||||
|
bool ignoreConditions = false)
|
||||||
|
{
|
||||||
|
var layers = new List<LayerModel>();
|
||||||
|
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
||||||
|
{
|
||||||
|
if (!layerModel.Enabled ||
|
||||||
|
!includeMice && layerModel.LayerType == LayerType.Mouse ||
|
||||||
|
!includeHeadsets && layerModel.LayerType == LayerType.Headset)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ignoreConditions)
|
||||||
{
|
{
|
||||||
// Setup the DrawingVisual's size
|
if (!layerModel.ConditionsMet<T>(dataModel))
|
||||||
c.PushClip(new RectangleGeometry(keyboardRect));
|
continue;
|
||||||
c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
|
|
||||||
|
|
||||||
// Draw the layers
|
|
||||||
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
|
||||||
layerModel.Draw<T>(gameDataModel, c, preview);
|
|
||||||
|
|
||||||
// Remove the clip
|
|
||||||
c.Pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect);
|
layers.Add(layerModel);
|
||||||
});
|
layers.AddRange(layerModel.GetRenderLayers<T>(dataModel, includeMice, includeHeadsets, ignoreConditions));
|
||||||
return bitmap;
|
}
|
||||||
|
|
||||||
|
return layers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks at all the layers wthin the profile and makes sure they are within boundaries of the given rectangle
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="keyboardRectangle"></param>
|
||||||
|
public void FixBoundaries(Rect keyboardRectangle)
|
||||||
|
{
|
||||||
|
foreach (var layer in GetLayers())
|
||||||
|
{
|
||||||
|
if (layer.LayerType != LayerType.Keyboard && layer.LayerType != LayerType.KeyboardGif)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var props = (KeyboardPropertiesModel) layer.Properties;
|
||||||
|
var layerRect = new Rect(new Point(props.X, props.Y), new Size(props.Width, props.Height));
|
||||||
|
if (keyboardRectangle.Contains(layerRect))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
props.X = 0;
|
||||||
|
props.Y = 0;
|
||||||
|
layer.Properties = props;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a bitmap showing all the provided layers of type Keyboard and KeyboardGif
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="renderLayers">The layers to render</param>
|
||||||
|
/// <param name="dataModel">The data model to base the layer's properties on</param>
|
||||||
|
/// <param name="keyboardRect">A rectangle matching the current keyboard's size on a scale of 4, used for clipping</param>
|
||||||
|
/// <param name="preview">Indicates wheter the layer is drawn as a preview, ignoring dynamic properties</param>
|
||||||
|
/// <param name="updateAnimations">Wheter or not to update the layer's animations</param>
|
||||||
|
/// <returns>The generated bitmap</returns>
|
||||||
|
internal Bitmap GenerateBitmap(List<LayerModel> renderLayers, IDataModel dataModel, Rect keyboardRect,
|
||||||
|
bool preview,
|
||||||
|
bool updateAnimations)
|
||||||
|
{
|
||||||
|
var visual = new DrawingVisual();
|
||||||
|
using (var c = visual.RenderOpen())
|
||||||
|
{
|
||||||
|
// Setup the DrawingVisual's size
|
||||||
|
c.PushClip(new RectangleGeometry(keyboardRect));
|
||||||
|
c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
|
||||||
|
|
||||||
|
// Draw the layers
|
||||||
|
foreach (var layerModel in renderLayers
|
||||||
|
.Where(l => l.LayerType == LayerType.Keyboard ||
|
||||||
|
l.LayerType == LayerType.KeyboardGif))
|
||||||
|
{
|
||||||
|
layerModel.Draw(dataModel, c, preview, updateAnimations);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the clip
|
||||||
|
c.Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a brush out of the given layer, for usage with mice and headsets
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="layerModel">The layer to base the brush on</param>
|
||||||
|
/// <param name="dataModel">The game data model to base the layer's properties on</param>
|
||||||
|
/// <returns>The generated brush</returns>
|
||||||
|
public Brush GenerateBrush(LayerModel layerModel, IDataModel dataModel)
|
||||||
|
{
|
||||||
|
return layerModel?.Properties.GetAppliedProperties(dataModel).Brush;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
using Artemis.Utilities;
|
||||||
|
using static System.Decimal;
|
||||||
|
|
||||||
|
namespace Artemis.Models.Profiles.Properties
|
||||||
|
{
|
||||||
|
public class DynamicPropertiesModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Property this dynamic property applies on
|
||||||
|
/// </summary>
|
||||||
|
public string LayerProperty { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Property to base the percentage upon
|
||||||
|
/// </summary>
|
||||||
|
public string GameProperty { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Percentage source, the number that defines 100%
|
||||||
|
/// </summary>
|
||||||
|
public double PercentageSource { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Percentage source property, the property that defines 100%
|
||||||
|
/// </summary>
|
||||||
|
public string PercentageProperty { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Type of property
|
||||||
|
/// </summary>
|
||||||
|
public LayerPropertyType LayerPropertyType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extra options on top of the selected properties
|
||||||
|
/// </summary>
|
||||||
|
public LayerPropertyOptions LayerPropertyOptions { get; set; }
|
||||||
|
|
||||||
|
internal void ApplyProperty(IDataModel dataModel, ref AppliedProperties properties)
|
||||||
|
{
|
||||||
|
if (LayerPropertyType == LayerPropertyType.PercentageOf)
|
||||||
|
ApplyPercentageOf(dataModel, ref properties, PercentageSource);
|
||||||
|
if (LayerPropertyType == LayerPropertyType.PercentageOfProperty)
|
||||||
|
ApplyPercentageOfProperty(dataModel, ref properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyPercentageOf(IDataModel dataModel, ref AppliedProperties properties, double src)
|
||||||
|
{
|
||||||
|
if (GameProperty == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var gameProperty = dataModel.GetPropValue<int>(GameProperty);
|
||||||
|
var percentage = ToDouble(gameProperty)/src;
|
||||||
|
|
||||||
|
if (LayerProperty == "Width")
|
||||||
|
ApplyWidth(ref properties, percentage);
|
||||||
|
else if (LayerProperty == "Height")
|
||||||
|
ApplyHeight(ref properties, percentage);
|
||||||
|
else if (LayerProperty == "Opacity")
|
||||||
|
ApplyOpacity(ref properties, percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyWidth(ref AppliedProperties properties, double percentage)
|
||||||
|
{
|
||||||
|
var newWidth = percentage*properties.Width;
|
||||||
|
var difference = properties.Width - newWidth;
|
||||||
|
properties.Width = newWidth;
|
||||||
|
|
||||||
|
// Apply the right to left option
|
||||||
|
if (LayerPropertyOptions == LayerPropertyOptions.RightToLeft)
|
||||||
|
properties.X = properties.X + difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyHeight(ref AppliedProperties properties, double percentage)
|
||||||
|
{
|
||||||
|
var newHeight = percentage*properties.Height;
|
||||||
|
var difference = properties.Height - newHeight;
|
||||||
|
properties.Height = newHeight;
|
||||||
|
|
||||||
|
if (LayerPropertyOptions == LayerPropertyOptions.Downwards)
|
||||||
|
properties.Y = properties.Y + difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyOpacity(ref AppliedProperties properties, double percentage)
|
||||||
|
{
|
||||||
|
properties.Opacity = percentage*properties.Opacity;
|
||||||
|
if (properties.Opacity < 0.0)
|
||||||
|
properties.Opacity = 0.0;
|
||||||
|
if (properties.Opacity > 1.0)
|
||||||
|
properties.Opacity = 1.0;
|
||||||
|
|
||||||
|
// Apply the inverse/decrease option
|
||||||
|
if (LayerPropertyOptions == LayerPropertyOptions.Decrease)
|
||||||
|
properties.Opacity = 1.0 - properties.Opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyPercentageOfProperty(IDataModel dataModel, ref AppliedProperties properties)
|
||||||
|
{
|
||||||
|
var value = dataModel.GetPropValue<int>(PercentageProperty);
|
||||||
|
ApplyPercentageOf(dataModel, ref properties, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LayerPropertyType
|
||||||
|
{
|
||||||
|
[Description("% of")] PercentageOf,
|
||||||
|
[Description("% of property")] PercentageOfProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LayerPropertyOptions
|
||||||
|
{
|
||||||
|
[Description("Left to right")] LeftToRight,
|
||||||
|
[Description("Right to left")] RightToLeft,
|
||||||
|
[Description("Downwards")] Downwards,
|
||||||
|
[Description("Upwards")] Upwards,
|
||||||
|
[Description("Increase")] Increase,
|
||||||
|
[Description("Decrease")] Decrease
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Artemis.Models.Profiles.Properties
|
||||||
|
{
|
||||||
|
public class FolderPropertiesModel : LayerPropertiesModel
|
||||||
|
{
|
||||||
|
public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
|
||||||
|
{
|
||||||
|
return new AppliedProperties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Artemis.Models.Profiles.Properties
|
||||||
|
{
|
||||||
|
public class HeadsetPropertiesModel : LayerPropertiesModel
|
||||||
|
{
|
||||||
|
public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
|
||||||
|
{
|
||||||
|
return new AppliedProperties {Brush = Brush};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Artemis.Models.Profiles.Properties
|
||||||
|
{
|
||||||
|
public class KeyboardPropertiesModel : LayerPropertiesModel
|
||||||
|
{
|
||||||
|
public KeyboardPropertiesModel()
|
||||||
|
{
|
||||||
|
DynamicProperties = new List<DynamicPropertiesModel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double X { get; set; }
|
||||||
|
public double Y { get; set; }
|
||||||
|
public double Width { get; set; }
|
||||||
|
public double Height { get; set; }
|
||||||
|
public double Opacity { get; set; }
|
||||||
|
public bool Contain { get; set; }
|
||||||
|
public LayerAnimation Animation { get; set; }
|
||||||
|
public double AnimationSpeed { get; set; }
|
||||||
|
public string GifFile { get; set; }
|
||||||
|
public List<DynamicPropertiesModel> DynamicProperties { get; set; }
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public double AnimationProgress { get; set; }
|
||||||
|
|
||||||
|
public Rect GetRect(int scale = 4)
|
||||||
|
{
|
||||||
|
return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
|
||||||
|
{
|
||||||
|
var applied = new AppliedProperties
|
||||||
|
{
|
||||||
|
X = X,
|
||||||
|
Y = Y,
|
||||||
|
Width = Width,
|
||||||
|
Height = Height,
|
||||||
|
Opacity = Opacity,
|
||||||
|
Brush = Brush.CloneCurrentValue()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ignoreDynamic)
|
||||||
|
return applied;
|
||||||
|
|
||||||
|
foreach (var dynamicProperty in DynamicProperties)
|
||||||
|
dynamicProperty.ApplyProperty(dataModel, ref applied);
|
||||||
|
|
||||||
|
if (Math.Abs(applied.Opacity - 1) > 0.001)
|
||||||
|
{
|
||||||
|
applied.Brush = Brush.CloneCurrentValue();
|
||||||
|
applied.Brush.Opacity = applied.Opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return applied;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LayerAnimation
|
||||||
|
{
|
||||||
|
[Description("None")] None,
|
||||||
|
[Description("Slide left")] SlideLeft,
|
||||||
|
[Description("Slide right")] SlideRight,
|
||||||
|
[Description("Slide up")] SlideUp,
|
||||||
|
[Description("Slide down")] SlideDown,
|
||||||
|
[Description("Grow")] Grow,
|
||||||
|
[Description("Pulse")] Pulse
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Artemis.Models.Profiles.Properties
|
||||||
|
{
|
||||||
|
[XmlInclude(typeof(SolidColorBrush))]
|
||||||
|
[XmlInclude(typeof(LinearGradientBrush))]
|
||||||
|
[XmlInclude(typeof(RadialGradientBrush))]
|
||||||
|
[XmlInclude(typeof(MatrixTransform))]
|
||||||
|
[XmlInclude(typeof(KeyboardPropertiesModel))]
|
||||||
|
[XmlInclude(typeof(MousePropertiesModel))]
|
||||||
|
[XmlInclude(typeof(HeadsetPropertiesModel))]
|
||||||
|
[XmlInclude(typeof(FolderPropertiesModel))]
|
||||||
|
public abstract class LayerPropertiesModel
|
||||||
|
{
|
||||||
|
private Brush _brush;
|
||||||
|
|
||||||
|
protected LayerPropertiesModel()
|
||||||
|
{
|
||||||
|
Conditions = new List<LayerConditionModel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LayerConditionModel> Conditions { get; set; }
|
||||||
|
|
||||||
|
public Brush Brush
|
||||||
|
{
|
||||||
|
get { return _brush; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
_brush = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.IsFrozen)
|
||||||
|
{
|
||||||
|
_brush = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone the brush off of the UI thread and freeze it
|
||||||
|
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
|
||||||
|
cloned.Freeze();
|
||||||
|
_brush = cloned;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct AppliedProperties
|
||||||
|
{
|
||||||
|
public double X { get; set; }
|
||||||
|
public double Y { get; set; }
|
||||||
|
public double Width { get; set; }
|
||||||
|
public double Height { get; set; }
|
||||||
|
public double Opacity { get; set; }
|
||||||
|
public Brush Brush { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Artemis.Models.Profiles.Properties
|
||||||
|
{
|
||||||
|
public class MousePropertiesModel : LayerPropertiesModel
|
||||||
|
{
|
||||||
|
public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
|
||||||
|
{
|
||||||
|
return new AppliedProperties {Brush = Brush};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,14 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
using Artemis.Models;
|
using Artemis.Models;
|
||||||
|
using Artemis.Models.Profiles;
|
||||||
using Artemis.Utilities.Keyboard;
|
using Artemis.Utilities.Keyboard;
|
||||||
using Kaliko.ImageLibrary;
|
|
||||||
using Kaliko.ImageLibrary.Filters;
|
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.AmbientLightning
|
namespace Artemis.Modules.Effects.AmbientLightning
|
||||||
{
|
{
|
||||||
@ -21,7 +19,7 @@ namespace Artemis.Modules.Effects.AmbientLightning
|
|||||||
private KeyboardRectangle _topRect;
|
private KeyboardRectangle _topRect;
|
||||||
|
|
||||||
public AmbientLightningEffectModel(MainManager mainManager, AmbientLightningEffectSettings settings)
|
public AmbientLightningEffectModel(MainManager mainManager, AmbientLightningEffectSettings settings)
|
||||||
: base(mainManager)
|
: base(mainManager, null)
|
||||||
{
|
{
|
||||||
Name = "Ambient Lightning";
|
Name = "Ambient Lightning";
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
@ -49,9 +47,9 @@ namespace Artemis.Modules.Effects.AmbientLightning
|
|||||||
|
|
||||||
_colors = new List<Color>();
|
_colors = new List<Color>();
|
||||||
_screenCapturer = new ScreenCapture();
|
_screenCapturer = new ScreenCapture();
|
||||||
_topRect = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, 0, new List<Color>(),
|
_topRect = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0, 0, new List<Color>(),
|
||||||
LinearGradientMode.Horizontal) {Height = MainManager.KeyboardManager.ActiveKeyboard.Height*Scale/2};
|
LinearGradientMode.Horizontal) {Height = MainManager.DeviceManager.ActiveKeyboard.Height*Scale/2};
|
||||||
_botRect = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, 0, new List<Color>(),
|
_botRect = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0, 0, new List<Color>(),
|
||||||
LinearGradientMode.Horizontal);
|
LinearGradientMode.Horizontal);
|
||||||
|
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
@ -102,8 +100,8 @@ namespace Artemis.Modules.Effects.AmbientLightning
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Put the resulting colors in 6 rectangles, their size differs per keyboard
|
// Put the resulting colors in 6 rectangles, their size differs per keyboard
|
||||||
var rectWidth = MainManager.KeyboardManager.ActiveKeyboard.Width/3*Scale;
|
var rectWidth = MainManager.DeviceManager.ActiveKeyboard.Width/3*Scale;
|
||||||
var rectHeight = MainManager.KeyboardManager.ActiveKeyboard.Height/2*Scale;
|
var rectHeight = MainManager.DeviceManager.ActiveKeyboard.Height/2*Scale;
|
||||||
for (var row = 0; row < 2; row++)
|
for (var row = 0; row < 2; row++)
|
||||||
{
|
{
|
||||||
for (var column = 0; column < 3; column++)
|
for (var column = 0; column < 3; column++)
|
||||||
@ -114,25 +112,9 @@ namespace Artemis.Modules.Effects.AmbientLightning
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Bitmap GenerateBitmap()
|
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||||
{
|
{
|
||||||
var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(Scale);
|
return null;
|
||||||
using (var g = Graphics.FromImage(bitmap))
|
|
||||||
{
|
|
||||||
var i = 0;
|
|
||||||
foreach (var rectangle in _rectangles)
|
|
||||||
{
|
|
||||||
g.FillRectangle(new SolidBrush(_colors[i]), rectangle);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var test = new KalikoImage(bitmap);
|
|
||||||
test.ApplyFilter(new GaussianBlurFilter(8f));
|
|
||||||
var ms = new MemoryStream();
|
|
||||||
test.SaveBmp(ms);
|
|
||||||
ms.Position = 0;
|
|
||||||
return new Bitmap(ms);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,25 +5,17 @@ using Caliburn.Micro;
|
|||||||
|
|
||||||
namespace Artemis.Modules.Effects.AmbientLightning
|
namespace Artemis.Modules.Effects.AmbientLightning
|
||||||
{
|
{
|
||||||
internal class AmbientLightningEffectViewModel : EffectViewModel, IHandle<ActiveEffectChanged>
|
public sealed class AmbientLightningEffectViewModel : EffectViewModel, IHandle<ActiveEffectChanged>
|
||||||
{
|
{
|
||||||
public AmbientLightningEffectViewModel(MainManager mainManager)
|
public AmbientLightningEffectViewModel(MainManager main, IEventAggregator events)
|
||||||
|
: base(main, new AmbientLightningEffectModel(main, new AmbientLightningEffectSettings()))
|
||||||
{
|
{
|
||||||
// Subscribe to main model
|
DisplayName = "Ambient Lightning";
|
||||||
MainManager = mainManager;
|
|
||||||
MainManager.Events.Subscribe(this);
|
|
||||||
|
|
||||||
// Settings are loaded from file by class
|
events.Subscribe(this);
|
||||||
EffectSettings = new AmbientLightningEffectSettings();
|
|
||||||
|
|
||||||
// Create effect model and add it to MainManager
|
|
||||||
EffectModel = new AmbientLightningEffectModel(mainManager, (AmbientLightningEffectSettings) EffectSettings);
|
|
||||||
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static string Name => "Ambient Lightning";
|
|
||||||
|
|
||||||
public void Handle(ActiveEffectChanged message)
|
public void Handle(ActiveEffectChanged message)
|
||||||
{
|
{
|
||||||
NotifyOfPropertyChange(() => EffectEnabled);
|
NotifyOfPropertyChange(() => EffectEnabled);
|
||||||
|
|||||||
@ -18,10 +18,10 @@ namespace Artemis.Modules.Effects.AmbientLightning
|
|||||||
internal class ScreenCapture : IDisposable
|
internal class ScreenCapture : IDisposable
|
||||||
{
|
{
|
||||||
private readonly Device _device;
|
private readonly Device _device;
|
||||||
|
private readonly OutputDuplication _duplicatedOutput;
|
||||||
private readonly Factory1 _factory;
|
private readonly Factory1 _factory;
|
||||||
private readonly Texture2D _screenTexture;
|
private readonly Texture2D _screenTexture;
|
||||||
private DataStream _dataStream;
|
private DataStream _dataStream;
|
||||||
private readonly OutputDuplication _duplicatedOutput;
|
|
||||||
private Resource _screenResource;
|
private Resource _screenResource;
|
||||||
private Surface _screenSurface;
|
private Surface _screenSurface;
|
||||||
|
|
||||||
|
|||||||
@ -5,11 +5,13 @@ using System.Drawing.Drawing2D;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
using Artemis.Models;
|
using Artemis.Models;
|
||||||
|
using Artemis.Models.Profiles;
|
||||||
using Artemis.Modules.Effects.AudioVisualizer.Utilities;
|
using Artemis.Modules.Effects.AudioVisualizer.Utilities;
|
||||||
using Artemis.Utilities;
|
using Artemis.Utilities;
|
||||||
using Artemis.Utilities.Keyboard;
|
using Artemis.Utilities.Keyboard;
|
||||||
using NAudio.CoreAudioApi;
|
using NAudio.CoreAudioApi;
|
||||||
using NAudio.Wave;
|
using NAudio.Wave;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.AudioVisualizer
|
namespace Artemis.Modules.Effects.AudioVisualizer
|
||||||
{
|
{
|
||||||
@ -22,7 +24,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
|||||||
private int _sensitivity;
|
private int _sensitivity;
|
||||||
private IWaveIn _waveIn;
|
private IWaveIn _waveIn;
|
||||||
|
|
||||||
public AudioVisualizerModel(MainManager mainManager, AudioVisualizerSettings settings) : base(mainManager)
|
public AudioVisualizerModel(MainManager mainManager, AudioVisualizerSettings settings) : base(mainManager, null)
|
||||||
{
|
{
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
Name = "Audiovisualizer";
|
Name = "Audiovisualizer";
|
||||||
@ -49,6 +51,8 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
|||||||
_sampleAggregator.PerformFFT = false;
|
_sampleAggregator.PerformFFT = false;
|
||||||
_sampleAggregator.FftCalculated -= FftCalculated;
|
_sampleAggregator.FftCalculated -= FftCalculated;
|
||||||
|
|
||||||
|
if (_waveIn == null)
|
||||||
|
return;
|
||||||
_waveIn.StopRecording();
|
_waveIn.StopRecording();
|
||||||
_waveIn.DataAvailable -= OnDataAvailable;
|
_waveIn.DataAvailable -= OnDataAvailable;
|
||||||
_waveIn = null;
|
_waveIn = null;
|
||||||
@ -57,7 +61,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
|||||||
public override void Enable()
|
public override void Enable()
|
||||||
{
|
{
|
||||||
Initialized = false;
|
Initialized = false;
|
||||||
Lines = MainManager.KeyboardManager.ActiveKeyboard.Width;
|
Lines = MainManager.DeviceManager.ActiveKeyboard.Width;
|
||||||
|
|
||||||
// TODO: Device selection
|
// TODO: Device selection
|
||||||
SelectedDeviceId = new MMDeviceEnumerator()
|
SelectedDeviceId = new MMDeviceEnumerator()
|
||||||
@ -69,7 +73,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
|||||||
for (var i = 0; i < Lines; i++)
|
for (var i = 0; i < Lines; i++)
|
||||||
{
|
{
|
||||||
SoundRectangles.Add(new KeyboardRectangle(
|
SoundRectangles.Add(new KeyboardRectangle(
|
||||||
MainManager.KeyboardManager.ActiveKeyboard,
|
MainManager.DeviceManager.ActiveKeyboard,
|
||||||
0, 0, new List<Color>
|
0, 0, new List<Color>
|
||||||
{
|
{
|
||||||
ColorHelpers.ToDrawingColor(Settings.TopColor),
|
ColorHelpers.ToDrawingColor(Settings.TopColor),
|
||||||
@ -121,7 +125,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
|||||||
// Apply Sensitivity setting
|
// Apply Sensitivity setting
|
||||||
height = height*_sensitivity;
|
height = height*_sensitivity;
|
||||||
var keyboardHeight =
|
var keyboardHeight =
|
||||||
(int) Math.Round(MainManager.KeyboardManager.ActiveKeyboard.Height/100.00*height*Scale);
|
(int) Math.Round(MainManager.DeviceManager.ActiveKeyboard.Height/100.00*height*Scale);
|
||||||
if (keyboardHeight > SoundRectangles[i].Height)
|
if (keyboardHeight > SoundRectangles[i].Height)
|
||||||
SoundRectangles[i].Height = keyboardHeight;
|
SoundRectangles[i].Height = keyboardHeight;
|
||||||
else
|
else
|
||||||
@ -131,31 +135,12 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
|||||||
SoundRectangles[i].Width = Scale;
|
SoundRectangles[i].Width = Scale;
|
||||||
|
|
||||||
if (_fromBottom)
|
if (_fromBottom)
|
||||||
SoundRectangles[i].Y = MainManager.KeyboardManager.ActiveKeyboard.Height*Scale -
|
SoundRectangles[i].Y = MainManager.DeviceManager.ActiveKeyboard.Height*Scale -
|
||||||
SoundRectangles[i].Height;
|
SoundRectangles[i].Height;
|
||||||
}
|
}
|
||||||
_generating = false;
|
_generating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Bitmap GenerateBitmap()
|
|
||||||
{
|
|
||||||
if (SpectrumData == null || SoundRectangles == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Lock the _spectrumData array while busy with it
|
|
||||||
_generating = true;
|
|
||||||
|
|
||||||
var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(Scale);
|
|
||||||
using (var g = Graphics.FromImage(bitmap))
|
|
||||||
{
|
|
||||||
foreach (var soundRectangle in SoundRectangles)
|
|
||||||
soundRectangle.Draw(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
_generating = false;
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDataAvailable(object sender, WaveInEventArgs e)
|
private void OnDataAvailable(object sender, WaveInEventArgs e)
|
||||||
{
|
{
|
||||||
var buffer = e.Buffer;
|
var buffer = e.Buffer;
|
||||||
@ -199,5 +184,33 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
|||||||
SpectrumData.Add((byte) y);
|
SpectrumData.Add((byte) y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Render(out Bitmap keyboard, out Brush mouse, out Brush headset, bool renderMice,
|
||||||
|
bool renderHeadsets)
|
||||||
|
{
|
||||||
|
keyboard = null;
|
||||||
|
mouse = null;
|
||||||
|
headset = null;
|
||||||
|
|
||||||
|
if (SpectrumData == null || SoundRectangles == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Lock the _spectrumData array while busy with it
|
||||||
|
_generating = true;
|
||||||
|
|
||||||
|
keyboard = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(Scale);
|
||||||
|
using (var g = Graphics.FromImage(keyboard))
|
||||||
|
{
|
||||||
|
foreach (var soundRectangle in SoundRectangles)
|
||||||
|
soundRectangle.Draw(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
_generating = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,7 +22,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>
|
||||||
@ -80,38 +79,28 @@
|
|||||||
Grid.Row="4" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes"
|
Grid.Row="4" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes"
|
||||||
OffLabel="No" Margin="0,0,-5,0" Width="114" />
|
OffLabel="No" Margin="0,0,-5,0" Width="114" />
|
||||||
|
|
||||||
<!-- Bars amount -->
|
|
||||||
<TextBlock Grid.Row="5" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,8">
|
|
||||||
Bars amount (less bars means thicker bars)
|
|
||||||
</TextBlock>
|
|
||||||
<Slider x:Name="Bars" Grid.Row="5" Grid.Column="1" VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Right" Width="110" TickPlacement="BottomRight" TickFrequency="1"
|
|
||||||
Value="{Binding Path=EffectSettings.Bars, Mode=TwoWay}" Minimum="2" Maximum="21"
|
|
||||||
SmallChange="1" IsSnapToTickEnabled="True" />
|
|
||||||
|
|
||||||
<!-- Sensitivity -->
|
<!-- Sensitivity -->
|
||||||
<TextBlock Grid.Row="6" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
<TextBlock Grid.Row="5" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||||
Height="16" Margin="0,8">
|
Height="16" Margin="0,8">
|
||||||
Volume sensitivity multiplier
|
Volume sensitivity multiplier
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<Slider x:Name="Sensitivity" Grid.Row="6" Grid.Column="1" VerticalAlignment="Center"
|
<Slider x:Name="Sensitivity" Grid.Row="5" Grid.Column="1" VerticalAlignment="Center"
|
||||||
HorizontalAlignment="Right" Width="110" TickPlacement="BottomRight" TickFrequency="1"
|
HorizontalAlignment="Right" Width="110" TickPlacement="BottomRight" TickFrequency="1"
|
||||||
Value="{Binding Path=EffectSettings.Sensitivity, Mode=TwoWay}" Minimum="1" Maximum="10"
|
Value="{Binding Path=EffectSettings.Sensitivity, Mode=TwoWay}" Minimum="1" Maximum="10"
|
||||||
SmallChange="1" IsSnapToTickEnabled="True" />
|
SmallChange="1" IsSnapToTickEnabled="True" />
|
||||||
|
|
||||||
<!-- Fade speed -->
|
<!-- Fade speed -->
|
||||||
<TextBlock Grid.Row="7" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
<TextBlock Grid.Row="6" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||||
Height="16" Margin="0,8">
|
Height="16" Margin="0,8">
|
||||||
Bar fade-out speed
|
Bar fade-out speed
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<Slider x:Name="FadeSpeed" Grid.Row="7" Grid.Column="1" VerticalAlignment="Center"
|
<Slider x:Name="FadeSpeed" Grid.Row="6" Grid.Column="1" VerticalAlignment="Center"
|
||||||
HorizontalAlignment="Right" Width="110" TickPlacement="BottomRight" TickFrequency="1"
|
HorizontalAlignment="Right" Width="110" TickPlacement="BottomRight" TickFrequency="1"
|
||||||
Value="{Binding Path=EffectSettings.FadeSpeed, Mode=TwoWay}" Minimum="1" Maximum="3"
|
Value="{Binding Path=EffectSettings.FadeSpeed, Mode=TwoWay}" Minimum="1" Maximum="3"
|
||||||
SmallChange="1" IsSnapToTickEnabled="True" />
|
SmallChange="1" IsSnapToTickEnabled="True" />
|
||||||
|
|
||||||
<!-- Buttons -->
|
<!-- Buttons -->
|
||||||
<StackPanel Grid.Column="0" Grid.Row="8" Orientation="Horizontal" VerticalAlignment="Bottom">
|
<StackPanel Grid.Column="0" Grid.Row="7" 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"
|
||||||
|
|||||||
@ -5,24 +5,18 @@ using Caliburn.Micro;
|
|||||||
|
|
||||||
namespace Artemis.Modules.Effects.AudioVisualizer
|
namespace Artemis.Modules.Effects.AudioVisualizer
|
||||||
{
|
{
|
||||||
public class AudioVisualizerViewModel : EffectViewModel, IHandle<ActiveEffectChanged>
|
public sealed class AudioVisualizerViewModel : EffectViewModel, IHandle<ActiveEffectChanged>
|
||||||
{
|
{
|
||||||
public AudioVisualizerViewModel(MainManager mainManager)
|
public AudioVisualizerViewModel(MainManager main, IEventAggregator events)
|
||||||
|
: base(main, new AudioVisualizerModel(main, new AudioVisualizerSettings()))
|
||||||
{
|
{
|
||||||
// Subscribe to main model
|
DisplayName = "Audio Visualization";
|
||||||
MainManager = mainManager;
|
events.Subscribe(this);
|
||||||
MainManager.Events.Subscribe(this);
|
|
||||||
|
|
||||||
// Settings are loaded from file by class
|
|
||||||
EffectSettings = new AudioVisualizerSettings();
|
|
||||||
|
|
||||||
// Create effect model and add it to MainManager
|
|
||||||
EffectModel = new AudioVisualizerModel(mainManager, (AudioVisualizerSettings) EffectSettings);
|
|
||||||
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
||||||
|
EffectSettings = ((AudioVisualizerModel) EffectModel).Settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Name => "Audio Visualizer";
|
|
||||||
|
|
||||||
public void Handle(ActiveEffectChanged message)
|
public void Handle(ActiveEffectChanged message)
|
||||||
{
|
{
|
||||||
NotifyOfPropertyChange(() => EffectEnabled);
|
NotifyOfPropertyChange(() => EffectEnabled);
|
||||||
|
|||||||
@ -1,72 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using Artemis.Managers;
|
|
||||||
using Artemis.Models;
|
|
||||||
using Artemis.Utilities.Keyboard;
|
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.Debug
|
|
||||||
{
|
|
||||||
// TODO: Remove
|
|
||||||
internal class DebugEffectModel : EffectModel
|
|
||||||
{
|
|
||||||
public DebugEffectModel(MainManager mainManager, DebugEffectSettings settings) : base(mainManager)
|
|
||||||
{
|
|
||||||
Name = "Debug Effect";
|
|
||||||
Settings = settings;
|
|
||||||
Scale = 4;
|
|
||||||
Initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Scale { get; set; }
|
|
||||||
|
|
||||||
public DebugEffectSettings Settings { get; set; }
|
|
||||||
|
|
||||||
public KeyboardRectangle KeyboardRectangle { get; set; }
|
|
||||||
|
|
||||||
public override void Dispose()
|
|
||||||
{
|
|
||||||
Initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Enable()
|
|
||||||
{
|
|
||||||
Initialized = false;
|
|
||||||
|
|
||||||
KeyboardRectangle = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, 0, new List<Color>
|
|
||||||
{
|
|
||||||
Color.Red,
|
|
||||||
Color.OrangeRed,
|
|
||||||
Color.Yellow,
|
|
||||||
Color.Green,
|
|
||||||
Color.Blue,
|
|
||||||
Color.Purple,
|
|
||||||
Color.DeepPink
|
|
||||||
}, LinearGradientMode.Horizontal);
|
|
||||||
|
|
||||||
Initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update()
|
|
||||||
{
|
|
||||||
KeyboardRectangle.Height = Settings.Height;
|
|
||||||
KeyboardRectangle.Width = Settings.Width;
|
|
||||||
KeyboardRectangle.GradientMode = Settings.Type;
|
|
||||||
KeyboardRectangle.Rotate = Settings.Rotate;
|
|
||||||
KeyboardRectangle.Scale = Settings.Scale;
|
|
||||||
Scale = Settings.Scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Bitmap GenerateBitmap()
|
|
||||||
{
|
|
||||||
var bitmap = new Bitmap(21*Scale, 6*Scale);
|
|
||||||
|
|
||||||
using (var g = Graphics.FromImage(bitmap))
|
|
||||||
{
|
|
||||||
g.Clear(Color.Transparent);
|
|
||||||
KeyboardRectangle.Draw(g);
|
|
||||||
}
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
using System.Drawing.Drawing2D;
|
|
||||||
using Artemis.Models;
|
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.Debug
|
|
||||||
{
|
|
||||||
internal class DebugEffectSettings : EffectSettings
|
|
||||||
{
|
|
||||||
public DebugEffectSettings()
|
|
||||||
{
|
|
||||||
Load();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Width { get; set; }
|
|
||||||
public int Height { get; set; }
|
|
||||||
public bool Rotate { get; set; }
|
|
||||||
public int Scale { get; set; }
|
|
||||||
public LinearGradientMode Type { get; set; }
|
|
||||||
|
|
||||||
public sealed override void Load()
|
|
||||||
{
|
|
||||||
ToDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed override void Save()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed override void ToDefault()
|
|
||||||
{
|
|
||||||
Width = 84;
|
|
||||||
Height = 24;
|
|
||||||
Scale = 4;
|
|
||||||
Type = LinearGradientMode.Horizontal;
|
|
||||||
Rotate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
<UserControl x:Class="Artemis.Modules.Effects.Debug.DebugEffectView"
|
|
||||||
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"
|
|
||||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="476.986" d:DesignWidth="538.772">
|
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
|
||||||
<Grid Margin="15, 5, 15, 5">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto" />
|
|
||||||
<ColumnDefinition />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="*" />
|
|
||||||
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
|
||||||
<Label FontSize="20" MaxWidth="500" HorizontalAlignment="Left">
|
|
||||||
<Label.Content>
|
|
||||||
<AccessText TextWrapping="Wrap"
|
|
||||||
Text="A few debugging options, also lets you see what is being sent to the keyboard" />
|
|
||||||
</Label.Content>
|
|
||||||
</Label>
|
|
||||||
<StackPanel Orientation="Horizontal" 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"
|
|
||||||
Style="{DynamicResource MetroCircleToggleButtonStyle}"
|
|
||||||
cal:Message.Attach="[Event Click] = [Action ToggleEffect]"
|
|
||||||
ToolTip="Note: You can't enable an effect when Artemis is disabled"
|
|
||||||
ToolTipService.ShowOnDisabled="True" />
|
|
||||||
</StackPanel>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- Direction -->
|
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,8">
|
|
||||||
Color gradient direction
|
|
||||||
</TextBlock>
|
|
||||||
<ComboBox Grid.Row="1" Grid.Column="1" Width="110" HorizontalAlignment="Right" VerticalAlignment="Center"
|
|
||||||
x:Name="RectangleTypes" />
|
|
||||||
|
|
||||||
<!-- Width -->
|
|
||||||
<TextBlock Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,8">
|
|
||||||
Debug-rectangle width
|
|
||||||
</TextBlock>
|
|
||||||
<Slider x:Name="Width" Grid.Row="2" Grid.Column="1" VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Right" Width="110" TickPlacement="None" TickFrequency="1"
|
|
||||||
Value="{Binding Path=EffectSettings.Width, Mode=TwoWay}" Minimum="0" Maximum="84"
|
|
||||||
SmallChange="1" IsSnapToTickEnabled="True" />
|
|
||||||
|
|
||||||
<!-- Height -->
|
|
||||||
<TextBlock Grid.Row="3" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,8">
|
|
||||||
Debug-rectangle height
|
|
||||||
</TextBlock>
|
|
||||||
<Slider x:Name="Height" Grid.Row="3" Grid.Column="1" VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Right" Width="110" TickPlacement="None" TickFrequency="1"
|
|
||||||
Value="{Binding Path=EffectSettings.Height, Mode=TwoWay}" Minimum="0" Maximum="24"
|
|
||||||
SmallChange="1" IsSnapToTickEnabled="True" />
|
|
||||||
|
|
||||||
<!-- Scale -->
|
|
||||||
<TextBlock Grid.Row="4" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,8">
|
|
||||||
Debug-rectangle scale (higher means more fluent)
|
|
||||||
</TextBlock>
|
|
||||||
<Slider x:Name="Scale" Grid.Row="4" Grid.Column="1" VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Right" Width="110" TickPlacement="BottomRight" TickFrequency="1"
|
|
||||||
Value="{Binding Path=EffectSettings.Scale, Mode=TwoWay}" Minimum="1" Maximum="4"
|
|
||||||
SmallChange="1" IsSnapToTickEnabled="True" />
|
|
||||||
|
|
||||||
<!-- Color rotation -->
|
|
||||||
<TextBlock Grid.Row="5" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,9,0,10">
|
|
||||||
Rotate colors on debug-rectangle
|
|
||||||
</TextBlock>
|
|
||||||
<controls:ToggleSwitch IsChecked="{Binding Path=EffectSettings.Rotate, Mode=TwoWay}"
|
|
||||||
Grid.Row="5" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes"
|
|
||||||
OffLabel="No"
|
|
||||||
Margin="0,0,-5,0" Width="114" />
|
|
||||||
|
|
||||||
<!-- Preview panel -->
|
|
||||||
<StackPanel Grid.Row="6" Grid.Column="0" HorizontalAlignment="Left" Margin="0,25,0,0">
|
|
||||||
<TextBlock>
|
|
||||||
<InlineUIContainer>
|
|
||||||
<GroupBox Header="Preview" Margin="0" Height="70" Width="118">
|
|
||||||
<Image Source="{Binding ImageSource}"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Stretch="Fill" />
|
|
||||||
</GroupBox>
|
|
||||||
</InlineUIContainer>
|
|
||||||
</TextBlock>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- Buttons -->
|
|
||||||
<StackPanel Grid.Column="0" Grid.Row="8" 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>
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.Debug
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for DebugEffectView.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class DebugEffectView : UserControl
|
|
||||||
{
|
|
||||||
public DebugEffectView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using System.IO;
|
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
using Artemis.Events;
|
|
||||||
using Artemis.Managers;
|
|
||||||
using Artemis.ViewModels.Abstract;
|
|
||||||
using Caliburn.Micro;
|
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.Debug
|
|
||||||
{
|
|
||||||
internal class DebugEffectViewModel : EffectViewModel, IHandle<ChangeBitmap>, IHandle<ActiveEffectChanged>
|
|
||||||
{
|
|
||||||
private ImageSource _imageSource;
|
|
||||||
private string _selectedRectangleType;
|
|
||||||
|
|
||||||
public DebugEffectViewModel(MainManager mainManager)
|
|
||||||
{
|
|
||||||
// Subscribe to main model
|
|
||||||
MainManager = mainManager;
|
|
||||||
MainManager.Events.Subscribe(this);
|
|
||||||
|
|
||||||
// Settings are loaded from file by class
|
|
||||||
EffectSettings = new DebugEffectSettings();
|
|
||||||
|
|
||||||
// Create effect model and add it to MainManager
|
|
||||||
EffectModel = new DebugEffectModel(mainManager, (DebugEffectSettings) EffectSettings);
|
|
||||||
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static string Name => "Debug Effect";
|
|
||||||
|
|
||||||
public BindableCollection<string> RectangleTypes
|
|
||||||
=> new BindableCollection<string>(Enum.GetNames(typeof (LinearGradientMode)));
|
|
||||||
|
|
||||||
public string SelectedRectangleType
|
|
||||||
{
|
|
||||||
get { return _selectedRectangleType; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == _selectedRectangleType) return;
|
|
||||||
_selectedRectangleType = value;
|
|
||||||
NotifyOfPropertyChange(() => SelectedRectangleType);
|
|
||||||
|
|
||||||
((DebugEffectSettings) EffectSettings).Type =
|
|
||||||
(LinearGradientMode) Enum.Parse(typeof (LinearGradientMode), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImageSource ImageSource
|
|
||||||
{
|
|
||||||
get { return _imageSource; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_imageSource = value;
|
|
||||||
NotifyOfPropertyChange(() => ImageSource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(ActiveEffectChanged message)
|
|
||||||
{
|
|
||||||
NotifyOfPropertyChange(() => EffectEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(ChangeBitmap message)
|
|
||||||
{
|
|
||||||
using (var memory = new MemoryStream())
|
|
||||||
{
|
|
||||||
message.Bitmap.Save(memory, ImageFormat.Png);
|
|
||||||
memory.Position = 0;
|
|
||||||
|
|
||||||
var bitmapImage = new BitmapImage();
|
|
||||||
bitmapImage.BeginInit();
|
|
||||||
bitmapImage.StreamSource = memory;
|
|
||||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
|
||||||
bitmapImage.EndInit();
|
|
||||||
|
|
||||||
ImageSource = bitmapImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,27 +1,24 @@
|
|||||||
using System.Drawing;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
using Artemis.Models;
|
using Artemis.Models;
|
||||||
using Artemis.Models.Interfaces;
|
using Artemis.Models.Interfaces;
|
||||||
using Artemis.Models.Profiles;
|
using Artemis.Models.Profiles;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.ProfilePreview
|
namespace Artemis.Modules.Effects.ProfilePreview
|
||||||
{
|
{
|
||||||
public class ProfilePreviewModel : EffectModel
|
public class ProfilePreviewModel : EffectModel
|
||||||
{
|
{
|
||||||
private readonly ProfilePreviewDataModel _previewDataModel;
|
public ProfilePreviewModel(MainManager mainManager) : base(mainManager, new ProfilePreviewDataModel())
|
||||||
|
|
||||||
public ProfilePreviewModel(MainManager mainManager) : base(mainManager)
|
|
||||||
{
|
{
|
||||||
Name = "Profile Preview";
|
Name = "Profile Preview";
|
||||||
_previewDataModel = new ProfilePreviewDataModel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileModel SelectedProfile { get; set; }
|
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
Initialized = false;
|
Initialized = false;
|
||||||
SelectedProfile = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Enable()
|
public override void Enable()
|
||||||
@ -31,32 +28,38 @@ namespace Artemis.Modules.Effects.ProfilePreview
|
|||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
if (SelectedProfile == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var layerModel in SelectedProfile.Layers)
|
|
||||||
layerModel.Update<ProfilePreviewDataModel>(_previewDataModel, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Bitmap GenerateBitmap()
|
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||||
{
|
{
|
||||||
var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(4);
|
return Profile.GetRenderLayers<ProfilePreviewDataModel>(DataModel, renderMice, renderHeadsets, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (SelectedProfile == null)
|
public override void Render(out Bitmap keyboard, out Brush mouse, out Brush headset, bool renderMice,
|
||||||
return bitmap;
|
bool renderHeadsets)
|
||||||
|
{
|
||||||
|
keyboard = null;
|
||||||
|
mouse = null;
|
||||||
|
headset = null;
|
||||||
|
|
||||||
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(4);
|
if (Profile == null || DataModel == null)
|
||||||
var image = SelectedProfile.GenerateBitmap<ProfilePreviewDataModel>(keyboardRect, _previewDataModel, true);
|
return;
|
||||||
|
|
||||||
// Draw on top of everything else
|
// Get all enabled layers who's conditions are met
|
||||||
using (var g = Graphics.FromImage(bitmap))
|
var renderLayers = GetRenderLayers(renderMice, renderHeadsets);
|
||||||
g.DrawImage(image, 0, 0);
|
|
||||||
|
|
||||||
return bitmap;
|
// Render the keyboard layer-by-layer
|
||||||
|
keyboard = Profile?.GenerateBitmap(renderLayers, DataModel,
|
||||||
|
MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(4), true, true);
|
||||||
|
// Render the first enabled mouse (will default to null if renderMice was false)
|
||||||
|
mouse = Profile?.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Mouse), DataModel);
|
||||||
|
// Render the first enabled headset (will default to null if renderHeadsets was false)
|
||||||
|
headset = Profile?.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Headset),
|
||||||
|
DataModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProfilePreviewDataModel : IGameDataModel
|
public class ProfilePreviewDataModel : IDataModel
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,40 +0,0 @@
|
|||||||
using System.Drawing;
|
|
||||||
using Artemis.Managers;
|
|
||||||
using Artemis.Models;
|
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.TypeHole
|
|
||||||
{
|
|
||||||
public class TypeHoleModel : EffectModel
|
|
||||||
{
|
|
||||||
public TypeHoleModel(MainManager mainManager) : base(mainManager)
|
|
||||||
{
|
|
||||||
Name = "TypeHole";
|
|
||||||
Initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Dispose()
|
|
||||||
{
|
|
||||||
Initialized = false;
|
|
||||||
|
|
||||||
// Disable logic
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Enable()
|
|
||||||
{
|
|
||||||
Initialized = false;
|
|
||||||
|
|
||||||
// Enable logic
|
|
||||||
|
|
||||||
Initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Bitmap GenerateBitmap()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.TypeHole
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for TypeHoleView.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class TypeHoleView : UserControl
|
|
||||||
{
|
|
||||||
public TypeHoleView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
using Artemis.Events;
|
|
||||||
using Artemis.Managers;
|
|
||||||
using Artemis.ViewModels.Abstract;
|
|
||||||
using Caliburn.Micro;
|
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.TypeHole
|
|
||||||
{
|
|
||||||
public class TypeHoleViewModel : EffectViewModel, IHandle<ActiveEffectChanged>
|
|
||||||
{
|
|
||||||
public TypeHoleViewModel(MainManager mainManager)
|
|
||||||
{
|
|
||||||
// Subscribe to main model
|
|
||||||
MainManager = mainManager;
|
|
||||||
MainManager.Events.Subscribe(this);
|
|
||||||
|
|
||||||
// Create effect model and add it to MainManager
|
|
||||||
EffectModel = new TypeHoleModel(mainManager);
|
|
||||||
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Name => "Type Holes (NYI)";
|
|
||||||
|
|
||||||
public void Handle(ActiveEffectChanged message)
|
|
||||||
{
|
|
||||||
NotifyOfPropertyChange(() => EffectEnabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,11 +3,13 @@ using System.Drawing;
|
|||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Artemis.KeyboardProviders.Corsair;
|
using Artemis.DeviceProviders.Corsair;
|
||||||
using Artemis.KeyboardProviders.Logitech.Utilities;
|
using Artemis.DeviceProviders.Logitech.Utilities;
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
using Artemis.Models;
|
using Artemis.Models;
|
||||||
|
using Artemis.Models.Profiles;
|
||||||
using Artemis.Utilities;
|
using Artemis.Utilities;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
|
|
||||||
namespace Artemis.Modules.Effects.TypeWave
|
namespace Artemis.Modules.Effects.TypeWave
|
||||||
{
|
{
|
||||||
@ -16,7 +18,7 @@ namespace Artemis.Modules.Effects.TypeWave
|
|||||||
private readonly List<Wave> _waves;
|
private readonly List<Wave> _waves;
|
||||||
private Color _randomColor;
|
private Color _randomColor;
|
||||||
|
|
||||||
public TypeWaveModel(MainManager mainManager, TypeWaveSettings settings) : base(mainManager)
|
public TypeWaveModel(MainManager mainManager, TypeWaveSettings settings) : base(mainManager, null)
|
||||||
{
|
{
|
||||||
Name = "TypeWave";
|
Name = "TypeWave";
|
||||||
_waves = new List<Wave>();
|
_waves = new List<Wave>();
|
||||||
@ -91,13 +93,23 @@ namespace Artemis.Modules.Effects.TypeWave
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Bitmap GenerateBitmap()
|
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||||
{
|
{
|
||||||
if (_waves.Count == 0)
|
return null;
|
||||||
return null;
|
}
|
||||||
|
|
||||||
var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(Scale);
|
public override void Render(out Bitmap keyboard, out Brush mouse, out Brush headset, bool renderMice,
|
||||||
using (var g = Graphics.FromImage(bitmap))
|
bool renderHeadsets)
|
||||||
|
{
|
||||||
|
keyboard = null;
|
||||||
|
mouse = null;
|
||||||
|
headset = null;
|
||||||
|
|
||||||
|
if (_waves.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
keyboard = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(Scale);
|
||||||
|
using (var g = Graphics.FromImage(keyboard))
|
||||||
{
|
{
|
||||||
g.Clear(Color.Transparent);
|
g.Clear(Color.Transparent);
|
||||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
@ -113,7 +125,7 @@ namespace Artemis.Modules.Effects.TypeWave
|
|||||||
_waves[i].Size, _waves[i].Size);
|
_waves[i].Size, _waves[i].Size);
|
||||||
|
|
||||||
Color fillColor;
|
Color fillColor;
|
||||||
if (MainManager.KeyboardManager.ActiveKeyboard is CorsairRGB)
|
if (MainManager.DeviceManager.ActiveKeyboard is CorsairRGB)
|
||||||
fillColor = Color.Black;
|
fillColor = Color.Black;
|
||||||
else
|
else
|
||||||
fillColor = Color.Transparent;
|
fillColor = Color.Transparent;
|
||||||
@ -132,7 +144,6 @@ namespace Artemis.Modules.Effects.TypeWave
|
|||||||
_waves[i].Point.Y - _waves[i].Size/2, _waves[i].Size, _waves[i].Size);
|
_waves[i].Point.Y - _waves[i].Size/2, _waves[i].Size, _waves[i].Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bitmap;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,24 +5,18 @@ using Caliburn.Micro;
|
|||||||
|
|
||||||
namespace Artemis.Modules.Effects.TypeWave
|
namespace Artemis.Modules.Effects.TypeWave
|
||||||
{
|
{
|
||||||
public class TypeWaveViewModel : EffectViewModel, IHandle<ActiveEffectChanged>
|
public sealed class TypeWaveViewModel : EffectViewModel, IHandle<ActiveEffectChanged>
|
||||||
{
|
{
|
||||||
public TypeWaveViewModel(MainManager mainManager)
|
public TypeWaveViewModel(MainManager main, IEventAggregator events)
|
||||||
|
: base(main, new TypeWaveModel(main, new TypeWaveSettings()))
|
||||||
{
|
{
|
||||||
// Subscribe to main model
|
DisplayName = "Type Waves";
|
||||||
MainManager = mainManager;
|
events.Subscribe(this);
|
||||||
MainManager.Events.Subscribe(this);
|
|
||||||
|
|
||||||
// Settings are loaded from file by class
|
|
||||||
EffectSettings = new TypeWaveSettings();
|
|
||||||
|
|
||||||
// Create effect model and add it to MainManager
|
|
||||||
EffectModel = new TypeWaveModel(mainManager, (TypeWaveSettings) EffectSettings);
|
|
||||||
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
||||||
|
EffectSettings = ((TypeWaveModel) EffectModel).Settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Name => "Type Waves";
|
|
||||||
|
|
||||||
public void Handle(ActiveEffectChanged message)
|
public void Handle(ActiveEffectChanged message)
|
||||||
{
|
{
|
||||||
NotifyOfPropertyChange(() => EffectEnabled);
|
NotifyOfPropertyChange(() => EffectEnabled);
|
||||||
|
|||||||
38
Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfile.Designer.cs
generated
Normal file
38
Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfile.Designer.cs
generated
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Effects.WindowsProfile {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
|
||||||
|
internal sealed partial class WindowsProfile : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static WindowsProfile defaultInstance = ((WindowsProfile)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new WindowsProfile())));
|
||||||
|
|
||||||
|
public static WindowsProfile Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("Demo (Duplicate to keep changes)")]
|
||||||
|
public string LastProfile {
|
||||||
|
get {
|
||||||
|
return ((string)(this["LastProfile"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["LastProfile"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
|
||||||
|
GeneratedClassNamespace="Artemis.Modules.Effects.WindowsProfile" GeneratedClassName="WindowsProfile">
|
||||||
|
<Profiles />
|
||||||
|
<Settings>
|
||||||
|
<Setting Name="LastProfile" Type="System.String" Scope="User">
|
||||||
|
<Value Profile="(Default)">Demo (Duplicate to keep changes)</Value>
|
||||||
|
</Setting>
|
||||||
|
</Settings>
|
||||||
|
</SettingsFile>
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Effects.WindowsProfile
|
||||||
|
{
|
||||||
|
public class WindowsProfileDataModel : IDataModel
|
||||||
|
{
|
||||||
|
public WindowsProfileDataModel()
|
||||||
|
{
|
||||||
|
Spotify = new Spotify();
|
||||||
|
Cpu = new CpuDataModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CpuDataModel Cpu { get; set; }
|
||||||
|
public Spotify Spotify { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CpuDataModel
|
||||||
|
{
|
||||||
|
public int Core1Usage { get; set; }
|
||||||
|
public int Core2Usage { get; set; }
|
||||||
|
public int Core3Usage { get; set; }
|
||||||
|
public int Core4Usage { get; set; }
|
||||||
|
public int Core5Usage { get; set; }
|
||||||
|
public int Core6Usage { get; set; }
|
||||||
|
public int Core7Usage { get; set; }
|
||||||
|
public int Core8Usage { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Spotify
|
||||||
|
{
|
||||||
|
public bool Running { get; set; }
|
||||||
|
public string Artist { get; set; }
|
||||||
|
public string SongName { get; set; }
|
||||||
|
public int SongPercentCompleted { get; set; }
|
||||||
|
public int SpotifyVolume { get; set; }
|
||||||
|
public string Album { get; set; }
|
||||||
|
public bool Repeat { get; set; }
|
||||||
|
public bool Shuffle { get; set; }
|
||||||
|
public bool Playing { get; set; }
|
||||||
|
public int SongLength { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,169 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Artemis.Managers;
|
||||||
|
using Artemis.Models;
|
||||||
|
using Artemis.Models.Profiles;
|
||||||
|
using SpotifyAPI.Local;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Effects.WindowsProfile
|
||||||
|
{
|
||||||
|
public class WindowsProfileModel : EffectModel
|
||||||
|
{
|
||||||
|
private List<PerformanceCounter> _cores;
|
||||||
|
private int _cpuFrames;
|
||||||
|
private SpotifyLocalAPI _spotify;
|
||||||
|
private bool _spotifySetupBusy;
|
||||||
|
|
||||||
|
public WindowsProfileModel(MainManager mainManager, WindowsProfileSettings settings)
|
||||||
|
: base(mainManager, new WindowsProfileDataModel())
|
||||||
|
{
|
||||||
|
Name = "WindowsProfile";
|
||||||
|
Settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WindowsProfileSettings Settings { get; set; }
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Enable()
|
||||||
|
{
|
||||||
|
SetupCpu();
|
||||||
|
SetupSpotify();
|
||||||
|
|
||||||
|
Initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
var dataModel = (WindowsProfileDataModel) DataModel;
|
||||||
|
UpdateCpu(dataModel);
|
||||||
|
UpdateSpotify(dataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region CPU
|
||||||
|
|
||||||
|
private void SetupCpu()
|
||||||
|
{
|
||||||
|
_cores = GetPerformanceCounters();
|
||||||
|
var coreCount = _cores.Count;
|
||||||
|
while (coreCount < 8)
|
||||||
|
{
|
||||||
|
_cores.Add(null);
|
||||||
|
coreCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCpu(WindowsProfileDataModel dataModel)
|
||||||
|
{
|
||||||
|
// CPU is only updated every 15 frames, the performance counter gives 0 if updated too often
|
||||||
|
_cpuFrames++;
|
||||||
|
if (_cpuFrames < 16)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_cpuFrames = 0;
|
||||||
|
|
||||||
|
// Update cores, not ideal but data models don't support lists.
|
||||||
|
if (_cores[0] != null)
|
||||||
|
dataModel.Cpu.Core1Usage = (int) _cores[0].NextValue();
|
||||||
|
if (_cores[1] != null)
|
||||||
|
dataModel.Cpu.Core2Usage = (int) _cores[1].NextValue();
|
||||||
|
if (_cores[2] != null)
|
||||||
|
dataModel.Cpu.Core3Usage = (int) _cores[2].NextValue();
|
||||||
|
if (_cores[3] != null)
|
||||||
|
dataModel.Cpu.Core4Usage = (int) _cores[3].NextValue();
|
||||||
|
if (_cores[4] != null)
|
||||||
|
dataModel.Cpu.Core5Usage = (int) _cores[4].NextValue();
|
||||||
|
if (_cores[5] != null)
|
||||||
|
dataModel.Cpu.Core6Usage = (int) _cores[5].NextValue();
|
||||||
|
if (_cores[6] != null)
|
||||||
|
dataModel.Cpu.Core7Usage = (int) _cores[6].NextValue();
|
||||||
|
if (_cores[7] != null)
|
||||||
|
dataModel.Cpu.Core8Usage = (int) _cores[7].NextValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||||
|
{
|
||||||
|
return Profile.GetRenderLayers<WindowsProfileDataModel>(DataModel, renderMice, renderHeadsets, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<PerformanceCounter> GetPerformanceCounters()
|
||||||
|
{
|
||||||
|
var performanceCounters = new List<PerformanceCounter>();
|
||||||
|
var procCount = Environment.ProcessorCount;
|
||||||
|
for (var i = 0; i < procCount; i++)
|
||||||
|
{
|
||||||
|
var pc = new PerformanceCounter("Processor", "% Processor Time", i.ToString());
|
||||||
|
performanceCounters.Add(pc);
|
||||||
|
}
|
||||||
|
return performanceCounters;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Spotify
|
||||||
|
|
||||||
|
public void SetupSpotify()
|
||||||
|
{
|
||||||
|
if (_spotifySetupBusy)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_spotifySetupBusy = true;
|
||||||
|
_spotify = new SpotifyLocalAPI {ListenForEvents = true};
|
||||||
|
_spotify.OnPlayStateChange += UpdateSpotifyPlayState;
|
||||||
|
_spotify.OnTrackChange += UpdateSpotifyTrack;
|
||||||
|
_spotify.OnTrackTimeChange += UpdateSpotifyTrackTime;
|
||||||
|
|
||||||
|
// Connecting can sometimes use a little bit more conviction
|
||||||
|
Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
var tryCount = 0;
|
||||||
|
while (tryCount <= 10)
|
||||||
|
{
|
||||||
|
tryCount++;
|
||||||
|
var connected = _spotify.Connect();
|
||||||
|
if (connected)
|
||||||
|
break;
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
}
|
||||||
|
_spotifySetupBusy = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSpotify(WindowsProfileDataModel dataModel)
|
||||||
|
{
|
||||||
|
if (!dataModel.Spotify.Running && SpotifyLocalAPI.IsSpotifyRunning())
|
||||||
|
SetupSpotify();
|
||||||
|
|
||||||
|
dataModel.Spotify.Running = SpotifyLocalAPI.IsSpotifyRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSpotifyPlayState(object sender, PlayStateEventArgs e)
|
||||||
|
{
|
||||||
|
((WindowsProfileDataModel) DataModel).Spotify.Playing = e.Playing;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSpotifyTrack(object sender, TrackChangeEventArgs e)
|
||||||
|
{
|
||||||
|
var dataModel = (WindowsProfileDataModel) DataModel;
|
||||||
|
dataModel.Spotify.Artist = e.NewTrack.ArtistResource?.Name;
|
||||||
|
dataModel.Spotify.SongName = e.NewTrack.TrackResource?.Name;
|
||||||
|
dataModel.Spotify.Album = e.NewTrack.AlbumResource?.Name;
|
||||||
|
dataModel.Spotify.SongLength = e.NewTrack.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSpotifyTrackTime(object sender, TrackTimeChangeEventArgs e)
|
||||||
|
{
|
||||||
|
var dataModel = (WindowsProfileDataModel) DataModel;
|
||||||
|
if (dataModel.Spotify.SongLength > 0)
|
||||||
|
dataModel.Spotify.SongPercentCompleted = (int) (e.TrackTime/dataModel.Spotify.SongLength*100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
using Artemis.Models;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Effects.WindowsProfile
|
||||||
|
{
|
||||||
|
public class WindowsProfileSettings : GameSettings
|
||||||
|
{
|
||||||
|
public WindowsProfileSettings()
|
||||||
|
{
|
||||||
|
Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed override void Load()
|
||||||
|
{
|
||||||
|
LastProfile = WindowsProfile.Default.LastProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed override void Save()
|
||||||
|
{
|
||||||
|
WindowsProfile.Default.LastProfile = LastProfile;
|
||||||
|
|
||||||
|
WindowsProfile.Default.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed override void ToDefault()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,49 +1,56 @@
|
|||||||
<UserControl x:Class="Artemis.Modules.Effects.TypeHole.TypeHoleView"
|
<UserControl x:Class="Artemis.Modules.Effects.WindowsProfile.WindowsProfileView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||||
xmlns:cal="http://www.caliburnproject.org"
|
xmlns:cal="http://www.caliburnproject.org"
|
||||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="407.812" d:DesignWidth="671.484"
|
d:DesignHeight="476.986" d:DesignWidth="538.772">
|
||||||
cal:Bind.AtDesignTime="True">
|
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||||
<Grid Margin="15, 5, 15, 5">
|
<Grid Margin="15, 5, 15, 5">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="320" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition />
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
|
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||||
<Label FontSize="20" HorizontalAlignment="Left">
|
<Label FontSize="20" HorizontalAlignment="Left">
|
||||||
<Label.Content>
|
<Label.Content>
|
||||||
<AccessText TextWrapping="Wrap"
|
<AccessText TextWrapping="Wrap"
|
||||||
Text="Creates holes in the keyboard's lightning as you press keys." />
|
Text="Allows you to create layers shown while not gaming" />
|
||||||
</Label.Content>
|
</Label.Content>
|
||||||
</Label>
|
</Label>
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||||
<Label Content="Enable effect" Margin="0 3 0 0" 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"
|
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
|
||||||
Style="{DynamicResource MetroCircleToggleButtonStyle}"
|
Style="{DynamicResource MetroCircleToggleButtonStyle}"
|
||||||
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
|
cal:Message.Attach="[Event Click] = [Action ToggleEffect]"
|
||||||
<Popup PlacementTarget="{Binding ElementName=EffectEnabled}"
|
ToolTip="Note: You can't enable an effect when Artemis is disabled" />
|
||||||
IsOpen="{Binding Path=ShowDisabledPopup, Mode=TwoWay}" Placement="Left" VerticalOffset="-10"
|
|
||||||
PopupAnimation="Fade" StaysOpen="False">
|
|
||||||
<Border Margin="1">
|
|
||||||
<TextBlock Background="{DynamicResource AccentColorBrush}"
|
|
||||||
Foreground="{DynamicResource IdealForegroundColorBrush}"
|
|
||||||
Text="You can't enable an effect when Artemis is disabled" Padding="4" />
|
|
||||||
</Border>
|
|
||||||
</Popup>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Profile editor -->
|
||||||
|
<ContentControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-30,0" />
|
||||||
|
|
||||||
|
<!-- Buttons -->
|
||||||
|
<StackPanel Grid.Column="0" Grid.Row="9" 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>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Effects.WindowsProfile
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for RocketLeagueView.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class WindowsProfileView : UserControl
|
||||||
|
{
|
||||||
|
public WindowsProfileView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Artemis.Events;
|
||||||
|
using Artemis.InjectionFactories;
|
||||||
|
using Artemis.Managers;
|
||||||
|
using Artemis.Modules.Effects.ProfilePreview;
|
||||||
|
using Artemis.ViewModels.Abstract;
|
||||||
|
using Artemis.ViewModels.Profiles;
|
||||||
|
using Caliburn.Micro;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Effects.WindowsProfile
|
||||||
|
{
|
||||||
|
// TODO: This effect is a hybrid between a regular effect and a game, may want to clean this up
|
||||||
|
public sealed class WindowsProfileViewModel : EffectViewModel, IHandle<ActiveEffectChanged>
|
||||||
|
{
|
||||||
|
public WindowsProfileViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory,
|
||||||
|
ProfilePreviewModel profilePreviewModel)
|
||||||
|
: base(main, new WindowsProfileModel(main, new WindowsProfileSettings()))
|
||||||
|
{
|
||||||
|
DisplayName = "Windows Profile";
|
||||||
|
PFactory = pFactory;
|
||||||
|
ProfilePreviewModel = profilePreviewModel;
|
||||||
|
EffectSettings = ((WindowsProfileModel) EffectModel).Settings;
|
||||||
|
ProfileEditor = PFactory.CreateProfileEditorVm(events, main, (WindowsProfileModel) EffectModel,
|
||||||
|
((WindowsProfileSettings) EffectSettings).LastProfile);
|
||||||
|
ProfilePreviewModel.Profile = ProfileEditor.SelectedProfile;
|
||||||
|
|
||||||
|
events.Subscribe(this);
|
||||||
|
ProfileEditor.PropertyChanged += ProfileUpdater;
|
||||||
|
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileEditorViewModel ProfileEditor { get; set; }
|
||||||
|
|
||||||
|
public IProfileEditorVmFactory PFactory { get; set; }
|
||||||
|
public ProfilePreviewModel ProfilePreviewModel { get; set; }
|
||||||
|
|
||||||
|
public void Handle(ActiveEffectChanged message)
|
||||||
|
{
|
||||||
|
NotifyOfPropertyChange(() => EffectEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProfileUpdater(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.PropertyName != "SelectedProfile" && IsActive)
|
||||||
|
return;
|
||||||
|
EffectModel.Profile = ProfileEditor.SelectedProfile;
|
||||||
|
ProfilePreviewModel.Profile = ProfileEditor.SelectedProfile;
|
||||||
|
|
||||||
|
if (e.PropertyName != "SelectedProfile" || !ProfileEditor.ProfileViewModel.Activated ||
|
||||||
|
ProfileEditor.ProfileViewModel.SelectedProfile == null)
|
||||||
|
return;
|
||||||
|
((WindowsProfileSettings) EffectSettings).LastProfile = ProfileEditor.ProfileViewModel.SelectedProfile.Name;
|
||||||
|
EffectSettings.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnActivate()
|
||||||
|
{
|
||||||
|
base.OnActivate();
|
||||||
|
ProfileEditor.ProfileViewModel.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDeactivate(bool close)
|
||||||
|
{
|
||||||
|
base.OnDeactivate(close);
|
||||||
|
ProfileEditor.ProfileViewModel.Deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -130,5 +130,17 @@ namespace Artemis.Modules.Games.CounterStrike {
|
|||||||
this["LowHpEnabled"] = value;
|
this["LowHpEnabled"] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("Default")]
|
||||||
|
public string LastProfile {
|
||||||
|
get {
|
||||||
|
return ((string)(this["LastProfile"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["LastProfile"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,9 @@
|
|||||||
<Setting Name="Enabled" Type="System.Boolean" Scope="User">
|
<Setting Name="Enabled" Type="System.Boolean" Scope="User">
|
||||||
<Value Profile="(Default)">True</Value>
|
<Value Profile="(Default)">True</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
<Setting Name="LastProfile" Type="System.String" Scope="User">
|
||||||
|
<Value Profile="(Default)">Default</Value>
|
||||||
|
</Setting>
|
||||||
<Setting Name="GameDirectory" Type="System.String" Scope="User">
|
<Setting Name="GameDirectory" Type="System.String" Scope="User">
|
||||||
<Value Profile="(Default)" />
|
<Value Profile="(Default)" />
|
||||||
</Setting>
|
</Setting>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Artemis.Modules.Games.CounterStrike
|
namespace Artemis.Modules.Games.CounterStrike
|
||||||
{
|
{
|
||||||
public class CounterStrikeDataModel : IGameDataModel
|
public class CounterStrikeDataModel : IDataModel
|
||||||
{
|
{
|
||||||
public Provider provider { get; set; }
|
public Provider provider { get; set; }
|
||||||
public Map map { get; set; }
|
public Map map { get; set; }
|
||||||
|
|||||||
@ -1,14 +1,18 @@
|
|||||||
using System.Drawing;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
using Artemis.Models;
|
using Artemis.Models;
|
||||||
|
using Artemis.Models.Profiles;
|
||||||
using Artemis.Utilities.GameState;
|
using Artemis.Utilities.GameState;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Ninject.Extensions.Logging;
|
||||||
|
|
||||||
namespace Artemis.Modules.Games.CounterStrike
|
namespace Artemis.Modules.Games.CounterStrike
|
||||||
{
|
{
|
||||||
public class CounterStrikeModel : GameModel
|
public class CounterStrikeModel : GameModel
|
||||||
{
|
{
|
||||||
public CounterStrikeModel(MainManager mainManager, CounterStrikeSettings settings) : base(mainManager, settings)
|
public CounterStrikeModel(MainManager mainManager, CounterStrikeSettings settings)
|
||||||
|
: base(mainManager, settings, new CounterStrikeDataModel())
|
||||||
{
|
{
|
||||||
Name = "CounterStrike";
|
Name = "CounterStrike";
|
||||||
ProcessName = "csgo";
|
ProcessName = "csgo";
|
||||||
@ -17,6 +21,7 @@ namespace Artemis.Modules.Games.CounterStrike
|
|||||||
Initialized = false;
|
Initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
public int Scale { get; set; }
|
public int Scale { get; set; }
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
@ -29,7 +34,6 @@ namespace Artemis.Modules.Games.CounterStrike
|
|||||||
{
|
{
|
||||||
Initialized = false;
|
Initialized = false;
|
||||||
|
|
||||||
GameDataModel = new CounterStrikeDataModel();
|
|
||||||
MainManager.GameStateWebServer.GameDataReceived += HandleGameData;
|
MainManager.GameStateWebServer.GameDataReceived += HandleGameData;
|
||||||
|
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
@ -37,20 +41,7 @@ namespace Artemis.Modules.Games.CounterStrike
|
|||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
if (Profile == null || GameDataModel == null)
|
// TODO: Set up active weapon in the datamodel
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var layerModel in Profile.Layers)
|
|
||||||
layerModel.Update<CounterStrikeDataModel>(GameDataModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Bitmap GenerateBitmap()
|
|
||||||
{
|
|
||||||
if (Profile == null || GameDataModel == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale);
|
|
||||||
return Profile.GenerateBitmap<CounterStrikeDataModel>(keyboardRect, GameDataModel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleGameData(object sender, GameDataReceivedEventArgs e)
|
public void HandleGameData(object sender, GameDataReceivedEventArgs e)
|
||||||
@ -62,7 +53,20 @@ namespace Artemis.Modules.Games.CounterStrike
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Parse the JSON
|
// Parse the JSON
|
||||||
GameDataModel = JsonConvert.DeserializeObject<CounterStrikeDataModel>(jsonString);
|
try
|
||||||
|
{
|
||||||
|
DataModel = JsonConvert.DeserializeObject<CounterStrikeDataModel>(jsonString);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger?.Error(ex, "Failed to deserialize CS:GO JSON");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||||
|
{
|
||||||
|
return Profile.GetRenderLayers<CounterStrikeDataModel>(DataModel, renderMice, renderHeadsets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -24,6 +24,7 @@ namespace Artemis.Modules.Games.CounterStrike
|
|||||||
public sealed override void Load()
|
public sealed override void Load()
|
||||||
{
|
{
|
||||||
Enabled = CounterStrike.Default.Enabled;
|
Enabled = CounterStrike.Default.Enabled;
|
||||||
|
LastProfile = CounterStrike.Default.LastProfile;
|
||||||
GameDirectory = CounterStrike.Default.GameDirectory;
|
GameDirectory = CounterStrike.Default.GameDirectory;
|
||||||
|
|
||||||
AmmoEnabled = CounterStrike.Default.AmmoEnabled;
|
AmmoEnabled = CounterStrike.Default.AmmoEnabled;
|
||||||
|
|||||||
@ -3,25 +3,23 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
|
||||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
|
||||||
xmlns:cal="http://www.caliburnproject.org"
|
xmlns:cal="http://www.caliburnproject.org"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="476.986" d:DesignWidth="538.772">
|
d:DesignHeight="476.986" d:DesignWidth="538.772">
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||||
<Grid Margin="15, 5, 15, 5">
|
<Grid Margin="15,5,5,5">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="80" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||||
<Label FontSize="20" HorizontalAlignment="Left">
|
<Label FontSize="20" HorizontalAlignment="Left">
|
||||||
<Label.Content>
|
<Label.Content>
|
||||||
@ -41,20 +39,20 @@
|
|||||||
<StackPanel Grid.Row="1"
|
<StackPanel Grid.Row="1"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Grid.ColumnSpan="2" Margin="0,0,1,0">
|
Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||||
<Label FontSize="16" Content="CS:GO Directory" FontFamily="Segoe UI Semibold" Foreground="#535353"
|
|
||||||
Width="130" HorizontalAlignment="Left" />
|
<Label FontSize="20" HorizontalAlignment="Left" Content="CS:GO Directory" />
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextBox x:Name="GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
|
<TextBox x:Name="GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
|
||||||
Text="{Binding Path=GameSettings.GameDirectory, Mode=TwoWay}"
|
Text="{Binding Path=GameSettings.GameDirectory, Mode=TwoWay}"
|
||||||
cal:Message.Attach="[Event LostFocus] = [Action PlaceConfigFile]" />
|
cal:Message.Attach="[Event LostFocus] = [Action PlaceConfigFile]" />
|
||||||
<Button x:Name="BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
|
<Button x:Name="BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
|
||||||
HorizontalAlignment="Right" Width="25"
|
HorizontalAlignment="Right" Width="25"
|
||||||
Style="{DynamicResource SquareButtonStyle}" Height="25" />
|
Style="{DynamicResource SquareButtonStyle}" Height="26" Margin="0,-2,0,0" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Profile editor -->
|
<!-- Profile editor -->
|
||||||
<ContentControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-30,0" />
|
<ContentControl Grid.Row="3" 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="4" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||||
|
|||||||
@ -1,23 +1,38 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Artemis.InjectionFactories;
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
using Artemis.Properties;
|
using Artemis.Properties;
|
||||||
|
using Artemis.Utilities;
|
||||||
using Artemis.ViewModels.Abstract;
|
using Artemis.ViewModels.Abstract;
|
||||||
|
using Caliburn.Micro;
|
||||||
|
|
||||||
namespace Artemis.Modules.Games.CounterStrike
|
namespace Artemis.Modules.Games.CounterStrike
|
||||||
{
|
{
|
||||||
public class CounterStrikeViewModel : GameViewModel<CounterStrikeDataModel>
|
public sealed class CounterStrikeViewModel : GameViewModel
|
||||||
{
|
{
|
||||||
public CounterStrikeViewModel(MainManager mainManager)
|
public CounterStrikeViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||||
: base(mainManager, new CounterStrikeModel(mainManager, new CounterStrikeSettings()))
|
: base(main, new CounterStrikeModel(main, new CounterStrikeSettings()), events, pFactory)
|
||||||
{
|
{
|
||||||
// Create effect model and add it to MainManager
|
DisplayName = "CS:GO";
|
||||||
MainManager.EffectManager.EffectModels.Add(GameModel);
|
MainManager.EffectManager.EffectModels.Add(GameModel);
|
||||||
|
|
||||||
|
FindGameDir();
|
||||||
PlaceConfigFile();
|
PlaceConfigFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Name => "CS:GO";
|
public void FindGameDir()
|
||||||
public string Content => "Counter-Strike: GO Content";
|
{
|
||||||
|
var gameSettings = (CounterStrikeSettings) GameSettings;
|
||||||
|
// If already propertly set up, don't do anything
|
||||||
|
if (gameSettings.GameDirectory != null && File.Exists(gameSettings.GameDirectory + "csgo.exe") &&
|
||||||
|
File.Exists(gameSettings.GameDirectory + "/csgo/cfg/gamestate_integration_artemis.cfg"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var dir = GeneralHelpers.FindSteamGame(@"\Counter-Strike Global Offensive\csgo.exe");
|
||||||
|
gameSettings.GameDirectory = dir ?? string.Empty;
|
||||||
|
gameSettings.Save();
|
||||||
|
}
|
||||||
|
|
||||||
public void BrowseDirectory()
|
public void BrowseDirectory()
|
||||||
{
|
{
|
||||||
@ -26,7 +41,7 @@ namespace Artemis.Modules.Games.CounterStrike
|
|||||||
if (result != DialogResult.OK)
|
if (result != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
((CounterStrikeSettings) GameSettings).GameDirectory = dialog.SelectedPath;
|
((CounterStrikeSettings) GameSettings).GameDirectory = Path.GetDirectoryName(dialog.SelectedPath);
|
||||||
NotifyOfPropertyChange(() => GameSettings);
|
NotifyOfPropertyChange(() => GameSettings);
|
||||||
|
|
||||||
GameSettings.Save();
|
GameSettings.Save();
|
||||||
@ -37,22 +52,22 @@ namespace Artemis.Modules.Games.CounterStrike
|
|||||||
{
|
{
|
||||||
if (((CounterStrikeSettings) GameSettings).GameDirectory == string.Empty)
|
if (((CounterStrikeSettings) GameSettings).GameDirectory == string.Empty)
|
||||||
return;
|
return;
|
||||||
if (Directory.Exists(((CounterStrikeSettings) GameSettings).GameDirectory + "/csgo/cfg"))
|
|
||||||
|
var path = ((CounterStrikeSettings) GameSettings).GameDirectory;
|
||||||
|
if (Directory.Exists(path + "/csgo/cfg"))
|
||||||
{
|
{
|
||||||
var cfgFile = Resources.csgoGamestateConfiguration.Replace("{{port}}",
|
var cfgFile = Resources.csgoGamestateConfiguration.Replace("{{port}}",
|
||||||
MainManager.GameStateWebServer.Port.ToString());
|
MainManager.GameStateWebServer.Port.ToString());
|
||||||
File.WriteAllText(
|
File.WriteAllText(path + "/csgo/cfg/gamestate_integration_artemis.cfg", cfgFile);
|
||||||
((CounterStrikeSettings) GameSettings).GameDirectory + "/csgo/cfg/gamestate_integration_artemis.cfg",
|
|
||||||
cfgFile);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainManager.DialogService.ShowErrorMessageBox("Please select a valid CS:GO directory\n\n" +
|
DialogService.ShowErrorMessageBox("Please select a valid CS:GO directory\n\n" +
|
||||||
@"By default CS:GO is in \SteamApps\common\Counter-Strike Global Offensive");
|
@"By default CS:GO is in \SteamApps\common\Counter-Strike Global Offensive");
|
||||||
|
|
||||||
((CounterStrikeSettings) GameSettings).GameDirectory = string.Empty;
|
((CounterStrikeSettings) GameSettings).GameDirectory = string.Empty;
|
||||||
NotifyOfPropertyChange(() => GameSettings);
|
NotifyOfPropertyChange(() => GameSettings);
|
||||||
|
|
||||||
GameSettings.Save();
|
GameSettings.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,6 +35,18 @@ namespace Artemis.Modules.Games.Dota2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("Default")]
|
||||||
|
public string LastProfile {
|
||||||
|
get {
|
||||||
|
return ((string)(this["LastProfile"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["LastProfile"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||||
|
|||||||
@ -7,6 +7,9 @@
|
|||||||
<Setting Name="Enabled" Type="System.Boolean" Scope="User">
|
<Setting Name="Enabled" Type="System.Boolean" Scope="User">
|
||||||
<Value Profile="(Default)">True</Value>
|
<Value Profile="(Default)">True</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
<Setting Name="LastProfile" Type="System.String" Scope="User">
|
||||||
|
<Value Profile="(Default)">Default</Value>
|
||||||
|
</Setting>
|
||||||
<Setting Name="GameDirectory" Type="System.String" Scope="User">
|
<Setting Name="GameDirectory" Type="System.String" Scope="User">
|
||||||
<Value Profile="(Default)" />
|
<Value Profile="(Default)" />
|
||||||
</Setting>
|
</Setting>
|
||||||
|
|||||||
@ -1,228 +1,228 @@
|
|||||||
namespace Artemis.Modules.Games.Dota2
|
using Artemis.Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Games.Dota2
|
||||||
{
|
{
|
||||||
public class Dota2DataModel
|
public class Dota2DataModel : IDataModel
|
||||||
{
|
{
|
||||||
public class Rootobject
|
public Provider provider { get; set; }
|
||||||
{
|
public Map map { get; set; }
|
||||||
public Provider provider { get; set; }
|
public Player player { get; set; }
|
||||||
public Map map { get; set; }
|
public Hero hero { get; set; }
|
||||||
public Player player { get; set; }
|
public Abilities abilities { get; set; }
|
||||||
public Hero hero { get; set; }
|
public Items items { get; set; }
|
||||||
public Abilities abilities { get; set; }
|
public Previously previously { get; set; }
|
||||||
public Items items { get; set; }
|
}
|
||||||
public Previously previously { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Provider
|
public class Provider
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public int appid { get; set; }
|
public int appid { get; set; }
|
||||||
public int version { get; set; }
|
public int version { get; set; }
|
||||||
public int timestamp { get; set; }
|
public int timestamp { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Map
|
public class Map
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public int dayCyclePercentage;
|
||||||
public long matchid { get; set; }
|
public string name { get; set; }
|
||||||
public int game_time { get; set; }
|
public long matchid { get; set; }
|
||||||
public int clock_time { get; set; }
|
public int game_time { get; set; }
|
||||||
public bool daytime { get; set; }
|
public int clock_time { get; set; }
|
||||||
public bool nightstalker_night { get; set; }
|
public bool daytime { get; set; }
|
||||||
public string game_state { get; set; }
|
public bool nightstalker_night { get; set; }
|
||||||
public string win_team { get; set; }
|
public string game_state { get; set; }
|
||||||
public string customgamename { get; set; }
|
public string win_team { get; set; }
|
||||||
public int ward_purchase_cooldown { get; set; }
|
public string customgamename { get; set; }
|
||||||
}
|
public int ward_purchase_cooldown { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class Player
|
public class Player
|
||||||
{
|
{
|
||||||
public string steamid { get; set; }
|
public string steamid { get; set; }
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public string activity { get; set; }
|
public string activity { get; set; }
|
||||||
public int kills { get; set; }
|
public int kills { get; set; }
|
||||||
public int deaths { get; set; }
|
public int deaths { get; set; }
|
||||||
public int assists { get; set; }
|
public int assists { get; set; }
|
||||||
public int last_hits { get; set; }
|
public int last_hits { get; set; }
|
||||||
public int denies { get; set; }
|
public int denies { get; set; }
|
||||||
public int kill_streak { get; set; }
|
public int kill_streak { get; set; }
|
||||||
public string team_name { get; set; }
|
public string team_name { get; set; }
|
||||||
public int gold { get; set; }
|
public int gold { get; set; }
|
||||||
public int gold_reliable { get; set; }
|
public int gold_reliable { get; set; }
|
||||||
public int gold_unreliable { get; set; }
|
public int gold_unreliable { get; set; }
|
||||||
public int gpm { get; set; }
|
public int gpm { get; set; }
|
||||||
public int xpm { get; set; }
|
public int xpm { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Hero
|
public class Hero
|
||||||
{
|
{
|
||||||
public int id { get; set; }
|
public int id { get; set; }
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public int level { get; set; }
|
public int level { get; set; }
|
||||||
public bool alive { get; set; }
|
public bool alive { get; set; }
|
||||||
public int respawn_seconds { get; set; }
|
public int respawn_seconds { get; set; }
|
||||||
public int buyback_cost { get; set; }
|
public int buyback_cost { get; set; }
|
||||||
public int buyback_cooldown { get; set; }
|
public int buyback_cooldown { get; set; }
|
||||||
public int health { get; set; }
|
public int health { get; set; }
|
||||||
public int max_health { get; set; }
|
public int max_health { get; set; }
|
||||||
public int health_percent { get; set; }
|
public int health_percent { get; set; }
|
||||||
public int mana { get; set; }
|
public int mana { get; set; }
|
||||||
public int max_mana { get; set; }
|
public int max_mana { get; set; }
|
||||||
public int mana_percent { get; set; }
|
public int mana_percent { get; set; }
|
||||||
public bool silenced { get; set; }
|
public bool silenced { get; set; }
|
||||||
public bool stunned { get; set; }
|
public bool stunned { get; set; }
|
||||||
public bool disarmed { get; set; }
|
public bool disarmed { get; set; }
|
||||||
public bool magicimmune { get; set; }
|
public bool magicimmune { get; set; }
|
||||||
public bool hexed { get; set; }
|
public bool hexed { get; set; }
|
||||||
public bool muted { get; set; }
|
public bool muted { get; set; }
|
||||||
public bool _break { get; set; }
|
public bool _break { get; set; }
|
||||||
public bool has_debuff { get; set; }
|
public bool has_debuff { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Abilities
|
public class Abilities
|
||||||
{
|
{
|
||||||
public Ability0 ability0 { get; set; }
|
public Ability0 ability0 { get; set; }
|
||||||
public Ability1 ability1 { get; set; }
|
public Ability1 ability1 { get; set; }
|
||||||
public Ability2 ability2 { get; set; }
|
public Ability2 ability2 { get; set; }
|
||||||
public Ability3 ability3 { get; set; }
|
public Ability3 ability3 { get; set; }
|
||||||
|
|
||||||
public Attributes attributes { get; set; }
|
public Attributes attributes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Ability0
|
public class Ability0
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public int level { get; set; }
|
public int level { get; set; }
|
||||||
public bool can_cast { get; set; }
|
public bool can_cast { get; set; }
|
||||||
public bool passive { get; set; }
|
public bool passive { get; set; }
|
||||||
public bool ability_active { get; set; }
|
public bool ability_active { get; set; }
|
||||||
public int cooldown { get; set; }
|
public int cooldown { get; set; }
|
||||||
public bool ultimate { get; set; }
|
public bool ultimate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Ability1
|
public class Ability1
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public int level { get; set; }
|
public int level { get; set; }
|
||||||
public bool can_cast { get; set; }
|
public bool can_cast { get; set; }
|
||||||
public bool passive { get; set; }
|
public bool passive { get; set; }
|
||||||
public bool ability_active { get; set; }
|
public bool ability_active { get; set; }
|
||||||
public int cooldown { get; set; }
|
public int cooldown { get; set; }
|
||||||
public bool ultimate { get; set; }
|
public bool ultimate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Ability2
|
public class Ability2
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public int level { get; set; }
|
public int level { get; set; }
|
||||||
public bool can_cast { get; set; }
|
public bool can_cast { get; set; }
|
||||||
public bool passive { get; set; }
|
public bool passive { get; set; }
|
||||||
public bool ability_active { get; set; }
|
public bool ability_active { get; set; }
|
||||||
public int cooldown { get; set; }
|
public int cooldown { get; set; }
|
||||||
public bool ultimate { get; set; }
|
public bool ultimate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Ability3
|
public class Ability3
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public int level { get; set; }
|
public int level { get; set; }
|
||||||
public bool can_cast { get; set; }
|
public bool can_cast { get; set; }
|
||||||
public bool passive { get; set; }
|
public bool passive { get; set; }
|
||||||
public bool ability_active { get; set; }
|
public bool ability_active { get; set; }
|
||||||
public int cooldown { get; set; }
|
public int cooldown { get; set; }
|
||||||
public bool ultimate { get; set; }
|
public bool ultimate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Attributes
|
public class Attributes
|
||||||
{
|
{
|
||||||
public int level { get; set; }
|
public int level { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Items
|
public class Items
|
||||||
{
|
{
|
||||||
public Slot0 slot0 { get; set; }
|
public Slot0 slot0 { get; set; }
|
||||||
public Slot1 slot1 { get; set; }
|
public Slot1 slot1 { get; set; }
|
||||||
public Slot2 slot2 { get; set; }
|
public Slot2 slot2 { get; set; }
|
||||||
public Slot3 slot3 { get; set; }
|
public Slot3 slot3 { get; set; }
|
||||||
public Slot4 slot4 { get; set; }
|
public Slot4 slot4 { get; set; }
|
||||||
public Slot5 slot5 { get; set; }
|
public Slot5 slot5 { get; set; }
|
||||||
public Stash0 stash0 { get; set; }
|
public Stash0 stash0 { get; set; }
|
||||||
public Stash1 stash1 { get; set; }
|
public Stash1 stash1 { get; set; }
|
||||||
public Stash2 stash2 { get; set; }
|
public Stash2 stash2 { get; set; }
|
||||||
public Stash3 stash3 { get; set; }
|
public Stash3 stash3 { get; set; }
|
||||||
public Stash4 stash4 { get; set; }
|
public Stash4 stash4 { get; set; }
|
||||||
public Stash5 stash5 { get; set; }
|
public Stash5 stash5 { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Slot0
|
public class Slot0
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Slot1
|
public class Slot1
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Slot2
|
public class Slot2
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Slot3
|
public class Slot3
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Slot4
|
public class Slot4
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Slot5
|
public class Slot5
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Stash0
|
public class Stash0
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Stash1
|
public class Stash1
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Stash2
|
public class Stash2
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Stash3
|
public class Stash3
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Stash4
|
public class Stash4
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Stash5
|
public class Stash5
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Previously
|
public class Previously
|
||||||
{
|
{
|
||||||
public Player1 player { get; set; }
|
public Player1 player { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Player1
|
public class Player1
|
||||||
{
|
{
|
||||||
public int gold { get; set; }
|
public int gold { get; set; }
|
||||||
public int gold_unreliable { get; set; }
|
public int gold_unreliable { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,25 +1,16 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Linq;
|
|
||||||
using Artemis.KeyboardProviders;
|
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
using Artemis.Models;
|
using Artemis.Models;
|
||||||
using Artemis.Utilities;
|
using Artemis.Models.Profiles;
|
||||||
using Artemis.Utilities.GameState;
|
using Artemis.Utilities.GameState;
|
||||||
using Artemis.Utilities.Keyboard;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Artemis.Modules.Games.Dota2
|
namespace Artemis.Modules.Games.Dota2
|
||||||
{
|
{
|
||||||
internal class Dota2Model : GameModel
|
internal class Dota2Model : GameModel
|
||||||
{
|
{
|
||||||
private KeyboardRegion _abilityKeys;
|
public Dota2Model(MainManager mainManager, Dota2Settings settings)
|
||||||
private KeyboardRegion _keyPad;
|
: base(mainManager, settings, new Dota2DataModel())
|
||||||
private KeyboardRegion _topRow;
|
|
||||||
|
|
||||||
public Dota2Model(MainManager mainManager, Dota2Settings settings) : base(mainManager, settings)
|
|
||||||
{
|
{
|
||||||
Name = "Dota2";
|
Name = "Dota2";
|
||||||
ProcessName = "dota2";
|
ProcessName = "dota2";
|
||||||
@ -29,6 +20,7 @@ namespace Artemis.Modules.Games.Dota2
|
|||||||
Scale = 4;
|
Scale = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int Scale { get; set; }
|
||||||
public new Dota2Settings Settings { get; set; }
|
public new Dota2Settings Settings { get; set; }
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
@ -40,278 +32,26 @@ namespace Artemis.Modules.Games.Dota2
|
|||||||
public override void Enable()
|
public override void Enable()
|
||||||
{
|
{
|
||||||
Initialized = false;
|
Initialized = false;
|
||||||
_topRow = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRegions.First(r => r.RegionName == "TopRow");
|
|
||||||
_keyPad = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRegions.First(r => r.RegionName == "NumPad");
|
|
||||||
_abilityKeys = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRegions.First(r => r.RegionName == "QWER");
|
|
||||||
HealthRectangle = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard
|
|
||||||
, 0
|
|
||||||
, _topRow.BottomRight.Y*Scale
|
|
||||||
, new List<Color>()
|
|
||||||
, LinearGradientMode.Horizontal)
|
|
||||||
{Height = Scale, ContainedBrush = false};
|
|
||||||
|
|
||||||
ManaRectangle = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard
|
|
||||||
, 0
|
|
||||||
, (_topRow.BottomRight.Y + 1)*Scale
|
|
||||||
, new List<Color>()
|
|
||||||
, LinearGradientMode.Horizontal)
|
|
||||||
{Height = Scale, ContainedBrush = false};
|
|
||||||
|
|
||||||
EventRectangle = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard
|
|
||||||
, 0
|
|
||||||
, _topRow.TopLeft.X + 3
|
|
||||||
, new List<Color>()
|
|
||||||
, LinearGradientMode.Horizontal)
|
|
||||||
{
|
|
||||||
Height = MainManager.KeyboardManager.ActiveKeyboard.Height*Scale - Scale
|
|
||||||
,
|
|
||||||
Width = MainManager.KeyboardManager.ActiveKeyboard.Width*Scale - Scale - 12
|
|
||||||
};
|
|
||||||
|
|
||||||
DayCycleRectangle = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard
|
|
||||||
, _keyPad.TopLeft.X*Scale
|
|
||||||
, _keyPad.TopLeft.Y*Scale
|
|
||||||
, new List<Color>()
|
|
||||||
, LinearGradientMode.Horizontal)
|
|
||||||
{
|
|
||||||
Height = _keyPad.GetRectangle().Height*Scale,
|
|
||||||
Width = _keyPad.GetRectangle().Width*Scale
|
|
||||||
};
|
|
||||||
|
|
||||||
SetAbilityKeys();
|
|
||||||
|
|
||||||
MainManager.GameStateWebServer.GameDataReceived += HandleGameData;
|
MainManager.GameStateWebServer.GameDataReceived += HandleGameData;
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetAbilityKeys()
|
|
||||||
{
|
|
||||||
#region Long Switch Statement for Keys
|
|
||||||
|
|
||||||
switch (Settings.KeyboardLayout)
|
|
||||||
{
|
|
||||||
case "0":
|
|
||||||
case "Default": //default
|
|
||||||
case "4": //Heroes of newearth
|
|
||||||
case "3": //League of Legends
|
|
||||||
for (var i = 0; i < AbilityKeysRectangles.Length; i++)
|
|
||||||
{
|
|
||||||
AbilityKeysRectangles[i] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
|
|
||||||
(_abilityKeys.TopLeft.X + i)*Scale - 2,
|
|
||||||
_abilityKeys.TopLeft.Y*Scale,
|
|
||||||
new List<Color>(),
|
|
||||||
LinearGradientMode.Horizontal)
|
|
||||||
{
|
|
||||||
Height = Scale,
|
|
||||||
Width = Scale
|
|
||||||
};
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "2":
|
|
||||||
AbilityKeysRectangles[0] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
|
|
||||||
_abilityKeys.TopLeft.X*Scale - 2,
|
|
||||||
_abilityKeys.TopLeft.Y*Scale,
|
|
||||||
new List<Color>(),
|
|
||||||
LinearGradientMode.Horizontal)
|
|
||||||
{
|
|
||||||
Height = Scale,
|
|
||||||
Width = Scale
|
|
||||||
};
|
|
||||||
AbilityKeysRectangles[1] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
|
|
||||||
(_abilityKeys.TopLeft.X + 2)*Scale - 2,
|
|
||||||
_abilityKeys.TopLeft.Y*Scale,
|
|
||||||
new List<Color>(),
|
|
||||||
LinearGradientMode.Horizontal)
|
|
||||||
{
|
|
||||||
Height = Scale,
|
|
||||||
Width = Scale
|
|
||||||
};
|
|
||||||
AbilityKeysRectangles[2] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
|
|
||||||
(_abilityKeys.TopLeft.X + 3)*Scale - 2,
|
|
||||||
_abilityKeys.TopLeft.Y*Scale,
|
|
||||||
new List<Color>(),
|
|
||||||
LinearGradientMode.Horizontal)
|
|
||||||
{
|
|
||||||
Height = Scale,
|
|
||||||
Width = Scale
|
|
||||||
};
|
|
||||||
AbilityKeysRectangles[3] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
|
|
||||||
(_abilityKeys.TopLeft.X + 3)*Scale - 2,
|
|
||||||
(_abilityKeys.TopLeft.Y + 1)*Scale,
|
|
||||||
new List<Color>(),
|
|
||||||
LinearGradientMode.Horizontal)
|
|
||||||
{
|
|
||||||
Height = Scale,
|
|
||||||
Width = Scale
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case "1": //MMO
|
|
||||||
case "5": //Smite
|
|
||||||
for (var i = 0; i < AbilityKeysRectangles.Length; i++)
|
|
||||||
{
|
|
||||||
AbilityKeysRectangles[i] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
|
|
||||||
(_abilityKeys.TopLeft.X + i)*Scale - 3,
|
|
||||||
(_abilityKeys.TopLeft.Y - 1)*Scale,
|
|
||||||
new List<Color>(),
|
|
||||||
LinearGradientMode.Horizontal)
|
|
||||||
{
|
|
||||||
Height = Scale,
|
|
||||||
Width = Scale
|
|
||||||
};
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
if (D2Json?.map == null)
|
UpdateDay();
|
||||||
return;
|
|
||||||
|
|
||||||
UpdateMainColor();
|
|
||||||
if (Settings.ShowEvents)
|
|
||||||
UpdateEvents();
|
|
||||||
if (Settings.ShowDayCycle)
|
|
||||||
UpdateDay();
|
|
||||||
if (!D2Json.hero.alive)
|
|
||||||
return;
|
|
||||||
if (Settings.CanCastAbility)
|
|
||||||
UpdateAbilities();
|
|
||||||
if (Settings.ShowHealth)
|
|
||||||
UpdateHealth();
|
|
||||||
if (Settings.ShowMana)
|
|
||||||
UpdateMana();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateMainColor()
|
|
||||||
{
|
|
||||||
var list = new List<Color> {ColorHelpers.ToDrawingColor(Settings.MainColor)};
|
|
||||||
EventRectangle.Colors = list;
|
|
||||||
DayCycleRectangle.Colors = list;
|
|
||||||
HealthRectangle.Colors = list;
|
|
||||||
ManaRectangle.Colors = list;
|
|
||||||
foreach (var key in AbilityKeysRectangles)
|
|
||||||
key.Colors = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateEvents()
|
|
||||||
{
|
|
||||||
List<Color> list = null;
|
|
||||||
if (!D2Json.hero.alive)
|
|
||||||
list = new List<Color> {Color.LightGray};
|
|
||||||
else if (D2Json.hero.disarmed)
|
|
||||||
list = new List<Color> {Color.Yellow};
|
|
||||||
else if (D2Json.hero.hexed)
|
|
||||||
list = new List<Color> {Color.Yellow};
|
|
||||||
else if (D2Json.hero.silenced)
|
|
||||||
list = new List<Color> {Color.Yellow};
|
|
||||||
else if (D2Json.hero.stunned)
|
|
||||||
list = new List<Color> {Color.Yellow};
|
|
||||||
else if (D2Json.hero.magicimmune)
|
|
||||||
list = new List<Color> {Color.Lime};
|
|
||||||
if (list == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
EventRectangle.Colors = list;
|
|
||||||
DayCycleRectangle.Colors = list;
|
|
||||||
HealthRectangle.Colors = list;
|
|
||||||
ManaRectangle.Colors = list;
|
|
||||||
foreach (var item in AbilityKeysRectangles)
|
|
||||||
item.Colors = list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateDay()
|
private void UpdateDay()
|
||||||
{
|
{
|
||||||
if (D2Json?.map?.daytime == null)
|
var dataModel = DataModel as Dota2DataModel;
|
||||||
|
if (dataModel?.map?.daytime == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (D2Json.map.nightstalker_night)
|
var timeLeft = 240 - dataModel.map.clock_time%240;
|
||||||
{
|
dataModel.map.dayCyclePercentage = (int) (100.00/240*timeLeft);
|
||||||
DayCycleRectangle.Colors = new List<Color> {Color.Blue};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var timeLeft = 240 - D2Json.map.clock_time%240;
|
|
||||||
var timePercentage = 100.00/240*timeLeft;
|
|
||||||
DayCycleRectangle.Width = (int) (_keyPad.GetRectangle().Width*Scale/100.00*timePercentage);
|
|
||||||
DayCycleRectangle.Colors = D2Json.map.daytime
|
|
||||||
? new List<Color> {Color.Yellow}
|
|
||||||
: new List<Color> {Color.Blue};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateMana()
|
|
||||||
{
|
|
||||||
if (D2Json?.hero == null || D2Json.hero.mana_percent == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var manaPercent = D2Json.hero.mana_percent;
|
|
||||||
ManaRectangle.Colors = new List<Color> {ColorHelpers.ToDrawingColor(Settings.ManaColor)};
|
|
||||||
ManaRectangle.Width = (int) Math.Floor(_topRow.GetRectangle().Width*Scale/100.00*manaPercent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateAbilities()
|
|
||||||
{
|
|
||||||
if (AbilityKeysRectangles == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AbilityKeysRectangles[0].Colors = D2Json?.abilities?.ability0?.can_cast == true
|
|
||||||
? new List<Color>
|
|
||||||
{ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
|
|
||||||
: new List<Color> {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
|
|
||||||
AbilityKeysRectangles[1].Colors = D2Json?.abilities?.ability1?.can_cast == true
|
|
||||||
? new List<Color>
|
|
||||||
{ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
|
|
||||||
: new List<Color> {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
|
|
||||||
AbilityKeysRectangles[2].Colors = D2Json?.abilities?.ability2?.can_cast == true
|
|
||||||
? new List<Color>
|
|
||||||
{ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
|
|
||||||
: new List<Color> {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
|
|
||||||
AbilityKeysRectangles[3].Colors = D2Json?.abilities?.ability3?.can_cast == true
|
|
||||||
? new List<Color>
|
|
||||||
{ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
|
|
||||||
: new List<Color> {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void UpdateHealth()
|
|
||||||
{
|
|
||||||
if (D2Json?.hero == null || D2Json.hero.health_percent == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var healthPercent = D2Json.hero.health_percent;
|
|
||||||
if (healthPercent > 66)
|
|
||||||
HealthRectangle.Colors = new List<Color> {Color.Lime};
|
|
||||||
else if (healthPercent > 33)
|
|
||||||
HealthRectangle.Colors = new List<Color> {Color.Yellow};
|
|
||||||
else
|
|
||||||
HealthRectangle.Colors = new List<Color> {Color.Red};
|
|
||||||
|
|
||||||
HealthRectangle.Width = (int) Math.Floor(_topRow.GetRectangle().Width*Scale/100.00*healthPercent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override Bitmap GenerateBitmap()
|
|
||||||
{
|
|
||||||
var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(Scale);
|
|
||||||
|
|
||||||
using (var g = Graphics.FromImage(bitmap))
|
|
||||||
{
|
|
||||||
g.Clear(Color.Transparent);
|
|
||||||
EventRectangle.Draw(g);
|
|
||||||
HealthRectangle.Draw(g);
|
|
||||||
ManaRectangle.Draw(g);
|
|
||||||
foreach (var item in AbilityKeysRectangles)
|
|
||||||
{
|
|
||||||
item.Draw(g);
|
|
||||||
}
|
|
||||||
DayCycleRectangle.Draw(g);
|
|
||||||
}
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void HandleGameData(object sender, GameDataReceivedEventArgs e)
|
public void HandleGameData(object sender, GameDataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
var jsonString = e.Json.ToString();
|
var jsonString = e.Json.ToString();
|
||||||
@ -321,19 +61,12 @@ namespace Artemis.Modules.Games.Dota2
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Parse the JSON
|
// Parse the JSON
|
||||||
D2Json = JsonConvert.DeserializeObject<Dota2DataModel.Rootobject>(jsonString);
|
DataModel = JsonConvert.DeserializeObject<Dota2DataModel>(jsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Variables
|
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||||
|
{
|
||||||
public Dota2DataModel.Rootobject D2Json { get; set; }
|
return Profile.GetRenderLayers<Dota2DataModel>(DataModel, renderMice, renderHeadsets);
|
||||||
public int Scale { get; set; }
|
}
|
||||||
public KeyboardRectangle HealthRectangle { get; set; }
|
|
||||||
public KeyboardRectangle EventRectangle { get; set; }
|
|
||||||
public KeyboardRectangle DayCycleRectangle { get; set; }
|
|
||||||
public KeyboardRectangle ManaRectangle { get; set; }
|
|
||||||
public KeyboardRectangle[] AbilityKeysRectangles = new KeyboardRectangle[4];
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,14 +29,16 @@ namespace Artemis.Modules.Games.Dota2
|
|||||||
|
|
||||||
public override void Save()
|
public override void Save()
|
||||||
{
|
{
|
||||||
|
Dota2.Default.Enabled = Enabled;
|
||||||
|
Dota2.Default.LastProfile = LastProfile;
|
||||||
|
Dota2.Default.GameDirectory = GameDirectory;
|
||||||
|
|
||||||
Dota2.Default.KeyboardLayout = KeyboardLayout;
|
Dota2.Default.KeyboardLayout = KeyboardLayout;
|
||||||
Dota2.Default.MainColor = MainColor;
|
Dota2.Default.MainColor = MainColor;
|
||||||
Dota2.Default.ManaColor = ManaColor;
|
Dota2.Default.ManaColor = ManaColor;
|
||||||
Dota2.Default.ShowDayCycle = ShowDayCycle;
|
Dota2.Default.ShowDayCycle = ShowDayCycle;
|
||||||
Dota2.Default.ShowHealth = ShowHealth;
|
Dota2.Default.ShowHealth = ShowHealth;
|
||||||
Dota2.Default.CanCastAbility = CanCastAbility;
|
Dota2.Default.CanCastAbility = CanCastAbility;
|
||||||
Dota2.Default.Enabled = Enabled;
|
|
||||||
Dota2.Default.GameDirectory = GameDirectory;
|
|
||||||
Dota2.Default.ShowMana = ShowMana;
|
Dota2.Default.ShowMana = ShowMana;
|
||||||
Dota2.Default.ShowEvents = ShowEvents;
|
Dota2.Default.ShowEvents = ShowEvents;
|
||||||
Dota2.Default.AbilityCooldownColor = AbilityCooldownColor;
|
Dota2.Default.AbilityCooldownColor = AbilityCooldownColor;
|
||||||
|
|||||||
@ -4,36 +4,27 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:cal="http://www.caliburnproject.org"
|
xmlns:cal="http://www.caliburnproject.org"
|
||||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
mc:Ignorable="d"
|
||||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
d:DesignHeight="476.986" d:DesignWidth="538.772">
|
||||||
mc:Ignorable="d" d:DesignWidth="635" Height="515.691">
|
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Margin="0,0,0,-19">
|
<Grid Margin="15,5,5,5">
|
||||||
<Grid Margin="15, 5, 15, 5">
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="80" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
<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>
|
||||||
|
|
||||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||||
<Label FontSize="20" HorizontalAlignment="Left">
|
<Label FontSize="20" HorizontalAlignment="Left">
|
||||||
<Label.Content>
|
<Label.Content>
|
||||||
<AccessText TextWrapping="Wrap"
|
<AccessText TextWrapping="Wrap"
|
||||||
Text="Shows game states and events from Dota 2." />
|
Text="Shows verious game states and events on the keyboard." />
|
||||||
</Label.Content>
|
</Label.Content>
|
||||||
</Label>
|
</Label>
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||||
@ -45,130 +36,31 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
<StackPanel Grid.Row="1"
|
<StackPanel Grid.Row="1"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Grid.ColumnSpan="2" Margin="0,0,1,0">
|
Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||||
<Label FontSize="16" Content="Dota 2 Directory" FontFamily="Segoe UI Semibold" Foreground="#535353"
|
<Label FontSize="20" HorizontalAlignment="Left" Content="Dota 2 Directory" />
|
||||||
Width="130" HorizontalAlignment="Left" />
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextBox x:Name="GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
|
<TextBox x:Name="GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
|
||||||
Text="{Binding Path=GameSettings.GameDirectory, Mode=TwoWay}"
|
Text="{Binding Path=GameSettings.GameDirectory, Mode=TwoWay}"
|
||||||
cal:Message.Attach="[Event LostFocus] = [Action PlaceConfigFile]" />
|
cal:Message.Attach="[Event LostFocus] = [Action PlaceConfigFile]" />
|
||||||
<Button x:Name="BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
|
<Button x:Name="BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
|
||||||
HorizontalAlignment="Right" Width="25"
|
HorizontalAlignment="Right" Width="25"
|
||||||
Style="{DynamicResource SquareButtonStyle}" Height="25" />
|
Style="{DynamicResource SquareButtonStyle}" Height="26" Margin="0,-2,0,0" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Main Color -->
|
<!-- Profile editor -->
|
||||||
<TextBlock Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" Width="114" VerticalAlignment="Center"
|
<ContentControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-20,0" />
|
||||||
Height="16" Margin="0,8">
|
|
||||||
Main keyboard color
|
|
||||||
</TextBlock>
|
|
||||||
<xctk:ColorPicker x:Name="MainColor"
|
|
||||||
SelectedColor="{Binding Path=GameSettings.MainColor, Mode=TwoWay}"
|
|
||||||
Grid.Row="2" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
|
||||||
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" />
|
|
||||||
|
|
||||||
<!-- Ability Ready Color -->
|
<!-- Buttons -->
|
||||||
<TextBlock Grid.Row="3" Grid.Column="0" HorizontalAlignment="Left" Width="114" VerticalAlignment="Center"
|
<StackPanel Grid.Column="0" Grid.Row="4" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||||
Height="16" Margin="0,8">
|
|
||||||
Ability Ready Color
|
|
||||||
</TextBlock>
|
|
||||||
<xctk:ColorPicker x:Name="AbilityReadyColor"
|
|
||||||
SelectedColor="{Binding Path=GameSettings.AbilityReadyColor, Mode=TwoWay}"
|
|
||||||
Grid.Row="3" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
|
||||||
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" />
|
|
||||||
|
|
||||||
<!-- Ability on Cooldown Color -->
|
|
||||||
<TextBlock Grid.Row="4" Grid.Column="0" HorizontalAlignment="Left" Width="147" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,8">
|
|
||||||
Ability on Cooldown Color
|
|
||||||
</TextBlock>
|
|
||||||
<xctk:ColorPicker x:Name="AbilityCooldownColor"
|
|
||||||
SelectedColor="{Binding Path=GameSettings.AbilityCooldownColor, Mode=TwoWay}"
|
|
||||||
Grid.Row="4" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
|
||||||
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" />
|
|
||||||
|
|
||||||
<!-- Abilities Display -->
|
|
||||||
<TextBlock Grid.Row="5" Grid.Column="0" HorizontalAlignment="Left" Width="168" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,10,0,9">
|
|
||||||
Keyboard Template
|
|
||||||
</TextBlock>
|
|
||||||
<ComboBox Grid.Row="5" Grid.Column="1" x:Name="KeyboardLayouts"
|
|
||||||
ItemsSource="{Binding Path=KeyboardLayouts}"
|
|
||||||
SelectedIndex="{Binding Path=GameSettings.KeyboardLayout}" VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Width="109" Margin="0,6,0,7" />
|
|
||||||
|
|
||||||
<!-- Items Display -->
|
|
||||||
<TextBlock Grid.Row="6" Grid.Column="0" HorizontalAlignment="Left" Width="168" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,10,0,9">
|
|
||||||
Castable Abilities
|
|
||||||
</TextBlock>
|
|
||||||
<controls:ToggleSwitch IsChecked="{Binding Path=GameSettings.CanCastAbility, Mode=TwoWay}"
|
|
||||||
Grid.Row="6" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes" OffLabel="No"
|
|
||||||
Margin="0,0,-5,0" Width="114" />
|
|
||||||
|
|
||||||
<!-- Health Display -->
|
|
||||||
<TextBlock Grid.Row="7" Grid.Column="0" HorizontalAlignment="Left" Width="168" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,10,0,9">
|
|
||||||
Display health
|
|
||||||
</TextBlock>
|
|
||||||
<controls:ToggleSwitch IsChecked="{Binding Path=GameSettings.ShowHealth, Mode=TwoWay}"
|
|
||||||
Grid.Row="7" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes" OffLabel="No"
|
|
||||||
Margin="0,0,-5,0" Width="114" />
|
|
||||||
|
|
||||||
<!-- Mana Display-->
|
|
||||||
<TextBlock Grid.Row="8" Grid.Column="0" HorizontalAlignment="Left" Width="168" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,10,0,9">
|
|
||||||
Display mana
|
|
||||||
</TextBlock>
|
|
||||||
<controls:ToggleSwitch IsChecked="{Binding Path=GameSettings.ShowMana, Mode=TwoWay}"
|
|
||||||
Grid.Row="8" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes" OffLabel="No"
|
|
||||||
Margin="0,0,-5,0" Width="114" />
|
|
||||||
|
|
||||||
<!-- Mana Color -->
|
|
||||||
<TextBlock Grid.Row="9" Grid.Column="0" HorizontalAlignment="Left" Width="114" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,8">
|
|
||||||
Mana color
|
|
||||||
</TextBlock>
|
|
||||||
<xctk:ColorPicker x:Name="ManaColor"
|
|
||||||
SelectedColor="{Binding Path=GameSettings.ManaColor, Mode=TwoWay}"
|
|
||||||
Grid.Row="9" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
|
||||||
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" />
|
|
||||||
|
|
||||||
<!-- Daytime Display -->
|
|
||||||
<TextBlock Grid.Row="10" Grid.Column="0" HorizontalAlignment="Left" Width="168" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,10,0,9">
|
|
||||||
Display day/night
|
|
||||||
</TextBlock>
|
|
||||||
<controls:ToggleSwitch IsChecked="{Binding Path=GameSettings.ShowDayCycle, Mode=TwoWay}"
|
|
||||||
Grid.Row="10" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes"
|
|
||||||
OffLabel="No"
|
|
||||||
Margin="0,0,-5,0" Width="114" />
|
|
||||||
|
|
||||||
<!-- Dead Display -->
|
|
||||||
<TextBlock Grid.Row="11" Grid.Column="0" HorizontalAlignment="Left" Width="168" VerticalAlignment="Center"
|
|
||||||
Height="16" Margin="0,10,0,9">
|
|
||||||
Show events on the keyboard
|
|
||||||
</TextBlock>
|
|
||||||
<controls:ToggleSwitch IsChecked="{Binding Path=GameSettings.ShowEvents, Mode=TwoWay}"
|
|
||||||
Grid.Row="11" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes"
|
|
||||||
OffLabel="No"
|
|
||||||
Margin="0,0,-5,0" Width="114" />
|
|
||||||
|
|
||||||
|
|
||||||
<StackPanel Grid.Column="0" Grid.Row="12" 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"
|
||||||
Margin="10,0,0,0"
|
Margin="10,0,0,0"
|
||||||
Style="{DynamicResource SquareButtonStyle}" />
|
Style="{DynamicResource SquareButtonStyle}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,33 +1,41 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Artemis.InjectionFactories;
|
||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
using Artemis.Properties;
|
using Artemis.Properties;
|
||||||
|
using Artemis.Utilities;
|
||||||
using Artemis.ViewModels.Abstract;
|
using Artemis.ViewModels.Abstract;
|
||||||
using Caliburn.Micro;
|
using Caliburn.Micro;
|
||||||
|
|
||||||
namespace Artemis.Modules.Games.Dota2
|
namespace Artemis.Modules.Games.Dota2
|
||||||
{
|
{
|
||||||
public class Dota2ViewModel : GameViewModel<Dota2DataModel>
|
public sealed class Dota2ViewModel : GameViewModel
|
||||||
{
|
{
|
||||||
public Dota2ViewModel(MainManager mainManager)
|
public Dota2ViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||||
: base(mainManager, new Dota2Model(mainManager, new Dota2Settings()))
|
: base(main, new Dota2Model(main, new Dota2Settings()), events, pFactory)
|
||||||
{
|
{
|
||||||
|
DisplayName = "Dota 2";
|
||||||
MainManager.EffectManager.EffectModels.Add(GameModel);
|
MainManager.EffectManager.EffectModels.Add(GameModel);
|
||||||
|
|
||||||
|
FindGameDir();
|
||||||
PlaceConfigFile();
|
PlaceConfigFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BindableCollection<string> KeyboardLayouts => new BindableCollection<string>(new[]
|
public void FindGameDir()
|
||||||
{
|
{
|
||||||
"Default",
|
var gameSettings = (Dota2Settings) GameSettings;
|
||||||
"MMO",
|
// If already propertly set up, don't do anything
|
||||||
"WASD",
|
if (gameSettings.GameDirectory != null && File.Exists(gameSettings.GameDirectory + "csgo.exe") &&
|
||||||
"League of Legends",
|
File.Exists(gameSettings.GameDirectory + "/csgo/cfg/gamestate_integration_artemis.cfg"))
|
||||||
"Heros of Newearth",
|
return;
|
||||||
"Smite"
|
|
||||||
});
|
|
||||||
|
|
||||||
public static string Name => "Dota 2";
|
var dir = GeneralHelpers.FindSteamGame(@"\dota 2 beta\game\bin\win32\dota2.exe");
|
||||||
public string Content => "Dota 2 Content";
|
// Remove subdirectories where they stuck the executable
|
||||||
|
dir = dir?.Substring(0, dir.Length - 15);
|
||||||
|
|
||||||
|
gameSettings.GameDirectory = dir ?? string.Empty;
|
||||||
|
gameSettings.Save();
|
||||||
|
}
|
||||||
|
|
||||||
public void BrowseDirectory()
|
public void BrowseDirectory()
|
||||||
{
|
{
|
||||||
@ -68,12 +76,11 @@ namespace Artemis.Modules.Games.Dota2
|
|||||||
cfgFile);
|
cfgFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainManager.DialogService.ShowErrorMessageBox("Please select a valid Dota 2 directory\n\n" +
|
DialogService.ShowErrorMessageBox("Please select a valid Dota 2 directory\n\n" +
|
||||||
@"By default Dota 2 is in \SteamApps\common\dota 2 beta");
|
@"By default Dota 2 is in \SteamApps\common\dota 2 beta");
|
||||||
((Dota2Settings) GameSettings).GameDirectory = string.Empty;
|
((Dota2Settings) GameSettings).GameDirectory = string.Empty;
|
||||||
NotifyOfPropertyChange(() => GameSettings);
|
NotifyOfPropertyChange(() => GameSettings);
|
||||||
|
|
||||||
|
|||||||
62
Artemis/Artemis/Modules/Games/Overwatch/Overwatch.Designer.cs
generated
Normal file
62
Artemis/Artemis/Modules/Games/Overwatch/Overwatch.Designer.cs
generated
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Games.Overwatch {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
|
||||||
|
internal sealed partial class Overwatch : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Overwatch defaultInstance = ((Overwatch)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Overwatch())));
|
||||||
|
|
||||||
|
public static Overwatch Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||||
|
public bool Enabled {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["Enabled"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["Enabled"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("Default")]
|
||||||
|
public string LastProfile {
|
||||||
|
get {
|
||||||
|
return ((string)(this["LastProfile"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["LastProfile"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||||
|
public string GameDirectory {
|
||||||
|
get {
|
||||||
|
return ((string)(this["GameDirectory"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["GameDirectory"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
Artemis/Artemis/Modules/Games/Overwatch/Overwatch.settings
Normal file
17
Artemis/Artemis/Modules/Games/Overwatch/Overwatch.settings
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
|
||||||
|
GeneratedClassNamespace="Artemis.Modules.Games.Overwatch" GeneratedClassName="Overwatch">
|
||||||
|
<Profiles />
|
||||||
|
<Settings>
|
||||||
|
<Setting Name="Enabled" Type="System.Boolean" Scope="User">
|
||||||
|
<Value Profile="(Default)">True</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="LastProfile" Type="System.String" Scope="User">
|
||||||
|
<Value Profile="(Default)">Default</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="GameDirectory" Type="System.String" Scope="User">
|
||||||
|
<Value Profile="(Default)" />
|
||||||
|
</Setting>
|
||||||
|
</Settings>
|
||||||
|
</SettingsFile>
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Games.Overwatch
|
||||||
|
{
|
||||||
|
public class OverwatchDataModel : IDataModel
|
||||||
|
{
|
||||||
|
public OverwatchStatus Status { get; set; }
|
||||||
|
public OverwatchCharacter Character { get; set; }
|
||||||
|
public bool UltimateReady { get; set; }
|
||||||
|
public bool Ability1Ready { get; set; }
|
||||||
|
public bool Ability2Ready { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum OverwatchStatus
|
||||||
|
{
|
||||||
|
Unkown,
|
||||||
|
InMainMenu,
|
||||||
|
InGame
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum OverwatchCharacter
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Genji,
|
||||||
|
Mccree,
|
||||||
|
Pharah,
|
||||||
|
Reaper,
|
||||||
|
Soldier76,
|
||||||
|
Tracer,
|
||||||
|
Bastion,
|
||||||
|
Hanzo,
|
||||||
|
Junkrat,
|
||||||
|
Mei,
|
||||||
|
Torbjörn,
|
||||||
|
Widowmaker,
|
||||||
|
Dva,
|
||||||
|
Reinhardt,
|
||||||
|
Roadhog,
|
||||||
|
Winston,
|
||||||
|
Zarya,
|
||||||
|
Lúcio,
|
||||||
|
Mercy,
|
||||||
|
Symmetra,
|
||||||
|
Zenyatta
|
||||||
|
}
|
||||||
|
}
|
||||||
147
Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
Normal file
147
Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using Artemis.Events;
|
||||||
|
using Artemis.Managers;
|
||||||
|
using Artemis.Models;
|
||||||
|
using Artemis.Models.Interfaces;
|
||||||
|
using Artemis.Models.Profiles;
|
||||||
|
using Artemis.Utilities;
|
||||||
|
using Artemis.Utilities.DataReaders;
|
||||||
|
using Caliburn.Micro;
|
||||||
|
using Color = System.Windows.Media.Color;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Games.Overwatch
|
||||||
|
{
|
||||||
|
public class OverwatchModel : GameModel
|
||||||
|
{
|
||||||
|
private readonly IEventAggregator _events;
|
||||||
|
|
||||||
|
public OverwatchModel(IEventAggregator events, MainManager mainManager, OverwatchSettings settings)
|
||||||
|
: base(mainManager, settings, new OverwatchDataModel())
|
||||||
|
{
|
||||||
|
_events = events;
|
||||||
|
Name = "Overwatch";
|
||||||
|
ProcessName = "Overwatch";
|
||||||
|
Scale = 4;
|
||||||
|
Enabled = Settings.Enabled;
|
||||||
|
Initialized = false;
|
||||||
|
|
||||||
|
MmfReader = new MmfReader("overwatchMmf");
|
||||||
|
LoadOverwatchCharacters();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OverwatchModel(MainManager mainManager, GameSettings settings, IDataModel dataModel)
|
||||||
|
: base(mainManager, settings, dataModel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CharacterColor> OverwatchCharacters { get; set; }
|
||||||
|
|
||||||
|
public MmfReader MmfReader { get; set; }
|
||||||
|
|
||||||
|
public int Scale { get; set; }
|
||||||
|
|
||||||
|
private void LoadOverwatchCharacters()
|
||||||
|
{
|
||||||
|
OverwatchCharacters = new List<CharacterColor>
|
||||||
|
{
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Genji, Color = Color.FromRgb(13, 61, 0)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Mccree, Color = Color.FromRgb(24, 1, 1)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Pharah, Color = Color.FromRgb(0, 6, 32)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Reaper, Color = Color.FromRgb(7, 0, 0)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Soldier76, Color = Color.FromRgb(3, 5, 11)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Tracer, Color = Color.FromRgb(46, 12, 0)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Bastion, Color = Color.FromRgb(6, 10, 5)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Hanzo, Color = Color.FromRgb(28, 24, 8)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Junkrat, Color = Color.FromRgb(59, 28, 0)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Mei, Color = Color.FromRgb(3, 20, 55)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Torbjörn, Color = Color.FromRgb(31, 4, 3)},
|
||||||
|
new CharacterColor
|
||||||
|
{
|
||||||
|
OverwatchCharacter = OverwatchCharacter.Widowmaker,
|
||||||
|
Color = Color.FromRgb(16, 3, 17)
|
||||||
|
},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Dva, Color = Color.FromRgb(62, 12, 32)},
|
||||||
|
new CharacterColor
|
||||||
|
{
|
||||||
|
OverwatchCharacter = OverwatchCharacter.Reinhardt,
|
||||||
|
Color = Color.FromRgb(12, 16, 16)
|
||||||
|
},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Roadhog, Color = Color.FromRgb(26, 10, 0)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Winston, Color = Color.FromRgb(17, 18, 26)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Zarya, Color = Color.FromRgb(58, 7, 24)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Lúcio, Color = Color.FromRgb(8, 35, 0)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Mercy, Color = Color.FromRgb(60, 56, 26)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Symmetra, Color = Color.FromRgb(11, 29, 37)},
|
||||||
|
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Zenyatta, Color = Color.FromRgb(62, 54, 6)}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Enable()
|
||||||
|
{
|
||||||
|
Initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
var gameDataModel = (OverwatchDataModel) DataModel;
|
||||||
|
var colors = MmfReader.GetColorArray();
|
||||||
|
if (colors == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var bitmap = new Bitmap(22, 6);
|
||||||
|
|
||||||
|
using (var g = Graphics.FromImage(bitmap))
|
||||||
|
{
|
||||||
|
for (var y = 0; y < 6; y++)
|
||||||
|
{
|
||||||
|
for (var x = 0; x < 22; x++)
|
||||||
|
{
|
||||||
|
g.DrawRectangle(new Pen(ColorHelpers.ToDrawingColor(colors[y, x])), y, x, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_events.PublishOnUIThread(new ChangeBitmap(bitmap));
|
||||||
|
|
||||||
|
// Determine general game state
|
||||||
|
gameDataModel.Status = colors[0, 0].Equals(Color.FromRgb(55, 30, 0))
|
||||||
|
? OverwatchStatus.InMainMenu
|
||||||
|
: OverwatchStatus.Unkown;
|
||||||
|
|
||||||
|
if (gameDataModel.Status == OverwatchStatus.InMainMenu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If ingame, look for a character
|
||||||
|
var characterMatch = OverwatchCharacters.FirstOrDefault(c => c.Color == colors[0, 0]);
|
||||||
|
if (characterMatch.OverwatchCharacter == OverwatchCharacter.None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gameDataModel.Status = OverwatchStatus.InGame;
|
||||||
|
gameDataModel.Character = characterMatch.OverwatchCharacter;
|
||||||
|
|
||||||
|
// Ability1 is ready when LShift is lid
|
||||||
|
gameDataModel.Ability1Ready = colors[4, 1].Equals(Color.FromRgb(4, 141, 144));
|
||||||
|
// Ability2 is ready when E is lid
|
||||||
|
gameDataModel.Ability2Ready = colors[2, 4].Equals(Color.FromRgb(4, 141, 144));
|
||||||
|
// Ultimate is ready when Q is blinking
|
||||||
|
gameDataModel.UltimateReady = !characterMatch.Color.Equals(colors[2, 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||||
|
{
|
||||||
|
return Profile.GetRenderLayers<OverwatchDataModel>(DataModel, renderMice, renderHeadsets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CharacterColor
|
||||||
|
{
|
||||||
|
public OverwatchCharacter OverwatchCharacter { get; set; }
|
||||||
|
public Color Color { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
36
Artemis/Artemis/Modules/Games/Overwatch/OverwatchSettings.cs
Normal file
36
Artemis/Artemis/Modules/Games/Overwatch/OverwatchSettings.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using Artemis.Models;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Games.Overwatch
|
||||||
|
{
|
||||||
|
public class OverwatchSettings : GameSettings
|
||||||
|
{
|
||||||
|
public OverwatchSettings()
|
||||||
|
{
|
||||||
|
Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GameDirectory { get; set; }
|
||||||
|
|
||||||
|
public sealed override void Load()
|
||||||
|
{
|
||||||
|
Enabled = Overwatch.Default.Enabled;
|
||||||
|
LastProfile = Overwatch.Default.LastProfile;
|
||||||
|
GameDirectory = Overwatch.Default.GameDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed override void Save()
|
||||||
|
{
|
||||||
|
Overwatch.Default.Enabled = Enabled;
|
||||||
|
Overwatch.Default.LastProfile = LastProfile;
|
||||||
|
Overwatch.Default.GameDirectory = GameDirectory;
|
||||||
|
|
||||||
|
Overwatch.Default.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed override void ToDefault()
|
||||||
|
{
|
||||||
|
Enabled = true;
|
||||||
|
GameDirectory = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
66
Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml
Normal file
66
Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<UserControl x:Class="Artemis.Modules.Games.Overwatch.OverwatchView"
|
||||||
|
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="410.933" d:DesignWidth="732.154">
|
||||||
|
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||||
|
<Grid Margin="15, 5, 15, 5">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition />
|
||||||
|
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||||
|
<Label FontSize="20" HorizontalAlignment="Left">
|
||||||
|
<Label.Content>
|
||||||
|
<AccessText TextWrapping="Wrap"
|
||||||
|
Text="Allows you to create layers based on ingame cooldown and your hero." />
|
||||||
|
</Label.Content>
|
||||||
|
</Label>
|
||||||
|
<StackPanel Orientation="Horizontal" 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>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||||
|
|
||||||
|
<Label FontSize="20" HorizontalAlignment="Left" Content="Overwatch 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 PlaceDll]" />
|
||||||
|
<Button x:Name="BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
|
||||||
|
HorizontalAlignment="Right" Width="25"
|
||||||
|
Style="{DynamicResource SquareButtonStyle}" Height="26" Margin="0,-2,0,0" />
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Profile editor -->
|
||||||
|
<ContentControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-30,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>
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Games.Overwatch
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for OverwatchView.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class OverwatchView : UserControl
|
||||||
|
{
|
||||||
|
public OverwatchView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Artemis.InjectionFactories;
|
||||||
|
using Artemis.Managers;
|
||||||
|
using Artemis.Properties;
|
||||||
|
using Artemis.ViewModels.Abstract;
|
||||||
|
using Caliburn.Micro;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
|
namespace Artemis.Modules.Games.Overwatch
|
||||||
|
{
|
||||||
|
public sealed class OverwatchViewModel : GameViewModel
|
||||||
|
{
|
||||||
|
public OverwatchViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||||
|
: base(main, new OverwatchModel(events, main, new OverwatchSettings()), events, pFactory)
|
||||||
|
{
|
||||||
|
DisplayName = "Overwatch";
|
||||||
|
MainManager.EffectManager.EffectModels.Add(GameModel);
|
||||||
|
|
||||||
|
FindOverwatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FindOverwatch()
|
||||||
|
{
|
||||||
|
var gameSettings = (OverwatchSettings) GameSettings;
|
||||||
|
// If already propertly set up, don't do anything
|
||||||
|
if (gameSettings.GameDirectory != null && File.Exists(gameSettings.GameDirectory + "Overwatch.exe") &&
|
||||||
|
File.Exists(gameSettings.GameDirectory + "RzChromaSDK64.dll"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var key = Registry.LocalMachine.OpenSubKey(
|
||||||
|
@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Overwatch");
|
||||||
|
if (key == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var path = key.GetValue("DisplayIcon").ToString();
|
||||||
|
if (!File.Exists(path))
|
||||||
|
return;
|
||||||
|
|
||||||
|
gameSettings.GameDirectory = path.Substring(0, path.Length - 14);
|
||||||
|
gameSettings.Save();
|
||||||
|
PlaceDll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BrowseDirectory()
|
||||||
|
{
|
||||||
|
var dialog = new FolderBrowserDialog {SelectedPath = ((OverwatchSettings) GameSettings).GameDirectory};
|
||||||
|
var result = dialog.ShowDialog();
|
||||||
|
if (result != DialogResult.OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
((OverwatchSettings) GameSettings).GameDirectory = dialog.SelectedPath;
|
||||||
|
NotifyOfPropertyChange(() => GameSettings);
|
||||||
|
GameSettings.Save();
|
||||||
|
|
||||||
|
PlaceDll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PlaceDll()
|
||||||
|
{
|
||||||
|
var path = ((OverwatchSettings) GameSettings).GameDirectory;
|
||||||
|
|
||||||
|
if (!File.Exists(path + @"\Overwatch.exe"))
|
||||||
|
{
|
||||||
|
DialogService.ShowErrorMessageBox("Please select a valid Overwatch directory\n\n" +
|
||||||
|
@"By default Overwatch is in C:\Program Files (x86)\Overwatch");
|
||||||
|
|
||||||
|
((OverwatchSettings) GameSettings).GameDirectory = string.Empty;
|
||||||
|
NotifyOfPropertyChange(() => GameSettings);
|
||||||
|
GameSettings.Save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllBytes(path + @"\RzChromaSDK64.dll", Resources.RzChromaSDK64);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger?.Error(e, "Couldn't place Overwatch DLL, Overwatch support won't work.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user