mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-02 00:47:45 +00:00
Implemented a basic actionintegrity implementation, subject to be changed.
Fixed replay packet sending.
This commit is contained in:
parent
0167367eeb
commit
85501effed
16 changed files with 160 additions and 24 deletions
|
@ -276,13 +276,14 @@ namespace Sapphire::Network::ActorControl
|
|||
HuntingLogSectionFinish = 0x21F,
|
||||
HuntingLogRankFinish = 0x220,
|
||||
|
||||
SetMaxGearSets = 0x320,
|
||||
|
||||
SetCharaGearParamUI = 0x260,
|
||||
|
||||
SetConfigFlags = 0x260,
|
||||
ToggleWireframeRendering = 0x261,
|
||||
|
||||
ExamineError = 0x2BF,
|
||||
|
||||
SetMaxGearSets = 0x320,
|
||||
GearSetEquipMsg = 0x321,
|
||||
|
||||
SetBait = 0x325, // param1: bait ID
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace Sapphire::Network::Packets
|
|||
*/
|
||||
void setSize( std::size_t packetSize )
|
||||
{
|
||||
m_segHdr.size = packetSize;
|
||||
m_segHdr.size = static_cast< uint32_t >( packetSize );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
#include <Manager/TerritoryMgr.h>
|
||||
#include <Service.h>
|
||||
|
||||
#include <Manager/TaskMgr.h>
|
||||
#include <Task/ActionIntegrityTask.h>
|
||||
|
||||
using namespace Sapphire;
|
||||
using namespace Sapphire::World::Action;
|
||||
using namespace Sapphire::Network::Packets;
|
||||
|
@ -110,7 +113,7 @@ void EffectBuilder::buildAndSendPackets( const std::vector< Entity::CharaPtr >&
|
|||
auto& teriMgr = Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref();
|
||||
auto zone = teriMgr.getZoneByTerritoryTypeId( m_sourceChara->getTerritoryTypeId() );
|
||||
|
||||
auto globalSequence = zone ? zone->getNextEffectSequence() : 0;
|
||||
auto globalSequence = zone ? zone->getNextEffectResultId() : 0;
|
||||
|
||||
do // we want to send at least one packet even nothing is hit so other players can see
|
||||
{
|
||||
|
@ -125,13 +128,13 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( const s
|
|||
auto remainingTargetCount = targetList.size();
|
||||
auto& teriMgr = Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref();
|
||||
auto zone = teriMgr.getTerritoryByGuId( m_sourceChara->getTerritoryId() );
|
||||
auto globalSequence = zone->getNextEffectSequence();
|
||||
auto resultId = zone->getNextEffectResultId();
|
||||
|
||||
if( remainingTargetCount > 1 ) // use AoeEffect packets
|
||||
{
|
||||
auto effectPacket = std::make_shared< EffectPacket >( m_sourceChara->getId(), m_actionId );
|
||||
effectPacket->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
|
||||
effectPacket->setSequence( globalSequence, m_sequence );
|
||||
effectPacket->setSequence( resultId, m_sequence );
|
||||
effectPacket->setTargetActor( targetList[ 0 ]->getId() );
|
||||
|
||||
uint8_t targetIndex = 0;
|
||||
|
@ -153,6 +156,8 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( const s
|
|||
else
|
||||
{
|
||||
effectPacket->addTargetEffect( effect, result->getTarget()->getId() );
|
||||
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
|
||||
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, result->getTarget(), 1000 ) );
|
||||
}
|
||||
|
||||
zone->addEffectResult( std::move( result ) );
|
||||
|
@ -177,7 +182,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( const s
|
|||
|
||||
auto effectPacket = std::make_shared< EffectPacket1 >( m_sourceChara->getId(), targetList[ 0 ]->getId(), m_actionId );
|
||||
effectPacket->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
|
||||
effectPacket->setSequence( globalSequence, m_sequence );
|
||||
effectPacket->setSequence( resultId, m_sequence );
|
||||
|
||||
for( auto it = m_actorEffectsMap.begin(); it != m_actorEffectsMap.end(); )
|
||||
{
|
||||
|
@ -197,6 +202,8 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( const s
|
|||
else
|
||||
{
|
||||
effectPacket->addTargetEffect( effect );
|
||||
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
|
||||
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, result->getTarget(), 1000 ) );
|
||||
}
|
||||
|
||||
zone->addEffectResult( std::move( result ) );
|
||||
|
@ -221,7 +228,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( const s
|
|||
effectPacket->data().DirTarget = Common::Util::floatToUInt16Rot( m_sourceChara->getRot() );
|
||||
effectPacket->data().Flag = Common::ActionEffectDisplayType::HideActionName;
|
||||
effectPacket->data().RequestId = m_sequence;
|
||||
effectPacket->data().ResultId = globalSequence;
|
||||
effectPacket->data().ResultId = resultId;
|
||||
|
||||
m_actorEffectsMap.clear();
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <Task/RemoveBNpcTask.h>
|
||||
#include <Task/FadeBNpcTask.h>
|
||||
#include <Task/DelayedEmnityTask.h>
|
||||
#include <Task/ActionIntegrityTask.h>
|
||||
#include <Service.h>
|
||||
|
||||
using namespace Sapphire::Common;
|
||||
|
@ -995,13 +996,17 @@ void Sapphire::Entity::BNpc::autoAttack( CharaPtr pTarget )
|
|||
effectEntry.Arg0 = 3;
|
||||
effectEntry.Arg1 = 7;
|
||||
//effectEntry.Arg2 = 0x71;
|
||||
effectPacket->setSequence( pZone->getNextEffectSequence() );
|
||||
auto resultId = pZone->getNextEffectResultId();
|
||||
effectPacket->setSequence( resultId );
|
||||
effectPacket->addTargetEffect( effectEntry );
|
||||
|
||||
sendToInRangeSet( effectPacket );
|
||||
|
||||
pTarget->takeDamage( static_cast< uint16_t >( damage.first ) );
|
||||
|
||||
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
|
||||
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, pTarget, 500 ) );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -407,8 +407,6 @@ void Sapphire::Entity::Chara::takeDamage( uint32_t damage )
|
|||
}
|
||||
else
|
||||
m_hp -= damage;
|
||||
|
||||
sendStatusUpdate();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -521,7 +519,7 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf
|
|||
|
||||
auto statusEffectAdd = makeZonePacket< FFXIVIpcActionIntegrity >( getId() );
|
||||
|
||||
statusEffectAdd->data().ResultId = pZone->getNextEffectSequence();
|
||||
statusEffectAdd->data().ResultId = pZone->getNextEffectResultId();
|
||||
statusEffectAdd->data().Target = pEffect->getTargetActorId();
|
||||
statusEffectAdd->data().Hp = getHp();
|
||||
statusEffectAdd->data().Mp = static_cast< uint16_t >( getMp() );
|
||||
|
|
|
@ -336,6 +336,18 @@ std::set< Sapphire::Entity::GameObjectPtr > Sapphire::Entity::GameObject::getInR
|
|||
return tempInRange;
|
||||
}
|
||||
|
||||
std::set< uint64_t > Sapphire::Entity::GameObject::getInRangePlayerIds( bool includeSelf )
|
||||
{
|
||||
std::set< uint64_t > playerIds;
|
||||
for( auto& player : m_inRangePlayers )
|
||||
playerIds.insert( player->getCharacterId() );
|
||||
|
||||
if( isPlayer() && includeSelf )
|
||||
playerIds.insert( getAsPlayer()->getCharacterId() );
|
||||
|
||||
return playerIds;
|
||||
}
|
||||
|
||||
uint32_t Sapphire::Entity::GameObject::getTerritoryTypeId() const
|
||||
{
|
||||
return m_territoryTypeId;
|
||||
|
|
|
@ -111,6 +111,8 @@ namespace Sapphire::Entity
|
|||
|
||||
std::set< GameObjectPtr > getInRangeActors( bool includeSelf = false );
|
||||
|
||||
std::set< uint64_t > getInRangePlayerIds( bool includeSelf = false );
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
CharaPtr getAsChara();
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
|
||||
#include "WorldServer.h"
|
||||
|
||||
#include <Manager/TaskMgr.h>
|
||||
#include <Task/ActionIntegrityTask.h>
|
||||
|
||||
using namespace Sapphire;
|
||||
using namespace Sapphire::Common;
|
||||
using namespace Sapphire::Network::Packets;
|
||||
|
@ -1327,7 +1330,8 @@ void Player::autoAttack( CharaPtr pTarget )
|
|||
//entry.Arg2 = 0x73;
|
||||
}
|
||||
|
||||
effectPacket->setSequence( pZone->getNextEffectSequence() );
|
||||
auto resultId = pZone->getNextEffectResultId();
|
||||
effectPacket->setResultId( resultId );
|
||||
|
||||
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
|
||||
effectPacket->addTargetEffect( entry );
|
||||
|
@ -1335,6 +1339,9 @@ void Player::autoAttack( CharaPtr pTarget )
|
|||
sendToInRangeSet( effectPacket, true );
|
||||
|
||||
pTarget->takeDamage( static_cast< uint32_t >( damage.first ) );
|
||||
|
||||
auto& taskMgr = Common::Service< TaskMgr >::ref();
|
||||
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, pTarget, 500 ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -544,7 +544,7 @@ void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr<
|
|||
|
||||
effectPacket->addTargetEffect( entry, static_cast< uint64_t >( player.getId() ) );
|
||||
|
||||
auto sequence = pCurrentZone->getNextEffectSequence();
|
||||
auto sequence = pCurrentZone->getNextEffectResultId();
|
||||
effectPacket->setSequence( sequence );
|
||||
|
||||
// effectPacket->setAnimationId( param1 );
|
||||
|
|
|
@ -417,7 +417,7 @@ void PlayerMgr::onZone( Sapphire::Entity::Player& player )
|
|||
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 5 ) ); // SalvageSkill
|
||||
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 6 ) ); // SalvageSkill
|
||||
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 7 ) ); // SalvageSkill
|
||||
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetCharaGearParamUI, player.getEquipDisplayFlags(), 1 ) );
|
||||
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetConfigFlags, player.getEquipDisplayFlags(), 1 ) );
|
||||
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetMaxGearSets, player.getMaxGearSets() ) );
|
||||
}
|
||||
|
||||
|
@ -425,13 +425,11 @@ void PlayerMgr::onZone( Sapphire::Entity::Player& player )
|
|||
//setStateFlag( PlayerStateFlag::BetweenAreas );
|
||||
//setStateFlag( PlayerStateFlag::BetweenAreas1 );
|
||||
|
||||
if( player.hasReward( Common::UnlockEntry::HuntingLog ) )
|
||||
player.sendHuntingLog();
|
||||
player.sendHuntingLog();
|
||||
|
||||
if( player.isLogin() )
|
||||
{
|
||||
player.sendItemLevel();
|
||||
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x39, 0 ) ); // unknown
|
||||
server.queueForPlayer( player.getCharacterId(), makePlayerSetup( player ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,11 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
|
|||
m_data.ResultId = static_cast< uint32_t>( sequence );
|
||||
}
|
||||
|
||||
void setResultId( uint32_t resultId )
|
||||
{
|
||||
m_data.ResultId = static_cast< uint32_t>( resultId );
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t m_targetEffectCount{ 0 };
|
||||
uint8_t m_sourceEffectCount{ 0 };
|
||||
|
|
|
@ -149,9 +149,10 @@ void Sapphire::World::Session::startReplay( const std::string& path )
|
|||
|
||||
for( auto set : loadedSets )
|
||||
{
|
||||
m_replayCache.emplace_back( Common::Util::getTimeMs() + ( std::get< 0 >( set ) - startTime ), std::get< 1 >( set ) );
|
||||
uint64_t setTime = std::get< 0 >( set );
|
||||
m_replayCache.emplace_back( Common::Util::getTimeMs() + ( ( setTime - startTime ) / 1 ), std::get< 1 >( set ) );
|
||||
|
||||
Logger::info( "Registering {0} for {1}", std::get< 1 >( set ), std::get< 0 >( set ) - startTime );
|
||||
Logger::info( "Registering {0} for {1}, oldTime {2}", std::get< 1 >( set ), setTime - startTime, setTime );
|
||||
}
|
||||
|
||||
PlayerMgr::sendDebug( *getPlayer(), "Registered {0} sets for replay" ), m_replayCache.size();
|
||||
|
@ -167,15 +168,19 @@ void Sapphire::World::Session::stopReplay()
|
|||
void Sapphire::World::Session::processReplay()
|
||||
{
|
||||
int at = 0;
|
||||
test:
|
||||
for( const auto& set : m_replayCache )
|
||||
{
|
||||
if( std::get< 0 >( set ) <= Common::Util::getTimeMs() )
|
||||
if( (std::get< 0 >( set ) ) <= Common::Util::getTimeMs() )
|
||||
{
|
||||
m_pZoneConnection->injectPacket( std::get< 1 >( set ), *getPlayer().get() );
|
||||
m_replayCache.erase( m_replayCache.begin() + at );
|
||||
//g_framework.getLogger().info( "Sent for " + std::to_string( std::get< 0 >( set ) ) + ", left: " + std::to_string( m_replayCache.size() ) );
|
||||
|
||||
Logger::info( "Sent for {0}, left: {1}", std::get< 1 >( set ), std::to_string( m_replayCache.size() ) );
|
||||
goto test;
|
||||
}
|
||||
at++;
|
||||
|
||||
}
|
||||
|
||||
if( m_replayCache.empty() )
|
||||
|
|
65
src/world/Task/ActionIntegrityTask.cpp
Normal file
65
src/world/Task/ActionIntegrityTask.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
#include "ActionIntegrityTask.h"
|
||||
|
||||
#include <Logging/Logger.h>
|
||||
#include <Actor/Player.h>
|
||||
#include <Actor/Chara.h>
|
||||
#include <WorldServer.h>
|
||||
#include <Service.h>
|
||||
#include <Network/PacketWrappers/WarpPacket.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace Sapphire::World;
|
||||
using namespace Sapphire::World::Manager;
|
||||
using namespace Sapphire::Network::Packets;
|
||||
using namespace Sapphire::Network::Packets::WorldPackets::Server;
|
||||
|
||||
ActionIntegrityTask::ActionIntegrityTask( uint32_t resultId, Entity::CharaPtr pTarget, uint64_t delayTime ) : Task( delayTime )
|
||||
{
|
||||
m_resultId = resultId;
|
||||
m_pTarget = std::move( pTarget );
|
||||
}
|
||||
|
||||
void ActionIntegrityTask::onQueue()
|
||||
{
|
||||
Logger::debug( { __FUNCTION__ } );
|
||||
}
|
||||
|
||||
void ActionIntegrityTask::execute()
|
||||
{
|
||||
auto& server = Common::Service< WorldServer >::ref();
|
||||
|
||||
auto inRangePlayers = m_pTarget->getInRangePlayerIds( true );
|
||||
|
||||
if( inRangePlayers.empty() )
|
||||
return;
|
||||
|
||||
auto integrityPacket = makeZonePacket< FFXIVIpcActionIntegrity >( 0 );
|
||||
auto& data = integrityPacket->data();
|
||||
integrityPacket->setSourceActor( m_pTarget->getId() );
|
||||
data.Hp = m_pTarget->getHp();
|
||||
data.HpMax = m_pTarget->getMaxHp();
|
||||
data.Mp = m_pTarget->getMp();
|
||||
data.MpMax = m_pTarget->getMaxMp();
|
||||
data.Tp = m_pTarget->getTp();
|
||||
data.ResultId = m_resultId;
|
||||
data.Target = m_pTarget->getId();
|
||||
|
||||
|
||||
for( auto& charId : inRangePlayers )
|
||||
{
|
||||
auto pPlayer = server.getPlayer( charId );
|
||||
Logger::debug( "Sending to {}", charId );
|
||||
integrityPacket->setTargetActor( pPlayer->getId() );
|
||||
|
||||
server.queueForPlayer( charId, integrityPacket );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string ActionIntegrityTask::toString()
|
||||
{
|
||||
return fmt::format( "ActionIntegrityTask: ResultId#{}, TargetId#{}, ElapsedTimeMs: {}", m_resultId, m_pTarget->getId(), getDelayTimeMs() );
|
||||
}
|
||||
|
||||
|
31
src/world/Task/ActionIntegrityTask.h
Normal file
31
src/world/Task/ActionIntegrityTask.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <ForwardsZone.h>
|
||||
#include "Task.h"
|
||||
|
||||
namespace Sapphire::World
|
||||
{
|
||||
|
||||
class ActionIntegrityTask : public Task
|
||||
{
|
||||
public:
|
||||
ActionIntegrityTask( uint32_t resultId, Entity::CharaPtr pTarget, uint64_t delayTime );
|
||||
|
||||
void onQueue() override;
|
||||
void execute() override;
|
||||
std::string toString() override;
|
||||
|
||||
private:
|
||||
uint32_t m_resultId;
|
||||
Entity::CharaPtr m_pTarget;
|
||||
};
|
||||
|
||||
template< typename... Args >
|
||||
std::shared_ptr< ActionIntegrityTask > makeActionIntegrityTask( Args... args )
|
||||
{
|
||||
return std::make_shared< ActionIntegrityTask >( args... );
|
||||
}
|
||||
|
||||
}
|
|
@ -825,7 +825,7 @@ void Territory::updateSpawnPoints()
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t Territory::getNextEffectSequence()
|
||||
uint32_t Territory::getNextEffectResultId()
|
||||
{
|
||||
return m_effectCounter++;
|
||||
}
|
||||
|
|
|
@ -194,7 +194,7 @@ namespace Sapphire
|
|||
|
||||
void updateSpawnPoints();
|
||||
|
||||
uint32_t getNextEffectSequence();
|
||||
uint32_t getNextEffectResultId();
|
||||
|
||||
std::shared_ptr< World::Navi::NaviProvider > getNaviProvider();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue