1
0
cuberite-2a/source/cFileFormatUpdater.cpp
faketruth b5b920deda You can now run multiple worlds by defining them in settings.ini . However there's no way to change worlds on the fly yet
Players are now stored in separate folder /players instead of in the world folder (!so move the folder!)
Fixed a memory leak/error in cPickup.cpp
Multiple worlds are stored in cRoot
cClientHandle lists are taken out of cWorld and now stored in cServer
Worlds now have names to distinguish them by
Some functions in the Core plugin now distinguish between worlds

git-svn-id: http://mc-server.googlecode.com/svn/trunk@40 0a769ca7-a7f5-676a-18bf-c427514a06d6
2011-11-01 21:57:08 +00:00

185 lines
5.6 KiB
C++

#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 = 0;
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;
}