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:
commit
a65b23778b
15 changed files with 367 additions and 210 deletions
50
deps/datReader/DatCategories/bg/lgb.h
vendored
50
deps/datReader/DatCategories/bg/lgb.h
vendored
|
@ -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 ) );
|
||||
case LgbEntryType::BgParts:
|
||||
{
|
||||
entries.emplace_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) );
|
||||
break;
|
||||
}
|
||||
else if( type == LgbEntryType::Gimmick )
|
||||
case LgbEntryType::Gimmick:
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) );
|
||||
entries.emplace_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) );
|
||||
break;
|
||||
}
|
||||
else if( type == LgbEntryType::EventNpc )
|
||||
case LgbEntryType::EventNpc:
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) );
|
||||
entries.emplace_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) );
|
||||
break;
|
||||
}
|
||||
else if( type == LgbEntryType::EventObject )
|
||||
case LgbEntryType::EventObject:
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) );
|
||||
entries.emplace_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) );
|
||||
break;
|
||||
}
|
||||
else if( type == LgbEntryType::ExitRange )
|
||||
case LgbEntryType::ExitRange:
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
entries.emplace_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
break;
|
||||
}
|
||||
else if( type == LgbEntryType::EventRange )
|
||||
case LgbEntryType::EventRange:
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
entries.emplace_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
break;
|
||||
}
|
||||
else if( type == LgbEntryType::PopRange )
|
||||
case LgbEntryType::PopRange:
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
entries.emplace_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
break;
|
||||
}
|
||||
else if( type == LgbEntryType::MapRange )
|
||||
case LgbEntryType::MapRange:
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
entries.emplace_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
{
|
||||
entries.push_back( std::make_shared< LgbEntry >( buf, entryOffset ) );
|
||||
entries.emplace_back( std::make_shared< LgbEntry >( buf, entryOffset ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( std::exception& e )
|
||||
|
|
60
deps/datReader/Exd.cpp
vendored
60
deps/datReader/Exd.cpp
vendored
|
@ -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 )
|
||||
|
|
185
deps/datReader/Exd.h
vendored
185
deps/datReader/Exd.h
vendored
|
@ -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
|
||||
{
|
||||
|
||||
|
@ -186,6 +230,147 @@ namespace xiv::exd
|
|||
// Get all 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
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 )
|
||||
{
|
||||
|
||||
if( pEntry->getType() == LgbEntryType::MapRange )
|
||||
switch( pEntry->getType() )
|
||||
{
|
||||
case LgbEntryType::MapRange:
|
||||
{
|
||||
auto pMapRange = std::reinterpret_pointer_cast< LGB_MAP_RANGE_ENTRY >( pEntry );
|
||||
m_mapRangeCache.insert( id, pMapRange );
|
||||
|
||||
break;
|
||||
}
|
||||
else if( pEntry->getType() == LgbEntryType::ExitRange )
|
||||
case 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::PopRange:
|
||||
{
|
||||
auto pPopRange = std::reinterpret_pointer_cast< LGB_POP_RANGE_ENTRY >( pEntry );
|
||||
m_popRangeCache.insert( id, pPopRange );
|
||||
break;
|
||||
}
|
||||
else if( pEntry->getType() == LgbEntryType::CollisionBox )
|
||||
case LgbEntryType::CollisionBox:
|
||||
{
|
||||
//auto pEObj = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
|
||||
|
||||
//Logger::debug( "CollisionBox {}", pEntry->header.nameOffset );
|
||||
break;
|
||||
}
|
||||
else if( pEntry->getType() == LgbEntryType::EventObject )
|
||||
case LgbEntryType::EventObject:
|
||||
{
|
||||
auto pEObj = std::reinterpret_pointer_cast< LGB_EOBJ_ENTRY >( pEntry );
|
||||
m_eobjCache.insert( id, pEObj );
|
||||
break;
|
||||
}
|
||||
else if( pEntry->getType() == LgbEntryType::EventNpc )
|
||||
case LgbEntryType::EventNpc:
|
||||
{
|
||||
auto pENpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
|
||||
m_enpcCache.insert( id, pENpc );
|
||||
break;
|
||||
}
|
||||
else if( pEntry->getType() == LgbEntryType::EventRange )
|
||||
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: {}",
|
||||
|
|
Loading…
Add table
Reference in a new issue