1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 14:57:44 +00:00

Basic implementation of an eventsystem.

This commit is contained in:
Mordred 2023-02-21 14:30:41 +01:00
parent d34bddc6ae
commit 48c2825df8
14 changed files with 148 additions and 22 deletions

View file

@ -7,6 +7,7 @@ file(GLOB UTILS_SOURCE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/Crypt/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Crypt/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Database/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Database/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Exd/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Exd/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Event/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Logging/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Logging/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Network/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Network/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Network/PacketDef/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Network/PacketDef/*.cpp"

14
src/common/Event/Event.h Normal file
View file

@ -0,0 +1,14 @@
#pragma once
#include <typeinfo>
namespace Sapphire::Common::EventSystem
{
class Event
{
public:
virtual~ Event() = default;
using DescriptorType = const char*;
virtual DescriptorType type() const = 0;
};
}

View file

@ -0,0 +1,21 @@
#include "EventDispatcher.h"
using namespace Sapphire::Common::EventSystem;
void EventDispatcher::subscribe( const Event::DescriptorType& descriptor, SlotType&& slot )
{
m_observers[ descriptor ].push_back( slot );
}
void EventDispatcher::emit( const Event& event ) const
{
auto type = event.type();
if( m_observers.find( type ) == m_observers.end() )
return;
auto&& observers = m_observers.at( type );
for( auto&& observer : observers )
observer( event );
}

View file

@ -0,0 +1,24 @@
#pragma once
#include <functional>
#include "Event.h"
#include <unordered_map>
namespace Sapphire::Common::EventSystem
{
class EventDispatcher
{
public:
using SlotType = std::function< void( const Event& ) >;
void subscribe( const Event::DescriptorType& descriptor, SlotType&& slot );
void emit( const Event& event ) const;
private:
std::unordered_map< Event::DescriptorType, std::vector< SlotType > > m_observers;
};
}

View file

@ -0,0 +1,11 @@
#pragma once
#include "Event.h"
namespace Sapphire::Common::EventSystem
{
class EventObserver
{
public:
virtual void handleEvent( const Event& e ) = 0;
};
}

View file

@ -477,20 +477,16 @@ Player::Discovery& Player::getDiscoveryBitmask()
return m_discovery; return m_discovery;
} }
void Player::discover( int16_t map_id, int16_t sub_id ) void Player::discover( int16_t mapId, int16_t subId )
{ {
// map.exd field 12 -> index in one of the two discovery sections, if field 15 is false, need to use 2nd section
// section 1 starts at 0 - 2 bytes each
// section to starts at 320 - 4 bytes long
auto& exdData = Common::Service< Data::ExdData >::ref(); auto& exdData = Common::Service< Data::ExdData >::ref();
int32_t offset; int32_t offset;
auto info = exdData.getRow< Excel::Map >( map_id ); auto info = exdData.getRow< Excel::Map >( mapId );
if( !info ) if( !info )
{ {
PlayerMgr::sendDebug( *this, "discover(): Could not obtain map data for map_id == {0}", map_id ); PlayerMgr::sendDebug( *this, "discover(): Could not obtain map data for map_id == {0}", mapId );
return; return;
} }
@ -499,15 +495,15 @@ void Player::discover( int16_t map_id, int16_t sub_id )
else else
offset = 320 + 4 * info->data().DiscoveryIndex; offset = 320 + 4 * info->data().DiscoveryIndex;
int32_t index = offset + sub_id / 8; uint16_t index;
uint8_t bitIndex = sub_id % 8; uint8_t bitIndex;
uint8_t value;
uint8_t value = 1 << bitIndex; Util::valueToFlagByteIndexValue( subId, value, index );
m_discovery[ index ] |= value; m_discovery[ index + offset ] |= value;
uint16_t level = getLevel(); uint16_t level = getLevel();
uint32_t exp = ( exdData.getRow< Excel::ParamGrow >( level )->data().NextExp * 5 / 100 ); uint32_t exp = ( exdData.getRow< Excel::ParamGrow >( level )->data().NextExp * 5 / 100 );
gainExp( exp ); gainExp( exp );
@ -517,8 +513,7 @@ void Player::discover( int16_t map_id, int16_t sub_id )
uint32_t discoveredAreas; uint32_t discoveredAreas;
if( info->data().IsUint16Discovery ) if( info->data().IsUint16Discovery )
{ {
discoveredAreas = ( m_discovery[ offset + 1 ] << 8 ) | discoveredAreas = ( m_discovery[ offset + 1 ] << 8 ) | m_discovery[ offset ];
m_discovery[ offset ];
} }
else else
{ {

View file

@ -438,7 +438,7 @@ namespace Sapphire::Entity
uint8_t getHomepoint() const; uint8_t getHomepoint() const;
/*! discover subarea subid fo map map_id, also send udpate packet */ /*! discover subarea subid fo map map_id, also send udpate packet */
void discover( int16_t map_id, int16_t sub_id ); void discover( int16_t mapId, int16_t subId );
/*! return a reference to the discovery bitmask array */ /*! return a reference to the discovery bitmask array */
Discovery& getDiscoveryBitmask(); Discovery& getDiscoveryBitmask();

View file

@ -0,0 +1,21 @@
#pragma once
#include <Event/Event.h>
namespace Sapphire::Common::EventSystem
{
class LoginEvent : public Event
{
public:
static constexpr DescriptorType descriptor = "LoginEvent";
virtual DescriptorType type() const { return descriptor; }
LoginEvent( uint64_t charId ) : characterId( charId ) {};
virtual ~LoginEvent() = default;
uint64_t characterId;
};
}

View file

@ -22,12 +22,23 @@
#include <Network/PacketDef/ClientIpcs.h> #include <Network/PacketDef/ClientIpcs.h>
#include "Session.h" #include "Session.h"
#include <Event/EventDefinitions/EventDefinitions.h>
using namespace Sapphire; using namespace Sapphire;
using namespace Sapphire::Network::Packets; using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server; using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::World::Manager; using namespace Sapphire::World::Manager;
void FreeCompanyMgr::handleEvent( const Common::EventSystem::Event& e )
{
if( e.type() == Common::EventSystem::LoginEvent::descriptor )
{
const Common::EventSystem::LoginEvent& loginEvent = static_cast< const Common::EventSystem::LoginEvent& >( e );
onFcLogin( loginEvent.characterId );
}
}
bool FreeCompanyMgr::loadFreeCompanies() bool FreeCompanyMgr::loadFreeCompanies()
{ {
auto& chatChannelMgr = Common::Service< Manager::ChatChannelMgr >::ref(); auto& chatChannelMgr = Common::Service< Manager::ChatChannelMgr >::ref();

View file

@ -5,13 +5,12 @@
#include <vector> #include <vector>
#include "ForwardsZone.h" #include "ForwardsZone.h"
#include "FreeCompany/FreeCompany.h" #include "FreeCompany/FreeCompany.h"
#include <Event/Observer.h>
namespace Sapphire::World::Manager namespace Sapphire::World::Manager
{ {
class FreeCompanyMgr : public Common::EventSystem::EventObserver
class FreeCompanyMgr
{ {
private: private:
std::unordered_map< uint64_t, FreeCompanyPtr > m_fcIdMap; std::unordered_map< uint64_t, FreeCompanyPtr > m_fcIdMap;
@ -27,6 +26,8 @@ namespace Sapphire::World::Manager
FreeCompanyMgr() = default; FreeCompanyMgr() = default;
void handleEvent( const Common::EventSystem::Event& e );
// initialize all fcs from db to memory // initialize all fcs from db to memory
bool loadFreeCompanies(); bool loadFreeCompanies();
void writeFreeCompany( uint64_t fcId ); void writeFreeCompany( uint64_t fcId );

View file

@ -41,12 +41,24 @@
#include <Util/UtilMath.h> #include <Util/UtilMath.h>
#include <Event/EventDefinitions/EventDefinitions.h>
using namespace Sapphire; using namespace Sapphire;
using namespace Sapphire::World::Manager; using namespace Sapphire::World::Manager;
using namespace Sapphire::Network::Packets; using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server; using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::Network::ActorControl; using namespace Sapphire::Network::ActorControl;
void PlayerMgr::handleEvent( const Common::EventSystem::Event& e )
{
if( e.type() == Common::EventSystem::LoginEvent::descriptor )
{
const Common::EventSystem::LoginEvent& loginEvent = static_cast< const Common::EventSystem::LoginEvent& >( e );
auto player = server().getPlayer( loginEvent.characterId );
onLogin( *player );
}
}
void PlayerMgr::onOnlineStatusChanged( Entity::Player& player, bool updateProfile ) void PlayerMgr::onOnlineStatusChanged( Entity::Player& player, bool updateProfile )
{ {

View file

@ -3,14 +3,17 @@
#include "ForwardsZone.h" #include "ForwardsZone.h"
#include <spdlog/fmt/fmt.h> #include <spdlog/fmt/fmt.h>
#include "MgrUtil.h" #include "MgrUtil.h"
#include <Event/Observer.h>
namespace Sapphire::World::Manager namespace Sapphire::World::Manager
{ {
class PlayerMgr class PlayerMgr : public Common::EventSystem::EventObserver
{ {
public: public:
PlayerMgr() = default; PlayerMgr() = default;
void handleEvent( const Common::EventSystem::Event& e );
void onOnlineStatusChanged( Sapphire::Entity::Player& player, bool updateProfile = true ); void onOnlineStatusChanged( Sapphire::Entity::Player& player, bool updateProfile = true );
void onEquipDisplayFlagsChanged( Sapphire::Entity::Player& player ); void onEquipDisplayFlagsChanged( Sapphire::Entity::Player& player );

View file

@ -64,6 +64,9 @@
#include "WorldServer.h" #include "WorldServer.h"
#include "Forwards.h" #include "Forwards.h"
#include <Event/EventDispatcher.h>
#include <Event/EventDefinitions/EventDefinitions.h>
using namespace Sapphire::Common; using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets; using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server; using namespace Sapphire::Network::Packets::WorldPackets::Server;
@ -370,7 +373,7 @@ void Sapphire::Network::GameConnection::syncHandler( const Packets::FFXIVARR_PAC
void Sapphire::Network::GameConnection::setLanguageHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) void Sapphire::Network::GameConnection::setLanguageHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
{ {
auto& playerMgr = Common::Service< World::Manager::PlayerMgr >::ref(); auto& playerMgr = Common::Service< World::Manager::PlayerMgr >::ref();
auto& eventDispatcher = Common::Service< Common::EventSystem::EventDispatcher >::ref();
auto& teriMgr = Common::Service< TerritoryMgr >::ref(); auto& teriMgr = Common::Service< TerritoryMgr >::ref();
auto pCurrentZone = teriMgr.getTerritoryByGuId( player.getTerritoryId() ); auto pCurrentZone = teriMgr.getTerritoryByGuId( player.getTerritoryId() );
@ -382,8 +385,9 @@ void Sapphire::Network::GameConnection::setLanguageHandler( const Packets::FFXIV
// if this is a login event // if this is a login event
if( player.isLogin() ) if( player.isLogin() )
{ {
eventDispatcher.emit( EventSystem::LoginEvent( player.getCharacterId() ) );
// fire the onLogin Event // fire the onLogin Event
playerMgr.onLogin( player ); //playerMgr.onLogin( player );
} }
// spawn the player for himself // spawn the player for himself

View file

@ -54,6 +54,9 @@
#include "Manager/FreeCompanyMgr.h" #include "Manager/FreeCompanyMgr.h"
#include "Manager/MapMgr.h" #include "Manager/MapMgr.h"
#include <Event/EventDispatcher.h>
#include <Event/EventDefinitions/EventDefinitions.h>
#include "ContentFinder/ContentFinder.h" #include "ContentFinder/ContentFinder.h"
#include "Territory/InstanceObjectCache.h" #include "Territory/InstanceObjectCache.h"
@ -181,8 +184,11 @@ void WorldServer::run( int32_t argc, char* argv[] )
auto pChatChannelMgr = std::make_shared< Manager::ChatChannelMgr >(); auto pChatChannelMgr = std::make_shared< Manager::ChatChannelMgr >();
Common::Service< Manager::ChatChannelMgr >::set( pChatChannelMgr ); Common::Service< Manager::ChatChannelMgr >::set( pChatChannelMgr );
auto pLsMgr = std::make_shared< Manager::LinkshellMgr >(); auto dispatcher = std::make_shared< Common::EventSystem::EventDispatcher >();
Logger::info( "EventDispatcher: Setup of event dispatcher" );
Common::Service< Common::EventSystem::EventDispatcher >::set( dispatcher );
auto pLsMgr = std::make_shared< Manager::LinkshellMgr >();
Logger::info( "LinkshellMgr: Caching linkshells" ); Logger::info( "LinkshellMgr: Caching linkshells" );
if( !pLsMgr->loadLinkshells() ) if( !pLsMgr->loadLinkshells() )
{ {
@ -306,6 +312,8 @@ void WorldServer::run( int32_t argc, char* argv[] )
Common::Service< ContentFinder >::set( contentFinder ); Common::Service< ContentFinder >::set( contentFinder );
Common::Service< Manager::TaskMgr >::set( taskMgr ); Common::Service< Manager::TaskMgr >::set( taskMgr );
dispatcher->subscribe( Common::EventSystem::LoginEvent::descriptor, std::bind( &Manager::PlayerMgr::handleEvent, pPlayerMgr, std::placeholders::_1 ) );
Logger::info( "World server running on {0}:{1}", m_ip, m_port ); Logger::info( "World server running on {0}:{1}", m_ip, m_port );