Player data is saved and loaded as human readable JSON now.

cFileFormatUpdate will loop through old files and convert them to new files (should replace legacy old format loading code)
cItem has two new functions to load from Json and output Json, this will keep the items in Json standard
ChestEntity and FurnaceEntity use the new functions in cItem

git-svn-id: http://mc-server.googlecode.com/svn/trunk@35 0a769ca7-a7f5-676a-18bf-c427514a06d6
master
faketruth 2011-10-31 21:30:14 +00:00
parent 1979404815
commit c2b43f33da
13 changed files with 531 additions and 260 deletions

View File

@ -234,6 +234,7 @@
<ClCompile Include="..\source\cCuboid.cpp" />
<ClCompile Include="..\source\cEnderman.cpp" />
<ClCompile Include="..\source\cEvent.cpp" />
<ClCompile Include="..\source\cFileFormatUpdater.cpp" />
<ClCompile Include="..\source\cFurnaceEntity.cpp" />
<ClCompile Include="..\Source\cFurnaceRecipe.cpp" />
<ClCompile Include="..\source\cFurnaceWindow.cpp" />
@ -242,6 +243,7 @@
<ClCompile Include="..\Source\cGroup.cpp" />
<ClCompile Include="..\Source\cGroupManager.cpp" />
<ClCompile Include="..\Source\cHeartBeat.cpp" />
<ClCompile Include="..\source\cItem.cpp" />
<ClCompile Include="..\Source\cLuaCommandBinder.cpp" />
<ClCompile Include="..\source\cMakeDir.cpp" />
<ClCompile Include="..\source\cMCLogger.cpp" />
@ -358,6 +360,7 @@
<ClInclude Include="..\Source\cCriticalSection.h" />
<ClInclude Include="..\source\cEnderman.h" />
<ClInclude Include="..\source\cEvent.h" />
<ClInclude Include="..\source\cFileFormatUpdater.h" />
<ClInclude Include="..\source\cFurnaceEntity.h" />
<ClInclude Include="..\Source\cFurnaceRecipe.h" />
<ClInclude Include="..\source\cFurnaceWindow.h" />

View File

@ -367,6 +367,9 @@
<Filter Include="cEntity\cPawn\cMonster\cZombiepigman">
<UniqueIdentifier>{e4620b72-4739-4233-b326-47d4b5ca23d2}</UniqueIdentifier>
</Filter>
<Filter Include="cFileFormatUpdater">
<UniqueIdentifier>{c9b053f2-89dd-475e-a889-5c25a20e6eec}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\source\cServer.cpp">
@ -733,6 +736,12 @@
<ClCompile Include="..\source\cZombiepigman.cpp">
<Filter>cEntity\cPawn\cMonster\cZombiepigman</Filter>
</ClCompile>
<ClCompile Include="..\source\cFileFormatUpdater.cpp">
<Filter>cFileFormatUpdater</Filter>
</ClCompile>
<ClCompile Include="..\source\cItem.cpp">
<Filter>cItem</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\source\cServer.h">
@ -1137,6 +1146,9 @@
<ClInclude Include="..\source\cZombiepigman.h">
<Filter>cEntity\cPawn\cMonster\cZombiepigman</Filter>
</ClInclude>
<ClInclude Include="..\source\cFileFormatUpdater.h">
<Filter>cFileFormatUpdater</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\source\AllToLua.pkg">

379
makefile
View File

@ -127,188 +127,7 @@ MCServer : \
build/cPacket_DestroyEntity.o\
build/cPacket_Disconnect.o\
build/cPacket_EntityEquipment.o\
build/cPacket_CreateInventoryAction.o\
build/cPacket_EntityLook.o\
build/cPacket_EntityStatus.o\
build/cPacket_Flying.o\
build/cPacket_Handshake.o\
build/cPacket_InventoryProgressBar.o\
build/cPacket_InventorySlot.o\
build/cPacket_ItemSwitch.o\
build/cPacket_KeepAlive.o\
build/cPacket_Login.o\
build/cPacket_MapChunk.o\
build/cPacket_Metadata.o\
build/cPacket_MultiBlock.o\
build/cPacket_NamedEntitySpawn.o\
build/cPacket_PickupSpawn.o\
build/cPacket_PlayerLook.o\
build/cPacket_PlayerMoveLook.o\
build/cPacket_PlayerPosition.o\
build/cPacket_PreChunk.o\
build/cPacket_RelativeEntityMove.o\
build/cPacket_RelativeEntityMoveLook.o\
build/cPacket_Respawn.o\
build/cPacket_SpawnMob.o\
build/cPacket_TeleportEntity.o\
build/cPacket_TimeUpdate.o\
build/cPacket_UpdateHealth.o\
build/cPacket_UpdateSign.o\
build/cPacket_UseEntity.o\
build/cPacket_WholeInventory.o\
build/cPacket_WindowClick.o\
build/cPacket_WindowClose.o\
build/cPacket_WindowOpen.o\
build/cPacket.o\
build/base64.o\
build/Socket.o\
build/StdHelpers.o\
build/UrlHelper.o\
build/WebServer.o\
build/tolua_event.o\
build/tolua_is.o\
build/tolua_map.o\
build/tolua_push.o\
build/tolua_to.o\
build/lapi.o\
build/lauxlib.o\
build/lbaselib.o\
build/lcode.o\
build/ldblib.o\
build/ldebug.o\
build/ldo.o\
build/ldump.o\
build/lfunc.o\
build/lgc.o\
build/linit.o\
build/liolib.o\
build/llex.o\
build/lmathlib.o\
build/lmem.o\
build/loadlib.o\
build/lobject.o\
build/lopcodes.o\
build/loslib.o\
build/lparser.o\
build/lstate.o\
build/lstring.o\
build/lstrlib.o\
build/ltable.o\
build/ltablib.o\
build/ltm.o\
build/luac.o\
build/lundump.o\
build/lvm.o\
build/lzio.o\
build/print.o\
build/adler32.o\
build/compress.o\
build/crc32.o\
build/deflate.o\
build/gzclose.o\
build/gzlib.o\
build/gzread.o\
build/gzwrite.o\
build/infback.o\
build/inffast.o\
build/inflate.o\
build/inftrees.o\
build/trees.o\
build/uncompr.o\
build/zutil.o\
build/iniFile.o\
build/cSocket.o\
build/cWaterSimulator.o
$(CC) $(LNK_OPTIONS) \
build/json_reader.o\
build/json_value.o\
build/json_writer.o\
build/cMakeDir.o\
build/cGenSettings.o\
build/cCuboid.o\
build/cNoise.o\
build/cTimer.o\
build/cSleep.o\
build/cMonsterConfig.o\
build/cSpider.o\
build/cThread.o\
build/cBlockingTCPLink.o\
build/cAuthenticator.o\
build/cLuaCommandBinder.o\
build/cChicken.o\
build/cCow.o\
build/cPig.o\
build/cSheep.o\
build/cSquid.o\
build/cWolf.o\
build/cZombie.o\
build/cEnderman.o\
build/cCreeper.o\
build/cGhast.o\
build/cCavespider.o\
build/cZombiepigman.o\
build/cSkeleton.o\
build/cSlime.o\
build/cSilverfish.o\
build/md5.o\
build/cReferenceManager.o\
build/Bindings.o\
build/cBlockToPickup.o\
build/cChatColor.o\
build/cChestEntity.o\
build/cChunk.o\
build/cChunkMap.o\
build/cClientHandle.o\
build/cCraftingWindow.o\
build/cCriticalSection.o\
build/cEntity.o\
build/cEvent.o\
build/cFurnaceEntity.o\
build/cFurnaceRecipe.o\
build/cFurnaceWindow.o\
build/cGroup.o\
build/cGroupManager.o\
build/cInventory.o\
build/cLog.o\
build/cMonster.o\
build/cPawn.o\
build/cPickup.o\
build/cPlayer.o\
build/cPlugin_Lua.o\
build/cPlugin.o\
build/cPluginManager.o\
build/cRecipeChecker.o\
build/cRoot.o\
build/cSemaphore.o\
build/cServer.o\
build/cSignEntity.o\
build/cStringMap.o\
build/cWebAdmin.o\
build/cWebPlugin.o\
build/cWindow.o\
build/cWorld.o\
build/main.o\
build/ManualBindings.o\
build/Matrix4f.o\
build/Vector3d.o\
build/Vector3f.o\
build/Vector3i.o\
build/cHeartBeat.o\
build/cTCPLink.o\
build/cMCLogger.o\
build/cTracer.o\
build/cPacket_13.o\
build/cPacket_AddToInventory.o\
build/cPacket_ArmAnim.o\
build/cPacket_BlockChange.o\
build/cPacket_BlockDig.o\
build/cPacket_BlockPlace.o\
build/cPacket_Chat.o\
build/cPacket_CollectItem.o\
build/cPacket_DestroyEntity.o\
build/cPacket_Disconnect.o\
build/cPacket_EntityEquipment.o\
build/cPacket_CreateInventoryAction.o\
build/cPacket_CreateInventoryAction.o\
build/cPacket_EntityLook.o\
build/cPacket_EntityStatus.o\
build/cPacket_Flying.o\
@ -400,6 +219,191 @@ MCServer : \
build/iniFile.o\
build/cSocket.o\
build/cWaterSimulator.o\
build/cFileFormatUpdater.o\
build/cItem.o
$(CC) $(LNK_OPTIONS) \
build/json_reader.o\
build/json_value.o\
build/json_writer.o\
build/cMakeDir.o\
build/cGenSettings.o\
build/cCuboid.o\
build/cNoise.o\
build/cTimer.o\
build/cSleep.o\
build/cMonsterConfig.o\
build/cSpider.o\
build/cThread.o\
build/cBlockingTCPLink.o\
build/cAuthenticator.o\
build/cLuaCommandBinder.o\
build/cChicken.o\
build/cCow.o\
build/cPig.o\
build/cSheep.o\
build/cSquid.o\
build/cWolf.o\
build/cZombie.o\
build/cEnderman.o\
build/cCreeper.o\
build/cGhast.o\
build/cCavespider.o\
build/cZombiepigman.o\
build/cSkeleton.o\
build/cSlime.o\
build/cSilverfish.o\
build/md5.o\
build/cReferenceManager.o\
build/Bindings.o\
build/cBlockToPickup.o\
build/cChatColor.o\
build/cChestEntity.o\
build/cChunk.o\
build/cChunkMap.o\
build/cClientHandle.o\
build/cCraftingWindow.o\
build/cCriticalSection.o\
build/cEntity.o\
build/cEvent.o\
build/cFurnaceEntity.o\
build/cFurnaceRecipe.o\
build/cFurnaceWindow.o\
build/cGroup.o\
build/cGroupManager.o\
build/cInventory.o\
build/cLog.o\
build/cMonster.o\
build/cPawn.o\
build/cPickup.o\
build/cPlayer.o\
build/cPlugin_Lua.o\
build/cPlugin.o\
build/cPluginManager.o\
build/cRecipeChecker.o\
build/cRoot.o\
build/cSemaphore.o\
build/cServer.o\
build/cSignEntity.o\
build/cStringMap.o\
build/cWebAdmin.o\
build/cWebPlugin.o\
build/cWindow.o\
build/cWorld.o\
build/main.o\
build/ManualBindings.o\
build/Matrix4f.o\
build/Vector3d.o\
build/Vector3f.o\
build/Vector3i.o\
build/cHeartBeat.o\
build/cTCPLink.o\
build/cMCLogger.o\
build/cTracer.o\
build/cPacket_13.o\
build/cPacket_AddToInventory.o\
build/cPacket_ArmAnim.o\
build/cPacket_BlockChange.o\
build/cPacket_BlockDig.o\
build/cPacket_BlockPlace.o\
build/cPacket_Chat.o\
build/cPacket_CollectItem.o\
build/cPacket_DestroyEntity.o\
build/cPacket_Disconnect.o\
build/cPacket_EntityEquipment.o\
build/cPacket_CreateInventoryAction.o\
build/cPacket_EntityLook.o\
build/cPacket_EntityStatus.o\
build/cPacket_Flying.o\
build/cPacket_Handshake.o\
build/cPacket_InventoryProgressBar.o\
build/cPacket_InventorySlot.o\
build/cPacket_ItemSwitch.o\
build/cPacket_KeepAlive.o\
build/cPacket_Login.o\
build/cPacket_MapChunk.o\
build/cPacket_Metadata.o\
build/cPacket_MultiBlock.o\
build/cPacket_NamedEntitySpawn.o\
build/cPacket_PickupSpawn.o\
build/cPacket_PlayerLook.o\
build/cPacket_PlayerMoveLook.o\
build/cPacket_PlayerPosition.o\
build/cPacket_PreChunk.o\
build/cPacket_RelativeEntityMove.o\
build/cPacket_RelativeEntityMoveLook.o\
build/cPacket_Respawn.o\
build/cPacket_SpawnMob.o\
build/cPacket_TeleportEntity.o\
build/cPacket_TimeUpdate.o\
build/cPacket_UpdateHealth.o\
build/cPacket_UpdateSign.o\
build/cPacket_UseEntity.o\
build/cPacket_WholeInventory.o\
build/cPacket_WindowClick.o\
build/cPacket_WindowClose.o\
build/cPacket_WindowOpen.o\
build/cPacket.o\
build/base64.o\
build/Socket.o\
build/StdHelpers.o\
build/UrlHelper.o\
build/WebServer.o\
build/tolua_event.o\
build/tolua_is.o\
build/tolua_map.o\
build/tolua_push.o\
build/tolua_to.o\
build/lapi.o\
build/lauxlib.o\
build/lbaselib.o\
build/lcode.o\
build/ldblib.o\
build/ldebug.o\
build/ldo.o\
build/ldump.o\
build/lfunc.o\
build/lgc.o\
build/linit.o\
build/liolib.o\
build/llex.o\
build/lmathlib.o\
build/lmem.o\
build/loadlib.o\
build/lobject.o\
build/lopcodes.o\
build/loslib.o\
build/lparser.o\
build/lstate.o\
build/lstring.o\
build/lstrlib.o\
build/ltable.o\
build/ltablib.o\
build/ltm.o\
build/luac.o\
build/lundump.o\
build/lvm.o\
build/lzio.o\
build/print.o\
build/adler32.o\
build/compress.o\
build/crc32.o\
build/deflate.o\
build/gzclose.o\
build/gzlib.o\
build/gzread.o\
build/gzwrite.o\
build/infback.o\
build/inffast.o\
build/inflate.o\
build/inftrees.o\
build/trees.o\
build/uncompr.o\
build/zutil.o\
build/iniFile.o\
build/cSocket.o\
build/cWaterSimulator.o\
build/cFileFormatUpdater.o\
build/cItem.o\
-o MCServer
clean :
@ -492,7 +496,7 @@ clean :
build/cPacket_DestroyEntity.o\
build/cPacket_Disconnect.o\
build/cPacket_EntityEquipment.o\
build/cPacket_CreateInventoryAction.o\
build/cPacket_CreateInventoryAction.o\
build/cPacket_EntityLook.o\
build/cPacket_EntityStatus.o\
build/cPacket_Flying.o\
@ -584,6 +588,8 @@ clean :
build/iniFile.o\
build/cSocket.o\
build/cWaterSimulator.o\
build/cFileFormatUpdater.o\
build/cItem.o\
MCServer
install : MCServer
@ -1346,4 +1352,11 @@ build/cSocket.o : source/cSocket.cpp
build/cWaterSimulator.o : source/cWaterSimulator.cpp
$(CC) $(CC_OPTIONS) source/cWaterSimulator.cpp -c $(INCLUDE) -o build/cWaterSimulator.o
build/cFileFormatUpdater.o : source/cFileFormatUpdater.cpp
$(CC) $(CC_OPTIONS) source/cFileFormatUpdater.cpp -c $(INCLUDE) -o build/cFileFormatUpdater.o
build/cItem.o : source/cItem.cpp
$(CC) $(CC_OPTIONS) source/cItem.cpp -c $(INCLUDE) -o build/cItem.o
##### END RUN ####

View File

@ -111,14 +111,8 @@ bool cChestEntity::LoadFromJson( const Json::Value& a_Value )
int SlotIdx = 0;
for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr )
{
Json::Value & Slot = *itr;
cItem Item;
Item.m_ItemID = (ENUM_ITEM_ID)Slot.get("ID", -1 ).asInt();
if( Item.m_ItemID > 0 )
{
Item.m_ItemCount = (char)Slot.get("Count", -1 ).asInt();
Item.m_ItemHealth = (short)Slot.get("Health", -1 ).asInt();
}
Item.FromJson( *itr );
SetSlot( SlotIdx, Item );
SlotIdx++;
}
@ -137,15 +131,7 @@ void cChestEntity::SaveToJson( Json::Value& a_Value )
{
Json::Value Slot;
cItem* Item = GetSlot( i );
if( Item )
{
Slot["ID"] = Item->m_ItemID;
if( Item->m_ItemID > 0 )
{
Slot["Count"] = Item->m_ItemCount;
Slot["Health"] = Item->m_ItemHealth;
}
}
if( Item ) Item->GetJson( Slot );
AllSlots.append( Slot );
}
a_Value["Slots"] = AllSlots;

View File

@ -0,0 +1,185 @@
#include "cFileFormatUpdater.h"
#include "cMCLogger.h"
#include "Vector3d.h"
#include "Vector3f.h"
#include <string>
#include <list>
#include <stdio.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#else
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <vector>
#include <string>
#include <iostream>
#include <cstdio>
#endif
#include "cItem.h"
#include <json/json.h>
typedef std::list< std::string > StringList;
StringList GetDirectoryContents( const char* a_Directory );
void cFileFormatUpdater::UpdateFileFormat()
{
UpdatePlayersOfWorld("world");
}
// Convert player .bin files to JSON
void cFileFormatUpdater::UpdatePlayersOfWorld( const char* a_WorldName )
{
std::string PlayerDir = std::string( a_WorldName ) + "/player/";
StringList AllFiles = GetDirectoryContents( PlayerDir.c_str() );
for( StringList::iterator itr = AllFiles.begin(); itr != AllFiles.end(); ++itr )
{
std::string & FileName = *itr;
if( FileName.rfind(".bin") != std::string::npos ) // Get only the files ending in .bin
{
PlayerBINtoJSON( (PlayerDir + FileName).c_str() );
}
}
}
// Converts player binary files to human readable JSON
void cFileFormatUpdater::PlayerBINtoJSON( const char* a_FileName )
{
Vector3d PlayerPos;
Vector3f PlayerRot;
short PlayerHealth;
const unsigned int NumInventorySlots = 45; // At this time the player inventory has/had 45 slots
cItem IventoryItems[ NumInventorySlots ];
FILE* f;
#ifdef _WIN32
if( fopen_s(&f, a_FileName, "rb" ) == 0 ) // no error
#else
if( (f = fopen(a_FileName, "rb" ) ) != 0 ) // no error
#endif
{
// First read player position, rotation and health
if( fread( &PlayerPos.x, sizeof(double), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", a_FileName); fclose(f); return; }
if( fread( &PlayerPos.y, sizeof(double), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", a_FileName); fclose(f); return; }
if( fread( &PlayerPos.z, sizeof(double), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", a_FileName); fclose(f); return; }
if( fread( &PlayerRot.x, sizeof(float), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", a_FileName); fclose(f); return; }
if( fread( &PlayerRot.y, sizeof(float), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", a_FileName); fclose(f); return; }
if( fread( &PlayerRot.z, sizeof(float), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", a_FileName); fclose(f); return; }
if( fread( &PlayerHealth, sizeof(short), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", a_FileName); fclose(f); return; }
for(unsigned int i = 0; i < NumInventorySlots; i++)
{
cItem & Item = IventoryItems[i];
if( fread( &Item.m_ItemID, sizeof(Item.m_ItemID), 1, f) != 1 ) { LOGERROR("ERROR READING INVENTORY FROM FILE"); return; }
if( fread( &Item.m_ItemCount, sizeof(Item.m_ItemCount), 1, f) != 1 ) { LOGERROR("ERROR READING INVENTORY FROM FILE"); return; }
if( fread( &Item.m_ItemHealth, sizeof(Item.m_ItemHealth), 1, f)!= 1 ) { LOGERROR("ERROR READING INVENTORY FROM FILE"); return; }
}
fclose(f);
}
// Loaded all the data, now create the JSON data
Json::Value JSON_PlayerPosition;
JSON_PlayerPosition.append( Json::Value( PlayerPos.x ) );
JSON_PlayerPosition.append( Json::Value( PlayerPos.y ) );
JSON_PlayerPosition.append( Json::Value( PlayerPos.z ) );
Json::Value JSON_PlayerRotation;
JSON_PlayerRotation.append( Json::Value( PlayerRot.x ) );
JSON_PlayerRotation.append( Json::Value( PlayerRot.y ) );
JSON_PlayerRotation.append( Json::Value( PlayerRot.z ) );
Json::Value JSON_Inventory;
for(unsigned int i = 0; i < NumInventorySlots; i++)
{
Json::Value JSON_Item;
IventoryItems[i].GetJson( JSON_Item );
JSON_Inventory.append( JSON_Item );
}
Json::Value root;
root["position"] = JSON_PlayerPosition;
root["rotation"] = JSON_PlayerRotation;
root["inventory"] = JSON_Inventory;
root["health"] = PlayerHealth;
Json::StyledWriter writer;
std::string JsonData = writer.write( root );
// Get correct filename
std::string FileName = a_FileName;
std::string FileNameWithoutExt = FileName.substr(0, FileName.find_last_of(".") );
std::string FileNameJson = FileNameWithoutExt + ".json";
// Write to file
#ifdef _WIN32
if( fopen_s(&f, FileNameJson.c_str(), "wb" ) == 0 ) // no error
#else
if( (f = fopen(FileNameJson.c_str(), "wb" ) ) != 0 ) // no error
#endif
{
if( fwrite( JsonData.c_str(), JsonData.size(), 1, f ) != 1 ) { LOGERROR("ERROR WRITING PLAYER JSON TO FILE %s", FileNameJson.c_str() ); return; }
fclose( f );
}
// Delete old format file, only do this when conversion has succeeded
if( std::remove( a_FileName ) != 0 )
{
LOGERROR("COULD NOT DELETE FILE %s", a_FileName );
return;
}
LOGINFO("Successfully converted binary to Json %s", FileNameJson.c_str() );
}
// Helper function
StringList GetDirectoryContents( const char* a_Directory )
{
StringList AllFiles;
#ifdef _WIN32
std::string FileFilter = std::string( a_Directory ) + "*.*";
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
if( ( hFind = FindFirstFile(FileFilter.c_str(), &FindFileData) ) != INVALID_HANDLE_VALUE)
{
do
{
AllFiles.push_back( FindFileData.cFileName );
} while( FindNextFile(hFind, &FindFileData) );
FindClose(hFind);
}
#else
DIR *dp;
struct dirent *dirp;
if( (dp = opendir( a_Directory ) ) == NULL)
{
LOGERROR("Error (%i) opening %s\n", errno, a_Directory );
}
else
{
while ((dirp = readdir(dp)) != NULL)
{
AllFiles.push_back( dirp->d_name );
}
closedir(dp);
}
#endif
return AllFiles;
}

View File

@ -0,0 +1,11 @@
#pragma once
class cFileFormatUpdater
{
public:
static void UpdateFileFormat();
private:
static void UpdatePlayersOfWorld( const char* a_WorldName );
static void PlayerBINtoJSON( const char* a_FileName );
};

View File

@ -288,14 +288,7 @@ bool cFurnaceEntity::LoadFromJson( const Json::Value& a_Value )
int SlotIdx = 0;
for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr )
{
Json::Value & Slot = *itr;
cItem & Item = m_Items[ SlotIdx ];
Item.m_ItemID = (ENUM_ITEM_ID)Slot.get("ID", -1 ).asInt();
if( Item.m_ItemID > 0 )
{
Item.m_ItemCount = (char)Slot.get("Count", -1 ).asInt();
Item.m_ItemHealth = (short)Slot.get("Health", -1 ).asInt();
}
m_Items[ SlotIdx ].FromJson( *itr );
SlotIdx++;
}
@ -304,12 +297,7 @@ bool cFurnaceEntity::LoadFromJson( const Json::Value& a_Value )
if( !JsonItem.empty() )
{
cItem Item;
Item.m_ItemID = (ENUM_ITEM_ID)JsonItem.get("ID", -1).asInt();
if( Item.m_ItemID > 0 )
{
Item.m_ItemCount = (char)JsonItem.get("Count", -1).asInt();
Item.m_ItemHealth = (short)JsonItem.get("Health", -1).asInt();
}
Item.FromJson( JsonItem );
if( !Item.IsEmpty() )
{
m_CookingItem = new cItem( Item );
@ -335,13 +323,7 @@ void cFurnaceEntity::SaveToJson( Json::Value& a_Value )
for(unsigned int i = 0; i < 3; i++)
{
Json::Value Slot;
cItem & Item = m_Items[ i ];
Slot["ID"] = Item.m_ItemID;
if( Item.m_ItemID > 0 )
{
Slot["Count"] = Item.m_ItemCount;
Slot["Health"] = Item.m_ItemHealth;
}
m_Items[ i ].GetJson( Slot );
AllSlots.append( Slot );
}
a_Value["Slots"] = AllSlots;
@ -350,12 +332,7 @@ void cFurnaceEntity::SaveToJson( Json::Value& a_Value )
if( m_CookingItem )
{
Json::Value JsonItem;
JsonItem["ID"] = m_CookingItem->m_ItemID;
if( m_CookingItem->m_ItemID > 0 )
{
JsonItem["Count"] = m_CookingItem->m_ItemCount;
JsonItem["Health"] = m_CookingItem->m_ItemHealth;
}
m_CookingItem->GetJson( JsonItem );
a_Value["Cooking"] = JsonItem;
}

View File

@ -8,6 +8,8 @@
#include "cRecipeChecker.h"
#include "cRoot.h"
#include <json/json.h>
#include "packets/cPacket_WindowClick.h"
#include "packets/cPacket_WholeInventory.h"
#include "packets/cPacket_InventorySlot.h"
@ -340,25 +342,23 @@ void cInventory::DrawInventory()
}
}
void cInventory::WriteToFile(FILE* a_File)
void cInventory::SaveToJson(Json::Value & a_Value)
{
for(unsigned int i = 0; i < c_NumSlots; i++)
{
cItem & Item = m_Slots[i];
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 );
Json::Value JSON_Item;
m_Slots[i].GetJson( JSON_Item );
a_Value.append( JSON_Item );
}
}
bool cInventory::LoadFromFile(FILE* a_File)
bool cInventory::LoadFromJson(Json::Value & a_Value)
{
for(unsigned int i = 0; i < c_NumSlots; i++)
int SlotIdx = 0;
for( Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr )
{
cItem & Item = m_Slots[i];
if( fread( &Item.m_ItemID, sizeof(Item.m_ItemID), 1, a_File) != 1 ) { LOGERROR("ERROR READING INVENTORY FROM FILE"); return false; }
if( fread( &Item.m_ItemCount, sizeof(Item.m_ItemCount), 1, a_File) != 1 ) { LOGERROR("ERROR READING INVENTORY FROM FILE"); return false; }
if( fread( &Item.m_ItemHealth, sizeof(Item.m_ItemHealth), 1, a_File)!= 1 ) { LOGERROR("ERROR READING INVENTORY FROM FILE"); return false; }
m_Slots[SlotIdx].FromJson( *itr );
SlotIdx++;
}
return true;
}

View File

@ -4,6 +4,11 @@
#include "cWindowOwner.h"
#include "FileDefine.h"
namespace Json
{
class Value;
};
class cItem;
class cClientHandle;
class cPlayer;
@ -25,8 +30,8 @@ public:
bool RemoveItem( cItem & a_Item ); //tolua_export
void DrawInventory();
void WriteToFile(FILE* a_File);
bool LoadFromFile(FILE* a_File);
void SaveToJson(Json::Value & a_Value);
bool LoadFromJson(Json::Value & a_Value);
void SendWholeInventory( cClientHandle* a_Client );

22
source/cItem.cpp Normal file
View File

@ -0,0 +1,22 @@
#include "cItem.h"
#include <json/json.h>
void cItem::GetJson( Json::Value & a_OutValue )
{
a_OutValue["ID"] = m_ItemID;
if( m_ItemID > 0 )
{
a_OutValue["Count"] = m_ItemCount;
a_OutValue["Health"] = m_ItemHealth;
}
}
void cItem::FromJson( const Json::Value & a_Value )
{
m_ItemID = (ENUM_ITEM_ID)a_Value.get("ID", -1 ).asInt();
if( m_ItemID > 0 )
{
m_ItemCount = (char)a_Value.get("Count", -1 ).asInt();
m_ItemHealth = (short)a_Value.get("Health", -1 ).asInt();
}
}

View File

@ -3,6 +3,11 @@
#include "Defines.h"
#include "BlockID.h"
namespace Json
{
class Value;
};
class cItem //tolua_export
{ //tolua_export
public:
@ -27,6 +32,10 @@ public:
{ //tolua_export
return ( (m_ItemID == a_Item.m_ItemID) && (m_ItemHealth == a_Item.m_ItemHealth) );
} //tolua_export
void GetJson( Json::Value & a_OutValue ); //tolua_export
void FromJson( const Json::Value & a_Value ); //tolua_export
ENUM_ITEM_ID m_ItemID; //tolua_export
char m_ItemCount; //tolua_export
short m_ItemHealth; //tolua_export

View File

@ -32,6 +32,7 @@
#include "Vector3f.h"
#include "../iniFile/iniFile.h"
#include <json/json.h>
#ifndef _WIN32 // for mkdir
#include <sys/stat.h>
@ -636,7 +637,7 @@ bool cPlayer::LoadFromDisk()
}
char SourceFile[128];
sprintf_s(SourceFile, 128, "world/player/%s.bin", m_pState->PlayerName.c_str() );
sprintf_s(SourceFile, 128, "world/player/%s.json", m_pState->PlayerName.c_str() );
FILE* f;
#ifdef _WIN32
@ -645,15 +646,43 @@ bool cPlayer::LoadFromDisk()
if( (f = fopen(SourceFile, "rb" ) ) != 0 ) // no error
#endif
{
if( fread( &m_Pos->x, sizeof(double), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
if( fread( &m_Pos->y, sizeof(double), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
if( fread( &m_Pos->z, sizeof(double), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
if( fread( &m_Rot->x, sizeof(float), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
if( fread( &m_Rot->y, sizeof(float), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
if( fread( &m_Rot->z, sizeof(float), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
if( fread( &m_Health, sizeof(m_Health), 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
if( !m_Inventory->LoadFromFile( f ) ) { LOGERROR("ERROR READING INVENTORY FROM FILE %s", SourceFile); fclose(f); return false; }
// Get file size
fseek (f , 0 , SEEK_END);
long FileSize = ftell (f);
rewind(f);
char* buffer = new char[ FileSize ];
if( fread( buffer, FileSize, 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
fclose(f);
Json::Value root;
Json::Reader reader;
if( !reader.parse( buffer, root, false ) )
{
LOGERROR("ERROR WHILE PARSING JSON FROM FILE %s", SourceFile);
}
delete [] buffer;
Json::Value & JSON_PlayerPosition = root["position"];
if( JSON_PlayerPosition.size() == 3 )
{
m_Pos->x = JSON_PlayerPosition[(unsigned int)0].asDouble();
m_Pos->y = JSON_PlayerPosition[(unsigned int)1].asDouble();
m_Pos->z = JSON_PlayerPosition[(unsigned int)2].asDouble();
}
Json::Value & JSON_PlayerRotation = root["rotation"];
if( JSON_PlayerRotation.size() == 3 )
{
m_Rot->x = (float)JSON_PlayerRotation[(unsigned int)0].asDouble();
m_Rot->y = (float)JSON_PlayerRotation[(unsigned int)1].asDouble();
m_Rot->z = (float)JSON_PlayerRotation[(unsigned int)2].asDouble();
}
m_Health = root.get("health", 0 ).asInt();
m_Inventory->LoadFromJson(root["inventory"]);
return true;
}
return false;
@ -677,8 +706,31 @@ bool cPlayer::SaveToDisk()
}
#endif
// create the JSON data
Json::Value JSON_PlayerPosition;
JSON_PlayerPosition.append( Json::Value( m_Pos->x ) );
JSON_PlayerPosition.append( Json::Value( m_Pos->y ) );
JSON_PlayerPosition.append( Json::Value( m_Pos->z ) );
Json::Value JSON_PlayerRotation;
JSON_PlayerRotation.append( Json::Value( m_Rot->x ) );
JSON_PlayerRotation.append( Json::Value( m_Rot->y ) );
JSON_PlayerRotation.append( Json::Value( m_Rot->z ) );
Json::Value JSON_Inventory;
m_Inventory->SaveToJson( JSON_Inventory );
Json::Value root;
root["position"] = JSON_PlayerPosition;
root["rotation"] = JSON_PlayerRotation;
root["inventory"] = JSON_Inventory;
root["health"] = m_Health;
Json::StyledWriter writer;
std::string JsonData = writer.write( root );
char SourceFile[128];
sprintf_s(SourceFile, 128, "world/player/%s.bin", m_pState->PlayerName.c_str() );
sprintf_s(SourceFile, 128, "world/player/%s.json", m_pState->PlayerName.c_str() );
FILE* f;
#ifdef _WIN32
@ -687,14 +739,7 @@ bool cPlayer::SaveToDisk()
if( (f = fopen(SourceFile, "wb" ) ) != 0 ) // no error
#endif
{
fwrite( &m_Pos->x, sizeof(double), 1, f );
fwrite( &m_Pos->y, sizeof(double), 1, f );
fwrite( &m_Pos->z, sizeof(double), 1, f );
fwrite( &m_Rot->x, sizeof(float), 1, f );
fwrite( &m_Rot->y, sizeof(float), 1, f );
fwrite( &m_Rot->z, sizeof(float), 1, f );
fwrite( &m_Health, sizeof(m_Health), 1, f );
m_Inventory->WriteToFile( f );
if( fwrite( JsonData.c_str(), JsonData.size(), 1, f ) != 1 ) { LOGERROR("ERROR WRITING PLAYER JSON TO FILE %s", SourceFile ); return false; }
fclose(f);
return true;
}

View File

@ -10,6 +10,7 @@
#include "cMonsterConfig.h"
#include "cSleep.h"
#include "cThread.h"
#include "cFileFormatUpdater.h"
#include "../iniFile/iniFile.h"
@ -67,6 +68,8 @@ void cRoot::Start()
{
m_bRestart = false;
cFileFormatUpdater::UpdateFileFormat();
m_Server = new cServer();
cIniFile IniFile("settings.ini"); IniFile.ReadFile();