diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 884520177..9f1be00a2 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -404,6 +404,12 @@ TerrariaView.xaml + + + + + + diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs index 598bfa3b1..0e198c4e0 100644 --- a/Artemis/Artemis/Managers/LoopManager.cs +++ b/Artemis/Artemis/Managers/LoopManager.cs @@ -16,9 +16,12 @@ namespace Artemis.Managers { private readonly DebugViewModel _debugViewModel; private readonly DeviceManager _deviceManager; + private readonly ILogger _logger; + //private readonly Timer _loopTimer; private readonly Task _loopTask; + private readonly ModuleManager _moduleManager; public LoopManager(ILogger logger, ModuleManager moduleManager, DeviceManager deviceManager, @@ -163,9 +166,7 @@ namespace Artemis.Managers var keyboardOnly = !mice.Any() && !headsets.Any() && !generics.Any() && !mousemats.Any(); // Setup the frame for this tick - using ( - var frame = new FrameModel(_deviceManager.ActiveKeyboard, mice.Any(), headsets.Any(), generics.Any(), - mousemats.Any())) + using (var frame = new FrameModel(_deviceManager.ActiveKeyboard, mice.Any(), headsets.Any(), generics.Any(), mousemats.Any())) { if (renderModule.IsInitialized) renderModule.Render(frame, keyboardOnly); @@ -207,4 +208,4 @@ namespace Artemis.Managers RenderCompleted?.Invoke(this, EventArgs.Empty); } } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Models/DeviceVisualModel.cs b/Artemis/Artemis/Models/DeviceVisualModel.cs index 43d59c3c4..cf64bdef0 100644 --- a/Artemis/Artemis/Models/DeviceVisualModel.cs +++ b/Artemis/Artemis/Models/DeviceVisualModel.cs @@ -54,8 +54,7 @@ namespace Artemis.Models using (var g = Graphics.FromImage(bitmap)) { g.Clear(Color.Black); - g.DrawImage(frame, new Rectangle(0, 0, bitmap.Width, bitmap.Height), RelativeRectangle, - GraphicsUnit.Pixel); + g.DrawImage(frame, new Rectangle(0, 0, bitmap.Width, bitmap.Height), RelativeRectangle, GraphicsUnit.Pixel); } return bitmap; @@ -72,4 +71,4 @@ namespace Artemis.Models _ctx = null; } } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Modules/Games/WoW/Models/WoWAura.cs b/Artemis/Artemis/Modules/Games/WoW/Models/WoWAura.cs new file mode 100644 index 000000000..3511e7db7 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WoW/Models/WoWAura.cs @@ -0,0 +1,27 @@ +using System; +using MoonSharp.Interpreter; +using Newtonsoft.Json.Linq; + +namespace Artemis.Modules.Games.WoW.Models +{ + [MoonSharpUserData] + public class WoWAura + { + public string Name { get; set; } + public int Id { get; set; } + public string Caster { get; set; } + public int Stacks { get; set; } + public DateTime StartTime { set; get; } + public DateTime EndTime { get; set; } + + public void ApplyJson(JToken buffJson) + { + Name = buffJson["name"].Value(); + Id = buffJson["spellID"].Value(); + Stacks = buffJson["count"].Value(); + Caster = buffJson["caster"]?.Value(); + + // TODO: Duration + } + } +} diff --git a/Artemis/Artemis/Modules/Games/WoW/Models/WoWCastBar.cs b/Artemis/Artemis/Modules/Games/WoW/Models/WoWCastBar.cs new file mode 100644 index 000000000..37cc83c79 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WoW/Models/WoWCastBar.cs @@ -0,0 +1,57 @@ +using System; +using MoonSharp.Interpreter; +using Newtonsoft.Json.Linq; + +namespace Artemis.Modules.Games.WoW.Models +{ + [MoonSharpUserData] + public class WoWCastBar + { + public WoWCastBar() + { + Spell = new WoWSpell(); + } + + public WoWSpell Spell { get; set; } + public DateTime StartTime { set; get; } + public DateTime EndTime { get; set; } + public bool NonInterruptible { get; set; } + public float Progress { get; set; } + + public void ApplyJson(JToken spellJson) + { + var castMs = spellJson["endTime"].Value() - spellJson["startTime"].Value(); + var tickCount = Environment.TickCount; + var difference = tickCount - spellJson["startTime"].Value(); + + Spell.Name = spellJson["name"].Value(); + Spell.Id = spellJson["spellID"].Value(); + StartTime = new DateTime(DateTime.Now.Ticks + difference); + EndTime = StartTime.AddMilliseconds(castMs); + NonInterruptible = spellJson["notInterruptible"].Value(); + } + + public void UpdateProgress() + { + if (Spell.Name == null) + return; + + var elapsed = DateTime.Now - StartTime; + var total = EndTime - StartTime; + + Progress = (float) (elapsed.TotalMilliseconds / total.TotalMilliseconds); + if (Progress > 1) + Clear(); + } + + public void Clear() + { + Spell.Name = null; + Spell.Id = 0; + StartTime = DateTime.MinValue; + EndTime = DateTime.MinValue; + NonInterruptible = false; + Progress = 0; + } + } +} diff --git a/Artemis/Artemis/Modules/Games/WoW/Models/WoWEnums.cs b/Artemis/Artemis/Modules/Games/WoW/Models/WoWEnums.cs new file mode 100644 index 000000000..9a484d508 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WoW/Models/WoWEnums.cs @@ -0,0 +1,44 @@ +namespace Artemis.Modules.Games.WoW.Models +{ + public enum WoWRace + { + Human, + Orc, + Dwarf, + NightElf, + Undead, + Tauren, + Gnome, + Troll, + BloodElf, + Draenei, + Goblin, + Worgen, + Pandaren + } + + public enum WoWPowerType + { + Mana = 0, + Rage = 1, + Focus = 2, + Energy = 3, + ComboPoints = 4, + Runes = 5, + RunicPower = 6, + SoulShards = 7, + LunarPower = 8, + HolyPower = 9, + AlternatePower = 10, + Maelstrom = 11, + Chi = 12, + Insanity = 13, + ArcaneCharges = 16 + } + + public enum WoWGender + { + Male, + Female + } +} diff --git a/Artemis/Artemis/Modules/Games/WoW/Models/WoWSpecialization.cs b/Artemis/Artemis/Modules/Games/WoW/Models/WoWSpecialization.cs new file mode 100644 index 000000000..63e66fd09 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WoW/Models/WoWSpecialization.cs @@ -0,0 +1,20 @@ +using MoonSharp.Interpreter; +using Newtonsoft.Json.Linq; + +namespace Artemis.Modules.Games.WoW.Models +{ + [MoonSharpUserData] + public class WoWSpecialization + { + public string Name { get; set; } + public int Id { get; set; } + public string Role { get; set; } + + public void ApplyJson(JToken specJson) + { + Name = specJson["name"].Value(); + Id = specJson["id"].Value(); + Role = specJson["role"].Value(); + } + } +} diff --git a/Artemis/Artemis/Modules/Games/WoW/Models/WoWSpell.cs b/Artemis/Artemis/Modules/Games/WoW/Models/WoWSpell.cs new file mode 100644 index 000000000..8210bf2cb --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WoW/Models/WoWSpell.cs @@ -0,0 +1,11 @@ +using MoonSharp.Interpreter; + +namespace Artemis.Modules.Games.WoW.Models +{ + [MoonSharpUserData] + public class WoWSpell + { + public string Name { get; set; } + public int Id { get; set; } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/WoW/Models/WoWUnit.cs b/Artemis/Artemis/Modules/Games/WoW/Models/WoWUnit.cs new file mode 100644 index 000000000..de82392e5 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/WoW/Models/WoWUnit.cs @@ -0,0 +1,118 @@ +using System.Collections.Generic; +using System.Linq; +using Artemis.Utilities; +using MoonSharp.Interpreter; +using Newtonsoft.Json.Linq; + +namespace Artemis.Modules.Games.WoW.Models +{ + [MoonSharpUserData] + public class WoWUnit + { + private readonly List _currentFrameCasts = new List(); + + public WoWUnit() + { + CastBar = new WoWCastBar(); + Specialization = new WoWSpecialization(); + + Buffs = new List(); + Debuffs = new List(); + RecentIntantCasts = new List(); + } + + public string Name { get; set; } + public int Level { get; set; } + public int Health { get; set; } + public int MaxHealth { get; set; } + public int Power { get; set; } + public int MaxPower { get; set; } + public WoWPowerType PowerType { get; set; } + public string Class { get; set; } + public WoWRace Race { get; set; } + public WoWGender Gender { get; set; } + + public WoWCastBar CastBar { get; set; } + public WoWSpecialization Specialization { get; } + + public List Buffs { get; } + public List Debuffs { get; } + public List RecentIntantCasts { get; private set; } + + public void ApplyJson(JObject json) + { + if (json["name"] == null) + return; + + Name = json["name"].Value(); + Level = json["level"].Value(); + Class = json["class"].Value(); + Gender = json["gender"].Value() == 3 ? WoWGender.Female : WoWGender.Male; + + if (json["race"] != null) + Race = GeneralHelpers.ParseEnum(json["race"].Value()); + if (json["specialization"] != null) + Specialization.ApplyJson(json["specialization"]); + } + + public void ApplyStateJson(JObject json) + { + Health = json["health"].Value(); + MaxHealth = json["maxHealth"].Value(); + PowerType = GeneralHelpers.ParseEnum(json["powerType"].Value().ToString()); + Power = json["power"].Value(); + MaxPower = json["maxPower"].Value(); + } + + public void ApplyAuraJson(JObject json) + { + Buffs.Clear(); + if (json["buffs"] != null) + { + foreach (var auraJson in json["buffs"].Children()) + { + var aura = new WoWAura(); + aura.ApplyJson(auraJson); + Buffs.Add(aura); + } + } + Debuffs.Clear(); + if (json["debuffs"] != null) + { + foreach (var auraJson in json["debuffs"].Children()) + { + var aura = new WoWAura(); + aura.ApplyJson(auraJson); + Debuffs.Add(aura); + } + } + } + + public void AddInstantCast(WoWSpell spell) + { + lock (_currentFrameCasts) + { + _currentFrameCasts.Add(spell); + } + } + + public void ClearInstantCasts() + { + lock (_currentFrameCasts) + { + // Remove all casts that weren't cast in the after the last frame + RecentIntantCasts.Clear(); + RecentIntantCasts.AddRange(_currentFrameCasts); + + // Clear the that were after the last frame so that they are removed next frame when this method is called again + _currentFrameCasts.Clear(); + } + } + + public void Update() + { + CastBar.UpdateProgress(); + ClearInstantCasts(); + } + } +} diff --git a/Artemis/Artemis/Modules/Games/WoW/WoWDataModel.cs b/Artemis/Artemis/Modules/Games/WoW/WoWDataModel.cs index 4d04e2bcc..3e2365362 100644 --- a/Artemis/Artemis/Modules/Games/WoW/WoWDataModel.cs +++ b/Artemis/Artemis/Modules/Games/WoW/WoWDataModel.cs @@ -1,12 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using Artemis.Modules.Abstract; -using Artemis.Utilities; -using Newtonsoft.Json.Linq; +using Artemis.Modules.Abstract; +using Artemis.Modules.Games.WoW.Models; +using MoonSharp.Interpreter; namespace Artemis.Modules.Games.WoW { + [MoonSharpUserData] public class WoWDataModel : ModuleDataModel { public WoWDataModel() @@ -22,203 +20,4 @@ namespace Artemis.Modules.Games.WoW public string Zone { get; set; } public string SubZone { get; set; } } - - public class WoWUnit - { - public WoWUnit() - { - Buffs = new List(); - Debuffs = new List(); - CastBar = new WoWCastBar(); - } - - public string Name { get; set; } - public int Level { get; set; } - public int Health { get; set; } - public int MaxHealth { get; set; } - public int Power { get; set; } - public int MaxPower { get; set; } - public WoWPowerType PowerType { get; set; } - public string Class { get; set; } - public WoWRace Race { get; set; } - public WoWGender Gender { get; set; } - public List Buffs { get; set; } - public List Debuffs { get; set; } - public WoWCastBar CastBar { get; set; } - - public void ApplyJson(JObject json) - { - if (json["name"] == null) - return; - - Name = json["name"].Value(); - Level = json["level"].Value(); - Class = json["class"].Value(); - Gender = json["gender"].Value() == 3 ? WoWGender.Female : WoWGender.Male; - - if (json["race"] != null) - Race = GeneralHelpers.ParseEnum(json["race"].Value()); - } - - public void ApplyStateJson(JObject json) - { - Health = json["health"].Value(); - MaxHealth = json["maxHealth"].Value(); - PowerType = GeneralHelpers.ParseEnum(json["powerType"].Value().ToString()); - Power = json["power"].Value(); - MaxPower = json["maxPower"].Value(); - - Buffs.Clear(); - if (json["buffs"] != null) - { - foreach (var auraJson in json["buffs"].Children()) - { - var aura = new WoWAura(); - aura.ApplyJson(auraJson); - Buffs.Add(aura); - } - } - Debuffs.Clear(); - if (json["debuffs"] != null) - { - foreach (var auraJson in json["debuffs"].Children()) - { - var aura = new WoWAura(); - aura.ApplyJson(auraJson); - Debuffs.Add(aura); - } - } - } - } - - public class WoWAura - { - public string Name { get; set; } - public int Id { get; set; } - public string Caster { get; set; } - public int Stacks { get; set; } - public DateTime StartTime { set; get; } - public DateTime EndTime { get; set; } - - public void ApplyJson(JToken buffJson) - { - Name = buffJson["name"].Value(); - Id = buffJson["spellID"].Value(); - Caster = buffJson["caster"].Value(); - Stacks = buffJson["count"].Value(); - - // TODO: Duration - } - } - - public class WoWCastBar - { - public void ApplyJson(JToken spellJson) - { - var castMs = spellJson["endTime"].Value() - spellJson["startTime"].Value(); - var tickCount = Environment.TickCount; - var difference = tickCount - spellJson["startTime"].Value(); - - SpellName = spellJson["name"].Value(); - SpellId = spellJson["spellID"].Value(); - StartTime = new DateTime(DateTime.Now.Ticks + difference); - EndTime = StartTime.AddMilliseconds(castMs); - NonInterruptible = spellJson["notInterruptible"].Value(); - - -// SpellName = spellJson["name"].Value(); -// SpellId = spellJson["spellID"].Value(); -// StartTime = DateTime.Now.AddMilliseconds(spellJson["startTime"].Value()/1000.0); -// EndTime = StartTime.AddMilliseconds(spellJson["endTime"].Value()/1000.0); -// NonInterruptible = spellJson["notInterruptible"].Value(); - } - - public void UpdateProgress() - { - if (SpellName == null) - return; - - var elapsed = DateTime.Now - StartTime; - var total = EndTime - StartTime; - Progress = (float) (elapsed.TotalMilliseconds / total.TotalMilliseconds); - Debug.WriteLine(Progress); - if (Progress > 1) - Clear(); - } - - public void Clear() - { - SpellName = null; - SpellId = 0; - StartTime = DateTime.MinValue; - EndTime = DateTime.MinValue; - NonInterruptible = false; - Progress = 0; - } - - public string SpellName { get; set; } - public int SpellId { get; set; } - public DateTime StartTime { set; get; } - public DateTime EndTime { get; set; } - public bool NonInterruptible { get; set; } - public float Progress { get; set; } - } - - public enum WoWPowerType - { - Mana = 0, - Rage = 1, - Focus = 2, - Energy = 3, - ComboPoints = 4, - Runes = 5, - RunicPower = 6, - SoulShards = 7, - LunarPower = 8, - HolyPower = 9, - AlternatePower = 10, - Maelstrom = 11, - Chi = 12, - Insanity = 13, - ArcaneCharges = 16 - } - - public enum WoWClass - { - Warrior, - Paladin, - Hunter, - Rogue, - Priest, - DeathKnight, - Shaman, - Mage, - Warlock, - Druid, - Monk, - DemonHunter - } - - public enum WoWRace - { - Human, - Orc, - Dwarf, - NightElf, - Undead, - Tauren, - Gnome, - Troll, - BloodElf, - Draenei, - Goblin, - Worgen, - Pandaren - } - - public enum WoWGender - { - Male, - Female - } } diff --git a/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs b/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs index e00838cc0..b3df1a6a5 100644 --- a/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs +++ b/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs @@ -1,198 +1,222 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Artemis.DAL; -using Artemis.Managers; -using Artemis.Modules.Abstract; -using Newtonsoft.Json.Linq; -using PcapDotNet.Core; -using PcapDotNet.Packets; - -namespace Artemis.Modules.Games.WoW -{ - public class WoWModel : ModuleModel - { - private readonly Regex _rgx; - private PacketCommunicator _communicator; - - public WoWModel(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager) - { - Settings = SettingsProvider.Load(); - DataModel = new WoWDataModel(); - ProcessNames.Add("Wow-64"); - - _rgx = new Regex("(artemis)\\((.*?)\\)", RegexOptions.Compiled); - } - - public override string Name => "WoW"; - public override bool IsOverlay => false; - public override bool IsBoundToProcess => true; - - - public override void Enable() - { - // Start scanning WoW packets - // Retrieve the device list from the local machine - IList allDevices = LivePacketDevice.AllLocalMachine; - - if (allDevices.Count == 0) - { - Logger.Warn("No interfaces found! Can't scan WoW packets."); - return; - } - - // Take the selected adapter - PacketDevice selectedDevice = allDevices.First(); - - // Open the device - _communicator = selectedDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 100); - Logger.Debug("Listening on " + selectedDevice.Description + " for WoW packets"); - - // Compile the filter - using (var filter = _communicator.CreateFilter("tcp")) - { - // Set the filter - _communicator.SetFilter(filter); - } - - Task.Run(() => ReceivePackets()); - base.Enable(); - } - - private void ReceivePackets() - { - // start the capture - try - { - _communicator.ReceivePackets(0, PacketHandler); - } - catch (InvalidOperationException) - { - // ignored, happens on shutdown - } - } - - private void PacketHandler(Packet packet) - { - // Ignore duplicates - if (packet.Ethernet.IpV4.Udp.SourcePort == 3724) - return; - - var str = Encoding.Default.GetString(packet.Buffer); - if (str.ToLower().Contains("artemis")) - { - var match = _rgx.Match(str); - if (match.Groups.Count != 3) - return; - - Logger.Debug("[{0}] {1}", packet.Ethernet.IpV4.Udp.SourcePort, match.Groups[2].Value); - // Get the command and argument - var parts = match.Groups[2].Value.Split('|'); - HandleGameData(parts[0], parts[1]); - } - } - - private void HandleGameData(string command, string data) - { - JObject json = null; - if (!data.StartsWith("\"") && !data.EndsWith("\"")) - json = JObject.Parse(data); - - lock (DataModel) - { - var dataModel = (WoWDataModel) DataModel; - switch (command) - { - case "player": - ParsePlayer(json, dataModel); - break; - case "target": - ParseTarget(json, dataModel); - break; - case "playerState": - ParsePlayerState(json, dataModel); - break; - case "targetState": - ParseTargetState(json, dataModel); - break; - case "spellCast": - ParseSpellCast(json, dataModel); - break; - case "spellCastFailed": - ParseSpellCastFailed(data, dataModel); - break; - case "spellCastInterrupted": - ParseSpellCastInterrupted(data, dataModel); - break; - } - } - } - - private void ParsePlayer(JObject json, WoWDataModel dataModel) - { - dataModel.Player.ApplyJson(json); - } - - private void ParseTarget(JObject json, WoWDataModel dataModel) - { - dataModel.Target.ApplyJson(json); - } - - private void ParsePlayerState(JObject json, WoWDataModel dataModel) - { - dataModel.Player.ApplyStateJson(json); - } - - private void ParseTargetState(JObject json, WoWDataModel dataModel) - { - dataModel.Target.ApplyStateJson(json); - } - - private void ParseSpellCast(JObject json, WoWDataModel dataModel) - { - if (json["unitID"].Value() == "player") - dataModel.Player.CastBar.ApplyJson(json); - else if (json["unitID"].Value() == "target") - dataModel.Target.CastBar.ApplyJson(json); - } - - private void ParseInstantSpellCast(JObject json, WoWDataModel dataModel) - { - - } - - private void ParseSpellCastFailed(string data, WoWDataModel dataModel) - { - if (data == "\"player\"") - dataModel.Player.CastBar.Clear(); - else if (data == "\"target\"") - dataModel.Target.CastBar.Clear(); - } - - private void ParseSpellCastInterrupted(string data, WoWDataModel dataModel) - { - if (data == "\"player\"") - dataModel.Player.CastBar.Clear(); - else if (data == "\"target\"") - dataModel.Target.CastBar.Clear(); - } - - public override void Dispose() - { - _communicator.Break(); - _communicator.Dispose(); - base.Dispose(); - } - - public override void Update() - { - var dataModel = (WoWDataModel)DataModel; - - dataModel.Player.CastBar.UpdateProgress(); - dataModel.Target.CastBar.UpdateProgress(); - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Artemis.DAL; +using Artemis.Managers; +using Artemis.Modules.Abstract; +using Artemis.Modules.Games.WoW.Models; +using Newtonsoft.Json.Linq; +using PcapDotNet.Core; +using PcapDotNet.Packets; + +namespace Artemis.Modules.Games.WoW +{ + public class WoWModel : ModuleModel + { + private readonly Regex _rgx; + private PacketCommunicator _communicator; + + public WoWModel(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager) + { + Settings = SettingsProvider.Load(); + DataModel = new WoWDataModel(); + ProcessNames.Add("Wow-64"); + + _rgx = new Regex("(artemis)\\((.*?)\\)", RegexOptions.Compiled); + } + + public override string Name => "WoW"; + public override bool IsOverlay => false; + public override bool IsBoundToProcess => true; + + + public override void Enable() + { + // Start scanning WoW packets + // Retrieve the device list from the local machine + IList allDevices = LivePacketDevice.AllLocalMachine; + + if (allDevices.Count == 0) + { + Logger.Warn("No interfaces found! Can't scan WoW packets."); + return; + } + + // Take the selected adapter + PacketDevice selectedDevice = allDevices.First(); + + // Open the device + _communicator = selectedDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 40); + Logger.Debug("Listening on " + selectedDevice.Description + " for WoW packets"); + + // Compile the filter + using (var filter = _communicator.CreateFilter("tcp")) + { + // Set the filter + _communicator.SetFilter(filter); + } + + Task.Run(() => ReceivePackets()); + base.Enable(); + } + + private void ReceivePackets() + { + // start the capture + try + { + _communicator.ReceivePackets(0, PacketHandler); + } + catch (InvalidOperationException) + { + // ignored, happens on shutdown + } + } + + private void PacketHandler(Packet packet) + { + // Ignore duplicates + if (packet.Ethernet.IpV4.Udp.SourcePort == 3724) + return; + + var str = Encoding.Default.GetString(packet.Buffer); + if (str.ToLower().Contains("artemis")) + { + var match = _rgx.Match(str); + if (match.Groups.Count != 3) + return; + + Logger.Trace("[{0}] {1}", packet.Ethernet.IpV4.Udp.SourcePort, match.Groups[2].Value); + // Get the command and argument + var parts = match.Groups[2].Value.Split('|'); + HandleGameData(parts[0], parts[1]); + } + } + + private void HandleGameData(string command, string data) + { + JObject json = null; + if (!data.StartsWith("\"") && !data.EndsWith("\"")) + json = JObject.Parse(data); + + lock (DataModel) + { + var dataModel = (WoWDataModel) DataModel; + switch (command) + { + case "player": + ParsePlayer(json, dataModel); + break; + case "target": + ParseTarget(json, dataModel); + break; + case "playerState": + ParsePlayerState(json, dataModel); + break; + case "targetState": + ParseTargetState(json, dataModel); + break; + case "auras": + ParseAuras(json, dataModel); + break; + case "spellCast": + ParseSpellCast(json, dataModel); + break; + case "instantSpellCast": + ParseInstantSpellCast(json, dataModel); + break; + case "spellCastFailed": + ParseSpellCastFailed(data, dataModel); + break; + case "spellCastInterrupted": + ParseSpellCastInterrupted(data, dataModel); + break; + default: + Logger.Warn("The WoW addon sent an unknown command: {0}", command); + break; + } + } + } + + private void ParsePlayer(JObject json, WoWDataModel dataModel) + { + dataModel.Player.ApplyJson(json); + } + + private void ParseTarget(JObject json, WoWDataModel dataModel) + { + dataModel.Target.ApplyJson(json); + } + + private void ParsePlayerState(JObject json, WoWDataModel dataModel) + { + dataModel.Player.ApplyStateJson(json); + } + + private void ParseTargetState(JObject json, WoWDataModel dataModel) + { + dataModel.Target.ApplyStateJson(json); + } + + private void ParseAuras(JObject json, WoWDataModel dataModel) + { + dataModel.Player.ApplyAuraJson(json); + } + + private void ParseSpellCast(JObject json, WoWDataModel dataModel) + { + if (json["unitID"].Value() == "player") + dataModel.Player.CastBar.ApplyJson(json); + else if (json["unitID"].Value() == "target") + dataModel.Target.CastBar.ApplyJson(json); + } + + private void ParseInstantSpellCast(JObject json, WoWDataModel dataModel) + { + var spell = new WoWSpell + { + Name = json["name"].Value(), + Id = json["spellID"].Value() + }; + + if (json["unitID"].Value() == "player") + dataModel.Player.AddInstantCast(spell); + else if (json["unitID"].Value() == "target") + dataModel.Target.AddInstantCast(spell); + } + + private void ParseSpellCastFailed(string data, WoWDataModel dataModel) + { + if (data == "\"player\"") + dataModel.Player.CastBar.Clear(); + else if (data == "\"target\"") + dataModel.Target.CastBar.Clear(); + } + + private void ParseSpellCastInterrupted(string data, WoWDataModel dataModel) + { + if (data == "\"player\"") + dataModel.Player.CastBar.Clear(); + else if (data == "\"target\"") + dataModel.Target.CastBar.Clear(); + } + + public override void Dispose() + { + _communicator.Break(); + _communicator.Dispose(); + base.Dispose(); + } + + public override void Update() + { + var dataModel = (WoWDataModel) DataModel; + + dataModel.Player.Update(); + dataModel.Target.Update(); + } + } +} diff --git a/Artemis/Artemis/Modules/Games/WoW/WoWSettings.cs b/Artemis/Artemis/Modules/Games/WoW/WoWSettings.cs index 2b2797c93..c4a3f3b5d 100644 --- a/Artemis/Artemis/Modules/Games/WoW/WoWSettings.cs +++ b/Artemis/Artemis/Modules/Games/WoW/WoWSettings.cs @@ -5,4 +5,4 @@ namespace Artemis.Modules.Games.WoW public class WoWSettings : ModuleSettings { } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml b/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml index 9537d78fd..032a99375 100644 --- a/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml +++ b/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml @@ -1,13 +1,6 @@ - + diff --git a/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml.cs b/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml.cs index 2e0bac541..33c9f8eb0 100644 --- a/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml.cs +++ b/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml.cs @@ -12,4 +12,4 @@ namespace Artemis.Modules.Games.WoW InitializeComponent(); } } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Modules/Games/WoW/WoWViewModel.cs b/Artemis/Artemis/Modules/Games/WoW/WoWViewModel.cs index eed8a1228..5978f88c2 100644 --- a/Artemis/Artemis/Modules/Games/WoW/WoWViewModel.cs +++ b/Artemis/Artemis/Modules/Games/WoW/WoWViewModel.cs @@ -14,4 +14,4 @@ namespace Artemis.Modules.Games.WoW public override bool UsesProfileEditor => true; } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs index 31aafa17d..265eb7ef3 100644 --- a/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs +++ b/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs @@ -12,6 +12,8 @@ namespace Artemis.Profiles.Layers.Conditions lock (layerModel.Properties.Conditions) { var checkConditions = layerModel.Properties.Conditions.Where(c => c.Field != null).ToList(); + if (!checkConditions.Any()) + return true; switch (layerModel.Properties.ConditionType) { case ConditionType.AnyMet: diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs index 9d7136081..b05d15b13 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs @@ -44,6 +44,8 @@ namespace Artemis.Profiles.Layers.Models var collectionField = _rgx.Match(Field).Groups[1].Value; var collectionInspect = (IEnumerable) GeneralHelpers.GetPropertyValue(subject, collectionField); var operatorParts = Operator.Split('|'); + var field = Field.Split(')').Last().Substring(1); + _lastValue = collectionInspect; if (operatorParts[0] == "any") @@ -51,7 +53,6 @@ namespace Artemis.Profiles.Layers.Models var anyMatch = false; foreach (var collectionValue in collectionInspect) { - var field = Field.Split(')').Last().Substring(1); anyMatch = EvaluateOperator(collectionValue, field, operatorParts[1]); if (anyMatch) break; @@ -63,7 +64,6 @@ namespace Artemis.Profiles.Layers.Models var allMatch = true; foreach (var collectionValue in collectionInspect) { - var field = Field.Split(')').Last().Substring(1); allMatch = EvaluateOperator(collectionValue, field, operatorParts[1]); if (!allMatch) break; @@ -75,7 +75,6 @@ namespace Artemis.Profiles.Layers.Models var noneMatch = true; foreach (var collectionValue in collectionInspect) { - var field = Field.Split(')').Last().Substring(1); noneMatch = !EvaluateOperator(collectionValue, field, operatorParts[1]); if (!noneMatch) break;