1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-21 17:47:45 +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,86 +1,77 @@
#include "DatCat.h"
#include "Index.h"
#include "Dat.h"
#include "File.h"
#include "GameData.h"
#include "Index.h"
namespace xiv
{
namespace dat
{
namespace dat
{
Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name ) :
m_name( name ),
m_catNum( catNum ),
m_chunk( -1 )
{
// From the category number, compute back the real filename for.index .datXs
std::stringstream ss;
ss << std::setw( 2 ) << std::setfill( '0' ) << std::hex << catNum;
std::string prefix = ss.str() + "0000.win32";
Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name ) : m_name( name ),
m_catNum( catNum ),
m_chunk( -1 )
{
std::stringstream ss;
ss << std::setw( 2 ) << std::setfill( '0' ) << std::hex << catNum;
std::string prefix = ss.str() + "0000.win32";
// Creates the index: XX0000.win32.index
m_index = std::unique_ptr<Index>( new Index( basePath / "ffxiv" / ( prefix + ".index" ) ) );
m_index = std::make_unique< 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 )
{
m_dats.emplace_back( std::make_unique< Dat >(basePath / "ffxiv" / ( prefix + ".dat" + std::to_string( i ) ), 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 ) );
}
}
Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name, uint32_t exNum, uint32_t chunk ) :
m_name( name ),
m_catNum( catNum ),
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" ) );
Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name, uint32_t exNum, uint32_t chunk ) : m_name( name ),
m_catNum( catNum ),
m_chunk( chunk )
{
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 )
{
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 ) );
}
}
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 ) );
}
}
Cat::~Cat()
{
Cat::~Cat()
{
}
}
const Index& Cat::getIndex() const
{
return *m_index;
}
const Index& Cat::getIndex() const
{
return *m_index;
}
std::unique_ptr< File > Cat::getFile( uint32_t dir_hash, uint32_t filename_hash ) const
{
auto& hash_table_entry = getIndex().getHashTableEntry( dir_hash, filename_hash );
return m_dats[ hash_table_entry.datNum ]->getFile( hash_table_entry.datOffset );
}
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);
return m_dats[hash_table_entry.datNum]->getFile(hash_table_entry.datOffset);
}
bool Cat::doesFileExist( uint32_t dir_hash, uint32_t filename_hash ) const
{
return getIndex().doesFileExist( dir_hash, filename_hash );
}
bool Cat::doesFileExist( uint32_t dir_hash, uint32_t filename_hash ) const
{
return getIndex().doesFileExist( dir_hash, filename_hash );
}
bool Cat::doesDirExist( uint32_t dir_hash ) const
{
return getIndex().doesDirExist( dir_hash );
}
bool Cat::doesDirExist( uint32_t dir_hash ) const
{
return getIndex().doesDirExist( dir_hash );
}
const std::string& Cat::getName() const
{
return m_name;
}
const std::string& Cat::getName() const
{
return m_name;
}
uint32_t Cat::getCatNum() const
{
return m_catNum;
}
uint32_t Cat::getCatNum() const
{
return m_catNum;
}
}
}
}// namespace dat
}// namespace xiv

View file

@ -1,9 +1,8 @@
#ifndef XIV_DAT_CAT_H
#define XIV_DAT_CAT_H
#pragma once
#include <filesystem>
#include <memory>
#include <vector>
#include <filesystem>
namespace xiv::dat
{
@ -60,9 +59,8 @@ namespace xiv::dat
std::unique_ptr< Index > m_index;
// The .datXs such as dat nb X => m_dats[X]
std::vector< std::unique_ptr< Dat>> m_dats;
std::vector< std::unique_ptr< Dat > > m_dats;
};
}
#endif // XIV_DAT_CAT_H

View file

@ -1,4 +1,5 @@
#include "conv.h"
#include <cstring>// for memcpy
namespace xiv::utils::conv
{
@ -9,19 +10,21 @@ namespace xiv::utils::conv
uint32_t t2;
uint32_t t3;
t1 = i_value & 0x7fff; // Non-sign bits
t2 = i_value & 0x8000; // Sign bit
t3 = i_value & 0x7c00; // Exponent
t1 <<= 13; // Align mantissa on MSB
t2 <<= 16; // Shift sign bit into position
t1 = i_value & 0x7fff; // Non-sign bits
t2 = i_value & 0x8000; // Sign bit
t3 = i_value & 0x7c00; // Exponent
t1 <<= 13; // Align mantissa on MSB
t2 <<= 16; // Shift sign bit into position
t1 += 0x38000000; // Adjust bias
t1 += 0x38000000; // Adjust bias
t1 = ( t3 == 0 ? 0 : t1 ); // Denormals-as-zero
t1 = ( t3 == 0 ? 0 : t1 );// Denormals-as-zero
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 )

View file

@ -1,79 +1,52 @@
#include "crc32.h"
#include <mutex>
#include <vector>
#include <array>
#include <string>
#include <zlib/zlib.h>
namespace internal
{
// Mutex to prevent two threads from concurrently trying to build the crc tables atthe same time
std::mutex crc_creation_mutex;
using CrcTable = std::array< uint32_t, 0x100 >;
typedef std::vector<uint32_t> CrcTable;
// Our crc/rev_crc tables
CrcTable crc_table;
CrcTable rev_crc_table;
bool crc_tables_created = false;
void build_crc_tables()
constexpr CrcTable build_crc_table()
{
CrcTable crc_table{};
for( size_t i = 0; i < 0x100; ++i )
{
std::lock_guard<std::mutex> lock(crc_creation_mutex);
if (!crc_tables_created)
{
crc_table.resize(0x100);
rev_crc_table.resize(0x100);
for (auto i = 0; i < 0x100; ++i)
{
uint32_t crc = i;
for (auto j = 0; j < 8; ++j)
{
if (crc & 1)
{
crc = 0xEDB88320 ^ (crc >> 1);
}
else
{
crc = crc >> 1;
}
}
crc_table[i] = crc;
rev_crc_table[crc >> 24] = i + ((crc & 0xFFFFFF) << 8);
}
}
crc_tables_created = true;
uint32_t crc = i;
for( size_t j = 0; j < 8; ++j )
{
crc = ( crc & 1 ) ? ( 0xEDB88320 ^ ( crc >> 1 ) ) : ( crc >> 1 );
}
crc_table[ i ] = crc;
}
return crc_table;
}
const CrcTable& get_crc_table()
constexpr CrcTable build_rev_crc_table()
{
CrcTable rev_crc_table{};
auto crc_table = build_crc_table();
for( size_t i = 0; i < 0x100; ++i )
{
if (!crc_tables_created)
{
build_crc_tables();
}
return crc_table;
uint32_t crc = crc_table[ i ];
rev_crc_table[ crc >> 24 ] = i + ( ( crc & 0xFFFFFF ) << 8 );
}
return rev_crc_table;
}
const CrcTable& get_rev_crc_table()
{
if (!crc_tables_created)
{
build_crc_tables();
}
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
{
uint32_t compute( const std::string& i_input, uint32_t init_crc )
{
// Classical crc stuff
auto& crc_table = internal::get_crc_table();
auto crc = init_crc;
for( std::size_t i = 0; i < i_input.size(); ++i )
auto& crc_table = internal::crc_table;
uint32_t crc = init_crc;
for( size_t i = 0; i < i_input.size(); ++i )
{
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 )
{
auto& rev_crc_table = internal::get_rev_crc_table();
auto crc = init_crc;
auto& rev_crc_table = internal::rev_crc_table;
uint32_t crc = init_crc;
const auto input_size = i_input.size();
// Reverse crc
for( auto i = input_size; i > 0; --i )
for( size_t i = input_size; i > 0; --i )
{
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( auto i = 0; i < 4; ++i )
for( size_t i = 0; i < 4; ++i )
{
crc = rev_crc_table[ crc >> 24 ] ^ ( ( crc << 8 ) & 0xFFFFFF00 );
}
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() );
o_hashes.resize( 10000 );
uint32_t i = 0;
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 )
{
str[ i_first_index + 1 ] = b;
i_format[ i_first_index + 1 ] = b;
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 )
{
str[ i_first_index + 3 ] = d;
o_hashes[ i ] = ::crc32( 0, reinterpret_cast<uint8_t*>(&( str[ 0 ] )), str_size ) ^ 0xFFFFFFFF;
i_format[ i_first_index + 3 ] = d;
o_hashes[ i ] = ::crc32( 0, reinterpret_cast< const Bytef* >( i_format.data() ), str_size ) ^ 0xFFFFFFFF;
++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,
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() );
o_hashes.resize( 100000000 );
uint32_t i = 0;
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 )
{
str[ i_first_index + 1 ] = b;
i_format[ i_first_index + 1 ] = b;
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 )
{
str[ i_first_index + 3 ] = d;
i_format[ i_first_index + 3 ] = d;
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 )
{
str[ i_second_index + 1 ] = f;
i_format[ i_second_index + 1 ] = f;
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 )
{
str[ i_second_index + 3 ] = h;
o_hashes[ i ] = ::crc32( 0, reinterpret_cast<uint8_t*>(&( str[ 0 ] )), str_size ) ^ 0xFFFFFFFF;
i_format[ i_second_index + 3 ] = h;
o_hashes[ i ] = ::crc32( 0, reinterpret_cast< const Bytef* >( i_format.data() ), str_size ) ^ 0xFFFFFFFF;
++i;
}
}
@ -171,5 +136,4 @@ namespace xiv::utils::crc32
}
}
}
}// namespace xiv::utils::crc32

View file

@ -1,8 +1,8 @@
#include "zlib.h"
#include <string>
#include <stdexcept>
#include <zlib/zlib.h>
#include <string>
#include <vector>
#include <zlib/zlib.h>
namespace xiv::utils::zlib
{
@ -18,13 +18,13 @@ namespace xiv::utils::zlib
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 );
}
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;
strm.zalloc = Z_NULL;
@ -41,7 +41,7 @@ namespace xiv::utils::zlib
}
// 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.next_out = out;
@ -56,4 +56,4 @@ namespace xiv::utils::zlib
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 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
#include <unordered_map>
#include <string>
#include <cstdint>
#include <memory>
#include <vector>
#include <stdint.h>
#include <string>
#include <typeindex>
#include <unordered_map>
#include <vector>
#if !_WIN32
# include <cxxabi.h>
#include <cxxabi.h>
#endif
#include <datReader/GameData.h>
#include <File.h>
#include <ExdData.h>
#include <ExdCat.h>
#include <Exd.h>
#include <ExdCat.h>
#include <ExdData.h>
#include <File.h>
#include <Logging/Logger.h>
#include <datReader/GameData.h>
namespace Sapphire::Data
{
class ExdData
{
public:
bool init( const std::string& path );
template< typename T >
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;
}
}
std::shared_ptr< Excel::ExcelStruct< T > > getRow( uint32_t row, uint32_t subrow = 0 );
template< typename T >
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;
}
std::vector< uint32_t > getIdList();
template< typename T >
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 >();
std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > getRows();
// 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;
}
return sheet.get_sheet_rows< T >();
}
std::shared_ptr< xiv::dat::GameData > getGameData()
std::shared_ptr< xiv::dat::GameData > ExdData::getGameData()
{
return m_data;
}
private:
template< typename T >
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);
}
std::string getSheetName();
return "[something fucking died]";
#else
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
}
template< typename T >
xiv::exd::Exd& getSheet();
std::unordered_map< std::type_index, xiv::exd::Exd > m_sheets;
std::shared_ptr< xiv::dat::GameData > m_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/lgb.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 <execution>
@ -23,12 +17,8 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
auto teriList = exdData.getRows< Excel::TerritoryType >();
size_t count = 0;
for( const auto& [ id, territoryType ] : teriList ) {
// show some loading indication...
if( count++ % 10 == 0 )
std::cout << ".";
for( const auto& [ id, territoryType ] : teriList )
{
auto path = territoryType->getString( territoryType->data().LVB );
if( path.empty() )
@ -36,16 +26,6 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
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 > planmap_file;
std::unique_ptr< xiv::dat::File > planevent_file;
@ -53,46 +33,39 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
try
{
if( exdData.getGameData()->doesFileExist( bgLgbPath ) )
bgFile = exdData.getGameData()->getFile( bgLgbPath );
if( exdData.getGameData()->doesFileExist( path + "/level/bg.lgb" ) )
bgFile = loadFile( path + "/level/bg.lgb" );
else
continue;
planmap_file = exdData.getGameData()->getFile( planmapLgbPath );
planevent_file = exdData.getGameData()->getFile( planeventLgbPath );
}
catch( std::runtime_error& )
planmap_file = loadFile( path + "/level/planmap.lgb" );
planevent_file = loadFile( path + "/level/planevent.lgb" );
} catch( std::runtime_error& )
{
// ignore files that aren't found
continue;
}
bgSection = bgFile->access_data_sections().at( 0 );
planmapSection = planmap_file->access_data_sections().at( 0 );
planeventSection = planevent_file->access_data_sections().at( 0 );
std::vector< char > bgSection( bgFile->access_data_sections().at( 0 ) );
std::vector< char > planmapSection( planmap_file->access_data_sections().at( 0 ) );
std::vector< char > planeventSection( planevent_file->access_data_sections().at( 0 ) );
std::vector< std::string > stringList;
uint32_t offset1 = 0x20;
LGB_FILE bgLgb( &bgSection[ 0 ], "bg" );
LGB_FILE planmapLgb( &planmapSection[ 0 ], "planmap" );
LGB_FILE planeventLgb( &planeventSection[ 0 ], "planevent" );
uint32_t max_index = 0;
LGB_FILE bgLgb( bgSection.data(), "bg" );
LGB_FILE planmapLgb( planmapSection.data(), "planmap" );
LGB_FILE planeventLgb( planeventSection.data(), "planevent" );
std::vector< LGB_FILE > lgbList;
try
{
planner_file = exdData.getGameData()->getFile( plannerLgbPath );
plannerSection = planner_file->access_data_sections().at( 0 );
LGB_FILE plannerLgb( &plannerSection[ 0 ], "planner" );
planner_file = loadFile( path + "/level/planner.lgb" );
std::vector< char > plannerSection( planner_file->access_data_sections().at( 0 ) );
LGB_FILE plannerLgb( plannerSection.data(), "planner" );
lgbList.reserve( 4 );
lgbList = { bgLgb, planmapLgb, planeventLgb, plannerLgb };
}
catch( std::runtime_error& )
} catch( std::runtime_error& )
{
lgbList.reserve( 3 );
lgbList = { bgLgb, planmapLgb, planeventLgb };
}
@ -126,9 +99,6 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
}
case LgbEntryType::CollisionBox:
{
//auto pEObj = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
//Logger::debug( "CollisionBox {}", pEntry->header.nameOffset );
break;
}
case LgbEntryType::EventObject:
@ -155,14 +125,20 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
}
}
std::cout << std::endl;
Logger::debug(
"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()
);
"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() );
}
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::getMapRange( uint16_t zoneId, uint32_t mapRangeId )

View file

@ -5,6 +5,13 @@
#include <unordered_map>
#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_EXIT_RANGE_ENTRY;
struct LGB_POP_RANGE_ENTRY;
@ -99,13 +106,14 @@ namespace Sapphire
InstanceObjectCache();
~InstanceObjectCache() = default;
std::unique_ptr< xiv::dat::File > loadFile( const std::string& filePath ) const;
MapRangePtr getMapRange( uint16_t zoneId, uint32_t mapRangeId );
ExitRangePtr getExitRange( uint16_t zoneId, uint32_t exitRangeId );
PopRangePtr getPopRange( uint32_t popRangeId );
std::shared_ptr< PopRangeInfo > getPopRangeInfo( uint32_t popRangeId );
EObjPtr getEObj( uint32_t eObjId );
ENpcPtr getENpc( uint32_t eNpcId );