diff --git a/.gitmodules b/.gitmodules index 69f7a3a6..a7b40f34 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "deps/spdlog"] path = deps/spdlog url = https://github.com/gabime/spdlog.git +[submodule "deps/recastnavigation"] + path = deps/recastnavigation + url = https://github.com/SapphireServer/recastnavigation diff --git a/CMakeLists.txt b/CMakeLists.txt index a1e8b0d4..9623c60e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ add_subdirectory( "deps/zlib" ) add_subdirectory( "deps/MySQL" ) add_subdirectory( "deps/datReader" ) add_subdirectory( "deps/mysqlConnector" ) +add_subdirectory( "deps/recastnavigation" ) ############################## # Main Sapphire Components # diff --git a/deps/recastnavigation b/deps/recastnavigation new file mode 160000 index 00000000..d24db2de --- /dev/null +++ b/deps/recastnavigation @@ -0,0 +1 @@ +Subproject commit d24db2de131d6be5a1bc38067fa8b649544a0dd2 diff --git a/src/common/Network/GamePacketNew.h b/src/common/Network/GamePacketNew.h index 0bb8a078..c32b8478 100644 --- a/src/common/Network/GamePacketNew.h +++ b/src/common/Network/GamePacketNew.h @@ -258,7 +258,7 @@ namespace Sapphire::Network::Packets // The IPC type itself. m_ipcHdr.type = static_cast< ServerZoneIpcType >( m_data._ServerIpcType ); - m_ipcHdr.timestamp = static_cast< uint32_t >( Util::getTimeSeconds() ); + m_ipcHdr.timestamp = Util::getTimeSeconds(); m_segHdr.size = sizeof( T ) + sizeof( FFXIVARR_IPC_HEADER ) + sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ); }; diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index f6f25116..08edad4e 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -119,35 +119,39 @@ namespace Sapphire::Network::Packets PlayerSpawn = 0x0175, // updated 4.5 NpcSpawn = 0x0176, // updated 4.5 + NpcSpawn2 = 0x0177, // ( Bigger statuseffectlist? ) updated 4.5 ActorMove = 0x0178, // updated 4.5 + ActorSetPos = 0x017A, // updated 4.5 ActorCast = 0x017C, // updated 4.5 PartyList = 0x017E, // updated 4.5 - HateList = 0x017F, // updated 4.5 + HateList = 0x0180, // updated 4.5 ObjectSpawn = 0x0181, // updated 4.5 ObjectDespawn = 0x0182, // updated 4.5 - UpdateClassInfo = 0x0183, // updated 4.5 SilentSetClassJob = 0x0184, // updated 4.5 - seems to be the case, not sure if it's actually used for anything - InitUI = 0x0185, // updated 4.5 PlayerStats = 0x0186, // updated 4.5 ActorOwner = 0x0187, // updated 4.5 PlayerStateFlags = 0x0188, // updated 4.5 PlayerClassInfo = 0x0189, // updated 4.5 + ModelEquip = 0x018B, // updated 4.5 Examine = 0x018C, // updated 4.5 CharaNameReq = 0x018D, // updated 4.5 + SetLevelSync = 0x1186, // not updated for 4.4, not sure what it is anymore ItemInfo = 0x0196, // updated 4.5 ContainerInfo = 0x0197, // updated 4.5 InventoryTransactionFinish = 0x0198, // updated 4.5 InventoryTransaction = 0x0199, // updated 4.5 + CurrencyCrystalInfo = 0x019B, // updated 4.5 + InventoryActionAck = 0x019D, // updated 4.5 UpdateInventorySlot = 0x019E, // updated 4.5 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index c1c3cf93..ef70853c 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -698,8 +698,7 @@ struct FFXIVIpcActorSetPos : * Structural representation of the packet sent by the server * to start an actors casting */ -struct FFXIVIpcActorCast : - FFXIVIpcBasePacket< ActorCast > +struct FFXIVIpcActorCast : FFXIVIpcBasePacket< ActorCast > { uint16_t action_id; Common::SkillType skillType; @@ -715,11 +714,10 @@ struct FFXIVIpcActorCast : uint16_t unknown_3; }; -struct FFXIVIpcHateList : - FFXIVIpcBasePacket< HateList > +struct FFXIVIpcHateList : FFXIVIpcBasePacket< HateList > { uint32_t numEntries; - struct LsEntry + struct { uint32_t actorId; uint8_t hatePercent; @@ -729,8 +727,7 @@ struct FFXIVIpcHateList : uint32_t padding; }; -struct FFXIVIpcUpdateClassInfo : - FFXIVIpcBasePacket< UpdateClassInfo > +struct FFXIVIpcUpdateClassInfo : FFXIVIpcBasePacket< UpdateClassInfo > { uint8_t classId; uint8_t level1; diff --git a/src/common/Util/Util.cpp b/src/common/Util/Util.cpp index 78db7be7..f443ddf8 100644 --- a/src/common/Util/Util.cpp +++ b/src/common/Util/Util.cpp @@ -119,10 +119,10 @@ uint64_t Sapphire::Util::getTimeMs() return epoch.count(); } -int64_t Sapphire::Util::getTimeSeconds() +uint32_t Sapphire::Util::getTimeSeconds() { - std::chrono::seconds epoch = std::chrono::seconds( std::time( nullptr ) ); - return epoch.count(); + auto currClock = std::chrono::system_clock::now(); + return std::chrono::time_point_cast< std::chrono::seconds >( currClock ).time_since_epoch().count(); } uint64_t Sapphire::Util::getEorzeanTimeStamp() diff --git a/src/common/Util/Util.h b/src/common/Util/Util.h index ab810cef..faea94c6 100644 --- a/src/common/Util/Util.h +++ b/src/common/Util/Util.h @@ -21,7 +21,12 @@ namespace Sapphire::Util uint64_t getTimeMs(); - int64_t getTimeSeconds(); + /*! + * @brief Get a POSIX epoch representation of the current time + * @return 32-bit unsigned integer + */ + + uint32_t getTimeSeconds(); uint64_t getEorzeanTimeStamp(); diff --git a/src/tools/pcb_reader/CMakeLists.txt b/src/tools/pcb_reader/CMakeLists.txt index 0a51293b..96b4af4e 100644 --- a/src/tools/pcb_reader/CMakeLists.txt +++ b/src/tools/pcb_reader/CMakeLists.txt @@ -8,9 +8,12 @@ file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*") add_executable(pcb_reader2 ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES}) if (UNIX) - target_link_libraries (pcb_reader2 common xivdat pthread mysqlclient dl z stdc++fs ) + target_link_libraries( pcb_reader2 common xivdat pthread mysqlclient dl z stdc++fs Recast Detour ) else() - target_link_libraries (pcb_reader2 common xivdat mysql zlib) + target_link_libraries( pcb_reader2 common xivdat mysql zlib Recast Detour ) endif() +target_include_directories( pcb_reader2 + PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/../../deps/" ) diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index d95e9056..86b5f402 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -61,6 +61,7 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX m_pos.z = posZ; m_rot = rot; m_level = level; + m_invincibilityType = InvincibilityNone; m_pCurrentZone = pZone; @@ -130,6 +131,11 @@ void Sapphire::Entity::BNpc::spawn( PlayerPtr pTarget ) pTarget->queuePacket( std::make_shared< NpcSpawnPacket >( *getAsBNpc(), *pTarget ) ); } +void Sapphire::Entity::BNpc::despawn( PlayerPtr pTarget ) +{ + pTarget->freePlayerSpawnId( getId() ); +} + Sapphire::Entity::BNpcState Sapphire::Entity::BNpc::getState() const { return m_state; @@ -243,7 +249,7 @@ void Sapphire::Entity::BNpc::hateListRemove( Sapphire::Entity::CharaPtr pChara ) if( pChara->isPlayer() ) { PlayerPtr tmpPlayer = pChara->getAsPlayer(); - //tmpPlayer->onMobDeaggro( getAsBattleNpc() ); + tmpPlayer->onMobDeaggro( getAsBNpc() ); } return; } @@ -273,7 +279,7 @@ void Sapphire::Entity::BNpc::aggro( Sapphire::Entity::CharaPtr pChara ) { PlayerPtr tmpPlayer = pChara->getAsPlayer(); tmpPlayer->queuePacket( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 0, 1, 1 ) ); - //tmpPlayer->onMobAggro( getAsBattleNpc() ); + tmpPlayer->onMobAggro( getAsBNpc() ); } } @@ -285,7 +291,7 @@ void Sapphire::Entity::BNpc::deaggro( Sapphire::Entity::CharaPtr pChara ) if( pChara->isPlayer() ) { PlayerPtr tmpPlayer = pChara->getAsPlayer(); - //tmpPlayer->onMobDeaggro( getAsBattleNpc() ); + tmpPlayer->onMobDeaggro( getAsBNpc() ); } } @@ -295,6 +301,9 @@ void Sapphire::Entity::BNpc::update( int64_t currTime ) const uint8_t aggroRange = 8; const uint8_t maxDistanceToOrigin = 30; + if( m_status == ActorStatus::Dead ) + return; + switch( m_state ) { case BNpcState::Retreat: @@ -306,6 +315,10 @@ void Sapphire::Entity::BNpc::update( int64_t currTime ) case BNpcState::Idle: { + // passive mobs should ignore players unless aggro'd + if( m_aggressionMode == 1 ) + return; + CharaPtr pClosestChara = getClosestChara(); if( pClosestChara && pClosestChara->isAlive() ) diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index 65bd166a..04a39164 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -44,6 +44,7 @@ namespace Sapphire::Entity virtual ~BNpc() override; void spawn( PlayerPtr pTarget ) override; + void despawn( PlayerPtr pTarget ) override; uint16_t getModelChara() const; uint8_t getLevel() const override; diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 991975e9..aef8cbe2 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -10,6 +10,7 @@ #include "Session.h" #include "Player.h" +#include "BNpc.h" #include "Manager/HousingMgr.h" #include "Manager/TerritoryMgr.h" @@ -1348,6 +1349,45 @@ void Sapphire::Entity::Player::initHateSlotQueue() m_freeHateSlotQueue.push( i ); } +void Sapphire::Entity::Player::hateListAdd( BNpcPtr pBNpc ) +{ + if( !m_freeHateSlotQueue.empty() ) + { + uint8_t hateId = m_freeHateSlotQueue.front(); + m_freeHateSlotQueue.pop(); + m_actorIdTohateSlotMap[ pBNpc->getId() ] = hateId; + sendHateList(); + } +} + +void Sapphire::Entity::Player::hateListRemove( BNpcPtr pBNpc ) +{ + + auto it = m_actorIdTohateSlotMap.begin(); + for( ; it != m_actorIdTohateSlotMap.end(); ++it ) + { + if( it->first == pBNpc->getId() ) + { + uint8_t hateSlot = it->second; + m_freeHateSlotQueue.push( hateSlot ); + m_actorIdTohateSlotMap.erase( it ); + sendHateList(); + + return; + } + } +} + +bool Sapphire::Entity::Player::hateListHasEntry( BNpcPtr pBNpc ) +{ + for( const auto& entry : m_actorIdTohateSlotMap ) + { + if( entry.first == pBNpc->getId() ) + return true; + } + return false; +} + void Sapphire::Entity::Player::sendHateList() { auto hateListPacket = makeZonePacket< FFXIVIpcHateList >( getId() ); @@ -1361,6 +1401,19 @@ void Sapphire::Entity::Player::sendHateList() queuePacket( hateListPacket ); } +void Sapphire::Entity::Player::onMobAggro( BNpcPtr pBNpc ) +{ + hateListAdd( pBNpc ); + queuePacket( makeActorControl142( getId(), ToggleAggro, 1 ) ); +} + +void Sapphire::Entity::Player::onMobDeaggro( BNpcPtr pBNpc ) +{ + hateListRemove( pBNpc ); + if( m_actorIdTohateSlotMap.empty() ) + queuePacket( makeActorControl142( getId(), ToggleAggro ) ); +} + bool Sapphire::Entity::Player::isLogin() const { return m_bIsLogin; @@ -1533,7 +1586,7 @@ uint32_t Sapphire::Entity::Player::getCFPenaltyMinutes() const void Sapphire::Entity::Player::setCFPenaltyMinutes( uint32_t minutes ) { auto currentTimestamp = Sapphire::Util::getTimeSeconds(); - setCFPenaltyTimestamp( static_cast< uint32_t >( currentTimestamp + minutes * 60 ) ); + setCFPenaltyTimestamp( currentTimestamp + minutes * 60 ); } uint8_t Sapphire::Entity::Player::getOpeningSequence() const diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 92a575e7..3c4382da 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -798,6 +798,11 @@ namespace Sapphire::Entity ////////////////////////////////////////////////////////////////////////////////////////////////////// void initHateSlotQueue(); + void hateListAdd( BNpcPtr pBNpc ); + void hateListRemove( BNpcPtr pBNpc ); + + bool hateListHasEntry( BNpcPtr pBNpc ); + void sendHateList(); bool actionHasCastTime( uint32_t actionId ); @@ -831,6 +836,9 @@ namespace Sapphire::Entity bool isAutoattackOn() const; + void onMobAggro( BNpcPtr pBNpc ); + void onMobDeaggro( BNpcPtr pBNpc ); + // Content Finder handling ////////////////////////////////////////////////////////////////////////////////////////////////////// /*! Get an unix time when the player can register into content finder again. */ diff --git a/src/world/Manager/MarketMgr.cpp b/src/world/Manager/MarketMgr.cpp index d18d28e1..5022471a 100644 --- a/src/world/Manager/MarketMgr.cpp +++ b/src/world/Manager/MarketMgr.cpp @@ -83,12 +83,11 @@ void Sapphire::World::Manager::MarketMgr::requestItemListingInfo( Sapphire::Enti listing.itemCatalogId = catalogId; listing.quantity = i + 1; - listing.purchaseTime = time( nullptr ); + listing.purchaseTime = Sapphire::Util::getTimeSeconds(); listing.salePrice = 69420420; listing.isHq = 1; listing.onMannequin = 1; - strcpy( listing.buyerName, name.c_str() ); } diff --git a/src/world/Manager/RNGMgr.cpp b/src/world/Manager/RNGMgr.cpp new file mode 100644 index 00000000..69c21185 --- /dev/null +++ b/src/world/Manager/RNGMgr.cpp @@ -0,0 +1,10 @@ +#include "RNGMgr.h" +#include + +Sapphire::World::Manager::RNGMgr::RNGMgr( FrameworkPtr pFw ) : + BaseManager( pFw ), + m_engine( *engineSeed< std::mt19937::state_size >() ) +{ + +} + diff --git a/src/world/Manager/RNGMgr.h b/src/world/Manager/RNGMgr.h new file mode 100644 index 00000000..a91325f2 --- /dev/null +++ b/src/world/Manager/RNGMgr.h @@ -0,0 +1,94 @@ +#ifndef SAPPHIRE_RNGMGR_H +#define SAPPHIRE_RNGMGR_H + +#include "Forwards.h" +#include "BaseManager.h" + +#include +#include +#include +#include +#include +#include + +namespace Sapphire::World::Manager +{ + /*! + * @brief Generator object that is used on multiple state situations + */ + template< typename T, typename = typename std::enable_if< std::is_arithmetic< T >::value, T >::type > + class RandGenerator + { + public: + RandGenerator( T minRange = std::numeric_limits< T >::min(), T maxRange = std::numeric_limits< T >::max() ) + : m_engine( *engineSeed< std::mt19937::state_size >() ), m_dist( minRange, maxRange ) + { + + } + + T next() + { + return m_dist( m_engine ); + } + private: + template< std::size_t STATE_SIZE > + std::unique_ptr< std::seed_seq > engineSeed() + { + std::array< uint32_t, STATE_SIZE > seedArray; + std::random_device rd; + + std::generate_n( seedArray.data(), seedArray.size(), std::ref( rd ) ); + auto pSeq = std::make_unique< std::seed_seq >( std::begin( seedArray ), std::end( seedArray ) ); + + return pSeq; + } + + std::uniform_real_distribution< T > m_dist; + std::mt19937 m_engine; + }; + + class RNGMgr : public BaseManager + { + + public: + + + RNGMgr( FrameworkPtr pFw ); + virtual ~RNGMgr() = default; + + RNGMgr( const RNGMgr& pRNGMgr ) = delete; + RNGMgr& operator=( const RNGMgr& pRNGMgr ) = delete; + + /*! + * @brief Creates a RNG with specified parameters for multiple uses + * @tparam Numeric type to be used for the generator + * @param Minimum value possible for the random value + * @param Maximum value possible for the random value + * @return Random number generator object + */ + template< typename T, typename = typename std::enable_if< std::is_arithmetic< T >::value, T >::type > + RandGenerator< T > getRandGenerator( T minRange, T maxRange ) + { + return RandGenerator< T >( minRange, maxRange ); + } + + private: + + template< std::size_t STATE_SIZE > + std::unique_ptr< std::seed_seq > engineSeed() + { + std::array< uint32_t, STATE_SIZE > seedArray; + std::random_device rd; + + std::generate_n( seedArray.data(), seedArray.size(), std::ref( rd ) ); + auto pSeq = std::make_unique< std::seed_seq >( std::begin( seedArray ), std::end( seedArray ) ); + + return pSeq; + } + + std::mt19937 m_engine; + }; + +} + +#endif // SAPPHIRE_RNGMGR_H diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index 13523dcd..006ee48b 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -385,6 +385,7 @@ void Sapphire::Network::GameConnection::handlePackets( const Sapphire::Network:: const std::vector< Sapphire::Network::Packets::FFXIVARR_PACKET_RAW >& packetData ) { auto pServerZone = m_pFw->get< World::ServerMgr >(); + // if a session is set, update the last time it recieved a game packet if( m_pSession ) m_pSession->updateLastDataTime(); @@ -427,7 +428,7 @@ void Sapphire::Network::GameConnection::handlePackets( const Sapphire::Network:: auto pe = std::make_shared< FFXIVRawPacket >( 0x07, 0x18, 0, 0 ); *( unsigned int* ) ( &pe->data()[ 0 ] ) = 0xE0037603; - *( unsigned int* ) ( &pe->data()[ 4 ] ) = static_cast< uint32_t >( time( nullptr ) ); + *( unsigned int* ) ( &pe->data()[ 4 ] ) = Sapphire::Util::getTimeSeconds(); sendSinglePacket( pe ); // main connection, assinging it to the session diff --git a/src/world/Network/Handlers/PacketHandlers.cpp b/src/world/Network/Handlers/PacketHandlers.cpp index fecf8ed9..956b1d9e 100644 --- a/src/world/Network/Handlers/PacketHandlers.cpp +++ b/src/world/Network/Handlers/PacketHandlers.cpp @@ -14,10 +14,8 @@ #include "Network/GameConnection.h" -#include "Manager/TerritoryMgr.h" #include "Territory/Zone.h" #include "Territory/HousingZone.h" -#include "Manager/HousingMgr.h" #include "Territory/Land.h" #include "Territory/ZonePosition.h" #include "Territory/House.h" @@ -37,6 +35,9 @@ #include "Manager/DebugCommandMgr.h" #include "Manager/EventMgr.h" #include "Manager/MarketMgr.h" +#include "Manager/TerritoryMgr.h" +#include "Manager/HousingMgr.h" +#include "Manager/RNGMgr.h" #include "Action/Action.h" #include "Action/ActionTeleport.h" @@ -440,7 +441,7 @@ void Sapphire::Network::GameConnection::pingHandler( FrameworkPtr pFw, queueOutPacket( std::make_shared< Server::PingPacket >( player, packet.data().timestamp ) ); - player.setLastPing( static_cast< uint32_t >( time( nullptr ) ) ); + player.setLastPing( Sapphire::Util::getTimeSeconds() ); } diff --git a/src/world/Network/PacketWrappers/NpcSpawnPacket.h b/src/world/Network/PacketWrappers/NpcSpawnPacket.h index ce6a0005..f487c50f 100644 --- a/src/world/Network/PacketWrappers/NpcSpawnPacket.h +++ b/src/world/Network/PacketWrappers/NpcSpawnPacket.h @@ -75,18 +75,13 @@ namespace Sapphire::Network::Packets::Server m_data.bNPCBase = bnpc.getBNpcBaseId(); m_data.bNPCName = bnpc.getBNpcNameId(); - m_data.state = 1; - if( target.getId() == bnpc.getId() ) - { - m_data.spawnIndex = 0x00; - } - else - { - m_data.spawnIndex = target.getSpawnIdForActorId( bnpc.getId() ); + assert( target.getId() != bnpc.getId() ); + + m_data.spawnIndex = target.getSpawnIdForActorId( bnpc.getId() ); + + if( !target.isActorSpawnIdValid( m_data.spawnIndex ) ) + return; - if( !target.isActorSpawnIdValid( m_data.spawnIndex ) ) - return; - } // 0x20 == spawn hidden to be displayed by the spawneffect control //m_data.displayFlags = bnpc.getDisplayFlags(); diff --git a/src/world/ServerMgr.cpp b/src/world/ServerMgr.cpp index c16092b0..3de61f73 100644 --- a/src/world/ServerMgr.cpp +++ b/src/world/ServerMgr.cpp @@ -40,6 +40,7 @@ #include "Manager/EventMgr.h" #include "Manager/ItemMgr.h" #include "Manager/MarketMgr.h" +#include "Manager/RNGMgr.h" using namespace Sapphire::World::Manager; @@ -205,6 +206,7 @@ void Sapphire::World::ServerMgr::run( int32_t argc, char* argv[] ) auto pInventoryMgr = std::make_shared< Manager::InventoryMgr >( framework() ); auto pEventMgr = std::make_shared< Manager::EventMgr >( framework() ); auto pItemMgr = std::make_shared< Manager::ItemMgr >( framework() ); + auto pRNGMgr = std::make_shared< Manager::RNGMgr >( framework() ); framework()->set< DebugCommandMgr >( pDebugCom ); framework()->set< Manager::PlayerMgr >( pPlayerMgr ); @@ -212,6 +214,7 @@ void Sapphire::World::ServerMgr::run( int32_t argc, char* argv[] ) framework()->set< Manager::InventoryMgr >( pInventoryMgr ); framework()->set< Manager::EventMgr >( pEventMgr ); framework()->set< Manager::ItemMgr >( pItemMgr ); + framework()->set< Manager::RNGMgr >( pRNGMgr ); Logger::info( "World server running on {0}:{1}", m_ip, m_port ); @@ -256,7 +259,7 @@ void Sapphire::World::ServerMgr::mainLoop() auto currTime = Util::getTimeSeconds(); - pTeriMgr->updateTerritoryInstances( static_cast< uint32_t >( currTime ) ); + pTeriMgr->updateTerritoryInstances( currTime ); pScriptMgr->update(); @@ -473,7 +476,7 @@ Sapphire::Entity::BNpcTemplatePtr Sapphire::World::ServerMgr::getBNpcTemplate( c Sapphire::Entity::BNpcTemplatePtr Sapphire::World::ServerMgr::getBNpcTemplate( uint32_t id ) { - for( auto entry : m_bNpcTemplateMap ) + for( const auto& entry : m_bNpcTemplateMap ) { if( entry.second->getId() == id ) return entry.second; diff --git a/src/world/Session.cpp b/src/world/Session.cpp index 682fdb45..6f49d45f 100644 --- a/src/world/Session.cpp +++ b/src/world/Session.cpp @@ -206,7 +206,7 @@ void Sapphire::World::Session::update() // SESSION LOGIC m_pPlayer->update( Util::getTimeMs() ); - if( ( static_cast< uint32_t >( Util::getTimeSeconds() ) - static_cast< uint32_t >( getLastSqlTime() ) ) > 10 ) + if( Util::getTimeSeconds() - static_cast< uint32_t >( getLastSqlTime() ) > 10 ) { updateLastSqlTime(); m_pPlayer->updateSql(); diff --git a/src/world/Session.h b/src/world/Session.h index d51122be..97d51241 100644 --- a/src/world/Session.h +++ b/src/world/Session.h @@ -56,9 +56,9 @@ namespace Sapphire::World Entity::PlayerPtr m_pPlayer; - int64_t m_lastDataTime; + uint32_t m_lastDataTime; - int64_t m_lastSqlTime; + uint32_t m_lastSqlTime; bool m_isValid; bool m_isReplaying; diff --git a/src/world/Territory/Housing/HousingInteriorTerritory.cpp b/src/world/Territory/Housing/HousingInteriorTerritory.cpp index 1121e268..4d0b436e 100644 --- a/src/world/Territory/Housing/HousingInteriorTerritory.cpp +++ b/src/world/Territory/Housing/HousingInteriorTerritory.cpp @@ -39,7 +39,7 @@ Sapphire::World::Territory::Housing::HousingInteriorTerritory::HousingInteriorTe Zone( territoryTypeId, guId, internalName, contentName, pFw ), m_landIdent( ident ) { - m_lastActivityTime = static_cast< uint32_t >( Util::getTimeSeconds() ); + m_lastActivityTime = Util::getTimeSeconds(); } Housing::HousingInteriorTerritory::~HousingInteriorTerritory() = default; diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index 15411d24..a0cf5cbc 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -30,7 +30,7 @@ Sapphire::Land::Land( uint16_t territoryTypeId, uint8_t wardNum, uint8_t landId, Sapphire::Data::HousingLandSetPtr info, FrameworkPtr pFw ) : m_currentPrice( 0 ), m_minPrice( 0 ), - m_nextDrop( static_cast< uint32_t >( Util::getTimeSeconds() ) + 21600 ), + m_nextDrop( Util::getTimeSeconds() + 21600 ), m_ownerId( 0 ), m_landSetId( landSetId ), m_landInfo( info ), @@ -185,7 +185,7 @@ uint64_t Sapphire::Land::getOwnerId() uint32_t Sapphire::Land::getDevaluationTime() { - return m_nextDrop - static_cast< uint32_t >( Util::getTimeSeconds() ); + return m_nextDrop - Util::getTimeSeconds(); } void Sapphire::Land::setCurrentPrice( uint32_t currentPrice ) diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Zone.cpp index 3ad04d39..21817559 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Zone.cpp @@ -39,6 +39,8 @@ #include "Zone.h" #include "Framework.h" +#include + using namespace Sapphire::Common; using namespace Sapphire::Network::Packets; using namespace Sapphire::Network::Packets::Server; @@ -159,7 +161,7 @@ void Sapphire::Zone::loadCellCache() Weather Sapphire::Zone::getNextWeather() { - uint32_t unixTime = static_cast< uint32_t >( Util::getTimeSeconds() ); + uint32_t unixTime = Util::getTimeSeconds(); // Get Eorzea hour for weather start uint32_t bell = unixTime / 175; // Do the magic 'cause for calculations 16:00 is 0, 00:00 is 8 and 08:00 is 16 @@ -381,9 +383,8 @@ void Sapphire::Zone::updateBNpcs( int64_t tickCount ) { if( ( tickCount - m_lastMobUpdate ) > 250 ) { - m_lastMobUpdate = tickCount; - uint32_t currTime = static_cast< uint32_t >( time( nullptr ) ); + uint32_t currTime = Sapphire::Util::getTimeSeconds(); /*for( auto it3 = m_BattleNpcDeadMap.begin(); it3 != m_BattleNpcDeadMap.end(); ++it3 ) { @@ -802,7 +803,7 @@ bool Sapphire::Zone::loadSpawnGroups() float r = res->getFloat( 5 ); uint32_t gimmickId = res->getUInt( 6 ); - group.getSpawnPointList().push_back( std::make_shared< Entity::SpawnPoint >( x, y, z, r, gimmickId ) ); + group.getSpawnPointList().emplace_back( std::make_shared< Entity::SpawnPoint >( x, y, z, r, gimmickId ) ); Logger::debug( "id: {0}, x: {1}, y: {2}, z: {3}, gimmickId: {4}", id, x, y, z, gimmickId ); } @@ -812,9 +813,8 @@ bool Sapphire::Zone::loadSpawnGroups() void Sapphire::Zone::updateSpawnPoints() { - std::random_device rd; - std::mt19937 mt( rd() ); - std::uniform_real_distribution< float > dist( 0.0, PI * 2 ); + auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >(); + auto rng = pRNGMgr->getRandGenerator< float >( 0.f, PI * 2 ); for( auto& group : m_spawnGroups ) { @@ -837,7 +837,7 @@ void Sapphire::Zone::updateSpawnPoints() point->getPosX(), point->getPosY(), point->getPosZ(), - dist( mt ), + rng.next(), group.getLevel(), group.getMaxHp(), shared_from_this(), m_pFw ); point->setLinkedBNpc( pBNpc );