diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index d255465a..e9817c9b 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -214,6 +214,8 @@ enum ActorControlType : // Housing ShowHousingItemUI = 0x3F7, + ShowBuildPresetUI = 0x3E9, + BuildPresetResponse = 0x3ED, // PvP Duel SetPvPState = 0x5E0, // param3 must be 6 to engage a duel (hardcoded in the client) @@ -289,7 +291,10 @@ enum ClientTriggerType AchievementCritReq = 0x3E8, AchievementList = 0x3E9, + RequestHousingBuildPreset = 0x44C, RequestHousingSign = 0x451, + RequestHousingInfoSign = 0x452, + RequestHousingRename = 0x45A, RequestHousingItemUI = 0x463, RequestSharedEstateSettings = 0x46F, diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 2503be96..8b43346b 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -187,9 +187,12 @@ namespace Core::Network::Packets LandUpdate = 0x0221, // updated 4.4 YardObjectSpawn = 0x0222, // updated 4.4 - LandPriceUpdate = 0x0224, // updated 4.3 + LandPriceUpdate = 0x0224, // updated 4.4 + LandInfoSign = 0x0225, // updated 4.4 + LandRename = 0x0226, // updated 4.4 LandPermissionSlot = 0x0228, // updated 4.4 + LandPermission = 0x0229, // updated 4.4 LandSetYardInitialize = 0x022C, // updated 4.4 @@ -280,6 +283,7 @@ namespace Core::Network::Packets InventoryModifyHandler = 0x0142, // updated 4.4 + BuildPresetHandler = 0x014A, // updated 4.4 TalkEventHandler = 0x014B, // updated 4.4 EmoteEventHandler = 0x014C, // updated 4.4 WithinRangeEventHandler = 0x014D, // updated 4.4 @@ -292,6 +296,8 @@ namespace Core::Network::Packets LinkshellEventHandler = 0x0150, // updated 4.1 ?? LinkshellEventHandler1 = 0x0151, // updated 4.1 ?? + LandRenameHandler = 0x0171, // updated 4.4 + SetSharedEstateSettings = 0x0177, // updated 4.4 PerformNoteHandler = 0x029B, // updated 4.3 diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index f973bfa7..7dae9236 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -189,6 +189,25 @@ struct FFXIVIpcInventoryModifyHandler : /* 0028 */ uint32_t splitCount; }; +struct FFXIVIpcRenameLandHandler : + FFXIVIpcBasePacket< LandRenameHandler > +{ + /* 0000 */ uint16_t landId; + /* 0002 */ uint16_t wardNum; + /* 0004 */ uint16_t zoneId; + /* 0006 */ uint16_t worldId; + /* 0008 */ char landName[20]; + /* 0028 */ uint32_t padding; +}; + +struct FFXIVIpcBuildPresetHandler : + FFXIVIpcBasePacket< BuildPresetHandler > +{ + /* 0000 */ uint32_t itemId; + /* 0004 */ uint8_t plotNum; + /* 0005 */ char stateString[27]; +}; + struct FFXIVIpcSetSharedEstateSettings : FFXIVIpcBasePacket< SetSharedEstateSettings > { diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 2e82cdc9..84ab8c5f 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1611,6 +1611,37 @@ struct FFXIVIpcLandPriceUpdate : FFXIVIpcBasePacket< LandPriceUpdate > uint32_t timeLeft; }; +struct FFXIVIpcLandInfoSign : FFXIVIpcBasePacket< LandInfoSign > +{ + uint16_t landId; + uint16_t wardNum; + uint16_t zoneId; + uint16_t worldId; + uint32_t ownerId; + uint16_t someState1;//private 0x0 : fc 0x17 + uint8_t someState2;//private 0x21 : fc 0x40 + uint8_t someState3; //private 0x80 : fc 0 + uint32_t unknow1; //seems like not always 0 (6 of 5 times 0, one time it was 0x14) + uint8_t houseIconAdd; + uint8_t houseState; + uint8_t houseSize; + char landName[23]; + char landMsg[193]; + char ownerName[31]; + char fcTag[7]; + uint8_t tag[3]; +}; + +struct FFXIVIpcLandRename : FFXIVIpcBasePacket< LandRename > +{ + uint16_t landId; + uint16_t wardNum; + uint16_t zoneId; + uint16_t worldId; + char landName[20]; + uint32_t padding; +}; + struct FFXIVIpcLandSetMap : FFXIVIpcBasePacket< LandSetMap > { uint8_t u1; diff --git a/src/servers/sapphire_zone/Network/GameConnection.cpp b/src/servers/sapphire_zone/Network/GameConnection.cpp index 879c7751..5d412727 100644 --- a/src/servers/sapphire_zone/Network/GameConnection.cpp +++ b/src/servers/sapphire_zone/Network/GameConnection.cpp @@ -83,6 +83,8 @@ Core::Network::GameConnection::GameConnection( Core::Network::HivePtr pHive, setZoneHandler( ClientZoneIpcType::InventoryModifyHandler, "InventoryModifyHandler", &GameConnection::inventoryModifyHandler ); + setZoneHandler( ClientZoneIpcType::BuildPresetHandler, "BuildPresetHandler", &GameConnection::eventHandlerTalk ); + setZoneHandler( ClientZoneIpcType::LandRenameHandler, "LandRenameHandler", &GameConnection::landRenameHandler ); setZoneHandler( ClientZoneIpcType::TalkEventHandler, "EventHandlerTalk", &GameConnection::eventHandlerTalk ); setZoneHandler( ClientZoneIpcType::EmoteEventHandler, "EventHandlerEmote", &GameConnection::eventHandlerEmote ); setZoneHandler( ClientZoneIpcType::WithinRangeEventHandler, "EventHandlerWithinRange", diff --git a/src/servers/sapphire_zone/Network/GameConnection.h b/src/servers/sapphire_zone/Network/GameConnection.h index 1138a5fc..8ba31549 100644 --- a/src/servers/sapphire_zone/Network/GameConnection.h +++ b/src/servers/sapphire_zone/Network/GameConnection.h @@ -162,6 +162,10 @@ namespace Core::Network DECLARE_HANDLER( performNoteHandler ); + DECLARE_HANDLER( landRenameHandler ); + + DECLARE_HANDLER( buildPresetHandler ); + DECLARE_HANDLER( tellHandler ); }; diff --git a/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp b/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp index cbd7873a..f4b69960 100644 --- a/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp @@ -11,6 +11,7 @@ #include "Zone/Zone.h" #include "Zone/ZonePosition.h" #include "Zone/HousingZone.h" +#include "Zone/HousingMgr.h" #include "Zone/Land.h" #include "Network/GameConnection.h" @@ -309,6 +310,23 @@ void Core::Network::GameConnection::clientTriggerHandler( const Packets::FFXIVAR player.removeQuest( static_cast< uint16_t >( param1 ) ); break; } + case ClientTriggerType::RequestHousingBuildPreset: + { + auto pShowBuildPresetUIPacket = makeActorControl142( player.getId(), ShowBuildPresetUI, param11 ); + + auto zone = player.getCurrentZone(); + + auto hZone = std::dynamic_pointer_cast< HousingZone >( zone ); + + if (!hZone) + return; + + player.setActiveLand( param11, hZone->getWardNum() ); + + player.queuePacket( pShowBuildPresetUIPacket ); + + break; + } case ClientTriggerType::RequestHousingSign: { @@ -335,9 +353,76 @@ void Core::Network::GameConnection::clientTriggerHandler( const Packets::FFXIVAR break; } + case ClientTriggerType::RequestHousingInfoSign: + { + + auto LandInfoSignPacket = makeZonePacket< Server::FFXIVIpcLandInfoSign >( player.getId() ); + + uint8_t ward = ( param12 & 0xFF00 ) >> 8; + uint8_t plot = ( param12 & 0xFF ); + pLog->debug( " Ward: " + std::to_string( ward ) + " Plot: " + std::to_string( plot ) ); + + player.setActiveLand( plot, ward ); + + auto zone = player.getCurrentZone(); + + auto hZone = std::dynamic_pointer_cast< HousingZone >( zone ); + + auto land = hZone->getLand( plot ); + if( !land ) + { + auto pHousingMgr = g_fw.get< HousingMgr >(); + land = pHousingMgr->getLandByOwnerId( player.getId() ); + } + + memcpy( &LandInfoSignPacket->data().landMsg, "Hello World", 11 ); + memcpy( &LandInfoSignPacket->data().landName, land->getLandName().c_str(), 20 ); + LandInfoSignPacket->data().houseSize = land->getHouseSize(); + LandInfoSignPacket->data().houseState = land->getState(); + LandInfoSignPacket->data().landId = land->getLandId(); + LandInfoSignPacket->data().ownerId = land->getPlayerOwner(); + memcpy( &LandInfoSignPacket->data().ownerName, "Hello World", 11 ); + LandInfoSignPacket->data().wardNum = land->getWardNum(); + LandInfoSignPacket->data().worldId = 67; + LandInfoSignPacket->data().zoneId = land->getZoneId(); + + player.queuePacket( LandInfoSignPacket ); + + break; + } + case ClientTriggerType::RequestHousingRename: + { + auto landRenamePacket = makeZonePacket< Server::FFXIVIpcLandRename >( player.getId() ); + + uint8_t ward = ( param12 & 0xFF00 ) >> 8; + uint8_t plot = ( param12 & 0xFF ); + + auto zone = player.getCurrentZone(); + + auto hZone = std::dynamic_pointer_cast< HousingZone >( zone ); + + auto land = hZone->getLand( plot ); + + if( !land ) + { + auto pHousingMgr = g_fw.get< HousingMgr >(); + land = pHousingMgr->getLandByOwnerId( player.getId() ); + } + + landRenamePacket->data().landId = land->getLandId(); + landRenamePacket->data().wardNum = land->getWardNum(); + landRenamePacket->data().worldId = 67; + landRenamePacket->data().zoneId = land->getZoneId(); + memcpy( &landRenamePacket->data().landName, land->getLandName().c_str(), 20 ); + + player.queuePacket( landRenamePacket ); + + break; + } case ClientTriggerType::RequestHousingItemUI: { - uint32_t plot = param2; + uint8_t ward = ( param12 & 0xFF00 ) >> 8; + uint8_t plot = ( param12 & 0xFF ); auto pShowHousingItemUIPacket = makeActorControl142( player.getId(), ShowHousingItemUI, 0, plot ); player.queuePacket( pShowHousingItemUIPacket ); diff --git a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp index 34293a13..de2f34d5 100644 --- a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp @@ -16,6 +16,9 @@ #include "Zone/TerritoryMgr.h" #include "Zone/Zone.h" +#include "Zone/HousingZone.h" +#include "Zone/HousingMgr.h" +#include "Zone/Land.h" #include "Zone/ZonePosition.h" #include "Network/PacketWrappers/InitUIPacket.h" @@ -648,3 +651,61 @@ void Core::Network::GameConnection::performNoteHandler( const Core::Network::Pac memcpy( &performPacket->data().data[ 0 ], &inPacket.data[ 0x10 ], 32 ); player.sendToInRangeSet( performPacket ); } + +void Core::Network::GameConnection::landRenameHandler( const Core::Network::Packets::FFXIVARR_PACKET_RAW& inPacket, + Entity::Player& player ) +{ + const auto packet = ZoneChannelPacket< Client::FFXIVIpcRenameLandHandler >( inPacket ); + + uint32_t landSetId = ( static_cast< uint32_t >( packet.data().zoneId ) << 16 ) | packet.data().wardNum; + auto pHousingMgr = g_fw.get< HousingMgr >(); + auto pLand = pHousingMgr->getHousingZoneByLandSetId( landSetId )->getLand( packet.data().landId ); + + if( !pLand ) + return; + + pLand->setLandName( packet.data().landName ); +} + +void Core::Network::GameConnection::buildPresetHandler( const Core::Network::Packets::FFXIVARR_PACKET_RAW& inPacket, + Entity::Player& player ) +{ + const auto packet = ZoneChannelPacket< Client::FFXIVIpcBuildPresetHandler >( inPacket ); + + auto zone = player.getCurrentZone(); + auto plotNum = packet.data().plotNum; + auto preset = packet.data().itemId; + std::string landString = std::string( packet.data().stateString ); + auto hZone = std::dynamic_pointer_cast< HousingZone >( zone ); + + if( !hZone ) + return; + + auto pLand = hZone->getLand( plotNum ); + /* + if (!pLand) + player.sendDebug( "Something went wrong..." ); + + if( stateString.find( "Private" ) ) + { + pLand->setPreset( preset ); + pLand->setState( HouseState::privateHouse ); + pLand->UpdateLandDb(); + hZone->sendLandUpdate( plotNum ); + } + else if( stateString.find("Free") ) + { + pLand->setPreset( preset ); + pLand->setState( HouseState::fcHouse ); + pLand->UpdateLandDb(); + hZone->sendLandUpdate( plotNum ); + } + else + { + player.sendDebug( "You tried to build a preset on not supported land." ); + } + + auto pSuccessBuildingPacket = makeActorControl142( player.getId(), BuildPresetResponse, plotNum ); + + player.queuePacket( pSuccessBuildingPacket );*/ +} diff --git a/src/servers/sapphire_zone/Zone/HousingMgr.cpp b/src/servers/sapphire_zone/Zone/HousingMgr.cpp index 48f4cdcd..a4756d82 100644 --- a/src/servers/sapphire_zone/Zone/HousingMgr.cpp +++ b/src/servers/sapphire_zone/Zone/HousingMgr.cpp @@ -53,6 +53,22 @@ Core::Data::HousingZonePtr Core::HousingMgr::getHousingZone( uint16_t id ) return it->second; } +Core::Data::HousingZonePtr Core::HousingMgr::getHousingZoneByLandSetId( uint32_t id ) +{ + for( const auto& hZoneIt : m_housingZonePtrMap ) + { + auto pHousingZone = hZoneIt.second; + for( uint8_t landId = 0; landId < 60; landId++ ) + { + if( pHousingZone->getLandSetId() == id ) + { + return pHousingZone; + } + } + } + return nullptr; +} + Core::LandPtr Core::HousingMgr::getLandByOwnerId( uint32_t id ) { for( const auto& hZoneIt : m_housingZonePtrMap ) diff --git a/src/servers/sapphire_zone/Zone/HousingMgr.h b/src/servers/sapphire_zone/Zone/HousingMgr.h index e2981ade..b1a77858 100644 --- a/src/servers/sapphire_zone/Zone/HousingMgr.h +++ b/src/servers/sapphire_zone/Zone/HousingMgr.h @@ -25,6 +25,7 @@ namespace Core uint16_t getNexLandId(); void insertHousingZone( Core::Data::HousingZonePtr hZone ); Core::Data::HousingZonePtr getHousingZone( uint16_t id ); + Core::Data::HousingZonePtr getHousingZoneByLandSetId( uint32_t id ); Core::LandPtr getLandByOwnerId( uint32_t id ); private: diff --git a/src/servers/sapphire_zone/Zone/HousingZone.cpp b/src/servers/sapphire_zone/Zone/HousingZone.cpp index eea9a46d..8f45e1a5 100644 --- a/src/servers/sapphire_zone/Zone/HousingZone.cpp +++ b/src/servers/sapphire_zone/Zone/HousingZone.cpp @@ -193,6 +193,7 @@ Core::LandPurchaseResult Core::HousingZone::purchseLand( Entity::Player& player, player.setLandPermissions( LandPermissionSlot::Private, 0x00, plot, pHousing->getWardNum(), pHousing->getTerritoryTypeId() ); player.sendLandPermissions(); + pLand->setLandName( "Private Estate" + std::to_string( pHousing->getWardNum() ) + "-" + std::to_string( plot ) ); pLand->UpdateLandDb(); sendLandUpdate( plot ); return LandPurchaseResult::SUCCESS; diff --git a/src/servers/sapphire_zone/Zone/Land.cpp b/src/servers/sapphire_zone/Zone/Land.cpp index 52ab103d..2201c3c1 100644 --- a/src/servers/sapphire_zone/Zone/Land.cpp +++ b/src/servers/sapphire_zone/Zone/Land.cpp @@ -39,6 +39,9 @@ Core::Land::Land( uint16_t zoneId, uint8_t wardNum, uint8_t landId, uint32_t lan { memset( &m_land, 0x00, sizeof( LandStruct ) ); memset( &m_tag, 0x00, 3 ); + memset( &m_landMsg, 0x00, 193 ); + memset( &m_landName, 0x00, 23 ); + load(); } @@ -62,6 +65,7 @@ void Core::Land::load() m_currentPrice = m_landInfo->prices[ m_landId ]; m_minPrice = m_landInfo->minPrices[ m_landId ]; m_land.houseSize = m_landInfo->sizes[ m_landId ]; + m_land.houseState = HouseState::forSale; } else { @@ -152,6 +156,11 @@ void Core::Land::setSharing( uint8_t state ) m_land.iconAddIcon = state; } +void Core::Land::setLandName( const std::string& name ) +{ + memcpy( &m_landName, name.c_str(), 20 ); +} + uint8_t Core::Land::getHouseSize() { return m_land.houseSize; @@ -192,6 +201,11 @@ uint16_t Core::Land::getZoneId() return m_zoneId; } +std::string Core::Land::getLandName() +{ + return std::string( m_landName ); +} + //Free Comapny void Core::Land::setFreeCompany( uint32_t id, uint32_t icon, uint32_t color ) { diff --git a/src/servers/sapphire_zone/Zone/Land.h b/src/servers/sapphire_zone/Zone/Land.h index 75d44ea4..6cdbf593 100644 --- a/src/servers/sapphire_zone/Zone/Land.h +++ b/src/servers/sapphire_zone/Zone/Land.h @@ -1,6 +1,7 @@ #ifndef LAND_H_ #define LAND_H_ #include +#include "Exd/ExdDataGenerated.h" #include "ForwardsZone.h" namespace Core @@ -24,6 +25,7 @@ namespace Core void setState( uint8_t state ); void setOwnership( uint8_t state ); void setSharing( uint8_t state ); + void setLandName( const std::string& name ); //Gerneral uint8_t getHouseSize(); @@ -34,6 +36,7 @@ namespace Core uint8_t getWardNum(); uint8_t getLandId(); uint16_t getZoneId(); + std::string getLandName(); //Free Comapny void setFreeCompany( uint32_t id, uint32_t icon, uint32_t color ); @@ -90,7 +93,11 @@ namespace Core uint32_t m_currentPrice; uint32_t m_minPrice; - //Tags + //information + char m_landName[23]; + char m_landMsg[193]; + char m_ownerName[31]; + char fcTag[7]; uint8_t m_tag[3]; };