1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-26 14:37:44 +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 )
{
@ -98,6 +182,9 @@ namespace xiv
// 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() )
{

View file

@ -47,6 +47,8 @@ public:
// Get a row by its 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
const std::map<uint32_t, std::vector<Field>>& get_rows();

View file

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

File diff suppressed because it is too large Load diff

View file

@ -45,8 +45,8 @@ std::vector< std::string > cppKeyWords
"class"
};
//std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
std::string datLocation( "/home/mordred/sqpack" );
//std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
std::map< uint8_t, std::string > g_typeMap;
@ -117,29 +117,57 @@ std::string generateStruct( const std::string& exd )
std::ifstream exJson( "ex.json" );
exJson >> json;
for( auto& definition : json["sheets"][exd] )
for( auto& sheet : json[ "sheets" ] )
{
uint32_t index;
std::string converterTarget = "";
bool isRepeat = false;
int num = 0;
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"] )
if( sheet[ "sheet" ] != exd )
continue;
for( auto& definition : sheet[ "definitions" ] )
{
num = std::stoi( std::string( count ) );
isRepeat = true;
indexIsArrayMap[ index ] = true;
indexCountMap[ index ] = num;
uint32_t index;
std::string converterTarget = "";
bool isRepeat = false;
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"];
indexToNameMap[ index ] = fName;
try
{
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++;
}
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";
return result;
@ -229,11 +265,20 @@ std::string generateConstructorsDecl( const std::string& exd )
int count = 0;
result += "\nCore::Data::" + exd + "::" + exd + "( uint32_t row_id, Core::Data::ExdDataGenerated* exdData )\n";
result += "{\n";
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 )
{
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" ) )
//{
//std::string name = sheet.second.get< std::string >( "sheet" );
//nameTaken[name] = "1";
//}
for( auto& sheet : json["sheets"] )
{
std::string name = json["sheet"];
forwards += "struct " + name + ";\n";
structDefs += generateStruct( name );
dataDecl += generateDatAccessDecl( name );
idListsDecl += generateIdListDecl( name );
getterDecl += generateDirectGetters( name );
datAccCall += generateSetDatAccessCall( name );
constructorDecl += generateConstructorsDecl( name );
idListGetters += generateIdListGetter( name );
//
for( auto& sheet : json[ "sheets" ] )
{
std::string name = sheet[ "sheet" ];
forwards += "struct " + name + ";\n";
structDefs += generateStruct( name );
dataDecl += generateDatAccessDecl( name );
idListsDecl += generateIdListDecl( name );
getterDecl += generateDirectGetters( name );
datAccCall += generateSetDatAccessCall( name );
constructorDecl += generateConstructorsDecl( name );
idListGetters += generateIdListGetter( name );
}
getterDecl +=