Skip to content
This repository was archived by the owner on Nov 25, 2021. It is now read-only.

Support hero compositions extraction (aka battle presets) #59

Merged
merged 1 commit into from
Apr 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Python Utilities/address_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
}],
'public class UserHeroData ': [{
'public Dictionary<int, Hero> HeroById;': ' public static int UserHeroDataHeroById = {}; // UserHeroData.HeroById\n',
'public Dictionary<int, int[]> BattlePresets;': ' public static int UserHeroDataBattlePresets = {}; // UserHeroData.BattlePresets\n',
}],
'public class UserVillageData ': [{
'public Dictionary<Element, Dictionary<StatKindId, int>> CapitolBonusLevelByStatByElement;': ' public static int UserVillageDataCapitolBonusLevelByStatByElement = {}; // UserVillageData.UserVillageDataCapitolBonusLevelByStatByElement\n',
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ This application has 2 Modes:
* .NET Framework 4.8

## Future versions
* Extract last known hero compositions
* Account stats

## Projects Using Extracted Data!
Expand Down
3 changes: 3 additions & 0 deletions RaidExtractor.Core/AccountDumpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ public partial class AccountDump

[Newtonsoft.Json.JsonProperty("shards", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public Dictionary<string, ShardInfo> Shards { get; set; }

[Newtonsoft.Json.JsonProperty("stagePresets", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public Dictionary<int, int[]> StagePresets { get; set; }
}


Expand Down
42 changes: 41 additions & 1 deletion RaidExtractor.Core/Extractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,45 @@ public AccountDump GetDump()
shards[key].SummonData.Add(info);
}

#endregion

#region BattlePresets extraction

var presetsPointer = heroesWrapper;
NativeWrapper.ReadProcessMemory(handle, presetsPointer + RaidStaticInformation.HeroesWrapperHeroData, ref presetsPointer); // HeroesWrapperReadOnly.HeroData
NativeWrapper.ReadProcessMemory(handle, presetsPointer + RaidStaticInformation.UserHeroDataBattlePresets, ref presetsPointer); // UserHeroData.BattlePresets

var battlePresetsCount = 0;
var presetsDataPointer = IntPtr.Zero;

NativeWrapper.ReadProcessMemory(handle, presetsPointer + RaidStaticInformation.DictionaryCount, ref battlePresetsCount); // Dictionary<int, int[]>.Count
NativeWrapper.ReadProcessMemory(handle, presetsPointer + RaidStaticInformation.DictionaryEntries, ref presetsDataPointer); // Dictionary<int, int[]>.Entries

var stagePresets = new Dictionary<int, int[]>();

for (var i = 0; i < battlePresetsCount; i++)
{
var stageIdPointer = presetsDataPointer + 0x28 + 0x18 * i; // Dictionary<int, int[]>.Key;
var heroIdArrayPointer = presetsDataPointer + 0x30 + 0x18 * i; // Dictionary<int, int[]>.Value
int currentStage = 0;

NativeWrapper.ReadProcessMemory(handle, stageIdPointer, ref currentStage);
NativeWrapper.ReadProcessMemory(handle, heroIdArrayPointer, ref heroIdArrayPointer);

var heroArrayCount = 0;
NativeWrapper.ReadProcessMemory(handle, heroIdArrayPointer + RaidStaticInformation.ListCount, ref heroArrayCount); // Assuming Array.Count has identical offset as List.Count

// Making use of ReadProcessMemoryArray instead of iterating the array ourselves
if (heroArrayCount > 0)
{
var heroIdArray = new int[heroArrayCount];
var heroIdPointer = heroIdArrayPointer + 0x20; // Location of the first entry

NativeWrapper.ReadProcessMemoryArray(handle, heroIdPointer, heroIdArray);
stagePresets[currentStage] = heroIdArray;
}
}

#endregion

return new AccountDump
Expand All @@ -463,7 +502,8 @@ public AccountDump GetDump()
Heroes = heroes,
ArenaLeague = arenaLeague.ToString(),
GreatHall = greatHall,
Shards = shards
Shards = shards,
StagePresets = stagePresets,
};
}
finally
Expand Down
1 change: 1 addition & 0 deletions RaidExtractor.Core/Native/RaidStaticInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class RaidStaticInformation
public static int ShardSummonData = 0x18; // ShardWrapperReadOnly.UserShardData.SummonResults

public static int UserHeroDataHeroById = 0x18; // UserHeroData.HeroById
public static int UserHeroDataBattlePresets = 0x28; // UserHeroData.BattlePresets

public static int UserArtifactDataArtifacts = 0x28; // UserArtifactData.Artifactsa
public static int UserArtifactArtifactDataByHeroId = 0x30; // UserArtifactData.ArtifactDataByHeroId
Expand Down