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 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
|
#include "pilotfile/pilotfile_convert.h"
#include "playerman/managepilot.h"
#include "playerman/player.h"
pilotfile_convert::pilotfile_convert()
{
fver = 0;
m_size_offset = 0;
cfp = NULL;
plr = NULL;
csg = NULL;
}
pilotfile_convert::~pilotfile_convert()
{
if (cfp) {
cfclose(cfp);
}
if (plr) {
delete plr;
}
if (csg) {
delete csg;
}
}
void pilotfile_convert::startSection(Section section_id)
{
Assert( cfp );
const int zero = 0;
cfwrite_ushort( (ushort)section_id, cfp );
// to be updated when endSection() is called
cfwrite_int(zero, cfp);
// starting offset, for size of section
m_size_offset = cftell(cfp);
}
void pilotfile_convert::endSection()
{
Assert( cfp );
Assert( m_size_offset > 0 );
size_t cur = cftell(cfp);
Assert( cur >= m_size_offset );
size_t section_size = cur - m_size_offset;
if (section_size) {
// go back to section size in file and write proper value
cfseek(cfp, (int)(cur - section_size - sizeof(int)), CF_SEEK_SET);
cfwrite_int((int)section_size, cfp);
// go back to previous location for next section
cfseek(cfp, (int)cur, CF_SEEK_SET);
}
}
/**
* @brief Converts retail pilots to the "new" binary style
*/
static void convert_retail_pilot_files()
{
size_t idx, j, i;
size_t count, inf_count;
int max_convert, num_converted = 0;
SCP_vector<SCP_string> existing;
SCP_vector<SCP_string> old_files;
// get list of pilots which already exist (new or converted already)
cf_get_file_list(existing, CF_TYPE_PLAYERS, "*.plr", CF_SORT_NONE, nullptr,
CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
// get list of old pilots which may need converting, starting with inferno pilots
Get_file_list_child = "inferno";
cf_get_file_list(old_files, CF_TYPE_SINGLE_PLAYERS, "*.pl2", CF_SORT_NONE, nullptr,
CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
inf_count = old_files.size();
cf_get_file_list(old_files, CF_TYPE_SINGLE_PLAYERS, "*.pl2", CF_SORT_NONE, nullptr,
CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
if ( old_files.empty() ) {
return;
}
// rip out all files which already exist
i = 0;
count = old_files.size();
for (idx = 0; idx < existing.size(); idx++) {
const char *fname = existing[idx].c_str();
for (j = 0; j < count; j++) {
if ( !stricmp(fname, old_files[j].c_str()) ) {
// NOTE: we just clear the name here to avoid the fragmentation
// from resizing the vector
old_files[j] = "";
++i;
}
}
}
// don't convert enough pilots to exceed the pilot limit
max_convert = MAX_PILOTS - (int)existing.size();
// if everything is already converted then bail
// also bail if MAX_PILOTS (or more!) already exist
if (i == count || max_convert <= 0) {
return;
}
mprintf(("PILOT: Beginning pilot file conversion...\n"));
// now proceed to convert all of the old files
count = old_files.size();
for (idx = 0; idx < count; idx++) {
if ( old_files[idx].empty() ) {
continue;
}
pilotfile_convert *pcon = new pilotfile_convert;
bool inferno = (idx < inf_count);
if ( pcon->plr_convert(old_files[idx].c_str(), inferno) ) {
SCP_vector<SCP_string> savefiles;
SCP_string wildcard(old_files[idx]);
wildcard.append("*.cs2");
if (inferno) {
Get_file_list_child = "inferno";
}
cf_get_file_list(savefiles, CF_TYPE_SINGLE_PLAYERS, wildcard.c_str(), CF_SORT_NONE, nullptr,
CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
for (j = 0; j < savefiles.size(); j++) {
pcon->csg_convert(savefiles[j].c_str(), inferno);
}
++num_converted;
}
delete pcon;
if (num_converted >= max_convert) {
break;
}
}
mprintf(("PILOT: Pilot file conversion complete!\n"));
}
/**
* @brief Converts the binary pilots into the JSON representation
*
* This only converts the main pilot file to JSON at the moment to make debugging easier if something is wrong
*/
static void convert_binary_pilot_files() {
SCP_vector<SCP_string> binary_pilots;
SCP_vector<SCP_string> json_pilots;
// get list of binary pilot files
cf_get_file_list(binary_pilots, CF_TYPE_PLAYERS, "*.plr", 0, nullptr,
CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
// get list of existing json pilot files
cf_get_file_list(json_pilots, CF_TYPE_PLAYERS, "*.json", 0, nullptr,
CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
for (auto& binary_pilot : binary_pilots) {
for (auto& json_pilot : json_pilots) {
// The file extensions are already removed so we can just compare the iterator values
if (binary_pilot == json_pilot) {
// pilot was already converted. We just set this to the empty string to remove it from the list
binary_pilot = "";
}
}
}
// binary_pilots now contains all unconverted pilots
for (auto& callsign : binary_pilots) {
if (callsign.empty()) {
// This pilot already has a json pilot
continue;
}
// This is simple, read the binary pilot and then write it again as JSON
pilotfile file;
player plr; // Player struct to save the loaded values in
plr.reset();
if (!file.load_player(callsign.c_str(), &plr, true)) {
mprintf(("Failed to load binary pilot '%s'!\n", callsign.c_str()));
continue;
}
if (!file.save_player(&plr)) {
mprintf(("Failed to save JSON pilot '%s'!\n", callsign.c_str()));
continue;
}
mprintf(("Pilot '%s' was successfully converted to JSON.\n", callsign.c_str()));
}
}
void convert_pilot_files() {
convert_retail_pilot_files();
convert_binary_pilot_files();
}
|