-
Notifications
You must be signed in to change notification settings - Fork 8
WZ Format
WZ files are the 'filesystem' files of the game MapleStory. They contain Directory
s and Object
s entries. Objects
on the Directory
level are always Property
s. Setting them to a different kind of Object
is undefined.
Originally Wizet had plain .img
files (serialized Object
s) on the filesystem, built in a tree structure, with all having a main directory name (such as Character, Map, Etc and String).
At some point in time, Wizet decided to make files with the extension wz
. These files contains the tree structure and its files.
An other thing they added was the support for encryption. They made List.wz
(that is, ironically, no real wz file at all) with URI's to encrypted strings. If PCOM.dll
finds this file, it'll initialize a list of these strings. This list will be checked everytime a string is being de/encoded. Each string that is 'inside' a URI (that is: a URI inside the list is the prefix of the URI of node of the string), it'll be en/decrypted. This cryptography is pretty weak, as it use a single xor key for all the strings. This key is calculated like the MapleStory packet AES, but with a predefined IV for SEA and GMS.
50 4B 47 31 - "PKG1", file header/identifier
UINT64 - File size
INT32 - Absolute position of WZ content
NULL-TERMINATED STRING - File description, such as 'Package file v1.0 Copyright 2002 Wizet, ZMS'
Note: starts at Absolute position of WZ content
UINT16 - Encrypted version number
Directory - Root directory
Internal name: Package
Directories contain both sub Directory
and Object
s.
Whenever an Object
is found, treat is as one.
WZ-INT - Amount of entries
for i = 0; i < Amount of entries; i++ {
UINT8 - Type (if & 1 then its a Directory, else its an Object)
SERIALIZED-STRING - Name
WZ-INT - Size
WZ-INT - Checksum
WZ-OFFSET - Entry data position in file
}
An Object
is a string (telling which datatype will come) and then the datatype data.
Values using a #
will initialize the DLL before the #
and tries to initialize the COM object with the name after the #
.
These datatypes are supported:
Property
Canvas
Shape2D#Convex2D
Shape2D#Vector2D
UOL
Sound_DX8
SERIALIZED-STRING - Typename
... - The serialized datatype
Contains a list of key-value pairs (map), where the key is a string, and the value is the Variant object.
UINT8 - Unknown, seems to be some identifier for PCOM.dll to read as a BMS config file (ascii), whenever not 0?
UINT8 - Unknown, seems to be unused
WZ-INT - Amount of variants
for i = 0; i < Amount of variants; i++ {
SERIALIZED-STRING - Variant name (node name)
Variant - The variant
}
An object that supports multiple types.
UINT8 - Type
if Type == 0 {
// Object does not contain anything
} else if Type == 2 || Type == 11 {
INT16 - Value
} else if Type == 3 || Type == 19 {
WZ-INT - Value
} else if Type == 20 {
WZ-LONG - Value
} else if Type == 4 {
UINT8 - Flag for set float
if Flag for set float == 0x80 {
FLOAT32 - Value
} else {
// Default value is FLOAT32(0.0)
}
} else if Type == 5 {
FLOAT64 - Value
} else if Type == 8 {
SERIALIZED-STRING - Value
} else if Type == 9 {
// An Object
INT32 - Size
Object - The serialized object (= Value)
}
Internal function name: LoadPos
Note: Only used in Directory
s
This value is pretty weird. It's a UINT32. To calculate the offset, you have to do this:
uint32 currentPos = (current position in wzfile)
uint32 offset = (currentPos - Absolute position of WZ content) ^ 0xFFFFFFFF
offset *= WZ File version hash
offset -= 0x581C3F6D
offset = rotl(offset, (byte)(offset & 0x1F))
uint32 encryptedOffset = ReadUINT32()
offset ^= encryptedOffset
offset += (Absolute position of WZ content) * 2
return offset
Read a signed byte first. If its -128, read INT32. Else, return signed byte as INT32
sbyte possibleSize = ReadINT8()
if (possibleSize == -128) {
return ReadINT32()
} else {
return INT32(possibleSize)
}
Read a signed byte first. If its -128, read INT64. Else, return signed byte as INT64
sbyte possibleSize = ReadINT8()
if (possibleSize == -128) {
return ReadINT64()
} else {
return INT64(possibleSize)
}