mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-25 14:07:46 +00:00
fix issue where items couldn't be placed in storeroom from inv
This commit is contained in:
parent
35db5865a2
commit
66964ec8f6
6 changed files with 130 additions and 33 deletions
|
@ -58,6 +58,11 @@ namespace Sapphire
|
||||||
spdlog::get( "logger" )->error( text );
|
spdlog::get( "logger" )->error( text );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Logger::warn( const std::string& text )
|
||||||
|
{
|
||||||
|
spdlog::get( "logger" )->warn( text );
|
||||||
|
}
|
||||||
|
|
||||||
void Logger::info( const std::string& text )
|
void Logger::info( const std::string& text )
|
||||||
{
|
{
|
||||||
spdlog::get( "logger" )->info( text );
|
spdlog::get( "logger" )->info( text );
|
||||||
|
@ -73,4 +78,9 @@ namespace Sapphire
|
||||||
spdlog::get( "logger" )->critical( text );
|
spdlog::get( "logger" )->critical( text );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Logger::trace( const std::string& text )
|
||||||
|
{
|
||||||
|
spdlog::get( "logger" )->trace( text );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,16 @@ namespace Sapphire
|
||||||
|
|
||||||
static void error( const std::string& text );
|
static void error( const std::string& text );
|
||||||
|
|
||||||
|
static void warn( const std::string& text );
|
||||||
|
|
||||||
static void info( const std::string& text );
|
static void info( const std::string& text );
|
||||||
|
|
||||||
static void debug( const std::string& text );
|
static void debug( const std::string& text );
|
||||||
|
|
||||||
static void fatal( const std::string& text );
|
static void fatal( const std::string& text );
|
||||||
|
|
||||||
|
static void trace( const std::string& text );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,7 +253,7 @@ struct FFXIVIpcReqPlaceHousingItem :
|
||||||
/* 000C */ Common::FFXIVARR_POSITION3 position;
|
/* 000C */ Common::FFXIVARR_POSITION3 position;
|
||||||
/* 0018 */ float rotation;
|
/* 0018 */ float rotation;
|
||||||
|
|
||||||
/* 001C */ uint32_t unknown3; // always 1?
|
/* 001C */ uint32_t shouldPlaceItem; // 1 if placing an item, 0 if placing in store
|
||||||
/* 0020 */ uint32_t unknown4[2]; // always 0 it looks like
|
/* 0020 */ uint32_t unknown4[2]; // always 0 it looks like
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -416,11 +416,10 @@ bool Sapphire::World::Manager::HousingMgr::relinquishLand( Entity::Player& playe
|
||||||
|
|
||||||
auto pLand = pHousing->getLand( plot );
|
auto pLand = pHousing->getLand( plot );
|
||||||
auto plotMaxPrice = pLand->getCurrentPrice();
|
auto plotMaxPrice = pLand->getCurrentPrice();
|
||||||
auto landOwnerId = pLand->getOwnerId();
|
|
||||||
|
|
||||||
// can't relinquish when you are not the owner
|
// can't relinquish when you are not the owner
|
||||||
// TODO: actually use permissions here for FC houses
|
// TODO: actually use permissions here for FC houses
|
||||||
if( landOwnerId != player.getId() )
|
if( !hasPermission( player, *pLand, 0 ) )
|
||||||
{
|
{
|
||||||
auto msgPkt = makeActorControl143( player.getId(), ActorControl::LogMsg, 3304, 0 );
|
auto msgPkt = makeActorControl143( player.getId(), ActorControl::LogMsg, 3304, 0 );
|
||||||
player.queuePacket( msgPkt );
|
player.queuePacket( msgPkt );
|
||||||
|
@ -664,8 +663,7 @@ void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& pl
|
||||||
if( !pLand )
|
if( !pLand )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: when doing FC houses, look up the type from the original purchase and check perms from FC and set state accordingly
|
if( !hasPermission( player, *pLand, 0 ) )
|
||||||
if( pLand->getOwnerId() != player.getId() )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// create house
|
// create house
|
||||||
|
@ -763,8 +761,7 @@ void Sapphire::World::Manager::HousingMgr::updateEstateGreeting( Entity::Player&
|
||||||
if( !land )
|
if( !land )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: implement proper permissions checks
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
if( land->getOwnerId() != player.getId() )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto house = land->getHouse();
|
auto house = land->getHouse();
|
||||||
|
@ -789,8 +786,7 @@ void Sapphire::World::Manager::HousingMgr::requestEstateEditGuestAccess( Entity:
|
||||||
if( !land )
|
if( !land )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: add proper permission check
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
if( land->getOwnerId() != player.getId() )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto packet = makeZonePacket< Server::FFXIVIpcHousingShowEstateGuestAccess >( player.getId() );
|
auto packet = makeZonePacket< Server::FFXIVIpcHousingShowEstateGuestAccess >( player.getId() );
|
||||||
|
@ -854,8 +850,7 @@ void Sapphire::World::Manager::HousingMgr::sendEstateInventory( Entity::Player&
|
||||||
if( !targetLand )
|
if( !targetLand )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: add proper permissions checks
|
if( !hasPermission( player, *targetLand, 0 ) )
|
||||||
if( targetLand->getOwnerId() != player.getId() )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto& containers = getEstateInventory( targetLand->getLandIdent() );
|
auto& containers = getEstateInventory( targetLand->getLandIdent() );
|
||||||
|
@ -993,12 +988,11 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity
|
||||||
if( !land )
|
if( !land )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: add proper permissions checks
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
if( land->getOwnerId() != player.getId() )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: check item position and make sure it's not outside the plot
|
// todo: check item position and make sure it's not outside the plot
|
||||||
// retail uses a radius based check
|
// anecdotal evidence on reddit seems to imply retail uses a radius based check
|
||||||
|
|
||||||
// unlink item
|
// unlink item
|
||||||
Inventory::HousingItemPtr item;
|
Inventory::HousingItemPtr item;
|
||||||
|
@ -1009,6 +1003,8 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity
|
||||||
containerId == InventoryType::Bag3 )
|
containerId == InventoryType::Bag3 )
|
||||||
{
|
{
|
||||||
auto tmpItem = player.dropInventoryItem( static_cast< Common::InventoryType >( containerId ), slotId );
|
auto tmpItem = player.dropInventoryItem( static_cast< Common::InventoryType >( containerId ), slotId );
|
||||||
|
if( !tmpItem )
|
||||||
|
return;
|
||||||
|
|
||||||
item = Inventory::make_HousingItem( tmpItem->getUId(), tmpItem->getId(), framework() );
|
item = Inventory::make_HousingItem( tmpItem->getUId(), tmpItem->getId(), framework() );
|
||||||
|
|
||||||
|
@ -1042,6 +1038,76 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity
|
||||||
player.sendUrgent( "An internal error occurred when placing the item." );
|
player.sendUrgent( "An internal error occurred when placing the item." );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sapphire::World::Manager::HousingMgr::reqPlaceItemInStore( Sapphire::Entity::Player& player, uint16_t landId,
|
||||||
|
uint16_t containerId, uint16_t slotId )
|
||||||
|
{
|
||||||
|
LandPtr land;
|
||||||
|
bool isOutside = false;
|
||||||
|
|
||||||
|
if( auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ) )
|
||||||
|
{
|
||||||
|
land = zone->getLand( landId );
|
||||||
|
isOutside = true;
|
||||||
|
}
|
||||||
|
else if( auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ) )
|
||||||
|
{
|
||||||
|
// todo: this whole process is retarded and needs to be fixed
|
||||||
|
// perhaps maintain a list of estates by ident inside housingmgr?
|
||||||
|
auto ident = zone->getLandIdent();
|
||||||
|
auto landSet = toLandSetId( ident.territoryTypeId, ident.wardNum );
|
||||||
|
|
||||||
|
land = getHousingZoneByLandSetId( landSet )->getLand( ident.landId );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto invMgr = framework()->get< InventoryMgr >();
|
||||||
|
auto ident = land->getLandIdent();
|
||||||
|
auto& containers = getEstateInventory( ident );
|
||||||
|
|
||||||
|
if( isOutside )
|
||||||
|
{
|
||||||
|
auto& container = containers[ InventoryType::HousingExteriorStoreroom ];
|
||||||
|
|
||||||
|
auto freeSlot = container->getFreeSlot();
|
||||||
|
if( freeSlot == -1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto item = player.dropInventoryItem( static_cast< Common::InventoryType >( containerId ), slotId );
|
||||||
|
if( !item )
|
||||||
|
return;
|
||||||
|
|
||||||
|
container->setItem( freeSlot, item );
|
||||||
|
invMgr->sendInventoryContainer( player, container );
|
||||||
|
invMgr->saveHousingContainer( ident, container );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( auto houseContainer : m_internalStoreroomContainers )
|
||||||
|
{
|
||||||
|
auto needle = containers.find( houseContainer );
|
||||||
|
if( needle == containers.end() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto container = needle->second;
|
||||||
|
auto freeSlot = container->getFreeSlot();
|
||||||
|
if( freeSlot == -1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto item = player.dropInventoryItem( static_cast< Common::InventoryType >( containerId ), slotId );
|
||||||
|
if( !item )
|
||||||
|
return;
|
||||||
|
|
||||||
|
container->setItem( freeSlot, item );
|
||||||
|
invMgr->sendInventoryContainer( player, container );
|
||||||
|
invMgr->saveHousingContainer( ident, container );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Sapphire::World::Manager::HousingMgr::placeExternalItem( Entity::Player& player,
|
bool Sapphire::World::Manager::HousingMgr::placeExternalItem( Entity::Player& player,
|
||||||
Inventory::HousingItemPtr item,
|
Inventory::HousingItemPtr item,
|
||||||
Common::LandIdent ident )
|
Common::LandIdent ident )
|
||||||
|
@ -1107,9 +1173,6 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl
|
||||||
// have a free slot
|
// have a free slot
|
||||||
container->setItem( freeSlot, item );
|
container->setItem( freeSlot, item );
|
||||||
|
|
||||||
// todo: see comment above in placeExternalItem where the same func is called
|
|
||||||
invMgr->saveItem( player, item );
|
|
||||||
|
|
||||||
// resend container
|
// resend container
|
||||||
invMgr->sendInventoryContainer( player, container );
|
invMgr->sendInventoryContainer( player, container );
|
||||||
invMgr->saveHousingContainer( ident, container );
|
invMgr->saveHousingContainer( ident, container );
|
||||||
|
@ -1176,8 +1239,7 @@ void Sapphire::World::Manager::HousingMgr::reqMoveHousingItem( Entity::Player& p
|
||||||
if( !land )
|
if( !land )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: proper perms checks
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
if( land->getOwnerId() != player.getId() )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: what happens when either of these fail? how does the server let the client know that the moment failed
|
// todo: what happens when either of these fail? how does the server let the client know that the moment failed
|
||||||
|
@ -1250,8 +1312,7 @@ bool Sapphire::World::Manager::HousingMgr::moveExternalItem( Entity::Player& pla
|
||||||
{
|
{
|
||||||
auto land = terri.getLand( ident.landId );
|
auto land = terri.getLand( ident.landId );
|
||||||
|
|
||||||
// todo: add proper perms check
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
if( land->getOwnerId() != player.getId() )
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto& containers = getEstateInventory( ident );
|
auto& containers = getEstateInventory( ident );
|
||||||
|
@ -1298,8 +1359,7 @@ void Sapphire::World::Manager::HousingMgr::reqRemoveHousingItem( Sapphire::Entit
|
||||||
if( !land )
|
if( !land )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: proper perms checks
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
if( land->getOwnerId() != player.getId() )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
removeInternalItem( player, *terri, containerId, slot, sendToStoreroom );
|
removeInternalItem( player, *terri, containerId, slot, sendToStoreroom );
|
||||||
|
@ -1310,7 +1370,7 @@ void Sapphire::World::Manager::HousingMgr::reqRemoveHousingItem( Sapphire::Entit
|
||||||
if( !land )
|
if( !land )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( land->getOwnerId() != player.getId() )
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto containerType = static_cast< Common::InventoryType >( containerId );
|
auto containerType = static_cast< Common::InventoryType >( containerId );
|
||||||
|
@ -1419,11 +1479,13 @@ bool Sapphire::World::Manager::HousingMgr::removeExternalItem( Entity::Player& p
|
||||||
if( !item )
|
if( !item )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bool shouldDespawnItem = containerType != InventoryType::HousingExteriorStoreroom;
|
||||||
|
|
||||||
auto invMgr = framework()->get< InventoryMgr >();
|
auto invMgr = framework()->get< InventoryMgr >();
|
||||||
|
|
||||||
if( sendToStoreroom )
|
if( sendToStoreroom )
|
||||||
{
|
{
|
||||||
auto& storeroomContainer = containers[ InventoryType::HousingExteriorStoreroom ];
|
auto& storeroomContainer = containers[ containerType ];
|
||||||
auto freeSlot = storeroomContainer->getFreeSlot();
|
auto freeSlot = storeroomContainer->getFreeSlot();
|
||||||
|
|
||||||
if( freeSlot == -1 )
|
if( freeSlot == -1 )
|
||||||
|
@ -1431,8 +1493,8 @@ bool Sapphire::World::Manager::HousingMgr::removeExternalItem( Entity::Player& p
|
||||||
|
|
||||||
sourceContainer->removeItem( slotId );
|
sourceContainer->removeItem( slotId );
|
||||||
invMgr->sendInventoryContainer( player, sourceContainer );
|
invMgr->sendInventoryContainer( player, sourceContainer );
|
||||||
invMgr->removeHousingItemPosition( *item );
|
|
||||||
invMgr->removeItemFromHousingContainer( land.getLandIdent(), sourceContainer->getId(), slotId );
|
invMgr->removeItemFromHousingContainer( land.getLandIdent(), sourceContainer->getId(), slotId );
|
||||||
|
invMgr->removeHousingItemPosition( *item );
|
||||||
|
|
||||||
storeroomContainer->setItem( freeSlot, item );
|
storeroomContainer->setItem( freeSlot, item );
|
||||||
invMgr->sendInventoryContainer( player, storeroomContainer );
|
invMgr->sendInventoryContainer( player, storeroomContainer );
|
||||||
|
@ -1454,6 +1516,7 @@ bool Sapphire::World::Manager::HousingMgr::removeExternalItem( Entity::Player& p
|
||||||
player.insertInventoryItem( containerPair.first, containerPair.second, item );
|
player.insertInventoryItem( containerPair.first, containerPair.second, item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( shouldDespawnItem )
|
||||||
terri.despawnYardObject( land.getLandIdent().landId, slotId );
|
terri.despawnYardObject( land.getLandIdent().landId, slotId );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1495,8 +1558,7 @@ void Sapphire::World::Manager::HousingMgr::reqEstateExteriorRemodel( Sapphire::E
|
||||||
if( !land )
|
if( !land )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: proper perms checks
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
if( land->getOwnerId() != player.getId() )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto& inv = getEstateInventory( land->getLandIdent() );
|
auto& inv = getEstateInventory( land->getLandIdent() );
|
||||||
|
@ -1526,8 +1588,7 @@ void Sapphire::World::Manager::HousingMgr::reqEstateInteriorRemodel( Sapphire::E
|
||||||
if( !land )
|
if( !land )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// todo: proper perms checks
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
if( land->getOwnerId() != player.getId() )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto& inv = getEstateInventory( land->getLandIdent() );
|
auto& inv = getEstateInventory( land->getLandIdent() );
|
||||||
|
@ -1542,3 +1603,15 @@ void Sapphire::World::Manager::HousingMgr::reqEstateInteriorRemodel( Sapphire::E
|
||||||
auto pkt = Server::makeActorControl143( player.getId(), Network::ActorControl::ShowEstateInternalAppearanceUI );
|
auto pkt = Server::makeActorControl143( player.getId(), Network::ActorControl::ShowEstateInternalAppearanceUI );
|
||||||
player.queuePacket( pkt );
|
player.queuePacket( pkt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sapphire::World::Manager::HousingMgr::hasPermission( Sapphire::Entity::Player& player, Sapphire::Land& land,
|
||||||
|
uint32_t permission )
|
||||||
|
{
|
||||||
|
// todo: proper perms checks pls
|
||||||
|
if( land.getOwnerId() == player.getId() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// todo: check perms here
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -159,6 +159,8 @@ namespace Sapphire::World::Manager
|
||||||
void reqPlaceHousingItem( Entity::Player& player, uint16_t landId, uint16_t containerId, uint16_t slotId,
|
void reqPlaceHousingItem( Entity::Player& player, uint16_t landId, uint16_t containerId, uint16_t slotId,
|
||||||
Common::FFXIVARR_POSITION3 pos, float rotation );
|
Common::FFXIVARR_POSITION3 pos, float rotation );
|
||||||
|
|
||||||
|
void reqPlaceItemInStore( Entity::Player& player, uint16_t landId, uint16_t containerId, uint16_t slotId );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Returns the equivalent YardObject for a HousingItem
|
* @brief Returns the equivalent YardObject for a HousingItem
|
||||||
* @param item The item to convert into a YardObject
|
* @param item The item to convert into a YardObject
|
||||||
|
@ -179,6 +181,8 @@ namespace Sapphire::World::Manager
|
||||||
|
|
||||||
void reqEstateInteriorRemodel( Entity::Player& player );
|
void reqEstateInteriorRemodel( Entity::Player& player );
|
||||||
|
|
||||||
|
bool hasPermission( Entity::Player& player, Land& land, uint32_t permission );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ItemContainerPtr getFreeEstateInventorySlot( Common::LandIdent ident,
|
ItemContainerPtr getFreeEstateInventorySlot( Common::LandIdent ident,
|
||||||
|
|
|
@ -731,9 +731,15 @@ void Sapphire::Network::GameConnection::reqPlaceHousingItem( FrameworkPtr pFw,
|
||||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcReqPlaceHousingItem >( inPacket );
|
const auto packet = ZoneChannelPacket< Client::FFXIVIpcReqPlaceHousingItem >( inPacket );
|
||||||
const auto& data = packet.data();
|
const auto& data = packet.data();
|
||||||
|
|
||||||
|
if( data.shouldPlaceItem == 1 )
|
||||||
|
{
|
||||||
housingMgr->reqPlaceHousingItem( player, data.landId, data.sourceInvContainerId, data.sourceInvSlotId,
|
housingMgr->reqPlaceHousingItem( player, data.landId, data.sourceInvContainerId, data.sourceInvSlotId,
|
||||||
data.position, data.rotation );
|
data.position, data.rotation );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
housingMgr->reqPlaceItemInStore( player, data.landId, data.sourceInvContainerId, data.sourceInvSlotId );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Sapphire::Network::GameConnection::reqMoveHousingItem( FrameworkPtr pFw,
|
void Sapphire::Network::GameConnection::reqMoveHousingItem( FrameworkPtr pFw,
|
||||||
const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||||
|
|
Loading…
Add table
Reference in a new issue