1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-20 03:37:48 +00:00

Merge pull request #965 from hkAlice/i-need-speed

[3.x] cache eobj/enpc exd; fix server crash on aoe skills; !add unlockall (0xff unlock bitmask);
This commit is contained in:
hkAlice 2024-08-09 20:07:37 -03:00 committed by GitHub
commit 4a46b3dd80
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 77 additions and 35 deletions

View file

@ -171,6 +171,7 @@ std::shared_ptr< FFXIVPacketBase > ActionResultBuilder::createActionResultPacket
break;
}
m_actorResultsMap.clear();
return actionResult;
}
else // use Effect for single target

View file

@ -563,6 +563,11 @@ void Player::setRewardFlag( Common::UnlockEntry unlockId )
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetRewardFlag, unlock, 1 );
}
void Player::fillRewardFlags()
{
memset( m_unlocks.data(), 0xFF, m_unlocks.size() );
}
void Player::setBorrowAction( uint8_t slot, uint32_t action )
{
if( slot > Common::ARRSIZE_BORROWACTION )
@ -1815,6 +1820,9 @@ void Player::setFalling( bool state, const Common::FFXIVARR_POSITION3& pos, bool
takeDamage( damage );
}
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), SetFallDamage, damage );
// todo: this used to work without refreshing the entire UI state
// does 3.x use some sort of fall integrity?
Network::Util::Packet::sendHudParam( *this );
}
}
}

View file

@ -441,6 +441,9 @@ namespace Sapphire::Entity
/*! learn an action / update the unlock bitmask. */
void setRewardFlag( Common::UnlockEntry unlockId );
/*! helper/debug function to fill unlock bitmask */
void fillRewardFlags();
void setBorrowAction( uint8_t slot, uint32_t action );
BorrowAction& getBorrowAction();

View file

@ -11,6 +11,7 @@
#include <Database/DatabaseDef.h>
#include <cmath>
#include <Network/PacketWrappers/EffectPacket.h>
#include <Network/Util/PacketUtil.h>
#include <Service.h>
#include "DebugCommand/DebugCommand.h"
@ -159,6 +160,7 @@ void DebugCommandMgr::help( char* data, Entity::Player& player, std::shared_ptr<
void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
{
auto& server = Sapphire::Common::Service< Sapphire::World::WorldServer >::ref();
auto& playerMgr = Common::Service< PlayerMgr >::ref();
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() );
@ -233,7 +235,8 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr<
else if( subCommand == "discovery_reset" )
{
player.resetDiscovery();
server.queueForPlayer( player.getCharacterId(), std::make_shared< PlayerSetupPacket >( player ) );
player.setIsLogin( true );
playerMgr.onMoveZone( player );
}
else if( subCommand == "classjob" )
{
@ -385,6 +388,7 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr<
void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
{
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
auto& playerMgr = Common::Service< PlayerMgr >::ref();
auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() );
std::string subCommand;
@ -525,6 +529,13 @@ void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr<
sscanf( params.c_str(), "%d", &id );
player.setRewardFlag( static_cast< Common::UnlockEntry >( id ) );
}
else if( subCommand == "unlockall" )
{
player.fillRewardFlags();
player.setIsLogin( true );
playerMgr.onMoveZone( player );
}
else if( subCommand == "effect" )
{
uint16_t param1;

View file

@ -35,11 +35,24 @@ using namespace Sapphire::World::Manager;
bool MapMgr::loadQuests()
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto questList = exdData.getRows< Excel::Quest >();
auto eNpcList = exdData.getRows< Excel::ENpcBase >();
auto eObjList = exdData.getRows< Excel::EObj >();
for( auto& [ id, questExdData ] : questList )
{
m_quests.emplace( id, std::move( questExdData ) );
m_questCacheMap.emplace( id, std::move( questExdData ) );
}
for( auto& [ id, eNpcExdData ] : eNpcList )
{
m_eNpcCacheMap.emplace( id, std::move( eNpcExdData ) );
}
for( auto& [ id, eObjExdData ] : eObjList )
{
m_eObjCacheMap.emplace( id, std::move( eObjExdData ) );
}
return true;
@ -58,12 +71,12 @@ void MapMgr::updateAll( Entity::Player& player )
for( const auto& eventNpc : *eventNpcs )
{
auto eNpc = exdData.getRow< Excel::ENpcBase >( eventNpc.second->data.enpcId );
if( !eNpc )
auto eNpcIt = m_eNpcCacheMap.find( eventNpc.second->data.enpcId );
if( eNpcIt == std::end( m_eNpcCacheMap ) )
continue;
auto eNpcData = eNpc->data().EventHandler;
for( int npcEvent = 0; npcEvent < 32; npcEvent++ )
auto eNpcData = eNpcIt->second->data().EventHandler;
for( auto npcEvent = 0; npcEvent < 32; ++npcEvent )
{
auto npcData = eNpcData[ npcEvent ].EventHandler;
@ -80,7 +93,7 @@ void MapMgr::updateAll( Entity::Player& player )
{
case EventHandler::EventHandlerType::Quest:
{
auto& quest = m_quests[ npcData ]->data();
auto& quest = m_questCacheMap[ npcData ]->data();
if( quest.Client == eventNpc.second->data.enpcId )
{
@ -102,7 +115,7 @@ void MapMgr::updateAll( Entity::Player& player )
{
if( guildLeve.NeedGrandCompanyRank > 0 && player.getGc() != 0 )
{
for( int8_t i = 0; i < 3; i++ )
for( int8_t i = 0; i < 3; ++i )
{
if( player.getGcRankArray()[ i ] >= guildLeve.NeedGrandCompanyRank )
{
@ -162,11 +175,11 @@ void MapMgr::updateAll( Entity::Player& player )
for( const auto& eventObj : *eventObjs )
{
auto eObj = exdData.getRow< Excel::EObj >( eventObj.second->data.BaseId );
if( !eObj )
return;
auto eObjIt = m_eObjCacheMap.find( eventObj.second->data.BaseId );
if( eObjIt == std::end( m_eObjCacheMap ) )
continue;
auto eObjData = eObj->data();
auto eObjData = eObjIt->second->data();
EventData eventData;
eventData.handlerId = eObjData.EventHandler;
eventData.layoutId = eventObj.first;
@ -175,7 +188,7 @@ void MapMgr::updateAll( Entity::Player& player )
if( eventHandlerType == EventHandler::EventHandlerType::Quest )
{
auto& quest = m_quests[ eObjData.EventHandler ]->data();
auto& quest = m_questCacheMap[ eObjData.EventHandler ]->data();
if( quest.Client == eventObj.second->data.BaseId )
{
@ -200,13 +213,13 @@ void MapMgr::updateQuests( Entity::Player& player )
for( const auto& eventNpc : *eventNpcs )
{
auto eNpc = exdData.getRow< Excel::ENpcBase >( eventNpc.second->data.enpcId );
if( !eNpc )
auto eNpcIt = m_eNpcCacheMap.find( eventNpc.second->data.enpcId );
if( eNpcIt == std::end( m_eNpcCacheMap ) )
continue;
auto eNpcData = eNpc->data().EventHandler;
auto eNpcData = eNpcIt->second->data().EventHandler;
for( int npcEvent = 0; npcEvent < 32; npcEvent++ )
for( auto npcEvent = 0; npcEvent < 32; ++npcEvent )
{
auto npcData = eNpcData[ npcEvent ].EventHandler;
@ -221,7 +234,7 @@ void MapMgr::updateQuests( Entity::Player& player )
if( eventHandlerType == EventHandler::EventHandlerType::Quest )
{
auto& quest = m_quests[ npcData ]->data();
auto& quest = m_questCacheMap[ npcData ]->data();
if( quest.Client == eventNpc.second->data.enpcId )
{
@ -237,11 +250,11 @@ void MapMgr::updateQuests( Entity::Player& player )
for( const auto& eventObj : *eventObjs )
{
auto eObj = exdData.getRow< Excel::EObj >( eventObj.second->data.BaseId );
if( !eObj )
return;
auto eObjIt = m_eObjCacheMap.find( eventObj.second->data.BaseId );
if( eObjIt == std::end( m_eObjCacheMap ) )
continue;
auto eObjData = eObj->data();
auto eObjData = eObjIt->second->data();
EventData eventData;
eventData.handlerId = eObjData.EventHandler;
eventData.layoutId = eventObj.first;
@ -250,7 +263,7 @@ void MapMgr::updateQuests( Entity::Player& player )
if( eventHandlerType == EventHandler::EventHandlerType::Quest )
{
auto& quest = m_quests[ eObjData.EventHandler ]->data();
auto& quest = m_questCacheMap[ eObjData.EventHandler ]->data();
if( quest.Client == eventObj.second->data.BaseId )
{
@ -267,7 +280,7 @@ void MapMgr::insertQuest( Entity::Player& player, uint32_t questId, uint32_t lay
auto& exdData = Common::Service< Data::ExdData >::ref();
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
auto& quest = m_quests[ questId ]->data();
auto& quest = m_questCacheMap[ questId ]->data();
if( isQuestVisible( player, questId, quest ) )
{
@ -307,7 +320,7 @@ bool MapMgr::isQuestAvailable( Entity::Player& player, uint32_t questId, Excel::
if( quest.InstanceContentOperator == 1 )
{
for( int32_t i = 0; i < 3; i++ )
for( int32_t i = 0; i < 3; ++i )
{
if( quest.InstanceContent[ i ] == 0 )
continue;
@ -319,7 +332,7 @@ bool MapMgr::isQuestAvailable( Entity::Player& player, uint32_t questId, Excel::
}
else if( quest.InstanceContentOperator == 2 )
{
for( int32_t i = 0; i < 3; i++ )
for( int32_t i = 0; i < 3; ++i )
{
if( quest.InstanceContent[ i ] == 0 )
continue;
@ -396,7 +409,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
if( quest.PrevQuestOperator == 1 )
{
for( int32_t i = 0; i < 3; i++ )
for( auto i = 0; i < 3; ++i )
{
if( quest.PrevQuest[ i ] == 0 )
continue;
@ -419,7 +432,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
}
else if( quest.PrevQuestOperator == 2 )
{
for( int32_t i = 0; i < 3; i++ )
for( auto i = 0; i < 3; ++i )
{
if( quest.PrevQuest[ i ] == 0 )
continue;
@ -434,7 +447,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
if( quest.ExcludeQuestOperator == 1 )
{
for( int32_t i = 0; i < 2; i++ )
for( auto i = 0; i < 2; ++i )
{
if( quest.ExcludeQuest[ i ] == 0 )
continue;
@ -448,7 +461,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
}
else if( quest.ExcludeQuestOperator == 2 )
{
for( int32_t i = 0; i < 2; i++ )
for( auto i = 0; i < 2; ++i )
{
if( quest.ExcludeQuest[ i ] == 0 )
continue;
@ -475,7 +488,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
{
auto classJobCategory = exdData.getRow< Excel::ClassJobCategory >( quest.ClassJob )->data().ClassJob;
for( int32_t i = 1; i <= Common::CLASSJOB_TOTAL; i++ )
for( auto i = 1; i <= Common::CLASSJOB_TOTAL; ++i )
{
if( i == Common::CLASSJOB_TOTAL )
return false;
@ -494,13 +507,14 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
}
// TODO: I think this changed in 3.x to be for all relics, more research is needed.
for( int32_t i = 0; i < Common::CLASSJOB_TOTAL; i++ )
// todo: fix this inner j loop
for( auto i = 0; i < Common::CLASSJOB_TOTAL; ++i )
{
auto classJob = exdData.getRow< Excel::ClassJob >( i );
if( classJob->data().ARRRelicQuestId == questId )
{
for( int32_t j = 0; i < Common::CLASSJOB_TOTAL; i++ )
for( auto j = 0; i < Common::CLASSJOB_TOTAL; ++i )
{
classJob = exdData.getRow< Excel::ClassJob >( i );

View file

@ -11,6 +11,8 @@
namespace Sapphire::World::Manager
{
using QuestMap = std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< Excel::Quest > > >;
using EObjDataCache = std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< Excel::EObj > > >;
using ENpcDataCache = std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< Excel::ENpcBase > > >;
class MapMgr
{
@ -64,8 +66,11 @@ namespace Sapphire::World::Manager
};
using EventSet = std::multiset< EventData, less >;
QuestMap m_quests;
QuestMap m_questCacheMap;
ENpcDataCache m_eNpcCacheMap;
EObjDataCache m_eObjCacheMap;
void insertQuest( Entity::Player& player, uint32_t questId, uint32_t layoutId, EventSet& mapData );

View file

@ -253,7 +253,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
}
case GmCommand::Kill:
{
targetActor->getAsChara()->takeDamage( 9999999 );
targetActor->getAsChara()->takeDamage( 0xFFFFFFFF );
PlayerMgr::sendServerNotice( player, "Killed {0}", targetActor->getId());
break;
}