2012-06-14 09:06:06 -04:00
// WSSAnvil.h
// Interfaces to the cWSSAnvil class representing the Anvil world storage scheme
# pragma once
# include "WorldStorage.h"
# include "FastNBT.h"
2014-02-23 13:44:58 -05:00
# include "../Mobs/Monster.h"
2012-06-14 09:06:06 -04:00
2013-05-26 11:29:43 -04:00
// fwd: ItemGrid.h
class cItemGrid ;
2013-09-07 15:26:17 -04:00
class cProjectileEntity ;
2014-03-14 21:45:25 -04:00
class cHangingEntity ;
2014-08-03 16:03:48 -04:00
class cWolf ;
2013-09-07 15:26:17 -04:00
2013-05-26 11:29:43 -04:00
2012-06-14 09:06:06 -04:00
enum
{
2015-07-28 09:53:28 -04:00
/** Maximum number of chunks in an MCA file - also the count of the header items */
2012-06-14 09:06:06 -04:00
MCA_MAX_CHUNKS = 32 * 32 ,
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** The MCA header is 8 KiB */
2012-06-14 09:06:06 -04:00
MCA_HEADER_SIZE = MCA_MAX_CHUNKS * 8 ,
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** There are 5 bytes of header in front of each chunk */
2012-06-14 09:06:06 -04:00
MCA_CHUNK_HEADER_LENGTH = 5 ,
} ;
class cWSSAnvil :
public cWSSchema
{
typedef cWSSchema super ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
public :
2014-01-17 14:01:14 -05:00
cWSSAnvil ( cWorld * a_World , int a_CompressionFactor ) ;
2012-06-14 09:06:06 -04:00
virtual ~ cWSSAnvil ( ) ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
protected :
class cMCAFile
{
public :
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
cMCAFile ( cWSSAnvil & a_ParentSchema , const AString & a_FileName , int a_RegionX , int a_RegionZ ) ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
bool GetChunkData ( const cChunkCoords & a_Chunk , AString & a_Data ) ;
bool SetChunkData ( const cChunkCoords & a_Chunk , const AString & a_Data ) ;
bool EraseChunkData ( const cChunkCoords & a_Chunk ) ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
int GetRegionX ( void ) const { return m_RegionX ; }
int GetRegionZ ( void ) const { return m_RegionZ ; }
const AString & GetFileName ( void ) const { return m_FileName ; }
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
protected :
2015-07-28 09:53:28 -04:00
cWSSAnvil & m_ParentSchema ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
int m_RegionX ;
int m_RegionZ ;
cFile m_File ;
AString m_FileName ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
// The header, copied from the file so we don't have to seek to it all the time
// First 1024 entries are chunk locations - the 3 + 1 byte sector-offset and sector-count
unsigned m_Header [ MCA_MAX_CHUNKS ] ;
2016-02-05 16:45:45 -05:00
2014-12-07 17:44:08 -05:00
// Chunk timestamps, following the chunk headers
unsigned m_TimeStamps [ MCA_MAX_CHUNKS ] ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Finds a free location large enough to hold a_Data. Gets a hint of the chunk coords, places the data there if it fits. Returns the sector number. */
2012-06-14 09:06:06 -04:00
unsigned FindFreeLocation ( int a_LocalX , int a_LocalZ , const AString & a_Data ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Opens a MCA file either for a Read operation (fails if doesn't exist) or for a Write operation (creates new if not found) */
2012-06-14 09:06:06 -04:00
bool OpenFile ( bool a_IsForReading ) ;
} ;
typedef std : : list < cMCAFile * > cMCAFiles ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
cCriticalSection m_CS ;
cMCAFiles m_Files ; // a MRU cache of MCA files
2016-02-05 16:45:45 -05:00
2014-01-17 14:01:14 -05:00
int m_CompressionFactor ;
2012-06-14 09:06:06 -04:00
2015-07-28 09:53:28 -04:00
/** Reports that the specified chunk failed to load and saves the chunk data to an external file. */
void ChunkLoadFailed ( int a_ChunkX , int a_ChunkZ , const AString & a_Reason , const AString & a_ChunkDataToSave ) ;
/** Gets chunk data from the correct file; locks file CS as needed */
2012-06-14 09:06:06 -04:00
bool GetChunkData ( const cChunkCoords & a_Chunk , AString & a_Data ) ;
2015-07-28 09:53:28 -04:00
/** Sets chunk data into the correct file; locks file CS as needed */
2012-06-14 09:06:06 -04:00
bool SetChunkData ( const cChunkCoords & a_Chunk , const AString & a_Data ) ;
2015-07-28 09:53:28 -04:00
/** Loads the chunk from the data (no locking needed) */
2012-06-14 09:06:06 -04:00
bool LoadChunkFromData ( const cChunkCoords & a_Chunk , const AString & a_Data ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Saves the chunk into datastream (no locking needed) */
2012-06-14 09:06:06 -04:00
bool SaveChunkToData ( const cChunkCoords & a_Chunk , AString & a_Data ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Loads the chunk from NBT data (no locking needed).
a_RawChunkData is the raw ( compressed ) chunk data , used for offloading when chunk loading fails . */
bool LoadChunkFromNBT ( const cChunkCoords & a_Chunk , const cParsedNBT & a_NBT , const AString & a_RawChunkData ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Saves the chunk into NBT data using a_Writer; returns true on success */
2012-06-14 09:06:06 -04:00
bool SaveChunkToNBT ( const cChunkCoords & a_Chunk , cFastNBTWriter & a_Writer ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Loads the chunk's biome map from vanilla-format; returns a_BiomeMap if biomes present and valid, nullptr otherwise */
2012-10-28 13:30:10 -04:00
cChunkDef : : BiomeMap * LoadVanillaBiomeMapFromNBT ( cChunkDef : : BiomeMap * a_BiomeMap , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Loads the chunk's biome map from MCS format; returns a_BiomeMap if biomes present and valid, nullptr otherwise */
2012-06-14 09:06:06 -04:00
cChunkDef : : BiomeMap * LoadBiomeMapFromNBT ( cChunkDef : : BiomeMap * a_BiomeMap , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1) */
2012-06-14 09:06:06 -04:00
void LoadEntitiesFromNBT ( cEntityList & a_Entitites , const cParsedNBT & a_NBT , int a_Tag ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) */
2013-06-20 07:41:44 -04:00
void LoadBlockEntitiesFromNBT ( cBlockEntityList & a_BlockEntitites , const cParsedNBT & a_NBT , int a_Tag , BLOCKTYPE * a_BlockTypes , NIBBLETYPE * a_BlockMetas ) ;
2016-02-05 16:45:45 -05:00
2014-08-29 12:19:27 -04:00
/** Loads the data for a block entity from the specified NBT tag.
2014-10-20 16:55:07 -04:00
Returns the loaded block entity , or nullptr upon failure . */
2014-08-29 12:19:27 -04:00
cBlockEntity * LoadBlockEntityFromNBT ( const cParsedNBT & a_NBT , int a_Tag , int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
2015-07-28 09:53:28 -04:00
/** Loads a cItem contents from the specified NBT tag; returns true if successful. Doesn't load the Slot tag */
2013-03-09 09:35:43 -05:00
bool LoadItemFromNBT ( cItem & a_Item , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2016-02-05 16:45:45 -05:00
2013-05-26 11:29:43 -04:00
/** Loads contentents of an Items[] list tag into a cItemGrid
ItemGrid begins at the specified slot offset
2015-07-28 09:53:28 -04:00
Slots outside the ItemGrid range are ignored */
2013-05-26 11:29:43 -04:00
void LoadItemGridFromNBT ( cItemGrid & a_ItemGrid , const cParsedNBT & a_NBT , int a_ItemsTagIdx , int s_SlotOffset = 0 ) ;
2016-02-05 16:45:45 -05:00
2014-08-29 12:19:27 -04:00
/** Returns true iff the "id" child tag inside the specified tag equals the specified expected type. */
bool CheckBlockEntityType ( const cParsedNBT & a_NBT , int a_TagIdx , const char * a_ExpectedType ) ;
cBlockEntity * LoadBeaconFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2015-09-24 04:48:33 -04:00
cBlockEntity * LoadBrewingstandFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
2014-08-29 12:19:27 -04:00
cBlockEntity * LoadChestFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_ChestBlockType ) ;
cBlockEntity * LoadCommandBlockFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
cBlockEntity * LoadDispenserFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
cBlockEntity * LoadDropperFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
cBlockEntity * LoadFlowerPotFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
cBlockEntity * LoadFurnaceFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
2014-12-08 11:22:40 -05:00
cBlockEntity * LoadMobSpawnerFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2014-08-29 12:19:27 -04:00
cBlockEntity * LoadHopperFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
cBlockEntity * LoadJukeboxFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
cBlockEntity * LoadMobHeadFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
cBlockEntity * LoadNoteBlockFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
cBlockEntity * LoadSignFromNBT ( const cParsedNBT & a_NBT , int a_TagIdx , int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_SignBlockType ) ;
2016-02-05 16:45:45 -05:00
2014-05-09 13:33:22 -04:00
void LoadEntityFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_EntityTagIdx , const char * a_IDTag , size_t a_IDTagLength ) ;
2016-02-05 16:45:45 -05:00
2013-09-09 05:13:14 -04:00
void LoadBoatFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2014-03-25 14:59:33 -04:00
void LoadEnderCrystalFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2013-09-07 15:26:17 -04:00
void LoadFallingBlockFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2013-12-25 11:07:52 -05:00
void LoadPickupFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2014-03-14 19:32:49 -04:00
void LoadTNTFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadExpOrbFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2014-07-19 08:53:41 -04:00
void LoadHangingFromNBT ( cHangingEntity & a_Hanging , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2014-03-14 21:45:25 -04:00
void LoadItemFrameFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2015-03-13 19:05:06 -04:00
void LoadPaintingFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2013-12-25 11:07:52 -05:00
2013-09-07 15:26:17 -04:00
void LoadMinecartRFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadMinecartCFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadMinecartFFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadMinecartTFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadMinecartHFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2013-12-25 11:07:52 -05:00
2013-09-07 15:26:17 -04:00
void LoadArrowFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2014-07-11 21:58:11 -04:00
void LoadSplashPotionFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2013-09-07 15:26:17 -04:00
void LoadSnowballFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadEggFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadFireballFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadFireChargeFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadThrownEnderpearlFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2013-12-25 11:07:52 -05:00
void LoadBatFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadBlazeFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadCaveSpiderFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadChickenFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadCowFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadCreeperFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadEnderDragonFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadEndermanFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadGhastFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadGiantFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2014-12-18 13:30:32 -05:00
void LoadGuardianFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2013-12-25 11:07:52 -05:00
void LoadHorseFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadIronGolemFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadMagmaCubeFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadMooshroomFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadOcelotFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadPigFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2014-12-20 04:31:34 -05:00
void LoadRabbitFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2013-12-25 11:07:52 -05:00
void LoadSheepFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadSilverfishFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadSkeletonFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadSlimeFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadSnowGolemFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadSpiderFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadSquidFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadVillagerFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadWitchFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadWitherFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadWolfFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadZombieFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
void LoadPigZombieFromNBT ( cEntityList & a_Entities , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2016-02-05 16:45:45 -05:00
2014-08-03 16:03:48 -04:00
/** Loads the wolf's owner information from the NBT into the specified wolf entity. */
void LoadWolfOwner ( cWolf & a_Wolf , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Loads entity common data from the NBT compound; returns true if successful */
2013-03-09 09:35:43 -05:00
bool LoadEntityBaseFromNBT ( cEntity & a_Entity , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Loads monster common data from the NBT compound; returns true if successful */
2014-02-23 13:44:58 -05:00
bool LoadMonsterBaseFromNBT ( cMonster & a_Monster , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Loads projectile common data from the NBT compound; returns true if successful */
2013-09-07 15:26:17 -04:00
bool LoadProjectileBaseFromNBT ( cProjectileEntity & a_Entity , const cParsedNBT & a_NBT , int a_TagIx ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Loads an array of doubles of the specified length from the specified NBT list tag a_TagIdx; returns true if successful */
2013-03-09 09:35:43 -05:00
bool LoadDoublesListFromNBT ( double * a_Doubles , int a_NumDoubles , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2015-07-28 09:53:28 -04:00
/** Loads an array of floats of the specified length from the specified NBT list tag a_TagIdx; returns true if successful */
2014-02-23 13:44:58 -05:00
bool LoadFloatsListFromNBT ( float * a_Floats , int a_NumFloats , const cParsedNBT & a_NBT , int a_TagIdx ) ;
2015-07-28 09:53:28 -04:00
/** Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful */
2012-06-14 09:06:06 -04:00
bool GetBlockEntityNBTPos ( const cParsedNBT & a_NBT , int a_TagIdx , int & a_X , int & a_Y , int & a_Z ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Gets the correct MCA file either from cache or from disk, manages the m_MCAFiles cache; assumes m_CS is locked */
2012-06-14 09:06:06 -04:00
cMCAFile * LoadMCAFile ( const cChunkCoords & a_Chunk ) ;
2016-02-05 16:45:45 -05:00
2015-07-28 09:53:28 -04:00
/** Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer */
2014-05-09 13:57:59 -04:00
void CopyNBTData ( const cParsedNBT & a_NBT , int a_Tag , const AString & a_ChildName , char * a_Destination , size_t a_Length ) ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
// 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 " anvil " ; }
} ;