1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-23 10:17:44 +00:00

Fixed exd slowness

This commit is contained in:
AriAvery 2023-04-23 15:30:18 +02:00
parent a65b23778b
commit 137a75d5a5
9 changed files with 247 additions and 352 deletions

View file

@ -1,44 +1,37 @@
#include "DatCat.h" #include "DatCat.h"
#include "Index.h"
#include "Dat.h" #include "Dat.h"
#include "File.h" #include "File.h"
#include "GameData.h" #include "GameData.h"
#include "Index.h"
namespace xiv namespace xiv
{ {
namespace dat namespace dat
{ {
Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name ) : Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name ) : m_name( name ),
m_name( name ),
m_catNum( catNum ), m_catNum( catNum ),
m_chunk( -1 ) m_chunk( -1 )
{ {
// From the category number, compute back the real filename for.index .datXs
std::stringstream ss; std::stringstream ss;
ss << std::setw( 2 ) << std::setfill( '0' ) << std::hex << catNum; ss << std::setw( 2 ) << std::setfill( '0' ) << std::hex << catNum;
std::string prefix = ss.str() + "0000.win32"; std::string prefix = ss.str() + "0000.win32";
// Creates the index: XX0000.win32.index m_index = std::make_unique< Index >( basePath / "ffxiv" / ( prefix + ".index" ) );
m_index = std::unique_ptr<Index>( new Index( basePath / "ffxiv" / ( prefix + ".index" ) ) );
// For all dat files linked to this index, create it: XX0000.win32.datX
for( uint32_t i = 0; i < getIndex().getDatCount(); ++i ) for( uint32_t i = 0; i < getIndex().getDatCount(); ++i )
{ {
m_dats.emplace_back( std::make_unique< Dat >( basePath / "ffxiv" / ( prefix + ".dat" + std::to_string( i ) ), i ) ); m_dats.emplace_back( std::make_unique< Dat >( basePath / "ffxiv" / ( prefix + ".dat" + std::to_string( i ) ), i ) );
} }
} }
Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name, uint32_t exNum, uint32_t chunk ) : Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name, uint32_t exNum, uint32_t chunk ) : m_name( name ),
m_name( name ),
m_catNum( catNum ), m_catNum( catNum ),
m_chunk( chunk ) m_chunk( chunk )
{ {
// Creates the index: XX0000.win32.index
m_index = std::make_unique< Index >( basePath / GameData::buildDatStr( "ex" + std::to_string( exNum ), catNum, exNum, chunk, "win32", "index" ) ); m_index = std::make_unique< Index >( basePath / GameData::buildDatStr( "ex" + std::to_string( exNum ), catNum, exNum, chunk, "win32", "index" ) );
// For all dat files linked to this index, create it: XX0000.win32.datX
for( uint32_t i = 0; i < getIndex().getDatCount(); ++i ) for( uint32_t i = 0; i < getIndex().getDatCount(); ++i )
{ {
m_dats.emplace_back( std::make_unique< Dat >( basePath / GameData::buildDatStr( "ex" + std::to_string( exNum ), catNum, exNum, chunk, "win32", "dat" + std::to_string( i ) ), i ) ); m_dats.emplace_back( std::make_unique< Dat >( basePath / GameData::buildDatStr( "ex" + std::to_string( exNum ), catNum, exNum, chunk, "win32", "dat" + std::to_string( i ) ), i ) );
@ -47,7 +40,6 @@ Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::str
Cat::~Cat() Cat::~Cat()
{ {
} }
const Index& Cat::getIndex() const const Index& Cat::getIndex() const
@ -57,7 +49,6 @@ const Index& Cat::getIndex() const
std::unique_ptr< File > Cat::getFile( uint32_t dir_hash, uint32_t filename_hash ) const std::unique_ptr< File > Cat::getFile( uint32_t dir_hash, uint32_t filename_hash ) const
{ {
// Fetch the correct hash_table_entry for these hashes, from that request the file from the right dat file
auto& hash_table_entry = getIndex().getHashTableEntry( dir_hash, filename_hash ); auto& hash_table_entry = getIndex().getHashTableEntry( dir_hash, filename_hash );
return m_dats[ hash_table_entry.datNum ]->getFile( hash_table_entry.datOffset ); return m_dats[ hash_table_entry.datNum ]->getFile( hash_table_entry.datOffset );
} }
@ -82,5 +73,5 @@ uint32_t Cat::getCatNum() const
return m_catNum; return m_catNum;
} }
} }// namespace dat
} }// namespace xiv

View file

@ -1,9 +1,8 @@
#ifndef XIV_DAT_CAT_H #pragma once
#define XIV_DAT_CAT_H
#include <filesystem>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <filesystem>
namespace xiv::dat namespace xiv::dat
{ {
@ -65,4 +64,3 @@ namespace xiv::dat
} }
#endif // XIV_DAT_CAT_H

View file

@ -1,4 +1,5 @@
#include "conv.h" #include "conv.h"
#include <cstring>// for memcpy
namespace xiv::utils::conv namespace xiv::utils::conv
{ {
@ -21,7 +22,9 @@ namespace xiv::utils::conv
t1 |= t2; // Re-insert sign bit t1 |= t2; // Re-insert sign bit
return *reinterpret_cast< float* >( &t1 ); float result;
memcpy( &result, &t1, sizeof( float ) );// Convert uint32_t to float using memcpy
return result;
} }
float ubyte2float( const uint8_t i_value ) float ubyte2float( const uint8_t i_value )

View file

@ -1,79 +1,52 @@
#include "crc32.h" #include "crc32.h"
#include <mutex> #include <array>
#include <vector> #include <string>
#include <zlib/zlib.h> #include <zlib/zlib.h>
namespace internal namespace internal
{ {
// Mutex to prevent two threads from concurrently trying to build the crc tables atthe same time using CrcTable = std::array< uint32_t, 0x100 >;
std::mutex crc_creation_mutex;
typedef std::vector<uint32_t> CrcTable; constexpr CrcTable build_crc_table()
// Our crc/rev_crc tables
CrcTable crc_table;
CrcTable rev_crc_table;
bool crc_tables_created = false;
void build_crc_tables()
{ {
std::lock_guard<std::mutex> lock(crc_creation_mutex); CrcTable crc_table{};
if (!crc_tables_created) for( size_t i = 0; i < 0x100; ++i )
{
crc_table.resize(0x100);
rev_crc_table.resize(0x100);
for (auto i = 0; i < 0x100; ++i)
{ {
uint32_t crc = i; uint32_t crc = i;
for (auto j = 0; j < 8; ++j) for( size_t j = 0; j < 8; ++j )
{ {
if (crc & 1) crc = ( crc & 1 ) ? ( 0xEDB88320 ^ ( crc >> 1 ) ) : ( crc >> 1 );
{
crc = 0xEDB88320 ^ (crc >> 1);
}
else
{
crc = crc >> 1;
}
} }
crc_table[ i ] = crc; crc_table[ i ] = crc;
rev_crc_table[crc >> 24] = i + ((crc & 0xFFFFFF) << 8);
}
}
crc_tables_created = true;
}
const CrcTable& get_crc_table()
{
if (!crc_tables_created)
{
build_crc_tables();
} }
return crc_table; return crc_table;
} }
const CrcTable& get_rev_crc_table() constexpr CrcTable build_rev_crc_table()
{ {
if (!crc_tables_created) CrcTable rev_crc_table{};
auto crc_table = build_crc_table();
for( size_t i = 0; i < 0x100; ++i )
{ {
build_crc_tables(); uint32_t crc = crc_table[ i ];
rev_crc_table[ crc >> 24 ] = i + ( ( crc & 0xFFFFFF ) << 8 );
} }
return rev_crc_table; return rev_crc_table;
} }
}
constexpr CrcTable crc_table = build_crc_table();
constexpr CrcTable rev_crc_table = build_rev_crc_table();
}// namespace internal
namespace xiv::utils::crc32 namespace xiv::utils::crc32
{ {
uint32_t compute( const std::string& i_input, uint32_t init_crc ) uint32_t compute( const std::string& i_input, uint32_t init_crc )
{ {
// Classical crc stuff auto& crc_table = internal::crc_table;
auto& crc_table = internal::get_crc_table(); uint32_t crc = init_crc;
auto crc = init_crc; for( size_t i = 0; i < i_input.size(); ++i )
for( std::size_t i = 0; i < i_input.size(); ++i )
{ {
crc = crc_table[ ( crc ^ i_input[ i ] ) & 0xFF ] ^ ( crc >> 8 ); crc = crc_table[ ( crc ^ i_input[ i ] ) & 0xFF ] ^ ( crc >> 8 );
} }
@ -82,43 +55,38 @@ namespace xiv::utils::crc32
uint32_t rev_compute( const std::string& i_input, uint32_t init_crc ) uint32_t rev_compute( const std::string& i_input, uint32_t init_crc )
{ {
auto& rev_crc_table = internal::get_rev_crc_table(); auto& rev_crc_table = internal::rev_crc_table;
auto crc = init_crc; uint32_t crc = init_crc;
const auto input_size = i_input.size(); const auto input_size = i_input.size();
// Reverse crc for( size_t i = input_size; i > 0; --i )
for( auto i = input_size; i > 0; --i )
{ {
crc = rev_crc_table[ crc >> 24 ] ^ ( ( crc << 8 ) & 0xFFFFFF00 ) ^ i_input[ input_size - i - 1 ]; crc = rev_crc_table[ crc >> 24 ] ^ ( ( crc << 8 ) & 0xFFFFFF00 ) ^ i_input[ input_size - i - 1 ];
} }
// Compute the 4 bytes needed for this init_crc for( size_t i = 0; i < 4; ++i )
for( auto i = 0; i < 4; ++i )
{ {
crc = rev_crc_table[ crc >> 24 ] ^ ( ( crc << 8 ) & 0xFFFFFF00 ); crc = rev_crc_table[ crc >> 24 ] ^ ( ( crc << 8 ) & 0xFFFFFF00 );
} }
return crc; return crc;
} }
void generate_hashes_1( std::string& i_format, const uint32_t i_first_index, std::vector< uint32_t >& o_hashes ) void generate_hashes_1( std::string& i_format, const uint32_t i_first_index, std::array< uint32_t, 10000 >& o_hashes )
{ {
char* str = const_cast<char*>(i_format.data());
const auto str_size = static_cast< uInt >( i_format.size() ); const auto str_size = static_cast< uInt >( i_format.size() );
o_hashes.resize( 10000 );
uint32_t i = 0; uint32_t i = 0;
for( char a = '0'; a <= '9'; ++a ) for( char a = '0'; a <= '9'; ++a )
{ {
str[ i_first_index ] = a; i_format[ i_first_index ] = a;
for( char b = '0'; b <= '9'; ++b ) for( char b = '0'; b <= '9'; ++b )
{ {
str[ i_first_index + 1 ] = b; i_format[ i_first_index + 1 ] = b;
for( char c = '0'; c <= '9'; ++c ) for( char c = '0'; c <= '9'; ++c )
{ {
str[ i_first_index + 2 ] = c; i_format[ i_first_index + 2 ] = c;
for( char d = '0'; d <= '9'; ++d ) for( char d = '0'; d <= '9'; ++d )
{ {
str[ i_first_index + 3 ] = d; i_format[ i_first_index + 3 ] = d;
o_hashes[ i ] = ::crc32( 0, reinterpret_cast<uint8_t*>(&( str[ 0 ] )), str_size ) ^ 0xFFFFFFFF; o_hashes[ i ] = ::crc32( 0, reinterpret_cast< const Bytef* >( i_format.data() ), str_size ) ^ 0xFFFFFFFF;
++i; ++i;
} }
} }
@ -127,39 +95,36 @@ namespace xiv::utils::crc32
} }
void generate_hashes_2( std::string& i_format, const uint32_t i_first_index, const uint32_t i_second_index, void generate_hashes_2( std::string& i_format, const uint32_t i_first_index, const uint32_t i_second_index,
std::vector< uint32_t >& o_hashes ) std::array< uint32_t, 100000000 >& o_hashes )
{ {
char* str = const_cast<char*>(i_format.data());
const auto str_size = static_cast< uInt >( i_format.size() ); const auto str_size = static_cast< uInt >( i_format.size() );
o_hashes.resize( 100000000 );
uint32_t i = 0; uint32_t i = 0;
for( char a = '0'; a <= '9'; ++a ) for( char a = '0'; a <= '9'; ++a )
{ {
str[ i_first_index ] = a; i_format[ i_first_index ] = a;
for( char b = '0'; b <= '9'; ++b ) for( char b = '0'; b <= '9'; ++b )
{ {
str[ i_first_index + 1 ] = b; i_format[ i_first_index + 1 ] = b;
for( char c = '0'; c <= '9'; ++c ) for( char c = '0'; c <= '9'; ++c )
{ {
str[ i_first_index + 2 ] = c; i_format[ i_first_index + 2 ] = c;
for( char d = '0'; d <= '9'; ++d ) for( char d = '0'; d <= '9'; ++d )
{ {
str[ i_first_index + 3 ] = d; i_format[ i_first_index + 3 ] = d;
for( char e = '0'; e <= '9'; ++e ) for( char e = '0'; e <= '9'; ++e )
{ {
str[ i_second_index ] = e; i_format[ i_second_index ] = e;
for( char f = '0'; f <= '9'; ++f ) for( char f = '0'; f <= '9'; ++f )
{ {
str[ i_second_index + 1 ] = f; i_format[ i_second_index + 1 ] = f;
for( char g = '0'; g <= '9'; ++g ) for( char g = '0'; g <= '9'; ++g )
{ {
str[ i_second_index + 2 ] = g; i_format[ i_second_index + 2 ] = g;
for( char h = '0'; h <= '9'; ++h ) for( char h = '0'; h <= '9'; ++h )
{ {
str[ i_second_index + 3 ] = h; i_format[ i_second_index + 3 ] = h;
o_hashes[ i ] = ::crc32( 0, reinterpret_cast<uint8_t*>(&( str[ 0 ] )), str_size ) ^ 0xFFFFFFFF; o_hashes[ i ] = ::crc32( 0, reinterpret_cast< const Bytef* >( i_format.data() ), str_size ) ^ 0xFFFFFFFF;
++i; ++i;
} }
} }
@ -171,5 +136,4 @@ namespace xiv::utils::crc32
} }
} }
}// namespace xiv::utils::crc32
}

View file

@ -1,8 +1,8 @@
#include "zlib.h" #include "zlib.h"
#include <string>
#include <stdexcept> #include <stdexcept>
#include <zlib/zlib.h> #include <string>
#include <vector> #include <vector>
#include <zlib/zlib.h>
namespace xiv::utils::zlib namespace xiv::utils::zlib
{ {
@ -18,13 +18,13 @@ namespace xiv::utils::zlib
if( ret != Z_OK ) if( ret != Z_OK )
{ {
throw std::runtime_error( "Error at zlib uncompress: " + std::to_string( ret ) ); throw std::runtime_error( "Error at zlib compress: " + std::to_string( ret ) );
} }
out.resize( out_size ); out.resize( out_size );
} }
void no_header_decompress( uint8_t* in, size_t in_size, uint8_t* out, size_t out_size ) void no_header_decompress( const uint8_t* in, size_t in_size, uint8_t* out, size_t out_size )
{ {
z_stream strm; z_stream strm;
strm.zalloc = Z_NULL; strm.zalloc = Z_NULL;
@ -41,7 +41,7 @@ namespace xiv::utils::zlib
} }
// Set pointers to the right addresses // Set pointers to the right addresses
strm.next_in = in; strm.next_in = const_cast< uint8_t* >( in );
strm.avail_out = static_cast< uInt >( out_size ); strm.avail_out = static_cast< uInt >( out_size );
strm.next_out = out; strm.next_out = out;
@ -56,4 +56,4 @@ namespace xiv::utils::zlib
inflateEnd( &strm ); inflateEnd( &strm );
} }
} }// namespace xiv::utils::zlib

View file

@ -10,7 +10,7 @@ namespace xiv::utils::zlib
void compress( const std::vector< char >& in, std::vector< char >& out ); void compress( const std::vector< char >& in, std::vector< char >& out );
void no_header_decompress( uint8_t* in, size_t in_size, uint8_t* out, size_t out_size ); void no_header_decompress( const uint8_t* in, size_t in_size, uint8_t* out, size_t out_size );
} }

View file

@ -1,162 +1,117 @@
#pragma once #pragma once
#include <unordered_map> #include <cstdint>
#include <string>
#include <memory> #include <memory>
#include <vector> #include <string>
#include <stdint.h>
#include <typeindex> #include <typeindex>
#include <unordered_map>
#include <vector>
#if !_WIN32 #if !_WIN32
#include <cxxabi.h> #include <cxxabi.h>
#endif #endif
#include <datReader/GameData.h>
#include <File.h>
#include <ExdData.h>
#include <ExdCat.h>
#include <Exd.h> #include <Exd.h>
#include <ExdCat.h>
#include <ExdData.h>
#include <File.h>
#include <Logging/Logger.h> #include <Logging/Logger.h>
#include <datReader/GameData.h>
namespace Sapphire::Data namespace Sapphire::Data
{ {
class ExdData class ExdData
{ {
public: public:
bool init( const std::string& path ); bool init( const std::string& path );
template< typename T > template< typename T >
std::shared_ptr< Excel::ExcelStruct< T > > getRow( uint32_t row, uint32_t subrow = 0 ) std::shared_ptr< Excel::ExcelStruct< T > > getRow( uint32_t row, uint32_t subrow = 0 );
{
xiv::exd::Exd sheet;
auto needle = m_sheets.find( typeid( T ) );
if( needle == m_sheets.end() )
{
auto sheetName = getSheetName< T >();
// load sheet
auto& cat = m_exd_data->get_category( sheetName );
m_sheets[ typeid( T ) ] = sheet = static_cast< xiv::exd::Exd >( cat.get_data( xiv::exd::Language::en ) );
}
else
{
sheet = needle->second;
}
try
{
return sheet.get_row< T >( row );
}
catch( const std::runtime_error& ex )
{
Logger::error( "Error fetching row from sheet {}: {}", getSheetName< T >(), ex.what() );
return nullptr;
}
catch( const std::out_of_range& )
{
return nullptr;
}
}
template< typename T > template< typename T >
std::vector< uint32_t > getIdList() std::vector< uint32_t > getIdList();
{
xiv::exd::Exd sheet;
auto needle = m_sheets.find( typeid( T ) );
if( needle == m_sheets.end() )
{
auto sheetName = getSheetName< T >();
// load sheet
auto& cat = m_exd_data->get_category( sheetName );
m_sheets[ typeid( T ) ] = sheet = static_cast< xiv::exd::Exd >( cat.get_data( xiv::exd::Language::en ) );
}
else
{
sheet = needle->second;
}
auto rows = sheet.get_rows();
std::vector< uint32_t > ids;
for( const auto& row : rows )
{
ids.push_back( row.first );
}
return ids;
}
template< typename T > template< typename T >
std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > getRows() std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > getRows();
{
xiv::exd::Exd sheet;
auto needle = m_sheets.find( typeid( T ) );
if( needle == m_sheets.end() )
{
auto sheetName = getSheetName< T >();
// load sheet std::shared_ptr< xiv::dat::GameData > ExdData::getGameData()
auto& cat = m_exd_data->get_category( sheetName );
m_sheets[ typeid( T ) ] = sheet = static_cast< xiv::exd::Exd >( cat.get_data( xiv::exd::Language::en ) );
}
else
{
sheet = needle->second;
}
return sheet.get_sheet_rows< T >();
}
std::shared_ptr< xiv::dat::GameData > getGameData()
{ {
return m_data; return m_data;
} }
private: private:
template< typename T > template< typename T >
std::string getSheetName() std::string getSheetName();
{
auto origName = std::string( typeid( T ).name() );
#if _WIN32
auto pos = origName.find_last_of(':');
if (pos != std::string::npos)
{
return origName.substr(pos + 1);
}
return "[something fucking died]"; template< typename T >
#else xiv::exd::Exd& getSheet();
int status = -4;
auto res = abi::__cxa_demangle( origName.c_str(), NULL, NULL, &status );
auto name = ( status == 0 ) ? res : origName;
std::string demangledName( name );
auto pos = demangledName.find_last_of( ':' );
if( pos != std::string::npos )
{
demangledName = demangledName.substr( pos + 1 );
}
free( res );
return demangledName;
#endif
}
std::unordered_map< std::type_index, xiv::exd::Exd > m_sheets; std::unordered_map< std::type_index, xiv::exd::Exd > m_sheets;
std::shared_ptr< xiv::dat::GameData > m_data; std::shared_ptr< xiv::dat::GameData > m_data;
std::shared_ptr< xiv::exd::ExdData > m_exd_data; std::shared_ptr< xiv::exd::ExdData > m_exd_data;
}; };
template< typename T >
std::string ExdData::getSheetName()
{
auto origName = std::string( typeid( T ).name() );
#if _WIN32
auto pos = origName.find_last_of( ':' );
return pos != std::string::npos ? origName.substr( pos + 1 ) : "[something_fucking_died]";
#else
int status = -4;
char* res = abi::__cxa_demangle( origName.c_str(), nullptr, nullptr, &status );
std::string demangledName = ( status == 0 ) ? res : origName;
auto pos = demangledName.find_last_of( ':' );
if( pos != std::string::npos ) demangledName = demangledName.substr( pos + 1 );
free( res );
return demangledName;
#endif
} }
template< typename T >
xiv::exd::Exd& ExdData::getSheet()
{
auto needle = m_sheets.find( typeid( T ) );
if( needle == m_sheets.end() )
{
auto sheetName = getSheetName< T >();
auto& cat = m_exd_data->get_category( sheetName );
needle = m_sheets.emplace( typeid( T ), static_cast< xiv::exd::Exd >( cat.get_data( xiv::exd::Language::en ) ) ).first;
}
return needle->second;
}
template< typename T >
std::shared_ptr< Excel::ExcelStruct< T > > ExdData::getRow( uint32_t row, uint32_t subrow )
{
try
{
return getSheet< T >().get_row< T >( row );
} catch( const std::runtime_error& ex )
{
Logger::error( "Error fetching row from sheet {}: {}", getSheetName< T >(), ex.what() );
return nullptr;
} catch( const std::out_of_range& )
{
return nullptr;
}
}
template< typename T >
std::vector< uint32_t > ExdData::getIdList()
{
auto sheet = getSheet< T >();
auto rows = sheet.get_rows();
std::vector< uint32_t > ids;
for( const auto& row : rows ) ids.push_back( row.first );
return ids;
}
template< typename T >
std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > ExdData::getRows()
{
return getSheet< T >().get_sheet_rows< T >();
}
}// namespace Sapphire::Data

View file

@ -4,12 +4,6 @@
#include <datReader/DatCategories/bg/pcb.h> #include <datReader/DatCategories/bg/pcb.h>
#include <datReader/DatCategories/bg/lgb.h> #include <datReader/DatCategories/bg/lgb.h>
#include <datReader/DatCategories/bg/sgb.h> #include <datReader/DatCategories/bg/sgb.h>
#include <GameData.h>
#include <File.h>
#include <DatCat.h>
#include <ExdData.h>
#include <ExdCat.h>
#include <Exd.h>
#include <algorithm> #include <algorithm>
#include <execution> #include <execution>
@ -23,12 +17,8 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref(); auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
auto teriList = exdData.getRows< Excel::TerritoryType >(); auto teriList = exdData.getRows< Excel::TerritoryType >();
size_t count = 0; for( const auto& [ id, territoryType ] : teriList )
for( const auto& [ id, territoryType ] : teriList ) { {
// show some loading indication...
if( count++ % 10 == 0 )
std::cout << ".";
auto path = territoryType->getString( territoryType->data().LVB ); auto path = territoryType->getString( territoryType->data().LVB );
if( path.empty() ) if( path.empty() )
@ -36,16 +26,6 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
path = std::string( "bg/" ) + path.substr( 0, path.find( "/level/" ) ); path = std::string( "bg/" ) + path.substr( 0, path.find( "/level/" ) );
// TODO: it does feel like this needs to be streamlined into the datReader instead of being done here...
std::string bgLgbPath( path + "/level/bg.lgb" );
std::string planmapLgbPath( path + "/level/planmap.lgb" );
std::string planeventLgbPath( path + "/level/planevent.lgb" );
std::string plannerLgbPath( path + "/level/planner.lgb" );
std::vector< char > bgSection;
std::vector< char > planmapSection;
std::vector< char > planeventSection;
std::vector< char > plannerSection;
std::unique_ptr< xiv::dat::File > bgFile; std::unique_ptr< xiv::dat::File > bgFile;
std::unique_ptr< xiv::dat::File > planmap_file; std::unique_ptr< xiv::dat::File > planmap_file;
std::unique_ptr< xiv::dat::File > planevent_file; std::unique_ptr< xiv::dat::File > planevent_file;
@ -53,46 +33,39 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
try try
{ {
if( exdData.getGameData()->doesFileExist( bgLgbPath ) ) if( exdData.getGameData()->doesFileExist( path + "/level/bg.lgb" ) )
bgFile = exdData.getGameData()->getFile( bgLgbPath ); bgFile = loadFile( path + "/level/bg.lgb" );
else else
continue; continue;
planmap_file = exdData.getGameData()->getFile( planmapLgbPath ); planmap_file = loadFile( path + "/level/planmap.lgb" );
planevent_file = exdData.getGameData()->getFile( planeventLgbPath ); planevent_file = loadFile( path + "/level/planevent.lgb" );
} } catch( std::runtime_error& )
catch( std::runtime_error& )
{ {
// ignore files that aren't found
continue; continue;
} }
bgSection = bgFile->access_data_sections().at( 0 ); std::vector< char > bgSection( bgFile->access_data_sections().at( 0 ) );
planmapSection = planmap_file->access_data_sections().at( 0 ); std::vector< char > planmapSection( planmap_file->access_data_sections().at( 0 ) );
planeventSection = planevent_file->access_data_sections().at( 0 ); std::vector< char > planeventSection( planevent_file->access_data_sections().at( 0 ) );
std::vector< std::string > stringList; LGB_FILE bgLgb( bgSection.data(), "bg" );
LGB_FILE planmapLgb( planmapSection.data(), "planmap" );
uint32_t offset1 = 0x20; LGB_FILE planeventLgb( planeventSection.data(), "planevent" );
LGB_FILE bgLgb( &bgSection[ 0 ], "bg" );
LGB_FILE planmapLgb( &planmapSection[ 0 ], "planmap" );
LGB_FILE planeventLgb( &planeventSection[ 0 ], "planevent" );
uint32_t max_index = 0;
std::vector< LGB_FILE > lgbList; std::vector< LGB_FILE > lgbList;
try try
{ {
planner_file = exdData.getGameData()->getFile( plannerLgbPath ); planner_file = loadFile( path + "/level/planner.lgb" );
plannerSection = planner_file->access_data_sections().at( 0 ); std::vector< char > plannerSection( planner_file->access_data_sections().at( 0 ) );
LGB_FILE plannerLgb( &plannerSection[ 0 ], "planner" ); LGB_FILE plannerLgb( plannerSection.data(), "planner" );
lgbList.reserve( 4 );
lgbList = { bgLgb, planmapLgb, planeventLgb, plannerLgb }; lgbList = { bgLgb, planmapLgb, planeventLgb, plannerLgb };
} } catch( std::runtime_error& )
catch( std::runtime_error& )
{ {
lgbList.reserve( 3 );
lgbList = { bgLgb, planmapLgb, planeventLgb }; lgbList = { bgLgb, planmapLgb, planeventLgb };
} }
@ -126,9 +99,6 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
} }
case LgbEntryType::CollisionBox: case LgbEntryType::CollisionBox:
{ {
//auto pEObj = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
//Logger::debug( "CollisionBox {}", pEntry->header.nameOffset );
break; break;
} }
case LgbEntryType::EventObject: case LgbEntryType::EventObject:
@ -155,14 +125,20 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
} }
} }
std::cout << std::endl;
Logger::debug( Logger::debug(
"InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {} EventObj: {} EventNpc: {} EventRange: {}", "InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {} EventObj: {} EventNpc: {} EventRange: {}",
m_mapRangeCache.size(), m_exitRangeCache.size(), m_popRangeCache.size(), m_eobjCache.size(), m_enpcCache.size(), m_eventRangeCache.size() m_mapRangeCache.size(), m_exitRangeCache.size(), m_popRangeCache.size(), m_eobjCache.size(), m_enpcCache.size(),
); m_eventRangeCache.size() );
} }
std::unique_ptr< xiv::dat::File > Sapphire::InstanceObjectCache::loadFile( const std::string& filePath ) const
{
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
if( exdData.getGameData()->doesFileExist( filePath ) )
return exdData.getGameData()->getFile( filePath );
throw std::runtime_error( "File not found: " + filePath );
}
Sapphire::InstanceObjectCache::MapRangePtr Sapphire::InstanceObjectCache::MapRangePtr
Sapphire::InstanceObjectCache::getMapRange( uint16_t zoneId, uint32_t mapRangeId ) Sapphire::InstanceObjectCache::getMapRange( uint16_t zoneId, uint32_t mapRangeId )

View file

@ -5,6 +5,13 @@
#include <unordered_map> #include <unordered_map>
#include <Common.h> #include <Common.h>
#include <GameData.h>
#include <File.h>
#include <DatCat.h>
#include <ExdData.h>
#include <ExdCat.h>
#include <Exd.h>
struct LGB_MAP_RANGE_ENTRY; struct LGB_MAP_RANGE_ENTRY;
struct LGB_EXIT_RANGE_ENTRY; struct LGB_EXIT_RANGE_ENTRY;
struct LGB_POP_RANGE_ENTRY; struct LGB_POP_RANGE_ENTRY;
@ -99,13 +106,14 @@ namespace Sapphire
InstanceObjectCache(); InstanceObjectCache();
~InstanceObjectCache() = default; ~InstanceObjectCache() = default;
std::unique_ptr< xiv::dat::File > loadFile( const std::string& filePath ) const;
MapRangePtr getMapRange( uint16_t zoneId, uint32_t mapRangeId ); MapRangePtr getMapRange( uint16_t zoneId, uint32_t mapRangeId );
ExitRangePtr getExitRange( uint16_t zoneId, uint32_t exitRangeId ); ExitRangePtr getExitRange( uint16_t zoneId, uint32_t exitRangeId );
PopRangePtr getPopRange( uint32_t popRangeId ); PopRangePtr getPopRange( uint32_t popRangeId );
std::shared_ptr< PopRangeInfo > getPopRangeInfo( uint32_t popRangeId ); std::shared_ptr< PopRangeInfo > getPopRangeInfo( uint32_t popRangeId );
EObjPtr getEObj( uint32_t eObjId ); EObjPtr getEObj( uint32_t eObjId );
ENpcPtr getENpc( uint32_t eNpcId ); ENpcPtr getENpc( uint32_t eNpcId );