Nab on 3/3/2009 at 09:24
I have been tossing around the underworld 2 data files for some time now - mainly according to the file specifications of underworld adventures.
However I cannot read the character information file PLAYER.DAT due to an encryption scheme which still eludes me.
More annoyingly there already is a character editor for uw2 for which the source was never released. So I am looking for the solution of a problem which was solved 15 years ago...
Does anybody know how to read the PLAYER.DAT?
Volca on 3/3/2009 at 10:41
Would (
http://www.bootstrike.com/Ultima/Online/uwformat.html) this help, hopefully?
Code:
The file "player.dat" contains the main character data. The first 220 bytes
are encrypted with a rather simple xor algorithm. The first byte in the
file is the starting xor value. The next byte is xor'ed with xorvalue + 3,
and for each next byte the xorvalue is incremented by 3. A simple
implementation in C is here (it is assumed that xorvalue already contains
the first byte):
// descramble data
unsigned char incrnum = 3;
for(int i=0; i<220; i++)
{
if (i==80) incrnum = 3;
data
^= (xorvalue+incrnum);
incrnum += 3;
}
Nab on 3/3/2009 at 15:24
sadly no.
The encryption has changed from uw1 to uw2 and the snippet you posted works for uw1 only.
well, like I said, there is this one program (uw2edit by robin wöhler) which can be used to load, edit and save the character. Meanwhile I got the algorithm by reverse engineering this little bugger. However the encryption seems to use some magic bytes which I am still hunting down.
Will post again once I'm done. Deriving algorithms from assembly traces is actually fun
Nab on 7/3/2009 at 12:21
uw2-formats.txt in the SVN repository of abysmal engine on sourceforge now contains the decryption algorithm for uw2 PLAYER.DAT
Al_B on 8/3/2009 at 19:16
Good info.
Quote:
Inventory layout:
* seems like some kind of compression is being used
From memory (would have to check) a bit-field format is used for the inventory items (similar to the object format within the level files).
Al_B on 9/3/2009 at 23:41
I've had a quick play with the algorithm and I think I must be missing something. Each save file I've created appears to start with the player name, with the first character XORd with 0xAA.
The document says that a magic seed (i.e. byte 0) of 0x98 results in the first entry in MA of 0xDC. This is easy to reproduce - just create a character with the first letter of their name being "2" (0x32 hex = 0x98^0xAA). However, the doesn't decode this correctly and produces the value 0x44 or "D" instead.
It's probably down to a simple misunderstanding - any pointers welcome.
Nab on 10/3/2009 at 10:16
The very first byte of PLAYER.DAT serves only as the magic seed. The second byte (and the following 15 or so) contain the player name.
If your implementation results in a 0x44, you applied the the magic block to the entire file, including the magic byte. Since the magic block depends entirely on the magic seed, the magic seed would always be deciphered to the same value (0x44).
The first block that you want to decode is 0001-0051.
This is my implementation:
(
http://uw2rev.svn.sourceforge.net/viewvc/uw2rev/trunk/libuw2/libuw2GamePlayer.cpp)
ps. yes there is a memory leak :-)
Al_B on 10/3/2009 at 20:19
Ah - that did it, thanks. Changing the starting index to 1 from 0 worked perfectly (well, I haven't checked the result in detail but it looks reasonable). As I said in my previous post, the seed seems to be first character in the name ^ 0xAA which may be useful during re-encoding. I hadn't realised that the first character is in effect repeated - which was throwing me off.