1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-30 16:17:46 +00:00

Merge pull request #276 from NotAdam/actor_rewrite

instance player binding done, minor refactoring
This commit is contained in:
Mordred 2018-03-16 19:34:08 +01:00 committed by GitHub
commit f2684f6c7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 108 additions and 57 deletions

View file

@ -614,7 +614,7 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint32_t unknownC; uint32_t unknownC;
uint32_t charId; uint32_t charId;
uint32_t restedExp; uint32_t restedExp;
uint16_t unknown18; uint16_t currentLevel;
uint8_t maxLevel; uint8_t maxLevel;
uint8_t expansion; uint8_t expansion;
uint8_t unknown1A; uint8_t unknown1A;
@ -730,8 +730,8 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint16_t pvpFrontlineWeekly2nd; uint16_t pvpFrontlineWeekly2nd;
uint16_t pvpFrontlineWeekly3rd; uint16_t pvpFrontlineWeekly3rd;
uint8_t unknown61E; uint8_t unknown61E;
uint8_t unknown61F[32]; uint8_t centurioSealHunts[32];
uint8_t unknown63F[22]; uint8_t alliedSealHunts[22];
uint8_t tripleTriadCards[28]; uint8_t tripleTriadCards[28];
uint8_t unknown671[11]; uint8_t unknown671[11];
uint8_t unknownMask67C[22]; uint8_t unknownMask67C[22];
@ -739,12 +739,12 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint8_t orchestrionMask[40]; uint8_t orchestrionMask[40];
uint8_t hallOfNoviceCompleteMask[3]; uint8_t hallOfNoviceCompleteMask[3];
uint8_t unknownMask6C0[11]; uint8_t unknownMask6C0[11];
uint8_t unknownMask6CB[16]; uint8_t animaRelicMask[16]; // [2] = anima glass key item, [1] = ulan's note key item
uint8_t unknown6DB[14]; uint8_t unknown6DB[14];
uint8_t unlockedRaids[28]; uint8_t unlockedRaids[28];
uint8_t unlockedDungeons[18]; uint8_t unlockedDungeons[18];
uint8_t unlockedGuildhests[10]; uint8_t unlockedGuildhests[10];
uint8_t unlockedTrails[7]; uint8_t unlockedTrials[7];
uint8_t unlockedPvp[5]; uint8_t unlockedPvp[5];
uint8_t unknownMask72D[28]; uint8_t unknownMask72D[28];
uint8_t unknownMask749[18]; uint8_t unknownMask749[18];

View file

@ -6,7 +6,7 @@
#include <Exd/ExdDataGenerated.h> #include <Exd/ExdDataGenerated.h>
#include "Zone/TerritoryMgr.h" #include "Zone/TerritoryMgr.h"
#include "Zone/Zone.h" #include "Zone/InstanceContent.h"
#include "Network/GameConnection.h" #include "Network/GameConnection.h"
#include "Network/PacketWrappers/ServerNoticePacket.h" #include "Network/PacketWrappers/ServerNoticePacket.h"
@ -54,19 +54,25 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::GamePacket& i
{ {
auto pTeriMgr = g_fw.get< TerritoryMgr >(); auto pTeriMgr = g_fw.get< TerritoryMgr >();
auto pExdData = g_fw.get< Data::ExdDataGenerated >(); auto pExdData = g_fw.get< Data::ExdDataGenerated >();
// TODO use for loop for this
auto contentId1 = inPacket.getValAt< uint16_t >( 0x2E );
auto contentId2 = inPacket.getValAt< uint16_t >( 0x30 );
auto contentId3 = inPacket.getValAt< uint16_t >( 0x32 );
auto contentId4 = inPacket.getValAt< uint16_t >( 0x34 );
auto contentId5 = inPacket.getValAt< uint16_t >( 0x36 );
player.sendDebug( "Duty register request"); std::vector< uint16_t > selectedContent;
player.sendDebug( "ContentId1: " + std::to_string( contentId1 ) );
player.sendDebug( "ContentId2: " + std::to_string( contentId2 ) ); for( uint32_t offset = 0x2E; offset <= 0x36; offset += 0x2 )
player.sendDebug( "ContentId3: " + std::to_string( contentId3 ) ); {
player.sendDebug( "ContentId4: " + std::to_string( contentId4 ) ); auto id = inPacket.getValAt< uint16_t >( offset );
player.sendDebug( "ContentId5: " + std::to_string( contentId5 ) ); if( id == 0 )
break;
player.sendDebug( "got contentId: " + std::to_string( id ) );
selectedContent.push_back( id );
}
// todo: rand bias problem, will do for now tho
auto index = std::rand() % selectedContent.size();
auto contentId = selectedContent.at( index );
player.sendDebug( "Duty register request for contentid: " + std::to_string( contentId ) );
// let's cancel it because otherwise you can't register it again // let's cancel it because otherwise you can't register it again
ZoneChannelPacket< FFXIVIpcCFNotify > cfCancelPacket( player.getId() ); ZoneChannelPacket< FFXIVIpcCFNotify > cfCancelPacket( player.getId() );
@ -74,7 +80,7 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::GamePacket& i
cfCancelPacket.data().state2 = 1; // Your registration is withdrawn. cfCancelPacket.data().state2 = 1; // Your registration is withdrawn.
queueOutPacket( cfCancelPacket ); queueOutPacket( cfCancelPacket );
auto cfCondition = pExdData->get< Core::Data::ContentFinderCondition >( contentId1 ); auto cfCondition = pExdData->get< Core::Data::ContentFinderCondition >( contentId );
if( !cfCondition ) if( !cfCondition )
return; return;
@ -82,6 +88,9 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::GamePacket& i
if( !instance ) if( !instance )
return; return;
auto pInstance = instance->getAsInstanceContent();
pInstance->bindPlayer( player.getId() );
player.sendDebug( "Created instance with id: " + std::to_string( instance->getGuId() ) ); player.sendDebug( "Created instance with id: " + std::to_string( instance->getGuId() ) );
player.setInstance( instance ); player.setInstance( instance );
@ -90,6 +99,11 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::GamePacket& i
void Core::Network::GameConnection::cfRegisterRoulette( const Packets::GamePacket& inPacket, void Core::Network::GameConnection::cfRegisterRoulette( const Packets::GamePacket& inPacket,
Entity::Player& player) Entity::Player& player)
{ {
ZoneChannelPacket< FFXIVIpcCFNotify > cfCancelPacket( player.getId() );
cfCancelPacket.data().state1 = 3;
cfCancelPacket.data().state2 = 1; // Your registration is withdrawn.
queueOutPacket( cfCancelPacket );
player.sendDebug( "Roulette register" ); player.sendDebug( "Roulette register" );
} }

View file

@ -418,7 +418,9 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
// if the zone is an instanceContent instance, make sure the player is actually bound to it // if the zone is an instanceContent instance, make sure the player is actually bound to it
auto pInstance = instance->getAsInstanceContent(); auto pInstance = instance->getAsInstanceContent();
if( !pInstance->isPlayerBound( player.getId() ) )
// pInstance will be nullptr if you're accessing a normal zone via its allocated instance id rather than its zoneid
if( pInstance && !pInstance->isPlayerBound( player.getId() ) )
{ {
player.sendUrgent( "Not able to join instance: " + std::to_string( param1 ) ); player.sendUrgent( "Not able to join instance: " + std::to_string( param1 ) );
player.sendUrgent( "Player not bound! ( run !instance bind <instanceId> first ) " + std::to_string( param1 ) ); player.sendUrgent( "Player not bound! ( run !instance bind <instanceId> first ) " + std::to_string( param1 ) );

View file

@ -38,6 +38,7 @@ private:
m_data.gender = player.getLookAt( Common::CharaLook::Gender ); m_data.gender = player.getLookAt( Common::CharaLook::Gender );
m_data.currentClass = static_cast< uint8_t >( player.getClass() ); m_data.currentClass = static_cast< uint8_t >( player.getClass() );
m_data.currentJob = static_cast< uint8_t >( player.getClass() ); m_data.currentJob = static_cast< uint8_t >( player.getClass() );
m_data.currentLevel = player.getLevel();
m_data.deity = static_cast< uint8_t >( player.getGuardianDeity() ); m_data.deity = static_cast< uint8_t >( player.getGuardianDeity() );
m_data.namedayMonth = player.getBirthMonth(); m_data.namedayMonth = player.getBirthMonth();
m_data.namedayDay = player.getBirthDay(); m_data.namedayDay = player.getBirthDay();
@ -74,6 +75,17 @@ private:
m_data.maxLevel = 0x46; m_data.maxLevel = 0x46;
m_data.expansion = 2; m_data.expansion = 2;
// df stuff
// todo: actually do this properly
m_data.unknown70[4] = 1; // enable df
// enable all raids/guildhests/dungeons
memset( m_data.unlockedDungeons, 0xFF, sizeof( m_data.unlockedDungeons ) );
memset( m_data.unlockedGuildhests, 0xFF, sizeof( m_data.unlockedGuildhests ) );
memset( m_data.unlockedPvp, 0xFF, sizeof( m_data.unlockedPvp ) );
memset( m_data.unlockedRaids, 0xFF, sizeof( m_data.unlockedRaids ) );
memset( m_data.unlockedTrials, 0xFF, sizeof( m_data.unlockedTrials ) );
}; };
}; };

View file

@ -27,19 +27,19 @@ using namespace Core::Common;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server; using namespace Core::Network::Packets::Server;
Core::InstanceContent::InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceContent, Core::InstanceContent::InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceConfiguration,
uint32_t guId, uint32_t guId,
const std::string& internalName, const std::string& internalName,
const std::string& contentName, const std::string& contentName,
uint32_t instanceContentId ) uint32_t instanceContentId )
: Zone( static_cast< uint16_t >( pInstanceContent->territoryType ), guId, internalName, contentName ), : Zone( static_cast< uint16_t >( pInstanceConfiguration->territoryType ), guId, internalName, contentName ),
Director( Event::Director::InstanceContent, instanceContentId ), Director( Event::Director::InstanceContent, instanceContentId ),
m_instanceContentInfo( pInstanceContent ), m_instanceConfiguration( pInstanceConfiguration ),
m_instanceContentId( instanceContentId ), m_instanceContentId( instanceContentId ),
m_state( Created ), m_state( Created ),
m_pEntranceEObj( nullptr ), m_pEntranceEObj( nullptr ),
m_instanceCommenceTime( 0 ), m_instanceCommenceTime( 0 ),
m_currentBgm( pInstanceContent->bGM ) m_currentBgm( pInstanceConfiguration->bGM )
{ {
} }
@ -63,15 +63,15 @@ uint32_t Core::InstanceContent::getInstanceContentId() const
return m_instanceContentId; return m_instanceContentId;
} }
Core::Data::ExdDataGenerated::InstanceContentPtr Core::InstanceContent::getInstanceContentInfo() const Core::Data::ExdDataGenerated::InstanceContentPtr Core::InstanceContent::getInstanceConfiguration() const
{ {
return m_instanceContentInfo; return m_instanceConfiguration;
} }
void Core::InstanceContent::onPlayerZoneIn( Entity::Player& player ) void Core::InstanceContent::onPlayerZoneIn( Entity::Player& player )
{ {
auto pLog = g_fw.get< Logger >(); auto pLog = g_fw.get< Logger >();
pLog->debug( "InstanceContent::onEnterTerritory: Zone#" + std::to_string( getGuId() ) + "|" pLog->debug( "InstanceContent::onPlayerZoneIn: Zone#" + std::to_string( getGuId() ) + "|"
+ std::to_string( getInstanceContentId() ) + + std::to_string( getInstanceContentId() ) +
+ ", Entity#" + std::to_string( player.getId() ) ); + ", Entity#" + std::to_string( player.getId() ) );
@ -100,26 +100,28 @@ void Core::InstanceContent::onLeaveTerritory( Entity::Player& player )
void Core::InstanceContent::onUpdate( uint32_t currTime ) void Core::InstanceContent::onUpdate( uint32_t currTime )
{ {
// TODO: check all players if still bound, if not, remove
// needs to happen regardless of state
switch( m_state ) switch( m_state )
{ {
case Created: case Created:
{ {
// temporary handling for instance state progression if( m_boundPlayerIds.size() == 0 )
if( m_playerMap.size() < 1 )
return; return;
// TODO: 1. check all bound players instead of just players in instance at the time for( const auto playerId : m_boundPlayerIds )
{
auto it = m_playerMap.find( playerId );
if( it == m_playerMap.end() )
return;
}
for( const auto& playerIt : m_playerMap ) for( const auto& playerIt : m_playerMap )
{ {
if( !playerIt.second->isLoadingComplete() || const auto& player = playerIt.second;
!playerIt.second->isDirectorInitialized() ||
!playerIt.second->isOnEnterEventDone() || if( !player->isLoadingComplete() ||
playerIt.second->hasStateFlag( PlayerStateFlag::WatchingCutscene ) ) !player->isDirectorInitialized() ||
!player->isOnEnterEventDone() ||
player->hasStateFlag( PlayerStateFlag::WatchingCutscene ) )
return; return;
} }
@ -136,13 +138,13 @@ void Core::InstanceContent::onUpdate( uint32_t currTime )
auto pPlayer = playerIt.second; auto pPlayer = playerIt.second;
pPlayer->queuePacket( pPlayer->queuePacket(
ActorControlPacket143( pPlayer->getId(), DirectorUpdate, ActorControlPacket143( pPlayer->getId(), DirectorUpdate,
getDirectorId(), 0x40000001, m_instanceContentInfo->timeLimitmin * 60u ) ); getDirectorId(), 0x40000001, m_instanceConfiguration->timeLimitmin * 60u ) );
} }
if( m_pEntranceEObj ) if( m_pEntranceEObj )
m_pEntranceEObj->setState( 7 ); m_pEntranceEObj->setState( 7 );
m_state = DutyInProgress; m_state = DutyInProgress;
m_instanceExpireTime = Util::getTimeSeconds() + ( m_instanceContentInfo->timeLimitmin * 60u ); m_instanceExpireTime = Util::getTimeSeconds() + ( m_instanceConfiguration->timeLimitmin * 60u );
break; break;
} }
@ -159,9 +161,9 @@ void Core::InstanceContent::onUpdate( uint32_t currTime )
case DutyFinished: case DutyFinished:
break; break;
} }
auto pScriptMgr = g_fw.get< Scripting::ScriptMgr >(); auto pScriptMgr = g_fw.get< Scripting::ScriptMgr >();
pScriptMgr->onInstanceUpdate( getAsInstanceContent(), currTime ); pScriptMgr->onInstanceUpdate( getAsInstanceContent(), currTime );
} }
void Core::InstanceContent::onFinishLoading( Entity::Player& player ) void Core::InstanceContent::onFinishLoading( Entity::Player& player )
@ -338,6 +340,10 @@ Core::InstanceContent::InstanceContentState Core::InstanceContent::getState() co
void Core::InstanceContent::onBeforePlayerZoneIn( Core::Entity::Player& player ) void Core::InstanceContent::onBeforePlayerZoneIn( Core::Entity::Player& player )
{ {
// remove any players from the instance who aren't bound on zone in
if( !isPlayerBound( player.getId() ) )
player.exitInstance();
// if a player has already spawned once inside this instance, don't move them if they happen to zone in again // if a player has already spawned once inside this instance, don't move them if they happen to zone in again
if( !hasPlayerPreviouslySpawned( player ) ) if( !hasPlayerPreviouslySpawned( player ) )
{ {
@ -411,6 +417,11 @@ void Core::InstanceContent::setCurrentBGM( uint16_t bgmIndex )
} }
} }
void Core::InstanceContent::setPlayerBGM( Core::Entity::Player& player, uint16_t bgmId )
{
player.queuePacket( ActorControlPacket143( player.getId(), DirectorUpdate, getDirectorId(), 0x80000001, bgmId ) );
}
uint16_t Core::InstanceContent::getCurrentBGM() const uint16_t Core::InstanceContent::getCurrentBGM() const
{ {
return m_currentBgm; return m_currentBgm;
@ -438,4 +449,8 @@ bool Core::InstanceContent::isPlayerBound( uint32_t playerId ) const
void Core::InstanceContent::unbindPlayer( uint32_t playerId ) void Core::InstanceContent::unbindPlayer( uint32_t playerId )
{ {
m_boundPlayerIds.erase( playerId ); m_boundPlayerIds.erase( playerId );
auto it = m_playerMap.find( playerId );
if( it != m_playerMap.end() )
it->second->exitInstance();
} }

View file

@ -22,7 +22,7 @@ public:
DutyFinished DutyFinished
}; };
InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceContent, InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceConfiguration,
uint32_t guId, uint32_t guId,
const std::string& internalName, const std::string& internalName,
const std::string& contentName, const std::string& contentName,
@ -51,14 +51,16 @@ public:
void endEventCutscene(); void endEventCutscene();
/*! set the current bgm index (inside bgm.exd) */ /*! set the current bgm index (inside bgm.exd) */
void setCurrentBGM( uint16_t bgmIndex ); void setCurrentBGM( uint16_t bgmId );
/*! set the current bgm for a specific player */
void setPlayerBGM( Entity::Player& player, uint16_t bgmId );
/*! get the currently playing bgm index */ /*! get the currently playing bgm index */
uint16_t getCurrentBGM() const; uint16_t getCurrentBGM() const;
bool hasPlayerPreviouslySpawned( Entity::Player& player ) const; bool hasPlayerPreviouslySpawned( Entity::Player& player ) const;
InstanceContentState getState() const; InstanceContentState getState() const;
boost::shared_ptr< Core::Data::InstanceContent > getInstanceContentInfo() const; boost::shared_ptr< Core::Data::InstanceContent > getInstanceConfiguration() const;
uint32_t getInstanceContentId() const; uint32_t getInstanceContentId() const;
@ -77,7 +79,7 @@ public:
const uint32_t instanceStartDelay = 1250; const uint32_t instanceStartDelay = 1250;
private: private:
boost::shared_ptr< Core::Data::InstanceContent > m_instanceContentInfo; boost::shared_ptr< Core::Data::InstanceContent > m_instanceConfiguration;
uint32_t m_instanceContentId; uint32_t m_instanceContentId;
InstanceContentState m_state; InstanceContentState m_state;
uint16_t m_currentBgm; uint16_t m_currentBgm;

View file

@ -70,15 +70,18 @@ bool Core::TerritoryMgr::isInstanceContentTerritory( uint32_t territoryTypeId )
if( !pTeri ) if( !pTeri )
return false; return false;
return pTeri->territoryIntendedUse == TerritoryIntendedUse::AllianceRaid || auto intendedUse = pTeri->territoryIntendedUse;
pTeri->territoryIntendedUse == TerritoryIntendedUse::BeforeTrialDung ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Trial || return intendedUse == TerritoryIntendedUse::AllianceRaid ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Dungeon || intendedUse == TerritoryIntendedUse::BeforeTrialDung ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::OpenWorldInstanceBattle || intendedUse == TerritoryIntendedUse::Trial ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::PalaceOfTheDead || intendedUse == TerritoryIntendedUse::Dungeon ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::RaidFights || intendedUse == TerritoryIntendedUse::OpenWorldInstanceBattle ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Raids || intendedUse == TerritoryIntendedUse::PalaceOfTheDead ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::TreasureMapInstance; intendedUse == TerritoryIntendedUse::RaidFights ||
intendedUse == TerritoryIntendedUse::Raids ||
intendedUse == TerritoryIntendedUse::TreasureMapInstance ||
intendedUse == TerritoryIntendedUse::EventTrial;
} }
bool Core::TerritoryMgr::isPrivateTerritory( uint32_t territoryTypeId ) const bool Core::TerritoryMgr::isPrivateTerritory( uint32_t territoryTypeId ) const

View file

@ -53,7 +53,10 @@ namespace Core
FreeCompanyGarrison = 30, FreeCompanyGarrison = 30,
PalaceOfTheDead = 31, PalaceOfTheDead = 31,
TreasureMapInstance = 33, TreasureMapInstance = 33,
EventArea = 40, EventTrial = 36,
TheFeastArea = 37,
PrivateEventArea = 40,
//Eureka = 41, // wat
}; };
TerritoryMgr(); TerritoryMgr();