From fe477bd5c2b330817d05d63b9360b4b1b322143d Mon Sep 17 00:00:00 2001 From: Roy Falk Date: Sat, 30 Nov 2024 18:43:58 +0200 Subject: [PATCH] Switch save game to json --- engine/src/cmd/csv.cpp | 23 ------ engine/src/cmd/unit_csv.cpp | 31 ++++++++- engine/src/cmd/unit_csv_factory.cpp | 100 --------------------------- engine/src/cmd/unit_csv_factory.h | 2 - engine/src/cmd/unit_generic.cpp | 6 +- engine/src/cmd/unit_json_factory.cpp | 13 ++-- engine/src/cmd/unit_json_factory.h | 2 +- engine/src/options.cpp | 1 - engine/src/savegame.cpp | 4 +- engine/src/universe.cpp | 19 ----- 10 files changed, 44 insertions(+), 157 deletions(-) diff --git a/engine/src/cmd/csv.cpp b/engine/src/cmd/csv.cpp index b49a3c826a..a67af60b99 100644 --- a/engine/src/cmd/csv.cpp +++ b/engine/src/cmd/csv.cpp @@ -198,29 +198,6 @@ CSVTable::CSVTable(const string &data, const string &root) { } CSVTable::CSVTable(VSFileSystem::VSFile &f, const string &root) { - /*if (f.GetFilename() == "units_description.csv" || - f.GetFilename() == "master_part_list.csv") { - } else if (f.GetFilename() == "units.csv") { - VSFileSystem::VSFile jsonFile; - VSFileSystem::VSError err = jsonFile.OpenReadOnly("units.json", VSFileSystem::UnitFile); - if (err <= VSFileSystem::Ok) { - UnitJSONFactory::ParseJSON(jsonFile); - } - jsonFile.Close(); - }*/ - - if (f.GetFilename() == "units_description.csv" || - f.GetFilename() == "master_part_list.csv") { - // Not the CSV file we expect. Will crash unit_csv_factory - } /*else if (f.GetFilename() != "units.csv") { - // Open a saved game. - std::cerr << "Parsing " << f.GetFilename() << std::endl; - //abort(); - UnitCSVFactory factory; - factory.ParseCSV(f, true); - f.Begin(); - }*/ - std::string data = f.ReadFull(); this->rootdir = root; Init(data); diff --git a/engine/src/cmd/unit_csv.cpp b/engine/src/cmd/unit_csv.cpp index a5c7103132..f2cfef598b 100644 --- a/engine/src/cmd/unit_csv.cpp +++ b/engine/src/cmd/unit_csv.cpp @@ -63,7 +63,30 @@ extern void pushMesh(std::vector &mesh, void addShieldMesh(Unit::XML *xml, const char *filename, const float scale, int faction, class Flightgroup *fg); void addRapidMesh(Unit::XML *xml, const char *filename, const float scale, int faction, class Flightgroup *fg); +// TODO: This is a terrible kludge. Replace with boost::json +std::string MapToJson(std::map unit) { + std::string json_string = "[\n\t{\n"; + + int len = unit.size(); + int i = 0; + + for (auto const& pair : unit) { + std::cout << pair.first << " = " << pair.second << std::endl; + boost::format new_line; + if(i < len-1) { + new_line = boost::format("\t\t\"%1%\": \"%2%\",\n") % pair.first % pair.second; + } else { + new_line = boost::format("\t\t\"%1%\": \"%2%\"\n") % pair.first % pair.second; + } + + i++; + json_string += new_line.str(); + } + json_string += "\t}\n]\n"; + + return json_string; +} void AddMeshes(std::vector &xmeshes, float &randomstartframe, @@ -1088,12 +1111,14 @@ void Unit::WriteUnit(const char *modifications) { std::string savedir = modifications; VSFileSystem::CreateDirectoryHome(VSFileSystem::savedunitpath + "/" + savedir); VSFileSystem::VSFile f; - VSFileSystem::VSError err = f.OpenCreateWrite(savedir + "/" + name + ".csv", VSFileSystem::UnitFile); + VSFileSystem::VSError err = f.OpenCreateWrite(savedir + "/" + name + ".json", VSFileSystem::UnitFile); if (err > VSFileSystem::Ok) { VS_LOG(error, (boost::format("!!! ERROR : Writing saved unit file : %1%") % f.GetFullPath().c_str())); return; } - std::string towrite = WriteUnitString(); + + std::map map = UnitToMap(); + std::string towrite = MapToJson(map); f.Write(towrite.c_str(), towrite.length()); f.Close(); } @@ -1356,6 +1381,8 @@ const std::map Unit::UnitToMap() { return unit; } + + string Unit::WriteUnitString() { std::map unit = UnitToMap(); return writeCSV(unit); diff --git a/engine/src/cmd/unit_csv_factory.cpp b/engine/src/cmd/unit_csv_factory.cpp index 0f0951c393..d0bf43763c 100644 --- a/engine/src/cmd/unit_csv_factory.cpp +++ b/engine/src/cmd/unit_csv_factory.cpp @@ -35,106 +35,6 @@ std::map> UnitCSVFactory::units; // This is probably unique enough to ensure no collision std::string UnitCSVFactory::DEFAULT_ERROR_VALUE = "UnitCSVFactory::_GetVariable DEFAULT_ERROR_VALUE"; -void ExtractColumns(std::string &line) { - std::string data(line); - std::string delimiter = ","; - size_t pos = 0; - std::string token; - - while ((pos = data.find(delimiter)) != std::string::npos) { - token = data.substr(0, pos); - data.erase(0, pos + delimiter.length()); - } -} - -int line_num = 1; - -/** - * @brief ProcessLine is a slightly complicated CSV parsing, as it - * needs to account for quotes and commas within these quotes. - * This code won't work if there are quotes within quotes. - * @param line - the input string - */ -std::vector ProcessLine(std::string &line) { - std::string data(line); - std::vector cells; - - std::string token; - - size_t comma_index = data.find(","); - size_t quote_index = data.find("\""); - - while (comma_index != std::string::npos) { - // Start quote - if (quote_index < comma_index) { - // End quote - quote_index = data.find("\"", quote_index + 1); - // Comma after quote - comma_index = data.find(",", quote_index); - } - - token = data.substr(0, comma_index); - data.erase(0, comma_index + 1); - - // If token starts and ends with a quote, remove them - if (token[0] == '"' && token[token.size() - 1] == '"') { - token = token.substr(1, token.size() - 2); - } - - cells.push_back(token); - - comma_index = data.find(","); - quote_index = data.find("\""); - } - - token = data.substr(0, comma_index); - cells.push_back(token); - - return cells; -} - -void UnitCSVFactory::ParseCSV(std::string data, std::string root, bool saved_game) { - std::vector columns; - std::string delimiter = "\n"; - size_t pos = 0; - std::string token; - bool first_line = true; - - line_num = 1; - - // Add newline to end of file, so last line will be processed. - if (!data.empty() && data.back() != '\n') { - data.append("\n"); - } - - while ((pos = data.find(delimiter)) != std::string::npos) { - token = data.substr(0, pos); - if (first_line) { - columns = ProcessLine(token); - - first_line = false; - } else { - - std::vector line = ProcessLine(token); - std::map unit_attributes; - - for (unsigned int i = 1; i < columns.size(); i++) { - unit_attributes[columns[i]] = line[i]; - } - - // Add root - unit_attributes["root"] = root; - - std::string key = (saved_game ? "player_ship" : line[0]); - - if(!key.empty()) { - UnitCSVFactory::units[key] = unit_attributes; - } - } - data.erase(0, pos + delimiter.length()); - } -} - // TODO: place this somewhere else with similar code from unit_csv std::string GetUnitKeyFromNameAndFaction(const std::string unit_name, const std::string unit_faction) { diff --git a/engine/src/cmd/unit_csv_factory.h b/engine/src/cmd/unit_csv_factory.h index 5dcc613cde..c37d305e0d 100644 --- a/engine/src/cmd/unit_csv_factory.h +++ b/engine/src/cmd/unit_csv_factory.h @@ -109,8 +109,6 @@ class UnitCSVFactory { friend class UnitJSONFactory; friend class UnitOptimizeFactory; public: - static void ParseCSV(std::string data, std::string root, bool saved_game); - template static inline T GetVariable(std::string unit_key, std::string const &attribute_key, T default_value) = delete; static bool HasVariable(std::string unit_key, std::string const &attribute_key) { diff --git a/engine/src/cmd/unit_generic.cpp b/engine/src/cmd/unit_generic.cpp index 7d2687c3a5..37b0f76de4 100644 --- a/engine/src/cmd/unit_generic.cpp +++ b/engine/src/cmd/unit_generic.cpp @@ -77,6 +77,7 @@ #include "resource/resource.h" #include "base_util.h" #include "unit_csv_factory.h" +#include "unit_json_factory.h" #include "savegame.h" #include "manifest.h" @@ -448,10 +449,9 @@ void Unit::Init(const char *filename, //Try to open save if (filename[0]) { VSFile unitTab; - VSError taberr = unitTab.OpenReadOnly(filepath + ".csv", UnitSaveFile); + VSError taberr = unitTab.OpenReadOnly(filepath + ".json", UnitSaveFile); if (taberr <= Ok) { - std::string data = unitTab.ReadFull(); - UnitCSVFactory::ParseCSV(data, unitTab.GetRoot(), true); + UnitJSONFactory::ParseJSON(unitTab, true); unitTab.Close(); saved_game = true; } diff --git a/engine/src/cmd/unit_json_factory.cpp b/engine/src/cmd/unit_json_factory.cpp index c86e3ec229..28216c41a5 100644 --- a/engine/src/cmd/unit_json_factory.cpp +++ b/engine/src/cmd/unit_json_factory.cpp @@ -35,7 +35,7 @@ #include "json.h" -void UnitJSONFactory::ParseJSON(VSFileSystem::VSFile &file) { +void UnitJSONFactory::ParseJSON(VSFileSystem::VSFile &file, bool player_ship) { const std::string json_text = file.ReadFull(); std::vector units = json::parsing::parse_array(json_text.c_str()); @@ -58,9 +58,14 @@ void UnitJSONFactory::ParseJSON(VSFileSystem::VSFile &file) { // Add root unit_attributes["root"] = file.GetRoot(); - std::string unit_key = unit.get("Key"); - std::string stripped_unit_key = unit_key.substr(1, unit_key.size() - 2); + - UnitCSVFactory::units[stripped_unit_key] = unit_attributes; + if(player_ship) { + UnitCSVFactory::units["player_ship"] = unit_attributes; + } else { + std::string unit_key = unit.get("Key"); + std::string stripped_unit_key = unit_key.substr(1, unit_key.size() - 2); + UnitCSVFactory::units[stripped_unit_key] = unit_attributes; + } } } diff --git a/engine/src/cmd/unit_json_factory.h b/engine/src/cmd/unit_json_factory.h index 83905e8ef3..9d3479fac0 100644 --- a/engine/src/cmd/unit_json_factory.h +++ b/engine/src/cmd/unit_json_factory.h @@ -32,6 +32,6 @@ class UnitJSONFactory { static std::string DEFAULT_ERROR_VALUE; public: - static void ParseJSON(VSFileSystem::VSFile &file); + static void ParseJSON(VSFileSystem::VSFile &file, bool player_ship = false); }; #endif //VEGA_STRIKE_ENGINE_CMD_UNIT_JSON_FACTORY_H diff --git a/engine/src/options.cpp b/engine/src/options.cpp index efe411ff9b..a731bb4245 100644 --- a/engine/src/options.cpp +++ b/engine/src/options.cpp @@ -312,7 +312,6 @@ void vs_options::init() { universe_path = vs_config->getVariable("data", "universe_path", "universe"); sectors = vs_config->getVariable("data", "sectors", "sectors"); techniquesBasePath = vs_config->getVariable("data", "techniques", "techniques"); - unitCSV = vs_config->getVariable("data", "UnitCSV", "units.csv"); modUnitCSV = vs_config->getVariable("data", "ModUnitCSV", ""); cockpits = vs_config->getVariable("data", "cockpits", "cockpits"); animations = vs_config->getVariable("data", "animations", "animations"); diff --git a/engine/src/savegame.cpp b/engine/src/savegame.cpp index 9c433a10c7..c4ae22c409 100644 --- a/engine/src/savegame.cpp +++ b/engine/src/savegame.cpp @@ -421,10 +421,10 @@ void CopySavedShips(std::string filename, int player_num, const std::vector