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}/Database/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Exd/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Event/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Logging/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Network/*.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;
}
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();
int32_t offset;
auto info = exdData.getRow< Excel::Map >( map_id );
auto info = exdData.getRow< Excel::Map >( mapId );
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;
}
@ -499,15 +495,15 @@ void Player::discover( int16_t map_id, int16_t sub_id )
else
offset = 320 + 4 * info->data().DiscoveryIndex;
int32_t index = offset + sub_id / 8;
uint8_t bitIndex = sub_id % 8;
uint16_t index;
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();
uint32_t exp = ( exdData.getRow< Excel::ParamGrow >( level )->data().NextExp * 5 / 100 );
gainExp( exp );
@ -517,8 +513,7 @@ void Player::discover( int16_t map_id, int16_t sub_id )
uint32_t discoveredAreas;
if( info->data().IsUint16Discovery )
{
discoveredAreas = ( m_discovery[ offset + 1 ] << 8 ) |
m_discovery[ offset ];
discoveredAreas = ( m_discovery[ offset + 1 ] << 8 ) | m_discovery[ offset ];
}
else
{

View file

@ -438,7 +438,7 @@ namespace Sapphire::Entity
uint8_t getHomepoint() const;
/*! 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 */
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 "Session.h"
#include <Event/EventDefinitions/EventDefinitions.h>
using namespace Sapphire;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
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()
{
auto& chatChannelMgr = Common::Service< Manager::ChatChannelMgr >::ref();

View file

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

View file

@ -41,12 +41,24 @@
#include <Util/UtilMath.h>
#include <Event/EventDefinitions/EventDefinitions.h>
using namespace Sapphire;
using namespace Sapphire::World::Manager;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
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 )
{

View file

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

View file

@ -64,6 +64,9 @@
#include "WorldServer.h"
#include "Forwards.h"
#include <Event/EventDispatcher.h>
#include <Event/EventDefinitions/EventDefinitions.h>
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
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 )
{
auto& playerMgr = Common::Service< World::Manager::PlayerMgr >::ref();
auto& eventDispatcher = Common::Service< Common::EventSystem::EventDispatcher >::ref();
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
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( player.isLogin() )
{
eventDispatcher.emit( EventSystem::LoginEvent( player.getCharacterId() ) );
// fire the onLogin Event
playerMgr.onLogin( player );
//playerMgr.onLogin( player );
}
// spawn the player for himself

View file

@ -54,6 +54,9 @@
#include "Manager/FreeCompanyMgr.h"
#include "Manager/MapMgr.h"
#include <Event/EventDispatcher.h>
#include <Event/EventDefinitions/EventDefinitions.h>
#include "ContentFinder/ContentFinder.h"
#include "Territory/InstanceObjectCache.h"
@ -181,8 +184,11 @@ void WorldServer::run( int32_t argc, char* argv[] )
auto pChatChannelMgr = std::make_shared< Manager::ChatChannelMgr >();
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" );
if( !pLsMgr->loadLinkshells() )
{
@ -306,6 +312,8 @@ void WorldServer::run( int32_t argc, char* argv[] )
Common::Service< ContentFinder >::set( contentFinder );
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 );