From 51dc47bc70d66667ed1aee597d82dbdcfaf92fa1 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Mon, 30 Jan 2012 16:01:45 +0000 Subject: More cFile cleanup; removed old format writing for block entities git-svn-id: http://mc-server.googlecode.com/svn/trunk@193 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Globals.h | 1 + source/cChestEntity.cpp | 46 +++--- source/cChestEntity.h | 5 +- source/cChunk.cpp | 375 +++++++++++++++++++++++--------------------- source/cChunkMap.cpp | 4 - source/cCriticalSection.cpp | 13 ++ source/cCriticalSection.h | 1 + source/cFurnaceEntity.cpp | 79 ++++------ source/cFurnaceEntity.h | 7 +- source/cSignEntity.cpp | 81 +++++++--- source/cSignEntity.h | 17 +- 11 files changed, 343 insertions(+), 286 deletions(-) diff --git a/source/Globals.h b/source/Globals.h index 5551386ce..d4484e4c9 100644 --- a/source/Globals.h +++ b/source/Globals.h @@ -59,6 +59,7 @@ #include "cSemaphore.h" #include "cEvent.h" #include "cThread.h" +#include "cFile.h" #include "cMCLogger.h" diff --git a/source/cChestEntity.cpp b/source/cChestEntity.cpp index 4df900327..b30800700 100644 --- a/source/cChestEntity.cpp +++ b/source/cChestEntity.cpp @@ -77,46 +77,40 @@ void cChestEntity::SetSlot( int a_Slot, cItem & a_Item ) } } -void cChestEntity::WriteToFile(FILE* a_File) -{ - fwrite( &m_BlockType, sizeof( ENUM_BLOCK_ID ), 1, a_File ); - fwrite( &m_PosX, sizeof( int ), 1, a_File ); - fwrite( &m_PosY, sizeof( int ), 1, a_File ); - fwrite( &m_PosZ, sizeof( int ), 1, a_File ); - unsigned int NumSlots = c_ChestHeight*c_ChestWidth; - fwrite( &NumSlots, sizeof(unsigned int), 1, a_File ); - for(unsigned int i = 0; i < NumSlots; i++) - { - cItem* Item = GetSlot( i ); - if( Item ) - { - fwrite( &Item->m_ItemID, sizeof(Item->m_ItemID), 1, a_File ); - fwrite( &Item->m_ItemCount, sizeof(Item->m_ItemCount), 1, a_File ); - fwrite( &Item->m_ItemHealth, sizeof(Item->m_ItemHealth), 1, a_File ); - } + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING cChestEntity %s FROM FILE (line %d)", #Var, __LINE__); \ + return false; \ } -} -bool cChestEntity::LoadFromFile(FILE* a_File) +bool cChestEntity::LoadFromFile(cFile & f) { - if( fread( &m_PosX, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; } - if( fread( &m_PosY, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; } - if( fread( &m_PosZ, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; } + READ(f, m_PosX); + READ(f, m_PosY); + READ(f, m_PosZ); unsigned int NumSlots = 0; - if( fread( &NumSlots, sizeof(unsigned int), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; } + READ(f, NumSlots); for(unsigned int i = 0; i < NumSlots; i++) { cItem Item; - if( fread( &Item.m_ItemID, sizeof(Item.m_ItemID), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; } - if( fread( &Item.m_ItemCount, sizeof(Item.m_ItemCount), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; } - if( fread( &Item.m_ItemHealth, sizeof(Item.m_ItemHealth), 1, a_File)!= 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; } + READ(f, Item.m_ItemID); + READ(f, Item.m_ItemCount); + READ(f, Item.m_ItemHealth); SetSlot( i, Item ); } return true; } + + + + bool cChestEntity::LoadFromJson( const Json::Value& a_Value ) { m_PosX = a_Value.get("x", 0).asInt(); diff --git a/source/cChestEntity.h b/source/cChestEntity.h index 60d93b049..6082b6a52 100644 --- a/source/cChestEntity.h +++ b/source/cChestEntity.h @@ -17,7 +17,7 @@ class cNBTData; class cChestEntity : public cBlockEntity, public cWindowOwner { public: - cChestEntity(int a_X, int a_Y, int a_Z, cChunk* a_Chunk); + cChestEntity(int a_X, int a_Y, int a_Z, cChunk * a_Chunk); virtual ~cChestEntity(); virtual void Destroy(); @@ -26,8 +26,7 @@ public: cItem * GetSlot( int a_Slot ); void SetSlot( int a_Slot, cItem & a_Item ); - void WriteToFile(FILE* a_File); - bool LoadFromFile(FILE* a_File); + bool LoadFromFile(cFile & a_File); // deprecated format bool LoadFromJson( const Json::Value& a_Value ); void SaveToJson( Json::Value& a_Value ); diff --git a/source/cChunk.cpp b/source/cChunk.cpp index 8d93b34ec..7d93b4ba9 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -4,8 +4,6 @@ #ifndef _WIN32 #include #include -#include // for mkdir -#include #endif @@ -52,6 +50,10 @@ typedef std::list< cClientHandle* > ClientHandleList; typedef std::list< cBlockEntity* > BlockEntityList; typedef std::list< cEntity* > EntityList; + + + + struct cChunk::sChunkState { sChunkState() @@ -78,6 +80,36 @@ struct cChunk::sChunkState int NumRefs; }; + + + + +cChunk::cChunk(int a_X, int a_Y, int a_Z, cWorld* a_World) + : m_pState( new sChunkState ) + , m_bCalculateLighting( false ) + , m_bCalculateHeightmap( false ) + , m_PosX( a_X ) + , m_PosY( a_Y ) + , m_PosZ( a_Z ) + , m_BlockType( m_BlockData ) // Offset the pointers + , m_BlockMeta( m_BlockType + c_NumBlocks ) + , m_BlockLight( m_BlockMeta + c_NumBlocks/2 ) + , m_BlockSkyLight( m_BlockLight + c_NumBlocks/2 ) + , m_BlockTickNum( 0 ) + , m_BlockTickX( 0 ) + , m_BlockTickY( 0 ) + , m_BlockTickZ( 0 ) + , m_EntitiesCriticalSection( 0 ) + , m_World( a_World ) +{ + //LOG("cChunk::cChunk(%i, %i, %i)", a_X, a_Y, a_Z); + m_EntitiesCriticalSection = new cCriticalSection(); +} + + + + + cChunk::~cChunk() { //LOG("~cChunk() %i %i %i", m_PosX, m_PosY, m_PosZ ); @@ -125,31 +157,13 @@ cChunk::~cChunk() delete m_pState; } -cChunk::cChunk(int a_X, int a_Y, int a_Z, cWorld* a_World) - : m_pState( new sChunkState ) - , m_bCalculateLighting( false ) - , m_bCalculateHeightmap( false ) - , m_PosX( a_X ) - , m_PosY( a_Y ) - , m_PosZ( a_Z ) - , m_BlockType( m_BlockData ) // Offset the pointers - , m_BlockMeta( m_BlockType + c_NumBlocks ) - , m_BlockLight( m_BlockMeta + c_NumBlocks/2 ) - , m_BlockSkyLight( m_BlockLight + c_NumBlocks/2 ) - , m_BlockTickNum( 0 ) - , m_BlockTickX( 0 ) - , m_BlockTickY( 0 ) - , m_BlockTickZ( 0 ) - , m_EntitiesCriticalSection( 0 ) - , m_World( a_World ) -{ - //LOG("cChunk::cChunk(%i, %i, %i)", a_X, a_Y, a_Z); - m_EntitiesCriticalSection = new cCriticalSection(); -} + + + void cChunk::Initialize() { - if( !LoadFromDisk() ) + if (!LoadFromDisk()) { // Clear memory memset( m_BlockData, 0x00, c_BlockDataSize ); @@ -163,9 +177,8 @@ void cChunk::Initialize() // During generation, some blocks might have been set by using (Fast)SetBlock() causing this list to fill. // This chunk has not been sent to anybody yet, so there is no need for separately sending block changes when you can send an entire chunk - m_pState->BlockListCriticalSection.Lock(); + cCSLock Lock(m_pState->BlockListCriticalSection); m_pState->PendingSendBlocks.clear(); - m_pState->BlockListCriticalSection.Unlock(); } else { @@ -174,14 +187,22 @@ void cChunk::Initialize() } } + + + + void cChunk::Tick(float a_Dt) { - if( m_bCalculateLighting ) + if (m_bCalculateLighting) + { CalculateLighting(); - if( m_bCalculateHeightmap ) + } + if (m_bCalculateHeightmap) + { CalculateHeightmap(); + } - m_pState->BlockListCriticalSection.Lock(); + cCSLock Lock(m_pState->BlockListCriticalSection); unsigned int PendingSendBlocks = m_pState->PendingSendBlocks.size(); if( PendingSendBlocks > 1 ) { @@ -228,7 +249,7 @@ void cChunk::Tick(float a_Dt) } m_pState->PendingSendBlocks.clear(); } - m_pState->BlockListCriticalSection.Unlock(); + Lock.Unlock(); while( !m_pState->UnloadQuery.empty() ) { @@ -872,179 +893,137 @@ cBlockEntity* cChunk::GetBlockEntity( int a_X, int a_Y, int a_Z ) return 0; } + + + + +/// Loads the chunk from the old-format disk file, erases the file afterwards. Returns true if successful bool cChunk::LoadFromDisk() { char SourceFile[128]; - sprintf_s(SourceFile, 128, "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ ); - - FILE* f = 0; - #ifdef _WIN32 - if( fopen_s(&f, SourceFile, "rb" ) == 0 ) // no error - #else - if( (f = fopen(SourceFile, "rb" )) != 0 ) // no error - #endif + sprintf_s(SourceFile, ARRAYCOUNT(SourceFile), "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ ); + + cFile f; + if (!f.Open(SourceFile, cFile::fmRead)) { - if( fread( m_BlockData, sizeof(char)*c_BlockDataSize, 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; } + return false; + } - // Now load Block Entities - m_pState->BlockListCriticalSection.Lock(); - ENUM_BLOCK_ID BlockType; - while( fread( &BlockType, sizeof(ENUM_BLOCK_ID), 1, f) == 1 ) + if (f.Read(m_BlockData, sizeof(m_BlockData)) != sizeof(m_BlockData)) + { + LOGERROR("ERROR READING FROM FILE %s", SourceFile); + return false; + } + + // Now load Block Entities + cCSLock Lock(m_pState->BlockListCriticalSection); + + ENUM_BLOCK_ID BlockType; + while (f.Read(&BlockType, sizeof(ENUM_BLOCK_ID)) == sizeof(ENUM_BLOCK_ID)) + { + switch (BlockType) { - switch( BlockType ) - { case E_BLOCK_CHEST: + { + cChestEntity * ChestEntity = new cChestEntity( 0, 0, 0, this ); + if (!ChestEntity->LoadFromFile(f)) { - cChestEntity* ChestEntity = new cChestEntity( 0, 0, 0, this ); - if( !ChestEntity->LoadFromFile( f ) ) - { - LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile ); - delete ChestEntity; - fclose(f); - return false; - } - m_pState->BlockEntities.push_back( ChestEntity ); + LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile ); + delete ChestEntity; + return false; } + m_pState->BlockEntities.push_back( ChestEntity ); break; + } + case E_BLOCK_FURNACE: + { + cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0, this ); + if (!FurnaceEntity->LoadFromFile(f)) { - cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0, this ); - if( !FurnaceEntity->LoadFromFile( f ) ) - { - LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile ); - delete FurnaceEntity; - fclose(f); - return false; - } - m_pState->BlockEntities.push_back( FurnaceEntity ); - m_pState->TickBlockEntities.push_back( FurnaceEntity ); // They need tickin' + LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile ); + delete FurnaceEntity; + return false; } + m_pState->BlockEntities.push_back( FurnaceEntity ); + m_pState->TickBlockEntities.push_back( FurnaceEntity ); // They need tickin' break; + } + case E_BLOCK_SIGN_POST: case E_BLOCK_WALLSIGN: + { + cSignEntity * SignEntity = new cSignEntity(BlockType, 0, 0, 0, this ); + if (!SignEntity->LoadFromFile( f ) ) { - cSignEntity* SignEntity = new cSignEntity(BlockType, 0, 0, 0, this ); - if( !SignEntity->LoadFromFile( f ) ) - { - LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile ); - delete SignEntity; - fclose(f); - return false; - } - m_pState->BlockEntities.push_back( SignEntity ); + LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile ); + delete SignEntity; + return false; } + m_pState->BlockEntities.push_back( SignEntity ); break; + } + default: + { + assert(!"Unhandled block entity in file"); break; } } - m_pState->BlockListCriticalSection.Unlock(); - - fclose(f); - - // Delete old format file - if( std::remove( SourceFile ) != 0 ) - LOGERROR("Could not delete file %s", SourceFile ); - else - LOGINFO("Successfully deleted olf format file %s", SourceFile ); + } + Lock.Unlock(); + f.Close(); - return true; + // Delete old format file + if (std::remove(SourceFile) != 0) + { + LOGERROR("Could not delete file %s", SourceFile ); } else { - //LOGWARN("COULD NOT OPEN FILE %s\n", SourceFile); - return false; + LOGINFO("Successfully deleted old format file \"%s\"", SourceFile ); } + return true; } + + + + bool cChunk::SaveToDisk() { + assert(!"Old save format not supported anymore"); // Remove the call to this function + return true; //no more saving old format! +} - char SourceFile[128]; - sprintf_s(SourceFile, 128, "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ ); - #ifdef _WIN32 - { - SECURITY_ATTRIBUTES Attrib; - Attrib.nLength = sizeof(SECURITY_ATTRIBUTES); - Attrib.lpSecurityDescriptor = NULL; - Attrib.bInheritHandle = false; - ::CreateDirectory("world", &Attrib); - } - #else - { - mkdir("world", S_IRWXU | S_IRWXG | S_IRWXO); - } - #endif - - FILE* f = 0; -#ifdef _WIN32 - if( fopen_s(&f, SourceFile, "wb" ) == 0 ) // no error - #else - if( (f = fopen(SourceFile, "wb" )) != 0 ) // no error - #endif - { - fwrite( m_BlockData, sizeof(char)*c_BlockDataSize, 1, f ); - m_pState->BlockListCriticalSection.Lock(); - // Now write Block Entities - for( std::list::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr) - { - cBlockEntity* BlockEntity = *itr; - switch( BlockEntity->GetBlockType() ) - { - case E_BLOCK_CHEST: - { - cChestEntity* ChestEntity = reinterpret_cast< cChestEntity* >( BlockEntity ); - ChestEntity->WriteToFile( f ); - } - break; - case E_BLOCK_FURNACE: - { - cFurnaceEntity* FurnaceEntity = reinterpret_cast< cFurnaceEntity* >( BlockEntity ); - FurnaceEntity->WriteToFile( f ); - } - break; - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: - { - cSignEntity* SignEntity = reinterpret_cast< cSignEntity* >( BlockEntity ); - SignEntity->WriteToFile( f ); - } - break; - default: - break; - } - } - m_pState->BlockListCriticalSection.Unlock(); - fclose(f); - return true; - } - else - { - LOGERROR("ERROR WRITING TO FILE %s", SourceFile); - return false; - } -} void cChunk::Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude /* = 0 */ ) const { for( std::list< cClientHandle* >::const_iterator itr = m_pState->LoadedByClient.begin(); itr != m_pState->LoadedByClient.end(); ++itr ) { - if( *itr == a_Exclude ) continue; + if (*itr == a_Exclude) + { + continue; + } (*itr)->Send( a_Packet ); - } + } // for itr - LoadedByClient[] } + + + void cChunk::LoadFromJson( const Json::Value & a_Value ) { - m_pState->BlockListCriticalSection.Lock(); + cCSLock Lock(m_pState->BlockListCriticalSection); + // Load chests Json::Value AllChests = a_Value.get("Chests", Json::nullValue); - if( !AllChests.empty() ) + if (!AllChests.empty()) { for( Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr ) { @@ -1092,50 +1071,58 @@ void cChunk::LoadFromJson( const Json::Value & a_Value ) else m_pState->BlockEntities.push_back( SignEntity ); } } - m_pState->BlockListCriticalSection.Unlock(); } + + + + void cChunk::SaveToJson( Json::Value & a_Value ) { Json::Value AllChests; Json::Value AllFurnaces; Json::Value AllSigns; - m_pState->BlockListCriticalSection.Lock(); - for( std::list::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr) + cCSLock Lock(m_pState->BlockListCriticalSection); + for (std::list::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr) { cBlockEntity* BlockEntity = *itr; switch( BlockEntity->GetBlockType() ) { - case E_BLOCK_CHEST: + case E_BLOCK_CHEST: { cChestEntity* ChestEntity = reinterpret_cast< cChestEntity* >( BlockEntity ); Json::Value NewChest; ChestEntity->SaveToJson( NewChest ); AllChests.append( NewChest ); + break; } - break; - case E_BLOCK_FURNACE: + + case E_BLOCK_FURNACE: { cFurnaceEntity* FurnaceEntity = reinterpret_cast< cFurnaceEntity* >( BlockEntity ); Json::Value NewFurnace; FurnaceEntity->SaveToJson( NewFurnace ); AllFurnaces.append( NewFurnace ); + break; } - break; - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: + + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: { cSignEntity* SignEntity = reinterpret_cast< cSignEntity* >( BlockEntity ); Json::Value NewSign; SignEntity->SaveToJson( NewSign ); AllSigns.append( NewSign ); + break; } - break; - default: - break; - } - } - m_pState->BlockListCriticalSection.Unlock(); + + default: + { + assert(!"Unhandled blocktype in BlockEntities list while saving to JSON"); + break; + } + } // switch (BlockEntity->GetBlockType()) + } // for itr - BlockEntities[] if( !AllChests.empty() ) a_Value["Chests"] = AllChests; @@ -1145,29 +1132,47 @@ void cChunk::SaveToJson( Json::Value & a_Value ) a_Value["Signs"] = AllSigns; } + + + + EntityList & cChunk::GetEntities() { return m_pState->Entities; } + + + + const ClientHandleList & cChunk::GetClients() { return m_pState->LoadedByClient; } + + + void cChunk::AddTickBlockEntity( cFurnaceEntity* a_Entity ) { m_pState->TickBlockEntities.remove( a_Entity ); m_pState->TickBlockEntities.push_back( a_Entity ); } + + + + void cChunk::RemoveTickBlockEntity( cFurnaceEntity* a_Entity ) { m_pState->TickBlockEntities.remove( a_Entity ); } + + + void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z) { a_Y = a_ChunkY; @@ -1175,32 +1180,50 @@ void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, i a_Z = m_PosZ * 16 + a_ChunkZ; } + + + + void cChunk::AddReference() { - m_pState->ReferenceCriticalSection.Lock(); + cCSLock Lock(m_pState->ReferenceCriticalSection); m_pState->NumRefs++; - m_pState->ReferenceCriticalSection.Unlock(); } + + + + void cChunk::RemoveReference() { - m_pState->ReferenceCriticalSection.Lock(); + cCSLock Lock(m_pState->ReferenceCriticalSection); m_pState->NumRefs--; - if( m_pState->NumRefs < 0 ) + assert (m_pState->NumRefs >= 0); + if (m_pState->NumRefs < 0) { LOGWARN("WARNING: cChunk: Tried to remove reference, but the chunk is not referenced!"); } - m_pState->ReferenceCriticalSection.Unlock(); } + + + + int cChunk::GetReferenceCount() { - m_pState->ReferenceCriticalSection.Lock(); + cCSLock Lock(m_pState->ReferenceCriticalSection); int Refs = m_pState->NumRefs; - m_pState->ReferenceCriticalSection.Unlock(); return Refs; } + + + + #if !C_CHUNK_USE_INLINE # include "cChunk.inc" -#endif \ No newline at end of file +#endif + + + + diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp index b7f1e08a2..d815e311a 100644 --- a/source/cChunkMap.cpp +++ b/source/cChunkMap.cpp @@ -17,10 +17,6 @@ #include -// TODO: Move this into Globals.h after cFile has been finalized -#include "cFile.h" - - #define USE_MEMCPY #define LAYER_SIZE (32) diff --git a/source/cCriticalSection.cpp b/source/cCriticalSection.cpp index 6bc6e805a..95ee77c3d 100644 --- a/source/cCriticalSection.cpp +++ b/source/cCriticalSection.cpp @@ -92,6 +92,19 @@ cCSLock::cCSLock(cCriticalSection * a_CS) +cCSLock::cCSLock(cCriticalSection & a_CS) + : m_CS(&a_CS) + #ifdef _DEBUG + , m_IsLocked(false) + #endif +{ + Lock(); +} + + + + + cCSLock::~cCSLock() { Unlock(); diff --git a/source/cCriticalSection.h b/source/cCriticalSection.h index 60602e821..86c196255 100644 --- a/source/cCriticalSection.h +++ b/source/cCriticalSection.h @@ -30,6 +30,7 @@ class cCSLock public: cCSLock(cCriticalSection * a_CS); + cCSLock(cCriticalSection & a_CS); ~cCSLock(); // Temporarily unlock or re-lock: diff --git a/source/cFurnaceEntity.cpp b/source/cFurnaceEntity.cpp index b5ce42805..e07a1685d 100644 --- a/source/cFurnaceEntity.cpp +++ b/source/cFurnaceEntity.cpp @@ -219,67 +219,54 @@ void cFurnaceEntity::ResetCookTimer() m_CookTime = 0.f; } -void cFurnaceEntity::WriteToFile(FILE* a_File) -{ - fwrite( &m_BlockType, sizeof( ENUM_BLOCK_ID ), 1, a_File ); - fwrite( &m_PosX, sizeof( int ), 1, a_File ); - fwrite( &m_PosY, sizeof( int ), 1, a_File ); - fwrite( &m_PosZ, sizeof( int ), 1, a_File ); - unsigned int NumSlots = 3; - fwrite( &NumSlots, sizeof(unsigned int), 1, a_File ); - for(unsigned int i = 0; i < NumSlots; i++) - { - cItem* Item = &m_Items[i]; - if( Item ) - { - fwrite( &Item->m_ItemID, sizeof(Item->m_ItemID), 1, a_File ); - fwrite( &Item->m_ItemCount, sizeof(Item->m_ItemCount), 1, a_File ); - fwrite( &Item->m_ItemHealth, sizeof(Item->m_ItemHealth), 1, a_File ); - } + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING cFurnaceEntity %s FROM FILE (line %d)", #Var, __LINE__); \ + return false; \ } - cItem Item; - if( m_CookingItem ) Item = *m_CookingItem; - fwrite( &Item.m_ItemID, sizeof(Item.m_ItemID), 1, a_File ); - fwrite( &Item.m_ItemCount, sizeof(Item.m_ItemCount), 1, a_File ); - fwrite( &Item.m_ItemHealth, sizeof(Item.m_ItemHealth), 1, a_File ); - - fwrite( &m_CookTime, sizeof(float), 1, a_File ); - fwrite( &m_TimeCooked, sizeof(float), 1, a_File ); - fwrite( &m_BurnTime, sizeof(float), 1, a_File ); - fwrite( &m_TimeBurned, sizeof(float), 1, a_File ); -} -bool cFurnaceEntity::LoadFromFile(FILE* a_File) +bool cFurnaceEntity::LoadFromFile(cFile & f) { - if( fread( &m_PosX, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( fread( &m_PosY, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( fread( &m_PosZ, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } + READ(f, m_PosX); + READ(f, m_PosY); + READ(f, m_PosZ); unsigned int NumSlots = 0; - if( fread( &NumSlots, sizeof(unsigned int), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } + READ(f, NumSlots); m_Items = new cItem[ NumSlots ]; for(unsigned int i = 0; i < NumSlots; i++) { - cItem & Item = m_Items[ i ]; - if( fread( &Item.m_ItemID, sizeof(Item.m_ItemID), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( fread( &Item.m_ItemCount, sizeof(Item.m_ItemCount), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( fread( &Item.m_ItemHealth, sizeof(Item.m_ItemHealth), 1, a_File)!= 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } + cItem & Item = m_Items[i]; + READ(f, Item.m_ItemID); + READ(f, Item.m_ItemCount); + READ(f, Item.m_ItemHealth); + } + cItem CookingItem; + READ(f, CookingItem.m_ItemID); + READ(f, CookingItem.m_ItemCount); + READ(f, CookingItem.m_ItemHealth); + if (!CookingItem.IsEmpty()) + { + m_CookingItem = new cItem(CookingItem); } - cItem Item; - if( fread( &Item.m_ItemID, sizeof(Item.m_ItemID), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( fread( &Item.m_ItemCount, sizeof(Item.m_ItemCount), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( fread( &Item.m_ItemHealth, sizeof(Item.m_ItemHealth), 1, a_File)!= 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( !Item.IsEmpty() ) m_CookingItem = new cItem( Item ); - if( fread( &m_CookTime, sizeof(float), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( fread( &m_TimeCooked, sizeof(float), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( fread( &m_BurnTime, sizeof(float), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } - if( fread( &m_TimeBurned, sizeof(float), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; } + READ(f, m_CookTime); + READ(f, m_TimeCooked); + READ(f, m_BurnTime); + READ(f, m_TimeBurned); return true; } + + + + bool cFurnaceEntity::LoadFromJson( const Json::Value& a_Value ) { m_PosX = a_Value.get("x", 0).asInt(); diff --git a/source/cFurnaceEntity.h b/source/cFurnaceEntity.h index 86052d363..99209acf8 100644 --- a/source/cFurnaceEntity.h +++ b/source/cFurnaceEntity.h @@ -21,11 +21,10 @@ public: virtual ~cFurnaceEntity(); virtual void Destroy(); - void WriteToFile(FILE* a_File); - bool LoadFromFile(FILE* a_File); + bool LoadFromFile(cFile & a_File); // deprecated format - bool LoadFromJson( const Json::Value& a_Value ); - void SaveToJson( Json::Value& a_Value ); + bool LoadFromJson(const Json::Value& a_Value ); + void SaveToJson (Json::Value& a_Value ); bool Tick( float a_Dt ); virtual void UsedBy( cPlayer & a_Player ); diff --git a/source/cSignEntity.cpp b/source/cSignEntity.cpp index beac869c8..2f57b3867 100644 --- a/source/cSignEntity.cpp +++ b/source/cSignEntity.cpp @@ -22,16 +22,28 @@ cSignEntity::cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, c { } + + + + cSignEntity::~cSignEntity() { } + + + + // It don't do anything when 'used' void cSignEntity::UsedBy( cPlayer & a_Player ) { (void)a_Player; } + + + + void cSignEntity::SetLines( const std::string & a_Line1, const std::string & a_Line2, const std::string & a_Line3, const std::string & a_Line4 ) { m_Line[0] = a_Line1; @@ -40,6 +52,10 @@ void cSignEntity::SetLines( const std::string & a_Line1, const std::string & a_L m_Line[3] = a_Line4; } + + + + void cSignEntity::SetLine( int a_Index, std::string a_Line ) { if( a_Index < 4 && a_Index > -1 ) @@ -48,6 +64,10 @@ void cSignEntity::SetLine( int a_Index, std::string a_Line ) } } + + + + std::string cSignEntity::GetLine( int a_Index ) { if( a_Index < 4 && a_Index > -1 ) @@ -57,6 +77,10 @@ std::string cSignEntity::GetLine( int a_Index ) return ""; } + + + + void cSignEntity::SendTo( cClientHandle* a_Client ) { cPacket_UpdateSign Sign; @@ -68,51 +92,58 @@ void cSignEntity::SendTo( cClientHandle* a_Client ) Sign.m_Line3 = m_Line[2]; Sign.m_Line4 = m_Line[3]; - if( a_Client ) a_Client->Send( Sign ); + if( a_Client ) + { + a_Client->Send( Sign ); + } else // broadcast of a_Client == 0 { GetChunk()->Broadcast( Sign ); } } -void cSignEntity::WriteToFile(FILE* a_File) -{ - fwrite( &m_BlockType, sizeof( ENUM_BLOCK_ID ), 1, a_File ); - fwrite( &m_PosX, sizeof( int ), 1, a_File ); - fwrite( &m_PosY, sizeof( int ), 1, a_File ); - fwrite( &m_PosZ, sizeof( int ), 1, a_File ); - for( int i = 0; i < 4; i++ ) - { - short Size = (short)m_Line[i].size(); - fwrite( &Size, sizeof(short), 1, a_File ); - fwrite( m_Line[i].c_str(), Size * sizeof(char), 1, a_File ); + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING cSignEntity %s FROM FILE (line %d)", #Var, __LINE__); \ + return false; \ } -} -bool cSignEntity::LoadFromFile(FILE* a_File) +bool cSignEntity::LoadFromFile(cFile & f) { - if( fread( &m_PosX, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING SIGN FROM FILE"); return false; } - if( fread( &m_PosY, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING SIGN FROM FILE"); return false; } - if( fread( &m_PosZ, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING SIGN FROM FILE"); return false; } + READ(f, m_PosX); + READ(f, m_PosY); + READ(f, m_PosZ); for( int i = 0; i < 4; i++ ) { short Size = 0; - if( fread( &Size, sizeof(short), 1, a_File) != 1 ) { LOGERROR("ERROR READING SIGN FROM FILE"); return false; } - if( Size > 0 ) + READ(f, Size); + if (Size > 0) { - char* c_Str = new char[Size]; - if( fread( c_Str, Size * sizeof(char), 1, a_File) != 1 ) { LOGERROR("ERROR READING SIGN FROM FILE"); delete [] c_Str; return false; } + char * c_Str = new char[Size]; + if (f.Read(c_Str, Size) != Size ) + { + LOGERROR("ERROR READING SIGN FROM FILE"); + delete [] c_Str; + return false; + } m_Line[i].assign( c_Str, Size ); delete [] c_Str; } - LOG("Line %i: %s", i+1, m_Line[i].c_str() ); } return true; } + + + + bool cSignEntity::LoadFromJson( const Json::Value & a_Value ) { m_PosX = a_Value.get("x", 0).asInt(); @@ -137,4 +168,8 @@ void cSignEntity::SaveToJson( Json::Value & a_Value ) a_Value["Line2"] = m_Line[1]; a_Value["Line3"] = m_Line[2]; a_Value["Line4"] = m_Line[3]; -} \ No newline at end of file +} + + + + diff --git a/source/cSignEntity.h b/source/cSignEntity.h index b0e95e38c..31413c8c3 100644 --- a/source/cSignEntity.h +++ b/source/cSignEntity.h @@ -3,13 +3,19 @@ #include "cBlockEntity.h" #include "FileDefine.h" -#include + + + namespace Json { class Value; } + + + + class cWorld; class cSignEntity : public cBlockEntity { @@ -17,8 +23,7 @@ public: cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cChunk* a_Chunk); virtual ~cSignEntity(); - void WriteToFile(FILE* a_File); - bool LoadFromFile(FILE* a_File); + bool LoadFromFile(cFile & a_File); // deprecated format bool LoadFromJson( const Json::Value& a_Value ); void SaveToJson( Json::Value& a_Value ); @@ -32,4 +37,8 @@ public: virtual void SendTo( cClientHandle* a_Client ); private: std::string m_Line[4]; -}; \ No newline at end of file +}; + + + + -- cgit v1.2.3