1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-25 14:07:46 +00:00

Merge pull request #927 from hkAlice/faster-but-not-enough

[3.x] overall optimizations; add getRows to exd data;
This commit is contained in:
Mordred 2023-03-25 08:24:57 +01:00 committed by GitHub
commit a65b23778b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 367 additions and 210 deletions

View file

@ -227,6 +227,8 @@ struct LGB_GROUP
memcpy( (char*)&refs[0], buf + offset + header.LayerSetRef + layerSetReferencedList.LayerSets, layerSetReferencedList.LayerSetCount * sizeof( LayerSetReferenced ) );
}
entries.reserve( header.entryCount );
const auto entriesOffset = offset + header.entriesOffset;
for( auto i = 0; i < header.entryCount; ++i )
{
@ -235,41 +237,53 @@ struct LGB_GROUP
try
{
const auto type = *reinterpret_cast< LgbEntryType* >( buf + entryOffset );
if( type == LgbEntryType::BgParts )
switch( type )
{
entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::Gimmick )
{
entries.push_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::EventNpc )
{
entries.push_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::EventObject )
{
entries.push_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::ExitRange )
{
entries.push_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::EventRange )
{
entries.push_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::PopRange )
{
entries.push_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::MapRange )
{
entries.push_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) );
}
else
{
entries.push_back( std::make_shared< LgbEntry >( buf, entryOffset ) );
case LgbEntryType::BgParts:
{
entries.emplace_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) );
break;
}
case LgbEntryType::Gimmick:
{
entries.emplace_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) );
break;
}
case LgbEntryType::EventNpc:
{
entries.emplace_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) );
break;
}
case LgbEntryType::EventObject:
{
entries.emplace_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) );
break;
}
case LgbEntryType::ExitRange:
{
entries.emplace_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) );
break;
}
case LgbEntryType::EventRange:
{
entries.emplace_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) );
break;
}
case LgbEntryType::PopRange:
{
entries.emplace_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) );
break;
}
case LgbEntryType::MapRange:
{
entries.emplace_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) );
break;
}
default:
{
entries.emplace_back( std::make_shared< LgbEntry >( buf, entryOffset ) );
break;
}
}
}
catch( std::exception& e )

View file

@ -7,50 +7,6 @@
using xiv::utils::bparse::extract;
namespace xiv::exd
{
struct ExdHeader
{
char magic[0x4];
uint16_t unknown;
uint16_t unknown2;
uint32_t index_size;
};
struct ExdRecordIndex
{
uint32_t id;
uint32_t offset;
};
}
namespace xiv::utils::bparse {
template<>
inline void reorder< xiv::exd::ExdHeader >( xiv::exd::ExdHeader& i_struct )
{
for( int32_t i = 0; i < 0x4; ++i )
{
xiv::utils::bparse::reorder( i_struct.magic[ i ] );
}
i_struct.unknown = xiv::utils::bparse::byteswap( i_struct.unknown );
xiv::utils::bparse::reorder( i_struct.unknown );
i_struct.unknown2 = xiv::utils::bparse::byteswap( i_struct.unknown2 );
xiv::utils::bparse::reorder( i_struct.unknown2 );
i_struct.index_size = xiv::utils::bparse::byteswap( i_struct.index_size );
xiv::utils::bparse::reorder( i_struct.index_size );
}
template<>
inline void reorder< xiv::exd::ExdRecordIndex >( xiv::exd::ExdRecordIndex& i_struct )
{
i_struct.id = xiv::utils::bparse::byteswap( i_struct.id );
xiv::utils::bparse::reorder( i_struct.id );
i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset );
xiv::utils::bparse::reorder( i_struct.offset );
}
};
namespace xiv::exd
{
Exd::Exd( std::shared_ptr< Exh > i_exh, const std::vector< std::shared_ptr< dat::File>>& i_files )
@ -68,16 +24,16 @@ namespace xiv::exd
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
// Extract the header and skip to the record indices
auto exd_header = extract< ExdHeader >( iss );
auto exd_header = extract< ExdHeaderMinimal >( iss );
iss.seekg( 0x20 );
// Preallocate and extract the record_indices
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex );
std::vector< ExdRecordIndex > record_indices;
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData );
std::vector< ExdRecordIndexData > record_indices;
record_indices.reserve( record_count );
for( uint32_t i = 0; i < record_count; ++i )
{
auto recordIndex = extract< ExdRecordIndex >( iss );
auto recordIndex = extract< ExdRecordIndexData >( iss );
_idCache[ recordIndex.id ] = ExdCacheEntry{ file_ptr, recordIndex.offset };
}
}
@ -290,16 +246,16 @@ namespace xiv::exd
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
// Extract the header and skip to the record indices
auto exd_header = extract< ExdHeader >( iss );
auto exd_header = extract< ExdHeaderMinimal >( iss );
iss.seekg( 0x20 );
// Preallocate and extract the record_indices
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex );
std::vector< ExdRecordIndex > record_indices;
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData );
std::vector< ExdRecordIndexData > record_indices;
record_indices.reserve( record_count );
for( uint32_t i = 0; i < record_count; ++i )
{
record_indices.emplace_back( extract< ExdRecordIndex >( iss ) );
record_indices.emplace_back( extract< ExdRecordIndexData >( iss ) );
}
for( auto& record_index : record_indices )

191
deps/datReader/Exd.h vendored
View file

@ -2,6 +2,7 @@
#include <memory>
#include <map>
#include <unordered_map>
#include <variant>
@ -12,6 +13,49 @@
#include <fstream>
#include "Exh.h"
#include "bparse.h"
namespace xiv::exd
{
struct ExdHeaderMinimal {
char magic[ 0x4 ];
uint16_t unknown;
uint16_t unknown2;
uint32_t index_size;
};
struct ExdRecordIndexData {
uint32_t id;
uint32_t offset;
};
}
namespace xiv::utils::bparse
{
template<>
inline void reorder< xiv::exd::ExdHeaderMinimal >( xiv::exd::ExdHeaderMinimal& i_struct )
{
for( int32_t i = 0; i < 0x4; ++i )
{
xiv::utils::bparse::reorder( i_struct.magic[ i ] );
}
i_struct.unknown = xiv::utils::bparse::byteswap( i_struct.unknown );
xiv::utils::bparse::reorder( i_struct.unknown );
i_struct.unknown2 = xiv::utils::bparse::byteswap( i_struct.unknown2 );
xiv::utils::bparse::reorder( i_struct.unknown2 );
i_struct.index_size = xiv::utils::bparse::byteswap( i_struct.index_size );
xiv::utils::bparse::reorder( i_struct.index_size );
}
template<>
inline void reorder< xiv::exd::ExdRecordIndexData >( xiv::exd::ExdRecordIndexData& i_struct )
{
i_struct.id = xiv::utils::bparse::byteswap( i_struct.id );
xiv::utils::bparse::reorder( i_struct.id );
i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset );
xiv::utils::bparse::reorder( i_struct.offset );
}
};// namespace xiv::utils::bparse
namespace xiv::exd
{
@ -184,12 +228,153 @@ namespace xiv::exd
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();
const std::map< uint32_t, std::vector< Field > >& get_rows();
// Get all rows
template< typename T >
const std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > get_sheet_rows()
{
std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > sheets;
// Iterates over all the files
const uint32_t member_count = static_cast< uint32_t >( _exh->get_members().size() );
for( auto& file_ptr : _files )
{
// Get a stream
std::vector< char > dataCpy = file_ptr->get_data_sections().front();
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
// Extract the header and skip to the record indices
auto exd_header = xiv::utils::bparse::extract< ExdHeaderMinimal >( iss );
iss.seekg( 0x20 );
// Preallocate and extract the record_indices
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData );
std::vector< ExdRecordIndexData > record_indices;
record_indices.reserve( record_count );
for( uint32_t i = 0; i < record_count; ++i )
{
record_indices.emplace_back( xiv::utils::bparse::extract< ExdRecordIndexData >( iss ) );
}
for( auto& record_index : record_indices )
{
auto cacheEntryIt = _idCache.find( record_index.id );
if( cacheEntryIt == _idCache.end() )
throw std::out_of_range( "Id not found: " + std::to_string( record_index.id ) );
auto pSheet = std::make_shared< Excel::ExcelStruct< T > >();
// Get the vector fields for the given record and preallocate it
auto fields = _data[ record_index.id ];
fields.reserve( member_count );
iss.seekg( cacheEntryIt->second.offset + 6 );
iss.read( reinterpret_cast<char*>( &pSheet.get()->_data ), sizeof( T ) );
int stringCount = 0;
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 = xiv::utils::bparse::extract< uint32_t >( iss, "string_offset", false );
iss.seekg( cacheEntryIt->second.offset + 6 + _exh->get_header().data_offset + string_offset );
std::string value = xiv::utils::bparse::extract_cstring( iss, "string" );
auto it = pSheet->_strings.insert( pSheet->_strings.end(), value );
*reinterpret_cast< uint32_t* >( pSheet->ptr() + member_entry.offset ) =
static_cast< uint32_t >( std::distance( pSheet->_strings.begin(), it ) );
}
break;
case DataType::boolean:
xiv::utils::bparse::extract< bool >( iss, "bool" );
break;
case DataType::int8:
xiv::utils::bparse::extract< int8_t >( iss, "int8_t" );
break;
case DataType::uint8:
xiv::utils::bparse::extract< uint8_t >( iss, "uint8_t" );
break;
case DataType::int16:
{
int16_t value = xiv::utils::bparse::extract< int16_t >( iss, "int16_t", false );
*reinterpret_cast< int16_t* >( pSheet->ptr() + member_entry.offset ) = value;
}
break;
case DataType::uint16:
{
uint16_t value = xiv::utils::bparse::extract< uint16_t >( iss, "uint16_t", false );
*reinterpret_cast< uint16_t* >( pSheet->ptr() + member_entry.offset ) = value;
}
break;
case DataType::int32:
{
int32_t value = xiv::utils::bparse::extract< int32_t >( iss, "int32_t", false );
*reinterpret_cast< int32_t* >( pSheet->ptr() + member_entry.offset ) = value;
}
break;
case DataType::uint32:
{
uint32_t value = xiv::utils::bparse::extract< uint32_t >( iss, "uint32_t", false );
*reinterpret_cast< uint32_t* >( pSheet->ptr() + member_entry.offset ) = value;
}
break;
case DataType::float32:
{
float value = xiv::utils::bparse::extract< float >( iss, "float", false );
*reinterpret_cast< float* >( pSheet->ptr() + member_entry.offset ) = value;
}
break;
case DataType::uint64:
{
uint64_t value = xiv::utils::bparse::extract< uint64_t >( iss, "uint64_t", false );
*reinterpret_cast< uint64_t* >( pSheet->ptr() + member_entry.offset ) = value;
}
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 = xiv::utils::bparse::extract< uint64_t >( iss, "bool" );
int32_t shift = type - 0x19;
int32_t i = 1 << shift;
val &= i;
fields.emplace_back( ( val & i ) == i );
break;
}
}
sheets[ record_index.id ] = pSheet;
}
}
return sheets;
}
protected:
// Data indexed by the ID of the row, the vector is field with the same order as exh.members
std::map< uint32_t, std::vector< Field>> _data;
std::vector< std::shared_ptr< dat::File>> _files;
std::map< uint32_t, std::vector< Field > > _data;
std::vector< std::shared_ptr< dat::File > > _files;
std::shared_ptr< Exh > _exh;
std::map< uint32_t, ExdCacheEntry > _idCache;
};

View file

@ -91,6 +91,27 @@ namespace Sapphire::Data
return ids;
}
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 >();
// 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()
{
return m_data;

View file

@ -157,22 +157,20 @@ int main( int argc, char* argv[] )
Logger::fatal( "Error setting up EXD data " );
return 0;
}
auto idList = g_exdDataGen.getIdList< Excel::Action >();
auto actionList = g_exdDataGen.getRows< Excel::Action >();
std::map< uint32_t, ActionEntry > actions;
std::map< uint32_t, std::vector< uint32_t > > traversedCombos;
auto total = idList.size();
auto total = actionList.size();
int cursor = 0;
for( auto id : idList )
for( const auto& [ id, action ] : actionList )
{
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
if( cursor % 50 == 0 && cursor > 0 )
Logger::info( "Processing {} actions of {} ({:.2f}%)", cursor, total, done );
auto action = g_exdDataGen.getRow< Excel::Action >( id );
//auto actionTransient = g_exdData.get< Sapphire::Data::ActionTransient >( id );
if( action )
{

View file

@ -89,11 +89,11 @@ int main( int argc, char* argv[] )
// CFC list
{
auto idList = g_exdDataGen.getIdList< Excel::ContentFinderCondition >();
auto cfcList = g_exdDataGen.getRows< Excel::ContentFinderCondition >();
std::stringstream cfcOutputStream;
auto total = idList.size();
auto total = cfcList.size();
int cursor = 0;
std::map< uint8_t, std::string > instanceContentTypeMap;
@ -118,7 +118,7 @@ int main( int argc, char* argv[] )
cfcOutputStream << "| ID | Instance | Territory | Name | Type |" << std::endl
<< "| --- | --- | --- | --- | --- |" << std::endl;
for( auto id : idList )
for( const auto& [ id, cfc ] : cfcList )
{
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
if( cursor % 50 == 0 && cursor > 0 )
@ -127,8 +127,6 @@ int main( int argc, char* argv[] )
if( id == 0 )
continue;
auto cfc = g_exdDataGen.getRow< Excel::ContentFinderCondition >( id );
if( cfc )
{
auto& cfcData = cfc->data();
@ -234,24 +232,22 @@ int main( int argc, char* argv[] )
teriTypeIntendedUseMap[ TheFeastArea ] = "TheFeastArea";
teriTypeIntendedUseMap[ PrivateEventArea ] = "PrivateEventArea";
auto idList = g_exdDataGen.getIdList< Excel::TerritoryType >();
auto teriList = g_exdDataGen.getRows< Excel::TerritoryType >();
std::stringstream teritypeOutputStream;
teritypeOutputStream << "| ID | Place Name | Name | Intended Use |" << std::endl
<< "| --- | --- | --- | --- |" << std::endl;
auto total = idList.size();
auto total = teriList.size();
int cursor = 0;
for( auto id : idList )
for( const auto& [ id, teriType ] : teriList )
{
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
if( cursor % 50 == 0 && cursor > 0 )
Logger::info( "Processing {} teritypes of {} ({:.2f}%)", cursor, total, done );
auto teriType = g_exdDataGen.getRow< Excel::TerritoryType >( id );
if( teriType )
{
auto& teriTypeData = teriType->data();
@ -291,24 +287,22 @@ int main( int argc, char* argv[] )
// class/job list
{
auto idList = g_exdDataGen.getIdList< Excel::ClassJob >();
auto classJobList = g_exdDataGen.getRows< Excel::ClassJob >();
std::stringstream classjobOutputStream;
classjobOutputStream << "| ID | Name | Short | Main Class |" << std::endl
<< "| --- | --- | --- | --- |" << std::endl;
auto total = idList.size();
auto total = classJobList.size();
int cursor = 0;
for( auto id : idList )
for( const auto& [ id, classJob ] : classJobList )
{
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
if( cursor % 50 == 0 && cursor > 0 )
Logger::info( "Processing {} classjobs of {} ({:.2f}%)", cursor, total, done );
auto classJob = g_exdDataGen.getRow< Excel::ClassJob >( id );
if( classJob )
{
auto& classJobData = classJob->data();
@ -338,7 +332,7 @@ int main( int argc, char* argv[] )
// achievement list
{
auto idList = g_exdDataGen.getIdList< Excel::Achievement >();
auto achvList = g_exdDataGen.getRows< Excel::Achievement >();
enum class Type : uint8_t
{
@ -394,17 +388,15 @@ int main( int argc, char* argv[] )
achvOutputStream << "| ID | Name | Type (Subtype) | Description |" << std::endl
<< "| --- | --- | --- | --- |" << std::endl;
auto total = idList.size();
auto total = achvList.size();
int cursor = 0;
for( auto id : idList )
for( const auto& [ id, pAchv ] : achvList )
{
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
if( cursor % 50 == 0 && cursor > 0 )
Logger::info( "Processing {} achievements of {} ({:.2f}%)", cursor, total, done );
auto pAchv = g_exdDataGen.getRow< Excel::Achievement >( id );
if( pAchv )
{
auto& achvData = pAchv->data();

View file

@ -131,12 +131,11 @@ void World::ContentFinder::registerContentRequest( Entity::Player &player, uint3
void World::ContentFinder::registerRandomContentRequest( Entity::Player &player, uint32_t randomContentTypeId )
{
auto& exdData = Service< Data::ExdData >::ref();
auto contentListIds = exdData.getIdList< Excel::ContentFinderCondition >();
auto contentFinderList = exdData.getRows< Excel::ContentFinderCondition >();
std::vector< uint32_t > idList;
for( auto id : contentListIds )
for( const auto& [ id, instanceContent ] : contentFinderList )
{
auto instanceContent = exdData.getRow< Excel::ContentFinderCondition >( id );
if( instanceContent->data().RandomContentType == randomContentTypeId )
{
if( instanceContent->data().LevelMin <= player.getLevel() )

View file

@ -14,12 +14,10 @@ using namespace Sapphire::World::Manager;
bool AchievementMgr::cacheAchievements()
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto idList = exdData.getIdList< Excel::Achievement >();
auto achvDat = exdData.getRows< Excel::Achievement >();
for( auto id : idList )
for( const auto& [ id, achvExdData ] : achvDat )
{
auto achvExdData = exdData.getRow< Excel::Achievement >( id );
uint32_t key = achvExdData->data().ConditionType;
auto achvType = static_cast< Common::Achievement::Type >( key );

View file

@ -35,12 +35,10 @@ using namespace Sapphire::World::Manager;
bool MapMgr::loadQuests()
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto idList = exdData.getIdList< Excel::Quest >();
auto questList = exdData.getRows< Excel::Quest >();
for( auto id : idList )
for( auto& [ id, questExdData ] : questList )
{
auto questExdData = exdData.getRow< Excel::Quest >( id );
m_quests.emplace( id, std::move( questExdData ) );
}

View file

@ -12,13 +12,12 @@ using namespace Sapphire::World::Manager;
void ShopMgr::cacheShop( uint32_t shopId )
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto itemShopList = exdData.getIdList< Excel::Shop >();
auto itemShopList = exdData.getRows< Excel::Shop >();
uint8_t count = 0;
for( auto itemShop : itemShopList )
for( const auto& [ itemShop, shop ] : itemShopList )
{
if( shopId == itemShop )
{
auto shop = exdData.getRow< Excel::Shop >( itemShop );
for( auto shopItemId : shop->data().Item )
{
auto shopItem = exdData.getRow< Excel::ShopItem >( shopItemId );

View file

@ -35,14 +35,12 @@ TerritoryMgr::TerritoryMgr() :
void TerritoryMgr::loadTerritoryTypeDetailCache()
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto idList = exdData.getIdList< Excel::TerritoryType >();
auto teriList = exdData.getRows< Excel::TerritoryType >();
for( auto id : idList )
for( const auto& [ id, teri ] : teriList )
{
auto teri1 = exdData.getRow< Excel::TerritoryType >( id );
if( !teri1->getString( teri1->data().Name ).empty() && id > 90 )
m_territoryTypeDetailCacheMap[ id ] = teri1;
if( !teri->getString( teri->data().Name ).empty() && id > 90 )
m_territoryTypeDetailCacheMap[ id ] = teri;
}
}
@ -77,12 +75,11 @@ uint32_t TerritoryMgr::getNextInstanceId()
Excel::ExcelStructPtr< Excel::TerritoryType > TerritoryMgr::getTerritoryDetail( uint32_t territoryTypeId ) const
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto teri1 = exdData.getRow< Excel::TerritoryType >( territoryTypeId );
if( !teri1 )
auto it = m_territoryTypeDetailCacheMap.find( territoryTypeId );
if( it == m_territoryTypeDetailCacheMap.end() )
return nullptr;
return teri1;
return it->second;
}
bool TerritoryMgr::isInstanceContentTerritory( uint32_t territoryTypeId ) const
@ -159,11 +156,10 @@ bool TerritoryMgr::isHousingTerritory( uint32_t territoryTypeId ) const
uint32_t TerritoryMgr::getInstanceContentId( uint32_t territoryTypeId ) const
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto contentListIds = exdData.getIdList< Excel::InstanceContent >();
auto contentFinderList = exdData.getRows< Excel::InstanceContent >();
for( auto id : contentListIds )
for( const auto& [ id, instanceContent ] : contentFinderList )
{
auto instanceContent = exdData.getRow< Excel::InstanceContent >( id );
if( instanceContent->data().TerritoryType == territoryTypeId )
{
return id;
@ -198,8 +194,6 @@ bool TerritoryMgr::createDefaultTerritories()
pPlaceName->getString( pPlaceName->data().Text.SGL ) );
pZone->init();
std::string bgPath = territoryInfo->getString( territoryData.LVB );
bool hasNaviMesh = pZone->getNaviProvider() != nullptr;
Logger::info( "{0}\t{1}\t{2}\t{3:<10}\t{4}\t{5}\t{6}",
@ -309,10 +303,10 @@ TerritoryPtr TerritoryMgr::createQuestBattle( uint32_t questBattleId )
if( !pQuestInfo || pQuestInfo->getString( pQuestInfo->data().Text.Name ).empty() )
return nullptr;
for( auto& teriId : exdData.getIdList< Excel::TerritoryType >() )
{
auto teriList = exdData.getRows< Excel::TerritoryType >();
auto pTeri = exdData.getRow< Excel::TerritoryType >( teriId );
for( const auto& [ teriId, pTeri ] : teriList )
{
if( !pTeri || pTeri->data().QuestBattle != questBattleId )
continue;
@ -332,8 +326,6 @@ TerritoryPtr TerritoryMgr::createQuestBattle( uint32_t questBattleId )
m_instanceZoneSet.insert( pZone );
return pZone;
}
return nullptr;

View file

@ -74,12 +74,12 @@ void Sapphire::Network::GameConnection::find5Contents( const Packets::FFXIVARR_P
if( territoryType != 0 )
selectedContent.insert( territoryType );
auto contentListIds = exdData.getIdList< Excel::InstanceContent >();
std::vector< uint32_t > idList;
for( auto id : contentListIds )
auto contentFinderList = exdData.getRows< Excel::InstanceContent >();
for( const auto& [ id, instanceContent ] : contentFinderList )
{
auto instanceContent = exdData.getRow< Excel::InstanceContent >( id );
if( selectedContent.count( instanceContent->data().TerritoryType ) )
{
idList.push_back( id );

View file

@ -506,19 +506,14 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
bool doTeleport = false;
uint16_t teleport;
auto idList = exdData.getIdList< Excel::Aetheryte >();
auto aetheryteList = exdData.getRows< Excel::Aetheryte >();
for( auto i : idList )
for( const auto& [ id, data ] : aetheryteList )
{
auto data = exdData.getRow< Excel::Aetheryte >( i );
if( !data )
continue;
if( data->data().TerritoryType == param1 && data->data().Telepo )
{
doTeleport = true;
teleport = static_cast< uint16_t >( i );
teleport = static_cast< uint16_t >( id );
break;
}

View file

@ -52,15 +52,13 @@ void Util::Packet::sendBaseParams( Entity::Player& player )
std::fill( std::begin( statParams ), std::end( statParams ), 0 );
auto& exd = Common::Service< Data::ExdData >::ref();
auto idList = exd.getIdList< Excel::BaseParam >();
auto baseParamList = exd.getRows< Excel::BaseParam >();
for( const auto id : idList )
for( const auto& [ id, row ] : baseParamList )
{
auto row = exd.getRow< Excel::BaseParam >( id );
if( !row )
continue;
if( row->data().PacketIndex < 0 )
if( !row || row->data().PacketIndex < 0 )
continue;
statParams[ row->data().PacketIndex ] = player.getStatValue( static_cast< Common::BaseParam >( id ) );
}

View file

@ -11,27 +11,24 @@
#include <ExdCat.h>
#include <Exd.h>
#include <algorithm>
#include <execution>
#include <Logging/Logger.h>
#include <Service.h>
#include <Util/UtilMath.h>
Sapphire::InstanceObjectCache::InstanceObjectCache()
{
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
auto idList = exdData.getIdList< Excel::TerritoryType >();
auto teriList = exdData.getRows< Excel::TerritoryType >();
size_t count = 0;
for( const auto& id : idList )
{
for( const auto& [ id, territoryType ] : teriList ) {
// show some loading indication...
if( count++ % 10 == 0 )
std::cout << ".";
auto territoryType = exdData.getRow< Excel::TerritoryType >( id );
if( !territoryType )
continue;
auto path = territoryType->getString( territoryType->data().LVB );
if( path.empty() )
@ -56,7 +53,11 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
try
{
bgFile = exdData.getGameData()->getFile( bgLgbPath );
if( exdData.getGameData()->doesFileExist( bgLgbPath ) )
bgFile = exdData.getGameData()->getFile( bgLgbPath );
else
continue;
planmap_file = exdData.getGameData()->getFile( planmapLgbPath );
planevent_file = exdData.getGameData()->getFile( planeventLgbPath );
}
@ -101,49 +102,60 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
{
for( const auto& pEntry : group.entries )
{
switch( pEntry->getType() )
{
case LgbEntryType::MapRange:
{
auto pMapRange = std::reinterpret_pointer_cast< LGB_MAP_RANGE_ENTRY >( pEntry );
m_mapRangeCache.insert( id, pMapRange );
if( pEntry->getType() == LgbEntryType::MapRange )
{
auto pMapRange = std::reinterpret_pointer_cast< LGB_MAP_RANGE_ENTRY >( pEntry );
m_mapRangeCache.insert( id, pMapRange );
}
else if( pEntry->getType() == LgbEntryType::ExitRange )
{
auto pExitRange = std::reinterpret_pointer_cast< LGB_EXIT_RANGE_ENTRY >( pEntry );
m_exitRangeCache.insert( id, pExitRange );
}
else if( pEntry->getType() == LgbEntryType::PopRange )
{
break;
}
case LgbEntryType::ExitRange:
{
auto pExitRange = std::reinterpret_pointer_cast< LGB_EXIT_RANGE_ENTRY >( pEntry );
m_exitRangeCache.insert( id, pExitRange );
auto pPopRange = std::reinterpret_pointer_cast< LGB_POP_RANGE_ENTRY >( pEntry );
m_popRangeCache.insert( id, pPopRange );
}
else if( pEntry->getType() == LgbEntryType::CollisionBox )
{
//auto pEObj = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
break;
}
case LgbEntryType::PopRange:
{
auto pPopRange = std::reinterpret_pointer_cast< LGB_POP_RANGE_ENTRY >( pEntry );
m_popRangeCache.insert( id, pPopRange );
break;
}
case LgbEntryType::CollisionBox:
{
//auto pEObj = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
//Logger::debug( "CollisionBox {}", pEntry->header.nameOffset );
}
else if( pEntry->getType() == LgbEntryType::EventObject )
{
auto pEObj = std::reinterpret_pointer_cast< LGB_EOBJ_ENTRY >( pEntry );
m_eobjCache.insert( id, pEObj );
}
else if( pEntry->getType() == LgbEntryType::EventNpc )
{
auto pENpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
m_enpcCache.insert( id, pENpc );
}
else if( pEntry->getType() == LgbEntryType::EventRange )
{
auto pEventRange = std::reinterpret_pointer_cast< LGB_EVENT_RANGE_ENTRY >( pEntry );
m_eventRangeCache.insert( 0, pEventRange );
//Logger::debug( "CollisionBox {}", pEntry->header.nameOffset );
break;
}
case LgbEntryType::EventObject:
{
auto pEObj = std::reinterpret_pointer_cast< LGB_EOBJ_ENTRY >( pEntry );
m_eobjCache.insert( id, pEObj );
break;
}
case LgbEntryType::EventNpc:
{
auto pENpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
m_enpcCache.insert( id, pENpc );
break;
}
case LgbEntryType::EventRange:
{
auto pEventRange = std::reinterpret_pointer_cast< LGB_EVENT_RANGE_ENTRY >( pEntry );
m_eventRangeCache.insert( 0, pEventRange );
break;
}
}
}
}
}
}
std::cout << "\n";
std::cout << std::endl;
Logger::debug(
"InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {} EventObj: {} EventNpc: {} EventRange: {}",