From 4c535accd6760a615d1bf015f9f84d9ce534bd62 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 11 Apr 2019 19:06:27 +1000 Subject: [PATCH 1/8] begin tools cleanup, lgb group dumping --- .../Exd/StructureDef}/lgb.h | 12 +- .../Exd/StructureDef}/matrix4.h | 0 .../Exd/StructureDef}/pcb.h | 0 .../Exd/StructureDef}/sgb.h | 43 ++++-- .../Exd/StructureDef}/vec3.h | 0 src/tools/discovery_parser/main.cpp | 16 +-- src/tools/event_object_parser/main.cpp | 62 +++++--- src/tools/exd_struct_test/main.cpp | 135 ++++++++++++++++-- src/tools/nav_export/main.cpp | 20 +-- src/tools/nav_export/sgb.h | 6 +- src/tools/pcb_reader/main.cpp | 20 +-- src/tools/pcb_reader/sgb.h | 6 +- 12 files changed, 251 insertions(+), 69 deletions(-) rename src/{tools/event_object_parser => common/Exd/StructureDef}/lgb.h (97%) rename src/{tools/event_object_parser => common/Exd/StructureDef}/matrix4.h (100%) rename src/{tools/event_object_parser => common/Exd/StructureDef}/pcb.h (100%) rename src/{tools/event_object_parser => common/Exd/StructureDef}/sgb.h (87%) rename src/{tools/event_object_parser => common/Exd/StructureDef}/vec3.h (100%) diff --git a/src/tools/event_object_parser/lgb.h b/src/common/Exd/StructureDef/lgb.h similarity index 97% rename from src/tools/event_object_parser/lgb.h rename to src/common/Exd/StructureDef/lgb.h index 91f852b8..b8328ed4 100644 --- a/src/tools/event_object_parser/lgb.h +++ b/src/common/Exd/StructureDef/lgb.h @@ -278,7 +278,7 @@ struct LGB_GROUP { const auto type = *reinterpret_cast( buf + entryOffset ); // garbage to skip model loading - if( !ignoreModels && type == LgbEntryType::BgParts ) + if( type == LgbEntryType::BgParts ) { entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) ); } @@ -331,9 +331,15 @@ struct LGB_FILE { LGB_FILE_HEADER header; std::vector< LGB_GROUP > groups; - std::string name; + std::string m_name; - LGB_FILE( char* buf, const std::string& name ) + LGB_FILE( char* buf, const std::string& name ) : + LGB_FILE( buf ) + { + m_name = name; + } + + LGB_FILE( char* buf ) { header = *reinterpret_cast< LGB_FILE_HEADER* >( buf ); if( strncmp( &header.magic[ 0 ], "LGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "LGP1", 4 ) != 0 ) diff --git a/src/tools/event_object_parser/matrix4.h b/src/common/Exd/StructureDef/matrix4.h similarity index 100% rename from src/tools/event_object_parser/matrix4.h rename to src/common/Exd/StructureDef/matrix4.h diff --git a/src/tools/event_object_parser/pcb.h b/src/common/Exd/StructureDef/pcb.h similarity index 100% rename from src/tools/event_object_parser/pcb.h rename to src/common/Exd/StructureDef/pcb.h diff --git a/src/tools/event_object_parser/sgb.h b/src/common/Exd/StructureDef/sgb.h similarity index 87% rename from src/tools/event_object_parser/sgb.h rename to src/common/Exd/StructureDef/sgb.h index e6bcf2ce..fb384b69 100644 --- a/src/tools/event_object_parser/sgb.h +++ b/src/common/Exd/StructureDef/sgb.h @@ -11,9 +11,6 @@ #include "vec3.h" -// garbage to skip model loading -extern bool ignoreModels; - // // ported from https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Sgb/SgbDataType.cs @@ -36,6 +33,7 @@ enum SgbGroupEntryType : uint32_t { Model = 0x01, + Gimmick = 0x06, }; struct SGB_GROUP_HEADER @@ -64,6 +62,35 @@ struct SGB_GROUP_HEADER uint32_t unknown44; }; +struct SGB_GROUP1C_HEADER +{ + SgbDataType type; + int32_t nameOffset; + uint32_t unknown08; + + int32_t entryCount; + uint32_t unknown14; + int32_t modelFileOffset; + vec3 unknownFloat3; + vec3 unknownFloat3_2; + int32_t stateOffset; + int32_t modelFileOffset2; + uint32_t unknown3; + float unknown4; + int32_t nameOffset2; + vec3 unknownFloat3_3; +}; + +struct SGB_GROUP1C_ENTRY +{ + uint32_t unk; + uint32_t unk2; + int32_t nameOffset; + uint32_t index; + uint32_t unk3; + int32_t modelFileOffset; +}; + struct SGB_GROUP_ENTRY { public: @@ -113,8 +140,9 @@ struct SGB_MODEL_ENTRY : std::string modelFileName; std::string collisionFileName; - SGB_MODEL_ENTRY( char* buf, uint32_t offset ) + SGB_MODEL_ENTRY( char* buf, uint32_t offset, SgbGroupEntryType type ) { + this->type = type; header = *reinterpret_cast< SGB_MODEL_HEADER* >( buf + offset ); name = std::string( buf + offset + header.nameOffset ); modelFileName = std::string( buf + offset + header.modelFileOffset ); @@ -143,9 +171,9 @@ struct SGB_GROUP if( entryOffset > fileSize ) throw std::runtime_error( "SGB_GROUP entry offset was larger than SGB file size!" ); auto type = *reinterpret_cast< uint32_t* >( buf + entryOffset ); - if( type == SgbGroupEntryType::Model && !ignoreModels ) + if( type == SgbGroupEntryType::Model || type == SgbGroupEntryType::Gimmick ) { - entries.push_back( std::make_shared< SGB_MODEL_ENTRY >( buf, entryOffset ) ); + entries.push_back( std::make_shared< SGB_MODEL_ENTRY >( buf, entryOffset, ( SgbGroupEntryType )type ) ); } else { @@ -249,5 +277,4 @@ struct SGB_FILE }; }; - -#endif // !_SGB_H +#endif // !_SGB_H \ No newline at end of file diff --git a/src/tools/event_object_parser/vec3.h b/src/common/Exd/StructureDef/vec3.h similarity index 100% rename from src/tools/event_object_parser/vec3.h rename to src/common/Exd/StructureDef/vec3.h diff --git a/src/tools/discovery_parser/main.cpp b/src/tools/discovery_parser/main.cpp index 03ef65cc..e4ded7a5 100644 --- a/src/tools/discovery_parser/main.cpp +++ b/src/tools/discovery_parser/main.cpp @@ -46,7 +46,7 @@ std::string zoneName; std::set< std::string > zoneDumpList; -xiv::dat::GameData* data1 = nullptr; +xiv::dat::GameData* gameData = nullptr; xiv::exd::ExdData* eData = nullptr; void readFileToBuffer( const std::string& path, std::vector< char >& buf ); @@ -135,8 +135,8 @@ struct face // init void initExd( const std::string& gamePath ) { - data1 = data1 ? data1 : new xiv::dat::GameData( gamePath ); - eData = eData ? eData : new xiv::exd::ExdData( *data1 ); + gameData = gameData ? gameData : new xiv::dat::GameData( gamePath ); + eData = eData ? eData : new xiv::exd::ExdData( *gameData ); } std::string zoneNameToPath( const std::string& name ) @@ -338,13 +338,13 @@ int main( int argc, char* argv[] ) std::vector< char > section1; std::vector< char > section2; - auto test_file = data1->getFile( bgLgbPath ); + auto test_file = gameData->getFile( bgLgbPath ); section = test_file->access_data_sections().at( 0 ); - auto planmap_file = data1->getFile( planmapLgbPath ); + auto planmap_file = gameData->getFile( planmapLgbPath ); section2 = planmap_file->access_data_sections().at( 0 ); - auto test_file1 = data1->getFile( listPcbPath ); + auto test_file1 = gameData->getFile( listPcbPath ); section1 = test_file1->access_data_sections().at( 0 ); std::vector< std::string > stringList; @@ -467,7 +467,7 @@ int main( int argc, char* argv[] ) if( eData ) delete eData; - if( data1 ) - delete data1; + if( gameData ) + delete gameData; return 0; } diff --git a/src/tools/event_object_parser/main.cpp b/src/tools/event_object_parser/main.cpp index 21d89575..04a55f4b 100644 --- a/src/tools/event_object_parser/main.cpp +++ b/src/tools/event_object_parser/main.cpp @@ -11,9 +11,9 @@ #include #include -#include "pcb.h" -#include "lgb.h" -#include "sgb.h" +#include +#include +#include #include #include @@ -40,7 +40,7 @@ namespace fs = std::experimental::filesystem; // garbage to ignore models bool ignoreModels = false; -std::string gamePath( "/home/mordred/sqpack" ); +std::string gamePath( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" ); //std::string gamePath( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" ); std::unordered_map< uint32_t, std::string > eobjNameMap; std::unordered_map< uint16_t, std::vector< std::pair< uint16_t, std::string > > > zoneInstanceMap; @@ -58,15 +58,15 @@ std::vector< instanceContent > contentList; std::set< std::string > zoneDumpList; -xiv::dat::GameData* data1 = nullptr; +xiv::dat::GameData* gameData = nullptr; xiv::exd::ExdData* eData = nullptr; using namespace std::chrono_literals; void initExd( const std::string& gamePath ) { - data1 = data1 ? data1 : new xiv::dat::GameData( gamePath ); - eData = eData ? eData : new xiv::exd::ExdData( *data1 ); + gameData = gameData ? gameData : new xiv::dat::GameData( gamePath ); + eData = eData ? eData : new xiv::exd::ExdData( *gameData ); } int parseBlockEntry( char* data, std::vector< PCB_BLOCK_ENTRY >& entries, int gOff ) @@ -348,19 +348,48 @@ int main( int argc, char* argv[] ) std::string listPcbPath( zonePath + "/collision/list.pcb" ); std::string bgLgbPath( zonePath + "/level/bg.lgb" ); std::string planmapLgbPath( zonePath + "/level/planmap.lgb" ); + std::string planeventLgbPath( zonePath + "/level/planevent.lgb" ); std::string collisionFilePath( zonePath + "/collision/" ); + std::string plannerFilePath( zonePath + "/level/planner.lgb" ); + std::string lcbFilePath( zonePath + "/level/" + zoneName + ".lcb" ); + std::string svbFilePath( zonePath + "/level/" + zoneName + ".svb" ); std::vector< char > section; std::vector< char > section1; std::vector< char > section2; + std::vector< char > section3; - const xiv::dat::Cat& test = data1->getCategory( "bg" ); + const xiv::dat::Cat& test = gameData->getCategory( "bg" ); - auto test_file = data1->getFile( bgLgbPath ); + auto test_file = gameData->getFile( bgLgbPath ); section = test_file->access_data_sections().at( 0 ); - auto planmap_file = data1->getFile( planmapLgbPath ); + auto planmap_file = gameData->getFile( planmapLgbPath ); section2 = planmap_file->access_data_sections().at( 0 ); + auto planeventFile = gameData->getFile( planeventLgbPath ); + section3 = planeventFile->access_data_sections().at( 0 ); + + auto exportFile = [&]( const std::string& path ) + { + try + { + auto file = gameData->getFile( path ); + + if( !file ) + { + return; + } + auto p = fs::path( path ); + fs::create_directories( p.parent_path() ); + file->exportToFile( p ); + } + catch( const std::exception& ex ) {} + }; + + exportFile( planeventLgbPath ); + exportFile( plannerFilePath ); + exportFile( lcbFilePath ); + exportFile( svbFilePath ); std::vector< std::string > stringList; @@ -370,8 +399,9 @@ int main( int argc, char* argv[] ) LGB_FILE bgLgb( §ion[ 0 ], "bg" ); LGB_FILE planmapLgb( §ion2[ 0 ], "planmap" ); + LGB_FILE planeventLgb( §ion3[ 0 ], "planevent" ); - std::vector< LGB_FILE > lgbList{ bgLgb, planmapLgb }; + std::vector< LGB_FILE > lgbList{ bgLgb, planmapLgb, planeventLgb }; uint32_t max_index = 0; //if( ignoreModels ) @@ -385,7 +415,7 @@ int main( int argc, char* argv[] ) { char* dataSection = nullptr; //std::cout << fileName << " "; - auto file = data1->getFile( fileName ); + auto file = gameData->getFile( fileName ); auto sections = file->get_data_sections(); dataSection = §ions.at( 0 )[ 0 ]; sgbFile = SGB_FILE( &dataSection[ 0 ] ); @@ -453,7 +483,7 @@ int main( int argc, char* argv[] ) char* dataSection = nullptr; //std::cout << fileName << " "; - auto file = data1->getFile( pGObjR->gimmickFileName ); + auto file = gameData->getFile( pGObjR->gimmickFileName ); auto sections = file->get_data_sections(); dataSection = §ions.at( 0 )[ 0 ]; auto sgbFile = SGB_FILE( &dataSection[ 0 ] ); @@ -487,7 +517,7 @@ int main( int argc, char* argv[] ) if( eobjNameMap.find( id ) != eobjNameMap.end() ) { name = eobjNameMap[ id ]; - std::string remove = ",★_ '()[]-\xae\x1a\x1\x2\x1f\x1\x3.:"; + std::string remove = "\",★_ '()[]-\xae\x1a\x1\x2\x1f\x1\x3.:"; Sapphire::Util::eraseAllIn( name, remove ); name[ 0 ] = toupper( name[ 0 ] ); @@ -614,7 +644,7 @@ int main( int argc, char* argv[] ) if( eData ) delete eData; - if( data1 ) - delete data1; + if( gameData ) + delete gameData; return 0; } diff --git a/src/tools/exd_struct_test/main.cpp b/src/tools/exd_struct_test/main.cpp index b6da89bf..3426804d 100644 --- a/src/tools/exd_struct_test/main.cpp +++ b/src/tools/exd_struct_test/main.cpp @@ -16,18 +16,54 @@ #include #include +#include +#include +#include + #include +#include + Sapphire::Common::Util::CrashHandler crashHandler; Sapphire::Data::ExdDataGenerated g_exdData; +xiv::dat::GameData* gameData = nullptr; using namespace Sapphire; +namespace fs = std::experimental::filesystem; + //const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" ); const std::string datLocation( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" ); -int main() +void exportFile( const std::string& path ) +{ + try + { + auto file = gameData->getFile( path ); + + if( !file ) + { + return; + } + auto p = fs::path( path ); + fs::create_directories( p.parent_path() ); + file->exportToFile( p ); + } + catch( const std::exception& ex ) + { + Logger::error( "Failed to export file {0}, error: {1}", path, ex.what() ); + } +} + +struct DupeResult +{ + std::string groupName; + std::string lgb; + uint32_t id; +}; + +int main( int argc, char* argv[] ) { Logger::init( "struct_test" ); @@ -39,14 +75,97 @@ int main() return 0; } - auto gld = g_exdData.get< Sapphire::Data::ClassJob >( 1 ); - if( gld ) - { - Logger::info( "got {0}", gld->name ); - } - else - Logger::warn( "failed to get classjob {}", 1 ); + gameData = new xiv::dat::GameData( datLocation ); + if( argc > 1 ) + { + while( argc-- > 1 ) + { + Logger::info( "Exporting file: {}", argv[ argc ] ); + exportFile( argv[ argc ] ); + } + + return 0; + } + + std::vector< std::string > levelNames; + std::vector< std::string > paths; + + std::vector< uint32_t > lgbGroupIds; + std::vector< DupeResult > lgbGroupDupes; + + paths.emplace_back( "level/bg.lgb" ); + paths.emplace_back( "level/planmap.lgb" ); + paths.emplace_back( "level/planevent.lgb" ); + paths.emplace_back( "level/planlive.lgb" ); + paths.emplace_back( "level/sound.lgb" ); + paths.emplace_back( "level/planner.lgb" ); + + auto ids = g_exdData.getTerritoryTypeIdList(); + + for( auto id : ids ) + { + auto territoryType = g_exdData.get< Data::TerritoryType >( id ); + if( !territoryType ) + continue; + + auto bg = territoryType->bg; + bg = bg.substr( 0, bg.find( "/level/" ) ); + + if( bg.empty() ) + continue; + + if( std::find( levelNames.begin(), levelNames.end(), bg ) != levelNames.end() ) + continue; + + levelNames.push_back( bg ); + + Logger::info( "LGB groups for: {}", bg ); + + for( const auto& path : paths ) + { + auto filePath = fmt::format( "bg/{}/{}", bg, path ); + + try + { + auto file = gameData->getFile( filePath ); + auto data = file->access_data_sections().at( 0 ); + + LGB_FILE lgb( &data[ 0 ], "wtf" ); + + Logger::info(" {} groups: {}", path, lgb.header.groupCount ); + + for( const auto& group : lgb.groups ) + { + Logger::info( " - {:<7} {:<25} children: {}", group.header.unknown, group.name, group.header.entryCount ); + + if( std::find( lgbGroupIds.begin(), lgbGroupIds.end(), group.header.unknown ) == lgbGroupIds.end() ) + { + lgbGroupIds.emplace_back( group.header.unknown ); + } + else + { + lgbGroupDupes.push_back( { group.name, filePath, group.header.unknown } ); + } + } + Logger::info( "" ); + } + catch( const std::exception& ex ) + { + Logger::warn( "Failed on file {}, error: {}", path, ex.what() ); + } + } + } + + if( !lgbGroupDupes.empty() ) + { + Logger::info( "Found duplicate LGB group ids: " ); + + for( const auto& result : lgbGroupDupes ) + { + Logger::info( " - file: {:<50} group: {:<30} id: {}", result.lgb, result.groupName, result.id ); + } + } return 0; } diff --git a/src/tools/nav_export/main.cpp b/src/tools/nav_export/main.cpp index af3cf261..600ba1dd 100644 --- a/src/tools/nav_export/main.cpp +++ b/src/tools/nav_export/main.cpp @@ -42,7 +42,7 @@ std::set< std::string > zoneDumpList; std::shared_ptr< Cache > pCache; std::map< uint32_t, uint16_t > eobjSgbPaths; -xiv::dat::GameData* data1 = nullptr; +xiv::dat::GameData* gameData = nullptr; xiv::exd::ExdData* eData = nullptr; @@ -57,9 +57,9 @@ using namespace std::chrono_literals; void initExd( const std::string& gamePath ) { - data1 = data1 ? data1 : new xiv::dat::GameData( gamePath ); - eData = eData ? eData : new xiv::exd::ExdData( *data1 ); - pCache = std::make_shared< Cache >( data1 ); + gameData = gameData ? gameData : new xiv::dat::GameData( gamePath ); + eData = eData ? eData : new xiv::exd::ExdData( *gameData ); + pCache = std::make_shared< Cache >( gameData ); } void replaceAll( std::string& str, const std::string& from, const std::string& to ) { @@ -360,15 +360,15 @@ int main( int argc, char* argv[] ) std::vector< char > section1; std::vector< char > section2; - const xiv::dat::Cat& test = data1->getCategory( "bg" ); + const xiv::dat::Cat& test = gameData->getCategory( "bg" ); - auto test_file = data1->getFile( bgLgbPath ); + auto test_file = gameData->getFile( bgLgbPath ); section = test_file->access_data_sections().at( 0 ); - auto planmap_file = data1->getFile( planmapLgbPath ); + auto planmap_file = gameData->getFile( planmapLgbPath ); section2 = planmap_file->access_data_sections().at( 0 ); - auto test_file1 = data1->getFile( listPcbPath ); + auto test_file1 = gameData->getFile( listPcbPath ); section1 = test_file1->access_data_sections().at( 0 ); std::vector< std::string > stringList; @@ -456,7 +456,7 @@ int main( int argc, char* argv[] ) if( auto pGimmick = pCache->getSgbFile( sgbPath ) ) { - for( const auto& offset1cFile : pGimmick->offset1cObjects ) + for( const auto& offset1cFile : pGimmick->stateEntries ) exportSgbModel( offset1cFile, pEobj, exportedGroup, true ); } } @@ -497,7 +497,7 @@ int main( int argc, char* argv[] ) std::chrono::duration_cast< std::chrono::seconds >( std::chrono::high_resolution_clock::now() - startTime ).count() ); delete eData; - delete data1; + delete gameData; return 0; } diff --git a/src/tools/nav_export/sgb.h b/src/tools/nav_export/sgb.h index b3264055..1ae465b0 100644 --- a/src/tools/nav_export/sgb.h +++ b/src/tools/nav_export/sgb.h @@ -243,7 +243,7 @@ struct SGB_FILE { SGB_HEADER header; std::vector< SGB_GROUP > entries; - std::set< std::string > offset1cObjects; + std::set< std::string > stateEntries; SGB_FILE() { @@ -260,9 +260,9 @@ struct SGB_FILE try { - auto group = SGB_GROUP( buf, this, &offset1cObjects, header.fileSize, baseOffset + header.sharedOffset ); + auto group = SGB_GROUP( buf, this, &stateEntries, header.fileSize, baseOffset + header.sharedOffset ); entries.push_back( group ); - auto group2 = SGB_GROUP( buf, this, &offset1cObjects, header.fileSize, baseOffset+ header.offset1C, true ); + auto group2 = SGB_GROUP( buf, this, &stateEntries, header.fileSize, baseOffset+ header.offset1C, true ); entries.push_back( group2 ); } catch( std::exception& e ) diff --git a/src/tools/pcb_reader/main.cpp b/src/tools/pcb_reader/main.cpp index 8b44878e..7c922a12 100644 --- a/src/tools/pcb_reader/main.cpp +++ b/src/tools/pcb_reader/main.cpp @@ -44,7 +44,7 @@ std::set< std::string > zoneDumpList; std::shared_ptr< Cache > pCache; std::map< uint32_t, uint16_t > eobjSgbPaths; -xiv::dat::GameData* data1 = nullptr; +xiv::dat::GameData* gameData = nullptr; xiv::exd::ExdData* eData = nullptr; @@ -59,9 +59,9 @@ using namespace std::chrono_literals; void initExd( const std::string& gamePath ) { - data1 = data1 ? data1 : new xiv::dat::GameData( gamePath ); - eData = eData ? eData : new xiv::exd::ExdData( *data1 ); - pCache = std::make_shared< Cache >( data1 ); + gameData = gameData ? gameData : new xiv::dat::GameData( gamePath ); + eData = eData ? eData : new xiv::exd::ExdData( *gameData ); + pCache = std::make_shared< Cache >( gameData ); } void replaceAll( std::string& str, const std::string& from, const std::string& to ) { @@ -249,15 +249,15 @@ int main( int argc, char* argv[] ) std::vector< char > section1; std::vector< char > section2; - const xiv::dat::Cat& test = data1->getCategory( "bg" ); + const xiv::dat::Cat& test = gameData->getCategory( "bg" ); - auto test_file = data1->getFile( bgLgbPath ); + auto test_file = gameData->getFile( bgLgbPath ); section = test_file->access_data_sections().at( 0 ); - auto planmap_file = data1->getFile( planmapLgbPath ); + auto planmap_file = gameData->getFile( planmapLgbPath ); section2 = planmap_file->access_data_sections().at( 0 ); - auto test_file1 = data1->getFile( listPcbPath ); + auto test_file1 = gameData->getFile( listPcbPath ); section1 = test_file1->access_data_sections().at( 0 ); std::vector< std::string > stringList; @@ -499,7 +499,7 @@ int main( int argc, char* argv[] ) if( auto pGimmick = pCache->getSgbFile( sgbPath ) ) { - for( const auto& offset1cFile : pGimmick->offset1cObjects ) + for( const auto& offset1cFile : pGimmick->stateEntries ) exportSgbModel( offset1cFile, pEobj, true ); } } @@ -541,7 +541,7 @@ int main( int argc, char* argv[] ) std::chrono::duration_cast< std::chrono::seconds >( std::chrono::high_resolution_clock::now() - startTime ).count() ); delete eData; - delete data1; + delete gameData; return 0; } diff --git a/src/tools/pcb_reader/sgb.h b/src/tools/pcb_reader/sgb.h index b3264055..1ae465b0 100644 --- a/src/tools/pcb_reader/sgb.h +++ b/src/tools/pcb_reader/sgb.h @@ -243,7 +243,7 @@ struct SGB_FILE { SGB_HEADER header; std::vector< SGB_GROUP > entries; - std::set< std::string > offset1cObjects; + std::set< std::string > stateEntries; SGB_FILE() { @@ -260,9 +260,9 @@ struct SGB_FILE try { - auto group = SGB_GROUP( buf, this, &offset1cObjects, header.fileSize, baseOffset + header.sharedOffset ); + auto group = SGB_GROUP( buf, this, &stateEntries, header.fileSize, baseOffset + header.sharedOffset ); entries.push_back( group ); - auto group2 = SGB_GROUP( buf, this, &offset1cObjects, header.fileSize, baseOffset+ header.offset1C, true ); + auto group2 = SGB_GROUP( buf, this, &stateEntries, header.fileSize, baseOffset+ header.offset1C, true ); entries.push_back( group2 ); } catch( std::exception& e ) From c533449aebde0f82e63ee8a273762787de4e9640 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 11 Apr 2019 19:09:19 +1000 Subject: [PATCH 2/8] merge in maprange header changes and move to common defs --- src/common/Exd/StructureDef/lgb.h | 15 +- src/tools/discovery_parser/lgb.h | 404 --------------------------- src/tools/discovery_parser/main.cpp | 6 +- src/tools/discovery_parser/matrix4.h | 111 -------- src/tools/discovery_parser/pcb.h | 92 ------ src/tools/discovery_parser/sgb.h | 222 --------------- src/tools/discovery_parser/vec3.h | 60 ---- 7 files changed, 16 insertions(+), 894 deletions(-) delete mode 100644 src/tools/discovery_parser/lgb.h delete mode 100644 src/tools/discovery_parser/matrix4.h delete mode 100644 src/tools/discovery_parser/pcb.h delete mode 100644 src/tools/discovery_parser/sgb.h delete mode 100644 src/tools/discovery_parser/vec3.h diff --git a/src/common/Exd/StructureDef/lgb.h b/src/common/Exd/StructureDef/lgb.h index b8328ed4..5b9c5c50 100644 --- a/src/common/Exd/StructureDef/lgb.h +++ b/src/common/Exd/StructureDef/lgb.h @@ -218,9 +218,20 @@ struct LGB_MAPRANGE_HEADER : public LGB_ENTRY_HEADER { uint32_t type; - uint16_t unknown2; + uint8_t unknown2; + uint8_t unknown2_1; uint16_t unknown3; - uint8_t unknown4[0x10]; + uint32_t unknown5; + uint32_t mapId; + uint32_t offsetX, offsetY; + uint32_t unkInts[4]; + uint16_t unkShort; + uint8_t unkFlag; + uint8_t unkFlag2; + uint8_t discoveryIndex; + uint8_t unkFlag3; + uint8_t unkFlag4; + uint8_t unknown4[0x09]; }; struct LGB_MAPRANGE_ENTRY : diff --git a/src/tools/discovery_parser/lgb.h b/src/tools/discovery_parser/lgb.h deleted file mode 100644 index 8cfb3bc8..00000000 --- a/src/tools/discovery_parser/lgb.h +++ /dev/null @@ -1,404 +0,0 @@ -#ifndef _LGB_H -#define _LGB_H - -#include -#include -#include -#include -#include -#include -#include - -#include "matrix4.h" -#include "vec3.h" -#include "sgb.h" - -// garbage to skip model loading -extern bool ignoreModels; - -// all credit to -// https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/ -// this is simply their work ported to c++ since we dont c# -struct LGB_FILE; -struct LGB_FILE_HEADER; -struct LGB_GROUP; -struct LGB_GROUP_HEADER; - -enum class LgbEntryType : - uint32_t -{ - BgParts = 1, - Light = 3, - Vfx = 4, - PositionMarker = 5, - Gimmick = 6, - SharedGroup6 = 6,// secondary variable is set to 2 - Sound = 7, - EventNpc = 8, - BattleNpc = 9, - Aetheryte = 12, - EnvSpace = 13, - Gathering = 14, - SharedGroup15 = 15,// secondary variable is set to 13 - Treasure = 16, - Weapon = 39, - PopRange = 40, - ExitRange = 41, - MapRange = 43, - NaviMeshRange = 44, - EventObject = 45, - EnvLocation = 47, - EventRange = 49, - QuestMarker = 51, - CollisionBox = 57, - DoorRange = 58, - LineVfx = 59, - ClientPath = 65, - ServerPath = 66, - GimmickRange = 67, - TargetMarker = 68, - ChairMarker = 69, - ClickableRange = 70, - PrefetchRange = 71, - FateRange = 72, - SphereCastRange = 75, -}; - -struct LGB_ENTRY_HEADER -{ - LgbEntryType type; - uint32_t unknown; - uint32_t nameOffset; - vec3 translation; - vec3 rotation; - vec3 scale; -}; - -class LGB_ENTRY -{ -public: - char* m_buf; - uint32_t m_offset; - LGB_ENTRY_HEADER header; - - LGB_ENTRY() - { - m_buf = nullptr; - m_offset = 0; - memset( &header, 0, sizeof( header ) ); - }; - - LGB_ENTRY( char* buf, uint32_t offset ) - { - m_buf = buf; - m_offset = offset; - header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset ); - }; - - const LgbEntryType getType() const - { - return header.type; - }; - - virtual ~LGB_ENTRY() - { - }; -}; - - -struct LGB_BGPARTS_HEADER : - public LGB_ENTRY_HEADER -{ - uint32_t modelFileOffset; - uint32_t collisionFileOffset; - uint32_t unknown4; - uint32_t unknown5; - uint32_t unknown6; - uint32_t unknown7; - uint32_t unknown8; - uint32_t unknown9; -}; - -class LGB_BGPARTS_ENTRY : - public LGB_ENTRY -{ -public: - LGB_BGPARTS_HEADER header; - std::string name; - std::string modelFileName; - std::string collisionFileName; - - LGB_BGPARTS_ENTRY() - { - }; - - LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) : - LGB_ENTRY( buf, offset ) - { - header = *reinterpret_cast( buf + offset ); - name = std::string( buf + offset + header.nameOffset ); - modelFileName = std::string( buf + offset + header.modelFileOffset ); - collisionFileName = std::string( buf + offset + header.collisionFileOffset ); - }; -}; - -struct LGB_GIMMICK_HEADER : - public LGB_ENTRY_HEADER -{ - uint32_t gimmickFileOffset; - char unknownBytes[100]; -}; - -class LGB_GIMMICK_ENTRY : - public LGB_ENTRY -{ -public: - LGB_GIMMICK_HEADER header; - std::string name; - std::string gimmickFileName; - - LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) : - LGB_ENTRY( buf, offset ) - { - header = *reinterpret_cast( buf + offset ); - name = std::string( buf + offset + header.nameOffset ); - gimmickFileName = std::string( buf + offset + header.gimmickFileOffset ); - //std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n"; - }; -}; - -struct LGB_ENPC_HEADER : - public LGB_ENTRY_HEADER -{ - uint32_t enpcId; - uint8_t unknown1[0x24]; -}; - -class LGB_ENPC_ENTRY : - public LGB_ENTRY -{ -public: - LGB_ENPC_HEADER header; - std::string name; - - LGB_ENPC_ENTRY( char* buf, uint32_t offset ) : - LGB_ENTRY( buf, offset ) - { - header = *reinterpret_cast< LGB_ENPC_HEADER* >( buf + offset ); - name = std::string( buf + offset + header.nameOffset ); - //std::cout << "\t ENpc " << header.enpcId << " " << name << "\n"; - }; -}; - -struct LGB_EOBJ_HEADER : - public LGB_ENTRY_HEADER -{ - uint32_t eobjId; - uint32_t levelHierachyId; - uint8_t unknown1[0xC]; -}; - -class LGB_EOBJ_ENTRY : - public LGB_ENTRY -{ -public: - LGB_EOBJ_HEADER header; - std::string name; - - LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) : - LGB_ENTRY( buf, offset ) - { - header = *reinterpret_cast< LGB_EOBJ_HEADER* >( buf + offset ); - //std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n"; - name = std::string( buf + offset + header.nameOffset ); - }; -}; - -struct LGB_MAPRANGE_HEADER : - public LGB_ENTRY_HEADER -{ - uint32_t type; - uint8_t unknown2; - uint8_t unknown2_1; - uint16_t unknown3; - uint32_t unknown5; - uint32_t mapId; - uint32_t offsetX, offsetY; - uint32_t unkInts[4]; - uint16_t unkShort; - uint8_t unkFlag; - uint8_t unkFlag2; - uint8_t discoveryIndex; - uint8_t unkFlag3; - uint8_t unkFlag4; - uint8_t unknown4[0x09]; -}; - -struct LGB_MAPRANGE_ENTRY : - public LGB_ENTRY -{ -public: - LGB_MAPRANGE_HEADER header; - std::string name; - - LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) : - LGB_ENTRY( buf, offset ) - { - header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset ); - name = std::string( buf + offset + header.nameOffset ); - - }; -}; - -struct LGB_POPRANGE_ENTRY : - public LGB_ENTRY -{ -public: - LGB_MAPRANGE_HEADER header; - std::string name; - - LGB_POPRANGE_ENTRY( char* buf, uint32_t offset ) : - LGB_ENTRY( buf, offset ) - { - header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset ); - name = std::string( buf + offset + header.nameOffset ); - - }; -}; - -struct LGB_GROUP_HEADER -{ - uint32_t unknown; - int32_t groupNameOffset; - int32_t entriesOffset; - int32_t entryCount; - uint32_t unknown2; - uint32_t unknown3; - uint32_t unknown4; - uint32_t unknown5; - uint32_t unknown6; - uint32_t unknown7; - uint32_t unknown8; - uint32_t unknown9; - uint32_t unknown10; -}; - -struct LGB_GROUP -{ - LGB_FILE* parent; - LGB_GROUP_HEADER header; - std::string name; - std::vector< std::shared_ptr< LGB_ENTRY > > entries; - - LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset ) - { - parent = parentStruct; - header = *reinterpret_cast< LGB_GROUP_HEADER* >( buf + offset ); - name = std::string( buf + offset + header.groupNameOffset ); - //entries.resize( header.entryCount ); - //std::cout << name << "\n\t unknown: " << header.unknown << "\n"; - const auto entriesOffset = offset + header.entriesOffset; - for( auto i = 0; i < header.entryCount; ++i ) - { - const auto entryOffset = entriesOffset + *reinterpret_cast< int32_t* >( buf + ( entriesOffset + i * 4 ) ); - - try - { - const auto type = *reinterpret_cast( buf + entryOffset ); - // garbage to skip model loading - if( type == LgbEntryType::PopRange ) - { - entries.push_back( std::make_shared< LGB_POPRANGE_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::MapRange ) - { - entries.push_back( std::make_shared< LGB_MAPRANGE_ENTRY >( buf, entryOffset ) ); - } - /* - else - { - entries[i] = nullptr; - } - */ - - } - catch( std::exception& e ) - { - std::cout << name << " " << e.what() << std::endl; - } - } - }; -}; - -struct LGB_FILE_HEADER -{ - char magic[4]; // LGB 1 - uint32_t fileSize; - uint32_t unknown; - char magic2[4]; // LGP1 - uint32_t unknown2; - uint32_t unknown3; - uint32_t unknown4; - uint32_t unknown5; - int32_t groupCount; -}; - -struct LGB_FILE -{ - LGB_FILE_HEADER header; - std::vector< LGB_GROUP > groups; - std::string name; - - LGB_FILE( char* buf, const std::string& name ) - { - header = *reinterpret_cast< LGB_FILE_HEADER* >( buf ); - if( strncmp( &header.magic[ 0 ], "LGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "LGP1", 4 ) != 0 ) - throw std::runtime_error( "Invalid LGB file!" ); - - //groups.resize(header.groupCount); - - constexpr auto baseOffset = sizeof( header ); - for( auto i = 0; i < header.groupCount; ++i ) - { - const auto groupOffset = baseOffset + *reinterpret_cast< int32_t* >( buf + ( baseOffset + i * 4 ) ); - const auto group = LGB_GROUP( buf, this, groupOffset ); - groups.push_back( group ); - } - }; -}; - -/* -#if __cplusplus >= 201703L -#include -std::map getLgbFiles( const std::string& dir ) -{ - namespace fs = std::experimental::filesystem; - std::map fileMap; - for( const auto& path : fs::recursive_directory_iterator( dir ) ) - { - if( path.path().extension() == ".lgb" ) - { - const auto& strPath = path.path().string(); - auto f = fopen( strPath.c_str(), "rb" ); - fseek( f, 0, SEEK_END ); - const auto size = ftell( f ); - std::vector bytes( size ); - rewind( f ); - fread( bytes.data(), 1, size, f ); - fclose( f ); - try - { - LGB_FILE lgbFile( bytes.data() ); - fileMap.insert( std::make_pair( strPath, lgbFile ) ); - } - catch( std::exception& e ) - { - std::cout << "Unable to load " << strPath << std::endl; - } - } - } - return fileMap; -} -#endif -*/ -#endif \ No newline at end of file diff --git a/src/tools/discovery_parser/main.cpp b/src/tools/discovery_parser/main.cpp index e4ded7a5..1c87ce7d 100644 --- a/src/tools/discovery_parser/main.cpp +++ b/src/tools/discovery_parser/main.cpp @@ -13,9 +13,9 @@ #include -#include "pcb.h" -#include "lgb.h" -#include "sgb.h" +#include +#include +#include #include "tex.h" #include "tex_decode.h" diff --git a/src/tools/discovery_parser/matrix4.h b/src/tools/discovery_parser/matrix4.h deleted file mode 100644 index fdcee84c..00000000 --- a/src/tools/discovery_parser/matrix4.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef _MATRIX4_H -#define _MATRIX4_H - -#include -#include - -// https://github.com/jpd002/Play--Framework/tree/master/include/math -struct matrix4 -{ - // 4x4 - float grid[16]; - - matrix4() - { - memset( &grid[ 0 ], 0, sizeof( grid ) ); - } - - float operator()( int row, int col ) const - { - return grid[ ( row * 4 ) + col ]; - } - - float& operator()( int row, int col ) - { - return grid[ ( row * 4 ) + col ]; - } - - static matrix4 rotateX( float angle ) - { - matrix4 ret = matrix4(); - ret( 0, 0 ) = 1.000000000f; - ret( 1, 1 ) = cos( angle ); - ret( 1, 2 ) = -sin( angle ); - ret( 2, 1 ) = sin( angle ); - ret( 2, 2 ) = cos( angle ); - ret( 3, 3 ) = 1.000000000f; - return ret; - } - - static matrix4 rotateY( float angle ) - { - matrix4 ret = matrix4(); - ret( 0, 0 ) = cos( angle ); - ret( 0, 2 ) = sin( angle ); - ret( 1, 1 ) = 1.000000000f; - ret( 2, 0 ) = -sin( angle ); - ret( 2, 2 ) = cos( angle ); - ret( 3, 3 ) = 1.000000000f; - return ret; - } - - static matrix4 rotateZ( float angle ) - { - matrix4 ret = matrix4(); - ret( 0, 0 ) = cos( angle ); - ret( 0, 1 ) = -sin( angle ); - ret( 1, 0 ) = sin( angle ); - ret( 1, 1 ) = cos( angle ); - ret( 2, 2 ) = 1.000000000f; - ret( 3, 3 ) = 1.000000000f; - return ret; - } - - static matrix4 scale( float x, float y, float z ) - { - matrix4 ret = matrix4(); - ret( 0, 0 ) = x; - ret( 1, 1 ) = y; - ret( 2, 2 ) = z; - ret( 3, 3 ) = 1; - - return ret; - } - - static matrix4 translate( float x, float y, float z ) - { - matrix4 ret = matrix4(); - ret( 0, 0 ) = 1; - ret( 1, 1 ) = 1; - ret( 2, 2 ) = 1; - ret( 3, 3 ) = 1; - - ret( 3, 0 ) = x; - ret( 3, 1 ) = y; - ret( 3, 2 ) = z; - return ret; - } - - matrix4 operator*( const matrix4& rhs ) const - { - matrix4 ret; - for( unsigned int i = 0; i < 4; i++ ) - { - ret( i, 0 ) = - ( *this )( i, 0 ) * rhs( 0, 0 ) + ( *this )( i, 1 ) * rhs( 1, 0 ) + ( *this )( i, 2 ) * rhs( 2, 0 ) + - ( *this )( i, 3 ) * rhs( 3, 0 ); - ret( i, 1 ) = - ( *this )( i, 0 ) * rhs( 0, 1 ) + ( *this )( i, 1 ) * rhs( 1, 1 ) + ( *this )( i, 2 ) * rhs( 2, 1 ) + - ( *this )( i, 3 ) * rhs( 3, 1 ); - ret( i, 2 ) = - ( *this )( i, 0 ) * rhs( 0, 2 ) + ( *this )( i, 1 ) * rhs( 1, 2 ) + ( *this )( i, 2 ) * rhs( 2, 2 ) + - ( *this )( i, 3 ) * rhs( 3, 2 ); - ret( i, 3 ) = - ( *this )( i, 0 ) * rhs( 0, 3 ) + ( *this )( i, 1 ) * rhs( 1, 3 ) + ( *this )( i, 2 ) * rhs( 2, 3 ) + - ( *this )( i, 3 ) * rhs( 3, 3 ); - } - return ret; - } -}; - -#endif diff --git a/src/tools/discovery_parser/pcb.h b/src/tools/discovery_parser/pcb.h deleted file mode 100644 index 77a50d81..00000000 --- a/src/tools/discovery_parser/pcb.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef _PCB_H -#define _PCB_H - -#include -#include - -struct PCB_HEADER -{ - uint32_t unknown_1; - uint32_t unknown_2; - uint32_t num_entries; // count starts at 0 - uint32_t total_indices; - uint64_t padding; -}; - -struct PCB_BLOCK_HEADER -{ - uint32_t type; // 0 for entry, 0x30 for group - uint32_t group_size; // when group size in bytes for the group block - // bounding box - float x; - float y; - float z; - float x1; - float y1; - float z1; - // number of vertices packed into 16 bit - uint16_t num_v16; - // number of indices - uint16_t num_indices; - // number of normal floar vertices - uint32_t num_vertices; -}; - -struct PCB_VERTEXDATA -{ - float x; - float y; - float z; -}; - -struct PCB_INDEXDATA -{ - uint8_t index[3]; - uint8_t unknown[3]; - uint8_t unknown1[6]; -}; - -struct PCB_VERTEXDATAI16 -{ - uint16_t x; - uint16_t y; - uint16_t z; -}; - -struct PCB_BLOCK_DATA -{ - std::vector< PCB_VERTEXDATA > vertices; - std::vector< PCB_VERTEXDATAI16 > vertices_i16; - std::vector< PCB_INDEXDATA > indices; -}; - -struct PCB_BLOCK_ENTRY -{ - PCB_BLOCK_HEADER header; - PCB_BLOCK_DATA data; -}; - -struct PCB_FILE -{ - PCB_HEADER header; - std::vector< PCB_BLOCK_ENTRY > entries; -}; - -struct PCB_LIST_ENTRY -{ - uint32_t id; - float x, y, z, x2, y2, z2, rot; -}; - -struct PCB_LIST_BASE_ENTRY -{ - float x, y, z, x2, y2, z2, rot; -}; - -struct PCB_LIST_FILE -{ - uint32_t count; - PCB_LIST_BASE_ENTRY entry; - std::vector< PCB_LIST_ENTRY > entries; -}; -#endif \ No newline at end of file diff --git a/src/tools/discovery_parser/sgb.h b/src/tools/discovery_parser/sgb.h deleted file mode 100644 index cf03c12e..00000000 --- a/src/tools/discovery_parser/sgb.h +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef _SGB_H -#define _SGB_H - -#include -#include -#include -#include -#include -#include -#include - -#include "vec3.h" - -// garbage to skip model loading -extern bool ignoreModels; - -// -// ported from https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Sgb/SgbDataType.cs - -struct SGB_FILE; -struct SGB_HEADER; -struct SGB_MODEL_ENTRY; -struct SGB_MODEL_HEADER; -struct SGB_GROUP; -struct SGB_GROUP_HEADER; - - -enum SgbDataType : - uint32_t -{ - Unknown0008 = 0x0008, - Group = 0x0100, -}; - -enum SgbGroupEntryType : - uint32_t -{ - Model = 0x01, -}; - -struct SGB_GROUP_HEADER -{ - SgbDataType type; - int32_t nameOffset; - uint32_t unknown08; - uint32_t unknown0C; - - uint32_t unknown10; - uint32_t unknown14; - uint32_t unknown18; - uint32_t unknown1C; - - int32_t entryCount; - uint32_t unknown24; - uint32_t unknown28; - uint32_t unknown2C; - - uint32_t unknown30; - uint32_t unknown34; - uint32_t unknown38; - uint32_t unknown3C; - - uint32_t unknown40; - uint32_t unknown44; -}; - -struct SGB_GROUP_ENTRY -{ -public: - char* m_buf; - uint32_t m_offset; - - SGB_GROUP_ENTRY() - { - m_buf = nullptr; - m_offset = 0; - }; - - SGB_GROUP_ENTRY( char* buf, uint32_t offset ) - { - m_buf = buf; - m_offset = offset; - }; - - virtual ~SGB_GROUP_ENTRY() - { - }; -}; - -struct SGB_ENTRY_HEADER -{ - SgbGroupEntryType type; - uint32_t unknown2; - int32_t nameOffset; - vec3 translation; - vec3 rotation; - vec3 scale; -}; - -struct SGB_MODEL_HEADER : - public SGB_ENTRY_HEADER -{ - int32_t modelFileOffset; - int32_t collisionFileOffset; -}; - -struct SGB_MODEL_ENTRY : - public SGB_GROUP_ENTRY -{ - SGB_MODEL_HEADER header; - SgbGroupEntryType type; - std::string name; - std::string modelFileName; - std::string collisionFileName; - - SGB_MODEL_ENTRY( char* buf, uint32_t offset ) - { - header = *reinterpret_cast< SGB_MODEL_HEADER* >( buf + offset ); - name = std::string( buf + offset + header.nameOffset ); - modelFileName = std::string( buf + offset + header.modelFileOffset ); - collisionFileName = std::string( buf + offset + header.collisionFileOffset ); - } -}; - -struct SGB_GROUP -{ - SGB_GROUP_HEADER header; - std::string name; - SGB_FILE* parent; - std::vector< std::shared_ptr< SGB_GROUP_ENTRY > > entries; - - SGB_GROUP( char* buf, SGB_FILE* file, uint32_t fileSize, uint32_t offset ) - { - parent = file; - header = *reinterpret_cast< SGB_GROUP_HEADER* >( buf + offset ); - name = std::string( buf + offset + header.nameOffset ); - - auto entriesOffset = offset + sizeof( header ); - - for( auto i = 0; i < header.entryCount; ++i ) - { - auto entryOffset = entriesOffset + *reinterpret_cast< uint32_t* >( buf + ( entriesOffset + ( i * 4 ) ) ); - if( entryOffset > fileSize ) - throw std::runtime_error( "SGB_GROUP entry offset was larger than SGB file size!" ); - auto type = *reinterpret_cast< uint32_t* >( buf + entryOffset ); - if( type == SgbGroupEntryType::Model && !ignoreModels ) - { - entries.push_back( std::make_shared< SGB_MODEL_ENTRY >( buf, entryOffset ) ); - } - else - { - // std::cout << "\t\tUnknown SGB entry! Group: " << name << " type: " << type << " index: " << i << " entryOffset: " << entryOffset << "\n"; - } - } - } -}; - -struct SGB_HEADER -{ - char magic[4]; // SGB1 - uint32_t fileSize; - uint32_t unknown1; - char magic2[4]; // SCN1 - - uint32_t unknown10; - int32_t sharedOffset; - uint32_t unknown18; - int32_t offset1C; - - uint32_t unknown20; - uint32_t unknown24; - uint32_t unknown28; - uint32_t unknown2C; - - uint32_t unknown30; - uint32_t unknown34; - uint32_t unknown38; - uint32_t unknown3C; - - uint32_t unknown40; - uint32_t unknown44; - uint32_t unknown48; - uint32_t unknown4C; - - uint32_t unknown50; - uint32_t unknown54; -}; - -struct SGB_FILE -{ - SGB_HEADER header; - std::vector< SGB_GROUP > entries; - - SGB_FILE() - { - memset( &header, 0, sizeof( header ) ); - } - - SGB_FILE( char* buf ) - { - constexpr int baseOffset = 0x14; - header = *reinterpret_cast< SGB_HEADER* >( buf ); - - if( strncmp( &header.magic[ 0 ], "SGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "SCN1", 4 ) != 0 ) - throw std::runtime_error( "Unable to load SGB File!" ); - - try - { - auto group = SGB_GROUP( buf, this, header.fileSize, baseOffset + header.sharedOffset ); - entries.push_back( group ); - auto group2 = SGB_GROUP( buf, this, header.fileSize, baseOffset + header.offset1C ); - entries.push_back( group2 ); - } - catch( std::exception& e ) - { - std::cout << e.what() << "\n"; - } - }; -}; - - -#endif // !_SGB_H diff --git a/src/tools/discovery_parser/vec3.h b/src/tools/discovery_parser/vec3.h deleted file mode 100644 index 612c9026..00000000 --- a/src/tools/discovery_parser/vec3.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef _VEC3_H -#define _VEC3_H - -#include -#include "matrix4.h" - -struct vec3 -{ - float x, y, z; - - vec3() - { - x = 0.0f; - y = 0.0f; - z = 0.0f; - } - - vec3( float x, float y, float z ) - { - this->x = x; - this->y = y; - this->z = z; - }; -}; - -static vec3 operator*( const vec3& lhs, const matrix4& rhs ) -{ - vec3 ret; - ret.x = rhs( 0, 0 ) * lhs.x + rhs( 0, 1 ) * lhs.y + rhs( 0, 2 ) * lhs.z; - ret.y = rhs( 1, 0 ) * lhs.x + rhs( 1, 1 ) * lhs.y + rhs( 1, 2 ) * lhs.z; - ret.z = rhs( 2, 0 ) * lhs.x + rhs( 2, 1 ) * lhs.y + rhs( 2, 2 ) * lhs.z; - return ret; -}; - -static vec3 operator*( const vec3& lhs, float scalar ) -{ - return { lhs.x * scalar, lhs.y * scalar, lhs.z * scalar }; -} - -static vec3 operator+( const vec3& lhs, const vec3& rhs ) -{ - return { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z }; -} - -static vec3 operator-( const vec3& lhs, const vec3& rhs ) -{ - return { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z }; -} - -static vec3 operator/( const vec3& lhs, const vec3& rhs ) -{ - return { lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z }; -} - -static vec3 operator/( const vec3& lhs, float scalar ) -{ - return { lhs.x / scalar, lhs.y / scalar, lhs.z / scalar }; -} - -#endif \ No newline at end of file From 544d6e059187511e927045c89d51ec78987f4258 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 11 Apr 2019 19:15:07 +1000 Subject: [PATCH 3/8] cleanup leftover test code that was moved to exd_struct_test --- src/tools/event_object_parser/main.cpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/tools/event_object_parser/main.cpp b/src/tools/event_object_parser/main.cpp index 04a55f4b..32e63f6f 100644 --- a/src/tools/event_object_parser/main.cpp +++ b/src/tools/event_object_parser/main.cpp @@ -369,28 +369,6 @@ int main( int argc, char* argv[] ) auto planeventFile = gameData->getFile( planeventLgbPath ); section3 = planeventFile->access_data_sections().at( 0 ); - auto exportFile = [&]( const std::string& path ) - { - try - { - auto file = gameData->getFile( path ); - - if( !file ) - { - return; - } - auto p = fs::path( path ); - fs::create_directories( p.parent_path() ); - file->exportToFile( p ); - } - catch( const std::exception& ex ) {} - }; - - exportFile( planeventLgbPath ); - exportFile( plannerFilePath ); - exportFile( lcbFilePath ); - exportFile( svbFilePath ); - std::vector< std::string > stringList; uint32_t offset1 = 0x20; From c8eaa2fa0c306cb1ad3e0791eeb84a3b3f98b21a Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 11 Apr 2019 19:19:19 +1000 Subject: [PATCH 4/8] fix offsetX & offsetY sharing a line in maprange header def --- src/common/Exd/StructureDef/lgb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/Exd/StructureDef/lgb.h b/src/common/Exd/StructureDef/lgb.h index 5b9c5c50..89105fea 100644 --- a/src/common/Exd/StructureDef/lgb.h +++ b/src/common/Exd/StructureDef/lgb.h @@ -223,7 +223,8 @@ struct LGB_MAPRANGE_HEADER : uint16_t unknown3; uint32_t unknown5; uint32_t mapId; - uint32_t offsetX, offsetY; + uint32_t offsetX; + uint32_t offsetY; uint32_t unkInts[4]; uint16_t unkShort; uint8_t unkFlag; From a84a034ac2dc140fb8ea8f9c1a40c1bddc307bb4 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 11 Apr 2019 19:28:51 +1000 Subject: [PATCH 5/8] move data struct defs to datreader lib --- .../datReader/DatCategories/bg}/lgb.h | 0 .../datReader/DatCategories/bg}/matrix4.h | 0 .../datReader/DatCategories/bg}/pcb.h | 0 .../datReader/DatCategories/bg}/sgb.h | 0 .../datReader/DatCategories/bg}/vec3.h | 0 src/tools/discovery_parser/main.cpp | 6 +++--- src/tools/event_object_parser/main.cpp | 6 +++--- src/tools/exd_struct_test/main.cpp | 8 ++++---- 8 files changed, 10 insertions(+), 10 deletions(-) rename {src/common/Exd/StructureDef => deps/datReader/DatCategories/bg}/lgb.h (100%) rename {src/common/Exd/StructureDef => deps/datReader/DatCategories/bg}/matrix4.h (100%) rename {src/common/Exd/StructureDef => deps/datReader/DatCategories/bg}/pcb.h (100%) rename {src/common/Exd/StructureDef => deps/datReader/DatCategories/bg}/sgb.h (100%) rename {src/common/Exd/StructureDef => deps/datReader/DatCategories/bg}/vec3.h (100%) diff --git a/src/common/Exd/StructureDef/lgb.h b/deps/datReader/DatCategories/bg/lgb.h similarity index 100% rename from src/common/Exd/StructureDef/lgb.h rename to deps/datReader/DatCategories/bg/lgb.h diff --git a/src/common/Exd/StructureDef/matrix4.h b/deps/datReader/DatCategories/bg/matrix4.h similarity index 100% rename from src/common/Exd/StructureDef/matrix4.h rename to deps/datReader/DatCategories/bg/matrix4.h diff --git a/src/common/Exd/StructureDef/pcb.h b/deps/datReader/DatCategories/bg/pcb.h similarity index 100% rename from src/common/Exd/StructureDef/pcb.h rename to deps/datReader/DatCategories/bg/pcb.h diff --git a/src/common/Exd/StructureDef/sgb.h b/deps/datReader/DatCategories/bg/sgb.h similarity index 100% rename from src/common/Exd/StructureDef/sgb.h rename to deps/datReader/DatCategories/bg/sgb.h diff --git a/src/common/Exd/StructureDef/vec3.h b/deps/datReader/DatCategories/bg/vec3.h similarity index 100% rename from src/common/Exd/StructureDef/vec3.h rename to deps/datReader/DatCategories/bg/vec3.h diff --git a/src/tools/discovery_parser/main.cpp b/src/tools/discovery_parser/main.cpp index 1c87ce7d..41c833b6 100644 --- a/src/tools/discovery_parser/main.cpp +++ b/src/tools/discovery_parser/main.cpp @@ -13,9 +13,9 @@ #include -#include -#include -#include +#include +#include +#include #include "tex.h" #include "tex_decode.h" diff --git a/src/tools/event_object_parser/main.cpp b/src/tools/event_object_parser/main.cpp index 32e63f6f..38bf41bf 100644 --- a/src/tools/event_object_parser/main.cpp +++ b/src/tools/event_object_parser/main.cpp @@ -11,9 +11,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/src/tools/exd_struct_test/main.cpp b/src/tools/exd_struct_test/main.cpp index 3426804d..1a524ae8 100644 --- a/src/tools/exd_struct_test/main.cpp +++ b/src/tools/exd_struct_test/main.cpp @@ -16,9 +16,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include @@ -90,7 +90,7 @@ int main( int argc, char* argv[] ) std::vector< std::string > levelNames; std::vector< std::string > paths; - + std::vector< uint32_t > lgbGroupIds; std::vector< DupeResult > lgbGroupDupes; From caf82976333bd3990cac76b1eff5d08711f8884f Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 11 Apr 2019 22:18:18 +1000 Subject: [PATCH 6/8] correctly load all lgb entries even if there's no struct for them --- deps/datReader/DatCategories/bg/lgb.h | 7 +-- src/tools/exd_struct_test/main.cpp | 86 +++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 9 deletions(-) diff --git a/deps/datReader/DatCategories/bg/lgb.h b/deps/datReader/DatCategories/bg/lgb.h index 89105fea..50097735 100644 --- a/deps/datReader/DatCategories/bg/lgb.h +++ b/deps/datReader/DatCategories/bg/lgb.h @@ -252,7 +252,7 @@ public: struct LGB_GROUP_HEADER { - uint32_t unknown; + uint32_t id; int32_t groupNameOffset; int32_t entriesOffset; int32_t entryCount; @@ -310,12 +310,11 @@ struct LGB_GROUP { entries.push_back( std::make_shared< LGB_MAPRANGE_ENTRY >( buf, entryOffset ) ); } - /* else { - entries[i] = nullptr; + entries.push_back( std::make_shared< LGB_ENTRY >( buf, entryOffset ) ); } - */ + } catch( std::exception& e ) diff --git a/src/tools/exd_struct_test/main.cpp b/src/tools/exd_struct_test/main.cpp index 1a524ae8..88ad0d46 100644 --- a/src/tools/exd_struct_test/main.cpp +++ b/src/tools/exd_struct_test/main.cpp @@ -56,6 +56,49 @@ void exportFile( const std::string& path ) } } +const std::string getTypeString( uint32_t type ) +{ + switch( type ) + { + case 1: return "BgParts"; + case 3: return "Light"; + case 4: return "Vfx"; + case 5: return "PositionMarker"; + case 6: return "Gimmick/SharedGroup6"; + case 7: return "Sound"; + case 8: return "EventNpc"; + case 9: return "BattleNpc"; + case 12: return "Aetheryte"; + case 13: return "EnvSpace"; + case 14: return "Gathering"; + case 15: return "SharedGroup15"; + case 16: return "Treasure"; + case 39: return "Weapon"; + case 40: return "PopRange"; + case 41: return "ExitRange"; + case 43: return "MapRange"; + case 44: return "NaviMeshRange"; + case 45: return "EventObject"; + case 47: return "EnvLocation"; + case 49: return "EventRange"; + case 51: return "QuestMarker"; + case 57: return "CollisionBox"; + case 58: return "DoorRange"; + case 59: return "LineVfx"; + case 65: return "ClientPath"; + case 66: return "ServerPath"; + case 67: return "GimmickRange"; + case 68: return "TargetMarker"; + case 69: return "ChairMarker"; + case 70: return "ClickableRange"; + case 71: return "PrefetchRange"; + case 72: return "FateRange"; + case 75: return "SphereCastRange"; + + default: return ""; + } +} + struct DupeResult { std::string groupName; @@ -93,6 +136,7 @@ int main( int argc, char* argv[] ) std::vector< uint32_t > lgbGroupIds; std::vector< DupeResult > lgbGroupDupes; + std::vector< uint32_t > foundTypes; paths.emplace_back( "level/bg.lgb" ); paths.emplace_back( "level/planmap.lgb" ); @@ -137,15 +181,36 @@ int main( int argc, char* argv[] ) for( const auto& group : lgb.groups ) { - Logger::info( " - {:<7} {:<25} children: {}", group.header.unknown, group.name, group.header.entryCount ); + std::vector< uint32_t > types; - if( std::find( lgbGroupIds.begin(), lgbGroupIds.end(), group.header.unknown ) == lgbGroupIds.end() ) + for( const auto& entry : group.entries ) { - lgbGroupIds.emplace_back( group.header.unknown ); + types.emplace_back( static_cast< uint32_t >( entry->getType() ) ); + } + + std::string typeStr; + + std::sort( types.begin(), types.end() ); + auto end = std::unique( types.begin(), types.end() ); + types.erase( end, types.end() ); + + foundTypes.insert( foundTypes.end(), types.begin(), types.end() ); + + for( auto type : types ) + { + typeStr.append( " " + std::to_string( type ) ); + } + + Logger::info( " - {:<7} {:<25} groups: {:<3} types:{}", + group.header.id, group.name, group.header.entryCount, typeStr ); + + if( std::find( lgbGroupIds.begin(), lgbGroupIds.end(), group.header.id ) == lgbGroupIds.end() ) + { + lgbGroupIds.emplace_back( group.header.id ); } else { - lgbGroupDupes.push_back( { group.name, filePath, group.header.unknown } ); + lgbGroupDupes.push_back( { group.name, filePath, group.header.id } ); } } Logger::info( "" ); @@ -163,9 +228,20 @@ int main( int argc, char* argv[] ) for( const auto& result : lgbGroupDupes ) { - Logger::info( " - file: {:<50} group: {:<30} id: {}", result.lgb, result.groupName, result.id ); + Logger::info( " - id: {:<7} group: {:<30} file: {} ", result.id, result.groupName, result.lgb ); } } + Logger::info( "Found LGB entry types:" ); + + std::sort( foundTypes.begin(), foundTypes.end() ); + auto end = std::unique( foundTypes.begin(), foundTypes.end() ); + foundTypes.erase( end, foundTypes.end() ); + + for( auto type : foundTypes ) + { + Logger::info( " - {:<3} {}", type, getTypeString( type ) ); + } + return 0; } From f4a56cf636603984340ab9456beb406226c6ca51 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 13 Apr 2019 01:24:19 +1000 Subject: [PATCH 7/8] add questbattle script bruteforcer & decompiler --- src/tools/CMakeLists.txt | 1 + .../questbattle_bruteforce/CMakeLists.txt | 15 ++ src/tools/questbattle_bruteforce/main.cpp | 139 ++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 src/tools/questbattle_bruteforce/CMakeLists.txt create mode 100644 src/tools/questbattle_bruteforce/main.cpp diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 01f78aad..027cdb8d 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -26,3 +26,4 @@ add_subdirectory( "pcb_reader" ) add_subdirectory( "nav_export" ) add_subdirectory( "event_object_parser" ) add_subdirectory( "action_parse" ) +add_subdirectory( "questbattle_bruteforce" ) \ No newline at end of file diff --git a/src/tools/questbattle_bruteforce/CMakeLists.txt b/src/tools/questbattle_bruteforce/CMakeLists.txt new file mode 100644 index 00000000..9c974d15 --- /dev/null +++ b/src/tools/questbattle_bruteforce/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.6) +cmake_policy(SET CMP0015 NEW) +project(Tool_QuestBattle_BruteForce) + +file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*") +file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*") + +add_executable(questbattle_bruteforce ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES}) + +if (UNIX) + target_link_libraries (questbattle_bruteforce common xivdat pthread mysqlclient dl z stdc++fs ) +else() + target_link_libraries (questbattle_bruteforce common xivdat mysql zlib) +endif() + diff --git a/src/tools/questbattle_bruteforce/main.cpp b/src/tools/questbattle_bruteforce/main.cpp new file mode 100644 index 00000000..50df0b6d --- /dev/null +++ b/src/tools/questbattle_bruteforce/main.cpp @@ -0,0 +1,139 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +Sapphire::Common::Util::CrashHandler crashHandler; + +Sapphire::Data::ExdDataGenerated g_exdData; +xiv::dat::GameData* gameData = nullptr; + +using namespace Sapphire; + +namespace fs = std::experimental::filesystem; + +//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" ); +const std::string datLocation( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" ); + +void exportFile( const std::string& path ) +{ + try + { + auto file = gameData->getFile( path ); + + if( !file ) + { + return; + } + auto p = fs::path( path ); + fs::create_directories( p.parent_path() ); + file->exportToFile( p ); + } + catch( const std::exception& ex ) + { + Logger::error( "Failed to export file {0}, error: {1}", path, ex.what() ); + } +} + +bool replace(std::string& str, const std::string& from, const std::string& to) { + size_t start_pos = str.find(from); + if(start_pos == std::string::npos) + return false; + str.replace(start_pos, from.length(), to); + return true; +} + +int main( int argc, char* argv[] ) +{ + + Logger::init( "questbattle_bruteforce" ); + + Logger::info( "Setting up EXD data" ); + if( !g_exdData.init( datLocation ) ) + { + Logger::fatal( "Error setting up EXD data " ); + return 0; + } + + fs::create_directory( "questbattle_scripts" ); + + std::vector< std::string > luabFiles; + + gameData = new xiv::dat::GameData( datLocation ); + + auto questExdIds = g_exdData.getQuestIdList(); + + for( auto id : questExdIds ) + { + auto quest = g_exdData.get< Data::Quest >( id ); + + if( !quest ) + continue; + + auto idString = quest->id; + + if( idString.empty() ) + continue; + + // galaxy brain shit right here + auto folderId = fmt::format( "{:06d}", id & 0xFFFF ).substr( 1, 3 ); + + replace( idString, "_", "Btl_" ); + + auto path = fmt::format( "game_script/quest/{}/{}.luab", folderId, idString ); + + try + { + auto file = gameData->getFile( path ); + + if( !file ) + { + continue; + } + + auto filename = fmt::format( "questbattle_scripts/{}.luab", idString ); + + luabFiles.emplace_back( filename ); + file->exportToFile( filename ); + + Logger::info( "Exported file: {}", filename ); + } + catch( const std::exception& ex ) + { + + } + } + + Logger::info( "Decompiling luab scripts, pls wait..." ); + + int i = 0; + + for( auto& filename : luabFiles ) + { + filename.pop_back(); + + system( fmt::format( "java -jar unluac_2015_06_13.jar {}b > {}", filename, filename ).c_str() ); + + Logger::info( "Decompiling luab files - {} of {}", ++i, luabFiles.size() ); + } + + + return 0; +} From 35a7db9f540eea9abc45c592aa5ed02ffd920448 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 13 Apr 2019 01:25:53 +1000 Subject: [PATCH 8/8] fix style --- src/tools/questbattle_bruteforce/main.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tools/questbattle_bruteforce/main.cpp b/src/tools/questbattle_bruteforce/main.cpp index 50df0b6d..66b38d5e 100644 --- a/src/tools/questbattle_bruteforce/main.cpp +++ b/src/tools/questbattle_bruteforce/main.cpp @@ -52,11 +52,15 @@ void exportFile( const std::string& path ) } } -bool replace(std::string& str, const std::string& from, const std::string& to) { - size_t start_pos = str.find(from); - if(start_pos == std::string::npos) +bool replace( std::string& str, const std::string& from, const std::string& to ) +{ + size_t start_pos = str.find( from ); + + if( start_pos == std::string::npos ) return false; - str.replace(start_pos, from.length(), to); + + str.replace( start_pos, from.length(), to ); + return true; }