summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfaketruth <faketruth@0a769ca7-a7f5-676a-18bf-c427514a06d6>2011-10-31 22:30:14 +0100
committerfaketruth <faketruth@0a769ca7-a7f5-676a-18bf-c427514a06d6>2011-10-31 22:30:14 +0100
commitc2b43f33da1461939df43657752ffd3651933b6e (patch)
tree7dd0f79d11496bd04bcebe6d2af83e77b6dbcfa4
parentdenotch map converter can now successfully converter an mcr to a vaild pak file. Takes about 20 seconds per region file. (diff)
downloadcuberite-c2b43f33da1461939df43657752ffd3651933b6e.tar
cuberite-c2b43f33da1461939df43657752ffd3651933b6e.tar.gz
cuberite-c2b43f33da1461939df43657752ffd3651933b6e.tar.bz2
cuberite-c2b43f33da1461939df43657752ffd3651933b6e.tar.lz
cuberite-c2b43f33da1461939df43657752ffd3651933b6e.tar.xz
cuberite-c2b43f33da1461939df43657752ffd3651933b6e.tar.zst
cuberite-c2b43f33da1461939df43657752ffd3651933b6e.zip
-rw-r--r--VC2010/MCServer.vcxproj5
-rw-r--r--VC2010/MCServer.vcxproj.filters14
-rw-r--r--makefile23
-rw-r--r--source/cChestEntity.cpp18
-rw-r--r--source/cFileFormatUpdater.cpp185
-rw-r--r--source/cFileFormatUpdater.h11
-rw-r--r--source/cFurnaceEntity.cpp31
-rw-r--r--source/cInventory.cpp22
-rw-r--r--source/cInventory.h9
-rw-r--r--source/cItem.cpp22
-rw-r--r--source/cItem.h9
-rw-r--r--source/cPlayer.cpp81
-rw-r--r--source/cRoot.cpp3
13 files changed, 352 insertions, 81 deletions
diff --git a/VC2010/MCServer.vcxproj b/VC2010/MCServer.vcxproj
index 2c428a718..66ed07b48 100644
--- a/VC2010/MCServer.vcxproj
+++ b/VC2010/MCServer.vcxproj
@@ -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" />
@@ -515,4 +518,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
+</Project> \ No newline at end of file
diff --git a/VC2010/MCServer.vcxproj.filters b/VC2010/MCServer.vcxproj.filters
index 55edac971..2e0ec8324 100644
--- a/VC2010/MCServer.vcxproj.filters
+++ b/VC2010/MCServer.vcxproj.filters
@@ -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">
@@ -1147,4 +1159,4 @@
<ItemGroup>
<ResourceCompile Include="MCServer.rc" />
</ItemGroup>
-</Project>
+</Project> \ No newline at end of file
diff --git a/makefile b/makefile
index fb87b9081..1438549d1 100644
--- a/makefile
+++ b/makefile
@@ -127,7 +127,7 @@ MCServer : \
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\
@@ -218,7 +218,9 @@ MCServer : \
build/zutil.o\
build/iniFile.o\
build/cSocket.o\
- build/cWaterSimulator.o
+ build/cWaterSimulator.o\
+ build/cFileFormatUpdater.o\
+ build/cItem.o
$(CC) $(LNK_OPTIONS) \
build/json_reader.o\
build/json_value.o\
@@ -308,7 +310,7 @@ MCServer : \
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 +402,8 @@ MCServer : \
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
@@ -1342,8 +1348,15 @@ build/cMakeDir.o : source/cMakeDir.cpp
build/cSocket.o : source/cSocket.cpp
$(CC) $(CC_OPTIONS) source/cSocket.cpp -c $(INCLUDE) -o build/cSocket.o
-
+
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 ####
diff --git a/source/cChestEntity.cpp b/source/cChestEntity.cpp
index 54a06fcb9..9ec46014d 100644
--- a/source/cChestEntity.cpp
+++ b/source/cChestEntity.cpp
@@ -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;
diff --git a/source/cFileFormatUpdater.cpp b/source/cFileFormatUpdater.cpp
new file mode 100644
index 000000000..8516b5b40
--- /dev/null
+++ b/source/cFileFormatUpdater.cpp
@@ -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;
+} \ No newline at end of file
diff --git a/source/cFileFormatUpdater.h b/source/cFileFormatUpdater.h
new file mode 100644
index 000000000..fc6beed6e
--- /dev/null
+++ b/source/cFileFormatUpdater.h
@@ -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 );
+}; \ No newline at end of file
diff --git a/source/cFurnaceEntity.cpp b/source/cFurnaceEntity.cpp
index 95f5f566c..36524e3b7 100644
--- a/source/cFurnaceEntity.cpp
+++ b/source/cFurnaceEntity.cpp
@@ -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;
}
diff --git a/source/cInventory.cpp b/source/cInventory.cpp
index e78ac226e..788d38eaa 100644
--- a/source/cInventory.cpp
+++ b/source/cInventory.cpp
@@ -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;
}
diff --git a/source/cInventory.h b/source/cInventory.h
index cebcf346b..7d98af853 100644
--- a/source/cInventory.h
+++ b/source/cInventory.h
@@ -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 );
diff --git a/source/cItem.cpp b/source/cItem.cpp
new file mode 100644
index 000000000..b91a7a316
--- /dev/null
+++ b/source/cItem.cpp
@@ -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();
+ }
+} \ No newline at end of file
diff --git a/source/cItem.h b/source/cItem.h
index edf3468ac..dde0c649b 100644
--- a/source/cItem.h
+++ b/source/cItem.h
@@ -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
diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp
index 898bac54f..fee8df966 100644
--- a/source/cPlayer.cpp
+++ b/source/cPlayer.cpp
@@ -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;
}
diff --git a/source/cRoot.cpp b/source/cRoot.cpp
index 531d0c9f3..55ee28576 100644
--- a/source/cRoot.cpp
+++ b/source/cRoot.cpp
@@ -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();