ChunkMtlName_804
giniedp opened this issue · 7 comments
I'm hitting some chunk materials with version 804 which is currently not implemented.
Some time ago i simply added the following which solved the issue at the time being.
internal sealed class ChunkMtlName_804 : ChunkMtlName
{
public override void Read(BinaryReader b)
{
base.Read(b);
Name = b.ReadFString(128);
NumChildren = 0;
}
}
now, the game client has changed and this does not work any more. At least on some models. I am not sure how to proceed or decode the chunk structure. This is what i've got so far
Chunk Metadata
{
type: 3435921428, // 0xCCCC0014 -> MtlName
version: 2052, // 0x804
id: 2,
size: 78,
offset: 528
}
The byte content is
Int8Array(78) [
123, 56, 53, 67, 67, 50, 52, 67, 69, 45, 68, 52,
49, 53, 45, 53, 50, 67, 66, 45, 66, 53, 57, 48,
45, 69, 66, 68, 56, 67, 57, 57, 52, 65, 48, 52,
50, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, -1, -1, -1, -1,
99, 104, 101, 115, 116, 0
]
The first part is some UUID in curly braces: {85CC24CE-D415-52CB-B590-EBD8C994A042}
The middle part i can not digest
The last part is the actual material name: chest
Any chance this can be properly decoded?
i will try to collect all models with that chunk format to find a solid pattern
Which game is this for? And are there other mtlname chunks in the file?
The game is "New World"
There are no other mtlname chunks, however, there are lots of "UnknownSC1" chunks
I am seeing some success with following
internal sealed class ChunkMtlName_804 : ChunkMtlName
{
public override void Read(BinaryReader b)
{
base.Read(b);
SkipBytes(b, 38); // contains some ID e.g.: {85CC24CE-D415-52CB-B590-EBD8C994A042}
SkipBytes(b, 26); // usually empty bytes
// some count followed by 3 emtpy bytes
var count = b.ReadByte();
SkipBytes(b, 3);
// skip some flags
SkipBytes(b, count * 4);
Name = b.ReadCString();
NumChildren = 0;
}
}
Ok, I think I can see what is happening.
First I have to note, that the result of ChunkMtlName
is not needed for my workflow. I have a patch where i can tell cgf-converter
which material file to use. However, cgf-converter
still needs to read all the chunks and my addition of ChunkMtlName_804
(#165 (comment)) was sufficient.
The error I encountered today was the following
The output char buffer is too small to contain the decoded characters, encoding 'Unicode (UTF-8)' fallback 'System.Text.DecoderReplacementFallback'. (Parameter 'chars')
This made me look into the chunk format.
All ChunkMtlName_804
chunks had the following structure
ID_STRING // e.g. {33099872-8B47-513B-9EE5-49CEDEBD603A}
UNKNOWN // varying length
MATERIAL_NAME
So I thought that the MATERIAL_NAME
was the section i was looking for
However, when I check all the ChunkMtlName_800
chunks, I see the following structure
MATERIAL_FILE_NAME // e.g. male_femininelacelt2_forearms_matgroup
UNKNOWN // varying length
MATERIAL_NAME // e.g. male_FeminineLaceLT2_00_forearms
So the ID_STRING
in the 804
version seems to be an asset ID. This may be either something New World or chunk version specific.
For me, I can fix this with:
internal sealed class ChunkMtlName_804 : ChunkMtlName
{
public override void Read(BinaryReader b)
{
base.Read(b);
- Name = b.ReadFString(128);
+ Name = b.ReadCString(0);
NumChildren = 0;
}
}
Does New World use both 0x0800
and 0x0804
MtlName chunks?
there was a time they used both. I think its the latter for all assets now.
Ish, if they modified the 0x0800
MtlName format, that's going to cause a lot of problems. Those models may only work with the mtl file provided as an argument. I suspect you'd be ok with that though? The material in each submesh is referenced by the index they are found in the mtl file, so as long as the converter doesn't blow up on reading the file, it should still be able to use the correct material.
That work for you?
yeah, for NW i have no other choice as to pass in the material. So not blowing up on reading would be the only thing i actually need here, thx.