2012-06-29 16:44:26 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// This file is part of Remere's Map Editor
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2020-07-30 11:42:28 -03:00
|
|
|
// Remere's Map Editor is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// Remere's Map Editor is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2012-06-29 16:44:26 +02:00
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
|
|
|
|
|
|
#include "settings.h"
|
|
|
|
|
#include "filehandle.h"
|
|
|
|
|
|
|
|
|
|
#include "gui.h"
|
|
|
|
|
|
|
|
|
|
#include "client_version.h"
|
2019-07-23 10:21:07 -03:00
|
|
|
#include "otml.h"
|
|
|
|
|
#include <wx/dir.h>
|
2012-06-29 16:44:26 +02:00
|
|
|
|
|
|
|
|
// Static methods to load/save
|
|
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
ClientVersion::VersionMap ClientVersion::client_versions;
|
2014-01-22 20:16:17 +01:00
|
|
|
ClientVersion* ClientVersion::latest_version = nullptr;
|
2012-07-01 13:41:59 +02:00
|
|
|
ClientVersion::OtbMap ClientVersion::otb_versions;
|
2012-06-29 16:44:26 +02:00
|
|
|
|
|
|
|
|
void ClientVersion::loadVersions()
|
|
|
|
|
{
|
2012-07-01 13:41:59 +02:00
|
|
|
// Clean up old stuff
|
2012-07-01 16:53:39 +02:00
|
|
|
ClientVersion::unloadVersions();
|
2012-06-29 16:44:26 +02:00
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
// Locate the clients.xml file
|
2012-07-12 12:51:18 +02:00
|
|
|
wxFileName file_to_load;
|
|
|
|
|
|
|
|
|
|
wxFileName exec_dir_client_xml;
|
2016-09-29 20:30:54 -03:00
|
|
|
exec_dir_client_xml.Assign(g_gui.GetExecDirectory());
|
2016-11-05 15:28:14 +01:00
|
|
|
exec_dir_client_xml.SetFullName("clients.xml");
|
2016-09-29 19:24:45 -03:00
|
|
|
|
2012-07-12 12:51:18 +02:00
|
|
|
wxFileName data_dir_client_xml;
|
2016-09-29 20:30:54 -03:00
|
|
|
data_dir_client_xml.Assign(g_gui.GetDataDirectory());
|
2016-11-05 15:28:14 +01:00
|
|
|
data_dir_client_xml.SetFullName("clients.xml");
|
2012-07-12 12:51:18 +02:00
|
|
|
|
2014-01-24 02:33:09 -02:00
|
|
|
wxFileName work_dir_client_xml;
|
2016-09-29 20:30:54 -03:00
|
|
|
work_dir_client_xml.Assign(g_gui.getFoundDataDirectory());
|
2016-11-05 15:28:14 +01:00
|
|
|
work_dir_client_xml.SetFullName("clients.xml");
|
2014-01-24 02:33:09 -02:00
|
|
|
|
2012-07-12 12:51:18 +02:00
|
|
|
file_to_load = exec_dir_client_xml;
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!file_to_load.FileExists()) {
|
2012-07-12 12:51:18 +02:00
|
|
|
file_to_load = data_dir_client_xml;
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!file_to_load.FileExists()) {
|
2014-01-24 02:33:09 -02:00
|
|
|
file_to_load = work_dir_client_xml;
|
|
|
|
|
if(!file_to_load.FileExists()) {
|
|
|
|
|
file_to_load.Clear();
|
|
|
|
|
}
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
2012-07-12 12:51:18 +02:00
|
|
|
}
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!file_to_load.FileExists()) {
|
2012-07-12 12:51:18 +02:00
|
|
|
wxLogError(wxString() +
|
2016-11-05 15:28:14 +01:00
|
|
|
"Could not load clients.xml, editor will NOT be able to load any client data files.\n" +
|
|
|
|
|
"Checked paths:\n" +
|
2012-07-12 12:51:18 +02:00
|
|
|
exec_dir_client_xml.GetFullPath() + "\n" +
|
2014-01-24 02:33:09 -02:00
|
|
|
data_dir_client_xml.GetFullPath() + "\n" +
|
|
|
|
|
work_dir_client_xml.GetFullPath()
|
2012-07-12 12:51:18 +02:00
|
|
|
);
|
|
|
|
|
return;
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
// Parse the file
|
2014-01-22 20:16:17 +01:00
|
|
|
pugi::xml_document doc;
|
|
|
|
|
pugi::xml_parse_result result = doc.load_file(file_to_load.GetFullPath().mb_str());
|
2015-12-06 11:42:37 -03:00
|
|
|
if(result) {
|
2014-01-22 20:16:17 +01:00
|
|
|
pugi::xml_node node = doc.child("client_config");
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!node) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Could not load clients.xml (syntax error), editor will NOT be able to load any client data files.");
|
2012-06-29 16:44:26 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
for(pugi::xml_node childNode = node.first_child(); childNode; childNode = childNode.next_sibling()) {
|
2014-01-22 20:16:17 +01:00
|
|
|
const std::string& childName = as_lower_str(childNode.name());
|
2015-12-06 11:42:37 -03:00
|
|
|
if(childName == "otbs") {
|
|
|
|
|
for(pugi::xml_node otbNode = childNode.first_child(); otbNode; otbNode = otbNode.next_sibling()) {
|
|
|
|
|
if(as_lower_str(otbNode.name()) == "otb") {
|
2012-07-01 22:00:57 +02:00
|
|
|
loadOTBInfo(otbNode);
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
|
|
|
|
}
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(childName == "clients") {
|
|
|
|
|
for(pugi::xml_node versionNode = childNode.first_child(); versionNode; versionNode = versionNode.next_sibling()) {
|
|
|
|
|
if(as_lower_str(versionNode.name()) == "client") {
|
2014-01-25 22:01:11 +01:00
|
|
|
loadVersion(versionNode);
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
|
|
|
|
}
|
2012-07-01 22:00:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
for(pugi::xml_node childNode = node.first_child(); childNode; childNode = childNode.next_sibling()) {
|
|
|
|
|
if(as_lower_str(childNode.name()) != "clients") {
|
2014-01-22 20:16:17 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
for(pugi::xml_node versionNode = childNode.first_child(); versionNode; versionNode = versionNode.next_sibling()) {
|
|
|
|
|
if(as_lower_str(versionNode.name()) == "client") {
|
2014-01-25 22:01:11 +01:00
|
|
|
loadVersionExtensions(versionNode);
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
|
|
|
|
}
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-02 00:00:09 +02:00
|
|
|
// Assign a default if there isn't one.
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!latest_version && !client_versions.empty()) {
|
2012-07-02 00:00:09 +02:00
|
|
|
latest_version = client_versions.begin()->second;
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
2012-07-02 00:00:09 +02:00
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
// Load the data directory info
|
2023-04-03 10:36:16 -07:00
|
|
|
using json = nlohmann::json;
|
2012-06-29 16:44:26 +02:00
|
|
|
try
|
|
|
|
|
{
|
2023-03-25 19:22:47 -03:00
|
|
|
json read_obj = json::parse(g_settings.getString(Config::ASSETS_DATA_DIRS));
|
|
|
|
|
auto vers_obj = read_obj.get<std::vector<json>>();
|
|
|
|
|
for (const auto& ver_iter : vers_obj) {
|
|
|
|
|
const auto& ver_obj = ver_iter.get<json::object_t>();
|
|
|
|
|
auto version = get(ver_obj.at("id").get<std::string>());
|
|
|
|
|
if (version == nullptr) {
|
2012-06-29 16:44:26 +02:00
|
|
|
continue;
|
2023-03-25 19:22:47 -03:00
|
|
|
}
|
|
|
|
|
version->setClientPath(wxstr(ver_obj.at("path").get<std::string>()));
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
2023-04-03 10:36:16 -07:00
|
|
|
catch ([[maybe_unused]]const json::exception& e)
|
2012-06-29 16:44:26 +02:00
|
|
|
{
|
|
|
|
|
// pass
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-01 16:53:39 +02:00
|
|
|
void ClientVersion::unloadVersions()
|
|
|
|
|
{
|
2015-12-06 11:42:37 -03:00
|
|
|
for(VersionMap::iterator it = client_versions.begin(); it != client_versions.end(); ++it)
|
2012-07-01 16:53:39 +02:00
|
|
|
delete it->second;
|
|
|
|
|
client_versions.clear();
|
2014-01-22 20:16:17 +01:00
|
|
|
latest_version = nullptr;
|
2012-07-01 16:53:39 +02:00
|
|
|
otb_versions.clear();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-22 20:16:17 +01:00
|
|
|
void ClientVersion::loadOTBInfo(pugi::xml_node otbNode)
|
2012-07-01 13:41:59 +02:00
|
|
|
{
|
2015-12-06 11:42:37 -03:00
|
|
|
if(as_lower_str(otbNode.name()) != "otb") {
|
2014-01-22 20:16:17 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2012-07-01 13:41:59 +02:00
|
|
|
|
2014-01-22 20:16:17 +01:00
|
|
|
pugi::xml_attribute attribute;
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = otbNode.attribute("client"))) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'otb' must contain 'client' tag.");
|
2014-01-22 20:16:17 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2012-07-01 13:41:59 +02:00
|
|
|
|
2014-01-25 22:01:11 +01:00
|
|
|
OtbVersion otb = {"", OTB_VERSION_3, CLIENT_VERSION_NONE};
|
2014-01-22 20:16:17 +01:00
|
|
|
otb.name = attribute.as_string();
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = otbNode.attribute("id"))) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'otb' must contain 'id' tag.");
|
2014-01-22 20:16:17 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2012-07-01 22:00:57 +02:00
|
|
|
|
2021-06-06 23:45:46 -03:00
|
|
|
otb.id = static_cast<ClientVersionID>(attribute.as_int());
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = otbNode.attribute("version"))) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'otb' must contain 'version' tag.");
|
2014-01-22 20:16:17 +01:00
|
|
|
return;
|
2012-07-01 13:41:59 +02:00
|
|
|
}
|
2014-01-22 20:16:17 +01:00
|
|
|
|
2021-06-06 23:45:46 -03:00
|
|
|
OtbFormatVersion versionId = static_cast<OtbFormatVersion>(attribute.as_uint());
|
2015-12-06 11:42:37 -03:00
|
|
|
if(versionId < OTB_VERSION_1 || versionId > OTB_VERSION_3) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'otb' unrecognized format version (version 1..3 supported).");
|
2014-01-22 20:16:17 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
otb.format_version = versionId;
|
|
|
|
|
otb_versions[otb.name] = otb;
|
2012-07-01 13:41:59 +02:00
|
|
|
}
|
|
|
|
|
|
2014-01-22 20:16:17 +01:00
|
|
|
void ClientVersion::loadVersion(pugi::xml_node versionNode)
|
2012-07-01 13:41:59 +02:00
|
|
|
{
|
2014-01-22 20:16:17 +01:00
|
|
|
pugi::xml_attribute attribute;
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = versionNode.attribute("name"))) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'client' must contain 'name', 'data_directory' and 'otb' tags.");
|
2014-01-22 20:16:17 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2012-07-01 13:41:59 +02:00
|
|
|
|
2014-01-22 20:16:17 +01:00
|
|
|
const std::string& versionName = attribute.as_string();
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = versionNode.attribute("data_directory"))) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'client' must contain 'name', 'data_directory' and 'otb' tags.");
|
2012-07-01 13:41:59 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-22 20:16:17 +01:00
|
|
|
const std::string& dataPath = attribute.as_string();
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = versionNode.attribute("otb"))) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'client' must contain 'name', 'data_directory' and 'otb' tags.");
|
2014-01-22 20:16:17 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::string& otbVersionName = attribute.as_string();
|
2015-12-06 11:42:37 -03:00
|
|
|
if(otb_versions.find(otbVersionName) == otb_versions.end()) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'client' 'otb' tag is invalid (couldn't find this otb version).");
|
2012-07-01 13:41:59 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-01 22:00:57 +02:00
|
|
|
ClientVersion* version = newd ClientVersion(otb_versions[otbVersionName], versionName, wxstr(dataPath));
|
2012-07-01 13:41:59 +02:00
|
|
|
|
2014-01-22 20:16:17 +01:00
|
|
|
bool should_be_default = versionNode.attribute("default").as_bool();
|
|
|
|
|
version->visible = versionNode.attribute("visible").as_bool();
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
for(pugi::xml_node childNode = versionNode.first_child(); childNode; childNode = childNode.next_sibling()) {
|
2014-01-22 20:16:17 +01:00
|
|
|
const std::string& childName = as_lower_str(childNode.name());
|
2015-12-06 11:42:37 -03:00
|
|
|
if(childName == "otbm") {
|
|
|
|
|
if(!(attribute = childNode.attribute("version"))) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'otbm' missing version.");
|
2012-07-01 13:41:59 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-06 23:45:46 -03:00
|
|
|
int32_t otbmVersion = attribute.as_int() - 1;
|
2015-12-06 11:42:37 -03:00
|
|
|
if(otbmVersion < MAP_OTBM_1 || otbmVersion > MAP_OTBM_4) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'otbm' unsupported version.");
|
2012-07-01 13:41:59 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
if(childNode.attribute("preffered").as_bool() || version->preferred_map_version == MAP_OTBM_UNKNOWN) {
|
2014-01-22 20:16:17 +01:00
|
|
|
version->preferred_map_version = static_cast<MapVersionID>(otbmVersion);
|
|
|
|
|
}
|
|
|
|
|
version->map_versions_supported.push_back(version->preferred_map_version);
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(childName == "fucked_up_charges") {
|
2012-07-01 13:41:59 +02:00
|
|
|
version->usesFuckedUpCharges = true;
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(childName == "data") {
|
2012-07-01 13:41:59 +02:00
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = childNode.attribute("format"))) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'data' does not have 'format' tag.");
|
2012-07-01 13:41:59 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-05 21:07:44 -03:00
|
|
|
const std::string& format = attribute.as_string();
|
|
|
|
|
ClientData client_data = { DAT_FORMAT_74, 0, 0 };
|
2015-12-06 11:42:37 -03:00
|
|
|
if(format == "7.4") {
|
2015-02-05 21:07:44 -03:00
|
|
|
client_data.datFormat = DAT_FORMAT_74;
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(format == "7.55") {
|
2015-02-06 10:30:02 -03:00
|
|
|
client_data.datFormat = DAT_FORMAT_755;
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(format == "7.8") {
|
2015-02-05 21:07:44 -03:00
|
|
|
client_data.datFormat = DAT_FORMAT_78;
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(format == "8.6") {
|
2015-02-05 21:07:44 -03:00
|
|
|
client_data.datFormat = DAT_FORMAT_86;
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(format == "9.6") {
|
2015-02-05 21:07:44 -03:00
|
|
|
client_data.datFormat = DAT_FORMAT_96;
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(format == "10.10") {
|
2015-02-05 21:07:44 -03:00
|
|
|
client_data.datFormat = DAT_FORMAT_1010;
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(format == "10.50") {
|
2015-02-05 21:07:44 -03:00
|
|
|
client_data.datFormat = DAT_FORMAT_1050;
|
2015-12-06 11:42:37 -03:00
|
|
|
} else if(format == "10.57") {
|
2015-02-07 07:33:03 -03:00
|
|
|
client_data.datFormat = DAT_FORMAT_1057;
|
2014-01-22 20:16:17 +01:00
|
|
|
} else {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'data' 'format' is invalid (7.4, 7.55, 7.8, 8.6, 9.6, 10.10, 10.50, 10.57 are supported)");
|
2012-07-01 13:41:59 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = childNode.attribute("dat")) || !wxString(attribute.as_string(), wxConvUTF8).ToULong((unsigned long*)&client_data.datSignature, 16)) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'data' 'dat' tag is not hex-formatted.");
|
2012-07-01 13:41:59 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
2014-01-22 20:16:17 +01:00
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = childNode.attribute("spr")) || !wxString(attribute.as_string(), wxConvUTF8).ToULong((unsigned long*)&client_data.sprSignature, 16)) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Node 'data' 'spr' tag is not hex-formatted.");
|
2012-07-01 13:41:59 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
version->data_versions.push_back(client_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
if(client_versions[version->getID()]) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Duplicate version id %i, discarding version '%s'.", version->getID(), version->name);
|
2012-07-01 13:41:59 +02:00
|
|
|
delete version;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client_versions[version->getID()] = version;
|
2015-12-06 11:42:37 -03:00
|
|
|
if(should_be_default) {
|
2012-07-02 00:00:09 +02:00
|
|
|
latest_version = version;
|
2014-01-25 22:01:11 +01:00
|
|
|
}
|
2012-07-01 13:41:59 +02:00
|
|
|
}
|
2014-01-22 20:16:17 +01:00
|
|
|
|
|
|
|
|
void ClientVersion::loadVersionExtensions(pugi::xml_node versionNode)
|
2012-07-01 22:00:57 +02:00
|
|
|
{
|
2014-01-22 20:16:17 +01:00
|
|
|
pugi::xml_attribute attribute;
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!(attribute = versionNode.attribute("name"))) {
|
2012-07-01 22:00:57 +02:00
|
|
|
// Error has already been displayed earlier, no need to show another error about the same thing
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-22 20:16:17 +01:00
|
|
|
ClientVersion* version = get(attribute.as_string());
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!version) {
|
2012-07-01 22:00:57 +02:00
|
|
|
// Same rationale as above
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
for(pugi::xml_node childNode = versionNode.first_child(); childNode; childNode = childNode.next_sibling()) {
|
|
|
|
|
if(as_lower_str(childNode.name()) != "extensions") {
|
2014-01-22 20:16:17 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::string& from = childNode.attribute("from").as_string();
|
|
|
|
|
const std::string& to = childNode.attribute("to").as_string();
|
2015-02-05 21:07:44 -03:00
|
|
|
|
2014-01-22 20:16:17 +01:00
|
|
|
ClientVersion* fromVersion = get(from);
|
|
|
|
|
ClientVersion* toVersion = get(to);
|
2012-07-01 22:00:57 +02:00
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!fromVersion && !toVersion) {
|
2016-11-05 15:28:14 +01:00
|
|
|
wxLogError("Unknown client extension data.");
|
2014-01-22 20:16:17 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2016-09-29 19:24:45 -03:00
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!fromVersion) {
|
2014-01-22 20:16:17 +01:00
|
|
|
fromVersion = client_versions.begin()->second;
|
|
|
|
|
}
|
2016-09-29 19:24:45 -03:00
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!toVersion) {
|
2014-01-22 20:16:17 +01:00
|
|
|
toVersion = client_versions.rbegin()->second;
|
|
|
|
|
}
|
2012-07-19 23:14:29 +02:00
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
for(const auto& versionEntry : client_versions) {
|
2014-01-22 20:16:17 +01:00
|
|
|
ClientVersion* version = versionEntry.second;
|
2015-12-06 11:42:37 -03:00
|
|
|
if(version->getID() >= fromVersion->getID() && version->getID() <= toVersion->getID()) {
|
2014-01-22 20:16:17 +01:00
|
|
|
version->extension_versions.push_back(version);
|
|
|
|
|
}
|
2012-07-01 22:00:57 +02:00
|
|
|
}
|
2014-01-22 20:16:17 +01:00
|
|
|
|
|
|
|
|
std::sort(version->extension_versions.begin(), version->extension_versions.end(), VersionComparisonPredicate);
|
2012-07-01 22:00:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
2012-07-01 13:41:59 +02:00
|
|
|
|
2012-06-29 16:44:26 +02:00
|
|
|
void ClientVersion::saveVersions()
|
|
|
|
|
{
|
2023-03-25 19:22:47 -03:00
|
|
|
using json = nlohmann::json;
|
2023-04-03 10:36:16 -07:00
|
|
|
try {
|
|
|
|
|
json vers_obj;
|
|
|
|
|
|
|
|
|
|
for(auto& [id, version] : client_versions) {
|
|
|
|
|
json ver_obj;
|
|
|
|
|
ver_obj["id"] = version->getName();
|
|
|
|
|
ver_obj["path"] = version->getClientPath().GetFullPath().ToStdString();
|
|
|
|
|
vers_obj.push_back(ver_obj);
|
|
|
|
|
}
|
2012-06-29 16:44:26 +02:00
|
|
|
|
2023-04-03 10:36:16 -07:00
|
|
|
std::ostringstream out;
|
|
|
|
|
out << vers_obj;
|
|
|
|
|
g_settings.setString(Config::ASSETS_DATA_DIRS, out.str());
|
|
|
|
|
}
|
|
|
|
|
catch ([[maybe_unused]]const json::exception& e) {
|
|
|
|
|
// pass
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Client version class
|
|
|
|
|
|
2012-07-01 22:00:57 +02:00
|
|
|
ClientVersion::ClientVersion(OtbVersion otb, std::string versionName, wxString path) :
|
2012-07-01 13:41:59 +02:00
|
|
|
otb(otb),
|
2012-06-29 16:44:26 +02:00
|
|
|
name(versionName),
|
2012-07-01 13:41:59 +02:00
|
|
|
visible(false),
|
|
|
|
|
preferred_map_version(MAP_OTBM_UNKNOWN),
|
2012-06-29 16:44:26 +02:00
|
|
|
data_path(path)
|
|
|
|
|
{
|
2015-12-06 11:42:37 -03:00
|
|
|
////
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ClientVersion* ClientVersion::get(ClientVersionID id)
|
|
|
|
|
{
|
2012-07-01 13:41:59 +02:00
|
|
|
VersionMap::iterator i = client_versions.find(id);
|
|
|
|
|
if(i == client_versions.end())
|
2014-01-22 20:16:17 +01:00
|
|
|
return nullptr;
|
2012-07-01 13:41:59 +02:00
|
|
|
return i->second;
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ClientVersion* ClientVersion::get(std::string id)
|
|
|
|
|
{
|
2012-07-01 13:41:59 +02:00
|
|
|
for(VersionMap::iterator i = client_versions.begin(); i != client_versions.end(); ++i)
|
|
|
|
|
if(i->second->getName() == id)
|
|
|
|
|
return i->second;
|
2014-01-22 20:16:17 +01:00
|
|
|
return nullptr;
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ClientVersionList ClientVersion::getAll()
|
|
|
|
|
{
|
|
|
|
|
ClientVersionList l;
|
2012-07-01 13:41:59 +02:00
|
|
|
for(VersionMap::iterator i = client_versions.begin(); i != client_versions.end(); ++i)
|
|
|
|
|
l.push_back(i->second);
|
2012-06-29 16:44:26 +02:00
|
|
|
return l;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
ClientVersionList ClientVersion::getAllVisible()
|
|
|
|
|
{
|
|
|
|
|
ClientVersionList l;
|
|
|
|
|
for(VersionMap::iterator i = client_versions.begin(); i != client_versions.end(); ++i)
|
2015-12-06 11:42:37 -03:00
|
|
|
if(i->second->isVisible())
|
2012-07-01 13:41:59 +02:00
|
|
|
l.push_back(i->second);
|
|
|
|
|
return l;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-01 17:52:20 +02:00
|
|
|
ClientVersionList ClientVersion::getAllForOTBMVersion(MapVersionID id)
|
|
|
|
|
{
|
2015-12-06 11:42:37 -03:00
|
|
|
ClientVersionList list;
|
|
|
|
|
for(VersionMap::iterator i = client_versions.begin(); i != client_versions.end(); ++i) {
|
|
|
|
|
if(i->second->isVisible()) {
|
|
|
|
|
for(std::vector<MapVersionID>::iterator v = i->second->map_versions_supported.begin(); v != i->second->map_versions_supported.end(); ++v) {
|
|
|
|
|
if(*v == id)
|
|
|
|
|
list.push_back(i->second);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return list;
|
2012-07-01 17:52:20 +02:00
|
|
|
}
|
|
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
ClientVersion* ClientVersion::getLatestVersion()
|
|
|
|
|
{
|
|
|
|
|
return latest_version;
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-29 16:44:26 +02:00
|
|
|
FileName ClientVersion::getDataPath() const
|
|
|
|
|
{
|
2016-09-29 20:30:54 -03:00
|
|
|
wxString basePath = g_gui.GetDataDirectory();
|
2014-01-24 02:33:09 -02:00
|
|
|
if(!wxFileName(basePath).DirExists())
|
2016-09-29 20:30:54 -03:00
|
|
|
basePath = g_gui.getFoundDataDirectory();
|
2014-01-24 02:33:09 -02:00
|
|
|
return basePath + data_path + FileName::GetPathSeparator();
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FileName ClientVersion::getLocalDataPath() const
|
|
|
|
|
{
|
2016-09-29 20:30:54 -03:00
|
|
|
FileName f = g_gui.GetLocalDataDirectory() + data_path + FileName::GetPathSeparator();
|
2012-06-29 16:44:26 +02:00
|
|
|
f.Mkdir(0755, wxPATH_MKDIR_FULL);
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-23 10:21:07 -03:00
|
|
|
bool ClientVersion::hasValidPaths()
|
2012-06-29 16:44:26 +02:00
|
|
|
{
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!client_path.DirExists()) {
|
2012-06-29 16:44:26 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
2016-09-29 19:24:45 -03:00
|
|
|
|
2019-07-23 10:21:07 -03:00
|
|
|
wxDir dir(client_path.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
|
|
|
|
|
wxString otfi_file;
|
|
|
|
|
metadata_path = wxFileName(client_path.GetFullPath(), wxString(ASSETS_NAME) + ".dat");
|
|
|
|
|
sprites_path = wxFileName(client_path.GetFullPath(), wxString(ASSETS_NAME) + ".spr");
|
|
|
|
|
|
|
|
|
|
if(dir.GetFirst(&otfi_file, "*.otfi", wxDIR_FILES)) {
|
|
|
|
|
wxFileName otfi(client_path.GetFullPath(), otfi_file);
|
|
|
|
|
OTMLDocumentPtr doc = OTMLDocument::parse(otfi.GetFullPath().ToStdString());
|
|
|
|
|
if(doc->size() != 0 && doc->hasChildAt("DatSpr")) {
|
|
|
|
|
OTMLNodePtr node = doc->get("DatSpr");
|
|
|
|
|
std::string metadata = node->valueAt<std::string>("metadata-file", std::string(ASSETS_NAME) + ".dat");
|
|
|
|
|
std::string sprites = node->valueAt<std::string>("sprites-file", std::string(ASSETS_NAME) + ".spr");
|
|
|
|
|
metadata_path = wxFileName(client_path.GetFullPath(), wxString(metadata));
|
|
|
|
|
sprites_path = wxFileName(client_path.GetFullPath(), wxString(sprites));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!metadata_path.FileExists() || !sprites_path.FileExists()) {
|
2012-06-29 16:44:26 +02:00
|
|
|
return false;
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
2012-06-29 16:44:26 +02:00
|
|
|
|
2016-09-29 20:37:43 -03:00
|
|
|
if(!g_settings.getInteger(Config::CHECK_SIGNATURES)) {
|
2012-06-29 16:44:26 +02:00
|
|
|
return true;
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
2012-06-29 16:44:26 +02:00
|
|
|
|
|
|
|
|
// Peek the version of the files
|
2019-07-23 10:21:07 -03:00
|
|
|
FileReadHandle dat_file(static_cast<const char*>(metadata_path.GetFullPath().mb_str()));
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!dat_file.isOk()) {
|
2018-10-14 19:54:08 -03:00
|
|
|
wxLogError("Could not open metadata file.");
|
2012-06-29 16:44:26 +02:00
|
|
|
return false;
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
2012-06-29 16:44:26 +02:00
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
uint32_t datSignature;
|
|
|
|
|
dat_file.getU32(datSignature);
|
2012-06-29 16:44:26 +02:00
|
|
|
dat_file.close();
|
|
|
|
|
|
2019-07-23 10:21:07 -03:00
|
|
|
FileReadHandle spr_file(static_cast<const char*>(sprites_path.GetFullPath().mb_str()));
|
2015-12-06 11:42:37 -03:00
|
|
|
if(!spr_file.isOk()) {
|
2018-10-14 19:54:08 -03:00
|
|
|
wxLogError("Could not open sprites file.");
|
2012-06-29 16:44:26 +02:00
|
|
|
return false;
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
2012-06-29 16:44:26 +02:00
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
uint32_t sprSignature;
|
|
|
|
|
spr_file.getU32(sprSignature);
|
2012-06-29 16:44:26 +02:00
|
|
|
spr_file.close();
|
|
|
|
|
|
2015-12-06 11:42:37 -03:00
|
|
|
for(const auto& clientData : data_versions) {
|
|
|
|
|
if(clientData.sprSignature == sprSignature && clientData.datSignature == datSignature) {
|
2012-06-29 16:44:26 +02:00
|
|
|
return true;
|
2014-01-22 20:16:17 +01:00
|
|
|
}
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
2015-05-07 19:35:10 -03:00
|
|
|
|
2016-11-05 15:28:14 +01:00
|
|
|
wxString message = "Signatures are incorrect.\n";
|
2018-10-14 19:54:08 -03:00
|
|
|
message << "Metadata signature: %X\n";
|
|
|
|
|
message << "Sprites signature: %X";
|
2015-05-07 19:35:10 -03:00
|
|
|
wxLogError(wxString::Format(message, datSignature, sprSignature));
|
2012-06-29 16:44:26 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ClientVersion::loadValidPaths()
|
|
|
|
|
{
|
2015-12-06 11:42:37 -03:00
|
|
|
while(!hasValidPaths()) {
|
2019-07-23 10:21:07 -03:00
|
|
|
wxString message = "Could not locate metadata and/or sprite files, please navigate to your client assets %s installation folder.\n";
|
|
|
|
|
message << "Attempted metadata file: %s\n";
|
|
|
|
|
message << "Attempted sprites file: %s\n";
|
|
|
|
|
|
|
|
|
|
g_gui.PopupDialog("Error", wxString::Format(message, name, metadata_path.GetFullPath(), sprites_path.GetFullPath()), wxOK);
|
2012-07-12 13:47:04 +02:00
|
|
|
|
2018-10-14 19:54:08 -03:00
|
|
|
wxString dirHelpText("Select assets directory.");
|
2016-11-05 15:28:14 +01:00
|
|
|
wxDirDialog file_dlg(nullptr, dirHelpText, "", wxDD_DIR_MUST_EXIST);
|
2012-06-29 16:44:26 +02:00
|
|
|
int ok = file_dlg.ShowModal();
|
|
|
|
|
if(ok == wxID_CANCEL)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
client_path.Assign(file_dlg.GetPath() + FileName::GetPathSeparator());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ClientVersion::saveVersions();
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-05 21:07:44 -03:00
|
|
|
DatFormat ClientVersion::getDatFormatForSignature(uint32_t signature) const
|
2012-07-01 15:55:44 +02:00
|
|
|
{
|
2015-12-06 11:42:37 -03:00
|
|
|
for(std::vector<ClientData>::const_iterator iter = data_versions.begin(); iter != data_versions.end(); ++iter) {
|
2012-07-01 15:55:44 +02:00
|
|
|
if(iter->datSignature == signature)
|
2015-02-05 21:07:44 -03:00
|
|
|
return iter->datFormat;
|
2012-07-01 15:55:44 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-05 21:07:44 -03:00
|
|
|
return DAT_FORMAT_UNKNOWN;
|
2012-07-01 15:55:44 +02:00
|
|
|
}
|
|
|
|
|
|
2012-06-29 16:44:26 +02:00
|
|
|
std::string ClientVersion::getName() const
|
|
|
|
|
{
|
2012-07-01 22:00:57 +02:00
|
|
|
return name;
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ClientVersionID ClientVersion::getID() const
|
|
|
|
|
{
|
2012-07-01 13:41:59 +02:00
|
|
|
return otb.id;
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
bool ClientVersion::isVisible() const
|
2012-06-29 16:44:26 +02:00
|
|
|
{
|
2012-07-01 13:41:59 +02:00
|
|
|
return visible;
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClientVersion::setClientPath(const FileName& dir)
|
|
|
|
|
{
|
|
|
|
|
client_path.Assign(dir);
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-01 13:41:59 +02:00
|
|
|
MapVersionID ClientVersion::getPrefferedMapVersionID() const
|
2012-06-29 16:44:26 +02:00
|
|
|
{
|
2012-07-01 13:41:59 +02:00
|
|
|
return preferred_map_version;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OtbVersion ClientVersion::getOTBVersion() const
|
|
|
|
|
{
|
|
|
|
|
return otb;
|
2012-06-29 16:44:26 +02:00
|
|
|
}
|
2012-07-01 13:41:59 +02:00
|
|
|
|
|
|
|
|
ClientVersionList ClientVersion::getExtensionsSupported() const
|
|
|
|
|
{
|
2012-07-05 15:01:40 +02:00
|
|
|
return extension_versions;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-25 22:01:11 +01:00
|
|
|
ClientVersionList ClientVersion::getAllVersionsSupportedForClientVersion(ClientVersion* clientVersion)
|
2012-07-19 22:47:05 +02:00
|
|
|
{
|
2014-01-25 22:01:11 +01:00
|
|
|
ClientVersionList versionList;
|
2015-12-06 11:42:37 -03:00
|
|
|
for(const auto& versionEntry : client_versions) {
|
2014-01-25 22:01:11 +01:00
|
|
|
ClientVersion* version = versionEntry.second;
|
2015-12-06 11:42:37 -03:00
|
|
|
for(ClientVersion* checkVersion : version->getExtensionsSupported()) {
|
|
|
|
|
if(clientVersion == checkVersion) {
|
2014-01-25 22:01:11 +01:00
|
|
|
versionList.push_back(version);
|
2012-07-19 22:47:05 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-01-25 22:01:11 +01:00
|
|
|
std::sort(versionList.begin(), versionList.end(), VersionComparisonPredicate);
|
|
|
|
|
return versionList;
|
2012-07-19 22:47:05 +02:00
|
|
|
}
|