diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index cf9d9e8c..0db28603 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -50,8 +50,8 @@ void Core::Db::ZoneDbConnection::doPrepareStatements() "CFPenaltyUntil = ?, Pose = ? WHERE CharacterId = ?;", CONNECTION_ASYNC ); - prepareStatement( CHARA_SEL_MINIMAL, "SELECT Name, Customize, ModelEquip, TerritoryId, GuardianDeity, " - "Class, ContentId, BirthDay, BirthMonth " + prepareStatement( CHARA_SEL_MINIMAL, "SELECT Name, Customize, ModelMainWeapon, ModelSubWeapon, ModelEquip, TerritoryId, GuardianDeity, " + "Class, ContentId, BirthDay, BirthMonth, EquipDisplayFlags " "FROM charainfo WHERE CharacterId = ?;", CONNECTION_SYNC ); prepareStatement( CHARA_INS, "INSERT INTO charainfo (AccountId, CharacterId, ContentId, Name, Hp, Mp, " diff --git a/src/servers/sapphire_api/PlayerMinimal.cpp b/src/servers/sapphire_api/PlayerMinimal.cpp index c79b2f28..d117eea0 100644 --- a/src/servers/sapphire_api/PlayerMinimal.cpp +++ b/src/servers/sapphire_api/PlayerMinimal.cpp @@ -55,22 +55,32 @@ void PlayerMinimal::load( uint32_t charId ) auto modelEquip = res->getBlobVector( "ModelEquip" ); memcpy( ( char* ) m_modelEquip, modelEquip.data(), modelEquip.size() ); + m_modelMainWeapon = res->getUInt64( "ModelMainWeapon" ); + m_modelSubWeapon = res->getUInt64( "ModelSubWeapon" ); + m_equipDisplayFlags = res->getUInt8( "EquipDisplayFlags" ); + setBirthDay( res->getUInt8( "BirthDay" ), res->getUInt8( "BirthMonth" ) ); m_guardianDeity = res->getUInt8( "GuardianDeity" ); m_class = res->getUInt8( "Class" ); m_contentId = res->getUInt64( "ContentId" ); - m_zoneId = res->getUInt8( "TerritoryId" ); + m_zoneId = res->getUInt16( "TerritoryId" ); + + res.reset(); // SELECT ClassIdx, Exp, Lvl - auto stmtClass = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_SEL_MINIMAL ); + auto stmtClass = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_CLASS_SEL ); stmtClass->setInt( 1, m_id ); - auto resClass = g_charaDb.query( stmt ); + auto resClass = g_charaDb.query( stmtClass ); while( resClass->next() ) { - m_classMap[ resClass->getUInt( 1 ) ] = resClass->getUInt( 3 ); + auto classIdx = resClass->getUInt( 1 ); + auto lvl = resClass->getUInt( 3 ); + + m_classMap[ classIdx ] = lvl; + m_classLevel = getClassLevel(); } } @@ -104,15 +114,20 @@ std::string PlayerMinimal::getModelString() + std::to_string( m_modelEquip[ 1 ] ) + "\",\"" + std::to_string( m_modelEquip[ 2 ] ) + "\",\"" + std::to_string( m_modelEquip[ 3 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 4 ] ) + "\",\"5\",\"6\",\"7\",\"8\",\"9\""; + + std::to_string( m_modelEquip[ 4 ] ) + "\",\"" + + std::to_string( m_modelEquip[ 5 ] ) + "\",\"" + + std::to_string( m_modelEquip[ 6 ] ) + "\",\"" + + std::to_string( m_modelEquip[ 7 ] ) + "\",\"" + + std::to_string( m_modelEquip[ 8 ] ) + "\",\"" + + std::to_string( m_modelEquip[ 9 ] ) + "\""; return modelString; } std::string PlayerMinimal::getInfoJson() { std::string charDetails = "{\"content\":[\"" + std::string( getName() ) + "\"," + - //"[" + getClassString() + "]," + - "[\"0\",\"0\",\"0\",\"0\",\"0\",\"1\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]," + "[\"0\",\"0\",\"0\",\"0\",\"" + std::to_string( m_classLevel ) + + "\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]," "\"0\",\"0\",\"0\",\"" + std::to_string( getBirthMonth() ) + "\",\"" + std::to_string( getBirthDay() ) + @@ -120,15 +135,21 @@ std::string PlayerMinimal::getInfoJson() "\",\"" + std::to_string( m_class ) + "\",\"0\",\"" + std::to_string( getZoneId() ) + "\",\"0\"," + - "[" + getLookString() + "]," + - "\"0\",\"0\"," + + "\"" + std::to_string( m_modelMainWeapon ) + "\",\"" + std::to_string( m_modelSubWeapon ) + "\"," + "[" + getModelString() + "]," + - "\"1\",\"0\",\"0\",\"0\",\"0\",\"0\",\"\",\"0\",\"0\"]," + + "\"1\",\"0\",\"0\",\"0\",\"" + std::to_string( m_equipDisplayFlags ) + + "\",\"0\",\"\",\"0\",\"0\"]," + "\"classname\":\"ClientSelectData\",\"classid\":116}"; return charDetails; } +uint8_t PlayerMinimal::getClassLevel() +{ + uint8_t classJobIndex = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( m_class ) )->expArrayIndex; + return static_cast< uint8_t >( m_classMap[ classJobIndex ] ); +} + std::string PlayerMinimal::getClassString() { diff --git a/src/servers/sapphire_api/PlayerMinimal.h b/src/servers/sapphire_api/PlayerMinimal.h index d9105a8b..4bbe8036 100644 --- a/src/servers/sapphire_api/PlayerMinimal.h +++ b/src/servers/sapphire_api/PlayerMinimal.h @@ -31,6 +31,8 @@ public: std::string getClassString(); + uint8_t getClassLevel(); + // return the id of the actor uint32_t getId() const { @@ -177,6 +179,7 @@ private: uint8_t m_birthMonth; uint8_t m_birthDay; uint8_t m_class; + uint8_t m_classLevel; uint8_t m_voice; @@ -184,10 +187,15 @@ private: uint16_t m_zoneId; + uint64_t m_modelMainWeapon; + uint64_t m_modelSubWeapon; + uint8_t m_equipDisplayFlags; + std::map< uint8_t, uint8_t > m_lookMap; std::map< uint8_t, uint16_t > m_classMap; uint8_t m_look[26]; + uint8_t m_gmRank; bool m_gmInvis; diff --git a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp index 7a9a23f3..9b15a373 100644 --- a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -455,8 +456,41 @@ void Core::Network::GameConnection::gm1Handler( const Packets::FFXIVARR_PACKET_R break; } - targetPlayer->setPos( targetPlayer->getPos() ); - targetPlayer->performZoning( param1, targetPlayer->getPos(), 0 ); + bool doTeleport = false; + uint16_t teleport; + + auto pExdData = g_fw.get< Data::ExdDataGenerated >(); + auto idList = pExdData->getAetheryteIdList(); + + for( auto i : idList ) + { + auto data = pExdData->get< Core::Data::Aetheryte >( i ); + + if( !data ) + { + continue; + } + + if( data->territory == param1 ) + { + if( data->isAetheryte ) + { + doTeleport = true; + teleport = i; + break; + } + } + } + if( doTeleport ) + { + player.teleport( teleport ); + } + else + { + targetPlayer->setPos( targetPlayer->getPos() ); + targetPlayer->performZoning( param1, targetPlayer->getPos(), 0 ); + } + player.sendNotice( targetPlayer->getName() + " was warped to zone " + std::to_string( param1 ) + " (" + pZone->getName() + ")" ); } diff --git a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp index 877298c4..faa4cee3 100644 --- a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp @@ -371,7 +371,7 @@ void Core::Network::GameConnection::discoveryHandler( const Core::Network::Packe if( !pQR->next() ) { - player.sendNotice( "Discovery ref pos ID: " + std::to_string( positionRef ) + " not found. " ); + player.sendDebug( "Discovery ref pos ID: " + std::to_string( positionRef ) + " not found. " ); return; } @@ -380,7 +380,7 @@ void Core::Network::GameConnection::discoveryHandler( const Core::Network::Packe discoveryPacket->data().map_part_id = pQR->getUInt( 3 ); player.queuePacket( discoveryPacket ); - player.sendNotice( "Discovery ref pos ID: " + std::to_string( positionRef ) ); + player.sendDebug( "Discovery ref pos ID: " + std::to_string( positionRef ) ); player.discover( pQR->getUInt16( 2 ), pQR->getUInt16( 3 ) );