1
0
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:
SpoinkyNL 2017-09-04 21:46:40 +02:00
parent f05cf0b6d9
commit 04e5943996
17 changed files with 278 additions and 3617 deletions

View File

@ -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" />

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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; }
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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
}
}

View File

@ -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;
}
}
}
}
}

View File

@ -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.

View File

@ -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" />