Closed ericp1337 closed 10 years ago
The examples are pretty straight forward and the code is fairly well documented. To get a summary, you want to handle the FileInfo Packet or look at the last entity state (specifically CGameRulesProxy and CPlayerRessource).
I modified the chat example to only print out the FileInfo packet: https://gist.github.com/invokr/9adc0b98254c58570eca
The only real important change, apart from changing the types according to the different packet, is that forward_dem needs to be set to true because FileInfo is a DEM Packet.
I am able to now parse out the FileInfo packet from the end of the file, but I cannot seem to figure out how to parse out the combat log so I can generate the end of game stats screen such as KDA level and etc. I have looked at all examples, google, and been messing around with code but cannot seem to figure it out. any help is much appreciated.
I also tried to use the AliceSimple, but that throws a lot of errors when trying to compile.
I didn't know there were any problems compiling AliceSimple, but I haven't shown that project any love recently so yeah, it might be broken. It does not really fix what it is trying so solve though, a lightweight DSL would be better suited, but that is another topic.
Parsing the combat log and getting KDA / levels is something else entirely. To get the combatlog, do the following:
svc_GameEventList
, this one contains a list of all game events send by the serverdota_combatlog
, save its event idsvc_GameEvent
dota_combatlog
id, if so, you got a combatlog entryEach entry can be represented as the following structure:
struct combatlog_entry {
/** Type of the combat log entry, e.g. damage etc*/
uint8_t type;
/** ID of the owner of the entity performing the action */
int32_t sourcename;
/** ID of the target*/
int32_t targetname;
/** ID of the attacker */
int32_t attackername;
/** ID of the buf / debug inflicted*/
int32_t inflictorname;
/** is attacker an illusion */
bool attackerillusion;
/** is target an illusion */
bool targetillusion;
/** hp lost / gained*/
int32_t value;
/** hp after the action was made*/
int32_t health;
/** time this occured */
float timestamp;
/** owner id of the target entity*/
uint32_t targetsourcename;
};
Hence you can get it's values something like this (from the game event packet):
combatlog_entry e{
event->keys(0).val_byte(),
event->keys(1).val_short(), event->keys(2).val_short(),
event->keys(3).val_short(), event->keys(4).val_short(),
event->keys(5).val_bool(), event->keys(6).val_bool(),
event->keys(7).val_short(), event->keys(8).val_short(),
event->keys(9).val_float(), event->keys(10).val_short()
};
Next up would be getting KDA / LH etc.You need to grep these out of the entities along the lines of:
CDOTAGameRulesProxy
and CDOTA_PlayerRessource
.m_iKills.0000
from the player ressource, providing you with the number of kills the first player has.Your code could look like this:
// earlier
parser* p;
// in the function that receives the `FileInfo` Packet
uint32_t prId = p->getEntityIdFor("CDOTA_PlayerRessource");
uint32_t gId = p->getEntityIdFor("CDOTAGameRulesProxy");
auto entities = p->getEntities();
for (auto &e : entities) {
if (e.isInitialized() && e.getClassId() == prId) {
// Player Ressource, example: Get the number of kills for the first player
uint32_t kills_player_1 = e.prop<uint32_t>(".m_iKills.0000");
} else if (e.isInitialized() && e.getClassId() == gId) {
// Game Rules proxy, example: Get game winner:
float time = e.prop<float>(".dota_gamerules_data.m_fGameTime");
}
}
If you are unsure what property types certain entities are, or which are available at all, look at the devkit. It provides a nice overview over different entity types and values.
Is there an easy way of just getting the end of game stats from the file? a proper wiki outlining how the lib works would be very helpful.