From e95b33e9bb23d17ec63afba0dd55b9a3a0f22a31 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Thu, 7 Apr 2016 00:55:17 +0200 Subject: [PATCH] Layers are finally being drawn to keyboard --- Artemis/Artemis/Artemis.csproj | 1 + Artemis/Artemis/DAL/ProfileProvider.cs | 3 +- .../KeyboardProviders/KeyboardProvider.cs | 4 + Artemis/Artemis/Models/GameModel.cs | 8 +- .../Models/Profiles/LayerConditionModel.cs | 23 ++- Artemis/Artemis/Models/Profiles/LayerModel.cs | 21 ++- .../Models/Profiles/LayerPropertiesModel.cs | 6 +- .../CounterStrike/CounterStrikeDataModel.cs | 124 +++++++++++++ .../Games/CounterStrike/CounterStrikeModel.cs | 168 +++--------------- .../CounterStrike/CounterStrikeView.xaml | 73 +------- .../CounterStrike/CounterStrikeViewModel.cs | 7 + Artemis/Artemis/Utilities/ImageUtilities.cs | 27 ++- Artemis/Artemis/Utilities/LayerDrawer.cs | 2 + .../ViewModels/Abstract/GameViewModel.cs | 4 +- .../LayerEditor/LayerConditionViewModel.cs | 2 + .../ViewModels/LayerEditorViewModel.cs | 14 +- .../ViewModels/ProfileEditorViewModel.cs | 6 +- .../Views/LayerEditor/LayerConditionView.xaml | 33 ++-- 18 files changed, 262 insertions(+), 264 deletions(-) create mode 100644 Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 5561cc456..aea85129f 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -314,6 +314,7 @@ True True + diff --git a/Artemis/Artemis/DAL/ProfileProvider.cs b/Artemis/Artemis/DAL/ProfileProvider.cs index 6aca30e31..0324a344a 100644 --- a/Artemis/Artemis/DAL/ProfileProvider.cs +++ b/Artemis/Artemis/DAL/ProfileProvider.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Xml.Serialization; using Artemis.Models; using Artemis.Models.Profiles; -using Newtonsoft.Json; namespace Artemis.DAL { @@ -48,7 +47,7 @@ namespace Artemis.DAL if (!Directory.Exists(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")) { serializer.Serialize(file, prof); diff --git a/Artemis/Artemis/KeyboardProviders/KeyboardProvider.cs b/Artemis/Artemis/KeyboardProviders/KeyboardProvider.cs index ef6581dad..022cab79f 100644 --- a/Artemis/Artemis/KeyboardProviders/KeyboardProvider.cs +++ b/Artemis/Artemis/KeyboardProviders/KeyboardProvider.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; using System.Drawing; +using System.Windows; +using Size = System.Windows.Size; namespace Artemis.KeyboardProviders { @@ -28,5 +30,7 @@ namespace Artemis.KeyboardProviders /// /// public Bitmap KeyboardBitmap(int scale) => new Bitmap(Width*scale, Height*scale); + + public Rect KeyboardRectangle(int scale) => new Rect(new Size(Width*scale, Height*scale)); } } \ No newline at end of file diff --git a/Artemis/Artemis/Models/GameModel.cs b/Artemis/Artemis/Models/GameModel.cs index 6fca61341..8500747fc 100644 --- a/Artemis/Artemis/Models/GameModel.cs +++ b/Artemis/Artemis/Models/GameModel.cs @@ -1,11 +1,15 @@ using Artemis.Managers; +using Artemis.Models.Interfaces; +using Artemis.Models.Profiles; namespace Artemis.Models { public abstract class GameModel : EffectModel { - public bool Enabled; - public string ProcessName; + public bool Enabled { get; set; } + public string ProcessName { get; set; } + public IGameDataModel GameDataModel { get; set; } + public ProfileModel Profile { get; set; } protected GameModel(MainManager mainManager) : base(mainManager) { diff --git a/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs b/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs index 8a48cdbaa..e6956c274 100644 --- a/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs +++ b/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq.Dynamic; using Artemis.Models.Interfaces; @@ -9,13 +10,25 @@ namespace Artemis.Models.Profiles public string Field { get; set; } public string Value { get; set; } public string Operator { get; set; } + public string Type { get; set; } public bool ConditionMet(IGameDataModel subject) { - // Put the subject in a list, allowing Dynamic Linq to be used. - var subjectList = new List {(T) subject}; - var res = subjectList.Where($"{Field} {Operator} {Value}").Any(); - return res; + if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Type)) + return false; + try + { + // Put the subject in a list, allowing Dynamic Linq to be used. + var subjectList = new List {(T) subject}; + var res = Type == "String" + ? subjectList.Where($"{Field}.ToLower() {Operator} @0", Value.ToLower()).Any() + : subjectList.Where($"{Field} {Operator} {Value}").Any(); + return res; + } + catch (NullReferenceException) + { + return false; + } } } } \ No newline at end of file diff --git a/Artemis/Artemis/Models/Profiles/LayerModel.cs b/Artemis/Artemis/Models/Profiles/LayerModel.cs index 5a7c684b9..a6f3bede5 100644 --- a/Artemis/Artemis/Models/Profiles/LayerModel.cs +++ b/Artemis/Artemis/Models/Profiles/LayerModel.cs @@ -5,7 +5,6 @@ using System.Windows.Media; using System.Xml.Serialization; using Artemis.Models.Interfaces; using Artemis.Utilities; -using Newtonsoft.Json; namespace Artemis.Models.Profiles { @@ -57,10 +56,9 @@ namespace Artemis.Models.Profiles if (!ConditionsMet(dataModel)) return; - Update(dataModel); - if (LayerType == LayerType.Folder) - DrawChildren(dataModel, c); + foreach (var layerModel in Children) + layerModel.Draw(dataModel, c); else if (LayerType == LayerType.KeyboardRectangle || LayerType == LayerType.KeyboardEllipse) _drawer.Draw(c); else if (LayerType == LayerType.KeyboardGif) @@ -71,18 +69,19 @@ namespace Artemis.Models.Profiles _drawer.UpdateHeadset(); } - private void Update(IGameDataModel dataModel) + public void Update(IGameDataModel dataModel) { + if (LayerType == LayerType.Folder) + { + foreach (var layerModel in Children) + layerModel.Update(dataModel); + return; + } + GeneralHelpers.CopyProperties(LayerCalculatedProperties, LayerUserProperties); foreach (var dynamicProperty in LayerProperties) dynamicProperty.ApplyProperty(dataModel, LayerUserProperties, LayerCalculatedProperties); } - - private void DrawChildren(IGameDataModel dataModel, DrawingContext c) - { - foreach (var layerModel in Children) - layerModel.Draw(dataModel, c); - } } public enum LayerType diff --git a/Artemis/Artemis/Models/Profiles/LayerPropertiesModel.cs b/Artemis/Artemis/Models/Profiles/LayerPropertiesModel.cs index 9f05e4859..4a02d68c8 100644 --- a/Artemis/Artemis/Models/Profiles/LayerPropertiesModel.cs +++ b/Artemis/Artemis/Models/Profiles/LayerPropertiesModel.cs @@ -4,9 +4,9 @@ using System.Xml.Serialization; namespace Artemis.Models.Profiles { - [XmlInclude(typeof(LinearGradientBrush))] - [XmlInclude(typeof(RadialGradientBrush))] - [XmlInclude(typeof(MatrixTransform))] + [XmlInclude(typeof (LinearGradientBrush))] + [XmlInclude(typeof (RadialGradientBrush))] + [XmlInclude(typeof (MatrixTransform))] public class LayerPropertiesModel { public int X { get; set; } diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs new file mode 100644 index 000000000..de5d12920 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs @@ -0,0 +1,124 @@ +using Artemis.Models.Interfaces; + +namespace Artemis.Modules.Games.CounterStrike +{ + public class CounterStrikeDataModel : IGameDataModel + { + public Provider provider { get; set; } + public Map map { get; set; } + public Round round { get; set; } + public Player player { get; set; } + public Previously previously { get; set; } + } + + public class Provider + { + public string name { get; set; } + public int appid { get; set; } + public int version { get; set; } + public string steamid { get; set; } + public int timestamp { get; set; } + } + + public class TeamCt + { + public int score { get; set; } + } + + public class TeamT + { + public int score { get; set; } + } + + public class Map + { + public string mode { get; set; } + public string name { get; set; } + public string phase { get; set; } + public int round { get; set; } + public TeamCt team_ct { get; set; } + public TeamT team_t { get; set; } + } + + public class Round + { + public string phase { get; set; } + } + + public class State + { + public int health { get; set; } + public int armor { get; set; } + public bool helmet { get; set; } + public int flashed { get; set; } + public int smoked { get; set; } + public int burning { get; set; } + public int money { get; set; } + public int round_kills { get; set; } + public int round_killhs { get; set; } + } + + public class Weapon0 + { + public string name { get; set; } + public string paintkit { get; set; } + public string type { get; set; } + public string state { get; set; } + } + + public class Weapon1 + { + public string name { get; set; } + public string paintkit { get; set; } + public string type { get; set; } + public int ammo_clip { get; set; } + public int ammo_clip_max { get; set; } + public int ammo_reserve { get; set; } + public string state { get; set; } + } + + public class Weapon2 + { + public string name { get; set; } + public string paintkit { get; set; } + public string type { get; set; } + public string state { get; set; } + } + + public class Weapons + { + public Weapon0 weapon_0 { get; set; } + public Weapon1 weapon_1 { get; set; } + public Weapon2 weapon_2 { get; set; } + } + + public class MatchStats + { + public int kills { get; set; } + public int assists { get; set; } + public int deaths { get; set; } + public int mvps { get; set; } + public int score { get; set; } + } + + public class Player + { + public string steamid { get; set; } + public string name { get; set; } + public string team { get; set; } + public string activity { get; set; } + public State state { get; set; } + public Weapons weapons { get; set; } + public MatchStats match_stats { get; set; } + } + + public class Round2 + { + public string phase { get; set; } + } + + public class Previously + { + public Round2 round { get; set; } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs index 8a8501cd2..cabeb1b4f 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs @@ -1,23 +1,16 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Linq; -using Artemis.KeyboardProviders; +using System.Drawing; +using System.Windows.Media; +using System.Windows.Media.Imaging; using Artemis.Managers; using Artemis.Models; using Artemis.Utilities; using Artemis.Utilities.GameState; -using Artemis.Utilities.Keyboard; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace Artemis.Modules.Games.CounterStrike { public class CounterStrikeModel : GameModel { - private KeyboardRegion _topRow; - public CounterStrikeModel(MainManager mainManager, CounterStrikeSettings settings) : base(mainManager) { Settings = settings; @@ -30,14 +23,6 @@ namespace Artemis.Modules.Games.CounterStrike public CounterStrikeSettings Settings { get; set; } - public KeyboardRectangle EventRect { get; set; } - public KeyboardRectangle TeamRect { get; set; } - public KeyboardRectangle AmmoRect { get; set; } - public JObject CsJson { get; set; } - - public bool DrawingSmoke { get; set; } - public bool DrawingFlash { get; set; } - public int Scale { get; set; } public override void Dispose() @@ -50,23 +35,7 @@ namespace Artemis.Modules.Games.CounterStrike { Initialized = false; - // Some keyboards have a different baseline, Corsair F-keys start at row 1 - _topRow = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRegions.First(r => r.RegionName == "TopRow"); - AmmoRect = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, _topRow.TopLeft.X, - new List(), - LinearGradientMode.Horizontal) {Height = Scale, ContainedBrush = false}; - TeamRect = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, _topRow.TopLeft.X + 1, - new List(), - LinearGradientMode.Horizontal) - { - Height = MainManager.KeyboardManager.ActiveKeyboard.Height*Scale - Scale - }; - EventRect = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, _topRow.TopLeft.X + 1, - new List(), - LinearGradientMode.Horizontal) - { - Height = MainManager.KeyboardManager.ActiveKeyboard.Height*Scale - Scale - }; + GameDataModel = new CounterStrikeDataModel(); MainManager.GameStateWebServer.GameDataReceived += HandleGameData; Initialized = true; @@ -74,124 +43,33 @@ namespace Artemis.Modules.Games.CounterStrike public override void Update() { - if (CsJson == null) + if (Profile == null || GameDataModel == null) return; - if (Settings.AmmoEnabled) - UpdateAmmo(); - if (Settings.TeamColorEnabled) - UpdateTeam(); - if (Settings.LowHpEnabled) - UpdateHealth(); - if (Settings.FlashEnabled) - UpdateFlash(); - if (Settings.SmokeEnabled) - UpdateSmoke(); - } - - private void UpdateHealth() - { - if (CsJson["player"]?["state"]?["health"] == null) - return; - - var health = CsJson["player"]["state"]["health"].Value(); - if (health > 25 || health < 1) - return; - - TeamRect.Colors = new List {Color.Red, Color.OrangeRed, Color.Red, Color.OrangeRed}; - } - - private void UpdateSmoke() - { - if (CsJson["player"]?["state"]?["smoked"] == null) - return; - - var smoked = CsJson["player"]["state"]["smoked"].Value(); - if (smoked == 0 && !DrawingSmoke) - return; - - EventRect.Colors = new List {Color.FromArgb(smoked, 255, 255, 255)}; - DrawingSmoke = smoked != 0; - } - - private void UpdateFlash() - { - if (CsJson["player"]?["state"]?["flashed"] == null) - return; - - var flashed = CsJson["player"]["state"]["flashed"].Value(); - if (flashed == 0 && !DrawingFlash) - return; - - EventRect.Colors = new List {Color.FromArgb(flashed, 255, 255, 255)}; - DrawingFlash = flashed != 0; - } - - private void UpdateTeam() - { - var currentTeam = CsJson["player"]?["team"]; - if (currentTeam == null) - return; - - var t1 = Color.FromArgb(255, 255, 129, 0); - var t2 = Color.FromArgb(255, 255, 170, 125); - - var ct1 = Color.FromArgb(255, 203, 238, 255); - var ct2 = Color.FromArgb(255, 0, 173, 255); - - TeamRect.Colors = currentTeam.Value() == "T" - ? new List {t1, t2, t1, t2} - : new List {ct1, ct2, ct1, ct2}; - TeamRect.Rotate = true; - } - - private void UpdateAmmo() - { - if (CsJson["player"]["weapons"] == null) - return; - - var activeWeapon = - CsJson["player"]["weapons"].Children() - .Select(c => c.First) - .FirstOrDefault(w => w["state"]?.Value() == "active"); - - // Update the ammo display - if (activeWeapon?["ammo_clip_max"] == null || activeWeapon["ammo_clip"] == null) - return; - - var maxAmmo = activeWeapon["ammo_clip_max"].Value(); - var ammo = activeWeapon["ammo_clip"].Value(); - - if (maxAmmo < 0) - return; - - var ammoPercentage = (int) Math.Ceiling(100.00/maxAmmo)*ammo; - AmmoRect.Width = (int) Math.Floor(_topRow.BottomRight.Y/100.00*ammoPercentage)*Scale; - AmmoRect.Colors = new List - { - ColorHelpers.ToDrawingColor(Settings.AmmoMainColor), - ColorHelpers.ToDrawingColor(Settings.AmmoSecondaryColor) - }; - - // Low ammo indicator - if (ammoPercentage < 37) - AmmoRect.StartBlink(1000); - else - AmmoRect.StopBlink(); + foreach (var layerModel in Profile.Layers) + layerModel.Update(GameDataModel); } public override Bitmap GenerateBitmap() { - var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(Scale); + var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale); - using (var g = Graphics.FromImage(bitmap)) + var visual = new DrawingVisual(); + using (var drawingContext = visual.RenderOpen()) { - g.Clear(Color.Transparent); - AmmoRect.Draw(g); - TeamRect.Draw(g); - EventRect.Draw(g); + // Setup the DrawingVisual's size + drawingContext.PushClip(new RectangleGeometry(keyboardRect)); + drawingContext.DrawRectangle(new SolidColorBrush(System.Windows.Media.Color.FromArgb(0, 0, 0, 0)), null, keyboardRect); + + // Draw the layers + foreach (var layerModel in Profile.Layers) + layerModel.Draw(GameDataModel, drawingContext); + + // Remove the clip + drawingContext.Pop(); } - return bitmap; + + return ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect); } public void HandleGameData(object sender, GameDataReceivedEventArgs e) @@ -203,7 +81,7 @@ namespace Artemis.Modules.Games.CounterStrike return; // Parse the JSON - CsJson = JsonConvert.DeserializeObject(jsonString); + GameDataModel = JsonConvert.DeserializeObject(jsonString); } } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml index 449c1a6ec..0e5f255de 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml @@ -19,11 +19,6 @@ - - - - - @@ -58,73 +53,11 @@ - - - Display ammo on F-keys - - - - - - Main ammo color - - - - - - Secondary ammo color - - - - - - Display smoked effect - - - - - - Display flashed effect - - - - - - Color keyboard according to team - - - - - - Color keyboard red on low HP - - + + - +