diff --git a/sql/charadetail.sql b/sql/charadetail.sql index 2a47302c..8716365d 100644 --- a/sql/charadetail.sql +++ b/sql/charadetail.sql @@ -72,6 +72,7 @@ CREATE TABLE IF NOT EXISTS `charadetail` ( `GMRank` int(3) DEFAULT '0', `EquipDisplayFlags` int(3) DEFAULT '0', `unlocks` binary(64) DEFAULT NULL, + `Orchestrion` binary(38) DEFAULT NULL, `CharacterId` int(20) NOT NULL DEFAULT '0', `IS_DELETE` int(3) DEFAULT '0', `IS_NOT_ACTIVE_FLG` int(3) DEFAULT '0', diff --git a/sql/update.sql b/sql/update.sql index 67fdb72e..0f05e32a 100644 --- a/sql/update.sql +++ b/sql/update.sql @@ -28,4 +28,5 @@ -- ------------------------------------------- -- update.sql before titles added 09/10/2017 -ALTER TABLE `charadetail` CHANGE `TitleList` `Titlelist` BINARY(48) NULL DEFAULT NULL; \ No newline at end of file +ALTER TABLE `charadetail` CHANGE `TitleList` `Titlelist` BINARY(48) NULL DEFAULT NULL; +ALTER TABLE `charadetail` ADD COLUMN `Orchestrion` BINARY(38) DEFAULT NULL AFTER `unlocks`; \ No newline at end of file diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index 07889117..eb534594 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -949,7 +949,9 @@ namespace Core { SetCharaGearParamUI = 0x260, - GearSetEquipMsg = 0x321 + GearSetEquipMsg = 0x321, + + ToggleOrchestrionUnlock = 0x396 }; enum struct ChatType : uint32_t diff --git a/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h b/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h index 778f9a08..327a0847 100644 --- a/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h @@ -789,7 +789,7 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket uint8_t unknownRest[32]; uint8_t tripleTriadCards[26]; uint8_t unknownRest1[21]; - uint8_t orchestrionMask[19]; + uint8_t orchestrionMask[38]; uint8_t hallOfNoviceCompleteMask[3]; uint8_t unknownMask2[11]; uint8_t unknownMask3[16]; diff --git a/src/servers/Server_REST/PlayerMinimal.cpp b/src/servers/Server_REST/PlayerMinimal.cpp index f8c7e1fe..f36a14a1 100644 --- a/src/servers/Server_REST/PlayerMinimal.cpp +++ b/src/servers/Server_REST/PlayerMinimal.cpp @@ -178,6 +178,9 @@ namespace Core { char titleList[48]; memset( titleList, 0, 48 ); + char orchestrion[38]; + memset( orchestrion, 0, 38 ); + int16_t questTracking[5] = { -1, -1, -1, -1, -1 }; uint16_t size = static_cast< uint16_t >( m_lookMap.size() ); @@ -274,6 +277,7 @@ namespace Core { " QuestTracking, " " Aetheryte, " " TitleList, " + " Orchestrion, " " GMRank, " " UPDATE_DATE ) " " VALUES (" + std::to_string( m_iD ) + ", " @@ -290,6 +294,7 @@ namespace Core { + "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)questTracking, 10 ) ) + "'), " + "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)aetherytes, 12 ) ) + "')," + "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)titleList, 48 ) ) + "')," + + "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)orchestrion, 38 ) ) + "')," + std::to_string( m_gmRank ) + ", NOW());" ); diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 10c4cf2f..0199f3ca 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -608,6 +608,18 @@ void Core::Entity::Player::learnAction( uint8_t actionId ) queuePacket( ActorControlPacket143( getId(), ToggleActionUnlock, actionId, 1 ) ); } +void Core::Entity::Player::learnSong( uint8_t songId, uint32_t itemId ) +{ + uint16_t index; + uint8_t value; + Util::valueToFlagByteIndexValue( songId, value, index ); + + m_orchestrion[index] |= value; + + setSyncFlag( Unlocks ); + queuePacket( ActorControlPacket143( getId(), ToggleOrchestrionUnlock, songId, 1, itemId ) ); +} + bool Core::Entity::Player::isActionLearned( uint8_t actionId ) const { uint16_t index; @@ -1197,6 +1209,11 @@ const uint8_t * Core::Entity::Player::getUnlockBitmask() const return m_unlocks; } +const uint8_t * Core::Entity::Player::getOrchestrionBitmask() const +{ + return m_orchestrion; +} + uint64_t Core::Entity::Player::getContentId() const { return m_contentId; diff --git a/src/servers/Server_Zone/Actor/Player.h b/src/servers/Server_Zone/Actor/Player.h index 4f63533b..488065df 100644 --- a/src/servers/Server_Zone/Actor/Player.h +++ b/src/servers/Server_Zone/Actor/Player.h @@ -373,10 +373,14 @@ public: void updateHowtosSeen( uint32_t howToId ); /*! learn an action / update the unlock bitmask. */ void learnAction( uint8_t actionId ); + /*! learn a song / update the unlock bitmask. */ + void learnSong( uint8_t songId, uint32_t itemId ); /*! check if an action is already unlocked in the bitmask. */ bool isActionLearned( uint8_t actionId ) const; /*! return a const pointer to the unlock bitmask array */ const uint8_t * getUnlockBitmask() const; + /*! return a const pointer to the orchestrion bitmask array */ + const uint8_t * getOrchestrionBitmask() const; // Spawn handling @@ -594,6 +598,7 @@ private: uint32_t m_expArray[25]; uint8_t m_aetheryte[16]; uint8_t m_unlocks[64]; + uint8_t m_orchestrion[38]; uint8_t m_openingSequence; diff --git a/src/servers/Server_Zone/Actor/PlayerSql.cpp b/src/servers/Server_Zone/Actor/PlayerSql.cpp index b92c3a98..4ff24919 100644 --- a/src/servers/Server_Zone/Actor/PlayerSql.cpp +++ b/src/servers/Server_Zone/Actor/PlayerSql.cpp @@ -84,7 +84,8 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession ) "cd.GMRank, " "cd.EquipDisplayFlags, " "cd.ActiveTitle, " - "cd.TitleList " // 40 + "cd.TitleList, " // 40 + "cd.Orchestrion " "FROM charabase AS c " " INNER JOIN charadetail AS cd " " ON c.CharacterId = cd.CharacterId " @@ -181,6 +182,8 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession ) m_title = field[39].get< uint8_t >(); field[40].getBinary( reinterpret_cast< char* >( m_titleList ), sizeof( m_titleList ) ); + field[41].getBinary( reinterpret_cast< char* >( m_orchestrion ), sizeof( m_orchestrion ) ); + m_pCell = nullptr; if( !loadActiveQuests() || !loadClassData() || !loadSearchInfo() ) @@ -313,7 +316,11 @@ void Core::Entity::Player::createUpdateSql() charaDetailSet.insert( " TotalPlayTime = " + std::to_string( m_playTime ) ); if( m_updateFlags & PlayerSyncFlags::Unlocks ) - charaDetailSet.insert( " unlocks = UNHEX('" + Util::binaryToHexString( static_cast< uint8_t* >( m_unlocks ), sizeof( m_unlocks ) ) + "')" ); + { + charaDetailSet.insert( " unlocks = UNHEX('" + Util::binaryToHexString( static_cast< uint8_t* >( m_unlocks ), sizeof( m_unlocks ) ) + "')"); + charaDetailSet.insert( " Orchestrion = UNHEX('" + Util::binaryToHexString( static_cast< uint8_t* >( m_orchestrion ), sizeof( m_orchestrion ) ) + "')" ); + } + if( m_updateFlags & PlayerSyncFlags::QuestTracker ) charaDetailSet.insert( " QuestTracking = UNHEX('" + Util::binaryToHexString( reinterpret_cast< uint8_t* >( m_questTracking ), sizeof( m_questTracking ) ) + "')" ); diff --git a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp index f4bf6747..3a8805ed 100644 --- a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp @@ -118,6 +118,7 @@ void Core::DebugCommandHandler::scriptReload( char * data, Core::Entity::PlayerP boost::shared_ptr command ) { g_scriptMgr.reload(); + pPlayer->sendDebug( "Scripts reloaded." ); } void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlayer, boost::shared_ptr command ) diff --git a/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp b/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp index e74cbde6..cae64bc6 100644 --- a/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp +++ b/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp @@ -72,6 +72,8 @@ enum GmCommand Exp = 0x0068, Inv = 0x006A, + Orchestrion = 0x0074, + Item = 0x00C8, Gil = 0x00C9, Collect = 0x00CA, @@ -386,6 +388,29 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac } + break; + } + case GmCommand::Orchestrion: + { + if( param1 == 1 ) + { + if( param2 == 0 ) + { + for( uint8_t i = 0; i < 255; i++ ) + targetActor->getAsPlayer()->learnSong( i, 0 ); + + pPlayer->sendNotice( "All Songs for " + targetPlayer->getName() + + " were turned on." ); + } + else + { + targetActor->getAsPlayer()->learnSong( param2, 0 ); + pPlayer->sendNotice( "Song " + std::to_string( param2 ) + " for " + targetPlayer->getName() + + " was turned on." ); + } + } + + break; } diff --git a/src/servers/Server_Zone/Network/PacketWrappers/InitUIPacket.h b/src/servers/Server_Zone/Network/PacketWrappers/InitUIPacket.h index 1a4d06e5..60b69f1d 100644 --- a/src/servers/Server_Zone/Network/PacketWrappers/InitUIPacket.h +++ b/src/servers/Server_Zone/Network/PacketWrappers/InitUIPacket.h @@ -42,7 +42,7 @@ private: m_data.namedayMonth = player->getBirthMonth(); m_data.namedayDay = player->getBirthDay(); // TODO: Support grand company status. - m_data.grandCompany = static_cast< Common::GrandCompany >( player->getStartTown() ); + m_data.grandCompany = static_cast< Common::GrandCompany >( player->getGc() ); //m_data.gcRank = GCRank::None; // TODO: Support starting city. @@ -62,6 +62,8 @@ private: m_data.exp[i] = player->getExpArray()[i]; } + memcpy( m_data.orchestrionMask, player->getOrchestrionBitmask(), sizeof( m_data.orchestrionMask ) ); + memcpy( m_data.unlockBitmask, player->getUnlockBitmask(), sizeof( m_data.unlockBitmask ) ); memcpy( m_data.discovery, player->getDiscoveryBitmask(), sizeof( m_data.discovery ) );