Merge branch 'master' into MobSpawner
Conflicts: MCServer/Plugins/Core
This commit is contained in:
@@ -14,7 +14,6 @@ SET (SRCS
|
||||
ScoreboardSerializer.cpp
|
||||
StatSerializer.cpp
|
||||
WSSAnvil.cpp
|
||||
WSSCompact.cpp
|
||||
WorldStorage.cpp)
|
||||
|
||||
SET (HDRS
|
||||
@@ -27,7 +26,6 @@ SET (HDRS
|
||||
ScoreboardSerializer.h
|
||||
StatSerializer.h
|
||||
WSSAnvil.h
|
||||
WSSCompact.h
|
||||
WorldStorage.h)
|
||||
|
||||
if(NOT MSVC)
|
||||
|
||||
@@ -481,7 +481,7 @@ void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart)
|
||||
|
||||
void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
|
||||
{
|
||||
const char * EntityClass = NULL;
|
||||
const char * EntityClass = nullptr;
|
||||
switch (a_Monster->GetMobType())
|
||||
{
|
||||
case mtBat: EntityClass = "Bat"; break;
|
||||
@@ -618,6 +618,28 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
|
||||
m_Writer.AddByte("IsConverting", (((const cZombie *)a_Monster)->IsConverting() ? 1 : 0));
|
||||
break;
|
||||
}
|
||||
case mtInvalidType:
|
||||
case mtBlaze:
|
||||
case mtCaveSpider:
|
||||
case mtChicken:
|
||||
case mtCow:
|
||||
case mtEnderDragon:
|
||||
case mtGhast:
|
||||
case mtGiant:
|
||||
case mtIronGolem:
|
||||
case mtMooshroom:
|
||||
case mtOcelot:
|
||||
case mtPig:
|
||||
case mtSilverfish:
|
||||
case mtSnowGolem:
|
||||
case mtSpider:
|
||||
case mtSquid:
|
||||
case mtWitch:
|
||||
case mtZombiePigman:
|
||||
{
|
||||
// Other mobs have no special tags.
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
@@ -699,21 +721,21 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
|
||||
|
||||
void cNBTChunkSerializer::AddHangingEntity(cHangingEntity * a_Hanging)
|
||||
{
|
||||
m_Writer.AddByte("Direction", (unsigned char)a_Hanging->GetDirection());
|
||||
m_Writer.AddInt("TileX", a_Hanging->GetTileX());
|
||||
m_Writer.AddInt("TileY", a_Hanging->GetTileY());
|
||||
m_Writer.AddInt("TileZ", a_Hanging->GetTileZ());
|
||||
switch (a_Hanging->GetDirection())
|
||||
m_Writer.AddInt("TileX", a_Hanging->GetBlockX());
|
||||
m_Writer.AddInt("TileY", a_Hanging->GetBlockY());
|
||||
m_Writer.AddInt("TileZ", a_Hanging->GetBlockZ());
|
||||
switch (a_Hanging->GetFacing())
|
||||
{
|
||||
case BLOCK_FACE_YM: m_Writer.AddByte("Dir", (unsigned char)2); break;
|
||||
case BLOCK_FACE_YP: m_Writer.AddByte("Dir", (unsigned char)1); break;
|
||||
case BLOCK_FACE_ZM: m_Writer.AddByte("Dir", (unsigned char)0); break;
|
||||
case BLOCK_FACE_ZP: m_Writer.AddByte("Dir", (unsigned char)3); break;
|
||||
case BLOCK_FACE_XM: m_Writer.AddByte("Facing", 1); break;
|
||||
case BLOCK_FACE_XP: m_Writer.AddByte("Facing", 3); break;
|
||||
case BLOCK_FACE_ZM: m_Writer.AddByte("Facing", 2); break;
|
||||
case BLOCK_FACE_ZP: m_Writer.AddByte("Facing", 0); break;
|
||||
|
||||
case BLOCK_FACE_XM:
|
||||
case BLOCK_FACE_XP:
|
||||
case BLOCK_FACE_YM:
|
||||
case BLOCK_FACE_YP:
|
||||
case BLOCK_FACE_NONE:
|
||||
{
|
||||
// These directions are invalid, but they may have been previously loaded, so keep them.
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -754,7 +776,7 @@ void cNBTChunkSerializer::AddItemFrameEntity(cItemFrame * a_ItemFrame)
|
||||
AddBasicEntity(a_ItemFrame, "ItemFrame");
|
||||
AddHangingEntity(a_ItemFrame);
|
||||
AddItem(a_ItemFrame->GetItem(), -1, "Item");
|
||||
m_Writer.AddByte("ItemRotation", (unsigned char)a_ItemFrame->GetRotation());
|
||||
m_Writer.AddByte("ItemRotation", (unsigned char)a_ItemFrame->GetItemRotation());
|
||||
m_Writer.AddFloat("ItemDropChance", 1.0F);
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
@@ -766,7 +788,7 @@ void cNBTChunkSerializer::AddItemFrameEntity(cItemFrame * a_ItemFrame)
|
||||
void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart)
|
||||
{
|
||||
m_Writer.BeginList("Items", TAG_Compound);
|
||||
for (int i = 0; i < cMinecartWithChest::NumSlots; i++)
|
||||
for (int i = 0; i < cMinecartWithChest::ContentsHeight * cMinecartWithChest::ContentsWidth; i++)
|
||||
{
|
||||
const cItem & Item = a_Minecart->GetSlot(i);
|
||||
if (Item.IsEmpty())
|
||||
|
||||
@@ -174,13 +174,13 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
||||
a_Writer.BeginCompound("DisplaySlots");
|
||||
|
||||
cObjective * Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsList);
|
||||
a_Writer.AddString("slot_0", (Objective == NULL) ? "" : Objective->GetName());
|
||||
a_Writer.AddString("slot_0", (Objective == nullptr) ? "" : Objective->GetName());
|
||||
|
||||
Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsSidebar);
|
||||
a_Writer.AddString("slot_1", (Objective == NULL) ? "" : Objective->GetName());
|
||||
a_Writer.AddString("slot_1", (Objective == nullptr) ? "" : Objective->GetName());
|
||||
|
||||
Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsName);
|
||||
a_Writer.AddString("slot_2", (Objective == NULL) ? "" : Objective->GetName());
|
||||
a_Writer.AddString("slot_2", (Objective == nullptr) ? "" : Objective->GetName());
|
||||
|
||||
a_Writer.EndCompound(); // DisplaySlots
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) :
|
||||
#endif // _DEBUG
|
||||
|
||||
gzFile gz = gzopen((FILE_IO_PREFIX + fnam).c_str(), "wb");
|
||||
if (gz != NULL)
|
||||
if (gz != nullptr)
|
||||
{
|
||||
gzwrite(gz, Writer.GetResult().data(), (unsigned)Writer.GetResult().size());
|
||||
}
|
||||
@@ -193,7 +193,7 @@ bool cWSSAnvil::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
cMCAFile * File = LoadMCAFile(a_Chunk);
|
||||
if (File == NULL)
|
||||
if (File == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -208,7 +208,7 @@ bool cWSSAnvil::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Dat
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
cMCAFile * File = LoadMCAFile(a_Chunk);
|
||||
if (File == NULL)
|
||||
if (File == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -234,7 +234,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk)
|
||||
// Is it already cached?
|
||||
for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr)
|
||||
{
|
||||
if (((*itr) != NULL) && ((*itr)->GetRegionX() == RegionX) && ((*itr)->GetRegionZ() == RegionZ))
|
||||
if (((*itr) != nullptr) && ((*itr)->GetRegionX() == RegionX) && ((*itr)->GetRegionZ() == RegionZ))
|
||||
{
|
||||
// Move the file to front and return it:
|
||||
cMCAFile * f = *itr;
|
||||
@@ -253,9 +253,9 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk)
|
||||
cFile::CreateFolder(FILE_IO_PREFIX + FileName);
|
||||
AppendPrintf(FileName, "/r.%d.%d.mca", RegionX, RegionZ);
|
||||
cMCAFile * f = new cMCAFile(FileName, RegionX, RegionZ);
|
||||
if (f == NULL)
|
||||
if (f == nullptr)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
m_Files.push_front(f);
|
||||
|
||||
@@ -373,7 +373,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
||||
// Load the biomes from NBT, if present and valid. First try MCS-style, then Vanilla-style:
|
||||
cChunkDef::BiomeMap BiomeMap;
|
||||
cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "MCSBiomes"));
|
||||
if (Biomes == NULL)
|
||||
if (Biomes == nullptr)
|
||||
{
|
||||
// MCS-style biomes not available, load vanilla-style:
|
||||
Biomes = LoadVanillaBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes"));
|
||||
@@ -426,9 +426,9 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
||||
cSetChunkDataPtr SetChunkData(new cSetChunkData(
|
||||
a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ,
|
||||
BlockTypes, MetaData,
|
||||
IsLightValid ? BlockLight : NULL,
|
||||
IsLightValid ? SkyLight : NULL,
|
||||
NULL, Biomes,
|
||||
IsLightValid ? BlockLight : nullptr,
|
||||
IsLightValid ? SkyLight : nullptr,
|
||||
nullptr, Biomes,
|
||||
Entities, BlockEntities,
|
||||
false
|
||||
));
|
||||
@@ -525,12 +525,12 @@ cChunkDef::BiomeMap * cWSSAnvil::LoadVanillaBiomeMapFromNBT(cChunkDef::BiomeMap
|
||||
{
|
||||
if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_ByteArray))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
if (a_NBT.GetDataLength(a_TagIdx) != 16 * 16)
|
||||
{
|
||||
// The biomes stored don't match in size
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
const unsigned char * VanillaBiomeData = (const unsigned char *)(a_NBT.GetData(a_TagIdx));
|
||||
for (size_t i = 0; i < ARRAYCOUNT(*a_BiomeMap); i++)
|
||||
@@ -538,7 +538,7 @@ cChunkDef::BiomeMap * cWSSAnvil::LoadVanillaBiomeMapFromNBT(cChunkDef::BiomeMap
|
||||
if ((VanillaBiomeData)[i] == 0xff)
|
||||
{
|
||||
// Unassigned biomes
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
(*a_BiomeMap)[i] = (EMCSBiome)(VanillaBiomeData[i]);
|
||||
}
|
||||
@@ -553,12 +553,12 @@ cChunkDef::BiomeMap * cWSSAnvil::LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_Bio
|
||||
{
|
||||
if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_IntArray))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
if (a_NBT.GetDataLength(a_TagIdx) != sizeof(*a_BiomeMap))
|
||||
{
|
||||
// The biomes stored don't match in size
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
const char * BiomeData = (a_NBT.GetData(a_TagIdx));
|
||||
for (size_t i = 0; i < ARRAYCOUNT(*a_BiomeMap); i++)
|
||||
@@ -567,7 +567,7 @@ cChunkDef::BiomeMap * cWSSAnvil::LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_Bio
|
||||
if ((*a_BiomeMap)[i] == 0xff)
|
||||
{
|
||||
// Unassigned biomes
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return a_BiomeMap;
|
||||
@@ -631,7 +631,7 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
|
||||
BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, RelY, RelZ);
|
||||
NIBBLETYPE BlockMeta = cChunkDef::GetNibble(a_BlockMetas, RelX, RelY, RelZ);
|
||||
std::auto_ptr<cBlockEntity> be(LoadBlockEntityFromNBT(a_NBT, Child, x, y, z, BlockType, BlockMeta));
|
||||
if (be.get() == NULL)
|
||||
if (be.get() == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -670,7 +670,7 @@ cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a
|
||||
case E_BLOCK_WALLSIGN: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WALLSIGN);
|
||||
|
||||
// Blocktypes that have block entities but don't load their contents from disk:
|
||||
case E_BLOCK_ENDER_CHEST: return NULL;
|
||||
case E_BLOCK_ENDER_CHEST: return nullptr;
|
||||
}
|
||||
|
||||
// All the other blocktypes should have no entities assigned to them. Report an error:
|
||||
@@ -686,7 +686,7 @@ cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a
|
||||
ItemTypeToString(a_BlockType).c_str(), a_BlockType, TypeName.c_str(),
|
||||
a_BlockX, a_BlockY, a_BlockZ
|
||||
);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -696,11 +696,28 @@ cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a
|
||||
bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
int Type = a_NBT.FindChildByName(a_TagIdx, "id");
|
||||
if ((Type < 0) || (a_NBT.GetType(Type) != TAG_Short))
|
||||
if (Type <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
a_Item.m_ItemType = a_NBT.GetShort(Type);
|
||||
|
||||
if (a_NBT.GetType(Type) == TAG_String)
|
||||
{
|
||||
if (!StringToItem(a_NBT.GetString(Type), a_Item))
|
||||
{
|
||||
// Can't resolve item type
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (a_NBT.GetType(Type) == TAG_Short)
|
||||
{
|
||||
a_Item.m_ItemType = a_NBT.GetShort(Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a_Item.m_ItemType < 0)
|
||||
{
|
||||
a_Item.Empty();
|
||||
@@ -836,7 +853,7 @@ cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagI
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Beacon"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::auto_ptr<cBeaconEntity> Beacon(new cBeaconEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
@@ -881,13 +898,13 @@ cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagId
|
||||
// https://github.com/mc-server/MCServer/blob/d0551e2e0a98a28f31a88d489d17b408e4a7d38d/src/WorldStorage/WSSAnvil.cpp#L637
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Chest") && !CheckBlockEntityType(a_NBT, a_TagIdx, "TrappedChest"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
{
|
||||
return NULL; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this
|
||||
return nullptr; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this
|
||||
}
|
||||
std::auto_ptr<cChestEntity> Chest(new cChestEntity(a_BlockX, a_BlockY, a_BlockZ, m_World, a_ChestBlockType));
|
||||
LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items);
|
||||
@@ -903,7 +920,7 @@ cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Control"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::auto_ptr<cCommandBlockEntity> CmdBlock(new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
@@ -940,13 +957,13 @@ cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_T
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Trap"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
{
|
||||
return NULL; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this
|
||||
return nullptr; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this
|
||||
}
|
||||
std::auto_ptr<cDispenserEntity> Dispenser(new cDispenserEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
LoadItemGridFromNBT(Dispenser->GetContents(), a_NBT, Items);
|
||||
@@ -962,13 +979,13 @@ cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Dropper"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
{
|
||||
return NULL; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this
|
||||
return nullptr; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this
|
||||
}
|
||||
std::auto_ptr<cDropperEntity> Dropper(new cDropperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items);
|
||||
@@ -984,7 +1001,7 @@ cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_T
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "FlowerPot"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::auto_ptr<cFlowerPotEntity> FlowerPot(new cFlowerPotEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
@@ -1015,13 +1032,13 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Furnace"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
{
|
||||
return NULL; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this
|
||||
return nullptr; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this
|
||||
}
|
||||
|
||||
std::auto_ptr<cFurnaceEntity> Furnace(new cFurnaceEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World));
|
||||
@@ -1073,13 +1090,13 @@ cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagI
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Hopper"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
{
|
||||
return NULL; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this
|
||||
return nullptr; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this
|
||||
}
|
||||
std::auto_ptr<cHopperEntity> Hopper(new cHopperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items);
|
||||
@@ -1095,7 +1112,7 @@ cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "RecordPlayer"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::auto_ptr<cJukeboxEntity> Jukebox(new cJukeboxEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
@@ -1116,7 +1133,7 @@ cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Skull"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::auto_ptr<cMobHeadEntity> MobHead(new cMobHeadEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
@@ -1151,7 +1168,7 @@ cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_T
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Music"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::auto_ptr<cNoteEntity> NoteBlock(new cNoteEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
@@ -1172,7 +1189,7 @@ cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Sign"))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::auto_ptr<cSignEntity> Sign(new cSignEntity(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||
@@ -1660,30 +1677,41 @@ void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
|
||||
void cWSSAnvil::LoadHangingFromNBT(cHangingEntity & a_Hanging, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
int Direction = a_NBT.FindChildByName(a_TagIdx, "Direction");
|
||||
if (Direction > 0)
|
||||
// "Facing" tag is the prime source of the Facing; if not available, translate from older "Direction" or "Dir"
|
||||
int Facing = a_NBT.FindChildByName(a_TagIdx, "Facing");
|
||||
if (Facing > 0)
|
||||
{
|
||||
Direction = (int)a_NBT.GetByte(Direction);
|
||||
if ((Direction < 2) || (Direction > 5))
|
||||
Facing = (int)a_NBT.GetByte(Facing);
|
||||
if ((Facing >= 2) && (Facing <= 5))
|
||||
{
|
||||
a_Hanging.SetDirection(BLOCK_FACE_NORTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Hanging.SetDirection(static_cast<eBlockFace>(Direction));
|
||||
a_Hanging.SetFacing(static_cast<eBlockFace>(Facing));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Direction = a_NBT.FindChildByName(a_TagIdx, "Dir");
|
||||
if (Direction > 0)
|
||||
Facing = a_NBT.FindChildByName(a_TagIdx, "Direction");
|
||||
if (Facing > 0)
|
||||
{
|
||||
switch ((int)a_NBT.GetByte(Direction))
|
||||
switch ((int)a_NBT.GetByte(Facing))
|
||||
{
|
||||
case 0: a_Hanging.SetDirection(BLOCK_FACE_NORTH); break;
|
||||
case 1: a_Hanging.SetDirection(BLOCK_FACE_TOP); break;
|
||||
case 2: a_Hanging.SetDirection(BLOCK_FACE_BOTTOM); break;
|
||||
case 3: a_Hanging.SetDirection(BLOCK_FACE_SOUTH); break;
|
||||
case 0: a_Hanging.SetFacing(BLOCK_FACE_ZM); break;
|
||||
case 1: a_Hanging.SetFacing(BLOCK_FACE_XM); break;
|
||||
case 2: a_Hanging.SetFacing(BLOCK_FACE_ZP); break;
|
||||
case 3: a_Hanging.SetFacing(BLOCK_FACE_XP); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Facing = a_NBT.FindChildByName(a_TagIdx, "Dir"); // Has values 0 and 2 swapped
|
||||
if (Facing > 0)
|
||||
{
|
||||
switch ((int)a_NBT.GetByte(Facing))
|
||||
{
|
||||
case 0: a_Hanging.SetFacing(BLOCK_FACE_ZP); break;
|
||||
case 1: a_Hanging.SetFacing(BLOCK_FACE_XM); break;
|
||||
case 2: a_Hanging.SetFacing(BLOCK_FACE_ZM); break;
|
||||
case 3: a_Hanging.SetFacing(BLOCK_FACE_XP); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1732,7 +1760,7 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
int Rotation = a_NBT.FindChildByName(a_TagIdx, "ItemRotation");
|
||||
if (Rotation > 0)
|
||||
{
|
||||
ItemFrame->SetRotation((Byte)a_NBT.GetByte(Rotation));
|
||||
ItemFrame->SetItemRotation((Byte)a_NBT.GetByte(Rotation));
|
||||
}
|
||||
|
||||
a_Entities.push_back(ItemFrame.release());
|
||||
@@ -1744,7 +1772,7 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
|
||||
void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cArrowEntity> Arrow(new cArrowEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
std::auto_ptr<cArrowEntity> Arrow(new cArrowEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
if (!LoadProjectileBaseFromNBT(*Arrow.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -1808,7 +1836,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
|
||||
void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cSplashPotionEntity> SplashPotion(new cSplashPotionEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0), cItem()));
|
||||
std::auto_ptr<cSplashPotionEntity> SplashPotion(new cSplashPotionEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0), cItem()));
|
||||
if (!LoadProjectileBaseFromNBT(*SplashPotion.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -1832,7 +1860,7 @@ void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedN
|
||||
|
||||
void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cThrownSnowballEntity> Snowball(new cThrownSnowballEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
std::auto_ptr<cThrownSnowballEntity> Snowball(new cThrownSnowballEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
if (!LoadProjectileBaseFromNBT(*Snowball.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -1848,7 +1876,7 @@ void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
|
||||
void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cThrownEggEntity> Egg(new cThrownEggEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
std::auto_ptr<cThrownEggEntity> Egg(new cThrownEggEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
if (!LoadProjectileBaseFromNBT(*Egg.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -1864,7 +1892,7 @@ void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
|
||||
|
||||
void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cGhastFireballEntity> Fireball(new cGhastFireballEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
std::auto_ptr<cGhastFireballEntity> Fireball(new cGhastFireballEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
if (!LoadProjectileBaseFromNBT(*Fireball.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -1880,7 +1908,7 @@ void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
|
||||
void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cFireChargeEntity> FireCharge(new cFireChargeEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
std::auto_ptr<cFireChargeEntity> FireCharge(new cFireChargeEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
if (!LoadProjectileBaseFromNBT(*FireCharge.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -1896,7 +1924,7 @@ void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
|
||||
void cWSSAnvil::LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cThrownEnderPearlEntity> Enderpearl(new cThrownEnderPearlEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
std::auto_ptr<cThrownEnderPearlEntity> Enderpearl(new cThrownEnderPearlEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
if (!LoadProjectileBaseFromNBT(*Enderpearl.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2853,7 +2881,7 @@ bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading)
|
||||
if (m_File.Read(m_Header, sizeof(m_Header)) != sizeof(m_Header))
|
||||
{
|
||||
// Cannot read the header - perhaps the file has just been created?
|
||||
// Try writing a NULL header (both chunk offsets and timestamps):
|
||||
// Try writing a nullptr header (both chunk offsets and timestamps):
|
||||
memset(m_Header, 0, sizeof(m_Header));
|
||||
if (
|
||||
(m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) || // Real header - chunk offsets
|
||||
|
||||
@@ -113,10 +113,10 @@ protected:
|
||||
/// Saves the chunk into NBT data using a_Writer; returns true on success
|
||||
bool SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer);
|
||||
|
||||
/// Loads the chunk's biome map from vanilla-format; returns a_BiomeMap if biomes present and valid, NULL otherwise
|
||||
/// Loads the chunk's biome map from vanilla-format; returns a_BiomeMap if biomes present and valid, nullptr otherwise
|
||||
cChunkDef::BiomeMap * LoadVanillaBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
/// Loads the chunk's biome map from MCS format; returns a_BiomeMap if biomes present and valid, NULL otherwise
|
||||
/// Loads the chunk's biome map from MCS format; returns a_BiomeMap if biomes present and valid, nullptr otherwise
|
||||
cChunkDef::BiomeMap * LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
/// Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1)
|
||||
@@ -126,7 +126,7 @@ protected:
|
||||
void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas);
|
||||
|
||||
/** Loads the data for a block entity from the specified NBT tag.
|
||||
Returns the loaded block entity, or NULL upon failure. */
|
||||
Returns the loaded block entity, or nullptr upon failure. */
|
||||
cBlockEntity * LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
|
||||
/// Loads a cItem contents from the specified NBT tag; returns true if successful. Doesn't load the Slot tag
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,157 +0,0 @@
|
||||
|
||||
// WSSCompact.h
|
||||
|
||||
// Interfaces to the cWSSCompact class representing the "Compact" storage schema (PAK-files)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef WSSCOMPACT_H_INCLUDED
|
||||
#define WSSCOMPACT_H_INCLUDED
|
||||
|
||||
#include "WorldStorage.h"
|
||||
#include "../Vector3.h"
|
||||
#include "json/json.h"
|
||||
#include "ChunkDataCallback.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Helper class for serializing a chunk into Json
|
||||
class cJsonChunkSerializer :
|
||||
public cChunkDataArrayCollector
|
||||
{
|
||||
public:
|
||||
|
||||
cJsonChunkSerializer(void);
|
||||
|
||||
Json::Value & GetRoot (void) {return m_Root; }
|
||||
BLOCKTYPE * GetBlockData(void) {return (BLOCKTYPE *)m_BlockData; }
|
||||
bool HasJsonData (void) const {return m_HasJsonData; }
|
||||
|
||||
protected:
|
||||
|
||||
// NOTE: block data is serialized into inherited cChunkDataCollector's m_BlockData[] array
|
||||
|
||||
// Entities and BlockEntities are serialized to Json
|
||||
Json::Value m_Root;
|
||||
bool m_HasJsonData;
|
||||
|
||||
// cChunkDataCollector overrides:
|
||||
virtual void Entity (cEntity * a_Entity) override;
|
||||
virtual void BlockEntity (cBlockEntity * a_Entity) override;
|
||||
virtual void LightIsValid (bool a_IsLightValid) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cWSSCompact :
|
||||
public cWSSchema
|
||||
{
|
||||
public:
|
||||
cWSSCompact(cWorld * a_World, int a_CompressionFactor) : cWSSchema(a_World), m_CompressionFactor(a_CompressionFactor) {}
|
||||
virtual ~cWSSCompact();
|
||||
|
||||
protected:
|
||||
|
||||
enum
|
||||
{
|
||||
// Offsets to individual components in the joined blockdata array
|
||||
MetaOffset = cChunkDef::NumBlocks,
|
||||
LightOffset = MetaOffset + cChunkDef::NumBlocks / 2,
|
||||
SkyLightOffset = LightOffset + cChunkDef::NumBlocks / 2,
|
||||
} ;
|
||||
|
||||
struct sChunkHeader;
|
||||
typedef std::vector<sChunkHeader *> sChunkHeaders;
|
||||
|
||||
/// Implements a cache for a single PAK file; implements lazy-write in order to be able to write multiple chunks fast
|
||||
class cPAKFile
|
||||
{
|
||||
public:
|
||||
|
||||
cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ, int a_CompressionFactor);
|
||||
~cPAKFile();
|
||||
|
||||
bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data);
|
||||
bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data);
|
||||
bool EraseChunkData(const cChunkCoords & a_Chunk);
|
||||
|
||||
bool SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World);
|
||||
|
||||
int GetLayerX(void) const {return m_LayerX; }
|
||||
int GetLayerZ(void) const {return m_LayerZ; }
|
||||
|
||||
static const int PAK_VERSION = 1;
|
||||
#if AXIS_ORDER == AXIS_ORDER_XZY
|
||||
static const int CHUNK_VERSION = 3;
|
||||
#elif AXIS_ORDER == AXIS_ORDER_YZX
|
||||
static const int CHUNK_VERSION = 2;
|
||||
#endif
|
||||
protected:
|
||||
|
||||
AString m_FileName;
|
||||
int m_CompressionFactor;
|
||||
int m_LayerX;
|
||||
int m_LayerZ;
|
||||
|
||||
sChunkHeaders m_ChunkHeaders;
|
||||
AString m_DataContents; // Data contents of the file, cached
|
||||
|
||||
int m_NumDirty; // Number of chunks that were written into m_DataContents but not into the file
|
||||
|
||||
Vector3i m_ChunkSize; // Is related to m_ChunkVersion
|
||||
char m_ChunkVersion;
|
||||
char m_PakVersion;
|
||||
|
||||
bool SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World); // Saves the chunk to m_DataContents, updates headers and m_NumDirty
|
||||
void SynchronizeFile(void); // Writes m_DataContents along with the headers to file, resets m_NumDirty
|
||||
|
||||
void UpdateChunk1To2(void); // Height from 128 to 256
|
||||
void UpdateChunk2To3(void); // Axis order from YZX to XZY
|
||||
} ;
|
||||
|
||||
typedef std::list<cPAKFile *> cPAKFiles;
|
||||
|
||||
cCriticalSection m_CS;
|
||||
cPAKFiles m_PAKFiles; // A MRU cache of PAK files
|
||||
|
||||
int m_CompressionFactor;
|
||||
|
||||
/// Loads the correct PAK file either from cache or from disk, manages the m_PAKFiles cache
|
||||
cPAKFile * LoadPAKFile(const cChunkCoords & a_Chunk);
|
||||
|
||||
/// Gets chunk data from the correct file; locks CS as needed
|
||||
bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data);
|
||||
|
||||
/// Sets chunk data to the correct file; locks CS as needed
|
||||
bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data);
|
||||
|
||||
/// Erases chunk data from the correct file; locks CS as needed
|
||||
bool EraseChunkData(const cChunkCoords & a_Chunk);
|
||||
|
||||
/// Loads the chunk from the data (no locking needed)
|
||||
bool LoadChunkFromData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data, cWorld * a_World);
|
||||
|
||||
void LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World);
|
||||
|
||||
// cWSSchema overrides:
|
||||
virtual bool LoadChunk(const cChunkCoords & a_Chunk) override;
|
||||
virtual bool SaveChunk(const cChunkCoords & a_Chunk) override;
|
||||
virtual const AString GetName(void) const override {return "compact"; }
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // WSSCOMPACT_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "WorldStorage.h"
|
||||
#include "WSSCompact.h"
|
||||
#include "WSSAnvil.h"
|
||||
#include "../World.h"
|
||||
#include "../Generating/ChunkGenerator.h"
|
||||
@@ -40,8 +39,8 @@ protected:
|
||||
|
||||
cWorldStorage::cWorldStorage(void) :
|
||||
super("cWorldStorage"),
|
||||
m_World(NULL),
|
||||
m_SaveSchema(NULL)
|
||||
m_World(nullptr),
|
||||
m_SaveSchema(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -187,7 +186,6 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor)
|
||||
{
|
||||
// The first schema added is considered the default
|
||||
m_Schemas.push_back(new cWSSAnvil (m_World, a_StorageCompressionFactor));
|
||||
m_Schemas.push_back(new cWSSCompact (m_World, a_StorageCompressionFactor));
|
||||
m_Schemas.push_back(new cWSSForgetful(m_World));
|
||||
// Add new schemas here
|
||||
|
||||
|
||||
Reference in New Issue
Block a user