void cWSSAnvil::CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length) { int Child = a_NBT.FindChildByName(a_Tag, a_ChildName); if ((Child >= 0) && (a_NBT.GetType(Child) == TAG_ByteArray) && (a_NBT.GetDataLength(Child) == a_Length)) { memcpy(a_Destination, a_NBT.GetData(Child), a_Length); } }
void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas) { if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_List)) { return; } for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child)) { if (a_NBT.GetType(Child) != TAG_Compound) { continue; } int sID = a_NBT.FindChildByName(Child, "id"); if (sID < 0) { continue; } if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0) { LoadChestFromNBT(a_BlockEntities, a_NBT, Child); } else if (strncmp(a_NBT.GetData(sID), "Dropper", a_NBT.GetDataLength(sID)) == 0) { LoadDropperFromNBT(a_BlockEntities, a_NBT, Child); } else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0) { LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child, a_BlockTypes, a_BlockMetas); } else if (strncmp(a_NBT.GetData(sID), "Hopper", a_NBT.GetDataLength(sID)) == 0) { LoadHopperFromNBT(a_BlockEntities, a_NBT, Child); } else if (strncmp(a_NBT.GetData(sID), "Music", a_NBT.GetDataLength(sID)) == 0) { LoadNoteFromNBT(a_BlockEntities, a_NBT, Child); } else if (strncmp(a_NBT.GetData(sID), "RecordPlayer", a_NBT.GetDataLength(sID)) == 0) { LoadJukeboxFromNBT(a_BlockEntities, a_NBT, Child); } else if (strncmp(a_NBT.GetData(sID), "Sign", a_NBT.GetDataLength(sID)) == 0) { LoadSignFromNBT(a_BlockEntities, a_NBT, Child); } else if (strncmp(a_NBT.GetData(sID), "Trap", a_NBT.GetDataLength(sID)) == 0) { LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child); } // TODO: Other block entities } // for Child - tag children }
void cWSSAnvil::LoadEntitiesFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_List)) { return; } for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child)) { if (a_NBT.GetType(Child) != TAG_Compound) { continue; } int sID = a_NBT.FindChildByName(Child, "id"); if (sID < 0) { continue; } LoadEntityFromNBT(a_Entities, a_NBT, Child, a_NBT.GetData(sID), a_NBT.GetDataLength(sID)); } // for Child - a_NBT[] }
bool cBlockArea::LoadFromSchematicNBT(cParsedNBT & a_NBT) { int TMaterials = a_NBT.FindChildByName(a_NBT.GetRoot(), "Materials"); if ((TMaterials > 0) && (a_NBT.GetType(TMaterials) == TAG_String)) { AString Materials = a_NBT.GetString(TMaterials); if (Materials.compare("Alpha") != 0) { LOG("Materials tag is present and \"%s\" instead of \"Alpha\". Possibly a wrong-format schematic file.", Materials.c_str()); return false; } } int TSizeX = a_NBT.FindChildByName(a_NBT.GetRoot(), "Width"); int TSizeY = a_NBT.FindChildByName(a_NBT.GetRoot(), "Height"); int TSizeZ = a_NBT.FindChildByName(a_NBT.GetRoot(), "Length"); if ( (TSizeX < 0) || (TSizeY < 0) || (TSizeZ < 0) || (a_NBT.GetType(TSizeX) != TAG_Short) || (a_NBT.GetType(TSizeY) != TAG_Short) || (a_NBT.GetType(TSizeZ) != TAG_Short) ) { LOG("Dimensions are missing from the schematic file (%d, %d, %d), (%d, %d, %d)", TSizeX, TSizeY, TSizeZ, a_NBT.GetType(TSizeX), a_NBT.GetType(TSizeY), a_NBT.GetType(TSizeZ) ); return false; } int SizeX = a_NBT.GetShort(TSizeX); int SizeY = a_NBT.GetShort(TSizeY); int SizeZ = a_NBT.GetShort(TSizeZ); if ((SizeX < 1) || (SizeY < 1) || (SizeZ < 1)) { LOG("Dimensions are invalid in the schematic file: %d, %d, %d", SizeX, SizeY, SizeZ); return false; } int TBlockTypes = a_NBT.FindChildByName(a_NBT.GetRoot(), "Blocks"); int TBlockMetas = a_NBT.FindChildByName(a_NBT.GetRoot(), "Data"); if ((TBlockTypes < 0) || (a_NBT.GetType(TBlockTypes) != TAG_ByteArray)) { LOG("BlockTypes are invalid in the schematic file: %d", TBlockTypes); return false; } bool AreMetasPresent = (TBlockMetas > 0) && (a_NBT.GetType(TBlockMetas) == TAG_ByteArray); Clear(); SetSize(SizeX, SizeY, SizeZ, AreMetasPresent ? (baTypes | baMetas) : baTypes); // Copy the block types and metas: int NumBytes = m_SizeX * m_SizeY * m_SizeZ; if (a_NBT.GetDataLength(TBlockTypes) < NumBytes) { LOG("BlockTypes truncated in the schematic file (exp %d, got %d bytes). Loading partial.", NumBytes, a_NBT.GetDataLength(TBlockTypes) ); NumBytes = a_NBT.GetDataLength(TBlockTypes); } memcpy(m_BlockTypes, a_NBT.GetData(TBlockTypes), NumBytes); if (AreMetasPresent) { int NumBytes = m_SizeX * m_SizeY * m_SizeZ; if (a_NBT.GetDataLength(TBlockMetas) < NumBytes) { LOG("BlockMetas truncated in the schematic file (exp %d, got %d bytes). Loading partial.", NumBytes, a_NBT.GetDataLength(TBlockMetas) ); NumBytes = a_NBT.GetDataLength(TBlockMetas); } memcpy(m_BlockMetas, a_NBT.GetData(TBlockMetas), NumBytes); } return true; }
bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) { int Data = a_NBT.FindChildByName(0, "data"); if (Data < 0) { return false; } int CurrLine = a_NBT.FindChildByName(Data, "scale"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Byte)) { unsigned int Scale = (unsigned int)a_NBT.GetByte(CurrLine); m_Map->SetScale(Scale); } CurrLine = a_NBT.FindChildByName(Data, "dimension"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Byte)) { eDimension Dimension = (eDimension) a_NBT.GetByte(CurrLine); if (Dimension != m_Map->m_World->GetDimension()) { // TODO 2014-03-20 xdot: We should store nether maps in nether worlds, e.t.c. return false; } } CurrLine = a_NBT.FindChildByName(Data, "width"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Short)) { unsigned int Width = (unsigned int)a_NBT.GetShort(CurrLine); if (Width != 128) { return false; } m_Map->m_Width = Width; } CurrLine = a_NBT.FindChildByName(Data, "height"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Short)) { unsigned int Height = (unsigned int)a_NBT.GetShort(CurrLine); if (Height >= 256) { return false; } m_Map->m_Height = Height; } CurrLine = a_NBT.FindChildByName(Data, "xCenter"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Int)) { int CenterX = a_NBT.GetInt(CurrLine); m_Map->m_CenterX = CenterX; } CurrLine = a_NBT.FindChildByName(Data, "zCenter"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Int)) { int CenterZ = a_NBT.GetInt(CurrLine); m_Map->m_CenterZ = CenterZ; } unsigned int NumPixels = m_Map->GetNumPixels(); m_Map->m_Data.resize(NumPixels); CurrLine = a_NBT.FindChildByName(Data, "colors"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_ByteArray)) { memcpy(m_Map->m_Data.data(), a_NBT.GetData(CurrLine), NumPixels); } return true; }
void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type) { if (a_TagIdx < 0) { return; } switch (a_Type) { case E_ITEM_FIREWORK_STAR: { for (int explosiontag = a_NBT.GetFirstChild(a_TagIdx); explosiontag >= 0; explosiontag = a_NBT.GetNextSibling(explosiontag)) { eTagType TagType = a_NBT.GetType(explosiontag); if (TagType == TAG_Byte) // Custon name tag { AString ExplosionName = a_NBT.GetName(explosiontag); if (ExplosionName == "Flicker") { a_FireworkItem.m_HasFlicker = (a_NBT.GetByte(explosiontag) == 1); } else if (ExplosionName == "Trail") { a_FireworkItem.m_HasTrail = (a_NBT.GetByte(explosiontag) == 1); } else if (ExplosionName == "Type") { a_FireworkItem.m_Type = a_NBT.GetByte(explosiontag); } } else if (TagType == TAG_IntArray) { AString ExplosionName = a_NBT.GetName(explosiontag); if (ExplosionName == "Colors") { // Divide by four as data length returned in bytes int DataLength = a_NBT.GetDataLength(explosiontag); // round to the next highest multiple of four DataLength -= DataLength % 4; if (DataLength == 0) { continue; } const char * ColourData = (a_NBT.GetData(explosiontag)); for (int i = 0; i < DataLength; i += 4 /* Size of network int*/) { a_FireworkItem.m_Colours.push_back(GetBEInt(ColourData + i)); } } else if (ExplosionName == "FadeColors") { int DataLength = a_NBT.GetDataLength(explosiontag) / 4; // round to the next highest multiple of four DataLength -= DataLength % 4; if (DataLength == 0) { continue; } const char * FadeColourData = (a_NBT.GetData(explosiontag)); for (int i = 0; i < DataLength; i += 4 /* Size of network int*/) { a_FireworkItem.m_FadeColours.push_back(GetBEInt(FadeColourData + i)); } } } } break; } case E_ITEM_FIREWORK_ROCKET: { for (int fireworkstag = a_NBT.GetFirstChild(a_TagIdx); fireworkstag >= 0; fireworkstag = a_NBT.GetNextSibling(fireworkstag)) { eTagType TagType = a_NBT.GetType(fireworkstag); if (TagType == TAG_Byte) // Custon name tag { if (a_NBT.GetName(fireworkstag) == "Flight") { a_FireworkItem.m_FlightTimeInTicks = a_NBT.GetByte(fireworkstag) * 20; } } else if ((TagType == TAG_List) && (a_NBT.GetName(fireworkstag) == "Explosions")) { int ExplosionsChild = a_NBT.GetFirstChild(fireworkstag); if ((a_NBT.GetType(ExplosionsChild) == TAG_Compound) && (a_NBT.GetName(ExplosionsChild).empty())) { ParseFromNBT(a_FireworkItem, a_NBT, ExplosionsChild, E_ITEM_FIREWORK_STAR); } } } break; } default: ASSERT(!"Unhandled firework item!"); break; } }
bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cParsedNBT & a_NBT) { int TMaterials = a_NBT.FindChildByName(a_NBT.GetRoot(), "Materials"); if ((TMaterials > 0) && (a_NBT.GetType(TMaterials) == TAG_String)) { AString Materials = a_NBT.GetString(TMaterials); if (Materials.compare("Alpha") != 0) { LOG("Materials tag is present and \"%s\" instead of \"Alpha\". Possibly a wrong-format schematic file.", Materials.c_str()); return false; } } int TSizeX = a_NBT.FindChildByName(a_NBT.GetRoot(), "Width"); int TSizeY = a_NBT.FindChildByName(a_NBT.GetRoot(), "Height"); int TSizeZ = a_NBT.FindChildByName(a_NBT.GetRoot(), "Length"); if ( (TSizeX < 0) || (TSizeY < 0) || (TSizeZ < 0) || (a_NBT.GetType(TSizeX) != TAG_Short) || (a_NBT.GetType(TSizeY) != TAG_Short) || (a_NBT.GetType(TSizeZ) != TAG_Short) ) { LOG("Dimensions are missing from the schematic file (%d, %d, %d), (%d, %d, %d)", TSizeX, TSizeY, TSizeZ, (TSizeX >= 0) ? a_NBT.GetType(TSizeX) : -1, (TSizeY >= 0) ? a_NBT.GetType(TSizeY) : -1, (TSizeZ >= 0) ? a_NBT.GetType(TSizeZ) : -1 ); return false; } int SizeX = a_NBT.GetShort(TSizeX); int SizeY = a_NBT.GetShort(TSizeY); int SizeZ = a_NBT.GetShort(TSizeZ); if ((SizeX < 1) || (SizeX > 65535) || (SizeY < 1) || (SizeY > cChunkDef::Height) || (SizeZ < 1) || (SizeZ > 65535)) { LOG("Dimensions are invalid in the schematic file: %d, %d, %d", SizeX, SizeY, SizeZ); return false; } int TBlockTypes = a_NBT.FindChildByName(a_NBT.GetRoot(), "Blocks"); int TBlockMetas = a_NBT.FindChildByName(a_NBT.GetRoot(), "Data"); if ((TBlockTypes < 0) || (a_NBT.GetType(TBlockTypes) != TAG_ByteArray)) { LOG("BlockTypes are invalid in the schematic file: %d", TBlockTypes); return false; } bool AreMetasPresent = (TBlockMetas > 0) && (a_NBT.GetType(TBlockMetas) == TAG_ByteArray); a_BlockArea.Clear(); a_BlockArea.SetSize(SizeX, SizeY, SizeZ, AreMetasPresent ? (cBlockArea::baTypes | cBlockArea::baMetas) : cBlockArea::baTypes); int TOffsetX = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetX"); int TOffsetY = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetY"); int TOffsetZ = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetZ"); if ( (TOffsetX < 0) || (TOffsetY < 0) || (TOffsetZ < 0) || (a_NBT.GetType(TOffsetX) != TAG_Int) || (a_NBT.GetType(TOffsetY) != TAG_Int) || (a_NBT.GetType(TOffsetZ) != TAG_Int) ) { // Not every schematic file has an offset, so we shoudn't give a warn message. a_BlockArea.SetWEOffset(0, 0, 0); } else { a_BlockArea.SetWEOffset(a_NBT.GetInt(TOffsetX), a_NBT.GetInt(TOffsetY), a_NBT.GetInt(TOffsetZ)); } // Copy the block types and metas: size_t NumTypeBytes = a_BlockArea.GetBlockCount(); if (a_NBT.GetDataLength(TBlockTypes) < NumTypeBytes) { LOG("BlockTypes truncated in the schematic file (exp %u, got %u bytes). Loading partial.", static_cast<unsigned>(NumTypeBytes), static_cast<unsigned>(a_NBT.GetDataLength(TBlockTypes)) ); NumTypeBytes = a_NBT.GetDataLength(TBlockTypes); } memcpy(a_BlockArea.GetBlockTypes(), a_NBT.GetData(TBlockTypes), NumTypeBytes); if (AreMetasPresent) { size_t NumMetaBytes = a_BlockArea.GetBlockCount(); if (a_NBT.GetDataLength(TBlockMetas) < NumMetaBytes) { LOG("BlockMetas truncated in the schematic file (exp %u, got %u bytes). Loading partial.", static_cast<unsigned>(NumMetaBytes), static_cast<unsigned>(a_NBT.GetDataLength(TBlockMetas)) ); NumMetaBytes = a_NBT.GetDataLength(TBlockMetas); } memcpy(a_BlockArea.GetBlockMetas(), a_NBT.GetData(TBlockMetas), NumMetaBytes); } return true; }