summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-01-30 17:01:45 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-01-30 17:01:45 +0100
commit51dc47bc70d66667ed1aee597d82dbdcfaf92fa1 (patch)
tree9e5fd39541516c0f8ced34b36f6e546bcd3886bb /source
parentInitial cFile implementation (using stdio FILE) and test in cChunkMap (diff)
downloadcuberite-51dc47bc70d66667ed1aee597d82dbdcfaf92fa1.tar
cuberite-51dc47bc70d66667ed1aee597d82dbdcfaf92fa1.tar.gz
cuberite-51dc47bc70d66667ed1aee597d82dbdcfaf92fa1.tar.bz2
cuberite-51dc47bc70d66667ed1aee597d82dbdcfaf92fa1.tar.lz
cuberite-51dc47bc70d66667ed1aee597d82dbdcfaf92fa1.tar.xz
cuberite-51dc47bc70d66667ed1aee597d82dbdcfaf92fa1.tar.zst
cuberite-51dc47bc70d66667ed1aee597d82dbdcfaf92fa1.zip
Diffstat (limited to 'source')
-rw-r--r--source/Globals.h1
-rw-r--r--source/cChestEntity.cpp46
-rw-r--r--source/cChestEntity.h5
-rw-r--r--source/cChunk.cpp375
-rw-r--r--source/cChunkMap.cpp4
-rw-r--r--source/cCriticalSection.cpp13
-rw-r--r--source/cCriticalSection.h1
-rw-r--r--source/cFurnaceEntity.cpp79
-rw-r--r--source/cFurnaceEntity.h7
-rw-r--r--source/cSignEntity.cpp81
-rw-r--r--source/cSignEntity.h17
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 <cstring>
#include <cstdlib>
-#include <sys/stat.h> // for mkdir
-#include <sys/types.h>
#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<cBlockEntity*>::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<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
+ cCSLock Lock(m_pState->BlockListCriticalSection);
+ for (std::list<cBlockEntity*>::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 <json/json.h>
-// 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 <string>
+
+
+
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
+};
+
+
+
+