From 0cb304083db3175928f6d88fff229cdfcdef4cf3 Mon Sep 17 00:00:00 2001 From: Mordred Date: Wed, 7 Feb 2018 00:00:48 +0100 Subject: [PATCH] More preparational director logic, state inside can be modified with !instance --- src/common/Network/PacketDef/Ipcs.h | 2 + .../Network/PacketDef/Zone/ServerZoneDef.h | 17 ++ src/servers/sapphire_zone/Actor/Player.cpp | 13 +- src/servers/sapphire_zone/Actor/Player.h | 5 + .../DebugCommand/DebugCommandHandler.cpp | 15 ++ src/servers/sapphire_zone/Event/Director.cpp | 155 +++++++++++++++++- src/servers/sapphire_zone/Event/Director.h | 95 ++++++++++- .../Network/Handlers/PacketHandlers.cpp | 2 + .../sapphire_zone/Zone/InstanceContent.cpp | 140 +++++++++++++++- .../sapphire_zone/Zone/InstanceContent.h | 5 +- 10 files changed, 436 insertions(+), 13 deletions(-) diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 69e49cfe..037818ca 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -142,6 +142,8 @@ namespace Packets { Mount = 0x01CD, // updated 4.2 + DirectorVars = 0x01CF, // updated 4.2 + WeatherChange = 0x01EA, // updated 4.2 PlayerTitleList = 0x01EB, // updated 4.2 Discovery = 0x01EC, // updated 4.2 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 16ea8098..29bf329a 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1273,6 +1273,23 @@ struct FFXIVIpcMount : FFXIVIpcBasePacket uint32_t id; }; +/** +* Structural representation of the packet sent by the server +* to mount a player +*/ +struct FFXIVIpcDirectorVars : FFXIVIpcBasePacket +{ + /*! DirectorType | ContentId */ + uint32_t m_directorId; + /*! currect sequence */ + uint8_t m_sequence; + /*! current branch */ + uint8_t m_branch; + /*! raw storage for flags/vars */ + uint8_t m_unionData[10]; +}; + + struct FFXIVIpcActorGauge : FFXIVIpcBasePacket { uint8_t classJobId; diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index 1cddcf49..058623f0 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -70,7 +70,8 @@ Core::Entity::Player::Player() : m_zoningType( Common::ZoneingType::None ), m_bAutoattack( false ), m_markedForRemoval( false ), - m_mount( 0 ) + m_mount( 0 ), + m_directorInitialized( false ) { m_id = 0; m_objKind = ObjKind::Player; @@ -1637,3 +1638,13 @@ void Player::sendZonePackets() m_bMarkedForZoning = false; } + +void Player::setDirectorInitialized( bool isInitialized ) +{ + m_directorInitialized = isInitialized; +} + +bool Player::isDirectorInitialized() const +{ + return m_directorInitialized; +} diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index 8cfe770a..5f917994 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -499,6 +499,9 @@ public: void sendUrgent( const std::string& message ); void sendDebug( const std::string& message ); + bool isDirectorInitialized() const; + void setDirectorInitialized( bool isInitialized ); + // Player Battle Handling ////////////////////////////////////////////////////////////////////////////////////////////////////// void onMobAggro( BattleNpcPtr pBNpc ); @@ -566,6 +569,8 @@ private: bool m_markedForRemoval; + bool m_directorInitialized; + private: Common::FFXIVARR_POSITION3 m_prevPos; diff --git a/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp index 121c9a25..76de7471 100644 --- a/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp @@ -26,6 +26,7 @@ #include "Actor/EventNpc.h" #include "Zone/Zone.h" +#include "Zone/InstanceContent.h" #include "ServerZone.h" @@ -753,6 +754,20 @@ void Core::DebugCommandHandler::instance( char* data, Entity::Player &player, bo { player.exitInstance(); } + else if( subCommand == "set" ) + { + uint32_t instanceId; + uint32_t index; + uint32_t value; + sscanf( params.c_str(), "%d %d %d", &instanceId, &index, &value ); + + auto pInstance = g_territoryMgr.getInstanceZonePtr( instanceId ); + if( !pInstance ) + return; + auto instance = boost::dynamic_pointer_cast< InstanceContent >( pInstance ); + + instance->setVar( static_cast< uint8_t >( index ), static_cast< uint8_t >( value ) ); + } else if( subCommand == "festival" ) { uint32_t festivalId; diff --git a/src/servers/sapphire_zone/Event/Director.cpp b/src/servers/sapphire_zone/Event/Director.cpp index f479e502..fb9444ac 100644 --- a/src/servers/sapphire_zone/Event/Director.cpp +++ b/src/servers/sapphire_zone/Event/Director.cpp @@ -1,13 +1,27 @@ #include "Director.h" +#include +#include + +#include "Actor/Player.h" + +#include "Network/PacketWrappers/ActorControlPacket142.h" +#include "Network/PacketWrappers/ActorControlPacket143.h" + + +using namespace Core::Common; +using namespace Core::Network::Packets; +using namespace Core::Network::Packets::Server; + Core::Event::Director::Director( Core::Event::Director::DirectorType type, uint16_t contentId ) : m_contentId( contentId ), m_type( type ), m_directorId( ( static_cast< uint32_t >( type ) << 16 ) | contentId ), - m_sequence( 0 ), - m_branch( 0 ) + m_sequence( 1 ), + m_branch( 0 ), + m_elapsedTime( 0 ) { - + memset( m_unionData.arrData, 0, sizeof( m_unionData ) ); } uint32_t Core::Event::Director::getDirectorId() const @@ -19,3 +33,138 @@ uint16_t Core::Event::Director::getContentId() const { return m_contentId; } + +uint8_t Core::Event::Director::getSequence() const +{ + return m_sequence; +} + +void Core::Event::Director::sendDirectorClear( Core::Entity::PlayerPtr pPlayer ) const +{ + pPlayer->queuePacket( ActorControlPacket143( pPlayer->getId(), DirectorClear, m_directorId ) ); +} + +void Core::Event::Director::sendDirectorVars( Core::Entity::PlayerPtr pPlayer ) const +{ + ZoneChannelPacket< FFXIVIpcDirectorVars > varPacket( pPlayer->getId() ); + varPacket.data().m_directorId = getDirectorId(); + varPacket.data().m_sequence = getSequence(); + varPacket.data().m_branch = 0; + memcpy( varPacket.data().m_unionData, m_unionData.arrData, sizeof( varPacket.data().m_unionData ) ); + pPlayer->queuePacket( varPacket ); +} + +void Core::Event::Director::sendDirectorInit( Core::Entity::PlayerPtr pPlayer ) const +{ + pPlayer->queuePacket( ActorControlPacket143( pPlayer->getId(), DirectorInit, m_directorId, m_contentId ) ); +} + +Core::Event::Director::DirectorType Core::Event::Director::getType() const +{ + return m_type; +} + +uint8_t Core::Event::Director::getBranch() const +{ + return m_branch; +} + +void Core::Event::Director::setDirectorUI8AL( uint8_t value ) +{ + m_unionData.ui8lh.UI8AL = value; +} + +void Core::Event::Director::setDirectorUI8AH( uint8_t value ) +{ + m_unionData.ui8lh.UI8AH = value; +} + +void Core::Event::Director::setDirectorUI8BL( uint8_t value ) +{ + m_unionData.ui8lh.UI8BL = value; +} + +void Core::Event::Director::setDirectorUI8BH( uint8_t value ) +{ + m_unionData.ui8lh.UI8BH = value; +} + +void Core::Event::Director::setDirectorUI8CL( uint8_t value ) +{ + m_unionData.ui8lh.UI8CL = value; +} + +void Core::Event::Director::setDirectorUI8CH( uint8_t value ) +{ + m_unionData.ui8lh.UI8CH = value; +} + +void Core::Event::Director::setDirectorUI8DL( uint8_t value ) +{ + m_unionData.ui8lh.UI8DL = value; +} + +void Core::Event::Director::setDirectorUI8DH( uint8_t value ) +{ + m_unionData.ui8lh.UI8DH = value; +} + +void Core::Event::Director::setDirectorUI8EL( uint8_t value ) +{ + m_unionData.ui8lh.UI8EL = value; +} + +void Core::Event::Director::setDirectorUI8EH( uint8_t value ) +{ + m_unionData.ui8lh.UI8EH = value; +} + +void Core::Event::Director::setDirectorUI8FL( uint8_t value ) +{ + m_unionData.ui8lh.UI8FL = value; +} + +void Core::Event::Director::setDirectorUI8FH( uint8_t value ) +{ + m_unionData.ui8lh.UI8FH = value; +} + +void Core::Event::Director::setDirectorUI8GL( uint8_t value ) +{ + m_unionData.ui8lh.UI8GL = value; +} + +void Core::Event::Director::setDirectorUI8GH( uint8_t value ) +{ + m_unionData.ui8lh.UI8GH = value; +} + +void Core::Event::Director::setDirectorUI8HL( uint8_t value ) +{ + m_unionData.ui8lh.UI8HL = value; +} + +void Core::Event::Director::setDirectorUI8HH( uint8_t value ) +{ + m_unionData.ui8lh.UI8HH = value; +} + +void Core::Event::Director::setDirectorUI8IL( uint8_t value ) +{ + m_unionData.ui8lh.UI8IL = value; +} + +void Core::Event::Director::setDirectorUI8IH( uint8_t value ) +{ + m_unionData.ui8lh.UI8IH = value; +} + +void Core::Event::Director::setDirectorUI8JL( uint8_t value ) +{ + m_unionData.ui8lh.UI8JL = value; +} + +void Core::Event::Director::setDirectorUI8JH( uint8_t value ) +{ + m_unionData.ui8lh.UI8JH = value; +} diff --git a/src/servers/sapphire_zone/Event/Director.h b/src/servers/sapphire_zone/Event/Director.h index c570acb6..74a7a84f 100644 --- a/src/servers/sapphire_zone/Event/Director.h +++ b/src/servers/sapphire_zone/Event/Director.h @@ -38,6 +38,40 @@ public: uint8_t getSequence() const; uint8_t getBranch() const; + void sendDirectorInit( Entity::PlayerPtr pPlayer ) const; + void sendDirectorClear( Entity::PlayerPtr pPlayer ) const; + void sendDirectorVars( Entity::PlayerPtr pPlayer ) const; + + void setDirectorUI8AL( uint8_t value ); + void setDirectorUI8AH( uint8_t value ); + + void setDirectorUI8BL( uint8_t value ); + void setDirectorUI8BH( uint8_t value ); + + void setDirectorUI8CL( uint8_t value ); + void setDirectorUI8CH( uint8_t value ); + + void setDirectorUI8DL( uint8_t value ); + void setDirectorUI8DH( uint8_t value ); + + void setDirectorUI8EL( uint8_t value ); + void setDirectorUI8EH( uint8_t value ); + + void setDirectorUI8FL( uint8_t value ); + void setDirectorUI8FH( uint8_t value ); + + void setDirectorUI8GL( uint8_t value ); + void setDirectorUI8GH( uint8_t value ); + + void setDirectorUI8HL( uint8_t value ); + void setDirectorUI8HH( uint8_t value ); + + void setDirectorUI8IL( uint8_t value ); + void setDirectorUI8IH( uint8_t value ); + + void setDirectorUI8JL( uint8_t value ); + void setDirectorUI8JH( uint8_t value ); + private: /*! Id of the content of the director */ uint16_t m_contentId; @@ -51,12 +85,69 @@ private: /*! current branch */ uint8_t m_branch; - /*! raw storage for flags/vars */ - uint8_t m_unionData[10]; + union + { + struct UI8LH + { + uint8_t UI8AL : 4; + uint8_t UI8AH : 4; + uint8_t UI8BL : 4; + uint8_t UI8BH : 4; + uint8_t UI8CL : 4; + uint8_t UI8CH : 4; + uint8_t UI8DL : 4; + uint8_t UI8DH : 4; + uint8_t UI8EL : 4; + uint8_t UI8EH : 4; + uint8_t UI8FL : 4; + uint8_t UI8FH : 4; + uint8_t UI8GL : 4; + uint8_t UI8GH : 4; + uint8_t UI8HL : 4; + uint8_t UI8HH : 4; + uint8_t UI8IL : 4; + uint8_t UI8IH : 4; + uint8_t UI8JL : 4; + uint8_t UI8JH : 4; + } ui8lh; + + struct UI8 + { + uint8_t UI8A; + uint8_t UI8B; + uint8_t UI8C; + uint8_t UI8D; + uint8_t UI8E; + uint8_t UI8F; + uint8_t UI8G; + uint8_t UI8H; + uint8_t UI8I; + uint8_t UI8J; + } ui8; + + struct FLAGS + { + uint8_t flags80; + uint8_t flags72; + uint8_t flags64; + uint8_t flags56; + uint8_t flags48; + uint8_t flags40; + uint8_t flags32; + uint8_t flags24; + uint8_t flags16; + uint8_t flags8; + } flags; + + /*! raw storage for flags/vars */ + uint8_t arrData[10]; + } m_unionData; /*! type of the director */ DirectorType m_type; + uint32_t m_elapsedTime; + }; diff --git a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp index cedb239e..b2425d69 100644 --- a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp @@ -406,6 +406,8 @@ void Core::Network::GameConnection::pingHandler( const Packets::GamePacket& inPa void Core::Network::GameConnection::finishLoadingHandler( const Packets::GamePacket& inPacket, Entity::Player& player ) { + player.getCurrentZone()->onFinishLoading( player.getAsPlayer() ); + // player is done zoning player.setLoadingComplete( true ); diff --git a/src/servers/sapphire_zone/Zone/InstanceContent.cpp b/src/servers/sapphire_zone/Zone/InstanceContent.cpp index be9af4e4..48f8fac9 100644 --- a/src/servers/sapphire_zone/Zone/InstanceContent.cpp +++ b/src/servers/sapphire_zone/Zone/InstanceContent.cpp @@ -4,7 +4,10 @@ #include #include #include -#include +#include +#include + +#include "Event/Director.h" #include "Actor/Player.h" @@ -51,9 +54,14 @@ void Core::InstanceContent::onEnterTerritory( Entity::PlayerPtr pPlayer ) + std::to_string( getInstanceContentId() ) + + ", Entity#" + std::to_string( pPlayer->getId() ) ); - pPlayer->queuePacket( ActorControlPacket143( pPlayer->getId(), DirectorInit, getDirectorId(), - getInstanceContentId() ) ); + // mark player as "bound by duty" pPlayer->setStateFlag( PlayerStateFlag::BoundByDuty ); + + // if the instance was not started yet, director init is sent on enter event. + // else it will be sent on finish loading. + if( m_state == Created ) + sendDirectorInit( pPlayer ); + } void Core::InstanceContent::onLeaveTerritory( Entity::PlayerPtr pPlayer ) @@ -61,21 +69,141 @@ void Core::InstanceContent::onLeaveTerritory( Entity::PlayerPtr pPlayer ) g_log.debug( "InstanceContent::onLeaveTerritory: Zone#" + std::to_string( getGuId() ) + "|" + std::to_string( getInstanceContentId() ) + + ", Entity#" + std::to_string( pPlayer->getId() ) ); - pPlayer->queuePacket( ActorControlPacket143( pPlayer->getId(), DirectorClear, getDirectorId() ) ); + sendDirectorClear( pPlayer ); + + pPlayer->setDirectorInitialized( false ); + // remove "bound by duty" state pPlayer->unsetStateFlag( PlayerStateFlag::BoundByDuty ); } void Core::InstanceContent::onUpdate( uint32_t currTime ) { + switch( m_state ) + { + case Created: + { + // temporary handling for instance state progression + if( m_playerMap.size() < 1 ) + return; + + for( const auto &playerIt : m_playerMap ) + { + if( !playerIt.second->isLoadingComplete() || !playerIt.second->isDirectorInitialized() ) + return; + } + + for( const auto &playerIt : m_playerMap ) + { + auto pPlayer = playerIt.second; + pPlayer->queuePacket( + ActorControlPacket143( pPlayer->getId(), DirectorUpdate, + getDirectorId(), 0x40000001, m_instanceContentInfo->timeLimitmin * 60u ) ); + } + + m_state = DutyInProgress; + break; + } + + + case DutyReset: + break; + + case DutyInProgress: + { + break; + } + + + case DutyFinished: + break; + } } void Core::InstanceContent::onFinishLoading( Entity::PlayerPtr pPlayer ) { - + if( m_state != Created ) + sendDirectorInit( pPlayer ); } void Core::InstanceContent::onInitDirector( Entity::PlayerPtr pPlayer ) { - + sendDirectorVars( pPlayer ); + pPlayer->setDirectorInitialized( true ); +} + +void Core::InstanceContent::setVar( uint8_t index, uint8_t value ) +{ + if( index > 19 ) + return; + + switch( index ) + { + case 0: + setDirectorUI8AL( value ); + break; + case 1: + setDirectorUI8AH( value ); + break; + case 2: + setDirectorUI8BL( value ); + break; + case 3: + setDirectorUI8BH( value ); + break; + case 4: + setDirectorUI8CL( value ); + break; + case 5: + setDirectorUI8CH( value ); + break; + case 6: + setDirectorUI8DL( value ); + break; + case 7: + setDirectorUI8DH( value ); + break; + case 8: + setDirectorUI8EL( value ); + break; + case 9: + setDirectorUI8EH( value ); + break; + case 10: + setDirectorUI8FL( value ); + break; + case 11: + setDirectorUI8FH( value ); + break; + case 12: + setDirectorUI8GL( value ); + break; + case 13: + setDirectorUI8GH( value ); + break; + case 14: + setDirectorUI8HL( value ); + break; + case 15: + setDirectorUI8HH( value ); + break; + case 16: + setDirectorUI8IL( value ); + break; + case 17: + setDirectorUI8IH( value ); + break; + case 18: + setDirectorUI8JL( value ); + break; + case 19: + setDirectorUI8JH( value ); + break; + + } + + for( const auto &playerIt : m_playerMap ) + { + sendDirectorVars( playerIt.second ); + } } diff --git a/src/servers/sapphire_zone/Zone/InstanceContent.h b/src/servers/sapphire_zone/Zone/InstanceContent.h index 1c1705e6..49bfedf7 100644 --- a/src/servers/sapphire_zone/Zone/InstanceContent.h +++ b/src/servers/sapphire_zone/Zone/InstanceContent.h @@ -15,7 +15,8 @@ public: enum InstanceContentState { Created, - DutyStarted, + DutyReset, + DutyInProgress, DutyFinished }; @@ -32,6 +33,8 @@ public: void onInitDirector( Entity::PlayerPtr pPlayer ) override; void onUpdate( uint32_t currTime ) override; + void setVar( uint8_t index, uint8_t value ); + Core::Data::ExdDataGenerated::InstanceContentPtr getInstanceContentInfo() const;