diff --git a/src/common/Event/EventDispatcher.cpp b/src/common/Event/EventDispatcher.cpp index 5015d875..2048aad7 100644 --- a/src/common/Event/EventDispatcher.cpp +++ b/src/common/Event/EventDispatcher.cpp @@ -2,11 +2,17 @@ using namespace Sapphire::Common::EventSystem; -void EventDispatcher::subscribe( const Event::DescriptorType& descriptor, SlotType&& slot ) +void EventDispatcher::subscribe( const Event::DescriptorType& descriptor, const SlotType& slot ) { m_observers[ descriptor ].push_back( slot ); } +void EventDispatcher::subscribe( const Event::DescriptorType& descriptor, const std::vector< SlotType >& slots ) +{ + for( auto& slot : slots ) + subscribe( descriptor, slot ); +} + void EventDispatcher::emit( const Event& event ) const { auto type = event.type(); @@ -14,8 +20,8 @@ void EventDispatcher::emit( const Event& event ) const if( m_observers.find( type ) == m_observers.end() ) return; - auto&& observers = m_observers.at( type ); + auto& observers = m_observers.at( type ); - for( auto&& observer : observers ) + for( auto& observer : observers ) observer( event ); } \ No newline at end of file diff --git a/src/common/Event/EventDispatcher.h b/src/common/Event/EventDispatcher.h index b750d00a..cfd81d61 100644 --- a/src/common/Event/EventDispatcher.h +++ b/src/common/Event/EventDispatcher.h @@ -3,6 +3,8 @@ #include "Event.h" #include +#define BIND_EVENT( v1, v2 ) std::bind( v1, v2, _1 ) + namespace Sapphire::Common::EventSystem { @@ -11,7 +13,8 @@ namespace Sapphire::Common::EventSystem public: using SlotType = std::function< void( const Event& ) >; - void subscribe( const Event::DescriptorType& descriptor, SlotType&& slot ); + void subscribe( const Event::DescriptorType& descriptor, const SlotType& slot ); + void subscribe( const Event::DescriptorType& descriptor, const std::vector< SlotType >& slots ); void emit( const Event& event ) const; diff --git a/src/common/Event/Observer.h b/src/common/Event/Observer.h deleted file mode 100644 index 576cbcc4..00000000 --- a/src/common/Event/Observer.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "Event.h" - -namespace Sapphire::Common::EventSystem -{ - class EventObserver - { - public: - virtual void handleEvent( const Event& e ) = 0; - }; -} diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 6c972ad0..5901498f 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -496,7 +496,6 @@ void Player::discover( int16_t mapId, int16_t subId ) offset = 320 + 4 * info->data().DiscoveryIndex; uint16_t index; - uint8_t bitIndex; uint8_t value; Util::valueToFlagByteIndexValue( subId, value, index ); diff --git a/src/world/Event/EventDefinitions/EventDefinitions.h b/src/world/Event/EventDefinitions/EventDefinitions.h index a242151f..fcbb124c 100644 --- a/src/world/Event/EventDefinitions/EventDefinitions.h +++ b/src/world/Event/EventDefinitions/EventDefinitions.h @@ -9,11 +9,9 @@ namespace Sapphire::Common::EventSystem { public: static constexpr DescriptorType descriptor = "LoginEvent"; - virtual DescriptorType type() const { return descriptor; } - - LoginEvent( uint64_t charId ) : characterId( charId ) {}; - virtual ~LoginEvent() = default; + DescriptorType type() const override { return descriptor; } + explicit LoginEvent( uint64_t charId ) : characterId( charId ) {}; uint64_t characterId; }; @@ -22,13 +20,12 @@ namespace Sapphire::Common::EventSystem { public: static constexpr DescriptorType descriptor = "LogoutEvent"; - virtual DescriptorType type() const { return descriptor; } - - LogoutEvent( uint64_t charId ) : characterId( charId ) {}; - virtual ~LogoutEvent() = default; + DescriptorType type() const override { return descriptor; } + LogoutEvent( uint64_t charId, bool disconnect ) : characterId( charId ), isDisconnect( disconnect ) {}; uint64_t characterId; + bool isDisconnect; }; } \ No newline at end of file diff --git a/src/world/Manager/FreeCompanyMgr.cpp b/src/world/Manager/FreeCompanyMgr.cpp index d00b0cbe..b549d5ae 100644 --- a/src/world/Manager/FreeCompanyMgr.cpp +++ b/src/world/Manager/FreeCompanyMgr.cpp @@ -271,6 +271,7 @@ void FreeCompanyMgr::onFcLogin( const Common::EventSystem::Event& e ) void FreeCompanyMgr::onFcLogout( const Common::EventSystem::Event& e ) { + Logger::debug( "{}", __FUNCTION__ ); const auto& logoutEvent = static_cast< const Common::EventSystem::LogoutEvent& >( e ); auto& server = Common::Service< World::WorldServer >::ref(); auto player = server.getPlayer( logoutEvent.characterId ); diff --git a/src/world/Manager/FreeCompanyMgr.h b/src/world/Manager/FreeCompanyMgr.h index 2b499978..4b252dff 100644 --- a/src/world/Manager/FreeCompanyMgr.h +++ b/src/world/Manager/FreeCompanyMgr.h @@ -5,7 +5,6 @@ #include #include "ForwardsZone.h" #include "FreeCompany/FreeCompany.h" -#include #include namespace Sapphire::World::Manager diff --git a/src/world/Manager/PartyMgr.cpp b/src/world/Manager/PartyMgr.cpp index 3365487e..7f6bc51e 100644 --- a/src/world/Manager/PartyMgr.cpp +++ b/src/world/Manager/PartyMgr.cpp @@ -171,15 +171,27 @@ void PartyMgr::onDisband( Entity::Player& disbandingPlayer ) void PartyMgr::onMoveZone( Sapphire::Entity::Player &movingPlayer ) { + if( movingPlayer.getPartyId() == 0 ) + return; auto party = getParty( movingPlayer.getPartyId() ); assert( party ); sendPartyUpdate( *party ); } -void PartyMgr::onMemberDisconnect( Entity::Player& disconnectingPlayer ) +void PartyMgr::onMemberLogout( const Common::EventSystem::Event& e ) { + Logger::debug( "{}", __FUNCTION__ ); + const auto& logoutEvent = dynamic_cast< const Common::EventSystem::LogoutEvent& >( e ); auto& server = Common::Service< World::WorldServer >::ref(); - auto party = getParty( disconnectingPlayer.getPartyId() ); + auto pMember = server.getPlayer( logoutEvent.characterId ); + + if( !pMember ) + return; + + if( pMember->getPartyId() == 0 ) + return; + + auto party = getParty( pMember->getPartyId() ); assert( party ); auto members = getPartyMembers( *party ); auto pLeader = getPartyLeader( *party ); @@ -203,8 +215,8 @@ void PartyMgr::onMemberDisconnect( Entity::Player& disconnectingPlayer ) for( const auto& member : members ) { // TODO: 2nd argument here makes it automatically send passing leadership message - server.queueForPlayer( member->getCharacterId(), { makePcPartyUpdate( disconnectingPlayer, UpdateStatus::OFFLINE_MEMBER, party->PartyCount ), - makeZonePacket< FFXIVIpcUpdateParty >( member->getId() ) } ); + server.queueForPlayer( member->getCharacterId(), { makePcPartyUpdate( *pMember, UpdateStatus::OFFLINE_MEMBER, party->PartyCount ), + makeZonePacket< FFXIVIpcUpdateParty >( member->getId() ) } ); } sendPartyUpdate( *party ); diff --git a/src/world/Manager/PartyMgr.h b/src/world/Manager/PartyMgr.h index 0fe4f7e5..74d07434 100644 --- a/src/world/Manager/PartyMgr.h +++ b/src/world/Manager/PartyMgr.h @@ -7,6 +7,8 @@ #include #include +#include + namespace Sapphire::World::Manager { @@ -56,7 +58,8 @@ namespace Sapphire::World::Manager void onKick( const std::string& kickPlayerName, Entity::Player& leader ); void onChangeLeader( const std::string& newLeaderName, Entity::Player& oldLeader ); - void onMemberDisconnect( Entity::Player& disconnectingPlayer ); + void onMemberLogout( const Common::EventSystem::Event& e ); + void onMemberRejoin( Entity::Player& joiningPlayer ); void onJoinBuddy( Entity::Player& buddyOwner, Party& party ); diff --git a/src/world/Manager/PlayerMgr.cpp b/src/world/Manager/PlayerMgr.cpp index 4f9e8378..f692ac61 100644 --- a/src/world/Manager/PlayerMgr.cpp +++ b/src/world/Manager/PlayerMgr.cpp @@ -355,13 +355,9 @@ void PlayerMgr::onLogin( const Common::EventSystem::Event& e ) void PlayerMgr::onLogout( const Common::EventSystem::Event& e ) { + Logger::debug( "{}", __FUNCTION__ ); const auto& logoutEvent = dynamic_cast< const Common::EventSystem::LogoutEvent& >( e ); auto player = *server().getPlayer( logoutEvent.characterId ); - - auto& partyMgr = Common::Service< World::Manager::PartyMgr >::ref(); - // send updates to mgrs - if( player.getPartyId() != 0 ) - partyMgr.onMemberDisconnect( player ); } void PlayerMgr::onDeath( Entity::Player& player ) @@ -461,11 +457,7 @@ void PlayerMgr::onMoveZone( Sapphire::Entity::Player& player ) onGrandCompanyChanged( player ); } - if( player.getPartyId() != 0 ) - { - partyMgr.onMoveZone( player ); - } - + partyMgr.onMoveZone( player ); } void PlayerMgr::onUpdate( Entity::Player& player, uint64_t tickCount ) diff --git a/src/world/WorldServer.cpp b/src/world/WorldServer.cpp index d0bc761c..f2a47ca5 100644 --- a/src/world/WorldServer.cpp +++ b/src/world/WorldServer.cpp @@ -63,6 +63,7 @@ using namespace Sapphire::World; using namespace Sapphire::World::Manager; +using namespace Sapphire::Common::EventSystem; WorldServer::WorldServer( const std::string& configName ) : m_configName( configName ), @@ -312,16 +313,7 @@ void WorldServer::run( int32_t argc, char* argv[] ) Common::Service< ContentFinder >::set( contentFinder ); Common::Service< Manager::TaskMgr >::set( taskMgr ); - using namespace Common; - using namespace Manager; - using namespace std::placeholders; - - dispatcher->subscribe( EventSystem::LoginEvent::descriptor, std::bind( &PlayerMgr::onLogin, pPlayerMgr, _1 ) ); - dispatcher->subscribe( EventSystem::LoginEvent::descriptor, std::bind( &FreeCompanyMgr::onFcLogin, pFcMgr, _1 ) ); - - dispatcher->subscribe( EventSystem::LogoutEvent::descriptor, std::bind( &PlayerMgr::onLogout, pPlayerMgr, _1 ) ); - dispatcher->subscribe( EventSystem::LogoutEvent::descriptor, std::bind( &FreeCompanyMgr::onFcLogout, pFcMgr, _1 ) ); - + setupEvents(); Logger::info( "World server running on {0}:{1}", m_ip, m_port ); @@ -334,6 +326,35 @@ void WorldServer::run( int32_t argc, char* argv[] ) } +void WorldServer::setupEvents() +{ + Logger::info( "Setting up events" ); + + auto& playerMgr = Common::Service< Manager::PlayerMgr >::ref(); + auto& partyMgr = Common::Service< Manager::PartyMgr >::ref(); + auto& fcMgr = Common::Service< Manager::FreeCompanyMgr >::ref(); + + auto& dispatcher = Common::Service< EventDispatcher >::ref(); + + using namespace Common; + using namespace Manager; + using namespace std::placeholders; + + dispatcher.subscribe( LoginEvent::descriptor, + { + BIND_EVENT( &PlayerMgr::onLogin, &playerMgr ), + BIND_EVENT( &FreeCompanyMgr::onFcLogin, &fcMgr ) + } ); + + dispatcher.subscribe( LogoutEvent::descriptor, + { + BIND_EVENT( &PlayerMgr::onLogout, &playerMgr ), + BIND_EVENT( &FreeCompanyMgr::onFcLogout, &fcMgr ), + BIND_EVENT( &PartyMgr::onMemberLogout, &partyMgr ) + } ); + +} + uint16_t WorldServer::getWorldId() const { return m_worldId; @@ -419,7 +440,7 @@ void WorldServer::updateSessions( uint32_t currTime ) player.addOnlineStatus( Common::OnlineStatus::Offline ); auto dispatcher = Common::Service< Common::EventSystem::EventDispatcher >::ref(); - dispatcher.emit( Common::EventSystem::LogoutEvent( player.getCharacterId() ) ); + dispatcher.emit( Common::EventSystem::LogoutEvent( player.getCharacterId(), !player.isMarkedForRemoval() ) ); Logger::info( "[{0}] Session removal", session->getId() ); session->close(); sessionRemovalQueue.push( session->getId() ); diff --git a/src/world/WorldServer.h b/src/world/WorldServer.h index 90a30c15..0e8922cc 100644 --- a/src/world/WorldServer.h +++ b/src/world/WorldServer.h @@ -47,6 +47,8 @@ namespace Sapphire::World void printBanner() const; + void setupEvents(); + bool loadSettings( int32_t argc, char* argv[] ); std::string getPlayerNameFromDb( uint64_t characterId, bool forceDbLoad = false );