The war3map.w3c file contains cameras created in the world editor's camera palette. Since patch 1.31, cameras can have local rotations (pitch, yaw, roll). Additionally, since 1.30, a camera can also have a near clipping plane.
In both cases, blizzard decided in their unmatched wisdom to not change the file's format version. As a result, trying to open and old version of this file in patch 1.31 or later, the world editor will incorrectly parse the data. The near clipping plane shouldn't be an issue here, since even in old patches there was already some sort of placeholder value in the file format that was usually set to 100 (although the default value for the near clipping plane is 16). However, the local pitch, local yaw, and local roll require an additional 12 bytes.
So how does the world editor deal with parsing this file if it was created in an older patch? Well... it simply doesn't. It will just assume the file is in the new format. Here's how that looks:
Again, this could all be prevented if blizzard simply changed the format version from 0 to... I don't know... 1? Maybe 2 if they updated the format for patch 1.30 as well.
So, how can we properly parse this file format, knowing that we cannot rely on a format version to know if we're reading an old or new format file? There are basically four ways:
The other three approaches appear to work correctly for all the files I've tried. Of course, there may be examples for which it's impossible to know if the file was created in the old or new file format.
The simplest example is a file with a single camera, which has a name of at least 13 characters, where the first 12 characters can be parsed as three floats, and the 13th character is not a whitespace character.
Another issue that applies to the first two approaches is that some cameras may be parsed in the old format, while others are parsed in the new format. With the last two approaches, you at least know for certain that all cameras will be parsed in the same format.
Of the third and fourth approaches, I'd probably prefer the fourth personally, since in that case you can also run into an end of stream exception, which is an indication that the file is in the old format (or that the file is corrupt). Something similar can be done for the third approach, by checking that there are exactly zero bytes left to be read in the stream after all cameras have been parsed. Although I haven't seen any examples of war3map.w3c files where this is the case, there are other war3map files where I have seen useless bytes are added to the end of the stream, so I find that approach less reliable than when you simply run into an exception.
In both cases, blizzard decided in their unmatched wisdom to not change the file's format version. As a result, trying to open and old version of this file in patch 1.31 or later, the world editor will incorrectly parse the data. The near clipping plane shouldn't be an issue here, since even in old patches there was already some sort of placeholder value in the file format that was usually set to 100 (although the default value for the near clipping plane is 16). However, the local pitch, local yaw, and local roll require an additional 12 bytes.
So how does the world editor deal with parsing this file if it was created in an older patch? Well... it simply doesn't. It will just assume the file is in the new format. Here's how that looks:
Again, this could all be prevented if blizzard simply changed the format version from 0 to... I don't know... 1? Maybe 2 if they updated the format for patch 1.30 as well.
So, how can we properly parse this file format, knowing that we cannot rely on a format version to know if we're reading an old or new format file? There are basically four ways:
- For every camera, try reading the local rotations, and if invalid, read the camera name string.
- For every camera, try reading the camera name string, and if invalid, read the local rotations.
- Read the entire file as if it's in the old format, and if any invalid data is found, read it in the new format.
- Read the entire file as if it's in the new format, and if any invalid data is found, read it in the old format.
The other three approaches appear to work correctly for all the files I've tried. Of course, there may be examples for which it's impossible to know if the file was created in the old or new file format.
The simplest example is a file with a single camera, which has a name of at least 13 characters, where the first 12 characters can be parsed as three floats, and the 13th character is not a whitespace character.
Another issue that applies to the first two approaches is that some cameras may be parsed in the old format, while others are parsed in the new format. With the last two approaches, you at least know for certain that all cameras will be parsed in the same format.
Of the third and fourth approaches, I'd probably prefer the fourth personally, since in that case you can also run into an end of stream exception, which is an indication that the file is in the old format (or that the file is corrupt). Something similar can be done for the third approach, by checking that there are exactly zero bytes left to be read in the stream after all cameras have been parsed. Although I haven't seen any examples of war3map.w3c files where this is the case, there are other war3map files where I have seen useless bytes are added to the end of the stream, so I find that approach less reliable than when you simply run into an exception.