bool cWSSAnvil::GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z) { int x = a_NBT.FindChildByName(a_TagIdx, "x"); if ((x < 0) || (a_NBT.GetType(x) != TAG_Int)) { return false; } int y = a_NBT.FindChildByName(a_TagIdx, "y"); if ((y < 0) || (a_NBT.GetType(y) != TAG_Int)) { return false; } int z = a_NBT.FindChildByName(a_TagIdx, "z"); if ((z < 0) || (a_NBT.GetType(z) != TAG_Int)) { return false; } a_X = a_NBT.GetInt(x); a_Y = a_NBT.GetInt(y); a_Z = a_NBT.GetInt(z); return true; }
void cWSSAnvil::LoadJukeboxFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) { ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); int x, y, z; if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) { return; } std::auto_ptr<cJukeboxEntity> Jukebox(new cJukeboxEntity(x, y, z, m_World)); int Record = a_NBT.FindChildByName(a_TagIdx, "Record"); if (Record >= 0) { Jukebox->SetRecord(a_NBT.GetInt(Record)); } a_BlockEntities.push_back(Jukebox.release()); }
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; }
bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { int Data = a_NBT.FindChildByName(0, "data"); if (Data < 0) { return false; } int Objectives = a_NBT.FindChildByName(Data, "Objectives"); if (Objectives < 0) { return false; } for (int Child = a_NBT.GetFirstChild(Objectives); Child >= 0; Child = a_NBT.GetNextSibling(Child)) { AString CriteriaName, DisplayName, Name; int CurrLine = a_NBT.FindChildByName(Child, "CriteriaName"); if (CurrLine >= 0) { CriteriaName = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "DisplayName"); if (CurrLine >= 0) { DisplayName = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "Name"); if (CurrLine >= 0) { Name = a_NBT.GetString(CurrLine); } cObjective::eType Type = cObjective::StringToType(CriteriaName); m_ScoreBoard->RegisterObjective(Name, DisplayName, Type); } int PlayerScores = a_NBT.FindChildByName(Data, "PlayerScores"); if (PlayerScores < 0) { return false; } for (int Child = a_NBT.GetFirstChild(PlayerScores); Child >= 0; Child = a_NBT.GetNextSibling(Child)) { AString Name, ObjectiveName; cObjective::Score Score = 0; int CurrLine = a_NBT.FindChildByName(Child, "Score"); if (CurrLine >= 0) { Score = a_NBT.GetInt(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "Name"); if (CurrLine >= 0) { Name = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "Objective"); if (CurrLine >= 0) { ObjectiveName = a_NBT.GetString(CurrLine); } cObjective * Objective = m_ScoreBoard->GetObjective(ObjectiveName); if (Objective) { Objective->SetScore(Name, Score); } } int Teams = a_NBT.FindChildByName(Data, "Teams"); if (Teams < 0) { return false; } for (int Child = a_NBT.GetFirstChild(Teams); Child >= 0; Child = a_NBT.GetNextSibling(Child)) { AString Name, DisplayName, Prefix, Suffix; bool AllowsFriendlyFire = true, CanSeeFriendlyInvisible = false; int CurrLine = a_NBT.FindChildByName(Child, "Name"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_String)) { Name = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "DisplayName"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_String)) { DisplayName = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "Prefix"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_String)) { Prefix = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "Suffix"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_String)) { Suffix = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "AllowFriendlyFire"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Int)) { AllowsFriendlyFire = (a_NBT.GetInt(CurrLine) != 0); } CurrLine = a_NBT.FindChildByName(Child, "SeeFriendlyInvisibles"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Int)) { CanSeeFriendlyInvisible = (a_NBT.GetInt(CurrLine) != 0); } cTeam * Team = m_ScoreBoard->RegisterTeam(Name, DisplayName, Prefix, Suffix); Team->SetFriendlyFire(AllowsFriendlyFire); Team->SetCanSeeFriendlyInvisible(CanSeeFriendlyInvisible); int Players = a_NBT.FindChildByName(Child, "Players"); if (Players < 0) { continue; } for (int ChildB = a_NBT.GetFirstChild(Players); ChildB >= 0; ChildB = a_NBT.GetNextSibling(ChildB)) { Team->AddPlayer(a_NBT.GetString(ChildB)); } } int DisplaySlots = a_NBT.FindChildByName(Data, "DisplaySlots"); if (DisplaySlots < 0) { return false; } int CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_0"); if (CurrLine >= 0) { AString Name = a_NBT.GetString(CurrLine); m_ScoreBoard->SetDisplay(Name, cScoreboard::dsList); } CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_1"); if (CurrLine >= 0) { AString Name = a_NBT.GetString(CurrLine); m_ScoreBoard->SetDisplay(Name, cScoreboard::dsSidebar); } CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_2"); if (CurrLine >= 0) { AString Name = a_NBT.GetString(CurrLine); m_ScoreBoard->SetDisplay(Name, cScoreboard::dsName); } return true; }
void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength) { if (strncmp(a_IDTag, "Boat", a_IDTagLength) == 0) { LoadBoatFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "FallingBlock", a_IDTagLength) == 0) { LoadFallingBlockFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "Minecart", a_IDTagLength) == 0) { // It is a minecart, old style, find out the type: int TypeTag = a_NBT.FindChildByName(a_EntityTagIdx, "Type"); if ((TypeTag < 0) || (a_NBT.GetType(TypeTag) != TAG_Int)) { return; } switch (a_NBT.GetInt(TypeTag)) { case 0: LoadMinecartRFromNBT(a_Entities, a_NBT, a_EntityTagIdx); break; // Rideable minecart case 1: LoadMinecartCFromNBT(a_Entities, a_NBT, a_EntityTagIdx); break; // Minecart with chest case 2: LoadMinecartFFromNBT(a_Entities, a_NBT, a_EntityTagIdx); break; // Minecart with furnace case 3: LoadMinecartTFromNBT(a_Entities, a_NBT, a_EntityTagIdx); break; // Minecart with TNT case 4: LoadMinecartHFromNBT(a_Entities, a_NBT, a_EntityTagIdx); break; // Minecart with Hopper } } else if (strncmp(a_IDTag, "MinecartRideable", a_IDTagLength) == 0) { LoadMinecartRFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "MinecartChest", a_IDTagLength) == 0) { LoadMinecartCFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "MinecartFurnace", a_IDTagLength) == 0) { LoadMinecartFFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "MinecartTNT", a_IDTagLength) == 0) { LoadMinecartTFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "MinecartHopper", a_IDTagLength) == 0) { LoadMinecartHFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "Item", a_IDTagLength) == 0) { LoadPickupFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "Arrow", a_IDTagLength) == 0) { LoadArrowFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "Snowball", a_IDTagLength) == 0) { LoadSnowballFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "Egg", a_IDTagLength) == 0) { LoadEggFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "Fireball", a_IDTagLength) == 0) { LoadFireballFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "SmallFireball", a_IDTagLength) == 0) { LoadFireChargeFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } else if (strncmp(a_IDTag, "ThrownEnderpearl", a_IDTagLength) == 0) { LoadThrownEnderpearlFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } // TODO: other entities }
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; }