Skip to content

Commit

Permalink
Add InCombat event and memory signatures
Browse files Browse the repository at this point in the history
It's not clear that "EnmityMemory" is the best place for this, but it
seemed better to put it with code that was roughly similar and already
doing the same sort of memory polling, rather than create separate
memory classes for this one off signature.
  • Loading branch information
quisquous committed Jun 7, 2020
1 parent 7aedcc1 commit ee1f4ba
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
25 changes: 25 additions & 0 deletions OverlayPlugin.Core/EventSources/EnmityEventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ public class EnmityEventSource : EventSourceBase
private const string EnmityTargetDataEvent = "EnmityTargetData";
// All of the mobs with aggro on the player. Equivalent of the sidebar aggro list in game.
private const string EnmityAggroListEvent = "EnmityAggroList";
// State of combat, both act and game.
private const string InCombatEvent = "InCombat";

[Serializable]
internal class InCombatDataObject {
public string type = InCombatEvent;
public bool inACTCombat = false;
public bool inGameCombat = false;
};
InCombatDataObject sentCombatData;

public BuiltinEventConfig Config { get; set; }

Expand Down Expand Up @@ -51,6 +61,7 @@ public EnmityEventSource(ILogger logger) : base(logger)
RegisterEventTypes(new List<string> {
EnmityTargetDataEvent, EnmityAggroListEvent,
});
RegisterCachedEventType(InCombatEvent);
}

public override Control CreateConfigControl()
Expand Down Expand Up @@ -117,6 +128,20 @@ protected override void Update()
memoryValid = true;
}

if (HasSubscriber(InCombatEvent))
{
bool inACTCombat = Advanced_Combat_Tracker.ActGlobals.oFormActMain.InCombat;
bool inGameCombat = memory.GetInCombat();
if (sentCombatData == null || sentCombatData.inACTCombat != inACTCombat || sentCombatData.inGameCombat != inGameCombat)
{
if (sentCombatData == null)
sentCombatData = new InCombatDataObject();
sentCombatData.inACTCombat = inACTCombat;
sentCombatData.inGameCombat = inGameCombat;
this.DispatchAndCacheEvent(JObject.FromObject(sentCombatData));
}
}

bool targetData = HasSubscriber(EnmityTargetDataEvent);
bool aggroList = HasSubscriber(EnmityAggroListEvent);
if (!targetData && !aggroList)
Expand Down
35 changes: 35 additions & 0 deletions OverlayPlugin.Core/EventSources/EnmityMemory50.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,19 @@ public class EnmityMemory50 : EnmityMemory
private IntPtr targetAddress = IntPtr.Zero;
private IntPtr enmityAddress = IntPtr.Zero;
private IntPtr aggroAddress = IntPtr.Zero;
private IntPtr inCombatAddress = IntPtr.Zero;

private const string charmapSignature = "488b420848c1e8033da701000077248bc0488d0d";
private const string targetSignature = "41bc000000e041bd01000000493bc47555488d0d";
private const string enmitySignature = "83f9ff7412448b048e8bd3488d0d";
private const string inCombatSignature = "84c07425450fb6c7488d0d";

// Offsets from the signature to find the correct address.
private const int charmapSignatureOffset = 0;
private const int targetSignatureOffset = 192;
private const int enmitySignatureOffset = -4648;
private const int inCombatSignatureBaseOffset = 0;
private const int inCombatSignatureOffsetOffset = 5;

// Offset from the enmityAddress to find various enmity data structures.
private const int aggroEnmityOffset = 0x908;
Expand Down Expand Up @@ -52,6 +56,7 @@ private void ResetPointers(object sender, EventArgs _)
targetAddress = IntPtr.Zero;
enmityAddress = IntPtr.Zero;
aggroAddress = IntPtr.Zero;
inCombatAddress = IntPtr.Zero;
}

private bool HasValidPointers()
Expand All @@ -64,6 +69,8 @@ private bool HasValidPointers()
return false;
if (aggroAddress == IntPtr.Zero)
return false;
if (inCombatAddress == IntPtr.Zero)
return false;
return true;
}

Expand Down Expand Up @@ -137,9 +144,29 @@ private bool GetPointerAddress()
success = false;
}

/// IN COMBAT
// The in combat address is set from a combination of two values, a base address and an offset.
// They are found adjacent to the same signature, but at different offsets.
var baseList = memory.SigScan(inCombatSignature, inCombatSignatureBaseOffset, bRIP);
// SigScan returns pointers, but the offset is a 32-bit immediate value. Do not use RIP.
var offsetList = memory.SigScan(inCombatSignature, inCombatSignatureOffsetOffset, false);
if (baseList != null && baseList.Count > 0 && offsetList != null && offsetList.Count > 0)
{
var baseAddress = baseList[0];
var offset = (int)(((UInt64)offsetList[0]) & 0xFFFFFFFF);
inCombatAddress = IntPtr.Add(baseAddress, offset);
}
else
{
inCombatAddress = IntPtr.Zero;
fail.Add(nameof(inCombatAddress));
success = false;
}

logger.Log(LogLevel.Debug, "charmapAddress: 0x{0:X}", charmapAddress.ToInt64());
logger.Log(LogLevel.Debug, "enmityAddress: 0x{0:X}", enmityAddress.ToInt64());
logger.Log(LogLevel.Debug, "targetAddress: 0x{0:X}", targetAddress.ToInt64());
logger.Log(LogLevel.Debug, "inCombatAddress: 0x{0:X}", inCombatAddress.ToInt64());
Combatant c = GetSelfCombatant();
if (c != null)
{
Expand Down Expand Up @@ -537,5 +564,13 @@ public unsafe EffectEntry GetEffectEntryFromBytes(byte[] source, int num = 0)
return effectEntry;
}
}

public override bool GetInCombat()
{
if (inCombatAddress == IntPtr.Zero)
return false;
byte[] bytes = memory.Read8(inCombatAddress, 1);
return bytes[0] != 0;
}
}
}
35 changes: 35 additions & 0 deletions OverlayPlugin.Core/EventSources/EnmityMemory52.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@ public class EnmityMemory52 : EnmityMemory
private IntPtr targetAddress = IntPtr.Zero;
private IntPtr enmityAddress = IntPtr.Zero;
private IntPtr aggroAddress = IntPtr.Zero;
private IntPtr inCombatAddress = IntPtr.Zero;

private const string charmapSignature = "48c1ea0381faa7010000????8bc2488d0d";
private const string targetSignatureH0 = "83E901740832C04883C4205BC3488D0D"; // pre hotfix
private const string targetSignatureH1 = "e8f2652f0084c00f8591010000488d0d"; // post hotfix 1
private const string enmitySignature = "83f9ff7412448b048e8bd3488d0d";
private const string inCombatSignature = "84c07425450fb6c7488d0d";

// Offsets from the signature to find the correct address.
private const int charmapSignatureOffset = 0;
private const int targetSignatureOffset = 0;
private const int enmitySignatureOffset = -2608;
private const int aggroEnmityOffset = -2336;
private const int inCombatSignatureBaseOffset = 0;
private const int inCombatSignatureOffsetOffset = 5;

// Offsets from the targetAddress to find the correct target type.
private const int targetTargetOffset = 176;
Expand All @@ -51,6 +55,7 @@ private void ResetPointers(object sender, EventArgs _)
targetAddress = IntPtr.Zero;
enmityAddress = IntPtr.Zero;
aggroAddress = IntPtr.Zero;
inCombatAddress = IntPtr.Zero;
}

private bool HasValidPointers()
Expand All @@ -63,6 +68,8 @@ private bool HasValidPointers()
return false;
if (aggroAddress == IntPtr.Zero)
return false;
if (inCombatAddress == IntPtr.Zero)
return false;
return true;
}

Expand Down Expand Up @@ -140,10 +147,30 @@ private bool GetPointerAddress()
success = false;
}

/// IN COMBAT
// The in combat address is set from a combination of two values, a base address and an offset.
// They are found adjacent to the same signature, but at different offsets.
var baseList = memory.SigScan(inCombatSignature, inCombatSignatureBaseOffset, bRIP);
// SigScan returns pointers, but the offset is a 32-bit immediate value. Do not use RIP.
var offsetList = memory.SigScan(inCombatSignature, inCombatSignatureOffsetOffset, false);
if (baseList != null && baseList.Count > 0 && offsetList != null && offsetList.Count > 0)
{
var baseAddress = baseList[0];
var offset = (int)(((UInt64)offsetList[0]) & 0xFFFFFFFF);
inCombatAddress = IntPtr.Add(baseAddress, offset);
}
else
{
inCombatAddress = IntPtr.Zero;
fail.Add(nameof(inCombatAddress));
success = false;
}

logger.Log(LogLevel.Debug, "charmapAddress: 0x{0:X}", charmapAddress.ToInt64());
logger.Log(LogLevel.Debug, "enmityAddress: 0x{0:X}", enmityAddress.ToInt64());
logger.Log(LogLevel.Debug, "aggroAddress: 0x{0:X}", aggroAddress.ToInt64());
logger.Log(LogLevel.Debug, "targetAddress: 0x{0:X}", targetAddress.ToInt64());
logger.Log(LogLevel.Debug, "inCombatAddress: 0x{0:X}", inCombatAddress.ToInt64());
Combatant c = GetSelfCombatant();
if (c != null)
{
Expand Down Expand Up @@ -591,5 +618,13 @@ public unsafe EffectEntry GetEffectEntryFromBytes(byte[] source, int num = 0)
return effectEntry;
}
}

public override bool GetInCombat()
{
if (inCombatAddress == IntPtr.Zero)
return false;
byte[] bytes = memory.Read8(inCombatAddress, 1);
return bytes[0] != 0;
}
}
}
1 change: 1 addition & 0 deletions OverlayPlugin.Core/EventSources/EnmityMemoryCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,6 @@ public abstract class EnmityMemory
abstract public List<Combatant> GetCombatantList();
abstract public List<EnmityEntry> GetEnmityEntryList(List<Combatant> combatantList);
abstract public unsafe List<AggroEntry> GetAggroList(List<Combatant> combatantList);
abstract public bool GetInCombat();
}
}

0 comments on commit ee1f4ba

Please sign in to comment.