• Welcome to Valhalla Legends Archive.
 

Parseing a warcraft replay file, need help

Started by phvckmeh, July 30, 2004, 02:03 AM

Previous topic - Next topic

phvckmeh

Alright ive read the documentation on replay files, but how would i even get to this step in visual basic?


i dunno how i would even get to this stage lol...


*******************************************************************************
* WarCraft III Replay file format description                                 *
*                                                                             *
* document version: 1.12                                                      *
* document date   : 2004-01-18                                                *
* document authors: blue, nagger                                              *
*                                                                             *
* For more informtion about w3g file format, please visit:                    *
*   http://warcraft.kliegman.com                                              *
* and the developer forum on:                                                 *
*   http://shadowflare.gameproc.com                                           *
* or contact us via mail                                                      *
*   mailto:[email protected]                                              *
*                                                                             *
*******************************************************************************

===============================================================================
Table of Content
===============================================================================
1.0 Introduction
2.0 [Header]
    2.1  [SubHeader] for header version 0
    2.2  [SubHeader] for header version 1
    2.3  Version information
    2.4  WarCraft III The Frozen Throne beta replay information
3.0 [Data block header]
4.0 [Decompressed data]
    4.1  [PlayerRecord]
    4.2  [GameName]
    4.3  [MapSettings]
    4.4  [MapRecord]
    4.5  [Map&CreatorName]
    4.6  [PlayerCount]
    4.7  [GameType]
    4.8  [LanguageID]
    4.9  [PlayerList]
    4.10 [GameStartRecord]
    4.11 [SlotRecord]
    4.12 [RandomSeed]
5.0 [ReplayData]
6.0 General notes
    6.1  Notes on official Blizzard Replays
7.0 Credits
8.0 Document revision history


===============================================================================
DISCLAIMER (please read it ...)
===============================================================================

All information in this document was solely obtained by looking at the replay
file and guessing the meaning of each single field. All knowledge about the
games mechanics is based on experience obtained by playing the game.
Neither reverse engineering was used nor any copyrighted files modified.
It is explicitly prohibited to use the information provided in this document
for any illegal activities including hacking, cheating and pirating.
Thank you Blizzard for your great games and a quite straight-forward
WarCraft III replay file format ;-)

The use of the information provided in this document is free of charge as long
as you follow the rules above. Furthermore you may copy it freely as long as
the file is unchanged (please mail us about any error or addition - we like
to keep things centralized).
We would really appreciate it if you credit us in your project or drop us
a line via mail - because we like to know if the work put into this document
was anything worth after all ;-)


===============================================================================
1.0 Introduction
===============================================================================

An important word ahead.
The information in this document is addressed to developers who want to create
programs, tools and websites that help to enrich the gaming experience for the
*whole* WarCraft III community.
We absolutely do not tolerate hacks and cheats. Therefore you MUST NOT use
the information provided in this document for any of these purposes.

This file is meant to contain a description of the replay format itself.
Additional notes and explanations on single fields and/or algorithms will
(eventually) be moved to a seperate file ("w3g_notes.txt") some day.

The whole file is still under construction. The meaning of some fields is still
unknown and "known" fields might be wrong. Please contact us if you figure out
any unknown values or find a replay that simply does not conform with the
description of a "known" field.

Convention:
-----------
Sections directly related to data stored in the replay file are written in
square brackets [].


===============================================================================
2.0 [Header]
===============================================================================

The replay file consist of a header followed by a variable number of compressed
data blocks. The header has the following format:

offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 | 28 chars  | zero terminated string "Warcraft III recorded game\0x1A\0"
0x001c |  1 dword  | fileoffset of first compressed data block (header size)
      |           |  0x40 for WarCraft III with patch <= v1.06
      |           |  0x44 for WarCraft III patch >= 1.07 and TFT replays
0x0020 |  1 dword  | overall size of compressed file
0x0024 |  1 dword  | replay header version:
      |           |  0x00 for WarCraft III with patch <= 1.06
      |           |  0x01 for WarCraft III patch >= 1.07 and TFT replays
0x0028 |  1 dword  | overall size of decompressed data (excluding header)
0x002c |  1 dword  | number of compressed data blocks in file
0x0030 |  n bytes  | SubHeader (see section 2.1 and 2.2)

The size of the header excluding the subheader is 0x30 bytes so far.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2.1 [SubHeader] for header version 0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

This header was used for all replays saved with WarCraft III patch version
v1.06 and below.

offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 |  1  word  | unknown (always zero so far)
0x0002 |  1  word  | version number (corresponds to patch 1.xx)
0x0004 |  1  word  | build number (see section 2.3)
0x0006 |  1  word  | flags
      |           |   0x0000 for single player games
      |           |   0x8000 for multiplayer games (LAN or Battle.net)
0x0008 |  1 dword  | replay length in msec
0x000C |  1 dword  | CRC32 checksum for the header
      |           | (the checksum is calculated for the complete header
      |           |  including this field which is set to zero)

Overall header size for version 0 is 0x40 bytes.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2.2 [SubHeader] for header version 1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

This header is used for all replays saved with WarCraft III patch version
v1.07 and above.

offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 |  1 dword  | version identifier string reading:
      |           |  'WAR3' for WarCraft III Classic
      |           |  'W3XP' for WarCraft III Expansion Set 'The Frozen Throne'
      |           | (note that this string is saved in little endian format
      |           |  in the replay file)
0x0004 |  1 dword  | version number (corresponds to patch 1.xx so far)
0x0008 |  1  word  | build number (see section 2.3)
0x000A |  1  word  | flags
      |           |   0x0000 for single player games
      |           |   0x8000 for multiplayer games (LAN or Battle.net)
0x000C |  1 dword  | replay length in msec
0x0010 |  1 dword  | CRC32 checksum for the header
      |           | (the checksum is calculated for the complete header
      |           |  including this field which is set to zero)

Overall header size for version 1 is 0x44 bytes.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2.3 Version information
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

game version | version in replay | version of war3.exe |  release date
--------------+-------------------+---------------------+----------------
   1.00      |     1.00.4448     |      1.0. 0.4448    |   2002-07-03
   1.01      |     1.01.4482     |      1.0. 1.4482    |   2002-07-05
   1.01b     |     1.01.4482     |      1.0. 1.4483    |   2002-07-10
   1.01c     |     1.01.4482     |                ?    |   2002-07-28
   1.02      |     1.02.4531     |      1.0. 1.4531    |   2002-08-15
   1.02a     |     1.02.4531     |      1.0. 1.4563    |   2002-09-06
   1.03      |     1.03.4572     |      1.0. 3.4653    |   2002-10-09
   1.04      |     1.04.4654     |      1.0. 3.4709    |   2002-11-04
   1.04b     |     1.04.4654     |      1.0. 3.4709    |   2002-11-07
   1.04c     |     1.04.4654     |      1.0. 4.4905    |   2003-01-30
   1.05      |     1.05.4654     |      1.0. 5.4944    |   2003-01-30
   1.06      |     1.06.4656     |      1.0. 6.5551    |   2003-06-03
   1.07      |     1.07.6031     |      1.0. 7.5535    |   2003-07-01
   1.10      |     1.10.6034     |      1.0.10.5610    |   2003-06-30
   1.11      |     1.11.6035     |      1.0.11.5616    |   2003-07-15
   1.12      |     1.12.6036     |      1.0.12.5636    |   2003-07-31
   1.13      |     1.13.6037     |      1.0.13.5816    |   2003-12-16
   1.13b     |     1.13.6037     |      1.0.13.5818    |   2003-12-19
   1.14      |     1.14.6039     |      1.0.13.5840    |   2004-01-07
   1.14b     |     1.14.6040     |      1.0.13.5840    |   2004-01-10

Notes on specific patches:
 o The mpq file for patch 1.02a is named 1.02c.
 o Patch 1.04b was only available as standalone patch (not on bnet)
   and solely adds a new copy protection to war3.exe.
 o The minor version number of the 'war3.exe' is wrong for patches
   1.02, 1.02a, 1.04, 1.04b.
 o Blizzard released no standalone versions of the patches:
   1.01c, 1.04c, 1.10.
 o Replays of patch 1.14 and 1.14b are incompatible

General notes:
 o There are no differences in replays between minor versions
   (except for patch 1.14 and 1.14b).
 o Check the file properties of the existing war3.exe to get the current
   installed version of Warcraft III (see column 3).
 o There are no differences in version and build numbers between RoC and TFT.
 o There are no differences between various language versions.
 o You can identify the replay version of the installed game by extracting
   the 'product version number' from the version resource of the 'war3.exe'.
 o You can identify the version of the 'war3.exe' by extracting the
   'file version number' from the version resource of the file.
 o On early patches build number of replays and 'war3.exe' are equal.
   Later on they differ.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2.4 WarCraft III The Frozen Throne beta replay information
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Beta replays are similar to RoC / final TFT replays.
Here comes a list of version numbers, header version and build numbers:

version | subheader version | build# | release date
--------+-------------------+--------+--------------
301    | version 0         |  6010  |  2003-03-04
302    | version 0         |  6011  |  2003-03-11
303    | version 0         |  6012  |  2003-03-14
304    | version 0         |  6013  |  2003-03-19
304a   | version 0         |  6013  |  2003-03-24
305    | version 1(*)      |  6015  |  2003-03-28
305a   | version 1(*)      |  6016  |  2003-03-30
306    | version 1         |  6018  |  2003-04-08
307    | version 1         |  6019  |  2003-04-11
308    | version 1         |  6021  |  2003-04-16
309    | version 1         |  6022  |  2003-04-17
310    | version 1         |  6023  |  2003-04-24
311    | version 1         |  6027  |  2003-04-30
312    | version 1         |  6030  |  2003-05-13
313    | version 1         |  6031  |  2003-05-19
314    | version 1         |  6034  |  2003-05-30
314a   | version 1         |  6034  |  2003-06-02
315    | version 1         |  6034  |  2003-06-10

(*) Patch 305 and 305a still use the old V0 GameVersion scheme (2 words).

 Notes:
 o 313 replays might be convertable to FT Retail 1.07 replays.
 o 315 replays might be convertable to FT Retail 1.10/1.11 replays.


===============================================================================
3.0 [Data block header]
===============================================================================

Each compressed data block consists of a header followed by compressed data.
The first data block starts at the address denoted in the replay file header.
All following addresses are relative to the start of the data block header.
The decompressed data blocks append to a single continueous data stream
(disregarding the block headers). The content of this stream (see section 4) is
completely independent of the original block boundaries.

offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 |  1  word  | size n of compressed data block (excluding header)
0x0002 |  1  word  | size of decompressed data block (currently 8k)
0x0004 |  1 dword  | unknown (probably checksum)
0x0008 |  n bytes  | compressed data (decompress using zlib)

To decompress one block with zlib:
1. call 'inflate_init'
2. call 'inflate' with Z_SYNC_FLUSH for the block

The last block is padded with 0 bytes up to the 8K border. These bytes can
be disregarded.

//TODO: add decompression details and move explanation to seperate file


===============================================================================
4.0 [Decompressed data]
===============================================================================

Decompressed data is a collection of data items that appear back to back in
the stream. The offsets for these items vary depending on the size of every
single item.

This section describes the records that always appear at the beginning of
a replay data stream. They hold information about settings and players right
before the start of the game. Data about the game in progress is described
in section 5.

The order of the start up items is as follows:

# |   Size   | Name
---+----------+--------------------------
1 |   4 byte | Unknown (0x00000110 - another record id?)
2 | variable | PlayerRecord (see 4.1)
3 | variable | GameName (null terminated string) (see 4.2)
4 |   6 byte | MapSettings (see 4.3)
5 |  10 byte | MapRecord (see 4.4)
6 | variable | Map&CreatorName  (encrypted null terminated string) (see 4.5)
7 |   4 byte | PlayerCount (see 4.6)
8 |   4 byte | GameType (see 4.7)
9 |   4 byte | LanguageID (see 4.8)
10 | variable | PlayerList (see 4.9)
11 | variable | GameStartRecord (see 4.11)

The following sections describe these items in detail.
After the static items (as described above) there follow variable information
organized in blocks that are described in section 5.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.1 [PlayerRecord]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 |  1 byte   | RecordID:
      |           |  0x00 for game host
      |           |  0x16 for additional players (see 4.9)
0x0001 |  1 byte   | PlayerID
0x0002 |  n bytes  | PlayerName (null terminated string)
  n+2 |  1 byte   | size of additional data:
      |           |  0x01 = custom
      |           |  0x08 = ladder

Depending on the game type one of these records follows:

o For custom games:

 offset | size/type | Description
 -------+-----------+---------------------------------------------------------
 0x0000 | 1 byte    | null byte (1 byte)

o For ladder games:

 offset | size/type | Description
 -------+-----------+---------------------------------------------------------
 0x0000 | 4 bytes   | runtime of players Warcraft.exe in milliseconds
 0x0004 | 4 bytes   | player race flags:
        |           |   0x01=human
        |           |   0x02=orc
        |           |   0x04=nightelf
        |           |   0x08=undead
        |           |  (0x10=daemon)
        |           |   0x20=random
        |           |   0x40=race selectable/fixed (see notes in section 4.11)


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.2 [GameName]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

This is a plain null terminated string reading the name of the game.

Only in custom battle.net games you can name your game, otherwise the name
is fixed:

o For ladder games it reads "BNet".

o For custom LAN games it holds a localized string including the game creators
 player name.
 Examples: a game created by the player 'Blue' results in:
          "Blue's game" for the english version of Warcraft III
          "Spiel von Blue" for the german version

o For custom single player games it holds a localized fixed string.
          "local game" for the english version
          "Lokales Spiel" for the german version

o Following is a list for all localized strings (encoded in plain ASCII) used
 by WarCraft III patch version 1.06 and earlier
 (see war3.mpq\UI\FrameDef\GlobalStrings.fdf: GAMENAME, LOCAL_GAME):

 English        : "%s's Game"         : "local game"
 Czech    (1029): "Hra %s"            : "Místní hra"
 German   (1031): "Spiel von %s"      : "Lokales Spiel"
 Spanish  (1034): "Partida de %s"     : "Partida local"
 French   (1036): "Partie de %s"      : "Partie locale"
 Italian  (1040): "Partita di %s"     : "Partita locale"
 Polish   (1045): "Gra (%s)"          : "Gra lokalna"

 %s denotes the game creators player name.

o The following list shows all localized strings (encoded in plain ASCII) used
 by WarCraft III patch version 1.07 and later
 (see war3.mpq\UI\FrameDef\GlobalStrings.fdf: GAMENAME, LOCAL_GAME):

 German   (1031): "Lokales Spiel (%s)"  : "Lokales Spiel"

 %s denotes the game creators player name.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.3 [MapSettings]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The map settings (extended options on create game screen) are encoded
using various flags distributed over 6 (?) bytes.
For details about the single options read the file
"support/Readme/(PC)UIMainMenus.html"
in your WarCraft III installation directory.

Denoted below are only nonzero flags.

offset | bitnr | Description
-------+-------+---------------------------------------------------------------
0x0000 |       | this byte was always 0x00 so far
-------+-------+---------------------------------------------------------------
0x0001 |   0   | unknown (always set ?)
      |   1   | == 1 means game speed set to 'normal'
      |   2   | == 1 means 'visibility: hide terrain'
      |   4   | == 1 means 'Full Shared Unit Control' was enabled
      |   5   | unknown - only set on map "(12)DivideAndConquer.w3m"
-------+-------+---------------------------------------------------------------
0x0002 |   0   | unknown (always set ?)
      |   1   | == 1 means game speed set to 'fast'
-------+-------+---------------------------------------------------------------
0x0003 |   0   | unknown (always set ?)
      |   1   | == 1 means 'visibility: map explored'
      |   2   | == 1 means 'visibility: always visible' (no fog of war)
      |   3   | == 1 means 'visibility: default'
      |   4   | == 1 means additional players as observer allowed
      |   5   | == 1 means 'Observers on Defeat'
      |   6   | == 1 means 'Teams Together'
      |       |    (team members are placed at neighbored starting locations)
-------+-------+---------------------------------------------------------------
0x0004 |   0   | unknown (always set ?)
      |   1   | == 1 if 'fixed teams' is set (both - bit 1 & 2 are set)
      |   2   | == 1 if 'fixed teams' is set
-------+-------+---------------------------------------------------------------
0x0005 |   0   | unknown (always set ?)
      |   1   | == 1 if 'random hero' is set
      |   2   | == 1 if 'random races' is set
      |   6   | == 1 means 'Referees'
-------+-------+---------------------------------------------------------------

Notes:
 o "slow" speed is set if neither 'normal' nor 'fast' speed is active
 o 'No Observers' (leave game on defeat) is selected if both bit 4 and 5
   of byte 0x03 are inactive
 o 'Full Observers' in game options results in both bit 4 and bit 5 of
   byte 0x03 set
 o 'Referees' in game options results in both bit 4 and 5 of byte 0x03
   cleared and bit 6 of byte 0x05 set
 o standard values for ladder games are: 0x00 0x01 0x03 0x43 0x07 0x01


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.4 [MapRecord]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

This is some sort of map specific record.
Here come some values I found in my replay archive for the two most
popular maps.

 01 01 01 91 01 01 F7 8F DB 05 - plunder 1.02 german (ladder)
 01 01 01 91 01 01 F7 8F DB 05 - plunder 1.03 german (ladder)
 01 01 01 A9 01 01 F5 89 A1 4F - plunder 1.04 german (ladder)
 01 01 01 A9 01 01 F5 89 A1 4F - plunder 1.05 german (ladder)
 01 01 01 A9 01 01 F5 89 A1 4F - plunder 1.06 german (ladder)

 01 01 01 C9 01 01 11 F5 61 13 - LT 1.02 german (ladder)
 01 01 01 C9 01 01 11 F5 61 13 - LT 1.03 german (ladder)
 01 01 01 E9 01 01 5D 0D 87 05 - LT 1.04 german (ladder)
 01 01 01 E9 01 01 5D 0D 87 05 - LT 1.05 german (ladder)
 01 01 01 E9 01 01 5D 0D 87 05 - LT 1.06 german (ladder)

- byte 2 and 5 are different in custom games (and different per map):

 01 01 01 A9 01 01 F5 89 A1 4F - plunder 1.05 german (ladder)
 01 55 01 A9 75 01 F5 89 A1 4F - plunder 1.05 german (custom)
 01 55 01 A1 75 01 63 59 9F B7 - plunder 1.10 german (custom)

 01 01 01 E9 01 01 5D 0D 87 05 - LT 1.05 german (ladder)
 01 7D 01 E9 7D 01 5D 0D 87 05 - LT 1.05 german (custom)

 The meaning of these fields is still unknown !

- The last dword is likely a checksum for the map used.
 WarCraft III does not load a replay if the the checksum does not match.

// TODO: check out some other language versions


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.5 [Map&CreatorName]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

There are three null-terminated strings here back-to-back, all encoded into a
single null terminated string. First is the map name, second is the game
creators name (can be "Battle.Net" for ladder) and third is an always empty
string.

The first character of this multiple string record is always an unencoded
character (that reads 'M' for 'Maps' if you have the maps in the standard
location).

After that character follow blocks of 8 byte each:

byte | description
-----+---------------------------------------
0   | control byte
1-7 | character of string

The control byte holds a bitfield with one bit for each byte of the 8 byte
block. Bit 0 corresponds to byte 0, bit 1 to byte 1, and so on.
Only Byte 1-7 contribute to the map/creator name string.
Bit 0 seems to be always 1;
Decoding these bytes works as follows:

If the corresponding bit is a '1' then the character is moved over directly.
If the corresponding bit is a '0' then subtract 1 from the character.

These blocks are repeated until you find a NULL character in the stream.

Example decompression code (in 'C'):

char* EncodedString;
char* DecodedString;
char  mask;
int   pos=1;
int   dpos=1;

DecodedString[0]=EncodedString[0];

while (EncodedString[pos] != 0)
{
 if ((pos-1)%8 == 0) mask=EncodedString[pos];
 else
 {
   if ((mask & (0x1 << ((pos-1)%8))) == 0)
     DecodedString[dpos++] = EncodedString[pos] - 1;
   else
     DecodedString[dpos++] = EncodedString[pos];
 }
 pos++;
}


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.6 [PlayerCount]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

4 bytes - num players or num slots
 in Bnet games is the exact ## of players
 in Custom games, is the ## of slots on the join game screen
 in Single Player custom games is 12


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.7 [GameType]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 |  1 byte   | Game Type:
      |           | (0x00 = unknown, just in a few  pre 1.03 custom games)
      |           |  0x01 =   Ladder -> 1on1 or FFA
                              Custom -> Scenario  (not 100% sure about this)
      |           |  0x09 = Custom game
      |           |  0x1D = Single player game
      |           |  0x20 = Ladder Team game (AT or RT, 2on2/3on3/4on4)
0x0001 |  1 byte   | PrivateFlag for custom games:
      |           |  0x00 - if it is a public LAN/Battle.net game
      |           |  0x08 - if it is a private Battle.net game
0x0002 |  1 word   | unknown (always 0x0000 so far)

TODO:
 values in patch >=1.07:
   01 00 00 00 : ladder 1on1 / custom scenario
   20 00 00 00 : ladder team
   09 00 00 00 : custom game
   09 A8 12 00 : custom game
   09 A0 12 00 : custom game
   09 A8 42 00 : custom game
   09 A8 14 00 : custom game
   09 A0 14 00 : custom game
   01 40 13 00 : custom game
   09 A0 42 00 : custom game
   09 A8 44 00 : custon game


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.8 [LanguageID]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4 byte - (independent of realm, map, gametype !)
Might be another checksum or encoded language.
I found the following numbers in my replays:

C4 F0 12 00 - patch 1.10 ger
90 F1 12 00 - patch 1.06 ger
90 F1 12 00 - patch 1.05 ger
A0 F6 6D 00 - patch 1.04 ger
24 F8 12 00 - patch 1.04 eng(?)
A0 F6 6D 00 - patch 1.03 ger
C0 F6 6D 00 - patch 1.02 ger

//TODO: Find out what this field is really about.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.9 [PlayerList]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The player list is an array of PlayerRecords for all additional players
(excluding the game host and any computer players).
If there is only one human player in the game it is not present at all!
Per additional player there is the following structure in the file:

offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 | 4/11 byte | PlayerRecord (see 4.1)
0x000? |    4 byte | unknown
      |           |  (always 0x00000000 for patch version >= 1.07
      |           |   always 0x00000001 for patch version <= 1.06)

This record is repeated as long as the first byte equals the additional
player record ID (0x16).


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.10 [GameStartRecord]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 |  1 byte   | RecordID - always 0x19
0x0001 |  1 word   | number of data bytes following
0x0003 |  1 byte   | nr of SlotRecords following (== nr of slots on startscreen)
0x0004 |  n bytes  | nr * SlotRecord (see 4.11)
  n+4 |  1 dword  | RandomSeed (see 4.12)
  n+8 |  1 byte   | SelectMode
      |           |   0x00 - team & race selectable (for standard custom games)
      |           |   0x01 - team not selectable
      |           |          (map setting: fixed alliances in WorldEditor)
      |           |   0x03 - team & race not selectable
      |           |          (map setting: fixed player properties in WorldEditor)
      |           |   0x04 - race fixed to random
      |           |          (extended map options: random races selected)
      |           |   0xcc - Automated Match Making (ladder)
  n+9 |  1 byte   | StartSpotCount (nr. of start positions in map)


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.11 [SlotRecord]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 |  1 byte   | player id (0x00 for computer players)
0x0001 |  1 byte   | unknown (0xff in ladder, 0x64 in custom ???)
0x0002 |  1 byte   | slotstatus:
      |           |   0x00 empty slot
      |           |   0x01 closed slot
      |           |   0x02 used slot
0x0003 |  1 byte   | computer player flag:
      |           |   0x00 for human player
      |           |   0x01 for computer player
0x0004 |  1 byte   | team number:0 - 11
      |           | (team 12 == observer or referee)
0x0005 |  1 byte   | color (0-11):
      |           |   value+1 matches player colors in world editor:
      |           |   (red, blue, cyan, purple, yellow, orange, green,
      |           |    pink, gray, light blue, dark green, brown)
      |           |   color 12 == observer or referee
0x0006 |  1 byte   | player race flags (as selected on map screen):
      |           |   0x01=human
      |           |   0x02=orc
      |           |   0x04=nightelf
      |           |   0x08=undead
      |           |   0x20=random
      |           |   0x40=race selectable/fixed (see notes below)
0x0007 |  1 byte   | computer AI strength: (only present in v1.03 or higher)
      |           |   0x00 for easy
      |           |   0x01 for normal
      |           |   0x02 for insane
      |           | for non-AI players this seems to be always 0x01
0x0008 |  1 byte   | player handicap in percent (as displayed on startscreen)
      |           | valid values: 0x32, 0x3C, 0x46, 0x50, 0x5A, 0x64
      |           | (field only present in v1.07 or higher)

Notes:
 o This record is only 7 bytes in pre 1.03 replays.
   The last two fields are missing there.

 o For pre v1.07 replays this record is only 8 bytes.
   The last field is missing there.

 o For open and closed slots team and color fields are undetermined.

 o For WarCraft III patch version <= 1.06:
   If bit 6 of player race flags is additionally set (0x40 added) then the
   race is fixed by the map (see also section 4.10).

 o For WarCraft III patch version >= 1.07:
   If bit 6 of player race flags is additionally set (0x40 added) then the
   race is selectable by the player - otherwise it is a ladder game or the
   race is fixed by the map (see also section 4.10).


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.12 [RandomSeed]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
This field is the best bet on the random seed the Warcraft III engine is
initialized with. The replay data that follows requires already a set up seed
(since starting positions and race are fixed at this time).

For custom games (no matter if battle.net or LAN) this dword appears to be
the runtime of the Warcraft.exe of the game host in milliseconds.

For ladder games the value variies very much - probably the battle.net server
hands out a 'real' seed (not runtime based) to the clients.


===============================================================================
5.0 [ReplayData]
===============================================================================

This section describes the Replay data following directly after the static data
described in section 4. It represents information about the game in progress.

Replay data is segmented into seperate blocks of either fixed or variable size.
The order of these blocks is not fixed and not all known blocktypes have to be
present in a replay.

Blocks always start with one byte representing the block ID. Using this ID one
can identify specific blocks while skipping unwanted (using the block size).
Below all known blocks are listed by their block ID followed by a description
of the data following the ID. Denoted in square brackets is the overall size
of each block (including the one byte block ID).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x17  - LeaveGame                                                   [ 14 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 1 dword - reason
            0x01 - connection closed by remote game
            0x0C - connection closed by local game
            0x0E - unknown (rare) (almost like 0x01)
 1 byte  - PlayerID
 1 dword - result - see table below
 1 dword - unknown (number of replays saved this warcraft session?)


Key for Table:
 player = player according to PlayerID
 saver  = replay saver ( = player of very last leave-action)
 INC    = the unknown parameter in the last leave-action was incremented by 1
          (compared to the other LeaveGame actions before)
 [?]    = entries marked with this symbol are true for common replays but
          we encountered at least one nonconform replay.
 [O]    = if the replay saver was an observer it regularly happens that
          players get a result of 0x01

  Reason   | Result | Description
===========+========+=======================================================
   0x01    |  0x01  | player left (disconnected or saver is observer)    [O]
 (remote)  |  0x07  | player left
           |  0x08  | player lost (was completly erased)
           |  0x09  | player won
           |  0x0A  | draw (long lasting tournament game)
           |  0x0B  | player left (was observer)                         [?]
-----------+--------+-------------------------------------------------------
   0x0E    |  0x01  | player left                                        [?]
 (remote)  |  0x07  | player left                                        [?]
           |  0x0B  | player left (was observer)                         [?]
===========+========+=======================================================
   0x0C    |  0x01  | saver disc. / observer left                        [O]
 (not last)|  0x07  | saver lost, no info about the player               [?]
           |  0x08  | saver lost (erased), no info about the player
           |  0x09  | saver won, no info about the player
           |  0x0A  | draw (long lasting tournament game)
           |  0x0B  | saver lost (obs or obs on defeat)                  [?]
-----------+--------+-------------------------------------------------------
 last 0x0C |  0x01  | saver disconnected
(rep.saver)|  0x07  | with INC => saver won
           |        | w/o  INC => saver lost
           |  0x08  | saver lost (completly erased)
           |  0x09  | saver won
           |  0x0B  | with INC => saver won most times, but not always   [?]
           |        | w/o  INC => saver left (was obs or obs on defeat)  [?]

Personal note:
 o Until now we have not found a robust winner detection algorithm that
   works for every replay :(
   We checked about 6000 replays. Normal ladder games works well,
   but especially FFA games saved by an observer are very &§*#$.
   So here is still work to do...

Notes:
 o Do NOT use the marked lines ([?],[N]) for winner detection.
   If you use these you will probably increase the detection rate but also
   get false detections.
   The unmarked lines proofed to be fail-safe (at least until now).

 o If at least one player gets a draw result the whole game is draw.

 o The result*s* of the replay saver - he can get more than one because all
   local leave actions (reason=0x0C) belong to this result - do not
   contradict (except in draw games). There is never a win and a loss result
   at the same time (if you use the none marked lines).

 o All result-values in a leave-action are player specific results.
   E.g. if one player of a team quits he gets a 'lost' result value - even
   if his team mate later wins the game.

 o If you get a win result for a player his team is definitely the winner and
   all other teams lost.

 o If the result for every player of a team is "loss" the whole team lost.

 o Even WarCraft cannot see into the future ;). If the saver of a team replay
   leaves the game first, you will always detect a 'saver-lost' result.
   It is impossible to detect who is the winner in this replay.
   Unfortunately this happens quite often. Imagine a 2vs2 game: One team was
   nearly beaten, both players say 'gg' and leave. If the replay saver (one of
   these losers) quits only 1 second before his team mate, you cannot detect
   the winner in this replay.
   Our strategy in this situation is to assume that the whole replay saver
   team lost. This might not be correct in every situation (but from the
   replay we will never know).
   An alternative strategy could be: The team with the most remaining players
   wins. This can be wrong too e.g. if in a 2on2 one team nearly won when one
   of the players of this team disconnects but the second player finishes the
   work.
   In 2on2 games both strategies lead to same result.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x1A      - unknown (first startblock)                               [ 5 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 1 dword - unknown (always 0x01 so far)

Notes:
 o This block seems to be always the first block at start of game.
   It is never repeated.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x1B      - unknown (second startblock)                              [ 5 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 1 dword - unknown (always 0x01 so far)

Notes:
 o This block seems to be always the second block at start of game.
   It is never repeated.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x1C      - unknown (third startblock)                               [ 5 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 1 dword - unknown (always 0x01 so far)

Notes:
 o This block seems to be always the third block at start of game.
   It is never repeated.
 o Rarely there is a chat block (0x20) or a LeaveGame block (0x17) between
   2nd startblock (0x1B) and this 3rd startblock (0x1C)


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x1E       - TimeSlot block                                       [ n+3 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
for details see block 0x1F

Notes:
 o For patch version <= 1.02 this block was used instead of block 0x1F.
 o This block also rarely appears in version >= 1.07. In this case the usual
   RandomSeed block (0x22) does *not* follow though.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x1F       - TimeSlot block                                       [ n+3 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 1 word   - n = number of bytes that follow
 1 word   - time increment (milliseconds)
             about 250 ms in battle.net
             about 100 ms in LAN and single player
 n-2 byte - CommandData block(s) (not present if n=2)

For every player which has executed an action during this time slot there is
at least one 'Command data block'.

CommandData block:
  1 byte  - PlayerID
  1 word  - Action block length
  n byte  - Action block(s) (see file 'w3g_actions.txt' for details)

Notes:
 o The 'time increments' are only correct for replays played at fastest speed.
 o Accumulate all 'time increments' to get the time of current action(s).
 o This block is always followed by a 'Random Seed' block (0x22)
 o For patch version <= 1.02 this block has the ID 0x1E.
 o A detailed description of the action block format and all valid actions can
   be found in the seperate document 'w3g_actions.txt'.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x20       - Player chat message (patch version >= 1.07)           [ n+4 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 1 byte   - PlayerID (message sender)
 1 word   - n = number of bytes that follow
 1 byte   - flags
             0x10   for delayed startup screen messages? (see note)
             0x20   for normal messages
 1 dword  - chat mode (not present if flag = 0x10):
             0x00   for messages to all players
             0x01   for messages to allies
             0x02   for messages to observers or referees
             0x03+N for messages to specific player N (with N = slotnumber)

 n bytes  - zero terminated string containing the text message

Notes:
 o This block was introduced with patch 1.07.
 o Only messages send and received by the player who saved the replay are
   present.
 o Messages to observers are not saved.
 o The slot number corresponds to the record number as per section 4.11
   starting with zero (first record = slot 0).
 o To get the time of the chat command, accumulate all 'time increments' from
   the 'TimeSlot' blocks (see above, block 0x1E and 0x1F).

Notes on chat messages with flag = 0x10:
 o Only appears on startup between action block 0x1B and 0x1C.
 o The 'chat mode' dword is not present. The message text starts right after
   the flag field. The length value reflects this correctly.
 o These chat messages do not appear when the replay is watched with WarCraft.
 o The messages only appear in custom game replays. Maybe these are chat
   messages written in the game startup screen, which were send right before
   the game was started and could not be shown there in time because of lag.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x22      - unknown (Checksum or random number/seed for next frame)  [ 6 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 1 byte  - number of bytes following (always 0x04 so far)
 1 dword - unknown (very random)

Notes:
 o For patch version <= 1.02 this block has the ID 0x20.
 o This message eventually syncs the random seed used for any calculation
   within the previous or next frame between all clients.
   It might be a complete gamescene checksum too though.
 o This block follows always after a 'TimeSlot' block.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x23      - unknown                                                 [ 11 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Maybe:
 1 dword - unknown
 1 byte  - unknown (always 4?)
 1 dword - unknown (random?)
 1 byte  - unknown (always 0?)

Notes:
 o Very rare.
 o Appears in front of a 'LeaveGame' action.

Examples:
 23 4C 0D 00 00 04 0B B0 B1 FC 00  ->  "#L........."    3404 4 4239503371 0
 23 64 07 00 00 04 AC 34 28 7E 00  ->  "#d.....4(~."    1892 4 2116564140 0
 23 FB 0D 00 00 04 DD B8 B1 87 00  ->  "#.........."    3579 4 2276571357 0
 23 D5 15 00 00 04 19 ED 43 72 00  ->  "#.......Cr."    5589 4 1917054233 0
 23 1B 03 00 00 04 D8 2E 81 4F 00  ->  "#........O."     795 4 1333866200 0
 23 F2 04 00 00 04 91 7F C6 01 00  ->  "#........."    1266 4   29786001 0


 all following back-to-back in a single replay:
 23 3A 03 00 00 04 B5 1F DC 80 00  ->  "#:........."     826 4 2161909685 0
 23 3B 03 00 00 04 DE A7 93 77 00  ->  "#;.......w."     827 4 2006165470 0
 23 3C 03 00 00 04 A9 A6 78 3B 00  ->  "#<......x;."     828 4  997762729 0
 23 3D 03 00 00 04 25 87 97 9C 00  ->  "#=....%...."     829 4 2627176229 0

TODO: more analysis


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x2F      - Forced game end countdown (map is revealed)              [ 9 byte ]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 1 dword - mode:
            0x00 countdown is running
            0x01 countdown is over (end is forced *now*)
 1 dword - countdown time in sec

Notes:
 o This block was introduced with patch 1.07.
 o Only found in battle.net tournament games which last too long.
 o Normally countdown starts with 4:58 and the block is repeated every 30s
   (4:58, 4:28, 3:58, ..., 0:58, 0:28, 0:00, now).
 o On first occurence of this block the "fog of war" is turned off
   (the complete map is revealed to all player).


===============================================================================
6.0 General notes
===============================================================================

o It seems that the following things are *not* to be found in the replay:
   + the Battle.net realm
   + the time/date of the game
   + the level/exp/record of the players in a ladder game

o You may add your own data at the end of the replay file - Warcraft III
 ignores them (except for official blizzard replays, see section 6.1).
 This might be useful e.g. for an replay database tool when storing a
 description of the game right with the replay data.

o The saver of the replay is the last player leaving the game. This
 'LeaveGame'-Action (see 5.0) is also the very last action of the replay.
 This means the player id of the replay saver is the 9th last byte of the
 uncompressed replay (so you don't have to parse the action-blocks to get the
 name of the replay saver). This method does not work for official Blizzard
 replays.

o Warcraft starts showing a replay with the game hosts point of view.

o The game type is not explicitly recorded in the replay:
  - there is no difference between AT (arranged team) and RT (random team)
    ladder games replay wise
  - one can detect team games by the team number in slot records
  - one can detect FFA games by all players having different team numbers
    and there are more than 2 in the game

o One can start Warcraft with the parameter '-loadfile' to play back a replay
 immediately:  War3.exe -loadfile "replayfilename"
 As a side effect the single-player user-name is automatically changed to
 'WorldEdit'.

o There was no patch 1.07, 1.08 and 1.09 for WarCraft III classic.
 Patch 1.10 was released after patch 1.06 reflecting the release of
 WarCraft III expansion set 'The Frozen Throne'.

o WarCraft III Frozen Throne was shipped with patch version 1.07 but was
 immediately patched to version 1.10. There was no patch 1.08 or 1.09.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6.1 Notes on official Blizzard Replays
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

These replays are automatically obtained by Blizzard during or after high level
ladder games and tournament final games. They are available for download
through the official Battle.net web page and show some differences to normal
replays saved by users.

Differences:
o The build number (see 2.2) is always zero.

o The filesize is 132 byte larger than denoted in header (see below).

o The map record (see 4.4) always reads '01 01  01 F9 01 01  FF FF FF FF'.

o The values of the unknown PlayerList entry (see 4.9) of all players in the
  replay is equal to the LanguageID (see 4.8).

o The number of SlotRecords (Byte 0x0003 of [GameStartRecord] in section 4.10)
  is always zero - there are no slot records (see 4.11) present.

o The StartSpotCount (see [GameStartRecord] in section 4.10) is always 0xCC.

o There is a signature block at the end of the replay:
   1 dword  : 4E 47 49 53 = 'NGIS' <=> 'SIGN'
   128 Byte : signature

Notes:
o Since the lack of all slot records, one has to generate these data:
  iterate slotNumber from 1 to number of PlayerRecords (see 4.1)
    player id    = slotNumber
    slotstatus   = 0x02                   (used)
    computerflag = 0x00                   (human player)
    team number  = (slotNumber -1) mod 2  (team membership alternates in
                                                            PlayerRecord)
    color        = unknown                (player gets random colors)
    race         = as in PlayerRecord
    computerAI   = 0x01                   (non computer player)
    handicap     = 0x64                   (100%)

o Tournament replays are given a unique name using the following scheme:
   'YYYYMMDDhhmmxxxxx-TAG-TYPEp.w3g'
  where:
    YYYY  - year of the beginning of the game in greenwitch mean time (GMT)
    MM    - month ...
    DD    - day ...
    hh    - hour ...
    mm    - minutes ...
    xxxxx - numeric ID
    TAG   - 'W3XP' for FrozenThrone, 'WAR3' for Classic
    TYPE  - standard or race/map limitations,...
              without limitations (day of week):
                FRI - friday
                SAT - saturday
                SUN - sunday
              race limitation tournament:
                HUM - Human
                ORC - Orc
                NLF - Nightelf
                UND - Undead
                RND - Random
              map limitation tournament:
                CLD - Coldheart
                FLD - Floodplains
                GNW - Gnollwood
                LST - Lost Temple
                RCK - Turtle Rock
                WET - Wetlands
    p     - number of players per team

  File name examples:
    20030816204000041-W3XP-SAT1.w3g
                       Frozen Throne 1on1 tournament on Saturday august 16th
                       (round started at 20:40 GMT)
    20030817222400050-W3XP-SUN2.w3g
                       Frozen Throne 2on2 tournament on Sunday august 17th
    20030820205400081-W3XP-LST1.w3g
                       TFT 1on1 "Lost Temple"-only tournament on august 20th


o Since one cannot change the name of the replay file, there has to be a
 checksum in the signature (or maybe within the replay data itself).

o This feature was officially announced by Blizzard a couple of days after the
 release of patch 1.12. It might have been present in previous versions of
 the game though.


TODO: - signature analysis


===============================================================================
7.0 Credits
===============================================================================

We like to thank the following people for their help on decoding the
W3G format (in alphabetical order):

o BlackDick for
  - info on header checksum calculation
  - info on updates with patch 1.10
  - version/build information on TFT beta replays
  - various other hints and minor updates

o DooMeer for
  - info on '-loadfile' parameter

o Ens for
  - info on chat modes (observer, specific player)

o Mark Pflug for
  - finding action blocks 0x1E and 0x23

o Kliegs for
  - his notes.txt on which this document is based
  - hosting a CVS for replay format related documents

o ShadowFlare for
  - WinMPQ
  - hosting the developer forum

o Soar
  - some infos on changes with TFT

o Ziutek for
  - Total Commander MPQ plugin


===============================================================================
8.0 Document revision history
===============================================================================

o general notes
+ information added
- information changed

version 1.12 - 2004-01-18
-------------------------
2004-01-17: - added build numbers for patches 1.14 and 1.14b


version 1.11 - 2004-01-02
-------------------------
2003-12-20: - added build numbers for patches 1.13 and 1.13b
2003-12-15: - fixed developer forum URL in header


version 1.10 - 2003-12-14
-------------------------
2003-12-14: - fixed even more grammar/spelling mistakes
2003-12-05: - fixed various grammar/spelling mistakes


version 1.09 - 2003-12-02
-------------------------
2003-12-02: o killed a lot of trailing spaces
2003-12-02: + added BETA patch release dates (section 2.4)
2003-11-25: + added patch release dates (section 2.3)
2003-11-23: - updated notes on version determination
2003-11-11: - fixed some typos/grammar mistakes
2003-11-11: - extended description of general block structure
2003-11-06: + added many notes on winner detection (LeaveGame section)
2003-11-03: + added version section (section 2.3)
2003-10-11: - renamed "game creator" to "game host" in some places
2003-10-11: - various minor layout improvements
2003-10-05: + added note and examples on block 0x23
2003-09-25: - changed one LeaveGame result
2003-09-24: + added flag 0x10 description of chat blocks
2003-09-24: + added note on third startblock


version 1.08 - 2003-09-20
-------------------------
+ added info on official Blizzard replays
+ added action blocks 0x1E and 0x23
+ added patch 1.12 build number
+ added note on loadfile-parameter
+ vastly improved leave game command (0x17) description
- fixed error in header ID string
- changed description of version number fields for subheaders version 0
- renamed action block 0x1F to 'TimeSlot' and improved description
- many minor updates and fixes


version 1.07 - 2003-07-31
-------------------------
+ added missing chat modes (thx Ens)
+ added size information to all blocks in section 5
+ improved introduction part of sections 4 and 5
- fixed 'referee' bug in map settings section
o various layout improvements


version 1.06 - 2003-07-22
-------------------------
+ added replay data block 0x2F
+ added some additional notes to disclaimer
+ added some more build numbers (thanks to blackdick)
+ added version/build information on TFT beta replays (thx BlackDick)
- renamed mostly all 'patch 1.10' to 'patch 1.07',
  because first TFT release was 1.07 and the replays had the same structure
  as in 1.10


version 1.05 - 2003-07-01
-------------------------
- fixed error in description of new chat message block (0x20)
+ added information on fixed races in patch 1.10
+ added some minor notes related to patch 1.10


version 1.04 - 2003-06-30
-------------------------
+ added note on game type in section 6.
+ added some minor notes
+ added patch 1.10 format changes:
   o new header (section 2)
   o handicap field (section 4.11)
   o referee type observers (sections 4.3 and 4.11)
   o chat message block (section 5)
+ added some patch 1.10 example records


version 1.03 - 2003-06-16
-------------------------
+ added build numbers for all released patches
+ added some minor notes in various sections
+ added some patch 1.06 example records
- fixed missing dword (section [LeaveGame])
+ added some language strings (section [GameName])
+ added notes about replay saver


version 1.02 - 2003-06-14
-------------------------
o removed all "//*" marks for better readability
- fixed some typos
- fixed patch version for blocks 0x1E and 0x20 in section 5
  (patch <= 1.02 instead of <1.05)
- minor cleanups of various sections


version 1.01 - 2003-06-12
-------------------------
o differences and additions to kliegs notes.txt are marked with //*
o minor layout improvements in section 5
- renamed 'Player Actions block' to 'Player commands block'
  and updated whole paragraph


version 1.00 - 2003-06-06
-------------------------
o first public release
o differences and additions to kliegs notes.txt are marked with //*
+ added info on header checksum calculation (thx BlackDick)
+ added info on first unknown field in header (thx BlackDick)


version 0.90 - 2003-06-04
-------------------------
o beta release
o differences and additions to kliegs notes.txt are marked with //*


This document was created using VIM 6.2 (www.vim.org).


===============================================================================
End of File
===============================================================================


Maddox

First you'll need to open the file and read in the header. Depending on the the sizes give in the header you'll read in the compressed data and uncompress it using a vb port of the zlib compression library.

After that you're free to extract whatever data you need.
asdf.

phvckmeh

Quote from: Maddox on July 30, 2004, 02:43 AM
First you'll need to open the file and read in the header. Depending on the the sizes give in the header you'll read in the compressed data and uncompress it using a vb port of the zlib compression library.

After that you're free to extract whatever data you need.
ok thanks i found that ocx, i just dont know which way to open it, if you could provide help or an example it would be much appreaciated, as i am really eager to write a replay program!

Maddox

It's the same way you add any OCX to a project.
asdf.

phvckmeh

i understand adding the ocx, i dont understand exactly how to "open" the warcraft replay file.

Stealth

#5

Dim f as Integer
f = FreeFile

Open "C:\replays\myreplay.w3g" For Binary Access Read As #f
   ' ... read
Close #f


A seemingly very detailed tutorial on using Binary Access
- Stealth
Author of StealthBot

Adron

Quote from: phvckmeh on July 30, 2004, 02:03 AM

Neither reverse engineering was used


Liars... Of course they were reverse engineering - what else would they be doing?

phvckmeh

#7

Dim f As Integer
Dim filepath As String

filepath = BrowseForFolder("Select a replay to upload", , Warcraft_GetPath & "Replay\", , True)

f = FreeFile

Open getshortname(filepath) For Binary Access Read As #f
MsgBox f

Close #f


f =1 when i load a valid replay....

here is my module

Option Explicit

Private Const MAX_PATH = 260

Private Type BrowseInfo
 hWndOwner      As Long
 pIDLRoot       As Long
 pszDisplayName As Long
 lpszTitle      As Long
 ulFlags        As Long
 lpfnCallback   As Long
 lParam         As Long
 iImage         As Long
End Type

Private Type SHITEMID
   cb As Long
   abID As Byte
End Type

Private Type ITEMIDLIST
   mkid As SHITEMID
End Type

Private Const WM_USER = &H400
Private Const BFFM_INITIALIZED = 1
Private Const BFFM_SELCHANGED = 2
Private Const BFFM_SETSTATUSTEXT = (WM_USER + 100)
Private Const BFFM_SETSELECTION = (WM_USER + 102)

Private Declare Function PathIsDirectory Lib "shlwapi.dll" Alias "PathIsDirectoryA" (ByVal pszPath As String) As Long
Private Declare Function SHBrowseForFolder Lib "shell32.dll" (lpbi As BrowseInfo) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32.dll" (ByVal pidList As Long, ByVal lpBuffer As String) As Long
Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal hMem As Long)
Private Declare Function lstrcat Lib "kernel32.dll" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal HWND As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private Declare Function SHParseDisplayName Lib "shell32.dll" (ByVal pszName As Long, ByVal pbc As Long, ByRef ppidl As Long, ByVal sfgaoIn As Long, ByRef psfgaoOut As Long) As Long
Private Declare Function SHGetSpecialFolderLocation Lib "shell32.dll" (ByVal hWndOwner As Long, ByVal nFolder As Long, pidl As ITEMIDLIST) As Long

Private m_CurrentDirectory As String

Public Declare Function GetShortPathName Lib "kernel32" _
   Alias "GetShortPathNameA" _
   (ByVal lpszLongPath As String, _
   ByVal lpszShortPath As String, _
   ByVal cchBuffer As Long) As Long

Public Function GetShortName(sFile As String) As String
   Dim sShortFile As String * 67
   Dim lResult As Long

   'Make a call to the GetShortPathName API
   lResult = GetShortPathName(sFile, sShortFile, _
   Len(sShortFile))

   'Trim out unused characters from the string.
   GetShortName = Left$(sShortFile, lResult)

End Function
Private Function GetAddressofFunction(add As Long) As Long
 GetAddressofFunction = add
End Function

Private Function BrowseCallbackProc(ByVal HWND As Long, ByVal uMsg As Long, ByVal lp As Long, ByVal pData As Long) As Long
 On Local Error Resume Next
 Dim lpIDList As Long
 Dim ret As Long
 Dim sBuffer As String
 Select Case uMsg
   Case BFFM_INITIALIZED
     SendMessage HWND, BFFM_SETSELECTION, 1, m_CurrentDirectory
   Case BFFM_SELCHANGED
     sBuffer = Space(MAX_PATH)
     ret = SHGetPathFromIDList(lp, sBuffer)
     If ret = 1 Then
       SendMessage HWND, BFFM_SETSTATUSTEXT, 0, sBuffer
     End If
 End Select
 BrowseCallbackProc = 0
End Function

Public Function BrowseForFolder(Optional ByVal Title As String = "", Optional ByVal RootDir As String = "", Optional ByVal StartDir As String = "", Optional owner As Form = Nothing, Optional IncludeFiles As Boolean = False) As String
 Const BIF_STATUSTEXT = &H4
 Const BIF_RETURNONLYFSDIRS = &H1
 Const BIF_BROWSEINCLUDEFILES = &H4000
 Dim lpIDList As Long, lpIDList2 As Long, IDL As ITEMIDLIST
 Dim sBuffer As String, tBrowseInfo As BrowseInfo, r As Long
 If Len(RootDir) > 0 Then
   If PathIsDirectory(RootDir) Then
     SHParseDisplayName StrPtr(RootDir), ByVal 0&, lpIDList2, ByVal 0&, ByVal 0&
     tBrowseInfo.pIDLRoot = lpIDList2
   Else
     r = SHGetSpecialFolderLocation(ByVal 0&, &H11, IDL)
     If r = 0 Then tBrowseInfo.pIDLRoot = IDL.mkid.cb
   End If
 Else
   r = SHGetSpecialFolderLocation(ByVal 0&, &H11, IDL)
   If r = 0 Then tBrowseInfo.pIDLRoot = IDL.mkid.cb
 End If
 If Len(StartDir) > 0 Then
   m_CurrentDirectory = StartDir & vbNullChar
 Else
   m_CurrentDirectory = vbNullChar
 End If
 If Len(Title) > 0 Then
   tBrowseInfo.lpszTitle = lstrcat(Title, "")
 Else
   tBrowseInfo.lpszTitle = lstrcat("Select A Directory", "")
 End If
 tBrowseInfo.lpfnCallback = GetAddressofFunction(AddressOf BrowseCallbackProc)
 If IncludeFiles = True Then
   tBrowseInfo.ulFlags = BIF_STATUSTEXT + BIF_RETURNONLYFSDIRS + BIF_BROWSEINCLUDEFILES
 Else
   tBrowseInfo.ulFlags = BIF_STATUSTEXT + BIF_RETURNONLYFSDIRS
 End If
 If Not (owner Is Nothing) Then tBrowseInfo.hWndOwner = owner.HWND
 lpIDList = SHBrowseForFolder(tBrowseInfo)
 If Len(RootDir) > 0 Then
   If PathIsDirectory(RootDir) Then CoTaskMemFree lpIDList2
 End If
 If (lpIDList) Then
   sBuffer = Space(MAX_PATH)
   SHGetPathFromIDList lpIDList, sBuffer
   CoTaskMemFree lpIDList
   sBuffer = Left(sBuffer, InStr(sBuffer, vbNullChar) - 1)
   BrowseForFolder = sBuffer
 Else
   BrowseForFolder = ""
 End If
End Function

Public Function Warcraft_GetPath() As String
   Dim Sh, Path$
   Set Sh = CreateObject("WScript.Shell")
   Path = Sh.regread("HKEY_CURRENT_USER\Software\Blizzard Entertainment\Warcraft III\InstallPath")
   If Right(Path, 1) <> "\" Then Path = Path & "\"
   Warcraft_GetPath = Path
End Function


phvckmeh

#9
omg i still have no clue how to start :P


CommonDialog1.InitDir = Warcraft_GetPath & "replay\"
CommonDialog1.Action = 1
   If Right(LCase(CommonDialog1.filename), 4) <> ".w3g" Then
       MsgBox "Invalid Replay File!", vbCritical, Me.Caption & " - Error"
       End
   End If
   
Dim buffer As String
Dim i As Integer
Dim temp

Open CommonDialog1.filename For Binary Access Read As #1

buffer = Space$(LOF(1))
Get #1, , buffer

temp = Split(buffer, vbCrLf)

For i = 1 To UBound(temp)
   Text1.Text = Text1.Text & temp(i)
Next



i either get nothing or some garbled crap