From f815e3e3d2761dc791878ceded386d6ba0784c82 Mon Sep 17 00:00:00 2001 From: Biscuit Boy Date: Thu, 19 Apr 2018 22:22:20 +1000 Subject: [PATCH] Added status priority and made the invis check better --- src/servers/sapphire_zone/Actor/Player.cpp | 128 ++++++------------ .../DebugCommand/DebugCommandHandler.cpp | 9 ++ 2 files changed, 54 insertions(+), 83 deletions(-) diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index e05308f4..f77c5eb5 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -169,74 +169,32 @@ bool Core::Entity::Player::isMarkedForRemoval() const Core::Common::OnlineStatus Core::Entity::Player::getOnlineStatus() { - uint64_t newMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::NewAdventurer ); - uint64_t afkMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::AwayfromKeyboard ); - uint64_t busyMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Busy ); - uint64_t dcMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Disconnected ); - uint64_t meldMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::LookingtoMeldMateria ); - uint64_t ptMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::LookingforParty ); - uint64_t rpMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Roleplaying ); + auto pExdData = g_fw.get< Data::ExdDataGenerated >(); + if( !pExdData ) + return OnlineStatus::Online; - uint64_t prodMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Producer ); - uint64_t gmMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::GameMaster ); - uint64_t gm1Mask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::GameMaster1 ); - uint64_t gm2Mask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::GameMaster2 ); + uint32_t statusDisplayOrder = 0xFF14; + uint32_t applicableStatus = 0; - uint64_t menMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Mentor ); - uint64_t retMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::Returner ); - uint64_t trialMask = uint64_t( 1 ) << static_cast< uint32_t >( OnlineStatus::TrialAdventurer ); + for( uint32_t i = 0; i < 64; i++ ) + { + bool bit = ( m_onlineStatus >> i ) & 1; + if( !bit ) + continue; - OnlineStatus status = OnlineStatus::Online; + auto pOnlineStatus = pExdData->get< Data::OnlineStatus >( i ); + if( !pOnlineStatus ) + continue; - //if( hasStateFlag( Common::PlayerStateFlag::NewAdventurer ) ) - if( m_onlineStatus & newMask ) - status = OnlineStatus::NewAdventurer; - - if( m_onlineStatus & afkMask ) - status = OnlineStatus::AwayfromKeyboard; - - if( m_onlineStatus & busyMask ) - status = OnlineStatus::Busy; - - if( m_onlineStatus & dcMask ) - status = OnlineStatus::Disconnected; - - if( m_onlineStatus & meldMask ) - status = OnlineStatus::LookingtoMeldMateria; - - if( m_onlineStatus & ptMask ) - status = OnlineStatus::LookingforParty; - - if( m_onlineStatus & rpMask ) - status = OnlineStatus::Roleplaying; - - if( m_onlineStatus & prodMask ) - status = OnlineStatus::Producer; - - if( m_onlineStatus & gmMask ) - status = OnlineStatus::GameMaster; - - if( m_onlineStatus & gm1Mask ) - status = OnlineStatus::GameMaster1; - - if( m_onlineStatus & gm2Mask ) - status = OnlineStatus::GameMaster2; - - if( m_onlineStatus & menMask ) - status = OnlineStatus::Mentor; - - if( m_onlineStatus & retMask ) - status = OnlineStatus::Returner; - - if( m_onlineStatus & trialMask ) - status = OnlineStatus::TrialAdventurer; - - if( hasStateFlag( PlayerStateFlag::WatchingCutscene ) ) - status = OnlineStatus::ViewingCutscene; - - // TODO: add all the logic for returning the proper online status, there probably is a better way for this alltogether - return status; + if( pOnlineStatus->priority < statusDisplayOrder ) + { + // todo: also check that the status can actually be set here, otherwise we need to ignore it (and ban the player obv) + statusDisplayOrder = pOnlineStatus->priority; + applicableStatus = i; + return static_cast< OnlineStatus >( applicableStatus ); + } + } } void Core::Entity::Player::setOnlineStatusMask( uint64_t status ) @@ -1642,22 +1600,34 @@ void Core::Entity::Player::sendTitleList() queuePacket( titleListPacket ); } +void Core::Entity::Player::sendZoneInPackets( uint32_t param1, uint32_t param2 = 0, uint32_t param3 = 0, uint32_t param4 = 0, bool pSetStatus = false ) +{ + auto zoneInPacket = ActorControlPacket143( getId(), ZoneIn, param1, param2, param3, param4 ); + auto SetStatusPacket = ActorControlPacket142( getId(), SetStatus, static_cast< uint8_t >( Entity::Chara::ActorStatus::Idle ) ); + + if( !Entity::Chara::Invisible ) + sendToInRangeSet( zoneInPacket, true ); + if( pSetStatus ) + sendToInRangeSet( SetStatusPacket ); + else + queuePacket( zoneInPacket ); + if (pSetStatus) + queuePacket( SetStatusPacket ); + + setZoningType( Common::ZoneingType::None ); + unsetStateFlag( PlayerStateFlag::BetweenAreas ); +} + void Core::Entity::Player::finishZoning() { switch( getZoningType() ) { case ZoneingType::None: - if (getGmInvis() == false) - sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01 ), true ); - else - queuePacket( ActorControlPacket143( getId(), ZoneIn, 0x01 ) ); + sendZoneInPackets( 0x01 ); break; case ZoneingType::Teleport: - if( getGmInvis() == false ) - sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0, 0, 110 ), true ); - else - queuePacket( ActorControlPacket143( getId(), ZoneIn, 0x01, 0, 0, 110 ) ); + sendZoneInPackets( 0x01, 0, 0, 110 ); break; case ZoneingType::Return: @@ -1668,27 +1638,19 @@ void Core::Entity::Player::finishZoning() resetHp(); resetMp(); setStatus( Entity::Chara::ActorStatus::Idle ); - if( getGmInvis() == false ) - sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x01, 0, 111 ), true ); - else - queuePacket( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x01, 0, 111 ) ); + + sendZoneInPackets( 0x01, 0x01, 0, 111, true ); sendToInRangeSet( ActorControlPacket142( getId(), SetStatus, static_cast< uint8_t >( Entity::Chara::ActorStatus::Idle ) ), true ); } else - if( getGmInvis() == false ) - sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x00, 0, 111 ), true ); - else - queuePacket( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x00, 0, 111 ) ); + sendZoneInPackets( 0x01, 0x00, 0, 111 ); } - break; + break; case ZoneingType::FadeIn: break; } - - setZoningType( Common::ZoneingType::None ); - unsetStateFlag( PlayerStateFlag::BetweenAreas ); } void Core::Entity::Player::emote( uint32_t emoteId, uint64_t targetId ) diff --git a/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp index 71d8d8fe..2789b756 100644 --- a/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp @@ -321,6 +321,15 @@ void Core::DebugCommandHandler::set( char * data, Entity::Player& player, boost: { pTerriMgr->disableCurrentFestival(); } + else if( subCommand == "logout" ) + { + Network::Packets::ZoneChannelPacket< Network::Packets::Server::FFXIVIpcLogout > logoutPacket( player.getId() ); + logoutPacket.data().flags1 = 0x0; + logoutPacket.data().flags2 = 0xE179C650; + player.queuePacket( logoutPacket ); + + player.setMarkedForRemoval(); + } else { player.sendUrgent( subCommand + " is not a valid SET command." );