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
This commit is contained in:
parent
7e743398a9
commit
51dc47bc70
@ -59,6 +59,7 @@
|
|||||||
#include "cSemaphore.h"
|
#include "cSemaphore.h"
|
||||||
#include "cEvent.h"
|
#include "cEvent.h"
|
||||||
#include "cThread.h"
|
#include "cThread.h"
|
||||||
|
#include "cFile.h"
|
||||||
#include "cMCLogger.h"
|
#include "cMCLogger.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -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++)
|
|
||||||
{
|
#define READ(File, Var) \
|
||||||
cItem* Item = GetSlot( i );
|
if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \
|
||||||
if( Item )
|
{ \
|
||||||
{
|
LOGERROR("ERROR READING cChestEntity %s FROM FILE (line %d)", #Var, __LINE__); \
|
||||||
fwrite( &Item->m_ItemID, sizeof(Item->m_ItemID), 1, a_File );
|
return false; \
|
||||||
fwrite( &Item->m_ItemCount, sizeof(Item->m_ItemCount), 1, a_File );
|
|
||||||
fwrite( &Item->m_ItemHealth, sizeof(Item->m_ItemHealth), 1, a_File );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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; }
|
READ(f, m_PosX);
|
||||||
if( fread( &m_PosY, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; }
|
READ(f, m_PosY);
|
||||||
if( fread( &m_PosZ, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; }
|
READ(f, m_PosZ);
|
||||||
|
|
||||||
unsigned int NumSlots = 0;
|
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++)
|
for(unsigned int i = 0; i < NumSlots; i++)
|
||||||
{
|
{
|
||||||
cItem Item;
|
cItem Item;
|
||||||
if( fread( &Item.m_ItemID, sizeof(Item.m_ItemID), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; }
|
READ(f, Item.m_ItemID);
|
||||||
if( fread( &Item.m_ItemCount, sizeof(Item.m_ItemCount), 1, a_File) != 1 ) { LOGERROR("ERROR READING CHEST FROM FILE"); return false; }
|
READ(f, Item.m_ItemCount);
|
||||||
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_ItemHealth);
|
||||||
SetSlot( i, Item );
|
SetSlot( i, Item );
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChestEntity::LoadFromJson( const Json::Value& a_Value )
|
bool cChestEntity::LoadFromJson( const Json::Value& a_Value )
|
||||||
{
|
{
|
||||||
m_PosX = a_Value.get("x", 0).asInt();
|
m_PosX = a_Value.get("x", 0).asInt();
|
||||||
|
@ -26,8 +26,7 @@ public:
|
|||||||
cItem * GetSlot( int a_Slot );
|
cItem * GetSlot( int a_Slot );
|
||||||
void SetSlot( int a_Slot, cItem & a_Item );
|
void SetSlot( int a_Slot, cItem & a_Item );
|
||||||
|
|
||||||
void WriteToFile(FILE* a_File);
|
bool LoadFromFile(cFile & a_File); // deprecated format
|
||||||
bool LoadFromFile(FILE* a_File);
|
|
||||||
|
|
||||||
bool LoadFromJson( const Json::Value& a_Value );
|
bool LoadFromJson( const Json::Value& a_Value );
|
||||||
void SaveToJson( Json::Value& a_Value );
|
void SaveToJson( Json::Value& a_Value );
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sys/stat.h> // for mkdir
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -52,6 +50,10 @@ typedef std::list< cClientHandle* > ClientHandleList;
|
|||||||
typedef std::list< cBlockEntity* > BlockEntityList;
|
typedef std::list< cBlockEntity* > BlockEntityList;
|
||||||
typedef std::list< cEntity* > EntityList;
|
typedef std::list< cEntity* > EntityList;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct cChunk::sChunkState
|
struct cChunk::sChunkState
|
||||||
{
|
{
|
||||||
sChunkState()
|
sChunkState()
|
||||||
@ -78,6 +80,36 @@ struct cChunk::sChunkState
|
|||||||
int NumRefs;
|
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()
|
cChunk::~cChunk()
|
||||||
{
|
{
|
||||||
//LOG("~cChunk() %i %i %i", m_PosX, m_PosY, m_PosZ );
|
//LOG("~cChunk() %i %i %i", m_PosX, m_PosY, m_PosZ );
|
||||||
@ -125,27 +157,9 @@ cChunk::~cChunk()
|
|||||||
delete m_pState;
|
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()
|
void cChunk::Initialize()
|
||||||
{
|
{
|
||||||
@ -163,9 +177,8 @@ void cChunk::Initialize()
|
|||||||
|
|
||||||
// During generation, some blocks might have been set by using (Fast)SetBlock() causing this list to fill.
|
// 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
|
// 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->PendingSendBlocks.clear();
|
||||||
m_pState->BlockListCriticalSection.Unlock();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -174,14 +187,22 @@ void cChunk::Initialize()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::Tick(float a_Dt)
|
void cChunk::Tick(float a_Dt)
|
||||||
{
|
{
|
||||||
if (m_bCalculateLighting)
|
if (m_bCalculateLighting)
|
||||||
|
{
|
||||||
CalculateLighting();
|
CalculateLighting();
|
||||||
|
}
|
||||||
if (m_bCalculateHeightmap)
|
if (m_bCalculateHeightmap)
|
||||||
|
{
|
||||||
CalculateHeightmap();
|
CalculateHeightmap();
|
||||||
|
}
|
||||||
|
|
||||||
m_pState->BlockListCriticalSection.Lock();
|
cCSLock Lock(m_pState->BlockListCriticalSection);
|
||||||
unsigned int PendingSendBlocks = m_pState->PendingSendBlocks.size();
|
unsigned int PendingSendBlocks = m_pState->PendingSendBlocks.size();
|
||||||
if( PendingSendBlocks > 1 )
|
if( PendingSendBlocks > 1 )
|
||||||
{
|
{
|
||||||
@ -228,7 +249,7 @@ void cChunk::Tick(float a_Dt)
|
|||||||
}
|
}
|
||||||
m_pState->PendingSendBlocks.clear();
|
m_pState->PendingSendBlocks.clear();
|
||||||
}
|
}
|
||||||
m_pState->BlockListCriticalSection.Unlock();
|
Lock.Unlock();
|
||||||
|
|
||||||
while( !m_pState->UnloadQuery.empty() )
|
while( !m_pState->UnloadQuery.empty() )
|
||||||
{
|
{
|
||||||
@ -872,24 +893,33 @@ cBlockEntity* cChunk::GetBlockEntity( int a_X, int a_Y, int a_Z )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Loads the chunk from the old-format disk file, erases the file afterwards. Returns true if successful
|
||||||
bool cChunk::LoadFromDisk()
|
bool cChunk::LoadFromDisk()
|
||||||
{
|
{
|
||||||
char SourceFile[128];
|
char SourceFile[128];
|
||||||
sprintf_s(SourceFile, 128, "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ );
|
sprintf_s(SourceFile, ARRAYCOUNT(SourceFile), "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ );
|
||||||
|
|
||||||
FILE* f = 0;
|
cFile f;
|
||||||
#ifdef _WIN32
|
if (!f.Open(SourceFile, cFile::fmRead))
|
||||||
if( fopen_s(&f, SourceFile, "rb" ) == 0 ) // no error
|
|
||||||
#else
|
|
||||||
if( (f = fopen(SourceFile, "rb" )) != 0 ) // no error
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
if( fread( m_BlockData, sizeof(char)*c_BlockDataSize, 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f.Read(m_BlockData, sizeof(m_BlockData)) != sizeof(m_BlockData))
|
||||||
|
{
|
||||||
|
LOGERROR("ERROR READING FROM FILE %s", SourceFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Now load Block Entities
|
// Now load Block Entities
|
||||||
m_pState->BlockListCriticalSection.Lock();
|
cCSLock Lock(m_pState->BlockListCriticalSection);
|
||||||
|
|
||||||
ENUM_BLOCK_ID BlockType;
|
ENUM_BLOCK_ID BlockType;
|
||||||
while( fread( &BlockType, sizeof(ENUM_BLOCK_ID), 1, f) == 1 )
|
while (f.Read(&BlockType, sizeof(ENUM_BLOCK_ID)) == sizeof(ENUM_BLOCK_ID))
|
||||||
{
|
{
|
||||||
switch (BlockType)
|
switch (BlockType)
|
||||||
{
|
{
|
||||||
@ -900,12 +930,12 @@ bool cChunk::LoadFromDisk()
|
|||||||
{
|
{
|
||||||
LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile );
|
LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile );
|
||||||
delete ChestEntity;
|
delete ChestEntity;
|
||||||
fclose(f);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_pState->BlockEntities.push_back( ChestEntity );
|
m_pState->BlockEntities.push_back( ChestEntity );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case E_BLOCK_FURNACE:
|
case E_BLOCK_FURNACE:
|
||||||
{
|
{
|
||||||
cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0, this );
|
cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0, this );
|
||||||
@ -913,13 +943,13 @@ bool cChunk::LoadFromDisk()
|
|||||||
{
|
{
|
||||||
LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile );
|
LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile );
|
||||||
delete FurnaceEntity;
|
delete FurnaceEntity;
|
||||||
fclose(f);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_pState->BlockEntities.push_back( FurnaceEntity );
|
m_pState->BlockEntities.push_back( FurnaceEntity );
|
||||||
m_pState->TickBlockEntities.push_back( FurnaceEntity ); // They need tickin'
|
m_pState->TickBlockEntities.push_back( FurnaceEntity ); // They need tickin'
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case E_BLOCK_SIGN_POST:
|
case E_BLOCK_SIGN_POST:
|
||||||
case E_BLOCK_WALLSIGN:
|
case E_BLOCK_WALLSIGN:
|
||||||
{
|
{
|
||||||
@ -928,120 +958,69 @@ bool cChunk::LoadFromDisk()
|
|||||||
{
|
{
|
||||||
LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile );
|
LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile );
|
||||||
delete SignEntity;
|
delete SignEntity;
|
||||||
fclose(f);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_pState->BlockEntities.push_back( SignEntity );
|
m_pState->BlockEntities.push_back( SignEntity );
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
m_pState->BlockListCriticalSection.Unlock();
|
|
||||||
|
|
||||||
fclose(f);
|
default:
|
||||||
|
{
|
||||||
|
assert(!"Unhandled block entity in file");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Lock.Unlock();
|
||||||
|
f.Close();
|
||||||
|
|
||||||
// Delete old format file
|
// Delete old format file
|
||||||
if (std::remove(SourceFile) != 0)
|
if (std::remove(SourceFile) != 0)
|
||||||
|
{
|
||||||
LOGERROR("Could not delete file %s", SourceFile );
|
LOGERROR("Could not delete file %s", SourceFile );
|
||||||
else
|
|
||||||
LOGINFO("Successfully deleted olf format file %s", SourceFile );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//LOGWARN("COULD NOT OPEN FILE %s\n", SourceFile);
|
LOGINFO("Successfully deleted old format file \"%s\"", SourceFile );
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::SaveToDisk()
|
bool cChunk::SaveToDisk()
|
||||||
{
|
{
|
||||||
|
assert(!"Old save format not supported anymore"); // Remove the call to this function
|
||||||
|
|
||||||
return true; //no more saving old format!
|
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
|
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 )
|
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 );
|
(*itr)->Send( a_Packet );
|
||||||
|
} // for itr - LoadedByClient[]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::LoadFromJson( const Json::Value & a_Value )
|
void cChunk::LoadFromJson( const Json::Value & a_Value )
|
||||||
{
|
{
|
||||||
m_pState->BlockListCriticalSection.Lock();
|
cCSLock Lock(m_pState->BlockListCriticalSection);
|
||||||
|
|
||||||
// Load chests
|
// Load chests
|
||||||
Json::Value AllChests = a_Value.get("Chests", Json::nullValue);
|
Json::Value AllChests = a_Value.get("Chests", Json::nullValue);
|
||||||
if (!AllChests.empty())
|
if (!AllChests.empty())
|
||||||
@ -1092,15 +1071,18 @@ void cChunk::LoadFromJson( const Json::Value & a_Value )
|
|||||||
else m_pState->BlockEntities.push_back( SignEntity );
|
else m_pState->BlockEntities.push_back( SignEntity );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_pState->BlockListCriticalSection.Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::SaveToJson( Json::Value & a_Value )
|
void cChunk::SaveToJson( Json::Value & a_Value )
|
||||||
{
|
{
|
||||||
Json::Value AllChests;
|
Json::Value AllChests;
|
||||||
Json::Value AllFurnaces;
|
Json::Value AllFurnaces;
|
||||||
Json::Value AllSigns;
|
Json::Value AllSigns;
|
||||||
m_pState->BlockListCriticalSection.Lock();
|
cCSLock Lock(m_pState->BlockListCriticalSection);
|
||||||
for (std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
for (std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
cBlockEntity* BlockEntity = *itr;
|
cBlockEntity* BlockEntity = *itr;
|
||||||
@ -1112,16 +1094,18 @@ void cChunk::SaveToJson( Json::Value & a_Value )
|
|||||||
Json::Value NewChest;
|
Json::Value NewChest;
|
||||||
ChestEntity->SaveToJson( NewChest );
|
ChestEntity->SaveToJson( NewChest );
|
||||||
AllChests.append( NewChest );
|
AllChests.append( NewChest );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case E_BLOCK_FURNACE:
|
case E_BLOCK_FURNACE:
|
||||||
{
|
{
|
||||||
cFurnaceEntity* FurnaceEntity = reinterpret_cast< cFurnaceEntity* >( BlockEntity );
|
cFurnaceEntity* FurnaceEntity = reinterpret_cast< cFurnaceEntity* >( BlockEntity );
|
||||||
Json::Value NewFurnace;
|
Json::Value NewFurnace;
|
||||||
FurnaceEntity->SaveToJson( NewFurnace );
|
FurnaceEntity->SaveToJson( NewFurnace );
|
||||||
AllFurnaces.append( NewFurnace );
|
AllFurnaces.append( NewFurnace );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case E_BLOCK_SIGN_POST:
|
case E_BLOCK_SIGN_POST:
|
||||||
case E_BLOCK_WALLSIGN:
|
case E_BLOCK_WALLSIGN:
|
||||||
{
|
{
|
||||||
@ -1129,13 +1113,16 @@ void cChunk::SaveToJson( Json::Value & a_Value )
|
|||||||
Json::Value NewSign;
|
Json::Value NewSign;
|
||||||
SignEntity->SaveToJson( NewSign );
|
SignEntity->SaveToJson( NewSign );
|
||||||
AllSigns.append( NewSign );
|
AllSigns.append( NewSign );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
|
assert(!"Unhandled blocktype in BlockEntities list while saving to JSON");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} // switch (BlockEntity->GetBlockType())
|
||||||
m_pState->BlockListCriticalSection.Unlock();
|
} // for itr - BlockEntities[]
|
||||||
|
|
||||||
if( !AllChests.empty() )
|
if( !AllChests.empty() )
|
||||||
a_Value["Chests"] = AllChests;
|
a_Value["Chests"] = AllChests;
|
||||||
@ -1145,29 +1132,47 @@ void cChunk::SaveToJson( Json::Value & a_Value )
|
|||||||
a_Value["Signs"] = AllSigns;
|
a_Value["Signs"] = AllSigns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EntityList & cChunk::GetEntities()
|
EntityList & cChunk::GetEntities()
|
||||||
{
|
{
|
||||||
return m_pState->Entities;
|
return m_pState->Entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ClientHandleList & cChunk::GetClients()
|
const ClientHandleList & cChunk::GetClients()
|
||||||
{
|
{
|
||||||
return m_pState->LoadedByClient;
|
return m_pState->LoadedByClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::AddTickBlockEntity( cFurnaceEntity* a_Entity )
|
void cChunk::AddTickBlockEntity( cFurnaceEntity* a_Entity )
|
||||||
{
|
{
|
||||||
m_pState->TickBlockEntities.remove( a_Entity );
|
m_pState->TickBlockEntities.remove( a_Entity );
|
||||||
m_pState->TickBlockEntities.push_back( a_Entity );
|
m_pState->TickBlockEntities.push_back( a_Entity );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::RemoveTickBlockEntity( cFurnaceEntity* a_Entity )
|
void cChunk::RemoveTickBlockEntity( cFurnaceEntity* a_Entity )
|
||||||
{
|
{
|
||||||
m_pState->TickBlockEntities.remove( 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)
|
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;
|
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;
|
a_Z = m_PosZ * 16 + a_ChunkZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::AddReference()
|
void cChunk::AddReference()
|
||||||
{
|
{
|
||||||
m_pState->ReferenceCriticalSection.Lock();
|
cCSLock Lock(m_pState->ReferenceCriticalSection);
|
||||||
m_pState->NumRefs++;
|
m_pState->NumRefs++;
|
||||||
m_pState->ReferenceCriticalSection.Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::RemoveReference()
|
void cChunk::RemoveReference()
|
||||||
{
|
{
|
||||||
m_pState->ReferenceCriticalSection.Lock();
|
cCSLock Lock(m_pState->ReferenceCriticalSection);
|
||||||
m_pState->NumRefs--;
|
m_pState->NumRefs--;
|
||||||
|
assert (m_pState->NumRefs >= 0);
|
||||||
if (m_pState->NumRefs < 0)
|
if (m_pState->NumRefs < 0)
|
||||||
{
|
{
|
||||||
LOGWARN("WARNING: cChunk: Tried to remove reference, but the chunk is not referenced!");
|
LOGWARN("WARNING: cChunk: Tried to remove reference, but the chunk is not referenced!");
|
||||||
}
|
}
|
||||||
m_pState->ReferenceCriticalSection.Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cChunk::GetReferenceCount()
|
int cChunk::GetReferenceCount()
|
||||||
{
|
{
|
||||||
m_pState->ReferenceCriticalSection.Lock();
|
cCSLock Lock(m_pState->ReferenceCriticalSection);
|
||||||
int Refs = m_pState->NumRefs;
|
int Refs = m_pState->NumRefs;
|
||||||
m_pState->ReferenceCriticalSection.Unlock();
|
|
||||||
return Refs;
|
return Refs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if !C_CHUNK_USE_INLINE
|
#if !C_CHUNK_USE_INLINE
|
||||||
# include "cChunk.inc"
|
# include "cChunk.inc"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,10 +17,6 @@
|
|||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
|
|
||||||
// TODO: Move this into Globals.h after cFile has been finalized
|
|
||||||
#include "cFile.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define USE_MEMCPY
|
#define USE_MEMCPY
|
||||||
|
|
||||||
#define LAYER_SIZE (32)
|
#define LAYER_SIZE (32)
|
||||||
|
@ -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()
|
cCSLock::~cCSLock()
|
||||||
{
|
{
|
||||||
Unlock();
|
Unlock();
|
||||||
|
@ -30,6 +30,7 @@ class cCSLock
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
cCSLock(cCriticalSection * a_CS);
|
cCSLock(cCriticalSection * a_CS);
|
||||||
|
cCSLock(cCriticalSection & a_CS);
|
||||||
~cCSLock();
|
~cCSLock();
|
||||||
|
|
||||||
// Temporarily unlock or re-lock:
|
// Temporarily unlock or re-lock:
|
||||||
|
@ -219,67 +219,54 @@ void cFurnaceEntity::ResetCookTimer()
|
|||||||
m_CookTime = 0.f;
|
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 );
|
#define READ(File, Var) \
|
||||||
fwrite( &m_TimeBurned, sizeof(float), 1, a_File );
|
if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \
|
||||||
|
{ \
|
||||||
|
LOGERROR("ERROR READING cFurnaceEntity %s FROM FILE (line %d)", #Var, __LINE__); \
|
||||||
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
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; }
|
READ(f, m_PosX);
|
||||||
if( fread( &m_PosY, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; }
|
READ(f, m_PosY);
|
||||||
if( fread( &m_PosZ, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; }
|
READ(f, m_PosZ);
|
||||||
|
|
||||||
unsigned int NumSlots = 0;
|
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 ];
|
m_Items = new cItem[ NumSlots ];
|
||||||
for(unsigned int i = 0; i < NumSlots; i++)
|
for(unsigned int i = 0; i < NumSlots; i++)
|
||||||
{
|
{
|
||||||
cItem & Item = m_Items[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; }
|
READ(f, Item.m_ItemID);
|
||||||
if( fread( &Item.m_ItemCount, sizeof(Item.m_ItemCount), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; }
|
READ(f, Item.m_ItemCount);
|
||||||
if( fread( &Item.m_ItemHealth, sizeof(Item.m_ItemHealth), 1, a_File)!= 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; }
|
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; }
|
READ(f, m_CookTime);
|
||||||
if( fread( &m_TimeCooked, sizeof(float), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; }
|
READ(f, m_TimeCooked);
|
||||||
if( fread( &m_BurnTime, sizeof(float), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; }
|
READ(f, m_BurnTime);
|
||||||
if( fread( &m_TimeBurned, sizeof(float), 1, a_File) != 1 ) { LOGERROR("ERROR READING FURNACE FROM FILE"); return false; }
|
READ(f, m_TimeBurned);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cFurnaceEntity::LoadFromJson( const Json::Value& a_Value )
|
bool cFurnaceEntity::LoadFromJson( const Json::Value& a_Value )
|
||||||
{
|
{
|
||||||
m_PosX = a_Value.get("x", 0).asInt();
|
m_PosX = a_Value.get("x", 0).asInt();
|
||||||
|
@ -21,8 +21,7 @@ public:
|
|||||||
virtual ~cFurnaceEntity();
|
virtual ~cFurnaceEntity();
|
||||||
virtual void Destroy();
|
virtual void Destroy();
|
||||||
|
|
||||||
void WriteToFile(FILE* a_File);
|
bool LoadFromFile(cFile & a_File); // deprecated format
|
||||||
bool LoadFromFile(FILE* a_File);
|
|
||||||
|
|
||||||
bool LoadFromJson(const Json::Value& a_Value );
|
bool LoadFromJson(const Json::Value& a_Value );
|
||||||
void SaveToJson (Json::Value& a_Value );
|
void SaveToJson (Json::Value& a_Value );
|
||||||
|
@ -22,16 +22,28 @@ cSignEntity::cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, c
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cSignEntity::~cSignEntity()
|
cSignEntity::~cSignEntity()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// It don't do anything when 'used'
|
// It don't do anything when 'used'
|
||||||
void cSignEntity::UsedBy( cPlayer & a_Player )
|
void cSignEntity::UsedBy( cPlayer & a_Player )
|
||||||
{
|
{
|
||||||
(void)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 )
|
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;
|
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;
|
m_Line[3] = a_Line4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSignEntity::SetLine( int a_Index, std::string a_Line )
|
void cSignEntity::SetLine( int a_Index, std::string a_Line )
|
||||||
{
|
{
|
||||||
if( a_Index < 4 && a_Index > -1 )
|
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 )
|
std::string cSignEntity::GetLine( int a_Index )
|
||||||
{
|
{
|
||||||
if( a_Index < 4 && a_Index > -1 )
|
if( a_Index < 4 && a_Index > -1 )
|
||||||
@ -57,6 +77,10 @@ std::string cSignEntity::GetLine( int a_Index )
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSignEntity::SendTo( cClientHandle* a_Client )
|
void cSignEntity::SendTo( cClientHandle* a_Client )
|
||||||
{
|
{
|
||||||
cPacket_UpdateSign Sign;
|
cPacket_UpdateSign Sign;
|
||||||
@ -68,51 +92,58 @@ void cSignEntity::SendTo( cClientHandle* a_Client )
|
|||||||
Sign.m_Line3 = m_Line[2];
|
Sign.m_Line3 = m_Line[2];
|
||||||
Sign.m_Line4 = m_Line[3];
|
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
|
else // broadcast of a_Client == 0
|
||||||
{
|
{
|
||||||
GetChunk()->Broadcast( Sign );
|
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 );
|
#define READ(File, Var) \
|
||||||
fwrite( m_Line[i].c_str(), Size * sizeof(char), 1, a_File );
|
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; }
|
READ(f, m_PosX);
|
||||||
if( fread( &m_PosY, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING SIGN FROM FILE"); return false; }
|
READ(f, m_PosY);
|
||||||
if( fread( &m_PosZ, sizeof(int), 1, a_File) != 1 ) { LOGERROR("ERROR READING SIGN FROM FILE"); return false; }
|
READ(f, m_PosZ);
|
||||||
|
|
||||||
for( int i = 0; i < 4; i++ )
|
for( int i = 0; i < 4; i++ )
|
||||||
{
|
{
|
||||||
short Size = 0;
|
short Size = 0;
|
||||||
if( fread( &Size, sizeof(short), 1, a_File) != 1 ) { LOGERROR("ERROR READING SIGN FROM FILE"); return false; }
|
READ(f, Size);
|
||||||
if (Size > 0)
|
if (Size > 0)
|
||||||
{
|
{
|
||||||
char * c_Str = new char[Size];
|
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; }
|
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 );
|
m_Line[i].assign( c_Str, Size );
|
||||||
delete [] c_Str;
|
delete [] c_Str;
|
||||||
}
|
}
|
||||||
LOG("Line %i: %s", i+1, m_Line[i].c_str() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cSignEntity::LoadFromJson( const Json::Value & a_Value )
|
bool cSignEntity::LoadFromJson( const Json::Value & a_Value )
|
||||||
{
|
{
|
||||||
m_PosX = a_Value.get("x", 0).asInt();
|
m_PosX = a_Value.get("x", 0).asInt();
|
||||||
@ -138,3 +169,7 @@ void cSignEntity::SaveToJson( Json::Value & a_Value )
|
|||||||
a_Value["Line3"] = m_Line[2];
|
a_Value["Line3"] = m_Line[2];
|
||||||
a_Value["Line4"] = m_Line[3];
|
a_Value["Line4"] = m_Line[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,13 +3,19 @@
|
|||||||
#include "cBlockEntity.h"
|
#include "cBlockEntity.h"
|
||||||
#include "FileDefine.h"
|
#include "FileDefine.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
namespace Json
|
||||||
{
|
{
|
||||||
class Value;
|
class Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cWorld;
|
class cWorld;
|
||||||
class cSignEntity : public cBlockEntity
|
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);
|
cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cChunk* a_Chunk);
|
||||||
virtual ~cSignEntity();
|
virtual ~cSignEntity();
|
||||||
|
|
||||||
void WriteToFile(FILE* a_File);
|
bool LoadFromFile(cFile & a_File); // deprecated format
|
||||||
bool LoadFromFile(FILE* a_File);
|
|
||||||
|
|
||||||
bool LoadFromJson( const Json::Value& a_Value );
|
bool LoadFromJson( const Json::Value& a_Value );
|
||||||
void SaveToJson( Json::Value& a_Value );
|
void SaveToJson( Json::Value& a_Value );
|
||||||
@ -33,3 +38,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
std::string m_Line[4];
|
std::string m_Line[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user