1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-25 14:07:46 +00:00

Linkshell groundwork, events can now be implemented more easy

This commit is contained in:
Mordred 2021-12-02 22:58:36 +01:00
parent 7af6eda26e
commit e385522e52
12 changed files with 148 additions and 25 deletions

View file

@ -259,13 +259,13 @@ struct FFXIVIpcYieldEventSceneString8 :
{
};
struct YieldEventSceneString16 :
struct FFXIVIpcYieldEventSceneString16 :
FFXIVIpcBasePacket< YieldEventSceneString16 >,
YieldEventSceneStringN< 16 >
{
};
struct YieldEventSceneString32 :
struct FFXIVIpcYieldEventSceneString32 :
FFXIVIpcBasePacket< YieldEventSceneString32 >,
YieldEventSceneStringN< 32 >
{

View file

@ -1494,17 +1494,13 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
* Structural representation of the packet sent by the server
* to respond to a linkshell creation event
*/
struct FFXIVIpcEventLinkshell : FFXIVIpcBasePacket< ResumeEventScene2 >
struct FFXIVIpcResumeEventScene2 : FFXIVIpcBasePacket< ResumeEventScene2 >
{
uint32_t eventId;
uint8_t scene;
uint8_t param1;
uint8_t param2;
uint8_t param3;
uint32_t unknown1;
uint32_t unknown2;
uint32_t unknown3;
uint32_t unknown4;
uint32_t handlerId;
uint16_t sceneId;
uint8_t resumeId;
uint8_t numOfArgs;
uint32_t args[4];
};
/**
@ -2165,5 +2161,4 @@ struct FFXIVIpcEorzeaTimeOffset : FFXIVIpcBasePacket< TimeOffset >
{
ZoneProtoDownMemberPos Member[8];
};
}

View file

@ -22,6 +22,7 @@ namespace Sapphire::Data
namespace Sapphire::World::Manager
{
class TerritoryMgr;
class LinkshellMgr;
}
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 );
}
extern "C" EXPORT void win32initLinkshell( std::shared_ptr< Sapphire::World::Manager::LinkshellMgr > lsMgr )
{
Sapphire::Common::Service< Sapphire::World::Manager::LinkshellMgr >::set( lsMgr );
}
#endif
extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts()

View file

@ -42,7 +42,13 @@ public:
// create linkshell
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

View file

@ -14,6 +14,7 @@ namespace Sapphire::Event
uint8_t errorCode;
uint8_t numOfResults;
std::vector< uint32_t > results;
std::string resultString;
uint32_t getResult( uint32_t index ) const;
};

View file

@ -314,6 +314,40 @@ void Sapphire::World::Manager::EventMgr::handleReturnEventScene( Entity::Player&
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 )
{
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 );
}
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 )
{
auto pEvent = bootstrapSceneEvent( player, eventId, flags );

View file

@ -21,6 +21,8 @@ namespace Sapphire::World::Manager
void handleReturnEventScene( Entity::Player& player, uint32_t eventId, uint16_t sceneId, uint8_t errorCode,
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 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,
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 */
void playScene( Entity::Player& player, uint32_t eventId, uint32_t scene, uint32_t flags,
Event::EventHandler::SceneReturnCallback eventReturnCallback = nullptr );

View file

@ -107,9 +107,9 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
setZoneHandler( StartUIEvent, "StartUIEvent", &GameConnection::startUiEvent );
setZoneHandler( YieldEventSceneString8, "YieldEventSceneString8", &GameConnection::eventHandlerLinkshell );
setZoneHandler( YieldEventSceneString16, "YieldEventSceneString16", &GameConnection::eventHandlerLinkshell );
setZoneHandler( YieldEventSceneString8, "YieldEventSceneString8", &GameConnection::yieldEventString );
setZoneHandler( YieldEventSceneString16, "YieldEventSceneString16", &GameConnection::yieldEventString );
setZoneHandler( YieldEventSceneString32, "YieldEventSceneString32", &GameConnection::yieldEventString );
setZoneHandler( RequestPenalties, "RequestPenalties", &GameConnection::cfRequestPenalties );
setZoneHandler( FindContent, "FindContent", &GameConnection::findContent );

View file

@ -160,6 +160,8 @@ namespace Sapphire::Network
DECLARE_HANDLER( eventHandlerLinkshell );
DECLARE_HANDLER( yieldEventString );
DECLARE_HANDLER( logoutHandler );
DECLARE_HANDLER( cfRequestPenalties );

View file

@ -22,6 +22,7 @@
#include "Territory/QuestBattle.h"
#include "Session.h"
#include <Network/PacketDef/ClientIpcs.h>
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
@ -291,15 +292,51 @@ void Sapphire::Network::GameConnection::eventHandlerLinkshell( const Packets::FF
auto& server = Common::Service< World::WorldServer >::ref();
const auto packet = ZoneChannelPacket< FFXIVIpcYieldEventSceneString8 >( inPacket );
auto linkshellEvent = makeZonePacket< FFXIVIpcEventLinkshell >( player.getId() );
linkshellEvent->data().eventId = packet.data().handlerId;
linkshellEvent->data().scene = static_cast< uint8_t >( packet.data().sceneId );
linkshellEvent->data().param3 = 1;
linkshellEvent->data().unknown1 = 0x15a;
auto linkshellEvent = makeZonePacket< FFXIVIpcResumeEventScene2 >( player.getId() );
linkshellEvent->data().handlerId = packet.data().handlerId;
linkshellEvent->data().sceneId = static_cast< uint8_t >( packet.data().sceneId );
linkshellEvent->data().numOfArgs = 1;
linkshellEvent->data().args[ 0 ] = 0x15a;
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,
Entity::Player& player )
{

View file

@ -5,6 +5,7 @@
#include "ForwardsZone.h"
#include "Event/EventHandler.h"
#include "Manager/EventMgr.h"
#include "Manager/LinkshellMgr.h"
#include "Service.h"
#ifdef _MSC_VER
@ -174,6 +175,11 @@ namespace Sapphire::ScriptAPI
{
return Common::Service< World::Manager::EventMgr >::ref();
}
World::Manager::LinkshellMgr& linkshellMgr()
{
return Common::Service< World::Manager::LinkshellMgr >::ref();
}
};
class QuestScript : public ScriptObject

View file

@ -113,10 +113,12 @@ Sapphire::ScriptAPI::ScriptObject** Sapphire::Scripting::ScriptLoader::getScript
#ifdef _WIN32
auto func = reinterpret_cast< getScripts >( GetProcAddress( handle, "getScripts" ) );
using win32initFunc = void(*)( std::shared_ptr< Sapphire::Data::ExdData >);
using win32initFuncTeri = void(*)( std::shared_ptr< Sapphire::World::Manager::TerritoryMgr >);
using win32initFunc = void(*)( std::shared_ptr< Sapphire::Data::ExdData > );
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 win32initTeri = reinterpret_cast< win32initFuncTeri >( GetProcAddress( handle, "win32initTeri" ) );
auto win32initLinkshell = reinterpret_cast< win32initFuncLinkshell >( GetProcAddress( handle, "win32initLinkshell" ) );
if( win32init )
{
@ -138,7 +140,18 @@ Sapphire::ScriptAPI::ScriptObject** Sapphire::Scripting::ScriptLoader::getScript
}
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
auto func = reinterpret_cast< getScripts >( dlsym( handle, "getScripts" ) );