1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-26 22:37:45 +00:00

Added variant identification to exds and fixed exd_struct_gen with adam

This commit is contained in:
mordred 2018-11-23 15:02:42 +01:00
parent 8456be8e7e
commit f6a5ad812a
5 changed files with 4031 additions and 152 deletions

View file

@ -81,6 +81,90 @@ namespace xiv
{ {
} }
const std::vector<Field> Exd::get_row( uint32_t id, uint32_t subRow )
{
auto cacheEntryIt = _idCache.find( id );
if( cacheEntryIt == _idCache.end() )
throw std::runtime_error( "Id not found: " + std::to_string( id ) );
// Iterates over all the files
const uint32_t member_count = _exh->get_members().size();
auto& file_ptr = cacheEntryIt->second.file;
std::vector< char > dataCpy = file_ptr->get_data_sections().front();
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
// Get the vector fields for the given record and preallocate it
auto fields = _data[id];
fields.reserve( member_count );
iss.seekg( cacheEntryIt->second.offset + 6 );
uint8_t subRows = *reinterpret_cast< uint8_t* >( &dataCpy[ cacheEntryIt->second.offset + 5 ] );
for( auto& member_entry : _exh->get_exh_members() )
{
// Seek to the position of the member to extract.
// 6 is because we have uint32_t/uint16_t at the start of each record
iss.seekg( cacheEntryIt->second.offset + 6 + member_entry.offset );
// Switch depending on the type to extract
switch( member_entry.type )
{
case DataType::string:
// Extract the offset to the actual string
// Seek to it then extract the actual string
{
auto string_offset = extract<uint32_t>( iss, "string_offset", false );
iss.seekg( cacheEntryIt->second.offset + 6 + _exh->get_header().data_offset + string_offset );
fields.emplace_back( utils::bparse::extract_cstring( iss, "string" ) );
}
break;
case DataType::boolean:
fields.emplace_back( extract<bool>( iss, "bool" ) );
break;
case DataType::int8:
fields.emplace_back( extract<int8_t>( iss, "int8_t" ) );
break;
case DataType::int16:
fields.emplace_back( extract<int16_t>( iss, "int16_t", false ) );
break;
case DataType::int32:
fields.emplace_back( extract<int32_t>( iss, "int32_t", false ) );
break;
case DataType::uint32:
fields.emplace_back( extract<uint32_t>( iss, "uint32_t", false ) );
break;
case DataType::float32:
fields.emplace_back( extract<float>( iss, "float", false ) );
break;
case DataType::uint64:
fields.emplace_back( extract<uint64_t>( iss, "uint64_t", false ) );
break;
default:
auto type = static_cast< uint16_t >( member_entry.type );
if( type < 0x19 || type > 0x20 )
throw std::runtime_error("Unknown DataType: " + std::to_string( type ));
uint64_t val = extract< uint64_t >( iss, "bool" );
int32_t shift = type - 0x19;
int32_t i = 1 << shift;
val &= i;
fields.emplace_back( ( val & i ) == i );
break;
}
}
return fields;
}
const std::vector<Field> Exd::get_row( uint32_t id ) const std::vector<Field> Exd::get_row( uint32_t id )
{ {
@ -98,6 +182,9 @@ namespace xiv
// Get the vector fields for the given record and preallocate it // Get the vector fields for the given record and preallocate it
auto fields = _data[id]; auto fields = _data[id];
fields.reserve( member_count ); fields.reserve( member_count );
iss.seekg( cacheEntryIt->second.offset + 6 );
uint8_t subRows = *reinterpret_cast< uint8_t* >( &dataCpy[ cacheEntryIt->second.offset + 5 ] );
for( auto& member_entry : _exh->get_exh_members() ) for( auto& member_entry : _exh->get_exh_members() )
{ {

View file

@ -47,6 +47,8 @@ public:
// Get a row by its id // Get a row by its id
const std::vector<Field> get_row(uint32_t id); const std::vector<Field> get_row(uint32_t id);
// Get a row by its id and sub-row
const std::vector<Field> get_row(uint32_t id, uint32_t subRow);
// Get all rows // Get all rows
const std::map<uint32_t, std::vector<Field>>& get_rows(); const std::map<uint32_t, std::vector<Field>>& get_rows();

View file

@ -31,6 +31,9 @@ namespace xiv
uint16_t field_count; uint16_t field_count;
uint16_t exd_count; uint16_t exd_count;
uint16_t language_count; uint16_t language_count;
uint16_t unknown1;
uint8_t u2;
uint8_t variant;
}; };
struct ExhMember struct ExhMember

File diff suppressed because it is too large Load diff

View file

@ -45,8 +45,8 @@ std::vector< std::string > cppKeyWords
"class" "class"
}; };
//std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" ); std::string datLocation( "/home/mordred/sqpack" );
std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" ); //std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
std::map< uint8_t, std::string > g_typeMap; std::map< uint8_t, std::string > g_typeMap;
@ -117,29 +117,57 @@ std::string generateStruct( const std::string& exd )
std::ifstream exJson( "ex.json" ); std::ifstream exJson( "ex.json" );
exJson >> json; exJson >> json;
for( auto& definition : json["sheets"][exd] ) for( auto& sheet : json[ "sheets" ] )
{ {
uint32_t index; if( sheet[ "sheet" ] != exd )
std::string converterTarget = ""; continue;
bool isRepeat = false;
int num = 0; for( auto& definition : sheet[ "definitions" ] )
index = definition["index"].get< uint32_t >();
indexToNameMap[ index ] = std::string( definition["name"] );
converterTarget = std::string( definition["converter"]["target"] );
if( nameTaken.find( converterTarget ) != nameTaken.end() )
indexToTarget[ index ] = converterTarget;
if( auto count = definition["count"] )
{ {
num = std::stoi( std::string( count ) ); uint32_t index;
isRepeat = true; std::string converterTarget = "";
indexIsArrayMap[ index ] = true; bool isRepeat = false;
indexCountMap[ index ] = num; int num = 0;
try
{
index = definition.at( "index" );
}
catch( ... )
{
index = 0;
}
try
{
std::string fieldName = std::string( definition.at( "name" ) );
indexToNameMap[ index ] = fieldName;
}
catch( ... )
{
}
std::string fName = definition["definition"]["name"]; try
indexToNameMap[ index ] = fName; {
converterTarget = std::string( definition.at( "converter" ).at( "target" ) );
if( nameTaken.find( converterTarget ) != nameTaken.end() )
indexToTarget[ index ] = converterTarget;
}
catch( ... )
{
}
try
{
num = definition.at( "count" );
isRepeat = true;
indexIsArrayMap[ index ] = true;
indexCountMap[ index ] = num;
std::string fName = definition.at( "definition" ).at( "name" );
indexToNameMap[ index ] = fName;
}
catch( ... )
{
}
} }
@ -213,7 +241,15 @@ std::string generateStruct( const std::string& exd )
count++; count++;
} }
result += "\n " + exd + "( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );\n"; auto exhHead = exh.get_header();
if( exhHead.variant == 2 )
{
result += "\n " + exd + "( uint32_t row_id, uint32_t subRow, Core::Data::ExdDataGenerated* exdData );\n";
}
else
{
result += "\n " + exd + "( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );\n";
}
result += "};\n\n"; result += "};\n\n";
return result; return result;
@ -229,11 +265,20 @@ std::string generateConstructorsDecl( const std::string& exd )
int count = 0; int count = 0;
result += "\nCore::Data::" + exd + "::" + exd + "( uint32_t row_id, Core::Data::ExdDataGenerated* exdData )\n";
result += "{\n";
std::string indent = " "; std::string indent = " ";
result += indent + "auto row = exdData->m_" + exd + "Dat.get_row( row_id );\n"; auto exhHead = exh.get_header();
if( exhHead.variant == 2 )
{
result += "\nCore::Data::" + exd + "::" + exd + "( uint32_t row_id, uint32_t subRow, Core::Data::ExdDataGenerated* exdData )\n";
result += "{\n";
result += indent + "auto row = exdData->m_" + exd + "Dat.get_row( row_id, subRow );\n";
}
else
{
result += "\nCore::Data::" + exd + "::" + exd + "( uint32_t row_id, Core::Data::ExdDataGenerated* exdData )\n";
result += "{\n";
result += indent + "auto row = exdData->m_" + exd + "Dat.get_row( row_id );\n";
}
for( auto member : exhMem ) for( auto member : exhMem )
{ {
if( indexToNameMap.find( count ) == indexToNameMap.end() ) if( indexToNameMap.find( count ) == indexToNameMap.end() )
@ -333,22 +378,20 @@ int main( int argc, char** argv )
//BOOST_FOREACH( boost::property_tree::ptree::value_type &sheet, m_propTree.get_child( "sheets" ) ) //BOOST_FOREACH( boost::property_tree::ptree::value_type &sheet, m_propTree.get_child( "sheets" ) )
//{ //{
//std::string name = sheet.second.get< std::string >( "sheet" );
//nameTaken[name] = "1"; //nameTaken[name] = "1";
//} //}
//
for( auto& sheet : json["sheets"] ) for( auto& sheet : json[ "sheets" ] )
{ {
std::string name = json["sheet"]; std::string name = sheet[ "sheet" ];
forwards += "struct " + name + ";\n";
forwards += "struct " + name + ";\n"; structDefs += generateStruct( name );
structDefs += generateStruct( name ); dataDecl += generateDatAccessDecl( name );
dataDecl += generateDatAccessDecl( name ); idListsDecl += generateIdListDecl( name );
idListsDecl += generateIdListDecl( name ); getterDecl += generateDirectGetters( name );
getterDecl += generateDirectGetters( name ); datAccCall += generateSetDatAccessCall( name );
datAccCall += generateSetDatAccessCall( name ); constructorDecl += generateConstructorsDecl( name );
constructorDecl += generateConstructorsDecl( name ); idListGetters += generateIdListGetter( name );
idListGetters += generateIdListGetter( name );
} }
getterDecl += getterDecl +=