mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-25 22:17:45 +00:00
Linkshell groundwork, events can now be implemented more easy
This commit is contained in:
parent
7af6eda26e
commit
e385522e52
12 changed files with 148 additions and 25 deletions
|
@ -259,13 +259,13 @@ struct FFXIVIpcYieldEventSceneString8 :
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct YieldEventSceneString16 :
|
struct FFXIVIpcYieldEventSceneString16 :
|
||||||
FFXIVIpcBasePacket< YieldEventSceneString16 >,
|
FFXIVIpcBasePacket< YieldEventSceneString16 >,
|
||||||
YieldEventSceneStringN< 16 >
|
YieldEventSceneStringN< 16 >
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct YieldEventSceneString32 :
|
struct FFXIVIpcYieldEventSceneString32 :
|
||||||
FFXIVIpcBasePacket< YieldEventSceneString32 >,
|
FFXIVIpcBasePacket< YieldEventSceneString32 >,
|
||||||
YieldEventSceneStringN< 32 >
|
YieldEventSceneStringN< 32 >
|
||||||
{
|
{
|
||||||
|
|
|
@ -1494,17 +1494,13 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
|
||||||
* Structural representation of the packet sent by the server
|
* Structural representation of the packet sent by the server
|
||||||
* to respond to a linkshell creation event
|
* to respond to a linkshell creation event
|
||||||
*/
|
*/
|
||||||
struct FFXIVIpcEventLinkshell : FFXIVIpcBasePacket< ResumeEventScene2 >
|
struct FFXIVIpcResumeEventScene2 : FFXIVIpcBasePacket< ResumeEventScene2 >
|
||||||
{
|
{
|
||||||
uint32_t eventId;
|
uint32_t handlerId;
|
||||||
uint8_t scene;
|
uint16_t sceneId;
|
||||||
uint8_t param1;
|
uint8_t resumeId;
|
||||||
uint8_t param2;
|
uint8_t numOfArgs;
|
||||||
uint8_t param3;
|
uint32_t args[4];
|
||||||
uint32_t unknown1;
|
|
||||||
uint32_t unknown2;
|
|
||||||
uint32_t unknown3;
|
|
||||||
uint32_t unknown4;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2165,5 +2161,4 @@ struct FFXIVIpcEorzeaTimeOffset : FFXIVIpcBasePacket< TimeOffset >
|
||||||
{
|
{
|
||||||
ZoneProtoDownMemberPos Member[8];
|
ZoneProtoDownMemberPos Member[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace Sapphire::Data
|
||||||
namespace Sapphire::World::Manager
|
namespace Sapphire::World::Manager
|
||||||
{
|
{
|
||||||
class TerritoryMgr;
|
class TerritoryMgr;
|
||||||
|
class LinkshellMgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" EXPORT void win32initExd( std::shared_ptr< Sapphire::Data::ExdData > exdData )
|
extern "C" EXPORT void win32initExd( std::shared_ptr< Sapphire::Data::ExdData > exdData )
|
||||||
|
@ -33,6 +34,10 @@ extern "C" EXPORT void win32initTeri( std::shared_ptr< Sapphire::World::Manager:
|
||||||
{
|
{
|
||||||
Sapphire::Common::Service< Sapphire::World::Manager::TerritoryMgr >::set( teriMgr );
|
Sapphire::Common::Service< Sapphire::World::Manager::TerritoryMgr >::set( teriMgr );
|
||||||
}
|
}
|
||||||
|
extern "C" EXPORT void win32initLinkshell( std::shared_ptr< Sapphire::World::Manager::LinkshellMgr > lsMgr )
|
||||||
|
{
|
||||||
|
Sapphire::Common::Service< Sapphire::World::Manager::LinkshellMgr >::set( lsMgr );
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts()
|
extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts()
|
||||||
|
|
|
@ -42,7 +42,13 @@ public:
|
||||||
// create linkshell
|
// create linkshell
|
||||||
void Scene00002( Entity::Player& player )
|
void Scene00002( Entity::Player& player )
|
||||||
{
|
{
|
||||||
eventMgr().playScene( player, getId(), 2, 0 );
|
auto callback = [ this ]( Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
linkshellMgr().createLinkshell( result.resultString, player );
|
||||||
|
eventMgr().resumeScene( player, result.eventId, result.sceneId, { 0x15a } );
|
||||||
|
};
|
||||||
|
|
||||||
|
eventMgr().playScene( player, getId(), 2, 0, callback );
|
||||||
}
|
}
|
||||||
|
|
||||||
// rename linkshell
|
// rename linkshell
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace Sapphire::Event
|
||||||
uint8_t errorCode;
|
uint8_t errorCode;
|
||||||
uint8_t numOfResults;
|
uint8_t numOfResults;
|
||||||
std::vector< uint32_t > results;
|
std::vector< uint32_t > results;
|
||||||
|
std::string resultString;
|
||||||
|
|
||||||
uint32_t getResult( uint32_t index ) const;
|
uint32_t getResult( uint32_t index ) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -314,6 +314,40 @@ void Sapphire::World::Manager::EventMgr::handleReturnEventScene( Entity::Player&
|
||||||
checkEvent( player, eventId );
|
checkEvent( player, eventId );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventMgr::handleReturnStringEventScene( Entity::Player& player, uint32_t eventId, uint16_t sceneId, const std::string& resultString )
|
||||||
|
{
|
||||||
|
std::string eventName = getEventName( eventId );
|
||||||
|
|
||||||
|
PlayerMgr::sendDebug( player, "eventId: {0} ({0:08X}) scene: {1}, string: {2} ", eventId, sceneId, resultString );
|
||||||
|
|
||||||
|
auto eventType = static_cast< uint16_t >( eventId >> 16 );
|
||||||
|
auto pEvent = player.getEvent( eventId );
|
||||||
|
|
||||||
|
if( pEvent )
|
||||||
|
{
|
||||||
|
pEvent->setPlayedScene( false );
|
||||||
|
// try to retrieve a stored callback
|
||||||
|
// if there is one, proceed to call it
|
||||||
|
Event::SceneResult result;
|
||||||
|
result.actorId = pEvent->getActorId();
|
||||||
|
result.eventId = eventId;
|
||||||
|
result.sceneId = sceneId;
|
||||||
|
result.resultString = resultString;
|
||||||
|
|
||||||
|
auto eventCallback = pEvent->getEventReturnCallback();
|
||||||
|
if( eventCallback )
|
||||||
|
{
|
||||||
|
eventCallback( player, result );
|
||||||
|
}
|
||||||
|
|
||||||
|
// we might have a scene chain callback instead so check for that too
|
||||||
|
else if( auto chainCallback = pEvent->getSceneChainCallback() )
|
||||||
|
chainCallback( player );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void EventMgr::checkEvent( Sapphire::Entity::Player &player, uint32_t eventId )
|
void EventMgr::checkEvent( Sapphire::Entity::Player &player, uint32_t eventId )
|
||||||
{
|
{
|
||||||
auto pEvent = player.getEvent( eventId );
|
auto pEvent = player.getEvent( eventId );
|
||||||
|
@ -508,6 +542,25 @@ void EventMgr::playScene( Entity::Player& player, uint32_t eventId, uint32_t sce
|
||||||
sendEventPlay( player, eventId, scene, flags );
|
sendEventPlay( player, eventId, scene, flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventMgr::resumeScene( Entity::Player& player, uint32_t eventId, uint32_t scene, std::vector< uint32_t > values )
|
||||||
|
{
|
||||||
|
auto pEvent = bootstrapSceneEvent( player, eventId, 0 );
|
||||||
|
if( !pEvent )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto linkshellEvent = makeZonePacket< FFXIVIpcResumeEventScene2 >( player.getId() );
|
||||||
|
linkshellEvent->data().handlerId = eventId;
|
||||||
|
linkshellEvent->data().sceneId = static_cast< uint8_t >( scene );
|
||||||
|
linkshellEvent->data().numOfArgs = values.size();
|
||||||
|
int i = 0;
|
||||||
|
for( auto& val : values )
|
||||||
|
{
|
||||||
|
linkshellEvent->data().args[ i++ ] = val;
|
||||||
|
}
|
||||||
|
auto& server = Common::Service< World::WorldServer >::ref();
|
||||||
|
server.queueForPlayer( player.getCharacterId(), linkshellEvent );
|
||||||
|
}
|
||||||
|
|
||||||
void EventMgr::playScene( Entity::Player& player, uint32_t eventId, uint32_t scene, uint32_t flags, Event::EventHandler::SceneReturnCallback eventCallback )
|
void EventMgr::playScene( Entity::Player& player, uint32_t eventId, uint32_t scene, uint32_t flags, Event::EventHandler::SceneReturnCallback eventCallback )
|
||||||
{
|
{
|
||||||
auto pEvent = bootstrapSceneEvent( player, eventId, flags );
|
auto pEvent = bootstrapSceneEvent( player, eventId, flags );
|
||||||
|
|
|
@ -21,6 +21,8 @@ namespace Sapphire::World::Manager
|
||||||
void handleReturnEventScene( Entity::Player& player, uint32_t eventId, uint16_t sceneId, uint8_t errorCode,
|
void handleReturnEventScene( Entity::Player& player, uint32_t eventId, uint16_t sceneId, uint8_t errorCode,
|
||||||
uint8_t numOfResults, const std::vector< uint32_t >& results );
|
uint8_t numOfResults, const std::vector< uint32_t >& results );
|
||||||
|
|
||||||
|
void handleReturnStringEventScene( Entity::Player& player, uint32_t eventId, uint16_t sceneId, const std::string& resultString );
|
||||||
|
|
||||||
|
|
||||||
void checkEvent( Entity::Player& player, uint32_t eventId );
|
void checkEvent( Entity::Player& player, uint32_t eventId );
|
||||||
void eventFinish( Entity::Player& player, uint32_t eventId, uint32_t freePlayer );
|
void eventFinish( Entity::Player& player, uint32_t eventId, uint32_t freePlayer );
|
||||||
|
@ -38,6 +40,9 @@ namespace Sapphire::World::Manager
|
||||||
void playScene( Entity::Player& player, uint32_t eventId, uint32_t scene, uint32_t flags, std::vector< uint32_t > values,
|
void playScene( Entity::Player& player, uint32_t eventId, uint32_t scene, uint32_t flags, std::vector< uint32_t > values,
|
||||||
Event::EventHandler::SceneReturnCallback eventReturnCallback = nullptr );
|
Event::EventHandler::SceneReturnCallback eventReturnCallback = nullptr );
|
||||||
|
|
||||||
|
/*! resume a subevent */
|
||||||
|
void resumeScene( Entity::Player& player, uint32_t eventId, uint32_t scene, std::vector< uint32_t > values );
|
||||||
|
|
||||||
/*! play a subevent */
|
/*! play a subevent */
|
||||||
void playScene( Entity::Player& player, uint32_t eventId, uint32_t scene, uint32_t flags,
|
void playScene( Entity::Player& player, uint32_t eventId, uint32_t scene, uint32_t flags,
|
||||||
Event::EventHandler::SceneReturnCallback eventReturnCallback = nullptr );
|
Event::EventHandler::SceneReturnCallback eventReturnCallback = nullptr );
|
||||||
|
|
|
@ -107,9 +107,9 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
||||||
|
|
||||||
setZoneHandler( StartUIEvent, "StartUIEvent", &GameConnection::startUiEvent );
|
setZoneHandler( StartUIEvent, "StartUIEvent", &GameConnection::startUiEvent );
|
||||||
|
|
||||||
setZoneHandler( YieldEventSceneString8, "YieldEventSceneString8", &GameConnection::eventHandlerLinkshell );
|
setZoneHandler( YieldEventSceneString8, "YieldEventSceneString8", &GameConnection::yieldEventString );
|
||||||
|
setZoneHandler( YieldEventSceneString16, "YieldEventSceneString16", &GameConnection::yieldEventString );
|
||||||
setZoneHandler( YieldEventSceneString16, "YieldEventSceneString16", &GameConnection::eventHandlerLinkshell );
|
setZoneHandler( YieldEventSceneString32, "YieldEventSceneString32", &GameConnection::yieldEventString );
|
||||||
|
|
||||||
setZoneHandler( RequestPenalties, "RequestPenalties", &GameConnection::cfRequestPenalties );
|
setZoneHandler( RequestPenalties, "RequestPenalties", &GameConnection::cfRequestPenalties );
|
||||||
setZoneHandler( FindContent, "FindContent", &GameConnection::findContent );
|
setZoneHandler( FindContent, "FindContent", &GameConnection::findContent );
|
||||||
|
|
|
@ -160,6 +160,8 @@ namespace Sapphire::Network
|
||||||
|
|
||||||
DECLARE_HANDLER( eventHandlerLinkshell );
|
DECLARE_HANDLER( eventHandlerLinkshell );
|
||||||
|
|
||||||
|
DECLARE_HANDLER( yieldEventString );
|
||||||
|
|
||||||
DECLARE_HANDLER( logoutHandler );
|
DECLARE_HANDLER( logoutHandler );
|
||||||
|
|
||||||
DECLARE_HANDLER( cfRequestPenalties );
|
DECLARE_HANDLER( cfRequestPenalties );
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Territory/QuestBattle.h"
|
#include "Territory/QuestBattle.h"
|
||||||
|
|
||||||
#include "Session.h"
|
#include "Session.h"
|
||||||
|
#include <Network/PacketDef/ClientIpcs.h>
|
||||||
|
|
||||||
using namespace Sapphire::Common;
|
using namespace Sapphire::Common;
|
||||||
using namespace Sapphire::Network::Packets;
|
using namespace Sapphire::Network::Packets;
|
||||||
|
@ -291,15 +292,51 @@ void Sapphire::Network::GameConnection::eventHandlerLinkshell( const Packets::FF
|
||||||
auto& server = Common::Service< World::WorldServer >::ref();
|
auto& server = Common::Service< World::WorldServer >::ref();
|
||||||
const auto packet = ZoneChannelPacket< FFXIVIpcYieldEventSceneString8 >( inPacket );
|
const auto packet = ZoneChannelPacket< FFXIVIpcYieldEventSceneString8 >( inPacket );
|
||||||
|
|
||||||
auto linkshellEvent = makeZonePacket< FFXIVIpcEventLinkshell >( player.getId() );
|
auto linkshellEvent = makeZonePacket< FFXIVIpcResumeEventScene2 >( player.getId() );
|
||||||
linkshellEvent->data().eventId = packet.data().handlerId;
|
linkshellEvent->data().handlerId = packet.data().handlerId;
|
||||||
linkshellEvent->data().scene = static_cast< uint8_t >( packet.data().sceneId );
|
linkshellEvent->data().sceneId = static_cast< uint8_t >( packet.data().sceneId );
|
||||||
linkshellEvent->data().param3 = 1;
|
linkshellEvent->data().numOfArgs = 1;
|
||||||
linkshellEvent->data().unknown1 = 0x15a;
|
linkshellEvent->data().args[ 0 ] = 0x15a;
|
||||||
server.queueForPlayer( player.getCharacterId(), linkshellEvent );
|
server.queueForPlayer( player.getCharacterId(), linkshellEvent );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sapphire::Network::GameConnection::yieldEventString( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||||
|
{
|
||||||
|
auto& server = Common::Service< World::WorldServer >::ref();
|
||||||
|
auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref();
|
||||||
|
|
||||||
|
std::string inString;
|
||||||
|
|
||||||
|
uint16_t type = *( ( uint16_t* ) ( &inPacket.data[ 2 ] ) );
|
||||||
|
switch( type )
|
||||||
|
{
|
||||||
|
case Packets::WorldPackets::Client::ClientZoneIpcType::YieldEventSceneString8:
|
||||||
|
{
|
||||||
|
const auto packet = ZoneChannelPacket< FFXIVIpcYieldEventSceneString8 >( inPacket );
|
||||||
|
inString = std::string( packet.data().result );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Packets::WorldPackets::Client::ClientZoneIpcType::YieldEventSceneString16:
|
||||||
|
{
|
||||||
|
const auto packet = ZoneChannelPacket< FFXIVIpcYieldEventSceneString16 >( inPacket );
|
||||||
|
inString = std::string( packet.data().result );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Packets::WorldPackets::Client::ClientZoneIpcType::YieldEventSceneString32:
|
||||||
|
{
|
||||||
|
const auto packet = ZoneChannelPacket< FFXIVIpcYieldEventSceneString32 >( inPacket );
|
||||||
|
inString = std::string( packet.data().result );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto packet = ZoneChannelPacket< FFXIVIpcYieldEventSceneString8 >( inPacket );
|
||||||
|
auto& data = packet.data();
|
||||||
|
eventMgr.handleReturnStringEventScene( player, data.handlerId, data.sceneId, inString );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Sapphire::Network::GameConnection::startUiEvent( const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
void Sapphire::Network::GameConnection::startUiEvent( const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||||
Entity::Player& player )
|
Entity::Player& player )
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "ForwardsZone.h"
|
#include "ForwardsZone.h"
|
||||||
#include "Event/EventHandler.h"
|
#include "Event/EventHandler.h"
|
||||||
#include "Manager/EventMgr.h"
|
#include "Manager/EventMgr.h"
|
||||||
|
#include "Manager/LinkshellMgr.h"
|
||||||
#include "Service.h"
|
#include "Service.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -174,6 +175,11 @@ namespace Sapphire::ScriptAPI
|
||||||
{
|
{
|
||||||
return Common::Service< World::Manager::EventMgr >::ref();
|
return Common::Service< World::Manager::EventMgr >::ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
World::Manager::LinkshellMgr& linkshellMgr()
|
||||||
|
{
|
||||||
|
return Common::Service< World::Manager::LinkshellMgr >::ref();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class QuestScript : public ScriptObject
|
class QuestScript : public ScriptObject
|
||||||
|
|
|
@ -113,10 +113,12 @@ Sapphire::ScriptAPI::ScriptObject** Sapphire::Scripting::ScriptLoader::getScript
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
auto func = reinterpret_cast< getScripts >( GetProcAddress( handle, "getScripts" ) );
|
auto func = reinterpret_cast< getScripts >( GetProcAddress( handle, "getScripts" ) );
|
||||||
|
|
||||||
using win32initFunc = void(*)( std::shared_ptr< Sapphire::Data::ExdData >);
|
using win32initFunc = void(*)( std::shared_ptr< Sapphire::Data::ExdData > );
|
||||||
using win32initFuncTeri = void(*)( std::shared_ptr< Sapphire::World::Manager::TerritoryMgr >);
|
using win32initFuncTeri = void(*)( std::shared_ptr< Sapphire::World::Manager::TerritoryMgr > );
|
||||||
|
using win32initFuncLinkshell = void(*)( std::shared_ptr< Sapphire::World::Manager::LinkshellMgr > );
|
||||||
auto win32init = reinterpret_cast< win32initFunc >( GetProcAddress( handle, "win32initExd" ) );
|
auto win32init = reinterpret_cast< win32initFunc >( GetProcAddress( handle, "win32initExd" ) );
|
||||||
auto win32initTeri = reinterpret_cast< win32initFuncTeri >( GetProcAddress( handle, "win32initTeri" ) );
|
auto win32initTeri = reinterpret_cast< win32initFuncTeri >( GetProcAddress( handle, "win32initTeri" ) );
|
||||||
|
auto win32initLinkshell = reinterpret_cast< win32initFuncLinkshell >( GetProcAddress( handle, "win32initLinkshell" ) );
|
||||||
|
|
||||||
if( win32init )
|
if( win32init )
|
||||||
{
|
{
|
||||||
|
@ -138,7 +140,18 @@ Sapphire::ScriptAPI::ScriptObject** Sapphire::Scripting::ScriptLoader::getScript
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger::warn( "did not find a win32init1 export on a windows script target - the server will likely crash!" );
|
Logger::warn( "did not find a win32initTeri export on a windows script target - the server will likely crash!" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( win32initLinkshell )
|
||||||
|
{
|
||||||
|
auto linkshellMgr = Common::Service< Sapphire::World::Manager::LinkshellMgr >::get();
|
||||||
|
auto tptr = linkshellMgr.lock();
|
||||||
|
win32initLinkshell( tptr );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::warn( "did not find a win32initLinkshell export on a windows script target - the server will likely crash!" );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
auto func = reinterpret_cast< getScripts >( dlsym( handle, "getScripts" ) );
|
auto func = reinterpret_cast< getScripts >( dlsym( handle, "getScripts" ) );
|
||||||
|
|
Loading…
Add table
Reference in a new issue