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"
2023-03-28 08:54:17 -03:00
using json = nlohmann : : json ;
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 ;
2023-10-15 18:51:57 -03:00
std : : shared_ptr < 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
2023-10-09 19:12:16 -07: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 ;
2023-10-09 19:12:16 -07:00
if ( ! file_to_load . FileExists ( ) ) {
2012-07-12 12:51:18 +02:00
file_to_load = data_dir_client_xml ;
2023-10-09 19:12:16 -07:00
if ( ! file_to_load . FileExists ( ) ) {
2014-01-24 02:33:09 -02:00
file_to_load = work_dir_client_xml ;
2023-10-09 19:12:16 -07:00
if ( ! file_to_load . FileExists ( ) ) {
2014-01-24 02:33:09 -02:00
file_to_load . Clear ( ) ;
}
2014-01-22 20:16:17 +01:00
}
2012-07-12 12:51:18 +02:00
}
2023-10-09 19:12:16 -07:00
if ( ! file_to_load . FileExists ( ) ) {
wxLogError ( wxString ( ) + " Could not load clients.xml, editor will NOT be able to load any client data files. \n " + " Checked paths: \n " + exec_dir_client_xml . GetFullPath ( ) + " \n " + 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 ( ) ) ;
2023-10-09 19:12:16 -07:00
if ( result ) {
2014-01-22 20:16:17 +01:00
pugi : : xml_node node = doc . child ( " client_config " ) ;
2023-10-09 19:12:16 -07: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 ;
}
2023-10-09 19:12:16 -07:00
for ( pugi : : xml_node childNode = node . first_child ( ) ; childNode ; childNode = childNode . next_sibling ( ) ) {
const std : : string & childName = as_lower_str ( childNode . name ( ) ) ;
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
}
}
2023-10-09 19:12:16 -07: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
}
}
2023-10-09 19:12:16 -07: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 ;
}
2023-10-09 19:12:16 -07: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.
2023-10-09 19:12:16 -07: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-10-09 19:12:16 -07:00
try {
2023-03-28 08:54:17 -03:00
json read_obj = json : : parse ( g_settings . getString ( Config : : ASSETS_DATA_DIRS ) ) ;
auto vers_obj = read_obj . get < std : : vector < json > > ( ) ;
2023-10-09 19:12:16 -07:00
for ( const auto & ver_iter : vers_obj ) {
const auto & ver_obj = ver_iter . get < json : : object_t > ( ) ;
2023-03-28 08:54:17 -03:00
auto version = get ( ver_obj . at ( " id " ) . get < std : : string > ( ) ) ;
2023-10-09 19:12:16 -07:00
if ( version = = nullptr ) {
2012-06-29 16:44:26 +02:00
continue ;
2023-10-09 19:12:16 -07:00
}
2023-03-28 08:54:17 -03:00
version - > setClientPath ( wxstr ( ver_obj . at ( " path " ) . get < std : : string > ( ) ) ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
} catch ( [[maybe_unused]] const json : : exception & e ) {
2012-06-29 16:44:26 +02:00
// pass
}
}
2023-10-09 19:12:16 -07:00
void ClientVersion : : unloadVersions ( ) {
2012-07-01 16:53:39 +02:00
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 ( ) ;
}
2023-10-09 19:12:16 -07:00
void ClientVersion : : loadOTBInfo ( pugi : : xml_node otbNode ) {
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 ;
2023-10-09 19:12:16 -07: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
2023-10-09 19:12:16 -07:00
OtbVersion otb = { " " , OTB_VERSION_3 , CLIENT_VERSION_NONE } ;
2014-01-22 20:16:17 +01:00
otb . name = attribute . as_string ( ) ;
2023-10-09 19:12:16 -07: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 ( ) ) ;
2023-10-09 19:12:16 -07: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 ( ) ) ;
2023-10-09 19:12:16 -07: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
}
2023-10-09 19:12:16 -07:00
void ClientVersion : : loadVersion ( pugi : : xml_node versionNode ) {
2014-01-22 20:16:17 +01:00
pugi : : xml_attribute attribute ;
2023-10-09 19:12:16 -07: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
2023-10-09 19:12:16 -07:00
const std : : string & versionName = attribute . as_string ( ) ;
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 ;
}
2023-10-09 19:12:16 -07:00
const std : : string & dataPath = attribute . as_string ( ) ;
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 ;
}
2023-10-09 19:12:16 -07:00
const std : : string & otbVersionName = attribute . as_string ( ) ;
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 ;
}
2023-10-15 18:51:57 -03:00
auto 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 ( ) ;
2023-10-09 19:12:16 -07:00
for ( pugi : : xml_node childNode = versionNode . first_child ( ) ; childNode ; childNode = childNode . next_sibling ( ) ) {
const std : : string & childName = as_lower_str ( childNode . name ( ) ) ;
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 ;
2023-10-09 19:12:16 -07: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 ;
}
2023-10-09 19:12:16 -07: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 ) ;
2023-10-09 19:12:16 -07:00
} else if ( childName = = " fucked_up_charges " ) {
2012-07-01 13:41:59 +02:00
version - > usesFuckedUpCharges = true ;
2023-10-09 19:12:16 -07:00
} else if ( childName = = " data " ) {
2012-07-01 13:41:59 +02:00
2023-10-09 19:12:16 -07: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 ;
}
2023-10-09 19:12:16 -07:00
const std : : string & format = attribute . as_string ( ) ;
2021-06-23 21:30:37 -03:00
ClientData client_data = { DAT_FORMAT_11 , 0 , 0 } ;
2023-10-09 19:12:16 -07:00
if ( format = = " 11 " ) {
2021-06-23 21:30:37 -03:00
client_data . datFormat = DAT_FORMAT_11 ;
2014-01-22 20:16:17 +01:00
} else {
2021-06-23 21:30:37 -03:00
wxLogError ( " Node 'data' 'format' is invalid (only 11.00 are supported) " ) ;
2012-07-01 13:41:59 +02:00
continue ;
}
2023-10-09 19:12:16 -07: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
2023-10-09 19:12:16 -07: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 ) ;
}
}
2023-10-09 19:12:16 -07: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
return ;
}
client_versions [ version - > getID ( ) ] = version ;
2023-10-09 19:12:16 -07: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
2023-10-09 19:12:16 -07:00
void ClientVersion : : loadVersionExtensions ( pugi : : xml_node versionNode ) {
2014-01-22 20:16:17 +01:00
pugi : : xml_attribute attribute ;
2023-10-09 19:12:16 -07: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 ;
}
2023-10-15 18:51:57 -03:00
auto version = get ( attribute . as_string ( ) ) ;
2023-10-09 19:12:16 -07:00
if ( ! version ) {
2012-07-01 22:00:57 +02:00
// Same rationale as above
return ;
}
2023-10-09 19:12:16 -07: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 ;
}
2023-10-09 19:12:16 -07:00
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
2023-10-15 18:51:57 -03:00
auto fromVersion = get ( from ) ;
auto toVersion = get ( to ) ;
2012-07-01 22:00:57 +02:00
2023-10-09 19:12:16 -07: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
2023-10-09 19:12:16 -07:00
if ( ! fromVersion ) {
2014-01-22 20:16:17 +01:00
fromVersion = client_versions . begin ( ) - > second ;
}
2016-09-29 19:24:45 -03:00
2023-10-09 19:12:16 -07:00
if ( ! toVersion ) {
2014-01-22 20:16:17 +01:00
toVersion = client_versions . rbegin ( ) - > second ;
}
2012-07-19 23:14:29 +02:00
2023-10-09 19:12:16 -07:00
for ( const auto & versionEntry : client_versions ) {
2023-10-15 18:51:57 -03:00
auto version = versionEntry . second ;
2023-10-09 19:12:16 -07: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
2023-10-09 19:12:16 -07:00
void ClientVersion : : saveVersions ( ) {
2023-04-03 19:46:34 -07:00
try {
json vers_obj ;
2023-10-09 19:12:16 -07:00
for ( auto & [ id , version ] : client_versions ) {
2023-04-03 19:46:34 -07:00
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 19:46:34 -07:00
std : : ostringstream out ;
out < < vers_obj ;
g_settings . setString ( Config : : ASSETS_DATA_DIRS , out . str ( ) ) ;
2023-10-09 19:12:16 -07:00
} catch ( [[maybe_unused]] const json : : exception & e ) {
2023-04-03 19:46:34 -07:00
// 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 ) ,
2023-10-09 19:12:16 -07:00
data_path ( path ) {
2015-12-06 11:42:37 -03:00
////
2012-06-29 16:44:26 +02:00
}
2023-10-15 18:51:57 -03:00
std : : shared_ptr < ClientVersion > ClientVersion : : get ( ClientVersionID id ) {
2012-07-01 13:41:59 +02:00
VersionMap : : iterator i = client_versions . find ( id ) ;
2023-10-09 19:12:16 -07:00
if ( i = = client_versions . end ( ) ) {
2014-01-22 20:16:17 +01:00
return nullptr ;
2023-10-09 19:12:16 -07:00
}
2012-07-01 13:41:59 +02:00
return i - > second ;
2012-06-29 16:44:26 +02:00
}
2023-10-15 18:51:57 -03:00
std : : shared_ptr < ClientVersion > ClientVersion : : get ( std : : string id ) {
2023-10-09 19:12:16 -07:00
for ( VersionMap : : iterator i = client_versions . begin ( ) ; i ! = client_versions . end ( ) ; + + i ) {
if ( i - > second - > getName ( ) = = id ) {
2012-07-01 13:41:59 +02:00
return i - > second ;
2023-10-09 19:12:16 -07:00
}
}
2014-01-22 20:16:17 +01:00
return nullptr ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
ClientVersionList ClientVersion : : getAll ( ) {
2012-06-29 16:44:26 +02:00
ClientVersionList l ;
2023-10-09 19:12:16 -07:00
for ( VersionMap : : iterator i = client_versions . begin ( ) ; i ! = client_versions . end ( ) ; + + i ) {
2012-07-01 13:41:59 +02:00
l . push_back ( i - > second ) ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
return l ;
}
2023-10-09 19:12:16 -07:00
ClientVersionList ClientVersion : : getAllVisible ( ) {
2012-07-01 13:41:59 +02:00
ClientVersionList l ;
2023-10-09 19:12:16 -07:00
for ( VersionMap : : iterator i = client_versions . begin ( ) ; i ! = client_versions . end ( ) ; + + i ) {
if ( i - > second - > isVisible ( ) ) {
2012-07-01 13:41:59 +02:00
l . push_back ( i - > second ) ;
2023-10-09 19:12:16 -07:00
}
}
2012-07-01 13:41:59 +02:00
return l ;
}
2023-10-09 19:12:16 -07:00
ClientVersionList ClientVersion : : getAllForOTBMVersion ( MapVersionID id ) {
2015-12-06 11:42:37 -03:00
ClientVersionList list ;
2023-10-09 19:12:16 -07:00
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 ) {
2015-12-06 11:42:37 -03:00
list . push_back ( i - > second ) ;
2023-10-09 19:12:16 -07:00
}
2015-12-06 11:42:37 -03:00
}
}
}
return list ;
2012-07-01 17:52:20 +02:00
}
2023-10-15 18:51:57 -03:00
std : : shared_ptr < ClientVersion > ClientVersion : : getLatestVersion ( ) {
2012-07-01 13:41:59 +02:00
return latest_version ;
}
2023-10-09 19:12:16 -07:00
FileName ClientVersion : : getDataPath ( ) const {
2016-09-29 20:30:54 -03:00
wxString basePath = g_gui . GetDataDirectory ( ) ;
2023-10-09 19:12:16 -07:00
if ( ! wxFileName ( basePath ) . DirExists ( ) ) {
2016-09-29 20:30:54 -03:00
basePath = g_gui . getFoundDataDirectory ( ) ;
2023-10-09 19:12:16 -07:00
}
2014-01-24 02:33:09 -02:00
return basePath + data_path + FileName : : GetPathSeparator ( ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07: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 ;
}
2023-10-09 19:12:16 -07:00
bool ClientVersion : : hasValidPaths ( ) {
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 " ) ;
2023-10-09 19:12:16 -07:00
if ( dir . GetFirst ( & otfi_file , " *.otfi " , wxDIR_FILES ) ) {
2019-07-23 10:21:07 -03:00
wxFileName otfi ( client_path . GetFullPath ( ) , otfi_file ) ;
OTMLDocumentPtr doc = OTMLDocument : : parse ( otfi . GetFullPath ( ) . ToStdString ( ) ) ;
2023-10-09 19:12:16 -07:00
if ( doc - > size ( ) ! = 0 & & doc - > hasChildAt ( " DatSpr " ) ) {
2019-07-23 10:21:07 -03:00
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 ) ) ;
}
}
2023-10-09 19:12:16 -07:00
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
2023-10-09 19:12:16 -07: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 ( ) ) ) ;
2023-10-09 19:12:16 -07: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 ( ) ) ) ;
2023-10-09 19:12:16 -07: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 ( ) ;
2023-10-09 19:12:16 -07: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 ;
}
2023-10-09 19:12:16 -07:00
bool ClientVersion : : loadValidPaths ( ) {
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 ( ) ;
2023-10-09 19:12:16 -07:00
if ( ok = = wxID_CANCEL ) {
2012-06-29 16:44:26 +02:00
return false ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
client_path . Assign ( file_dlg . GetPath ( ) + FileName : : GetPathSeparator ( ) ) ;
}
ClientVersion : : saveVersions ( ) ;
return true ;
}
2023-10-09 19:12:16 -07:00
DatFormat ClientVersion : : getDatFormatForSignature ( uint32_t signature ) const {
for ( std : : vector < ClientData > : : const_iterator iter = data_versions . begin ( ) ; iter ! = data_versions . end ( ) ; + + iter ) {
if ( iter - > datSignature = = signature ) {
2015-02-05 21:07:44 -03:00
return iter - > datFormat ;
2023-10-09 19:12:16 -07:00
}
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
}
2023-10-09 19:12:16 -07:00
std : : string ClientVersion : : getName ( ) const {
2012-07-01 22:00:57 +02:00
return name ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
ClientVersionID ClientVersion : : getID ( ) const {
2012-07-01 13:41:59 +02:00
return otb . id ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
bool ClientVersion : : isVisible ( ) const {
2012-07-01 13:41:59 +02:00
return visible ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void ClientVersion : : setClientPath ( const FileName & dir ) {
2012-06-29 16:44:26 +02:00
client_path . Assign ( dir ) ;
}
2023-10-09 19:12:16 -07:00
MapVersionID ClientVersion : : getPrefferedMapVersionID ( ) const {
2012-07-01 13:41:59 +02:00
return preferred_map_version ;
}
2023-10-09 19:12:16 -07:00
OtbVersion ClientVersion : : getOTBVersion ( ) const {
2012-07-01 13:41:59 +02:00
return otb ;
2012-06-29 16:44:26 +02:00
}
2012-07-01 13:41:59 +02:00
2023-10-09 19:12:16 -07:00
ClientVersionList ClientVersion : : getExtensionsSupported ( ) const {
2012-07-05 15:01:40 +02:00
return extension_versions ;
}
2023-10-15 18:51:57 -03:00
ClientVersionList ClientVersion : : getAllVersionsSupportedForClientVersion ( std : : shared_ptr < ClientVersion > clientVersion ) {
2014-01-25 22:01:11 +01:00
ClientVersionList versionList ;
2023-10-09 19:12:16 -07:00
for ( const auto & versionEntry : client_versions ) {
2023-10-15 18:51:57 -03:00
auto version = versionEntry . second ;
2023-10-15 21:52:40 +00:00
for ( const auto & checkVersion : version - > getExtensionsSupported ( ) ) {
2023-10-09 19:12:16 -07:00
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
}