Convert Minecraft server world files into MCserver world files.
#41
The NBT stuff is a tree, and therefore recursive, so it might be easiest to create functions for each label type in the NBT data (like I did in my parser).

I think you can use my parser just fine, I'm not sure though.
The constructor of the cNBTData class takes a pointer to the beginning of the COMPRESSED NBT data, and the length of the data. After you created an instance of cNBTData you call Decompress() on it and then ParseData(), if you want to see if the data has been parsed correctly you can call PrintData(), and it will recursively print all the data to the console.

My parser misses the Byte array tag though, since that didn't exist when I wrote it, so you'd have to add itTongue

On a side note, I designed my parser in a strange way lol, I never created a parser for anything before and this was my first attempt. It works, but it's unconventional
Reply
Thanks given by:
#42
(10-30-2011, 11:00 AM)FakeTruth Wrote: The NBT stuff is a tree, and therefore recursive, so it might be easiest to create functions for each label type in the NBT data (like I did in my parser).

I think you can use my parser just fine, I'm not sure though.
The constructor of the cNBTData class takes a pointer to the beginning of the COMPRESSED NBT data, and the length of the data. After you created an instance of cNBTData you call Decompress() on it and then ParseData(), if you want to see if the data has been parsed correctly you can call PrintData(), and it will recursively print all the data to the console.

My parser misses the Byte array tag though, since that didn't exist when I wrote it, so you'd have to add itTongue

On a side note, I designed my parser in a strange way lol, I never created a parser for anything before and this was my first attempt. It works, but it's unconventional


Unconventional? Sounds fun!Big Grin


Here's an error I got:

ret != Z_STREAM_END
WARNING: NBT Data received was too big! (More than 2048 bytes)


here's the code:

cNBTData* NBTData = new cNBTData::cNBTData(temparr, compdlength);
NBTData->Decompress();



The compressed data can definitely get larger than that, is there an easy way to fix this?
Reply
Thanks given by:
#43
Easiest way is to increase MAXNBTSIZE. A more difficult way is to refactor that piece of code and allow an arbitrary amount of data. If you can't figure it out I'll do it, but increasing MAXNBTSIZE to 200000 or something should at least fix that error
Reply
Thanks given by:
#44
Increasing MAXNBTSIZE was the first thing I tried. The char array is definitely smaller than the MAXNBTSIZE I set. I changed m_bDecompressed = true; at the beginning of cNBTData.cpp, and gave it the uncompressed char array and the DestSize. I was able to get the parser to print after parsing, but it told me about the unknown tag. After adding the tag I'm now coming u with a segmentation error. I'm not sure if it's because of an error in the tag I added or because now that the parser is doing something more it is running out of room in a variable of a set size somewhere.

The compression method used in alpha was different than the compression method used now (I ran across that problem with the PHP based NBT parser), so I'm not sure that your parser can read the compressed information.
Reply
Thanks given by:
#45
You might want to print all the data it parses and the tags it finds to figure out where and when it segfaults
Reply
Thanks given by:
#46
It's segfaulting at a tag value roughly the same size as DestSize. Doubling the value of DestSize move the segfault about twice the distance down.

I'll try quadrupling it
Reply
Thanks given by:
#47
I took a look at what you committed, and you added TAG_ByteArray somewhere in the middle of the enum declaration. All values in enums are the previous+1 unless specified otherwise, so all enum values are shifted now. All tags have a specific value that are compared with the values in NBT data which means you kinda messed it up :p you need to find the value of TAG_ByteArray and add it to the enum list in the correct place.
Reply
Thanks given by:
#48
Ohhhhhh, I wondered where it knew to get the tag numbers from.

I fixed the tag number and recompiled. As soon as the server's net connection stops spazzing out I'll test it again.


Segfault with normal DestSize, I'll try doubling it again.


Getting segfault with DestSize * 2 and DestSize * 10 at the same location, but at a different location than the normal DestSize.

DestSize:

Code:
82357 00   0
82358 00   0
82359 00   0
ParseTags idx:00 0a  10

OPEN COMPOUND:
ParseTags idx:03 0a  10

OPEN COMPOUND: Level
ParseTags idx:11 07   7
STRING: Data ()
ParseTags idx:20 40  64 @
Segmentation fault


for DestSize times 2 and times 10:
Code:
133987 00   0
133988 00   0
133989 00   0
133990 00   0
133991 00   0
133992 00   0
133993 00   0
133994 00   0
133995 00   0
133996 00   0
133997 00   0
133998 00   0
133999 00   0
Segmentation fault
Reply
Thanks given by:
#49
Hmm, I think that's just some kind of buffer overrun.

Code:
for(unsigned int i = 0; i < m_BufferSize; i++) {//re
     printf("%02i %02x %3i %c\n", i, (unsigned char)m_Buffer[i], (unsigned char)m_Buffer[i], m_Buffer[i] );//re
}

With m_BufferSize being artificially increased it couldn't have been printing data that was in the array.

Placing a return; under that bit of code still printed the numbers, but I didn't get the segfault.


The problem is happening when it tries to parse data tag 7.. The fault is happening on the first bit of data in the new tag I put in. I'm looking into a fix now
Reply
Thanks given by:
#50
I figured out quite a bit and am now successfully parsing the data.

I changed tag 7 to a char array and added tag 4 as a long. I can call data like the xPos like this:

Code:
printf("xPos: %i", NBTData->cNBTCompound::GetInteger("xPos") );
//will print
//xPos: 0


Trying to do anything with the arrays I made won't work though:
NBTData->cNBTCompound::GetByteArray("Blocks")[0]
calls a segmentation fault, but I can clearly see the ParseByteArray function loads the data into the array it passes to PutByteArray.

Code:
printf("VALUE: %s First 5 Chars: (%i,%i,%i,%i,%i)\n", Name.c_str(), ByteArray[0],ByteArray[1],ByteArray[2],ByteArray[3],ByteArray[4] );

prints the correct values

I'm stumped at this point. I'd imagine I can make this program work by using a publicly declared array and filling the arrays I want based on the data names, but I'd like to try and get NBTData->cNBTCompound::GetByteArray("Blocks") working if I can.

Any help and advice is always will be appreciated. Big Grin

printing of the data looks like this. It is missing the new tag I put in. I'm not sure why, but I haven't really look yet.
Code:
Tag End==== STRUCTURED NBT DATA ====
COMPOUND ( )
     COMPOUND
         COMPOUND (Level)
            LIST (Entities)
            LIST (TileEntities)
            INTEGER LastUpdate (0)
            INTEGER xPos (0)
            INTEGER zPos (0)
            BYTE TerrainPopulated (1)
=============================

Newest changes are here:
http://code.google.com/p/mc-server/source/detail?r=26
Reply
Thanks given by:




Users browsing this thread: 6 Guest(s)