mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Rewrote most of the WoW module
This commit is contained in:
parent
681ce58c1e
commit
53dce2c4a5
@ -404,6 +404,12 @@
|
||||
<DependentUpon>TerrariaView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Modules\Games\Terraria\TerrariaViewModel.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Models\WoWAura.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Models\WoWCastBar.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Models\WoWEnums.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Models\WoWSpecialization.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Models\WoWSpell.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Models\WoWUnit.cs" />
|
||||
<Compile Include="Modules\General\GeneralProfile\PerformanceInfo.cs" />
|
||||
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryData.cs" />
|
||||
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryDataReader.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
Artemis/Artemis/Modules/Games/WoW/Models/WoWAura.cs
Normal file
27
Artemis/Artemis/Modules/Games/WoW/Models/WoWAura.cs
Normal file
@ -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<string>();
|
||||
Id = buffJson["spellID"].Value<int>();
|
||||
Stacks = buffJson["count"].Value<int>();
|
||||
Caster = buffJson["caster"]?.Value<string>();
|
||||
|
||||
// TODO: Duration
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Artemis/Artemis/Modules/Games/WoW/Models/WoWCastBar.cs
Normal file
57
Artemis/Artemis/Modules/Games/WoW/Models/WoWCastBar.cs
Normal file
@ -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<int>() - spellJson["startTime"].Value<int>();
|
||||
var tickCount = Environment.TickCount;
|
||||
var difference = tickCount - spellJson["startTime"].Value<int>();
|
||||
|
||||
Spell.Name = spellJson["name"].Value<string>();
|
||||
Spell.Id = spellJson["spellID"].Value<int>();
|
||||
StartTime = new DateTime(DateTime.Now.Ticks + difference);
|
||||
EndTime = StartTime.AddMilliseconds(castMs);
|
||||
NonInterruptible = spellJson["notInterruptible"].Value<bool>();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
Artemis/Artemis/Modules/Games/WoW/Models/WoWEnums.cs
Normal file
44
Artemis/Artemis/Modules/Games/WoW/Models/WoWEnums.cs
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
@ -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<string>();
|
||||
Id = specJson["id"].Value<int>();
|
||||
Role = specJson["role"].Value<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Artemis/Artemis/Modules/Games/WoW/Models/WoWSpell.cs
Normal file
11
Artemis/Artemis/Modules/Games/WoW/Models/WoWSpell.cs
Normal file
@ -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; }
|
||||
}
|
||||
}
|
||||
118
Artemis/Artemis/Modules/Games/WoW/Models/WoWUnit.cs
Normal file
118
Artemis/Artemis/Modules/Games/WoW/Models/WoWUnit.cs
Normal file
@ -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<WoWSpell> _currentFrameCasts = new List<WoWSpell>();
|
||||
|
||||
public WoWUnit()
|
||||
{
|
||||
CastBar = new WoWCastBar();
|
||||
Specialization = new WoWSpecialization();
|
||||
|
||||
Buffs = new List<WoWAura>();
|
||||
Debuffs = new List<WoWAura>();
|
||||
RecentIntantCasts = new List<WoWSpell>();
|
||||
}
|
||||
|
||||
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<WoWAura> Buffs { get; }
|
||||
public List<WoWAura> Debuffs { get; }
|
||||
public List<WoWSpell> RecentIntantCasts { get; private set; }
|
||||
|
||||
public void ApplyJson(JObject json)
|
||||
{
|
||||
if (json["name"] == null)
|
||||
return;
|
||||
|
||||
Name = json["name"].Value<string>();
|
||||
Level = json["level"].Value<int>();
|
||||
Class = json["class"].Value<string>();
|
||||
Gender = json["gender"].Value<int>() == 3 ? WoWGender.Female : WoWGender.Male;
|
||||
|
||||
if (json["race"] != null)
|
||||
Race = GeneralHelpers.ParseEnum<WoWRace>(json["race"].Value<string>());
|
||||
if (json["specialization"] != null)
|
||||
Specialization.ApplyJson(json["specialization"]);
|
||||
}
|
||||
|
||||
public void ApplyStateJson(JObject json)
|
||||
{
|
||||
Health = json["health"].Value<int>();
|
||||
MaxHealth = json["maxHealth"].Value<int>();
|
||||
PowerType = GeneralHelpers.ParseEnum<WoWPowerType>(json["powerType"].Value<int>().ToString());
|
||||
Power = json["power"].Value<int>();
|
||||
MaxPower = json["maxPower"].Value<int>();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<WoWAura>();
|
||||
Debuffs = new List<WoWAura>();
|
||||
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<WoWAura> Buffs { get; set; }
|
||||
public List<WoWAura> Debuffs { get; set; }
|
||||
public WoWCastBar CastBar { get; set; }
|
||||
|
||||
public void ApplyJson(JObject json)
|
||||
{
|
||||
if (json["name"] == null)
|
||||
return;
|
||||
|
||||
Name = json["name"].Value<string>();
|
||||
Level = json["level"].Value<int>();
|
||||
Class = json["class"].Value<string>();
|
||||
Gender = json["gender"].Value<int>() == 3 ? WoWGender.Female : WoWGender.Male;
|
||||
|
||||
if (json["race"] != null)
|
||||
Race = GeneralHelpers.ParseEnum<WoWRace>(json["race"].Value<string>());
|
||||
}
|
||||
|
||||
public void ApplyStateJson(JObject json)
|
||||
{
|
||||
Health = json["health"].Value<int>();
|
||||
MaxHealth = json["maxHealth"].Value<int>();
|
||||
PowerType = GeneralHelpers.ParseEnum<WoWPowerType>(json["powerType"].Value<int>().ToString());
|
||||
Power = json["power"].Value<int>();
|
||||
MaxPower = json["maxPower"].Value<int>();
|
||||
|
||||
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<string>();
|
||||
Id = buffJson["spellID"].Value<int>();
|
||||
Caster = buffJson["caster"].Value<string>();
|
||||
Stacks = buffJson["count"].Value<int>();
|
||||
|
||||
// TODO: Duration
|
||||
}
|
||||
}
|
||||
|
||||
public class WoWCastBar
|
||||
{
|
||||
public void ApplyJson(JToken spellJson)
|
||||
{
|
||||
var castMs = spellJson["endTime"].Value<int>() - spellJson["startTime"].Value<int>();
|
||||
var tickCount = Environment.TickCount;
|
||||
var difference = tickCount - spellJson["startTime"].Value<int>();
|
||||
|
||||
SpellName = spellJson["name"].Value<string>();
|
||||
SpellId = spellJson["spellID"].Value<int>();
|
||||
StartTime = new DateTime(DateTime.Now.Ticks + difference);
|
||||
EndTime = StartTime.AddMilliseconds(castMs);
|
||||
NonInterruptible = spellJson["notInterruptible"].Value<bool>();
|
||||
|
||||
|
||||
// SpellName = spellJson["name"].Value<string>();
|
||||
// SpellId = spellJson["spellID"].Value<int>();
|
||||
// StartTime = DateTime.Now.AddMilliseconds(spellJson["startTime"].Value<long>()/1000.0);
|
||||
// EndTime = StartTime.AddMilliseconds(spellJson["endTime"].Value<long>()/1000.0);
|
||||
// NonInterruptible = spellJson["notInterruptible"].Value<bool>();
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<WoWSettings>();
|
||||
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<LivePacketDevice> 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<string>() == "player")
|
||||
dataModel.Player.CastBar.ApplyJson(json);
|
||||
else if (json["unitID"].Value<string>() == "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<WoWSettings>();
|
||||
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<LivePacketDevice> 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<string>() == "player")
|
||||
dataModel.Player.CastBar.ApplyJson(json);
|
||||
else if (json["unitID"].Value<string>() == "target")
|
||||
dataModel.Target.CastBar.ApplyJson(json);
|
||||
}
|
||||
|
||||
private void ParseInstantSpellCast(JObject json, WoWDataModel dataModel)
|
||||
{
|
||||
var spell = new WoWSpell
|
||||
{
|
||||
Name = json["name"].Value<string>(),
|
||||
Id = json["spellID"].Value<int>()
|
||||
};
|
||||
|
||||
if (json["unitID"].Value<string>() == "player")
|
||||
dataModel.Player.AddInstantCast(spell);
|
||||
else if (json["unitID"].Value<string>() == "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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,4 +5,4 @@ namespace Artemis.Modules.Games.WoW
|
||||
public class WoWSettings : ModuleSettings
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,6 @@
|
||||
<UserControl x:Class="Artemis.Modules.Games.WoW.WoWView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
xmlns:cal="http://www.caliburnproject.org"
|
||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="476.986" d:DesignWidth="538.772">
|
||||
<UserControl x:Class="Artemis.Modules.Games.WoW.WoWView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
xmlns:cal="http://www.caliburnproject.org" xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" mc:Ignorable="d" d:DesignHeight="476.986" d:DesignWidth="538.772">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
|
||||
@ -12,4 +12,4 @@ namespace Artemis.Modules.Games.WoW
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,4 +14,4 @@ namespace Artemis.Modules.Games.WoW
|
||||
|
||||
public override bool UsesProfileEditor => true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user