diff --git a/Artemis/Artemis/App.config b/Artemis/Artemis/App.config index 7a342616a..62b94b3c1 100644 --- a/Artemis/Artemis/App.config +++ b/Artemis/Artemis/App.config @@ -1,67 +1,40 @@  - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- + + + + True + + + Default + + Demo (Duplicate to keep changes) @@ -338,4 +311,4 @@ - \ No newline at end of file + diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 3a0358555..cc39b8ccf 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -9,7 +9,7 @@ Properties Artemis Artemis - v4.5.2 + v4.6.1 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 @@ -25,6 +25,7 @@ false + C:\Users\Robert\Desktop\Artemis builds\ true Disk @@ -39,7 +40,7 @@ Artemis Artemis 0 - 1.2.0.0 + 1.2.2.0 false true true @@ -199,6 +200,10 @@ ..\packages\NLog.4.3.4\lib\net45\NLog.dll True + + False + D:\Downloads\Chome Downloads\Process.NET-master\Process.NET-master\src\Process.NET\bin\Release\Process.NET.dll + ..\packages\SpotifyAPI-NET.2.9.0\lib\SpotifyAPI.dll True @@ -274,6 +279,7 @@ + @@ -306,6 +312,16 @@ + + True + True + WoW.settings + + + + + + @@ -314,6 +330,7 @@ + @@ -470,8 +487,9 @@ + - + @@ -480,15 +498,12 @@ - - - + + - - @@ -602,6 +617,10 @@ Code + + SettingsSingleFileGenerator + WoW.Designer.cs + @@ -852,9 +871,7 @@ false - - - + diff --git a/Artemis/Artemis/ArtemisBootstrapper.cs b/Artemis/Artemis/ArtemisBootstrapper.cs index 9d1ea7ac2..8f412eaf1 100644 --- a/Artemis/Artemis/ArtemisBootstrapper.cs +++ b/Artemis/Artemis/ArtemisBootstrapper.cs @@ -5,8 +5,11 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Forms; using Artemis.InjectionModules; +using Artemis.Profiles.Layers.Interfaces; +using Artemis.Profiles.Layers.Types.KeyPress; using Artemis.Settings; using Artemis.Utilities; +using Artemis.Utilities.Converters; using Artemis.ViewModels; using Caliburn.Micro; using Newtonsoft.Json; @@ -79,10 +82,16 @@ namespace Artemis protected override void Configure() { - JsonConvert.DefaultSettings = () => new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto}; _kernel = new StandardKernel(new BaseModules(), new ArtemisModules(), new ManagerModules()); _kernel.Bind().To().InSingletonScope(); _kernel.Bind().To().InSingletonScope(); + + var settings = new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto, + ContractResolver = _kernel.Get() + }; + JsonConvert.DefaultSettings = () => settings; } protected override void OnExit(object sender, EventArgs e) diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboards.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboards.cs index aa67d094c..3a64c1099 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboards.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboards.cs @@ -1,11 +1,17 @@ -using System.Drawing; +using System; +using System.Drawing; +using System.Linq; using System.Windows; +using System.Windows.Forms; +using Artemis.DeviceProviders.Corsair.Utilities; using Artemis.Properties; using Artemis.Utilities; using CUE.NET; using CUE.NET.Brushes; using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Keyboard; +using CUE.NET.Devices.Keyboard.Enums; +using CUE.NET.Devices.Keyboard.Keys; using Ninject.Extensions.Logging; using Point = System.Drawing.Point; @@ -47,28 +53,32 @@ namespace Artemis.DeviceProviders.Corsair case "K95 RGB": Height = 7; Width = 25; + Slug = "corsair-k95-rgb"; PreviewSettings = new PreviewSettings(676, 190, new Thickness(0, -15, 0, 0), Resources.k95); break; case "K70 RGB": case "K70 RGB RAPIDFIRE": + case "K70 LUX RGB": Height = 7; Width = 21; + Slug = "corsair-k70-rgb"; PreviewSettings = new PreviewSettings(676, 210, new Thickness(0, -25, 0, 0), Resources.k70); break; case "K65 RGB": Height = 7; Width = 18; + Slug = "corsair-k65-rgb"; PreviewSettings = new PreviewSettings(610, 240, new Thickness(0, -30, 0, 0), Resources.k65); break; case "STRAFE RGB": Height = 7; Width = 22; + Slug = "corsair-strafe-rgb"; PreviewSettings = new PreviewSettings(665, 215, new Thickness(0, -5, 0, 0), Resources.strafe); break; } - Logger.Debug("Corsair SDK reported device as: {0}", _keyboard.DeviceInfo.Model); - Slug = "corsair-" + _keyboard.DeviceInfo.Model.Replace(' ', '-').ToLower(); + Logger.Debug("Corsair SDK reported device as: {0}", _keyboard.DeviceInfo.Model); _keyboard.Brush = _keyboardBrush ?? (_keyboardBrush = new ImageBrush()); } @@ -106,5 +116,28 @@ namespace Artemis.DeviceProviders.Corsair image.Dispose(); } + + public override KeyMatch? GetKeyPosition(Keys keyCode) + { + var widthMultiplier = Width/_keyboard.KeyboardRectangle.Width; + var heightMultiplier = Height/_keyboard.KeyboardRectangle.Height; + + CorsairKey cueKey = null; + try + { + cueKey = _keyboard.Keys.FirstOrDefault(k => k.KeyId.ToString() == keyCode.ToString()) ?? + _keyboard.Keys.FirstOrDefault(k => k.KeyId == KeyMap.FormsKeys[keyCode]); + } + catch (Exception) + { + // ignored + } + + if (cueKey != null) + return new KeyMatch(keyCode, (int) (cueKey.KeyRectangle.X*widthMultiplier), + (int) (cueKey.KeyRectangle.Y*heightMultiplier)); + + return null; + } } } \ No newline at end of file diff --git a/Artemis/Artemis/DeviceProviders/Corsair/Utilities/KeyMap.cs b/Artemis/Artemis/DeviceProviders/Corsair/Utilities/KeyMap.cs new file mode 100644 index 000000000..aa8f34795 --- /dev/null +++ b/Artemis/Artemis/DeviceProviders/Corsair/Utilities/KeyMap.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.Windows.Forms; +using CUE.NET.Devices.Keyboard.Enums; +using CUE.NET.Devices.Keyboard.Keys; + +namespace Artemis.DeviceProviders.Corsair.Utilities +{ + public static class KeyMap + { + static KeyMap() + { + FormsKeys = new Dictionary + { + {Keys.Scroll, CorsairKeyboardKeyId.ScrollLock}, + {Keys.Pause, CorsairKeyboardKeyId.PauseBreak}, + {Keys.Back, CorsairKeyboardKeyId.Backspace}, + {Keys.Oemtilde, CorsairKeyboardKeyId.GraveAccentAndTilde}, + {Keys.OemMinus, CorsairKeyboardKeyId.MinusAndUnderscore}, + {Keys.Oemplus, CorsairKeyboardKeyId.EqualsAndPlus}, + {Keys.OemOpenBrackets, CorsairKeyboardKeyId.BracketLeft}, + {Keys.Oem6, CorsairKeyboardKeyId.BracketRight}, + {Keys.Return, CorsairKeyboardKeyId.Enter}, + {Keys.Next, CorsairKeyboardKeyId.PageDown}, + {Keys.Capital, CorsairKeyboardKeyId.CapsLock}, + {Keys.Oem1, CorsairKeyboardKeyId.SemicolonAndColon}, + {Keys.Oem7, CorsairKeyboardKeyId.ApostropheAndDoubleQuote}, + {Keys.OemBackslash, CorsairKeyboardKeyId.Backslash}, + {Keys.LShiftKey, CorsairKeyboardKeyId.LeftShift}, + {Keys.Oem5, CorsairKeyboardKeyId.NonUsBackslash}, + {Keys.Oemcomma, CorsairKeyboardKeyId.CommaAndLessThan}, + {Keys.OemPeriod, CorsairKeyboardKeyId.PeriodAndBiggerThan}, + {Keys.OemQuestion, CorsairKeyboardKeyId.SlashAndQuestionMark}, + {Keys.RShiftKey, CorsairKeyboardKeyId.RightShift}, + {Keys.LControlKey, CorsairKeyboardKeyId.LeftCtrl}, + {Keys.LWin, CorsairKeyboardKeyId.LeftGui}, + {Keys.LMenu, CorsairKeyboardKeyId.LeftAlt}, + {Keys.RMenu, CorsairKeyboardKeyId.RightAlt}, + {Keys.RWin, CorsairKeyboardKeyId.RightGui}, + {Keys.Apps, CorsairKeyboardKeyId.Application}, + {Keys.RControlKey, CorsairKeyboardKeyId.RightCtrl}, + {Keys.Left, CorsairKeyboardKeyId.LeftArrow}, + {Keys.Down, CorsairKeyboardKeyId.DownArrow}, + {Keys.Right, CorsairKeyboardKeyId.RightArrow}, + {Keys.Up, CorsairKeyboardKeyId.UpArrow}, + {Keys.NumPad0, CorsairKeyboardKeyId.Keypad0}, + {Keys.NumPad1, CorsairKeyboardKeyId.Keypad1}, + {Keys.NumPad2, CorsairKeyboardKeyId.Keypad2}, + {Keys.NumPad3, CorsairKeyboardKeyId.Keypad3}, + {Keys.NumPad4, CorsairKeyboardKeyId.Keypad4}, + {Keys.NumPad5, CorsairKeyboardKeyId.Keypad5}, + {Keys.NumPad6, CorsairKeyboardKeyId.Keypad6}, + {Keys.NumPad7, CorsairKeyboardKeyId.Keypad7}, + {Keys.NumPad8, CorsairKeyboardKeyId.Keypad8}, + {Keys.NumPad9, CorsairKeyboardKeyId.Keypad9}, + {Keys.Divide, CorsairKeyboardKeyId.KeypadSlash}, + {Keys.Multiply, CorsairKeyboardKeyId.KeypadAsterisk}, + {Keys.Subtract, CorsairKeyboardKeyId.KeypadMinus}, + {Keys.Add, CorsairKeyboardKeyId.KeypadPlus}, + {Keys.Decimal, CorsairKeyboardKeyId.KeypadPeriodAndDelete}, + {Keys.MediaStop, CorsairKeyboardKeyId.Stop}, + {Keys.MediaPreviousTrack, CorsairKeyboardKeyId.ScanPreviousTrack}, + {Keys.MediaNextTrack, CorsairKeyboardKeyId.ScanNextTrack}, + {Keys.MediaPlayPause, CorsairKeyboardKeyId.PlayPause}, + {Keys.VolumeMute, CorsairKeyboardKeyId.Mute}, + {Keys.VolumeUp, CorsairKeyboardKeyId.VolumeUp}, + {Keys.VolumeDown, CorsairKeyboardKeyId.VolumeDown} + }; + } + + public static Dictionary FormsKeys { get; set; } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs index 887f4be74..b4cf7f1e4 100644 --- a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs +++ b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs @@ -3,6 +3,7 @@ using System.Drawing; using System.Threading; using System.Threading.Tasks; using System.Windows; +using System.Windows.Forms; using MahApps.Metro.Controls.Dialogs; using Size = System.Windows.Size; @@ -96,6 +97,27 @@ namespace Artemis.DeviceProviders throw new NotImplementedException( "KeyboardProvider doesn't implement TryEnable, use CanEnableAsync instead."); } + + /// + /// Returns the real life X and Y coordinates of the given key + /// + /// + /// + public abstract KeyMatch? GetKeyPosition(Keys keyCode); + } + + public struct KeyMatch + { + public KeyMatch(Keys keyCode, int x, int y) + { + KeyCode = keyCode; + X = x; + Y = y; + } + + public Keys KeyCode { get; set; } + public int X { get; set; } + public int Y { get; set; } } public struct PreviewSettings diff --git a/Artemis/Artemis/DeviceProviders/Logitech/G810.cs b/Artemis/Artemis/DeviceProviders/Logitech/G810.cs index 8c7b35fbb..04163d171 100644 --- a/Artemis/Artemis/DeviceProviders/Logitech/G810.cs +++ b/Artemis/Artemis/DeviceProviders/Logitech/G810.cs @@ -1,4 +1,7 @@ -using System.Windows; +using System.Linq; +using System.Windows; +using System.Windows.Forms; +using Artemis.DeviceProviders.Logitech.Utilities; using Artemis.Properties; namespace Artemis.DeviceProviders.Logitech @@ -17,5 +20,10 @@ namespace Artemis.DeviceProviders.Logitech Width = 21; PreviewSettings = new PreviewSettings(675, 185, new Thickness(0, 35, 0, 0), Resources.g810); } + + public override KeyMatch? GetKeyPosition(Keys keyCode) + { + return KeyMap.UsEnglishOrionKeys.FirstOrDefault(k => k.KeyCode == keyCode); + } } } \ No newline at end of file diff --git a/Artemis/Artemis/DeviceProviders/Logitech/G910.cs b/Artemis/Artemis/DeviceProviders/Logitech/G910.cs index 6a335d180..ac481e9a0 100644 --- a/Artemis/Artemis/DeviceProviders/Logitech/G910.cs +++ b/Artemis/Artemis/DeviceProviders/Logitech/G910.cs @@ -1,4 +1,7 @@ -using System.Windows; +using System.Linq; +using System.Windows; +using System.Windows.Forms; +using Artemis.DeviceProviders.Logitech.Utilities; using Artemis.Properties; namespace Artemis.DeviceProviders.Logitech @@ -17,5 +20,10 @@ namespace Artemis.DeviceProviders.Logitech Width = 21; PreviewSettings = new PreviewSettings(540, 154, new Thickness(25, -80, 0, 0), Resources.g910); } + + public override KeyMatch? GetKeyPosition(Keys keyCode) + { + return KeyMap.UsEnglishOrionKeys.FirstOrDefault(k => k.KeyCode == keyCode); + } } } \ No newline at end of file diff --git a/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs b/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs index 32d9cc77d..8ad21c937 100644 --- a/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs +++ b/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs @@ -3,7 +3,7 @@ using System.Threading; using System.Windows; using Artemis.DeviceProviders.Logitech.Utilities; using Artemis.Utilities; -using Artemis.Utilities.LogitechDll; +using Artemis.Utilities.DataReaders; using Microsoft.Win32; namespace Artemis.DeviceProviders.Logitech @@ -24,7 +24,7 @@ namespace Artemis.DeviceProviders.Logitech return false; } - if (DllManager.RestoreDll()) + if (DllManager.RestoreLogitechDll()) RestoreDll(); int majorNum = 0, minorNum = 0, buildNum = 0; diff --git a/Artemis/Artemis/DeviceProviders/Logitech/Utilities/KeyMap.cs b/Artemis/Artemis/DeviceProviders/Logitech/Utilities/KeyMap.cs index f5ca002fc..6a8506a83 100644 --- a/Artemis/Artemis/DeviceProviders/Logitech/Utilities/KeyMap.cs +++ b/Artemis/Artemis/DeviceProviders/Logitech/Utilities/KeyMap.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Windows.Forms; -using Artemis.Utilities.Keyboard; namespace Artemis.DeviceProviders.Logitech.Utilities { @@ -10,128 +9,128 @@ namespace Artemis.DeviceProviders.Logitech.Utilities { // There are several keyboard layouts // TODO: Implemented more layouts and an option to select them - UsEnglishOrionKeys = new List + UsEnglishOrionKeys = new List { // Row 1 - new Key(Keys.Escape, 0, 0), - new Key(Keys.F1, 1, 0), - new Key(Keys.F2, 2, 0), - new Key(Keys.F3, 3, 0), - new Key(Keys.F4, 4, 0), - new Key(Keys.F5, 5, 0), - new Key(Keys.F6, 6, 0), - new Key(Keys.F7, 7, 0), - new Key(Keys.F8, 8, 0), - new Key(Keys.F9, 9, 0), - new Key(Keys.F10, 10, 0), - new Key(Keys.F11, 11, 0), - new Key(Keys.F12, 12, 0), - new Key(Keys.PrintScreen, 13, 0), - new Key(Keys.Scroll, 14, 0), - new Key(Keys.Pause, 15, 0), + new KeyMatch(Keys.Escape, 0, 0), + new KeyMatch(Keys.F1, 1, 0), + new KeyMatch(Keys.F2, 2, 0), + new KeyMatch(Keys.F3, 3, 0), + new KeyMatch(Keys.F4, 4, 0), + new KeyMatch(Keys.F5, 5, 0), + new KeyMatch(Keys.F6, 6, 0), + new KeyMatch(Keys.F7, 7, 0), + new KeyMatch(Keys.F8, 8, 0), + new KeyMatch(Keys.F9, 9, 0), + new KeyMatch(Keys.F10, 10, 0), + new KeyMatch(Keys.F11, 11, 0), + new KeyMatch(Keys.F12, 12, 0), + new KeyMatch(Keys.PrintScreen, 13, 0), + new KeyMatch(Keys.Scroll, 14, 0), + new KeyMatch(Keys.Pause, 15, 0), // Row 2 - new Key(Keys.Oemtilde, 0, 1), - new Key(Keys.D1, 1, 1), - new Key(Keys.D2, 2, 1), - new Key(Keys.D3, 3, 1), - new Key(Keys.D4, 4, 1), - new Key(Keys.D5, 5, 1), - new Key(Keys.D6, 6, 1), - new Key(Keys.D7, 7, 1), - new Key(Keys.D8, 8, 1), - new Key(Keys.D9, 9, 1), - new Key(Keys.D0, 10, 1), - new Key(Keys.OemMinus, 11, 1), - new Key(Keys.Oemplus, 12, 1), - new Key(Keys.Back, 13, 1), - new Key(Keys.Insert, 14, 1), - new Key(Keys.Home, 15, 1), - new Key(Keys.PageUp, 16, 1), - new Key(Keys.NumLock, 17, 1), - new Key(Keys.Divide, 18, 1), - new Key(Keys.Multiply, 19, 1), - new Key(Keys.Subtract, 20, 1), + new KeyMatch(Keys.Oemtilde, 0, 1), + new KeyMatch(Keys.D1, 1, 1), + new KeyMatch(Keys.D2, 2, 1), + new KeyMatch(Keys.D3, 3, 1), + new KeyMatch(Keys.D4, 4, 1), + new KeyMatch(Keys.D5, 5, 1), + new KeyMatch(Keys.D6, 6, 1), + new KeyMatch(Keys.D7, 7, 1), + new KeyMatch(Keys.D8, 8, 1), + new KeyMatch(Keys.D9, 9, 1), + new KeyMatch(Keys.D0, 10, 1), + new KeyMatch(Keys.OemMinus, 11, 1), + new KeyMatch(Keys.Oemplus, 12, 1), + new KeyMatch(Keys.Back, 13, 1), + new KeyMatch(Keys.Insert, 14, 1), + new KeyMatch(Keys.Home, 15, 1), + new KeyMatch(Keys.PageUp, 16, 1), + new KeyMatch(Keys.NumLock, 17, 1), + new KeyMatch(Keys.Divide, 18, 1), + new KeyMatch(Keys.Multiply, 19, 1), + new KeyMatch(Keys.Subtract, 20, 1), // Row 3 - new Key(Keys.Tab, 0, 2), - new Key(Keys.Q, 1, 2), - new Key(Keys.W, 2, 2), - new Key(Keys.E, 3, 2), - new Key(Keys.R, 4, 2), - new Key(Keys.T, 5, 2), - new Key(Keys.Y, 6, 2), - new Key(Keys.U, 7, 2), - new Key(Keys.I, 8, 2), - new Key(Keys.O, 9, 2), - new Key(Keys.P, 10, 2), - new Key(Keys.OemOpenBrackets, 11, 2), - new Key(Keys.Oem6, 12, 2), - new Key(Keys.Delete, 14, 2), - new Key(Keys.End, 15, 2), - new Key(Keys.Next, 16, 2), - new Key(Keys.NumPad7, 17, 2), - new Key(Keys.NumPad8, 18, 2), - new Key(Keys.NumPad9, 19, 2), - new Key(Keys.Add, 20, 2), + new KeyMatch(Keys.Tab, 0, 2), + new KeyMatch(Keys.Q, 1, 2), + new KeyMatch(Keys.W, 2, 2), + new KeyMatch(Keys.E, 3, 2), + new KeyMatch(Keys.R, 4, 2), + new KeyMatch(Keys.T, 5, 2), + new KeyMatch(Keys.Y, 6, 2), + new KeyMatch(Keys.U, 7, 2), + new KeyMatch(Keys.I, 8, 2), + new KeyMatch(Keys.O, 9, 2), + new KeyMatch(Keys.P, 10, 2), + new KeyMatch(Keys.OemOpenBrackets, 11, 2), + new KeyMatch(Keys.Oem6, 12, 2), + new KeyMatch(Keys.Delete, 14, 2), + new KeyMatch(Keys.End, 15, 2), + new KeyMatch(Keys.Next, 16, 2), + new KeyMatch(Keys.NumPad7, 17, 2), + new KeyMatch(Keys.NumPad8, 18, 2), + new KeyMatch(Keys.NumPad9, 19, 2), + new KeyMatch(Keys.Add, 20, 2), // Row 4 - new Key(Keys.Capital, 0, 3), - new Key(Keys.A, 1, 3), - new Key(Keys.S, 2, 3), - new Key(Keys.D, 3, 3), - new Key(Keys.F, 4, 3), - new Key(Keys.G, 5, 3), - new Key(Keys.H, 6, 3), - new Key(Keys.J, 7, 3), - new Key(Keys.K, 8, 3), - new Key(Keys.L, 9, 3), - new Key(Keys.Oem1, 10, 3), - new Key(Keys.Oem7, 11, 3), - new Key(Keys.Oem5, 12, 3), - new Key(Keys.Return, 13, 3), - new Key(Keys.NumPad4, 17, 3), - new Key(Keys.NumPad5, 18, 3), - new Key(Keys.NumPad6, 19, 3), + new KeyMatch(Keys.Capital, 0, 3), + new KeyMatch(Keys.A, 1, 3), + new KeyMatch(Keys.S, 2, 3), + new KeyMatch(Keys.D, 3, 3), + new KeyMatch(Keys.F, 4, 3), + new KeyMatch(Keys.G, 5, 3), + new KeyMatch(Keys.H, 6, 3), + new KeyMatch(Keys.J, 7, 3), + new KeyMatch(Keys.K, 8, 3), + new KeyMatch(Keys.L, 9, 3), + new KeyMatch(Keys.Oem1, 10, 3), + new KeyMatch(Keys.Oem7, 11, 3), + new KeyMatch(Keys.Oem5, 12, 3), + new KeyMatch(Keys.Return, 13, 3), + new KeyMatch(Keys.NumPad4, 17, 3), + new KeyMatch(Keys.NumPad5, 18, 3), + new KeyMatch(Keys.NumPad6, 19, 3), // Row 5 - new Key(Keys.LShiftKey, 1, 4), - new Key(Keys.OemBackslash, 2, 4), - new Key(Keys.Z, 2, 4), - new Key(Keys.X, 3, 4), - new Key(Keys.C, 4, 4), - new Key(Keys.V, 5, 4), - new Key(Keys.B, 6, 4), - new Key(Keys.N, 7, 4), - new Key(Keys.M, 8, 4), - new Key(Keys.Oemcomma, 9, 4), - new Key(Keys.OemPeriod, 10, 4), - new Key(Keys.OemQuestion, 11, 4), - new Key(Keys.RShiftKey, 13, 4), - new Key(Keys.Up, 15, 4), - new Key(Keys.NumPad1, 17, 4), - new Key(Keys.NumPad2, 18, 4), - new Key(Keys.NumPad3, 19, 4), + new KeyMatch(Keys.LShiftKey, 1, 4), + new KeyMatch(Keys.OemBackslash, 2, 4), + new KeyMatch(Keys.Z, 2, 4), + new KeyMatch(Keys.X, 3, 4), + new KeyMatch(Keys.C, 4, 4), + new KeyMatch(Keys.V, 5, 4), + new KeyMatch(Keys.B, 6, 4), + new KeyMatch(Keys.N, 7, 4), + new KeyMatch(Keys.M, 8, 4), + new KeyMatch(Keys.Oemcomma, 9, 4), + new KeyMatch(Keys.OemPeriod, 10, 4), + new KeyMatch(Keys.OemQuestion, 11, 4), + new KeyMatch(Keys.RShiftKey, 13, 4), + new KeyMatch(Keys.Up, 15, 4), + new KeyMatch(Keys.NumPad1, 17, 4), + new KeyMatch(Keys.NumPad2, 18, 4), + new KeyMatch(Keys.NumPad3, 19, 4), // Both returns return "Return" (Yes...) // new OrionKey(System.Windows.Forms.Keys.Return, 20, 4), // Row 6 - new Key(Keys.LControlKey, 0, 5), - new Key(Keys.LWin, 1, 5), - new Key(Keys.LMenu, 2, 5), - new Key(Keys.Space, 5, 5), - new Key(Keys.RMenu, 11, 5), - new Key(Keys.RWin, 12, 5), - new Key(Keys.Apps, 13, 5), - new Key(Keys.RControlKey, 14, 5), - new Key(Keys.Left, 15, 5), - new Key(Keys.Down, 16, 5), - new Key(Keys.Right, 17, 5), - new Key(Keys.NumPad0, 18, 5), - new Key(Keys.Decimal, 19, 5) + new KeyMatch(Keys.LControlKey, 0, 5), + new KeyMatch(Keys.LWin, 1, 5), + new KeyMatch(Keys.LMenu, 2, 5), + new KeyMatch(Keys.Space, 5, 5), + new KeyMatch(Keys.RMenu, 11, 5), + new KeyMatch(Keys.RWin, 12, 5), + new KeyMatch(Keys.Apps, 13, 5), + new KeyMatch(Keys.RControlKey, 14, 5), + new KeyMatch(Keys.Left, 15, 5), + new KeyMatch(Keys.Down, 16, 5), + new KeyMatch(Keys.Right, 17, 5), + new KeyMatch(Keys.NumPad0, 18, 5), + new KeyMatch(Keys.Decimal, 19, 5) }; } - public static List UsEnglishOrionKeys { get; set; } + public static List UsEnglishOrionKeys { get; set; } } } \ No newline at end of file diff --git a/Artemis/Artemis/DeviceProviders/Razer/BlackWidow.cs b/Artemis/Artemis/DeviceProviders/Razer/BlackWidow.cs index 3f1bd656a..588640cf5 100644 --- a/Artemis/Artemis/DeviceProviders/Razer/BlackWidow.cs +++ b/Artemis/Artemis/DeviceProviders/Razer/BlackWidow.cs @@ -1,9 +1,13 @@ using System.Drawing; +using System.Linq; using System.Windows; +using System.Windows.Forms; +using Artemis.DeviceProviders.Logitech.Utilities; using Artemis.DeviceProviders.Razer.Utilities; using Artemis.Properties; using Corale.Colore.Core; using Corale.Colore.Razer; +using Corale.Colore.Razer.Keyboard; using Constants = Corale.Colore.Razer.Keyboard.Constants; namespace Artemis.DeviceProviders.Razer @@ -49,5 +53,11 @@ namespace Artemis.DeviceProviders.Razer var razerArray = RazerUtilities.BitmapColorArray(bitmap, Height, Width); Chroma.Instance.Keyboard.SetCustom(razerArray); } + + public override KeyMatch? GetKeyPosition(Keys keyCode) + { + // TODO: Needs it's own keymap or a way to get it from the Chroma SDK + return KeyMap.UsEnglishOrionKeys.FirstOrDefault(k => k.KeyCode == keyCode); + } } } \ No newline at end of file diff --git a/Artemis/Artemis/InjectionModules/ArtemisModules.cs b/Artemis/Artemis/InjectionModules/ArtemisModules.cs index 9c23101b9..7347d9e09 100644 --- a/Artemis/Artemis/InjectionModules/ArtemisModules.cs +++ b/Artemis/Artemis/InjectionModules/ArtemisModules.cs @@ -21,6 +21,7 @@ using Artemis.Profiles.Layers.Types.Generic; using Artemis.Profiles.Layers.Types.Headset; using Artemis.Profiles.Layers.Types.Keyboard; using Artemis.Profiles.Layers.Types.KeyboardGif; +using Artemis.Profiles.Layers.Types.KeyPress; using Artemis.Profiles.Layers.Types.Mouse; using Artemis.ViewModels.Abstract; using Ninject.Modules; @@ -78,9 +79,11 @@ namespace Artemis.InjectionModules Bind().To(); Bind().To(); Bind().To(); + // Conditions Bind().To(); Bind().To(); + // Types Bind().To(); Bind().To(); @@ -88,6 +91,10 @@ namespace Artemis.InjectionModules Bind().To(); Bind().To(); Bind().To(); + Bind().To(); + + // Bind some Layer Types to self as well in order to allow JSON.NET injection + Bind().ToSelf(); #endregion } diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs index 56a357077..a8f91935a 100644 --- a/Artemis/Artemis/Managers/LoopManager.cs +++ b/Artemis/Artemis/Managers/LoopManager.cs @@ -168,9 +168,16 @@ namespace Artemis.Managers public RenderFrame(KeyboardProvider keyboard) { KeyboardBitmap = keyboard.KeyboardBitmap(4); + KeyboardBitmap.SetResolution(96, 96); + MouseBitmap = new Bitmap(40, 40); + MouseBitmap.SetResolution(96, 96); + HeadsetBitmap = new Bitmap(40, 40); + HeadsetBitmap.SetResolution(96, 96); + GenericBitmap = new Bitmap(40, 40); + GenericBitmap.SetResolution(96, 96); using (var g = Graphics.FromImage(KeyboardBitmap)) g.Clear(Color.Black); diff --git a/Artemis/Artemis/Managers/MainManager.cs b/Artemis/Artemis/Managers/MainManager.cs index 1d2693896..bec1c129d 100644 --- a/Artemis/Artemis/Managers/MainManager.cs +++ b/Artemis/Artemis/Managers/MainManager.cs @@ -5,9 +5,9 @@ using System.Timers; using Artemis.Events; using Artemis.Models; using Artemis.Modules.Effects.ProfilePreview; +using Artemis.Utilities.DataReaders; using Artemis.Utilities.GameState; using Artemis.Utilities.Keyboard; -using Artemis.Utilities.LogitechDll; using Artemis.ViewModels; using Caliburn.Micro; using Ninject; @@ -43,9 +43,6 @@ namespace Artemis.Managers ProgramEnabled = false; Running = false; - // TODO: Dependency inject utilities? - KeyboardHook = new KeyboardHook(); - // Create and start the web server GameStateWebServer = new GameStateWebServer(); GameStateWebServer.Start(); @@ -67,7 +64,6 @@ namespace Artemis.Managers public ProfileManager ProfileManager { get; set; } public PipeServer PipeServer { get; set; } - public KeyboardHook KeyboardHook { get; set; } public GameStateWebServer GameStateWebServer { get; set; } public bool ProgramEnabled { get; private set; } public bool Running { get; private set; } @@ -116,7 +112,7 @@ namespace Artemis.Managers if (!ProgramEnabled) return; - var runningProcesses = Process.GetProcesses(); + var runningProcesses = System.Diagnostics.Process.GetProcesses(); // If the currently active effect is a disabled game, get rid of it. if (EffectManager.ActiveEffect != null) diff --git a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWave.Designer.cs b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWave.Designer.cs index a40e4b8cd..6fda6a5f0 100644 --- a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWave.Designer.cs +++ b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWave.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Artemis.Settings { +namespace Artemis.Modules.Effects.TypeWave { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] diff --git a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs index ff4eb66fa..2326f1dcc 100644 --- a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs +++ b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs @@ -1,13 +1,12 @@ using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; -using System.Linq; using System.Windows.Forms; -using Artemis.DeviceProviders.Logitech.Utilities; using Artemis.Managers; using Artemis.Models; using Artemis.Profiles.Layers.Models; using Artemis.Utilities; +using Artemis.Utilities.Keyboard; namespace Artemis.Modules.Effects.TypeWave { @@ -30,7 +29,7 @@ namespace Artemis.Modules.Effects.TypeWave public override void Dispose() { Initialized = false; - MainManager.KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback; + KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback; } private void KeyboardHookOnKeyDownCallback(KeyEventArgs e) @@ -39,23 +38,19 @@ namespace Artemis.Modules.Effects.TypeWave if (_waves.Count >= 25) return; - var keyMatch = KeyMap.UsEnglishOrionKeys.FirstOrDefault(k => k.KeyCode == e.KeyCode); + var keyMatch = MainManager.DeviceManager.ActiveKeyboard.GetKeyPosition(e.KeyCode); if (keyMatch == null) return; _waves.Add(Settings.IsRandomColors - ? new Wave(new Point(keyMatch.PosX*KeyboardScale, keyMatch.PosY*KeyboardScale), 0, _randomColor) - : new Wave(new Point(keyMatch.PosX*KeyboardScale, keyMatch.PosY*KeyboardScale), 0, + ? new Wave(new Point(keyMatch.Value.X*KeyboardScale, keyMatch.Value.Y*KeyboardScale), 0, _randomColor) + : new Wave(new Point(keyMatch.Value.X*KeyboardScale, keyMatch.Value.Y*KeyboardScale), 0, ColorHelpers.ToDrawingColor(Settings.WaveColor))); } public override void Enable() { - Initialized = false; - - // Listener won't start unless the effect is active - MainManager.KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback; - + KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback; Initialized = true; } diff --git a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveSettings.cs b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveSettings.cs index 2f8876e4e..66f3820bc 100644 --- a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveSettings.cs +++ b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveSettings.cs @@ -19,24 +19,24 @@ namespace Artemis.Modules.Effects.TypeWave public sealed override void Load() { - IsRandomColors = Settings.TypeWave.Default.IsRandomColors; - WaveColor = Settings.TypeWave.Default.WaveColor; - IsShiftColors = Settings.TypeWave.Default.IsShiftColors; - ShiftColorSpeed = Settings.TypeWave.Default.ShiftColorSpeed; - TimeToLive = Settings.TypeWave.Default.TimeToLive; - SpreadSpeed = Settings.TypeWave.Default.SpreadSpeed; + IsRandomColors = TypeWave.Default.IsRandomColors; + WaveColor = TypeWave.Default.WaveColor; + IsShiftColors = TypeWave.Default.IsShiftColors; + ShiftColorSpeed = TypeWave.Default.ShiftColorSpeed; + TimeToLive = TypeWave.Default.TimeToLive; + SpreadSpeed = TypeWave.Default.SpreadSpeed; } public sealed override void Save() { - Settings.TypeWave.Default.IsRandomColors = IsRandomColors; - Settings.TypeWave.Default.WaveColor = WaveColor; - Settings.TypeWave.Default.IsShiftColors = IsShiftColors; - Settings.TypeWave.Default.ShiftColorSpeed = ShiftColorSpeed; - Settings.TypeWave.Default.TimeToLive = TimeToLive; - Settings.TypeWave.Default.SpreadSpeed = SpreadSpeed; + TypeWave.Default.IsRandomColors = IsRandomColors; + TypeWave.Default.WaveColor = WaveColor; + TypeWave.Default.IsShiftColors = IsShiftColors; + TypeWave.Default.ShiftColorSpeed = ShiftColorSpeed; + TypeWave.Default.TimeToLive = TimeToLive; + TypeWave.Default.SpreadSpeed = SpreadSpeed; - Settings.TypeWave.Default.Save(); + TypeWave.Default.Save(); } public sealed override void ToDefault() diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs index 3fa5f39fc..618d90564 100644 --- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs +++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Windows.Media; using Artemis.Events; using Artemis.Managers; @@ -8,7 +9,6 @@ using Artemis.Models; using Artemis.Models.Interfaces; using Artemis.Profiles.Layers.Models; using Artemis.Utilities; -using Artemis.Utilities.DataReaders; using Caliburn.Micro; namespace Artemis.Modules.Games.Overwatch @@ -17,6 +17,7 @@ namespace Artemis.Modules.Games.Overwatch { private readonly IEventAggregator _events; private DateTime _characterChange; + private string _lastMessage; // Using sticky values on these since they can cause flickering private StickyValue _stickyStatus; private StickyValue _stickyUltimateReady; @@ -34,7 +35,6 @@ namespace Artemis.Modules.Games.Overwatch Enabled = Settings.Enabled; Initialized = false; - MmfReader = new MmfReader("overwatchMmf", MainManager.Logger); LoadOverwatchCharacters(); } @@ -45,8 +45,6 @@ namespace Artemis.Modules.Games.Overwatch public List OverwatchCharacters { get; set; } - public MmfReader MmfReader { get; set; } - public int Scale { get; set; } private void LoadOverwatchCharacters() @@ -82,15 +80,27 @@ namespace Artemis.Modules.Games.Overwatch _stickyStatus = new StickyValue(300); _stickyUltimateReady = new StickyValue(350); _stickyUltimateUsed = new StickyValue(350); + MainManager.PipeServer.PipeMessage += PipeServerOnPipeMessage; + Initialized = true; } public override void Dispose() { + Initialized = false; + _stickyStatus.Dispose(); _stickyUltimateReady.Dispose(); _stickyUltimateUsed.Dispose(); - Initialized = false; + + MainManager.PipeServer.PipeMessage -= PipeServerOnPipeMessage; + } + + private void PipeServerOnPipeMessage(string message) + { + + _lastMessage = message; + } public override void Update() @@ -110,7 +120,12 @@ namespace Artemis.Modules.Games.Overwatch public void UpdateOverwatch() { var gameDataModel = (OverwatchDataModel) DataModel; - var colors = MmfReader.GetColorArray(); + + if (_lastMessage == null) + return; + + var colors = ParseColorArray(_lastMessage); + if (colors == null) return; @@ -135,6 +150,41 @@ namespace Artemis.Modules.Games.Overwatch ParseAbilities(gameDataModel, colors); } + public Color[,] ParseColorArray(string arrayString) + { + if (string.IsNullOrEmpty(arrayString)) + return null; + var intermediateArray = arrayString.Split('|'); + if (intermediateArray[0] == "1" || intermediateArray.Length < 2) + return null; + var array = intermediateArray[1].Substring(1).Split(' '); + if (!array.Any()) + return null; + + try + { + var colors = new Color[6, 22]; + foreach (var intermediate in array) + { + if (intermediate.Length > 16) + continue; + + // Can't parse to a byte directly since it may contain values >254 + var parts = intermediate.Split(',').Select(int.Parse).ToArray(); + if (parts[0] >= 5 && parts[1] >= 21) + continue; + + colors[parts[0], parts[1]] = Color.FromRgb((byte) parts[2], (byte) parts[3], (byte) parts[4]); + } + return colors; + } + catch (FormatException e) + { + MainManager.Logger.Trace(e, "Failed to parse to color array"); + return null; + } + } + private void ParseGameSate(OverwatchDataModel gameDataModel, Color[,] colors) { if (_ultimateUsed.AddSeconds(5) >= DateTime.Now) diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs index 494e60558..c02fd90a6 100644 --- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs +++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs @@ -1,9 +1,8 @@ -using System; -using System.IO; +using System.IO; using System.Windows.Forms; using Artemis.InjectionFactories; using Artemis.Managers; -using Artemis.Properties; +using Artemis.Utilities.DataReaders; using Artemis.ViewModels.Abstract; using Caliburn.Micro; using Microsoft.Win32; @@ -72,14 +71,7 @@ namespace Artemis.Modules.Games.Overwatch 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."); - } + DllManager.PlaceRazerDll(path); } } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs index 9b7ad7f25..6895b0a34 100644 --- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs +++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs @@ -81,15 +81,6 @@ namespace Artemis.Modules.Games.RocketLeague boostInt = 0; ((RocketLeagueDataModel) DataModel).Boost = boostInt; - - if (DateTime.Now.AddSeconds(-2) <= LastTrace) - return; - - MainManager.Logger.Trace("Offsets as JSON: \r\n{0}", - JsonConvert.SerializeObject(_pointer.GameAddresses, Formatting.Indented)); - MainManager.Logger.Trace("RL specific offsets: {0}", offsets); - MainManager.Logger.Trace("Boost address: {0}", boostAddress); - MainManager.Logger.Trace("Boost int: {0}", boostInt); } public override List GetRenderLayers(bool keyboardOnly) diff --git a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs index a817bd567..8f7cdb600 100644 --- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs +++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs @@ -5,7 +5,7 @@ using Artemis.Managers; using Artemis.Models; using Artemis.Profiles.Layers.Models; using Artemis.Utilities; -using Artemis.Utilities.LogitechDll; +using Artemis.Utilities.DataReaders; namespace Artemis.Modules.Games.TheDivision { @@ -34,11 +34,13 @@ namespace Artemis.Modules.Games.TheDivision Task.Factory.StartNew(() => { Thread.Sleep(2000); - DllManager.RestoreDll(); + DllManager.RestoreLogitechDll(); }); _stickyAmmo.Dispose(); _stickyHp.Dispose(); + + MainManager.PipeServer.PipeMessage -= PipeServerOnPipeMessage; } public override void Enable() @@ -48,7 +50,7 @@ namespace Artemis.Modules.Games.TheDivision _stickyAmmo = new StickyValue(200); _stickyHp = new StickyValue(200); - DllManager.PlaceDll(); + DllManager.PlaceLogitechDll(); MainManager.PipeServer.PipeMessage += PipeServerOnPipeMessage; Initialized = true; diff --git a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs index adee38e81..0b6ba18fd 100644 --- a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs +++ b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs @@ -80,7 +80,7 @@ namespace Artemis.Modules.Games.Witcher3 archive.ExtractToDirectory(folder + @"witcher3-mod", true); - Process.Start(new ProcessStartInfo("https://github.com/SpoinkyNL/Artemis/wiki/The-Witcher-3")); + System.Diagnostics.Process.Start(new ProcessStartInfo("https://github.com/SpoinkyNL/Artemis/wiki/The-Witcher-3")); return; } } diff --git a/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoW.Designer.cs b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoW.Designer.cs new file mode 100644 index 000000000..42350d4e9 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoW.Designer.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace Artemis.Modules.Games.WorldofWarcraft { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] + internal sealed partial class WoW : global::System.Configuration.ApplicationSettingsBase { + + private static WoW defaultInstance = ((WoW)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new WoW()))); + + public static WoW 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; + } + } + } +} diff --git a/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoW.settings b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoW.settings new file mode 100644 index 000000000..c2d66228b --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoW.settings @@ -0,0 +1,12 @@ + + + + + + True + + + Default + + + \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWAddresses.cs b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWAddresses.cs new file mode 100644 index 000000000..5d600759d --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWAddresses.cs @@ -0,0 +1,256 @@ +namespace Artemis.Modules.Games.WorldofWarcraft +{ + public static class WoWAddresses + { + public enum ActivateSettings + { + Activate_Offset = 0x34, + AutoDismount_Activate_Pointer = 0xe56850, + AutoInteract_Activate_Pointer = 0xe56848, + AutoLoot_Activate_Pointer = 0xe56868, + AutoSelfCast_Activate_Pointer = 0xe56874 + } + + public enum Battleground + { + MaxBattlegroundId = 0xec3fdc, + PvpExitWindow = 0xec4198, + StatPvp = 0xc3c03c + } + + public enum Chat + { + chatBufferPos = 0xeb1bf0, + chatBufferStart = 0xe58190, + msgFormatedChat = 0x65, + NextMessage = 0x17e8 + } + + public enum ClickToMove + { + CTM = 0xddf8f0, + CTM_PUSH = 0xddf8ac, + CTM_X = 0xddf918, + CTM_Y = 0xddf91c, + CTM_Z = 0xddf920 + } + + public enum CorpsePlayer + { + X = 0xe57894, + Y = 0xe57898, + Z = 0xe5789c + } + + public enum DBC + { + FactionTemplate = 0, + ItemClass = 0xd173c0, + ItemSubClass = 0, + Lock = 0, + Map = 0xd291a0, + QuestPOIPoint = 0xd1e950, + ResearchSite = 0xd1d2d0, + SpellCategories = 0, + Unknown = 0xf35428 + } + + public enum EventsListener + { + BaseEvents = 0xcb2474, + EventOffsetCount = 0x48, + EventOffsetName = 0x18, + EventsCount = 0xcb2470 + } + + public enum Fishing + { + BobberHasMoved = 0xf8 + } + + public enum FunctionWow + { + CGUnit_C__InitializeTrackingState = 0x30623b, + CGUnit_C__Interact = 0x524ff, + CGWorldFrame__Intersect = 0x5e46ab, + ClntObjMgrGetActivePlayerObj = 0x816d7, + FrameScript__GetLocalizedText = 0x300b48, + FrameScript_ExecuteBuffer = 0xa6772, + IsOutdoors = 0, + Spell_C_HandleTerrainClick = 0x2b76ff, + strlen = 0x74fcb0, + UnitCanAttack = 0, + WowClientDB2__GetRowPointer = 0x20c775 + } + + public enum GameInfo + { + AreaId = 0xc32c2c, + buildWoWVersionString = 0xd002a8, + gameState = 0xe56a49, + GetTime = 0xcb2150, + isLoading = 0xca59b0, + LastHardwareAction = 0xd0e090, + MapTextureId = 0xc3bd28, + SubAreaId = 0xc32c24, + subZoneMap = 0xe56a68, + TextBoxActivated = 0xbbe9ac, + zoneMap = 0xe56a64 + } + + public enum GameObject + { + CachedCastBarCaption = 12, + CachedData0 = 20, + CachedIconName = 8, + CachedName = 180, + CachedQuestItem1 = 0x9c, + CachedSize = 0x98, + DBCacheRow = 620, + GAMEOBJECT_FIELD_X = 0x138, + GAMEOBJECT_FIELD_Y = 0x13c, + GAMEOBJECT_FIELD_Z = 320, + PackedRotationQuaternion = 0x150, + TransformationMatrice = 0x278 + } + + public enum Hooking + { + DX_DEVICE = 0xcc523c, + DX_DEVICE_IDX = 0x2508, + ENDSCENE_IDX = 0xa8 + } + + public enum Login + { + realmName = 0xf35e16 + } + + public enum MovementFlagsOffsets + { + Offset1 = 0x124, + Offset2 = 0x40 + } + + public enum ObjectManager + { + continentId = 0x108, + firstObject = 0xd8, + localGuid = 0xf8, + nextObject = 0x44, + objectGUID = 0x30, + objectTYPE = 0x10 + } + + public class ObjectManagerClass + { + public static uint clientConnection; + public static uint sCurMgr; + } + + public enum Party + { + NumOfPlayers = 200, + NumOfPlayersSuBGroup = 0xcc, + PartyOffset = 0xeb5458, + PlayerGuid = 0x10 + } + + public enum PetBattle + { + IsInBattle = 0xba8a10 + } + + public enum Player + { + LocalPlayerSpellsOnCooldown = 0xd372b8, + petGUID = 0xec7158, + playerName = 0xf35e20, + RetrieveCorpseWindow = 0xe576f4, + RuneStartCooldown = 0xf18aa8, + SkillMaxValue = 0x400, + SkillValue = 0x200 + } + + public enum PlayerNameStore + { + PlayerNameNextOffset = 20, + PlayerNameStorePtr = 0xd0b4e0, + PlayerNameStringOffset = 0x11 + } + + public enum PowerIndex + { + Multiplicator = 0x10, + PowerIndexArrays = 0xddf914 + } + + public enum Quests + { + QuestGiverStatus = 0xf4 + } + + public enum SpellBook + { + FirstTalentBookPtr = 0xeb52ec, + KnownAllSpells = 0xeb5130, + MountBookMountsPtr = 0xeb5194, + MountBookNumMounts = 0xeb5190, + NextTalentBookPtr = 0xeb52e4, + SpellBookNumSpells = 0xeb5134, + SpellBookSpellsPtr = 0xeb5138, + SpellDBCMaxIndex = 0x30d40, + TalentBookOverrideSpellId = 0x1c, + TalentBookSpellId = 20 + } + + public enum UnitBaseGetUnitAura + { + AuraSize = 0x58, + AuraStructCasterLevel = 0x3a, + AuraStructCount = 0x39, + AuraStructCreatorGuid = 0x20, + AuraStructDuration = 60, + AuraStructFlag = 0x34, + AuraStructMask = 0x35, + AuraStructSpellEndTime = 0x40, + AuraStructSpellId = 0x30, + AuraStructUnk1 = 0x3b, + AuraStructUnk2 = 0x44, + AuraTable1 = 0x1150, + AuraTable2 = 0x580 + } + + public enum UnitField + { + CachedIsBoss = 0x60, + CachedModelId1 = 0x6c, + CachedName = 0x80, + CachedQuestItem1 = 60, + CachedSubName = 0, + CachedTypeFlag = 0x24, + CachedUnitClassification = 0x2c, + CanInterrupt = 0xfc4, + CanInterruptOffset = 0xe02ea0, + CanInterruptOffset2 = 0xe02ea4, + CanInterruptOffset3 = 0xe02ea8, + CastingSpellEndTime = 0x108c, + CastingSpellID = 0x1064, + CastingSpellStartTime = 0x1088, + ChannelSpellEndTime = 0x1098, + ChannelSpellID = 0x1090, + ChannelSpellStartTime = 0x1094, + DBCacheRow = 0xc80, + TransportGUID = 0xae8, + UNIT_FIELD_R = 0xb08, + UNIT_FIELD_X = 0xaf8, + UNIT_FIELD_Y = 0xafc, + UNIT_FIELD_Z = 0xb00 + } + + public enum VMT + { + CGUnit_C__GetFacing = 0x35 + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWDataModel.cs b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWDataModel.cs new file mode 100644 index 000000000..aeeb5421a --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWDataModel.cs @@ -0,0 +1,17 @@ +using Artemis.Models.Interfaces; + +namespace Artemis.Modules.Games.WorldofWarcraft +{ + public class WoWDataModel : IDataModel + { + public Player Player { get; set; } = new Player(); + } + + + public class Player + { + public string Name { get; set; } + public int Health { get; set; } + public int MaxHealth { get; set; } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWModel.cs b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWModel.cs new file mode 100644 index 000000000..093e6bd43 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWModel.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using Artemis.Managers; +using Artemis.Models; +using Artemis.Profiles.Layers.Models; +using Artemis.Utilities; +using Artemis.Utilities.Memory; + +namespace Artemis.Modules.Games.WorldofWarcraft +{ + public class WoWModel : GameModel + { + private Memory _memory; + + public WoWModel(MainManager mainManager, WoWSettings settings) + : base(mainManager, settings, new WoWDataModel()) + { + Name = "WoW"; + ProcessName = "Wow-64"; + Scale = 4; + Enabled = Settings.Enabled; + Initialized = false; + } + + public int Scale { get; set; } + + public override void Dispose() + { + Initialized = false; + } + + public override void Enable() + { + var tempProcess = MemoryHelpers.GetProcessIfRunning(ProcessName); + if (tempProcess == null) + return; + + _memory = new Memory(tempProcess); + + Initialized = true; + } + + public override void Update() + { + if (Profile == null || DataModel == null || _memory == null) + return; + +// _memory.ReadMemory(); + } + + public override List GetRenderLayers(bool keyboardOnly) + { + return Profile.GetRenderLayers(DataModel, keyboardOnly); + } + + + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWSettings.cs b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWSettings.cs new file mode 100644 index 000000000..7c04d9de0 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWSettings.cs @@ -0,0 +1,31 @@ +using Artemis.Models; + +namespace Artemis.Modules.Games.WorldofWarcraft +{ + public class WoWSettings : GameSettings + { + public WoWSettings() + { + Load(); + } + + public sealed override void Load() + { + Enabled = WoW.Default.Enabled; + LastProfile = WoW.Default.LastProfile; + } + + public sealed override void Save() + { + WoW.Default.Enabled = Enabled; + WoW.Default.LastProfile = LastProfile; + + WoW.Default.Save(); + } + + public sealed override void ToDefault() + { + Enabled = true; + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWViewModel.cs b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWViewModel.cs new file mode 100644 index 000000000..db4103852 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WorldofWarcraft/WoWViewModel.cs @@ -0,0 +1,17 @@ +using Artemis.InjectionFactories; +using Artemis.Managers; +using Artemis.ViewModels.Abstract; +using Caliburn.Micro; + +namespace Artemis.Modules.Games.WorldofWarcraft +{ + public sealed class WoWViewModel : GameViewModel + { + public WoWViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory) + : base(main, new WoWModel(main, new WoWSettings()), events, pFactory) + { + DisplayName = "World of Warcraft"; + MainManager.EffectManager.EffectModels.Add(GameModel); + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs index d9121701b..5ea452145 100644 --- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs +++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs @@ -5,6 +5,7 @@ using System.Windows.Forms; using Artemis.Managers; using Artemis.Models; using Artemis.Profiles.Layers.Models; +using Artemis.Utilities.Keyboard; using NAudio.CoreAudioApi; namespace Artemis.Modules.Overlays.VolumeDisplay @@ -26,13 +27,13 @@ namespace Artemis.Modules.Overlays.VolumeDisplay public override void Dispose() { - MainManager.KeyboardHook.KeyDownCallback -= KeyPressTask; + KeyboardHook.KeyDownCallback -= KeyPressTask; } public override void Enable() { // Listener won't start unless the effect is active - MainManager.KeyboardHook.KeyDownCallback += KeyPressTask; + KeyboardHook.KeyDownCallback += KeyPressTask; } public override void Update() diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs new file mode 100644 index 000000000..249f4140e --- /dev/null +++ b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs @@ -0,0 +1,120 @@ +using System.Collections.Generic; +using System.Linq; +using System.Windows; +using System.Windows.Forms; +using System.Windows.Media; +using Artemis.Managers; +using Artemis.Models.Interfaces; +using Artemis.Profiles.Layers.Abstract; +using Artemis.Profiles.Layers.Animations; +using Artemis.Profiles.Layers.Interfaces; +using Artemis.Profiles.Layers.Models; +using Artemis.Profiles.Layers.Types.Generic; +using Artemis.Properties; +using Artemis.Utilities; +using Artemis.Utilities.Keyboard; + +namespace Artemis.Profiles.Layers.Types.KeyPress +{ + internal class KeyPressType : ILayerType + { + private readonly MainManager _mainManager; + private List _keyPressLayers = new List(); + private LayerPropertiesModel _properties; + + public KeyPressType(MainManager mainManager) + { + _mainManager = mainManager; + KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback; + } + + public RadialGradientBrush TempBrush { get; set; } + + + public string Name { get; } = "Keyboard - Key press"; + public bool ShowInEdtor { get; } = false; + public DrawType DrawType { get; } = DrawType.Keyboard; + + public ImageSource DrawThumbnail(LayerModel layer) + { + var thumbnailRect = new Rect(0, 0, 18, 18); + var visual = new DrawingVisual(); + using (var c = visual.RenderOpen()) + c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.gif), thumbnailRect); + + var image = new DrawingImage(visual.Drawing); + return image; + } + + public void Draw(LayerModel layer, DrawingContext c) + { + lock (_keyPressLayers) + { + foreach (var keyPressLayer in _keyPressLayers) + keyPressLayer.LayerType.Draw(keyPressLayer, c); + } + } + + public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + { + // Key press is always as large as the entire keyboard it is drawn for + layerModel.Properties.Width = _mainManager.DeviceManager.ActiveKeyboard.Width; + layerModel.Properties.Height = _mainManager.DeviceManager.ActiveKeyboard.Height; + layerModel.Properties.X = 0; + layerModel.Properties.Y = 0; + layerModel.Properties.Contain = true; + + _properties = layerModel.Properties; + + lock (_keyPressLayers) + { + // Remove expired key presses + _keyPressLayers = _keyPressLayers.Where(k => !k.LayerAnimation.MustExpire(k)).ToList(); + // Update the ones that are still active + foreach (var keyPressLayer in _keyPressLayers) + keyPressLayer.Update(null, false, true); + } + } + + public void SetupProperties(LayerModel layerModel) + { + if (layerModel.Properties is SimplePropertiesModel) + return; + + layerModel.Properties = new SimplePropertiesModel(layerModel.Properties); + } + + public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel, + List layerAnimations, IDataModel dataModel, LayerModel proposedLayer) + { + if (layerPropertiesViewModel is GenericPropertiesViewModel) + return layerPropertiesViewModel; + return new GenericPropertiesViewModel(proposedLayer, dataModel, layerAnimations); + } + + private void KeyboardHookOnKeyDownCallback(KeyEventArgs e) + { + if (_properties == null) + return; + + var keyMatch = _mainManager.DeviceManager.ActiveKeyboard.GetKeyPosition(e.KeyCode); + if (keyMatch == null) + return; + + lock (_keyPressLayers) + { + var layer = LayerModel.CreateLayer(); + layer.Properties.Brush = _properties.Brush.CloneCurrentValue(); + layer.Properties.X = keyMatch.Value.X - 3; + layer.Properties.Y = keyMatch.Value.Y - 3; + layer.Properties.Width = 6; + layer.Properties.Height = 6; + + layer.Properties.AnimationSpeed = 1; + layer.LayerAnimation = new GrowAnimation(); + + _keyPressLayers.Add(layer); + } + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs index 4b0e03630..2e96a518f 100644 --- a/Artemis/Artemis/Profiles/ProfileModel.cs +++ b/Artemis/Artemis/Profiles/ProfileModel.cs @@ -63,8 +63,8 @@ namespace Artemis.Profiles // Remove the clip c.Pop(); } - - using (var bmp = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect)) + + using (var bmp = ImageUtilities.DrawingVisualToBitmap(visual, keyboardRect)) keyboard.DrawImage(bmp, new PointF(0, 0)); } @@ -143,7 +143,7 @@ namespace Artemis.Profiles c.Pop(); } - using (var bmp = ImageUtilities.DrawinVisualToBitmap(visual, rect)) + using (var bmp = ImageUtilities.DrawingVisualToBitmap(visual, rect)) g.DrawImage(bmp, new PointF(0, 0)); } @@ -172,7 +172,6 @@ namespace Artemis.Profiles /// /// Resizes layers that are shown in the editor and match exactly the full keyboard widht and height /// - /// The keyboard the profile was made for /// The new keyboard to adjust the layers for public void ResizeLayers(KeyboardProvider target) { diff --git a/Artemis/Artemis/Resources/RzChromaSDK64.dll b/Artemis/Artemis/Resources/RzChromaSDK64.dll index 12fb41954..4ffde6f3e 100644 Binary files a/Artemis/Artemis/Resources/RzChromaSDK64.dll and b/Artemis/Artemis/Resources/RzChromaSDK64.dll differ diff --git a/Artemis/Artemis/Utilities/Converters/NinjectCustomConverter.cs b/Artemis/Artemis/Utilities/Converters/NinjectCustomConverter.cs new file mode 100644 index 000000000..1021a99c7 --- /dev/null +++ b/Artemis/Artemis/Utilities/Converters/NinjectCustomConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json.Serialization; +using Ninject; + +namespace Artemis.Utilities.Converters +{ + public class NinjectContractResolver : DefaultContractResolver + + { + private readonly IKernel _kernel; + + public NinjectContractResolver(IKernel kernel) + { + _kernel = kernel; + } + + protected override JsonObjectContract CreateObjectContract(Type objectType) + + { + var contract = base.CreateObjectContract(objectType); + if ((bool) _kernel.CanResolve(objectType)) + contract.DefaultCreator = () => _kernel.Get(objectType); + return contract; + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Utilities/LogitechDll/DllManager.cs b/Artemis/Artemis/Utilities/DataReaders/DllManager.cs similarity index 78% rename from Artemis/Artemis/Utilities/LogitechDll/DllManager.cs rename to Artemis/Artemis/Utilities/DataReaders/DllManager.cs index 2387e1695..6f82a3b77 100644 --- a/Artemis/Artemis/Utilities/LogitechDll/DllManager.cs +++ b/Artemis/Artemis/Utilities/DataReaders/DllManager.cs @@ -1,91 +1,116 @@ -using System; -using System.IO; -using Artemis.Properties; -using Microsoft.Win32; - -namespace Artemis.Utilities.LogitechDll -{ - internal static class DllManager - { - private const string LogitechPath = @"C:\Program Files\Logitech Gaming Software\SDK\LED\x64\"; - - public static bool RestoreDll() - { - if (!File.Exists(LogitechPath + @"\LogitechLed.dll") || !File.Exists(LogitechPath + @"\artemis.txt")) - return false; - - try - { - // Get rid of our own DLL - File.Delete(LogitechPath + @"\LogitechLed.dll"); - - // Restore the backup - if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak")) - File.Copy(LogitechPath + @"\LogitechLed.dll.bak", LogitechPath + @"\LogitechLed.dll"); - - File.Delete(LogitechPath + @"\artemis.txt"); - - return true; - } - catch (Exception) - { - return false; - } - } - - public static void PlaceDll() - { - if (DllPlaced()) - return; - - // Create directory structure, just in case - Directory.CreateDirectory(LogitechPath + @""); - - // Backup the existing DLL - if (File.Exists(LogitechPath + @"\LogitechLed.dll")) - { - if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak")) - File.Delete(LogitechPath + @"\LogitechLed.dll.bak"); - File.Move(LogitechPath + @"\LogitechLed.dll", LogitechPath + @"\LogitechLed.dll.bak"); - } - - // Copy our own DLL in place - File.WriteAllBytes(LogitechPath + @"\LogitechLED.dll", - Resources.LogitechLED); - - // A token to show the file is placed - File.Create(LogitechPath + @"\artemis.txt"); - - // If the user doesn't have a Logitech device, the CLSID will be missing - // and we should create it ourselves. - if (!RegistryKeyPlaced()) - PlaceRegistryKey(); - } - - public static bool DllPlaced() - { - if (!Directory.Exists(LogitechPath + @"")) - return false; - if (!RegistryKeyPlaced()) - return false; - - return File.Exists(LogitechPath + @"\artemis.txt"); - } - - private static bool RegistryKeyPlaced() - { - var key = Registry - .LocalMachine.OpenSubKey( - @"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary"); - return key != null; - } - - private static void PlaceRegistryKey() - { - var key = Registry - .LocalMachine.OpenSubKey( - @"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true); - key?.SetValue(null, LogitechPath + @"\LogitechLed.dll"); - } - } +using System; +using System.IO; +using Artemis.Modules.Games.Overwatch; +using Artemis.Properties; +using Microsoft.Win32; +using NLog; + +namespace Artemis.Utilities.DataReaders +{ + internal static class DllManager + { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + #region Logitech + + private const string LogitechPath = @"C:\Program Files\Logitech Gaming Software\SDK\LED\x64\"; + + public static bool RestoreLogitechDll() + { + if (!File.Exists(LogitechPath + @"\LogitechLed.dll") || !File.Exists(LogitechPath + @"\artemis.txt")) + return false; + + try + { + // Get rid of our own DLL + File.Delete(LogitechPath + @"\LogitechLed.dll"); + + // Restore the backup + if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak")) + File.Copy(LogitechPath + @"\LogitechLed.dll.bak", LogitechPath + @"\LogitechLed.dll"); + + File.Delete(LogitechPath + @"\artemis.txt"); + + return true; + } + catch (Exception) + { + return false; + } + } + + public static void PlaceLogitechDll() + { + if (DllPlaced()) + return; + + // Create directory structure, just in case + Directory.CreateDirectory(LogitechPath + @""); + + // Backup the existing DLL + if (File.Exists(LogitechPath + @"\LogitechLed.dll")) + { + if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak")) + File.Delete(LogitechPath + @"\LogitechLed.dll.bak"); + File.Move(LogitechPath + @"\LogitechLed.dll", LogitechPath + @"\LogitechLed.dll.bak"); + } + + // Copy our own DLL in place + File.WriteAllBytes(LogitechPath + @"\LogitechLED.dll", + Resources.LogitechLED); + + // A token to show the file is placed + File.Create(LogitechPath + @"\artemis.txt"); + + // If the user doesn't have a Logitech device, the CLSID will be missing + // and we should create it ourselves. + if (!RegistryKeyPlaced()) + PlaceRegistryKey(); + } + + public static bool DllPlaced() + { + if (!Directory.Exists(LogitechPath + @"")) + return false; + if (!RegistryKeyPlaced()) + return false; + + return File.Exists(LogitechPath + @"\artemis.txt"); + } + + private static bool RegistryKeyPlaced() + { + var key = Registry + .LocalMachine.OpenSubKey( + @"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary"); + return key != null; + } + + private static void PlaceRegistryKey() + { + var key = Registry + .LocalMachine.OpenSubKey( + @"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true); + key?.SetValue(null, LogitechPath + @"\LogitechLed.dll"); + } + + #endregion + + #region Razer + + public static void PlaceRazerDll(string path) + { + try + { + File.WriteAllBytes(path + @"\RzChromaSDK64.dll", Resources.RzChromaSDK64); + Logger.Debug("Successfully placed Razer DLL in {0}", path); + } + catch (Exception e) + { + Logger.Error(e, "Couldn't place Razer DLL in {0}", path); + } + } + + #endregion + } } \ No newline at end of file diff --git a/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs b/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs deleted file mode 100644 index 51c0aaf57..000000000 --- a/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.IO; -using System.IO.MemoryMappedFiles; -using System.Linq; -using System.Text; -using System.Windows.Media; -using Ninject.Extensions.Logging; - -namespace Artemis.Utilities.DataReaders -{ - /// - /// A helper class for reading memory managed files - /// - public class MmfReader - { - private readonly ILogger _logger; - - public MmfReader(string mmfName, ILogger logger) - { - _logger = logger; - MmfName = mmfName; - } - - public string MmfName { get; set; } - - /// - /// Turns the MMF into an color array - /// - /// - public Color[,] GetColorArray() - { - var mffString = ReadMmf(MmfName); - if (string.IsNullOrEmpty(mffString)) - return null; - var intermediateArray = mffString.Split('|'); - if (intermediateArray[0] == "1" || intermediateArray.Length < 2) - return null; - var array = intermediateArray[1].Substring(1).Split(' '); - if (!array.Any()) - return null; - - try - { - var colors = new Color[6, 22]; - foreach (var intermediate in array) - { - if (intermediate.Length > 16) - continue; - - // Can't parse to a byte directly since it may contain values >254 - var parts = intermediate.Split(',').Select(int.Parse).ToArray(); - if (parts[0] >= 5 && parts[1] >= 21) - continue; - - colors[parts[0], parts[1]] = Color.FromRgb((byte) parts[2], (byte) parts[3], (byte) parts[4]); - } - return colors; - } - catch (FormatException e) - { - _logger.Trace(e, "Failed to parse to color array"); - return null; - } - } - - /// - /// Reads the contents of the given MFF into a string - /// - /// - /// - private string ReadMmf(string fileName) - { - try - { - using (var mmf = MemoryMappedFile.OpenExisting(fileName)) - { - using (var stream = mmf.CreateViewStream()) - { - using (var binReader = new BinaryReader(stream)) - { - var allBytes = binReader.ReadBytes((int) stream.Length); - return Encoding.UTF8.GetString(allBytes, 0, allBytes.Length); - } - } - } - } - catch (FileNotFoundException e) - { - _logger.Trace(e, "Failed to read mff"); - return null; - //ignored - } - } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Utilities/LogitechDll/PipeServer.cs b/Artemis/Artemis/Utilities/DataReaders/PipeServer.cs similarity index 93% rename from Artemis/Artemis/Utilities/LogitechDll/PipeServer.cs rename to Artemis/Artemis/Utilities/DataReaders/PipeServer.cs index 3958c5040..6cd907c3d 100644 --- a/Artemis/Artemis/Utilities/LogitechDll/PipeServer.cs +++ b/Artemis/Artemis/Utilities/DataReaders/PipeServer.cs @@ -1,131 +1,131 @@ -using System; -using System.Diagnostics; -using System.IO.Pipes; -using System.Security.AccessControl; -using System.Security.Principal; -using System.Text; -using System.Threading.Tasks; - -namespace Artemis.Utilities.LogitechDll -{ - // Delegate for passing received message back to caller - public delegate void DelegateMessage(string reply); - - public class PipeServer - { - private string _pipeName; - - public bool Running { get; set; } - public event DelegateMessage PipeMessage; - - public void Start(string pipeName) - { - Running = true; - _pipeName = pipeName; - var task = new Task(PipeLoop); - task.Start(); - } - - public void Stop() - { - Running = false; - } - - private void PipeLoop() - { - try - { - var security = new PipeSecurity(); - var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); - security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, - AccessControlType.Allow)); - - while (Running) - { - var namedPipeServerStream = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254, - PipeTransmissionMode.Byte, PipeOptions.None, 254, 254, security); - - namedPipeServerStream.WaitForConnection(); - var buffer = new byte[254]; - namedPipeServerStream.Read(buffer, 0, 254); - namedPipeServerStream.Close(); - - var task = new Task(() => HandleMessage(buffer)); - task.Start(); - } - } - catch - { - // ignored - } - } - - private void HandleMessage(byte[] buffer) - { - var request = Encoding.ASCII.GetString(buffer); - PipeMessage?.Invoke(request); - } - - public void Listen(string pipeName) - { - try - { - var security = new PipeSecurity(); - var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); - security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow)); - - // Set to class level var so we can re-use in the async callback method - _pipeName = pipeName; - // Create the new async pipe - var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte, - PipeOptions.Asynchronous, 254, 254, security); - - // Wait for a connection - pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer); - } - catch (Exception oEx) - { - Debug.WriteLine(oEx.Message); - } - } - - private void WaitForConnectionCallBack(IAsyncResult iar) - { - try - { - // Get the pipe - var pipeServer = (NamedPipeServerStream) iar.AsyncState; - // End waiting for the connection - pipeServer.EndWaitForConnection(iar); - - var buffer = new byte[255]; - - // Read the incoming message - pipeServer.Read(buffer, 0, 255); - - // Convert byte buffer to string - var stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length); - - // Pass message back to calling form - PipeMessage?.Invoke(stringData); - - // Kill original sever and create new wait server - pipeServer.Close(); - - var security = new PipeSecurity(); - var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); - security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow)); - - pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte, - PipeOptions.Asynchronous, 254, 254, security); - - // Recursively wait for the connection again and again.... - pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer); - } - catch - { - // ignored - } - } - } +using System; +using System.Diagnostics; +using System.IO.Pipes; +using System.Security.AccessControl; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; + +namespace Artemis.Utilities.DataReaders +{ + // Delegate for passing received message back to caller + public delegate void DelegateMessage(string reply); + + public class PipeServer + { + private string _pipeName; + + public bool Running { get; set; } + public event DelegateMessage PipeMessage; + + public void Start(string pipeName) + { + Running = true; + _pipeName = pipeName; + var task = new Task(PipeLoop); + task.Start(); + } + + public void Stop() + { + Running = false; + } + + private void PipeLoop() + { + try + { + var security = new PipeSecurity(); + var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); + security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, + AccessControlType.Allow)); + + while (Running) + { + var namedPipeServerStream = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254, + PipeTransmissionMode.Byte, PipeOptions.None, 4096, 4096, security); + + namedPipeServerStream.WaitForConnection(); + var buffer = new byte[4096]; + namedPipeServerStream.Read(buffer, 0, 4096); + namedPipeServerStream.Close(); + + var task = new Task(() => HandleMessage(buffer)); + task.Start(); + } + } + catch + { + // ignored + } + } + + private void HandleMessage(byte[] buffer) + { + var request = Encoding.ASCII.GetString(buffer); + PipeMessage?.Invoke(request); + } + + public void Listen(string pipeName) + { + try + { + var security = new PipeSecurity(); + var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); + security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow)); + + // Set to class level var so we can re-use in the async callback method + _pipeName = pipeName; + // Create the new async pipe + var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte, + PipeOptions.Asynchronous, 254, 254, security); + + // Wait for a connection + pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer); + } + catch (Exception oEx) + { + Debug.WriteLine(oEx.Message); + } + } + + private void WaitForConnectionCallBack(IAsyncResult iar) + { + try + { + // Get the pipe + var pipeServer = (NamedPipeServerStream) iar.AsyncState; + // End waiting for the connection + pipeServer.EndWaitForConnection(iar); + + var buffer = new byte[255]; + + // Read the incoming message + pipeServer.Read(buffer, 0, 255); + + // Convert byte buffer to string + var stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length); + + // Pass message back to calling form + PipeMessage?.Invoke(stringData); + + // Kill original sever and create new wait server + pipeServer.Close(); + + var security = new PipeSecurity(); + var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); + security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow)); + + pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte, + PipeOptions.Asynchronous, 254, 254, security); + + // Recursively wait for the connection again and again.... + pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer); + } + catch + { + // ignored + } + } + } } \ No newline at end of file diff --git a/Artemis/Artemis/Utilities/GeneralHelpers.cs b/Artemis/Artemis/Utilities/GeneralHelpers.cs index 58fb17d1d..af9771b92 100644 --- a/Artemis/Artemis/Utilities/GeneralHelpers.cs +++ b/Artemis/Artemis/Utilities/GeneralHelpers.cs @@ -26,7 +26,7 @@ namespace Artemis.Utilities // Start the new process try { - Process.Start(processInfo); + System.Diagnostics.Process.Start(processInfo); } catch (Exception) { @@ -50,13 +50,7 @@ namespace Artemis.Utilities if (ReferenceEquals(source, null)) return default(T); - var deserializeSettings = new JsonSerializerSettings - { - ObjectCreationHandling = ObjectCreationHandling.Replace, - TypeNameHandling = TypeNameHandling.Auto - }; - return (T) JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source), source.GetType(), - deserializeSettings); + return (T)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source), source.GetType()); } public static object GetPropertyValue(object o, string path) diff --git a/Artemis/Artemis/Utilities/ImageUtilities.cs b/Artemis/Artemis/Utilities/ImageUtilities.cs index c45875482..3326e3253 100644 --- a/Artemis/Artemis/Utilities/ImageUtilities.cs +++ b/Artemis/Artemis/Utilities/ImageUtilities.cs @@ -54,12 +54,12 @@ namespace Artemis.Utilities } } - public static Bitmap DrawinVisualToBitmap(DrawingVisual visual, Rect rect) + public static Bitmap DrawingVisualToBitmap(DrawingVisual visual, Rect rect) { var bmp = new RenderTargetBitmap((int) rect.Width, (int) rect.Height, 96, 96, PixelFormats.Pbgra32); bmp.Render(visual); - var encoder = new PngBitmapEncoder(); + var encoder = new BmpBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bmp)); Bitmap bitmap; @@ -68,6 +68,7 @@ namespace Artemis.Utilities encoder.Save(stream); bitmap = new Bitmap(stream); } + return bitmap; } diff --git a/Artemis/Artemis/Utilities/Keyboard/Key.cs b/Artemis/Artemis/Utilities/Keyboard/Key.cs deleted file mode 100644 index d671ac13c..000000000 --- a/Artemis/Artemis/Utilities/Keyboard/Key.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Windows.Forms; - -namespace Artemis.Utilities.Keyboard -{ - public class Key - { - public Key(Keys keyCode, int posX, int posY) - { - KeyCode = keyCode; - PosX = posX; - PosY = posY; - } - - public Keys KeyCode { get; set; } - public int PosX { get; set; } - public int PosY { get; set; } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs b/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs index fe6b1d74d..326552cae 100644 --- a/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs +++ b/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs @@ -4,21 +4,21 @@ using VirtualInput; namespace Artemis.Utilities.Keyboard { - public class KeyboardHook + public static class KeyboardHook { public delegate void KeyDownCallbackHandler(KeyEventArgs e); - public KeyboardHook() + static KeyboardHook() { - VirtualKeyboard.KeyDown += VirtualKeyboardOnKeyDown; VirtualKeyboard.StartInterceptor(); + VirtualKeyboard.KeyDown += VirtualKeyboardOnKeyDown; } - private void VirtualKeyboardOnKeyDown(object sender, KeyEventArgs keyEventArgs) + private static void VirtualKeyboardOnKeyDown(object sender, KeyEventArgs keyEventArgs) { Task.Factory.StartNew(() => { KeyDownCallback?.Invoke(keyEventArgs); }); } - public event KeyDownCallbackHandler KeyDownCallback; + public static event KeyDownCallbackHandler KeyDownCallback; } } \ No newline at end of file diff --git a/Artemis/Artemis/Utilities/LogitechDll/NamedPipeServer.cs b/Artemis/Artemis/Utilities/LogitechDll/NamedPipeServer.cs deleted file mode 100644 index b11bfab08..000000000 --- a/Artemis/Artemis/Utilities/LogitechDll/NamedPipeServer.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; -using Microsoft.Win32.SafeHandles; - -namespace Artemis.Utilities.LogitechDll -{ - public class NamedPipeServer - { - public const uint DUPLEX = 0x00000003; - public const uint FILE_FLAG_OVERLAPPED = 0x40000000; - - public const int BUFFER_SIZE = 100; - private SafeFileHandle clientHandle; - public Client clientse; - public int ClientType; - private Thread listenThread; - - public string pipeName; - - public NamedPipeServer(string PName, int Mode) - { - pipeName = PName; - ClientType = Mode; //0 Reading Pipe, 1 Writing Pipe - } - - public event PipeDataReceivedEventHandler PipeDataReceived; - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern SafeFileHandle CreateNamedPipe( - string pipeName, - uint dwOpenMode, - uint dwPipeMode, - uint nMaxInstances, - uint nOutBufferSize, - uint nInBufferSize, - uint nDefaultTimeOut, - IntPtr lpSecurityAttributes); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern int ConnectNamedPipe( - SafeFileHandle hNamedPipe, - IntPtr lpOverlapped); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern int DisconnectNamedPipe( - SafeFileHandle hNamedPipe); - - public void Start() - { - listenThread = new Thread(ListenForClients); - listenThread.Start(); - } - - private void ListenForClients() - { - while (true) - { - clientHandle = CreateNamedPipe(pipeName, DUPLEX | FILE_FLAG_OVERLAPPED, 0, 255, BUFFER_SIZE, BUFFER_SIZE, - 0, IntPtr.Zero); - //could not create named pipe - if (clientHandle.IsInvalid) - return; - - var success = ConnectNamedPipe(clientHandle, IntPtr.Zero); - - //could not connect client - if (success == 0) - return; - - clientse = new Client(); - clientse.handle = clientHandle; - clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true); - - if (ClientType == 0) - { - var readThread = new Thread(Read); - readThread.Start(); - } - } - } - - private void Read() - { - //Client client = (Client)clientObj; - //clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true); - byte[] buffer = null; - var encoder = new ASCIIEncoding(); - - while (true) - { - var bytesRead = 0; - - try - { - buffer = new byte[BUFFER_SIZE]; - bytesRead = clientse.stream.Read(buffer, 0, BUFFER_SIZE); - } - catch - { - //read error has occurred - break; - } - - //client has disconnected - if (bytesRead == 0) - break; - - //fire message received event - //if (this.MessageReceived != null) - // this.MessageReceived(clientse, encoder.GetString(buffer, 0, bytesRead)); - - var ReadLength = 0; - for (var i = 0; i < BUFFER_SIZE; i++) - { - if (buffer[i].ToString("x2") != "cc") - { - ReadLength++; - } - else - break; - } - if (ReadLength > 0) - { - var Rc = new byte[ReadLength]; - Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength); - OnPipeDataReceived(new PipeDataReceivedEventArgs(encoder.GetString(Rc, 0, ReadLength))); - - buffer.Initialize(); - } - } - - //clean up resources - clientse.stream.Close(); - clientse.handle.Close(); - } - - public void SendMessage(string message, Client client) - { - var encoder = new ASCIIEncoding(); - var messageBuffer = encoder.GetBytes(message); - - if (client.stream.CanWrite) - { - client.stream.Write(messageBuffer, 0, messageBuffer.Length); - client.stream.Flush(); - } - } - - public void StopServer() - { - //clean up resources - - DisconnectNamedPipe(clientHandle); - - - listenThread.Abort(); - } - - private void OnPipeDataReceived(PipeDataReceivedEventArgs e) - { - PipeDataReceived?.Invoke(this, e); - } - - public class Client - { - public SafeFileHandle handle; - public FileStream stream; - } - } - - public delegate void PipeDataReceivedEventHandler( - object sender, PipeDataReceivedEventArgs pipeDataReceivedEventArgs); - - public class PipeDataReceivedEventArgs - { - public PipeDataReceivedEventArgs(string data) - { - Data = data; - } - - public string Data { get; set; } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Utilities/Memory/Memory.cs b/Artemis/Artemis/Utilities/Memory/Memory.cs index 63caeb2a8..b40af023c 100644 --- a/Artemis/Artemis/Utilities/Memory/Memory.cs +++ b/Artemis/Artemis/Utilities/Memory/Memory.cs @@ -17,7 +17,7 @@ namespace Artemis.Utilities.Memory /// Initializes a new instance of the Memory /// /// Remote process - public Memory(Process process) + public Memory(System.Diagnostics.Process process) { if (process == null) throw new ArgumentNullException("process"); @@ -35,7 +35,7 @@ namespace Artemis.Utilities.Memory /// /// Gets the process to which this memory is attached to /// - public Process Process { get; private set; } + public System.Diagnostics.Process Process { get; private set; } #endregion diff --git a/Artemis/Artemis/Utilities/Memory/MemoryHelpers.cs b/Artemis/Artemis/Utilities/Memory/MemoryHelpers.cs index 42fd85158..94a0d9493 100644 --- a/Artemis/Artemis/Utilities/Memory/MemoryHelpers.cs +++ b/Artemis/Artemis/Utilities/Memory/MemoryHelpers.cs @@ -1,6 +1,6 @@ using System; -using System.Diagnostics; using System.Runtime.InteropServices; +using Process.NET.Memory; namespace Artemis.Utilities.Memory { @@ -10,9 +10,9 @@ namespace Artemis.Utilities.Memory public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead); - public static Process GetProcessIfRunning(string processName) + public static System.Diagnostics.Process GetProcessIfRunning(string processName) { - var processes = Process.GetProcessesByName(processName); + var processes = System.Diagnostics.Process.GetProcessesByName(processName); return processes.Length >= 1 ? processes[0] : null; } @@ -37,5 +37,14 @@ namespace Artemis.Utilities.Memory } return address; } + + public static T ReadMultilevelPointer(this IMemory memory, IntPtr address, params int[] offsets) where T : struct + { + for (var i = 0; i < offsets.Length - 1; i++) + { + address = memory.Read(address + offsets[i]); + } + return memory.Read(address + offsets[offsets.Length - 1]); + } } } \ No newline at end of file diff --git a/Artemis/Artemis/Utilities/Updater.cs b/Artemis/Artemis/Utilities/Updater.cs index 587cc74c8..6bd7c6ed9 100644 --- a/Artemis/Artemis/Utilities/Updater.cs +++ b/Artemis/Artemis/Utilities/Updater.cs @@ -15,12 +15,12 @@ namespace Artemis.Utilities { public static class Updater { - public static int CurrentVersion = 120; + public static int CurrentVersion = 1220; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); public static async Task CheckForUpdate(MetroDialogService dialogService) { - Logger.Info("Checking for updates - Current version: 1.2.0"); + Logger.Info("Checking for updates - Current version: 1.2.2.0"); if (!General.Default.CheckForUpdates) return null; @@ -39,7 +39,7 @@ namespace Artemis.Utilities "Note: You can disable update notifications in the settings menu"); if (viewUpdate.Value) - Process.Start(new ProcessStartInfo(newRelease["html_url"].Value())); + System.Diagnostics.Process.Start(new ProcessStartInfo(newRelease["html_url"].Value())); return null; } diff --git a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs index 946cba921..8cbb254c8 100644 --- a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs +++ b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs @@ -208,7 +208,7 @@ namespace Artemis.ViewModels.Flyouts public void NavigateTo(string url) { - Process.Start(new ProcessStartInfo(url)); + System.Diagnostics.Process.Start(new ProcessStartInfo(url)); } protected override void HandleOpen() diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs index 0dfea8c36..b2218c502 100644 --- a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs @@ -217,20 +217,17 @@ namespace Artemis.ViewModels.Profiles foreach (var conditionViewModel in LayerConditionVms) ProposedLayer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel); - // Ignore children on the comparison - var currentNoChildren = GeneralHelpers.Clone(Layer); - currentNoChildren.Children.Clear(); // If not a keyboard, ignore size and position if (ProposedLayer.LayerType.DrawType != DrawType.Keyboard) { - ProposedLayer.Properties.Width = currentNoChildren.Properties.Width; - ProposedLayer.Properties.Height = currentNoChildren.Properties.Height; - ProposedLayer.Properties.X = currentNoChildren.Properties.X; - ProposedLayer.Properties.Y = currentNoChildren.Properties.Y; - ProposedLayer.Properties.Contain = currentNoChildren.Properties.Contain; + ProposedLayer.Properties.Width = Layer.Properties.Width; + ProposedLayer.Properties.Height = Layer.Properties.Height; + ProposedLayer.Properties.X = Layer.Properties.X; + ProposedLayer.Properties.Y = Layer.Properties.Y; + ProposedLayer.Properties.Contain = Layer.Properties.Contain; } - var current = JsonConvert.SerializeObject(currentNoChildren, Formatting.Indented); + var current = JsonConvert.SerializeObject(Layer, Formatting.Indented); var proposed = JsonConvert.SerializeObject(ProposedLayer, Formatting.Indented); if (current.Equals(proposed)) diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs index 3e2929dd5..34a272f6e 100644 --- a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs @@ -414,8 +414,6 @@ namespace Artemis.ViewModels.Profiles { var clone = GeneralHelpers.Clone(layer); layer.InsertAfter(clone); - foreach (var layerModel in layer.Children) - clone.Children.Add(GeneralHelpers.Clone(layerModel)); UpdateLayerList(clone); } @@ -642,9 +640,10 @@ namespace Artemis.ViewModels.Profiles profile.KeyboardSlug = deviceManager.ActiveKeyboard.Slug; profile.Width = deviceManager.ActiveKeyboard.Width; profile.Height = deviceManager.ActiveKeyboard.Height; - profile.IsDefault = false; } + profile.IsDefault = false; + // Verify the name while (ProfileProvider.GetAll().Contains(profile)) { diff --git a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs index c4b4223f5..2d1ff3388 100644 --- a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs +++ b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs @@ -132,7 +132,7 @@ namespace Artemis.ViewModels var dialog = await DialogService.ShowProgressDialog("Enabling keyboard", "Artemis is still busy trying to enable your last used keyboard. " + - "Please wait while the progress completes"); + "Please wait while the process completes"); dialog.SetIndeterminate(); while (MainManager.DeviceManager.ChangingKeyboard) diff --git a/Artemis/Artemis/ViewModels/WelcomeViewModel.cs b/Artemis/Artemis/ViewModels/WelcomeViewModel.cs index 4d8f23524..c8735717b 100644 --- a/Artemis/Artemis/ViewModels/WelcomeViewModel.cs +++ b/Artemis/Artemis/ViewModels/WelcomeViewModel.cs @@ -12,7 +12,7 @@ namespace Artemis.ViewModels public void NavigateTo(string url) { - Process.Start(new ProcessStartInfo(url)); + System.Diagnostics.Process.Start(new ProcessStartInfo(url)); } } } \ No newline at end of file diff --git a/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml b/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml index 8a03e5159..c49fedda6 100644 --- a/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml +++ b/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml @@ -113,7 +113,7 @@ -