summaryrefslogtreecommitdiffstats
path: root/source/cFileFormatUpdater.cpp
blob: 8516b5b4032c4de0464fc307dc1fd497bc1cf4e7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
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;
}