mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Started WoW rework
This commit is contained in:
parent
f05cf0b6d9
commit
04e5943996
@ -255,6 +255,18 @@
|
||||
<HintPath>..\packages\squirrel.windows.1.4.4\lib\Net45\NuGet.Squirrel.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Base, Version=1.0.4.25027, Culture=neutral, PublicKeyToken=06a20bc2fabb1931, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Pcap.Net.x64.1.0.4.1\lib\net45\PcapDotNet.Base.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Core, Version=1.0.4.25149, Culture=neutral, PublicKeyToken=06a20bc2fabb1931, processorArchitecture=AMD64">
|
||||
<HintPath>..\packages\Pcap.Net.x64.1.0.4.1\lib\net45\PcapDotNet.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Core.Extensions, Version=1.0.4.25151, Culture=neutral, PublicKeyToken=06a20bc2fabb1931, processorArchitecture=AMD64">
|
||||
<HintPath>..\packages\Pcap.Net.x64.1.0.4.1\lib\net45\PcapDotNet.Core.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Packets, Version=1.0.4.25028, Culture=neutral, PublicKeyToken=06a20bc2fabb1931, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Pcap.Net.x64.1.0.4.1\lib\net45\PcapDotNet.Packets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Process.NET, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Process.NET.1.0.8\lib\Process.NET.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
@ -471,15 +483,6 @@
|
||||
<DependentUpon>UnrealTournamentView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Modules\Games\UnrealTournament\UnrealTournamentViewModel.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Data\Int128.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Data\WoWEnums.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Data\WoWOffsets.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Data\WoWStructs.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Data\WoWNameCache.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Data\WoWObjectManager.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Data\WoWObject.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Data\WoWPlayer.cs" />
|
||||
<Compile Include="Modules\Games\WoW\Data\WoWUnit.cs" />
|
||||
<Compile Include="Modules\Games\WoW\WoWView.xaml.cs">
|
||||
<DependentUpon>WoWView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@ -487,7 +490,6 @@
|
||||
<Compile Include="Modules\Games\WoW\WoWModel.cs" />
|
||||
<Compile Include="Modules\Games\WoW\WoWSettings.cs" />
|
||||
<Compile Include="Modules\Games\WoW\WoWViewModel.cs" />
|
||||
<Compile Include="Modules\Games\WoW\WoWAddresses.cs" />
|
||||
<Compile Include="Modules\Overlays\OverlayProfile\OverlayProfileDataModel.cs" />
|
||||
<Compile Include="Modules\Overlays\OverlayProfile\OverlayProfileModel.cs" />
|
||||
<Compile Include="Modules\Overlays\OverlayProfile\OverlayProfileSettings.cs" />
|
||||
@ -1098,6 +1100,7 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Modules\General\GeneralProfile\Discord\" />
|
||||
<Folder Include="Resources\Lua\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
||||
@ -24,10 +24,7 @@ namespace Artemis.Managers
|
||||
|
||||
Modules = new List<ModuleModel>(moduleModels.Where(m => !m.IsOverlay && !m.IsBoundToProcess));
|
||||
OverlayModules = new List<ModuleModel>(moduleModels.Where(m => m.IsOverlay));
|
||||
// Exclude WoW if needed
|
||||
ProcessModules = _generalSettings.GamestatePort == 62575
|
||||
? new List<ModuleModel>(moduleModels.Where(m => m.IsBoundToProcess))
|
||||
: new List<ModuleModel>(moduleModels.Where(m => m.IsBoundToProcess && m.Name != "WoW"));
|
||||
ProcessModules = new List<ModuleModel>(moduleModels.Where(m => m.IsBoundToProcess));
|
||||
|
||||
_logger.Info("Intialized ModuleManager");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,157 +0,0 @@
|
||||
namespace Artemis.Modules.Games.WoW.Data
|
||||
{
|
||||
public static class WoWEnums
|
||||
{
|
||||
public enum GuidType : byte
|
||||
{
|
||||
Null = 0,
|
||||
Uniq = 1,
|
||||
Player = 2,
|
||||
Item = 3,
|
||||
StaticDoor = 4,
|
||||
Transport = 5,
|
||||
Conversation = 6,
|
||||
Creature = 7,
|
||||
Vehicle = 8,
|
||||
Pet = 9,
|
||||
GameObject = 10,
|
||||
DynamicObject = 11,
|
||||
AreaTrigger = 12,
|
||||
Corpse = 13,
|
||||
LootObject = 14,
|
||||
SceneObject = 15,
|
||||
Scenario = 16,
|
||||
AiGroup = 17,
|
||||
DynamicDoor = 18,
|
||||
ClientActor = 19,
|
||||
Vignette = 20,
|
||||
CallForHelp = 21,
|
||||
AiResource = 22,
|
||||
AiLock = 23,
|
||||
AiLockTicket = 24,
|
||||
ChatChannel = 25,
|
||||
Party = 26,
|
||||
Guild = 27,
|
||||
WowAccount = 28,
|
||||
BNetAccount = 29,
|
||||
GmTask = 30,
|
||||
MobileSession = 31,
|
||||
RaidGroup = 32,
|
||||
Spell = 33,
|
||||
Mail = 34,
|
||||
WebObj = 35,
|
||||
LfgObject = 36,
|
||||
LfgList = 37,
|
||||
UserRouter = 38,
|
||||
PvpQueueGroup = 39,
|
||||
UserClient = 40,
|
||||
PetBattle = 41,
|
||||
UniqueUserClient = 42,
|
||||
BattlePet = 43
|
||||
}
|
||||
|
||||
public enum ObjectType
|
||||
{
|
||||
Object = 0,
|
||||
Item = 1,
|
||||
Container = 2,
|
||||
Unit = 3,
|
||||
Player = 4,
|
||||
GameObject = 5,
|
||||
DynamicObject = 6,
|
||||
Corpse = 7,
|
||||
AreaTrigger = 8,
|
||||
SceneObject = 9,
|
||||
Conversation = 10
|
||||
}
|
||||
|
||||
public enum PowerType
|
||||
{
|
||||
Mana = 0,
|
||||
Rage = 1,
|
||||
Focus = 2,
|
||||
Energy = 3,
|
||||
Happiness = 4,
|
||||
RunicPower = 5,
|
||||
Runes = 6,
|
||||
Health = 7,
|
||||
Maelstrom = 11,
|
||||
Insanity = 13,
|
||||
Fury = 17,
|
||||
Pain = 18,
|
||||
UNKNOWN
|
||||
}
|
||||
|
||||
public enum Reaction
|
||||
{
|
||||
Hostile = 1,
|
||||
Neutral = 3,
|
||||
Friendly = 4
|
||||
}
|
||||
|
||||
public enum ShapeshiftForm
|
||||
{
|
||||
Normal = 0,
|
||||
Cat = 1,
|
||||
TreeOfLife = 2,
|
||||
Travel = 3,
|
||||
Aqua = 4,
|
||||
Bear = 5,
|
||||
Ambient = 6,
|
||||
Ghoul = 7,
|
||||
DireBear = 8,
|
||||
CreatureBear = 14,
|
||||
CreatureCat = 15,
|
||||
GhostWolf = 16,
|
||||
BattleStance = 17,
|
||||
DefensiveStance = 18,
|
||||
BerserkerStance = 19,
|
||||
EpicFlightForm = 27,
|
||||
Shadow = 28,
|
||||
Stealth = 30,
|
||||
Moonkin = 31,
|
||||
SpiritOfRedemption = 32
|
||||
}
|
||||
|
||||
public enum WoWClass
|
||||
{
|
||||
None = 0,
|
||||
Warrior = 1,
|
||||
Paladin = 2,
|
||||
Hunter = 3,
|
||||
Rogue = 4,
|
||||
Priest = 5,
|
||||
DeathKnight = 6,
|
||||
Shaman = 7,
|
||||
Mage = 8,
|
||||
Warlock = 9,
|
||||
Druid = 11
|
||||
}
|
||||
|
||||
public enum WoWRace
|
||||
{
|
||||
Human = 1,
|
||||
Orc = 2,
|
||||
Dwarf = 3,
|
||||
NightElf = 4,
|
||||
Undead = 5,
|
||||
Tauren = 6,
|
||||
Gnome = 7,
|
||||
Troll = 8,
|
||||
Goblin = 9,
|
||||
BloodElf = 10,
|
||||
Draenei = 11,
|
||||
FelOrc = 12,
|
||||
Naga = 13,
|
||||
Broken = 14,
|
||||
Skeleton = 15,
|
||||
Worgen = 22
|
||||
}
|
||||
|
||||
public enum WoWType
|
||||
{
|
||||
Player,
|
||||
Npc
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,63 +0,0 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Process.NET;
|
||||
|
||||
namespace Artemis.Modules.Games.WoW.Data
|
||||
{
|
||||
public class WoWNameCache
|
||||
{
|
||||
public WoWNameCache(ProcessSharp process, IntPtr baseAddress)
|
||||
{
|
||||
Process = process;
|
||||
CurrentCacheAddress = process.Native.MainModule.BaseAddress + baseAddress.ToInt32();
|
||||
}
|
||||
|
||||
public ProcessSharp Process { get; set; }
|
||||
|
||||
public IntPtr CurrentCacheAddress { get; set; }
|
||||
|
||||
public WoWDetails GetNameByGuid(Guid searchGuid)
|
||||
{
|
||||
var current = Process.Memory.Read<IntPtr>(CurrentCacheAddress);
|
||||
var index = 0;
|
||||
while (current != IntPtr.Zero)
|
||||
{
|
||||
var guid = Process.Memory.Read<Guid>(current + 0x20);
|
||||
if (guid.Equals(searchGuid))
|
||||
{
|
||||
var pRace = Process.Memory.Read<int>(current + 0x88);
|
||||
var pClass = Process.Memory.Read<int>(current + 0x90);
|
||||
var pName = Process.Memory.Read(current + 0x31, Encoding.ASCII, 48);
|
||||
|
||||
var name = new WoWDetails(guid, pRace, pClass, WoWEnums.WoWType.Player, pName);
|
||||
return name;
|
||||
}
|
||||
|
||||
if (index > 20000)
|
||||
return null;
|
||||
|
||||
index++;
|
||||
current = Process.Memory.Read<IntPtr>(current);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class WoWDetails
|
||||
{
|
||||
public WoWDetails(Guid guid, int race, int @class, WoWEnums.WoWType type, string name)
|
||||
{
|
||||
Guid = guid;
|
||||
Race = (WoWEnums.WoWRace) race;
|
||||
Class = (WoWEnums.WoWClass) @class;
|
||||
Type = type;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public Guid Guid { get; set; }
|
||||
public WoWEnums.WoWRace Race { get; set; }
|
||||
public WoWEnums.WoWClass Class { get; set; }
|
||||
public WoWEnums.WoWType Type { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Process.NET;
|
||||
|
||||
namespace Artemis.Modules.Games.WoW.Data
|
||||
{
|
||||
public class WoWObject
|
||||
{
|
||||
private readonly bool _readPointer;
|
||||
|
||||
public WoWObject(IProcess process, IntPtr baseAddress, bool readPointer = false)
|
||||
{
|
||||
Process = process;
|
||||
BaseAddress = baseAddress;
|
||||
_readPointer = readPointer;
|
||||
|
||||
Guid = ReadField<Guid>(0x00);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public IntPtr BaseAddress { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public IProcess Process { get; set; }
|
||||
|
||||
public Guid Guid { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public WoWStructs.ObjectData Data { get; set; }
|
||||
|
||||
public T ReadField<T>(int offset)
|
||||
{
|
||||
var address = GetAddress();
|
||||
if (address == IntPtr.Zero)
|
||||
return default(T);
|
||||
|
||||
var ptr = Process.Memory.Read<IntPtr>(address + 0x10);
|
||||
return Process.Memory.Read<T>(ptr + offset);
|
||||
}
|
||||
|
||||
public T ReadField<T>(Enum offset)
|
||||
{
|
||||
var address = GetAddress();
|
||||
if (address == IntPtr.Zero)
|
||||
return default(T);
|
||||
|
||||
var ptr = Process.Memory.Read<IntPtr>(address + 0x10);
|
||||
return Process.Memory.Read<T>(ptr + Convert.ToInt32(offset));
|
||||
}
|
||||
|
||||
private IntPtr GetAddress()
|
||||
{
|
||||
return _readPointer
|
||||
? Process.Memory.Read<IntPtr>(Process.Native.MainModule.BaseAddress + BaseAddress.ToInt32())
|
||||
: BaseAddress;
|
||||
}
|
||||
|
||||
public WoWDetails GetNpcDetails()
|
||||
{
|
||||
var address = GetAddress();
|
||||
if (address == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
var npcCachePtr = Process.Memory.Read<IntPtr>(address + 0x1760);
|
||||
if (npcCachePtr == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
var npcName = Process.Memory.Read(Process.Memory.Read<IntPtr>(npcCachePtr + 0x00A0), Encoding.ASCII, 48);
|
||||
return new WoWDetails(Guid, 0, 0, WoWEnums.WoWType.Npc, npcName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Process.NET;
|
||||
|
||||
namespace Artemis.Modules.Games.WoW.Data
|
||||
{
|
||||
public class WoWObjectManager
|
||||
{
|
||||
public WoWObjectManager(IProcess process, IntPtr baseAddress)
|
||||
{
|
||||
Process = process;
|
||||
CurrentManagerAddress = process.Native.MainModule.BaseAddress + baseAddress.ToInt32();
|
||||
}
|
||||
|
||||
public IProcess Process { get; set; }
|
||||
|
||||
public IntPtr CurrentManagerAddress { get; set; }
|
||||
|
||||
public Dictionary<WoWStructs.Guid, WoWObject> WoWObjects { get; set; }
|
||||
|
||||
public IntPtr GetFirstObject()
|
||||
{
|
||||
var mgr = GetCurrentManager();
|
||||
return mgr.VisibleObjects.m_fulllist.baseClass.m_terminator.m_next;
|
||||
}
|
||||
|
||||
public WoWStructs.CurrentManager GetCurrentManager()
|
||||
{
|
||||
return Process.Memory.Read<WoWStructs.CurrentManager>(Process.Memory.Read<IntPtr>(CurrentManagerAddress));
|
||||
}
|
||||
|
||||
public IntPtr GetNextObjectFromCurrent(IntPtr current)
|
||||
{
|
||||
var mgr = GetCurrentManager();
|
||||
|
||||
return Process.Memory.Read<IntPtr>(
|
||||
current + mgr.VisibleObjects.m_fulllist.baseClass.m_linkoffset + IntPtr.Size);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
WoWObjects.Clear();
|
||||
var wowObjects = EnumVisibleObjects();
|
||||
foreach (var wowObject in wowObjects)
|
||||
WoWObjects[wowObject.Data.Guid] = wowObject;
|
||||
|
||||
OnObjectsUpdated(WoWObjects);
|
||||
}
|
||||
|
||||
public event EventHandler<Dictionary<WoWStructs.Guid, WoWObject>> ObjectsUpdated;
|
||||
|
||||
// Loop through the games object list.
|
||||
public IEnumerable<WoWObject> EnumVisibleObjects()
|
||||
{
|
||||
var first = GetFirstObject();
|
||||
var typeOffset = Marshal.OffsetOf(typeof(WoWStructs.ObjectData), "ObjectType").ToInt32();
|
||||
|
||||
while (((first.ToInt64() & 1) == 0) && (first != IntPtr.Zero))
|
||||
{
|
||||
var type = (WoWEnums.ObjectType) Process.Memory.Read<int>(first + typeOffset);
|
||||
|
||||
// Fix below with other object types as added.
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch (type)
|
||||
{
|
||||
case WoWEnums.ObjectType.Object:
|
||||
yield return new WoWObject(Process, first);
|
||||
break;
|
||||
case WoWEnums.ObjectType.Container:
|
||||
break;
|
||||
case WoWEnums.ObjectType.Unit:
|
||||
yield return new WoWUnit(Process, first);
|
||||
break;
|
||||
case WoWEnums.ObjectType.Player:
|
||||
yield return new WoWPlayer(Process, first, new IntPtr(0x179A6E0));
|
||||
break;
|
||||
default:
|
||||
yield return new WoWObject(Process, first);
|
||||
break;
|
||||
}
|
||||
|
||||
first = GetNextObjectFromCurrent(first);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnObjectsUpdated(Dictionary<WoWStructs.Guid, WoWObject> e)
|
||||
{
|
||||
ObjectsUpdated?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,368 +0,0 @@
|
||||
namespace Artemis.Modules.Games.WoW.Data
|
||||
{
|
||||
internal static class WoWOffsets
|
||||
{
|
||||
internal enum AreaTriggerData
|
||||
{
|
||||
OverrideScaleCurve = 0x30, // Size: 0x7, Flags: 0x201
|
||||
ExtraScaleCurve = 0x4C, // Size: 0x7, Flags: 0x201
|
||||
Caster = 0x68, // Size: 0x4, Flags: 0x1
|
||||
Duration = 0x78, // Size: 0x1, Flags: 0x1
|
||||
TimeToTarget = 0x7C, // Size: 0x1, Flags: 0x201
|
||||
TimeToTargetScale = 0x80, // Size: 0x1, Flags: 0x201
|
||||
TimeToTargetExtraScale = 0x84, // Size: 0x1, Flags: 0x201
|
||||
SpellId = 0x88, // Size: 0x1, Flags: 0x1
|
||||
SpellVisualId = 0x8C, // Size: 0x1, Flags: 0x80
|
||||
BoundsRadius2D = 0x90, // Size: 0x1, Flags: 0x280
|
||||
DecalPropertiesId = 0x94 // Size: 0x1, Flags: 0x1
|
||||
}
|
||||
|
||||
internal enum ContainerData
|
||||
{
|
||||
Slots = 0x150, // Size: 0x90, Flags: 0x1
|
||||
NumSlots = 0x390 // Size: 0x1, Flags: 0x1
|
||||
}
|
||||
|
||||
internal enum ConversationData
|
||||
{
|
||||
LastLineDuration = 0x30 // Size: 0x1, Flags: 0x80
|
||||
}
|
||||
|
||||
internal enum CorpseData
|
||||
{
|
||||
Owner = 0x30, // Size: 0x4, Flags: 0x1
|
||||
PartyGuid = 0x40, // Size: 0x4, Flags: 0x1
|
||||
DisplayId = 0x50, // Size: 0x1, Flags: 0x1
|
||||
Items = 0x54, // Size: 0x13, Flags: 0x1
|
||||
SkinId = 0xA0, // Size: 0x1, Flags: 0x1
|
||||
FacialHairStyleId = 0xA4, // Size: 0x1, Flags: 0x1
|
||||
Flags = 0xA8, // Size: 0x1, Flags: 0x1
|
||||
DynamicFlags = 0xAC, // Size: 0x1, Flags: 0x80
|
||||
FactionTemplate = 0xB0, // Size: 0x1, Flags: 0x1
|
||||
CustomDisplayOption = 0xB4 // Size: 0x1, Flags: 0x1
|
||||
}
|
||||
|
||||
internal enum DynamicObjectData
|
||||
{
|
||||
Caster = 0x30, // Size: 0x4, Flags: 0x1
|
||||
TypeAndVisualId = 0x40, // Size: 0x1, Flags: 0x80
|
||||
SpellId = 0x44, // Size: 0x1, Flags: 0x1
|
||||
Radius = 0x48, // Size: 0x1, Flags: 0x1
|
||||
CastTime = 0x4C // Size: 0x1, Flags: 0x1
|
||||
}
|
||||
|
||||
internal enum GameObjectData
|
||||
{
|
||||
CreatedBy = 0x30, // Size: 0x4, Flags: 0x1
|
||||
DisplayId = 0x40, // Size: 0x1, Flags: 0x280
|
||||
Flags = 0x44, // Size: 0x1, Flags: 0x201
|
||||
ParentRotation = 0x48, // Size: 0x4, Flags: 0x1
|
||||
FactionTemplate = 0x58, // Size: 0x1, Flags: 0x1
|
||||
Level = 0x5C, // Size: 0x1, Flags: 0x1
|
||||
PercentHealth = 0x60, // Size: 0x1, Flags: 0x201
|
||||
SpellVisualId = 0x64, // Size: 0x1, Flags: 0x281
|
||||
StateSpellVisualId = 0x68, // Size: 0x1, Flags: 0x280
|
||||
StateAnimId = 0x6C, // Size: 0x1, Flags: 0x280
|
||||
StateAnimKitId = 0x70, // Size: 0x1, Flags: 0x280
|
||||
StateWorldEffectId = 0x74 // Size: 0x4, Flags: 0x280
|
||||
}
|
||||
|
||||
internal enum ItemData
|
||||
{
|
||||
Owner = 0x30, // Size: 0x4, Flags: 0x1
|
||||
ContainedIn = 0x40, // Size: 0x4, Flags: 0x1
|
||||
Creator = 0x50, // Size: 0x4, Flags: 0x1
|
||||
GiftCreator = 0x60, // Size: 0x4, Flags: 0x1
|
||||
StackCount = 0x70, // Size: 0x1, Flags: 0x4
|
||||
Expiration = 0x74, // Size: 0x1, Flags: 0x4
|
||||
SpellCharges = 0x78, // Size: 0x5, Flags: 0x4
|
||||
DynamicFlags = 0x8C, // Size: 0x1, Flags: 0x1
|
||||
Enchantment = 0x90, // Size: 0x27, Flags: 0x1
|
||||
PropertySeed = 0x12C, // Size: 0x1, Flags: 0x1
|
||||
RandomPropertiesId = 0x130, // Size: 0x1, Flags: 0x1
|
||||
Durability = 0x134, // Size: 0x1, Flags: 0x4
|
||||
MaxDurability = 0x138, // Size: 0x1, Flags: 0x4
|
||||
CreatePlayedTime = 0x13C, // Size: 0x1, Flags: 0x1
|
||||
ModifiersMask = 0x140, // Size: 0x1, Flags: 0x4
|
||||
Context = 0x144, // Size: 0x1, Flags: 0x1
|
||||
ArtifactXp = 0x148, // Size: 0x1, Flags: 0x4
|
||||
ItemAppearanceModId = 0x14C // Size: 0x1, Flags: 0x4
|
||||
}
|
||||
|
||||
internal enum KeyBinding
|
||||
{
|
||||
NumKeyBindings = 0x1700030, // -0x17C0
|
||||
First = 0xC8,
|
||||
Next = 0xB8,
|
||||
Key = 0x30,
|
||||
Command = 0x58
|
||||
}
|
||||
|
||||
internal enum ObjectData
|
||||
{
|
||||
Guid = 0x0, // Size: 0x4, Flags: 0x1
|
||||
Data = 0x10, // Size: 0x4, Flags: 0x1
|
||||
Type = 0x20, // Size: 0x1, Flags: 0x1
|
||||
EntryId = 0x24, // Size: 0x1, Flags: 0x80
|
||||
DynamicFlags = 0x28, // Size: 0x1, Flags: 0x280
|
||||
Scale = 0x2C // Size: 0x1, Flags: 0x1
|
||||
}
|
||||
|
||||
internal enum PlayerData
|
||||
{
|
||||
DuelArbiter = 0x360, // Size: 0x4, Flags: 0x1
|
||||
WowAccount = 0x370, // Size: 0x4, Flags: 0x1
|
||||
LootTargetGuid = 0x380, // Size: 0x4, Flags: 0x1
|
||||
PlayerFlags = 0x390, // Size: 0x1, Flags: 0x1
|
||||
PlayerFlagsEx = 0x394, // Size: 0x1, Flags: 0x1
|
||||
GuildRankId = 0x398, // Size: 0x1, Flags: 0x1
|
||||
GuildDeleteDate = 0x39C, // Size: 0x1, Flags: 0x1
|
||||
GuildLevel = 0x3A0, // Size: 0x1, Flags: 0x1
|
||||
HairColorId = 0x3A4, // Size: 0x1, Flags: 0x1
|
||||
CustomDisplayOption = 0x3A8, // Size: 0x1, Flags: 0x1
|
||||
Inebriation = 0x3AC, // Size: 0x1, Flags: 0x1
|
||||
ArenaFaction = 0x3B0, // Size: 0x1, Flags: 0x1
|
||||
DuelTeam = 0x3B4, // Size: 0x1, Flags: 0x1
|
||||
GuildTimeStamp = 0x3B8, // Size: 0x1, Flags: 0x1
|
||||
QuestLog = 0x3BC, // Size: 0x320, Flags: 0x20
|
||||
VisibleItems = 0x103C, // Size: 0x26, Flags: 0x1
|
||||
PlayerTitle = 0x10D4, // Size: 0x1, Flags: 0x1
|
||||
FakeInebriation = 0x10D8, // Size: 0x1, Flags: 0x1
|
||||
VirtualPlayerRealm = 0x10DC, // Size: 0x1, Flags: 0x1
|
||||
CurrentSpecId = 0x10E0, // Size: 0x1, Flags: 0x1
|
||||
TaxiMountAnimKitId = 0x10E4, // Size: 0x1, Flags: 0x1
|
||||
AvgItemLevel = 0x10E8, // Size: 0x4, Flags: 0x1
|
||||
CurrentBattlePetBreedQuality = 0x10F8, // Size: 0x1, Flags: 0x1
|
||||
Prestige = 0x10FC, // Size: 0x1, Flags: 0x1
|
||||
HonorLevel = 0x1100, // Size: 0x1, Flags: 0x1
|
||||
InvSlots = 0x1104, // Size: 0x2EC, Flags: 0x2
|
||||
FarsightObject = 0x1CB4, // Size: 0x4, Flags: 0x2
|
||||
SummonedBattlePetGuid = 0x1CC4, // Size: 0x4, Flags: 0x2
|
||||
KnownTitles = 0x1CD4, // Size: 0xC, Flags: 0x2
|
||||
Coinage = 0x1D04, // Size: 0x2, Flags: 0x2
|
||||
Xp = 0x1D0C, // Size: 0x1, Flags: 0x2
|
||||
NextLevelXp = 0x1D10, // Size: 0x1, Flags: 0x2
|
||||
Skill = 0x1D14, // Size: 0x1C0, Flags: 0x2
|
||||
CharacterPoints = 0x2414, // Size: 0x1, Flags: 0x2
|
||||
MaxTalentTiers = 0x2418, // Size: 0x1, Flags: 0x2
|
||||
TrackCreatureMask = 0x241C, // Size: 0x1, Flags: 0x2
|
||||
TrackResourceMask = 0x2420, // Size: 0x1, Flags: 0x2
|
||||
MainhandExpertise = 0x2424, // Size: 0x1, Flags: 0x2
|
||||
OffhandExpertise = 0x2428, // Size: 0x1, Flags: 0x2
|
||||
RangedExpertise = 0x242C, // Size: 0x1, Flags: 0x2
|
||||
CombatRatingExpertise = 0x2430, // Size: 0x1, Flags: 0x2
|
||||
BlockPercentage = 0x2434, // Size: 0x1, Flags: 0x2
|
||||
DodgePercentage = 0x2438, // Size: 0x1, Flags: 0x2
|
||||
ParryPercentage = 0x243C, // Size: 0x1, Flags: 0x2
|
||||
CritPercentage = 0x2440, // Size: 0x1, Flags: 0x2
|
||||
RangedCritPercentage = 0x2444, // Size: 0x1, Flags: 0x2
|
||||
OffhandCritPercentage = 0x2448, // Size: 0x1, Flags: 0x2
|
||||
SpellCritPercentage = 0x244C, // Size: 0x1, Flags: 0x2
|
||||
ShieldBlock = 0x2450, // Size: 0x1, Flags: 0x2
|
||||
ShieldBlockCritPercentage = 0x2454, // Size: 0x1, Flags: 0x2
|
||||
Mastery = 0x2458, // Size: 0x1, Flags: 0x2
|
||||
Speed = 0x245C, // Size: 0x1, Flags: 0x2
|
||||
Lifesteal = 0x2460, // Size: 0x1, Flags: 0x2
|
||||
Avoidance = 0x2464, // Size: 0x1, Flags: 0x2
|
||||
Sturdiness = 0x2468, // Size: 0x1, Flags: 0x2
|
||||
Versatility = 0x246C, // Size: 0x1, Flags: 0x2
|
||||
VersatilityBonus = 0x2470, // Size: 0x1, Flags: 0x2
|
||||
PvpPowerDamage = 0x2474, // Size: 0x1, Flags: 0x2
|
||||
PvpPowerHealing = 0x2478, // Size: 0x1, Flags: 0x2
|
||||
ExploredZones = 0x247C, // Size: 0x100, Flags: 0x2
|
||||
RestInfo = 0x287C, // Size: 0x4, Flags: 0x2
|
||||
ModDamageDonePos = 0x288C, // Size: 0x7, Flags: 0x2
|
||||
ModDamageDoneNeg = 0x28A8, // Size: 0x7, Flags: 0x2
|
||||
ModDamageDonePercent = 0x28C4, // Size: 0x7, Flags: 0x2
|
||||
ModHealingDonePos = 0x28E0, // Size: 0x1, Flags: 0x2
|
||||
ModHealingPercent = 0x28E4, // Size: 0x1, Flags: 0x2
|
||||
ModHealingDonePercent = 0x28E8, // Size: 0x1, Flags: 0x2
|
||||
ModPeriodicHealingDonePercent = 0x28EC, // Size: 0x1, Flags: 0x2
|
||||
WeaponDmgMultipliers = 0x28F0, // Size: 0x3, Flags: 0x2
|
||||
WeaponAtkSpeedMultipliers = 0x28FC, // Size: 0x3, Flags: 0x2
|
||||
ModSpellPowerPercent = 0x2908, // Size: 0x1, Flags: 0x2
|
||||
ModResiliencePercent = 0x290C, // Size: 0x1, Flags: 0x2
|
||||
OverrideSpellPowerByApPercent = 0x2910, // Size: 0x1, Flags: 0x2
|
||||
OverrideApBySpellPowerPercent = 0x2914, // Size: 0x1, Flags: 0x2
|
||||
ModTargetResistance = 0x2918, // Size: 0x1, Flags: 0x2
|
||||
ModTargetPhysicalResistance = 0x291C, // Size: 0x1, Flags: 0x2
|
||||
LocalFlags = 0x2920, // Size: 0x1, Flags: 0x2
|
||||
NumRespecs = 0x2924, // Size: 0x1, Flags: 0x2
|
||||
SelfResSpell = 0x2928, // Size: 0x1, Flags: 0x2
|
||||
PvpMedals = 0x292C, // Size: 0x1, Flags: 0x2
|
||||
BuybackPrice = 0x2930, // Size: 0xC, Flags: 0x2
|
||||
BuybackTimestamp = 0x2960, // Size: 0xC, Flags: 0x2
|
||||
YesterdayHonorableKills = 0x2990, // Size: 0x1, Flags: 0x2
|
||||
LifetimeHonorableKills = 0x2994, // Size: 0x1, Flags: 0x2
|
||||
WatchedFactionIndex = 0x2998, // Size: 0x1, Flags: 0x2
|
||||
CombatRatings = 0x299C, // Size: 0x20, Flags: 0x2
|
||||
PvpInfo = 0x2A1C, // Size: 0x24, Flags: 0x2
|
||||
MaxLevel = 0x2AAC, // Size: 0x1, Flags: 0x2
|
||||
ScalingPlayerLevelDelta = 0x2AB0, // Size: 0x1, Flags: 0x2
|
||||
MaxCreatureScalingLevel = 0x2AB4, // Size: 0x1, Flags: 0x2
|
||||
NoReagentCostMask = 0x2AB8, // Size: 0x4, Flags: 0x2
|
||||
PetSpellPower = 0x2AC8, // Size: 0x1, Flags: 0x2
|
||||
Researching = 0x2ACC, // Size: 0xA, Flags: 0x2
|
||||
ProfessionSkillLine = 0x2AF4, // Size: 0x2, Flags: 0x2
|
||||
UiHitModifier = 0x2AFC, // Size: 0x1, Flags: 0x2
|
||||
UiSpellHitModifier = 0x2B00, // Size: 0x1, Flags: 0x2
|
||||
HomeRealmTimeOffset = 0x2B04, // Size: 0x1, Flags: 0x2
|
||||
ModPetHaste = 0x2B08, // Size: 0x1, Flags: 0x2
|
||||
OverrideSpellsId = 0x2B0C, // Size: 0x1, Flags: 0x402
|
||||
LfgBonusFactionId = 0x2B10, // Size: 0x1, Flags: 0x2
|
||||
LootSpecId = 0x2B14, // Size: 0x1, Flags: 0x2
|
||||
OverrideZonePvpType = 0x2B18, // Size: 0x1, Flags: 0x402
|
||||
BagSlotFlags = 0x2B1C, // Size: 0x4, Flags: 0x2
|
||||
BankBagSlotFlags = 0x2B2C, // Size: 0x7, Flags: 0x2
|
||||
InsertItemsLeftToRight = 0x2B48, // Size: 0x1, Flags: 0x2
|
||||
QuestCompleted = 0x2B4C, // Size: 0x36B, Flags: 0x2
|
||||
Honor = 0x38F8, // Size: 0x1, Flags: 0x2
|
||||
HonorNextLevel = 0x38FC // Size: 0x1, Flags: 0x2
|
||||
}
|
||||
|
||||
internal enum SceneObjectData
|
||||
{
|
||||
ScriptPackageId = 0x30, // Size: 0x1, Flags: 0x1
|
||||
RndSeedVal = 0x34, // Size: 0x1, Flags: 0x1
|
||||
CreatedBy = 0x38, // Size: 0x4, Flags: 0x1
|
||||
SceneType = 0x48 // Size: 0x1, Flags: 0x1
|
||||
}
|
||||
|
||||
internal enum Unit
|
||||
{
|
||||
CurrentCastId = 0x1B98,
|
||||
CurrentChanneledId = 0x1BB8,
|
||||
AuraTable = 0x1D10,
|
||||
AuraCount = 0x2390,
|
||||
AuraSize = 0x68,
|
||||
ClientRace = 0x2670,
|
||||
DisplayData = 0x1718
|
||||
}
|
||||
|
||||
// Note: Invalid possibly!
|
||||
internal enum UnitAuras : uint
|
||||
{
|
||||
AuraCount1 = 0x2390,
|
||||
AuraCount2 = 0x1D10,
|
||||
AuraTable1 = 0x1D14,
|
||||
AuraTable2 = 0x1D18,
|
||||
AuraSize = 0x68,
|
||||
|
||||
OwnerGuid = 0x40,
|
||||
AuraSpellId = 0x50,
|
||||
//AuraFlags = 0x54, //Not exactly sure here.
|
||||
//AuraLevel = 0x58, //Not exactly sure here.
|
||||
AuraStack = 0x59,
|
||||
TimeLeft = 0x60,
|
||||
//In case I need it:
|
||||
DruidEclipse = 0x2694
|
||||
}
|
||||
|
||||
// Below is all of the World of Warcraft in-game object field offsets.
|
||||
// Commenting is not used on purpose and enums below should remain internal.
|
||||
internal enum UnitData
|
||||
{
|
||||
Charm = 0x30, // Size: 0x4, Flags: 0x1
|
||||
Summon = 0x40, // Size: 0x4, Flags: 0x1
|
||||
Critter = 0x50, // Size: 0x4, Flags: 0x2
|
||||
CharmedBy = 0x60, // Size: 0x4, Flags: 0x1
|
||||
SummonedBy = 0x70, // Size: 0x4, Flags: 0x1
|
||||
CreatedBy = 0x80, // Size: 0x4, Flags: 0x1
|
||||
DemonCreator = 0x90, // Size: 0x4, Flags: 0x1
|
||||
Target = 0xA0, // Size: 0x4, Flags: 0x1
|
||||
BattlePetCompanionGuid = 0xB0, // Size: 0x4, Flags: 0x1
|
||||
BattlePetDbid = 0xC0, // Size: 0x2, Flags: 0x1
|
||||
ChannelObject = 0xC8, // Size: 0x4, Flags: 0x201
|
||||
ChannelSpell = 0xD8, // Size: 0x1, Flags: 0x201
|
||||
ChannelSpellXSpellVisual = 0xDC, // Size: 0x1, Flags: 0x201
|
||||
SummonedByHomeRealm = 0xE0, // Size: 0x1, Flags: 0x1
|
||||
Sex = 0xE4, // Size: 0x1, Flags: 0x1
|
||||
DisplayPower = 0xE8, // Size: 0x1, Flags: 0x1
|
||||
OverrideDisplayPowerId = 0xEC, // Size: 0x1, Flags: 0x1
|
||||
Health = 0xF0, // Size: 0x2, Flags: 0x1
|
||||
Power = 0xF8, // Size: 0x6, Flags: 0x401
|
||||
TertiaryPower = 0xFC,
|
||||
SecondaryPower = 0x100,
|
||||
MaxHealth = 0x110, // Size: 0x2, Flags: 0x1
|
||||
MaxPower = 0x118, // Size: 0x6, Flags: 0x1
|
||||
PowerRegenFlatModifier = 0x130, // Size: 0x6, Flags: 0x46
|
||||
PowerRegenInterruptedFlatModifier = 0x148, // Size: 0x6, Flags: 0x46
|
||||
Level = 0x160, // Size: 0x1, Flags: 0x1
|
||||
EffectiveLevel = 0x164, // Size: 0x1, Flags: 0x1
|
||||
ScalingLevelMin = 0x168, // Size: 0x1, Flags: 0x1
|
||||
ScalingLevelMax = 0x16C, // Size: 0x1, Flags: 0x1
|
||||
ScalingLevelDelta = 0x170, // Size: 0x1, Flags: 0x1
|
||||
FactionTemplate = 0x174, // Size: 0x1, Flags: 0x1
|
||||
VirtualItems = 0x178, // Size: 0x6, Flags: 0x1
|
||||
Flags = 0x190, // Size: 0x1, Flags: 0x201
|
||||
Flags2 = 0x194, // Size: 0x1, Flags: 0x201
|
||||
Flags3 = 0x198, // Size: 0x1, Flags: 0x201
|
||||
AuraState = 0x19C, // Size: 0x1, Flags: 0x1
|
||||
AttackRoundBaseTime = 0x1A0, // Size: 0x2, Flags: 0x1
|
||||
RangedAttackRoundBaseTime = 0x1A8, // Size: 0x1, Flags: 0x2
|
||||
BoundingRadius = 0x1AC, // Size: 0x1, Flags: 0x1
|
||||
CombatReach = 0x1B0, // Size: 0x1, Flags: 0x1
|
||||
DisplayId = 0x1B4, // Size: 0x1, Flags: 0x280
|
||||
NativeDisplayId = 0x1B8, // Size: 0x1, Flags: 0x201
|
||||
MountDisplayId = 0x1BC, // Size: 0x1, Flags: 0x201
|
||||
MinDamage = 0x1C0, // Size: 0x1, Flags: 0x16
|
||||
MaxDamage = 0x1C4, // Size: 0x1, Flags: 0x16
|
||||
MinOffHandDamage = 0x1C8, // Size: 0x1, Flags: 0x16
|
||||
MaxOffHandDamage = 0x1CC, // Size: 0x1, Flags: 0x16
|
||||
AnimTier = 0x1D0, // Size: 0x1, Flags: 0x1
|
||||
PetNumber = 0x1D4, // Size: 0x1, Flags: 0x1
|
||||
PetNameTimestamp = 0x1D8, // Size: 0x1, Flags: 0x1
|
||||
PetExperience = 0x1DC, // Size: 0x1, Flags: 0x4
|
||||
PetNextLevelExperience = 0x1E0, // Size: 0x1, Flags: 0x4
|
||||
ModCastingSpeed = 0x1E4, // Size: 0x1, Flags: 0x1
|
||||
ModSpellHaste = 0x1E8, // Size: 0x1, Flags: 0x1
|
||||
ModHaste = 0x1EC, // Size: 0x1, Flags: 0x1
|
||||
ModRangedHaste = 0x1F0, // Size: 0x1, Flags: 0x1
|
||||
ModHasteRegen = 0x1F4, // Size: 0x1, Flags: 0x1
|
||||
ModTimeRate = 0x1F8, // Size: 0x1, Flags: 0x1
|
||||
CreatedBySpell = 0x1FC, // Size: 0x1, Flags: 0x1
|
||||
NpcFlags = 0x200, // Size: 0x2, Flags: 0x81
|
||||
EmoteState = 0x208, // Size: 0x1, Flags: 0x1
|
||||
Stats = 0x20C, // Size: 0x4, Flags: 0x6
|
||||
StatPosBuff = 0x21C, // Size: 0x4, Flags: 0x6
|
||||
StatNegBuff = 0x22C, // Size: 0x4, Flags: 0x6
|
||||
Resistances = 0x23C, // Size: 0x7, Flags: 0x16
|
||||
ResistanceBuffModsPositive = 0x258, // Size: 0x7, Flags: 0x6
|
||||
ResistanceBuffModsNegative = 0x274, // Size: 0x7, Flags: 0x6
|
||||
ModBonusArmor = 0x290, // Size: 0x1, Flags: 0x6
|
||||
BaseMana = 0x294, // Size: 0x1, Flags: 0x1
|
||||
BaseHealth = 0x298, // Size: 0x1, Flags: 0x6
|
||||
ShapeshiftForm = 0x29C, // Size: 0x1, Flags: 0x1
|
||||
AttackPower = 0x2A0, // Size: 0x1, Flags: 0x6
|
||||
AttackPowerModPos = 0x2A4, // Size: 0x1, Flags: 0x6
|
||||
AttackPowerModNeg = 0x2A8, // Size: 0x1, Flags: 0x6
|
||||
AttackPowerMultiplier = 0x2AC, // Size: 0x1, Flags: 0x6
|
||||
RangedAttackPower = 0x2B0, // Size: 0x1, Flags: 0x6
|
||||
RangedAttackPowerModPos = 0x2B4, // Size: 0x1, Flags: 0x6
|
||||
RangedAttackPowerModNeg = 0x2B8, // Size: 0x1, Flags: 0x6
|
||||
RangedAttackPowerMultiplier = 0x2BC, // Size: 0x1, Flags: 0x6
|
||||
SetAttackSpeedAura = 0x2C0, // Size: 0x1, Flags: 0x6
|
||||
MinRangedDamage = 0x2C4, // Size: 0x1, Flags: 0x6
|
||||
MaxRangedDamage = 0x2C8, // Size: 0x1, Flags: 0x6
|
||||
PowerCostModifier = 0x2CC, // Size: 0x7, Flags: 0x6
|
||||
PowerCostMultiplier = 0x2E8, // Size: 0x7, Flags: 0x6
|
||||
MaxHealthModifier = 0x304, // Size: 0x1, Flags: 0x6
|
||||
HoverHeight = 0x308, // Size: 0x1, Flags: 0x1
|
||||
MinItemLevelCutoff = 0x30C, // Size: 0x1, Flags: 0x1
|
||||
MinItemLevel = 0x310, // Size: 0x1, Flags: 0x1
|
||||
MaxItemLevel = 0x314, // Size: 0x1, Flags: 0x1
|
||||
WildBattlePetLevel = 0x318, // Size: 0x1, Flags: 0x1
|
||||
BattlePetCompanionNameTimestamp = 0x31C, // Size: 0x1, Flags: 0x1
|
||||
InteractSpellId = 0x320, // Size: 0x1, Flags: 0x1
|
||||
StateSpellVisualId = 0x324, // Size: 0x1, Flags: 0x280
|
||||
StateAnimId = 0x328, // Size: 0x1, Flags: 0x280
|
||||
StateAnimKitId = 0x32C, // Size: 0x1, Flags: 0x280
|
||||
StateWorldEffectId = 0x330, // Size: 0x4, Flags: 0x280
|
||||
ScaleDuration = 0x340, // Size: 0x1, Flags: 0x1
|
||||
LooksLikeMountId = 0x344, // Size: 0x1, Flags: 0x1
|
||||
LooksLikeCreatureId = 0x348, // Size: 0x1, Flags: 0x1
|
||||
LookAtControllerId = 0x34C, // Size: 0x1, Flags: 0x1
|
||||
LookAtControllerTarget = 0x350 // Size: 0x4, Flags: 0x1
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Process.NET;
|
||||
|
||||
namespace Artemis.Modules.Games.WoW.Data
|
||||
{
|
||||
public class WoWPlayer : WoWUnit
|
||||
{
|
||||
private readonly IntPtr _targetIntPtr;
|
||||
|
||||
public WoWPlayer(IProcess process, IntPtr baseAddress, IntPtr targetIntPtr, bool readPointer = false)
|
||||
: base(process, baseAddress, readPointer)
|
||||
{
|
||||
_targetIntPtr = targetIntPtr;
|
||||
}
|
||||
|
||||
public WoWObject GetTarget(WoWObjectManager manager)
|
||||
{
|
||||
var targetGuid = Process.Memory.Read<Guid>(Process.Native.MainModule.BaseAddress + _targetIntPtr.ToInt32());
|
||||
return manager.EnumVisibleObjects().FirstOrDefault(o => o.Guid == targetGuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,181 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Artemis.Modules.Games.WoW.Data.WowSharp.Client.Patchables;
|
||||
|
||||
namespace Artemis.Modules.Games.WoW.Data
|
||||
{
|
||||
public static class WoWStructs
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct ObjectData
|
||||
{
|
||||
// x32 : x64
|
||||
[FieldOffset(0)] private readonly IntPtr vtable; // 0x00 0x00
|
||||
[FieldOffset(10)] public IntPtr Descriptors; // 0x04 0x10
|
||||
[FieldOffset(18)] private readonly IntPtr unk1; // 0x08 0x18
|
||||
[FieldOffset(20)] public int ObjectType; // 0x0C 0x20
|
||||
[FieldOffset(24)] private readonly IntPtr unk3; // 0x10 0x24
|
||||
[FieldOffset(28)] private readonly IntPtr unk4; // 0x14 0x28
|
||||
[FieldOffset(30)] private readonly IntPtr unk5; // 0x18 0x30
|
||||
[FieldOffset(38)] private readonly IntPtr unk6; // 0x1C 0x38
|
||||
[FieldOffset(40)] private readonly IntPtr unk7; // 0x20 0x40
|
||||
[FieldOffset(48)] private readonly IntPtr unk8; // 0x24 0x48
|
||||
[FieldOffset(50)] public Guid Guid; // 0x28 0x50
|
||||
}
|
||||
|
||||
public struct Guid
|
||||
{
|
||||
private readonly Int128 _mGuid;
|
||||
|
||||
public static readonly Guid Zero = new Guid(0);
|
||||
|
||||
public Guid(Int128 guid)
|
||||
{
|
||||
_mGuid = guid;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch (Type)
|
||||
{
|
||||
case WoWEnums.GuidType.Creature:
|
||||
case WoWEnums.GuidType.Vehicle:
|
||||
case WoWEnums.GuidType.Pet:
|
||||
case WoWEnums.GuidType.GameObject:
|
||||
case WoWEnums.GuidType.AreaTrigger:
|
||||
case WoWEnums.GuidType.DynamicObject:
|
||||
case WoWEnums.GuidType.Corpse:
|
||||
case WoWEnums.GuidType.LootObject:
|
||||
case WoWEnums.GuidType.SceneObject:
|
||||
case WoWEnums.GuidType.Scenario:
|
||||
case WoWEnums.GuidType.AiGroup:
|
||||
case WoWEnums.GuidType.DynamicDoor:
|
||||
case WoWEnums.GuidType.Vignette:
|
||||
case WoWEnums.GuidType.Conversation:
|
||||
case WoWEnums.GuidType.CallForHelp:
|
||||
case WoWEnums.GuidType.AiResource:
|
||||
case WoWEnums.GuidType.AiLock:
|
||||
case WoWEnums.GuidType.AiLockTicket:
|
||||
return $"{Type}-{SubType}-{RealmId}-{MapId}-{ServerId}-{Id}-{CreationBits:X10}";
|
||||
case WoWEnums.GuidType.Player:
|
||||
return $"{Type}-{RealmId}-{(ulong) (_mGuid >> 64):X8}";
|
||||
case WoWEnums.GuidType.Item:
|
||||
return $"{Type}-{RealmId}-{(uint) ((_mGuid >> 18) & 0xFFFFFF)}-{(ulong) (_mGuid >> 64):X10}";
|
||||
//case GuidType.ClientActor:
|
||||
// return String.Format("{0}-{1}-{2}", Type, RealmId, CreationBits);
|
||||
//case GuidType.Transport:
|
||||
//case GuidType.StaticDoor:
|
||||
// return String.Format("{0}-{1}-{2}", Type, RealmId, CreationBits);
|
||||
default:
|
||||
return $"{Type}-{_mGuid:X32}";
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is Guid)
|
||||
return _mGuid == ((Guid) obj)._mGuid;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _mGuid.GetHashCode();
|
||||
}
|
||||
|
||||
public WoWEnums.GuidType Type => (WoWEnums.GuidType) (byte) ((_mGuid >> 58) & 0x3F);
|
||||
|
||||
public byte SubType => (byte) ((_mGuid >> 120) & 0x3F);
|
||||
|
||||
public ushort RealmId => (ushort) ((_mGuid >> 42) & 0x1FFF);
|
||||
|
||||
public ushort ServerId => (ushort) ((_mGuid >> 104) & 0x1FFF);
|
||||
|
||||
public ushort MapId => (ushort) ((_mGuid >> 29) & 0x1FFF);
|
||||
|
||||
// Creature, Pet, Vehicle
|
||||
public uint Id => (uint) ((_mGuid >> 6) & 0x7FFFFF);
|
||||
|
||||
public ulong CreationBits => (ulong) ((_mGuid >> 64) & 0xFFFFFFFFFF);
|
||||
}
|
||||
|
||||
#region Manager
|
||||
|
||||
// Region is here due to the large amount of structs-
|
||||
// the CurremtManager struct depends on.
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct CurrentManager
|
||||
{
|
||||
public TsHashTable VisibleObjects; // m_objects
|
||||
public TsHashTable LazyCleanupObjects; // m_lazyCleanupObjects
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)]
|
||||
// m_lazyCleanupFifo, m_freeObjects, m_visibleObjects, m_reenabledObjects, whateverObjects...
|
||||
public TsExplicitList[] Links; // Links[13] has all objects stored in VisibleObjects it seems
|
||||
|
||||
#if !X64
|
||||
public int Unknown1; // wtf is that and why x86 only?
|
||||
#endif
|
||||
public Int128 ActivePlayer;
|
||||
public int MapId;
|
||||
public IntPtr ClientConnection;
|
||||
public IntPtr MovementGlobals;
|
||||
public int Unk1;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Ts
|
||||
{
|
||||
public IntPtr vtable;
|
||||
public uint m_alloc;
|
||||
public uint m_count;
|
||||
public IntPtr m_data; //TSExplicitList* m_data;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TsExplicitList
|
||||
{
|
||||
public TsList baseClass;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TsFixedArray
|
||||
{
|
||||
public Ts baseClass;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TsGrowableArray
|
||||
{
|
||||
public TsFixedArray baseclass;
|
||||
public uint m_chunk;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TsHashTable
|
||||
{
|
||||
public IntPtr vtable;
|
||||
public TsExplicitList m_fulllist;
|
||||
public int m_fullnessIndicator;
|
||||
public TsGrowableArray m_slotlistarray;
|
||||
public int m_slotmask;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TsLink
|
||||
{
|
||||
public IntPtr m_prevlink; //TSLink *m_prevlink
|
||||
public IntPtr m_next; // C_OBJECTHASH *m_next
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TsList
|
||||
{
|
||||
public int m_linkoffset;
|
||||
public TsLink m_terminator;
|
||||
}
|
||||
|
||||
#endregion;
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using Process.NET;
|
||||
using static Artemis.Modules.Games.WoW.Data.WoWEnums;
|
||||
using static Artemis.Modules.Games.WoW.Data.WoWOffsets;
|
||||
|
||||
namespace Artemis.Modules.Games.WoW.Data
|
||||
{
|
||||
public class WoWUnit : WoWObject
|
||||
{
|
||||
public WoWUnit(IProcess process, IntPtr baseAddress, bool readPointer = false)
|
||||
: base(process, baseAddress, readPointer)
|
||||
{
|
||||
}
|
||||
|
||||
public int Health => ReadField<int>(UnitData.Health);
|
||||
public int MaxHealth => ReadField<int>(UnitData.MaxHealth);
|
||||
public int Power => ReadField<int>(UnitData.Power);
|
||||
public int SecondaryPower => ReadField<int>(UnitData.SecondaryPower);
|
||||
public int TertiaryPower => ReadField<int>(UnitData.TertiaryPower);
|
||||
public int MaxPower => ReadField<int>(UnitData.MaxPower);
|
||||
public PowerType PowerType => (PowerType) ReadField<int>(UnitData.DisplayPower);
|
||||
public int Level => ReadField<int>(UnitData.Level);
|
||||
|
||||
public WoWDetails Details { get; set; }
|
||||
|
||||
public void UpdateDetails(WoWNameCache nameCache)
|
||||
{
|
||||
Details = GetNpcDetails() ?? nameCache.GetNameByGuid(Guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,256 +0,0 @@
|
||||
namespace Artemis.Modules.Games.WoW
|
||||
{
|
||||
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 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
|
||||
}
|
||||
|
||||
public class ObjectManagerClass
|
||||
{
|
||||
public static uint clientConnection;
|
||||
public static uint sCurMgr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,159 @@
|
||||
using Artemis.Modules.Abstract;
|
||||
using Artemis.Modules.Games.WoW.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Modules.Abstract;
|
||||
using Castle.Components.DictionaryAdapter;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Artemis.Modules.Games.WoW
|
||||
{
|
||||
public class WoWDataModel : ModuleDataModel
|
||||
{
|
||||
public WoWDataModel()
|
||||
{
|
||||
Player = new WoWUnit();
|
||||
Target = new WoWUnit();
|
||||
}
|
||||
|
||||
public WoWUnit Player { get; set; }
|
||||
public WoWUnit Target { get; set; }
|
||||
public string Realm { get; set; }
|
||||
public string Zone { get; set; }
|
||||
public string SubZone { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
public class WoWUnit
|
||||
{
|
||||
public WoWUnit()
|
||||
{
|
||||
Buffs = new List<WoWAura>();
|
||||
Debuffs = new EditableList<WoWAura>();
|
||||
}
|
||||
|
||||
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 WoWClass 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 void ApplyJson(JObject json)
|
||||
{
|
||||
if (json["name"] == null)
|
||||
return;
|
||||
|
||||
Name = json["name"].Value<string>();
|
||||
Level = json["level"].Value<int>();
|
||||
Class = (WoWClass) Enum.Parse(typeof(WoWClass), json["class"].Value<string>().Replace(" ", ""));
|
||||
Race = (WoWRace) Enum.Parse(typeof(WoWRace), json["race"].Value<string>().Replace(" ", ""));
|
||||
Gender = json["gender"].Value<int>() == 3 ? WoWGender.Female : WoWGender.Male;
|
||||
}
|
||||
|
||||
public void ApplyStateJson(JObject json)
|
||||
{
|
||||
Health = json["health"].Value<int>();
|
||||
MaxHealth = json["maxHealth"].Value<int>();
|
||||
PowerType = (WoWPowerType) Enum.Parse(typeof(WoWPowerType), json["powerType"].Value<int>().ToString(), true);
|
||||
Power = json["power"].Value<int>();
|
||||
MaxPower = json["maxPower"].Value<int>();
|
||||
|
||||
Buffs.Clear();
|
||||
foreach (var auraJson in json["buffs"].Children())
|
||||
{
|
||||
var aura = new WoWAura();
|
||||
aura.ApplyJson(auraJson);
|
||||
Buffs.Add(aura);
|
||||
}
|
||||
Debuffs.Clear();
|
||||
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 TimeSpan Duration { get; set; }
|
||||
public TimeSpan Expires { 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 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,21 +1,22 @@
|
||||
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.Data;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities.Memory;
|
||||
using Process.NET;
|
||||
using Process.NET.Memory;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PcapDotNet.Core;
|
||||
using PcapDotNet.Packets;
|
||||
|
||||
namespace Artemis.Modules.Games.WoW
|
||||
{
|
||||
public class WoWModel : ModuleModel
|
||||
{
|
||||
private readonly GamePointersCollection _pointer;
|
||||
private ProcessSharp _process;
|
||||
|
||||
private readonly Regex _rgx;
|
||||
private PacketCommunicator _communicator;
|
||||
|
||||
public WoWModel(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager)
|
||||
{
|
||||
@ -23,94 +24,119 @@ namespace Artemis.Modules.Games.WoW
|
||||
DataModel = new WoWDataModel();
|
||||
ProcessNames.Add("Wow-64");
|
||||
|
||||
// Currently WoW is locked behind a hidden trigger (obviously not that hidden since you're reading this)
|
||||
// It is using memory reading and lets first try to contact Blizzard
|
||||
var settings = SettingsProvider.Load<GeneralSettings>();
|
||||
Settings.IsEnabled = settings.GamestatePort == 62575 && Settings.IsEnabled;
|
||||
|
||||
_pointer = SettingsProvider.Load<OffsetSettings>().WorldOfWarcraft;
|
||||
//_pointer = new GamePointersCollection
|
||||
//{
|
||||
// Game = "WorldOfWarcraft",
|
||||
// GameVersion = "7.0.3.22810",
|
||||
// GameAddresses = new List<GamePointer>
|
||||
// {
|
||||
// new GamePointer
|
||||
// {
|
||||
// Description = "ObjectManager",
|
||||
// BasePointer = new IntPtr(0x1578070)
|
||||
// },
|
||||
// new GamePointer
|
||||
// {
|
||||
// Description = "LocalPlayer",
|
||||
// BasePointer = new IntPtr(0x169DF10)
|
||||
// },
|
||||
// new GamePointer
|
||||
// {
|
||||
// Description = "NameCache",
|
||||
// BasePointer = new IntPtr(0x151DCE8)
|
||||
// },
|
||||
// new GamePointer
|
||||
// {
|
||||
// Description = "TargetGuid",
|
||||
// BasePointer = new IntPtr(0x179C940)
|
||||
// }
|
||||
// }
|
||||
//};
|
||||
//var res = JsonConvert.SerializeObject(_pointer, Formatting.Indented);
|
||||
_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)
|
||||
{
|
||||
var json = JObject.Parse(data);
|
||||
var dataModel = (WoWDataModel) DataModel;
|
||||
switch (command)
|
||||
{
|
||||
case "player":
|
||||
ParsePlayer(json, dataModel);
|
||||
break;
|
||||
case "target":
|
||||
ParseTarget(json, dataModel);
|
||||
break;
|
||||
case "playerState":
|
||||
ParsePlayerState(json, 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);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_communicator.Break();
|
||||
_communicator.Dispose();
|
||||
base.Dispose();
|
||||
|
||||
_process?.Dispose();
|
||||
_process = null;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (_process == null)
|
||||
{
|
||||
var tempProcess = MemoryHelpers.GetProcessIfRunning(ProcessNames[0]);
|
||||
if (tempProcess == null)
|
||||
return;
|
||||
|
||||
_process = new ProcessSharp(tempProcess, MemoryType.Remote);
|
||||
}
|
||||
|
||||
if (ProfileModel == null || DataModel == null || _process == null)
|
||||
return;
|
||||
|
||||
var dataModel = (WoWDataModel) DataModel;
|
||||
|
||||
var objectManager = new WoWObjectManager(_process,
|
||||
_pointer.GameAddresses.First(a => a.Description == "ObjectManager").BasePointer);
|
||||
var nameCache = new WoWNameCache(_process,
|
||||
_pointer.GameAddresses.First(a => a.Description == "NameCache").BasePointer);
|
||||
var player = new WoWPlayer(_process,
|
||||
_pointer.GameAddresses.First(a => a.Description == "LocalPlayer").BasePointer,
|
||||
_pointer.GameAddresses.First(a => a.Description == "TargetGuid").BasePointer, true);
|
||||
|
||||
dataModel.Player = player;
|
||||
if (dataModel.Player != null && dataModel.Player.Guid != Guid.Empty)
|
||||
{
|
||||
dataModel.Player.UpdateDetails(nameCache);
|
||||
var target = player.GetTarget(objectManager);
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
dataModel.Target = new WoWUnit(target.Process, target.BaseAddress);
|
||||
dataModel.Target.UpdateDetails(nameCache);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataModel.Target = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.DAL;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Modules.Abstract;
|
||||
using Artemis.Settings;
|
||||
using Artemis.ViewModels.Abstract;
|
||||
|
||||
namespace Artemis.ViewModels
|
||||
@ -16,18 +13,7 @@ namespace Artemis.ViewModels
|
||||
{
|
||||
DisplayName = "Games";
|
||||
|
||||
// Currently WoW is locked behind a hidden trigger (obviously not that hidden since you're reading this)
|
||||
// It is using memory reading and lets first try to contact Blizzard
|
||||
if (SettingsProvider.Load<GeneralSettings>().GamestatePort == 62575)
|
||||
{
|
||||
_vms = moduleViewModels.Where(m => m.ModuleModel.IsBoundToProcess)
|
||||
.OrderBy(g => g.DisplayName).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
_vms = moduleViewModels.Where(m => m.ModuleModel.IsBoundToProcess && m.DisplayName != "WoW")
|
||||
.OrderBy(g => g.DisplayName).ToList();
|
||||
}
|
||||
_vms = moduleViewModels.Where(m => m.ModuleModel.IsBoundToProcess).OrderBy(g => g.DisplayName).ToList();
|
||||
}
|
||||
|
||||
protected override void OnActivate()
|
||||
@ -37,4 +23,4 @@ namespace Artemis.ViewModels
|
||||
Items.AddRange(_vms);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@ -24,6 +24,7 @@
|
||||
<package id="Ninject.Extensions.Logging.nlog4" version="3.2.3.0" targetFramework="net452" />
|
||||
<package id="NLog" version="4.4.4" targetFramework="net461" />
|
||||
<package id="NLog.Schema" version="4.4.4" targetFramework="net461" />
|
||||
<package id="Pcap.Net.x64" version="1.0.4.1" targetFramework="net461" />
|
||||
<package id="Process.NET" version="1.0.8" targetFramework="net461" />
|
||||
<package id="SharpDX" version="3.1.1" targetFramework="net461" />
|
||||
<package id="SharpDX.Direct3D9" version="3.1.1" targetFramework="net461" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user