ShadowFlare's Realm
http://sfsrealm.hopto.org/cgi-bin/yabb2/YaBB.pl
ShadowFlare's Realm Forums >> Program Development >> Need help about getting kills, deaths etc.
http://sfsrealm.hopto.org/cgi-bin/yabb2/YaBB.pl?num=1186677656

Message started by micdhack on Aug 9th, 2007, 4:40pm

Title: Need help about getting kills, deaths etc.
Post by micdhack on Aug 9th, 2007, 4:40pm

I need help about getting kills deaths from dota replays.
According to the reference below 0x6B should contain data for every player about kills and deaths.


Code:
 822 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 823 0x6B - SyncStoredInteger actions           [ n bytes ] [APM-]
 824 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 825  n byte  - unknown1 null terminated string - On the observed replay it seems to be always the same: A trigger name or identifier? -
 826  n byte  - unknown2 null terminated string - Player slot as a string. This info can and will be overridden by action 0x70 in replay of dota 6.39b and 6.39.
 827  n byte  - unknown3 null terminated string - stat identifier (so far "1" : kills - "2" : deaths - "3" : creepkills -  "4" : kills - creepdenies)
 828  1 dword - statValue - stat value associated to each identifier category.
 829
 830  Notes:
 831   o Observed in dota replay version 6.39 - at end of the game.  
 832   o unknown1 is always "dr.x" each time so far.
 833   o unknown2 value is correct starting to dota 6.40 version. For 6.39 and 6.39b, action 0x70 will override this value.
 834   o if you parse a dota replay (>=6.39), you'll see blocks of 8 actions (0x6B) denoting associated stats to a given player slot,
 835   then you'll see 4 actions (0x70) corresponding to the last 4 previous actions(0x6B) and overriding the associated player Slot.
 836   o starting dota 6.44, unknown3 will hold a 'winner' block and the action 0x70 will not be used anymore.
 837   in this case, the dword contains a value that designate the winning team, 1=sentinel, 2=scourge.
 838   o starting dota 6.45, unknown2 will hold a 'global' block for the 'winner' information. The action will not be repeated 10 times anymore.


Im using w3g-julas.php script so i see that in actions section there are some cases with values that represent an action. Thing is that i dont know assebly well and im having difficulties creating the code for reading this values.
If someone could help me i will appreciate it very much.

Title: Re: Need help about getting kills, deaths etc.
Post by matefkr on Aug 9th, 2007, 10:16pm

What is that? A game replay file?

Title: Re: Need help about getting kills, deaths etc.
Post by micdhack on Aug 10th, 2007, 10:07am

yes its a replay file from latest version of dota. According to the text their should be this 4 values for every player but i dont know how to read them...

I only created this code so far

Code:
case 0x6B:
n+=1
break;

Title: Re: Need help about getting kills, deaths etc.
Post by matefkr on Aug 10th, 2007, 10:49pm

Well, there could be some file operation in that language. Then use that.

If you want to know about assembly prog (under win32) you should check this out: http://win32assembly.online.fr

Title: Re: Need help about getting kills, deaths etc.
Post by esby on Aug 12th, 2007, 3:59pm

This has nothing to do with assembly.

To parse this action, you need to split it by 0x0 character 3 times, to read the 3 first strings, then depending the value of these strings, you have to interpretate them correctly.
After you'll need to read a dword.

Just to skip the action properly you'll need something like that:


Code:

  $n++;  // skip the action byte
 while ($actionblock{$n} != "\x00") {
             $n++;
 }
 $n++;  
 while ($actionblock{$n} != "\x00") {
             $n++;
 }
 $n++;  
 while ($actionblock{$n} != "\x00") {
             $n++;
 }
 $n++;  
 $n+=4; // skip the dword



You might also want to fix action 0x60 by the following code if it is not fixed.


Code:


      // Map trigger chat command (?)
         case 0x60:
           $n++;  // skip the action byte
           $n+=8; // skip two dwords
           while ($actionblock{$n} != "\x00") {
             $n++;
           }
           $n++;  
           break;



esby

Title: Re: Need help about getting kills, deaths etc.
Post by micdhack on Aug 12th, 2007, 5:32pm

thanks for your answer:
So added this code and it look something like this:

Code:

                             case 0x6B:
                                   $n++;  // skip the action byte
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $n++;
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $n++;
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $n++;
                                   $n+=4; // skip the dword
                                   break;

As i can understand the first two string we dont need them because they dont contain info about kills and such. So we need to read the third string. What im not getting is which variable has the kills and deaths.
I used this code

Code:

           case 0x6B:
                                   $n++;  // skip the action byte
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $n++;
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $n++;
                                   while ($actionblock{$n} != "\x00") {
                                         $mystring=$mystring.$actionblock{$n};
                                         $n++;
                                   }
                                   echo $mystring;
                                   $n++;
                                   $n+=4; // skip the dword
                                   break;

and $mystring returns a series of 100 digits with numbers varying from 1 to 4. If $actionblock{n} doesnt contain the number of kills which variable should i read?

Title: Re: Need help about getting kills, deaths etc.
Post by esby on Aug 13th, 2007, 10:20pm

The first variable is not needed, since it will be dr.x in all cases.

Now the second will be needed.
It should contain the #slot number or 'global'.
If it is global, it is currently used to indicate the winner side.

Just debug your value and check is what I gave out is exact or not. I havn't tested it.

Don't forget to initialize your strings.
You'll need the dword values to get the associated values.

esby

Title: Re: Need help about getting kills, deaths etc.
Post by micdhack on Aug 14th, 2007, 12:20pm

and the complete code is:


Code:
//kills and deaths and creep kills and creep denies
                             case 0x6B:
                                   $n++;  // skip the action byte
                                   $nbefore=$n;
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $useless_string=substr($actionblock, $nbefore, $n-$nbefore); // dr.x
                                   $n++;
                                   $nbefore=$n;
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $splayer_id=substr($actionblock, $nbefore, $n-$nbefore); //contains players id
                                   $n++;
                                   $nbefore=$n;
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $sstat_identifier=substr($actionblock, $nbefore, $n-$nbefore); //stat identifier 1,2,3,4
                                   $n++;
                                   $dword=substr($actionblock, $n , 4);
                                   $stats=unpack('Lvalue', $dword); //contains value according to stat identifier - $stats['value']
                                   
                                   if ($splayer_id<6) //this is in order to fix the weird bug that stats after 5 player id starts from 7 to 11
                                   {
                                         if ($sstat_identifier==1) {
                                               $this->players[$splayer_id]['kills'] = $stats['value'];      
                                         }
                                         if ($sstat_identifier==2) {
                                               $this->players[$splayer_id]['deaths'] = $stats['value'];      
                                         }
                                         if ($sstat_identifier==3) {
                                               $this->players[$splayer_id]['ckills'] = $stats['value'];      
                                         }
                                         if ($sstat_identifier==4) {
                                               $this->players[$splayer_id]['cdenies'] = $stats['value'];      
                                         }
                                   }
                                   else
                                   {
                                         if ($sstat_identifier==1) {
                                               $this->players[$splayer_id-1]['kills'] = $stats['value'];      
                                         }
                                         if ($sstat_identifier==2) {
                                               $this->players[$splayer_id-1]['deaths'] = $stats['value'];      
                                         }
                                         if ($sstat_identifier==3) {
                                               $this->players[$splayer_id-1]['ckills'] = $stats['value'];      
                                         }
                                         if ($sstat_identifier==4) {
                                               $this->players[$splayer_id-1]['cdenies'] = $stats['value'];      
                                         }
                                   }                              
                                   $n+=4; // skip the dword
                                   break;

I checked it with some dota replays and works great. Everyone is welcome to use it or make fixes on.

Title: Re: Need help about getting kills, deaths etc.
Post by micdhack on Aug 14th, 2007, 10:43pm

I found out comparing some replays that player_ids doesnt match with the positions the have in game. So i needed to change the code in order to calculate the position with a for and store the data accordingly

here is the code:

Code:
     //kills and deaths and creep kills and creep denies
                             case 0x6B:
                                   $n++;  // skip the action byte
                                   $nbefore=$n;
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $useless_string=substr($actionblock, $nbefore, $n-$nbefore); // dr.x
                                   $n++;
                                   $nbefore=$n;
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $splayer_id=substr($actionblock, $nbefore, $n-$nbefore); //contains players id
                                   $n++;
                                   $nbefore=$n;
                                   while ($actionblock{$n} != "\x00") {
                                         $n++;
                                   }
                                   $sstat_identifier=substr($actionblock, $nbefore, $n-$nbefore); //stat identifier 1,2,3,4
                                   $n++;
                                   $dword=substr($actionblock, $n , 4);
                                   $stats=unpack('Lvalue', $dword); //contains value according to stat identifier - $stats['value']
                             
                                   $playerposition=1;
                                   foreach ($this->players as $player) {
                                         if ($splayer_id<6)
                                         {
                                               if ($playerposition==$splayer_id)
                                               {

                                                     if ($sstat_identifier==1) {
                                                           $this->players[$player['player_id']['kills'] = $stats['value'];
                                                     }
                                                     if ($sstat_identifier==2) {
                                                           $this->players[$player['player_id']['deaths'] = $stats['value'];
                                                     }
                                                     if ($sstat_identifier==3) {
                                                           $this->players[$player['player_id']['ckills'] = $stats['value'];
                                                     }
                                                     if ($sstat_identifier==4) {
                                                           $this->players[$player['player_id']['cdenies'] = $stats['value'];
                                                     }
                                               }
                                         }
                                         else
                                         {
                                               if ($playerposition==$splayer_id-1)
                                               {
                                                     if ($sstat_identifier==1) {
                                                           $this->players[$player['player_id']['kills'] = $stats['value'];
                                                     }
                                                     if ($sstat_identifier==2) {
                                                           $this->players[$player['player_id']['deaths'] = $stats['value'];
                                                     }
                                                     if ($sstat_identifier==3) {
                                                           $this->players[$player['player_id']['ckills'] = $stats['value'];
                                                     }
                                                     if ($sstat_identifier==4) {
                                                           $this->players[$player['player_id']['cdenies'] = $stats['value'];
                                                     }
                                               }
                                         }
                                         $playerposition++;
                                   }

                                   $n+=4; // skip the dword
                                   break;

Title: Re: Need help about getting kills, deaths etc.
Post by esby on Oct 24th, 2007, 8:35pm

Updated the documentation

http://forums.dota-allstars.com/index.php?showtopic=181408

esby

ShadowFlare's Realm » Powered by YaBB 2.2.1!
YaBB © 2000-2008. All Rights Reserved.