c2b43f33da
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
185 lines
5.6 KiB
C++
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;
|
|
|
|
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;
|
|
} |