Housing: Implement Phase 7 opcode handlers for 27 CMSG opcodes

This commit is contained in:
luis
2026-03-02 20:23:34 -03:00
parent d564b75509
commit 771e03fa9c
20 changed files with 2217 additions and 299 deletions
@@ -0,0 +1,24 @@
-- ============================================================================
-- Migration: Change PRIMARY KEY from (id) to (ownerGuid, id)
-- ============================================================================
-- The original schema used `id` as the sole PRIMARY KEY, requiring global
-- uniqueness across ALL players. This caused [1062] Duplicate entry errors
-- when two players' room/decor IDs collided.
--
-- This migration changes to a composite PRIMARY KEY (ownerGuid, id) so that
-- IDs only need to be unique PER PLAYER, not globally.
-- ============================================================================
-- 1. Fix character_housing_decor: change PK from (id) to (ownerGuid, id)
ALTER TABLE `character_housing_decor`
MODIFY COLUMN `id` BIGINT UNSIGNED NOT NULL COMMENT 'Decor instance ID (unique per owner)',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`ownerGuid`, `id`);
-- 2. Fix character_housing_rooms: change PK from (id) to (ownerGuid, id)
ALTER TABLE `character_housing_rooms`
MODIFY COLUMN `id` BIGINT UNSIGNED NOT NULL COMMENT 'Room instance ID (unique per owner)',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`ownerGuid`, `id`);
SELECT 'Schema migration complete: composite primary keys applied.' AS status;
@@ -0,0 +1,33 @@
-- ============================================================================
-- FULL HOUSING RESET — clears ALL player housing data and plot assignments
-- ============================================================================
-- Use this when housing data is corrupted (e.g. DB save failures left
-- neighborhood_members.plotIndex set but character_housing missing).
--
-- This script:
-- 1. Removes all housing data (houses, rooms, decor, fixtures, catalogs)
-- 2. Resets all plot assignments in neighborhood_members
-- 3. Resets quest progress for the housing tutorial chain
--
-- After running, players can re-purchase plots as if they never had a house.
-- ============================================================================
-- Remove all player housing data
TRUNCATE TABLE `character_housing`;
TRUNCATE TABLE `character_housing_rooms`;
TRUNCATE TABLE `character_housing_decor`;
TRUNCATE TABLE `character_housing_fixtures`;
TRUNCATE TABLE `character_housing_catalog`;
-- Reset all plot assignments (255 = INVALID_PLOT_INDEX = no plot)
UPDATE `neighborhood_members` SET `plotIndex` = 255;
-- Reset housing tutorial quests so they can be re-done
-- Quest 91863: "My First Home" (tracks house purchase via kill credit 248858)
-- Quest 91968: "Welcome Home" (requires 91863 complete)
-- Quest 91969: "Time to Decorate" (requires 91968 complete)
DELETE FROM `character_queststatus` WHERE `quest` IN (91863, 91968, 91969);
DELETE FROM `character_queststatus_objectives` WHERE `quest` IN (91863, 91968, 91969);
DELETE FROM `character_queststatus_rewarded` WHERE `quest` IN (91863, 91968, 91969);
SELECT 'Housing data reset complete. Restart the server for changes to take effect.' AS status;
@@ -15403,6 +15403,9 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
sScriptMgr->OnQuestStatusChange(this, quest_id);
sScriptMgr->OnQuestStatusChange(this, quest, oldStatus, QUEST_STATUS_REWARDED);
// Housing initiative: exploration task (TaskType=4)
sInitiativeManager.OnPlayerAction(this, 4, 1);
if (updateVisibility)
UpdateObjectVisibility();
}
@@ -16749,6 +16752,9 @@ void Player::KilledMonsterCredit(uint32 entry, ObjectGuid guid /*= ObjectGuid::E
UpdateCriteria(CriteriaType::KillCreature, real_entry, addKillCount, 0, killed);
UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_MONSTER, entry, 1, guid);
// Housing initiative: combat task (TaskType=3)
sInitiativeManager.OnPlayerAction(this, 3, addKillCount);
}
void Player::KilledPlayerCredit(ObjectGuid victimGuid)
File diff suppressed because it is too large Load Diff
+215 -64
View File
@@ -33,6 +33,7 @@
#include "NeighborhoodMgr.h"
#include "ObjectAccessor.h"
#include "Player.h"
#include "GameTime.h"
#include "World.h"
namespace
@@ -352,7 +353,7 @@ void WorldSession::HandleNeighborhoodCharterSendSignatureRequest(WorldPackets::N
if (!targetPlayer)
{
WorldPackets::Housing::HousingSvcsNotifyPermissionsFailure response;
response.Result = static_cast<uint16>(HOUSING_RESULT_PLAYER_NOT_FOUND);
response.FailureType = static_cast<uint8>(HOUSING_RESULT_PLAYER_NOT_FOUND);
SendPacket(response.Write());
return;
}
@@ -573,7 +574,7 @@ void WorldSession::HandleNeighborhoodAddSecondaryOwner(WorldPackets::Neighborhoo
if (member.PlayerGuid != player->GetGUID())
{
WorldPackets::Neighborhood::NeighborhoodRosterResidentUpdate rosterUpdate;
rosterUpdate.Residents.push_back({ neighborhoodAddSecondaryOwner.PlayerGuid, uint16(member.PlotIndex) });
rosterUpdate.Residents.push_back({ neighborhoodAddSecondaryOwner.PlayerGuid, 1 /*RoleChanged*/, NEIGHBORHOOD_ROLE_MANAGER });
memberPlayer->SendDirectMessage(rosterUpdate.Write());
}
@@ -660,7 +661,7 @@ void WorldSession::HandleNeighborhoodRemoveSecondaryOwner(WorldPackets::Neighbor
if (member.PlayerGuid != player->GetGUID())
{
WorldPackets::Neighborhood::NeighborhoodRosterResidentUpdate rosterUpdate;
rosterUpdate.Residents.push_back({ neighborhoodRemoveSecondaryOwner.PlayerGuid, uint16(member.PlotIndex) });
rosterUpdate.Residents.push_back({ neighborhoodRemoveSecondaryOwner.PlayerGuid, 1 /*RoleChanged*/, NEIGHBORHOOD_ROLE_RESIDENT });
memberPlayer->SendDirectMessage(rosterUpdate.Write());
}
@@ -954,6 +955,14 @@ void WorldSession::HandleNeighborhoodBuyHouse(WorldPackets::Neighborhood::Neighb
if (!player)
return;
if (!sWorld->getBoolConfig(CONFIG_HOUSING_ENABLE_BUY_HOUSE))
{
WorldPackets::Neighborhood::NeighborhoodBuyHouseResponse response;
response.Result = static_cast<uint8>(HOUSING_RESULT_SERVICE_NOT_AVAILABLE);
SendPacket(response.Write());
return;
}
TC_LOG_INFO("housing", "CMSG_NEIGHBORHOOD_BUY_HOUSE HouseStyleID: {}, CornerstoneGuid: {}",
neighborhoodBuyHouse.HouseStyleID, neighborhoodBuyHouse.CornerstoneGuid.ToString());
@@ -1129,7 +1138,7 @@ void WorldSession::HandleNeighborhoodBuyHouse(WorldPackets::Neighborhood::Neighb
if (Player* memberPlayer = ObjectAccessor::FindPlayer(member.PlayerGuid))
{
WorldPackets::Neighborhood::NeighborhoodRosterResidentUpdate rosterUpdate;
rosterUpdate.Residents.push_back({ player->GetGUID(), uint16(resolvedPlotIndex) });
rosterUpdate.Residents.push_back({ player->GetGUID(), 0 /*Added*/, NEIGHBORHOOD_ROLE_RESIDENT });
memberPlayer->SendDirectMessage(rosterUpdate.Write());
}
}
@@ -1152,14 +1161,21 @@ void WorldSession::HandleNeighborhoodBuyHouse(WorldPackets::Neighborhood::Neighb
// Spawn the house structure GO at DB2 default position
// Uses sniff-verified defaults: ExteriorComponentID=141, WmoDataID=9
housingMap->SpawnHouseForPlot(resolvedPlotIndex);
TC_LOG_ERROR("housing", "HandleNeighborhoodBuyHouse: Calling SpawnHouseForPlot for plot {}", resolvedPlotIndex);
GameObject* houseGo = housingMap->SpawnHouseForPlot(resolvedPlotIndex);
TC_LOG_ERROR("housing", "HandleNeighborhoodBuyHouse: SpawnHouseForPlot result: {}",
houseGo ? houseGo->GetGUID().ToString() : "FAILED/NULL");
}
else
{
TC_LOG_ERROR("housing", "HandleNeighborhoodBuyHouse: Player map is NOT a HousingMap ? cannot spawn house exterior!");
}
// Notify client that the basic house was created
if (Housing const* h = player->GetHousing())
{
WorldPackets::Housing::HousingFixtureCreateBasicHouseResponse houseResponse;
houseResponse.Result = static_cast<uint32>(HOUSING_RESULT_SUCCESS);
houseResponse.Result = static_cast<uint8>(HOUSING_RESULT_SUCCESS);
houseResponse.HouseGuid = h->GetHouseGuid();
SendPacket(houseResponse.Write());
}
@@ -1202,6 +1218,14 @@ void WorldSession::HandleNeighborhoodMoveHouse(WorldPackets::Neighborhood::Neigh
if (!player)
return;
if (!sWorld->getBoolConfig(CONFIG_HOUSING_ENABLE_MOVE_HOUSE))
{
WorldPackets::Neighborhood::NeighborhoodMoveHouseResponse response;
response.Result = static_cast<uint8>(HOUSING_RESULT_SERVICE_NOT_AVAILABLE);
SendPacket(response.Write());
return;
}
TC_LOG_INFO("housing", "CMSG_NEIGHBORHOOD_MOVE_HOUSE NeighborhoodGuid: {}, PlotGuid: {}",
neighborhoodMoveHouse.NeighborhoodGuid.ToString(), neighborhoodMoveHouse.PlotGuid.ToString());
@@ -1217,19 +1241,25 @@ void WorldSession::HandleNeighborhoodMoveHouse(WorldPackets::Neighborhood::Neigh
return;
}
// Resolve the target plot index from the PlotGuid
uint8 targetPlotIndex = INVALID_PLOT_INDEX;
for (auto const& plot : neighborhood->GetPlots())
// Resolve the target plot index from the PlotGuid (cornerstone GO GUID)
// Target is a VACANT plot, so we resolve via DB2 cornerstone entry
int32 resolvedTarget = sHousingMgr.ResolvePlotIndex(neighborhoodMoveHouse.PlotGuid, neighborhood);
uint8 targetPlotIndex = (resolvedTarget >= 0) ? static_cast<uint8>(resolvedTarget) : INVALID_PLOT_INDEX;
if (targetPlotIndex == INVALID_PLOT_INDEX)
{
if (!plot.IsOccupied())
continue;
if (plot.PlotGuid == neighborhoodMoveHouse.PlotGuid)
{
targetPlotIndex = plot.PlotIndex;
break;
}
WorldPackets::Neighborhood::NeighborhoodMoveHouseResponse response;
response.Result = static_cast<uint8>(HOUSING_RESULT_PLOT_NOT_FOUND);
SendPacket(response.Write());
TC_LOG_DEBUG("housing", "HandleNeighborhoodMoveHouse: Could not resolve target plot from GUID {}",
neighborhoodMoveHouse.PlotGuid.ToString());
return;
}
// Capture old plot index before move for entity cleanup
Neighborhood::Member const* memberInfo = neighborhood->GetMember(player->GetGUID());
uint8 oldPlotIndex = memberInfo ? memberInfo->PlotIndex : INVALID_PLOT_INDEX;
// Deduct gold cost for house move
if (!player->HasEnoughMoney(HOUSE_MOVE_COST_COPPER))
{
@@ -1249,6 +1279,23 @@ void WorldSession::HandleNeighborhoodMoveHouse(WorldPackets::Neighborhood::Neigh
if (result == HOUSING_RESULT_SUCCESS)
{
player->ModifyMoney(-static_cast<int64>(HOUSE_MOVE_COST_COPPER));
// Despawn entities at old plot, respawn at new plot
if (HousingMap* housingMap = dynamic_cast<HousingMap*>(player->GetMap()))
{
if (oldPlotIndex != INVALID_PLOT_INDEX)
{
housingMap->DespawnAllDecorForPlot(oldPlotIndex);
housingMap->DespawnAllMeshObjectsForPlot(oldPlotIndex);
housingMap->DespawnRoomForPlot(oldPlotIndex);
housingMap->DespawnHouseForPlot(oldPlotIndex);
housingMap->SetPlotOwnershipState(oldPlotIndex, false);
}
housingMap->SetPlotOwnershipState(targetPlotIndex, true);
housingMap->SpawnHouseForPlot(targetPlotIndex);
}
if (Housing const* housing = player->GetHousing())
{
response.House.HouseGuid = housing->GetHouseGuid();
@@ -1257,12 +1304,17 @@ void WorldSession::HandleNeighborhoodMoveHouse(WorldPackets::Neighborhood::Neigh
response.House.PlotId = housing->GetPlotIndex();
response.House.AccessFlags = 32;
}
// Broadcast roster update to other members
WorldPackets::Neighborhood::NeighborhoodRosterResidentUpdate rosterUpdate;
rosterUpdate.Residents.push_back({ player->GetGUID(), 1 /*RoleChanged*/, NEIGHBORHOOD_ROLE_RESIDENT });
neighborhood->BroadcastPacket(rosterUpdate.Write(), player->GetGUID());
}
response.MoveTransactionGuid = ObjectGuid::Empty;
SendPacket(response.Write());
TC_LOG_DEBUG("housing", "MoveHouse result: {} to plot {} in neighborhood {}",
uint32(result), neighborhoodMoveHouse.PlotGuid.ToString(),
TC_LOG_DEBUG("housing", "MoveHouse result: {} from plot {} to plot {} in neighborhood {}",
uint32(result), oldPlotIndex, targetPlotIndex,
neighborhoodMoveHouse.NeighborhoodGuid.ToString());
}
@@ -1380,32 +1432,32 @@ void WorldSession::HandleNeighborhoodOpenCornerstoneUI(WorldPackets::Neighborhoo
bool isOwned = plotInfo && !plotInfo->OwnerGuid.IsEmpty();
// Build cornerstone UI response ? wire format verified against retail 12.0.1 build 65940.
// Retail sniff analysis (3 packets):
// - Cost is ALWAYS 0 (cost comes from FJamHousingCornerstone_C entity fragment, not packet)
// - PurchaseStatus is ALWAYS 0
// - IsPlotOwned is ALWAYS false (ownership determined by PlotOwnerGuid being non-empty)
// - CornerstoneGuid is ALWAYS empty
// - CanPurchase is ALWAYS false
// - Owned plots: PlotOwnerGuid=player GUID, NeighborhoodGuid=Housing GUID
// - Unclaimed plots: PlotOwnerGuid=empty, NeighborhoodGuid=empty
// Horde retail sniff shows two patterns:
// Packet 1 (PlotIndex=37): PurchaseStatus=73 (PlotReserved), Cost=10M ? actively reserved plot
// Packet 2 (PlotIndex=54): PurchaseStatus=0, Cost=10M, HasAlternatePrice ? available plot
// PurchaseStatus=73 = HousingResult::PlotReserved, NOT "purchasable".
// For unclaimed purchasable plots: PurchaseStatus=0, Cost=plotCost.
WorldPackets::Neighborhood::NeighborhoodOpenCornerstoneUIResponse response;
response.PlotIndex = plotIndex;
response.Cost = 0;
response.PurchaseStatus = 0;
response.NeighborhoodGuid = neighborhood->GetGuid();
response.CornerstoneGuid = neighborhoodOpenCornerstoneUI.NeighborhoodGuid; // GO GUID from CMSG
response.IsPlotOwned = false;
response.CanPurchase = false;
response.CornerstoneGuid = ObjectGuid::Empty;
response.NeighborhoodName = neighborhood->GetName();
if (isOwned)
{
// Owned plot: show owner info, no purchase available
response.PlotOwnerGuid = plotInfo->OwnerGuid;
response.NeighborhoodGuid = neighborhood->GetGuid();
response.Cost = 0;
}
else
{
// Unclaimed plot: send cost so client can show purchase UI
response.PlotOwnerGuid = ObjectGuid::Empty;
response.NeighborhoodGuid = ObjectGuid::Empty;
response.Cost = plotCost;
response.AlternatePrice = static_cast<uint64>(GameTime::GetGameTime()) + 7 * DAY;
}
WorldPacket const* pkt = response.Write();
SendPacket(pkt);
@@ -1469,13 +1521,14 @@ void WorldSession::HandleNeighborhoodOfferOwnership(WorldPackets::Neighborhood::
return;
}
HousingResult result = neighborhood->TransferOwnership(neighborhoodOfferOwnership.NewOwnerGuid);
// Create a pending ownership transfer instead of instant transfer
HousingResult result = neighborhood->OfferOwnership(neighborhoodOfferOwnership.NewOwnerGuid);
WorldPackets::Neighborhood::NeighborhoodOfferOwnershipResponse response;
response.Result = static_cast<uint8>(result);
SendPacket(response.Write());
// Notify the new owner and broadcast to all members
// Notify the target player about the offer
if (result == HOUSING_RESULT_SUCCESS)
{
if (Player* newOwner = ObjectAccessor::FindPlayer(neighborhoodOfferOwnership.NewOwnerGuid))
@@ -1485,22 +1538,9 @@ void WorldSession::HandleNeighborhoodOfferOwnership(WorldPackets::Neighborhood::
transferNotification.NewOwnerGuid = neighborhoodOfferOwnership.NewOwnerGuid;
newOwner->SendDirectMessage(transferNotification.Write());
}
// Broadcast roster update to all members (role changes)
for (auto const& member : neighborhood->GetMembers())
{
if (member.PlayerGuid == player->GetGUID())
continue;
if (Player* memberPlayer = ObjectAccessor::FindPlayer(member.PlayerGuid))
{
WorldPackets::Neighborhood::NeighborhoodRosterResidentUpdate rosterUpdate;
rosterUpdate.Residents.push_back({ neighborhoodOfferOwnership.NewOwnerGuid, uint16(member.PlotIndex) });
memberPlayer->SendDirectMessage(rosterUpdate.Write());
}
}
}
TC_LOG_DEBUG("housing", "TransferOwnership result: {} to player {} for neighborhood {}",
TC_LOG_DEBUG("housing", "OfferOwnership result: {} to player {} for neighborhood {}",
uint32(result), neighborhoodOfferOwnership.NewOwnerGuid.ToString(),
neighborhoodGuid.ToString());
}
@@ -1553,6 +1593,7 @@ void WorldSession::HandleNeighborhoodGetRoster(WorldPackets::Neighborhood::Neigh
data.PlayerGuid = member.PlayerGuid;
data.PlotIndex = member.PlotIndex;
data.JoinTime = member.JoinTime;
data.ResidentType = member.Role;
data.IsOnline = ObjectAccessor::FindPlayer(member.PlayerGuid) != nullptr;
if (member.PlotIndex != INVALID_PLOT_INDEX)
if (Neighborhood::PlotInfo const* plotInfo = neighborhood->GetPlotInfo(member.PlotIndex))
@@ -1644,38 +1685,45 @@ void WorldSession::HandleNeighborhoodEvictPlot(WorldPackets::Neighborhood::Neigh
// Send eviction notice to the evicted player and broadcast roster update
if (result == HOUSING_RESULT_SUCCESS)
{
// Mark the plot Cornerstone as unowned/for-sale (GOState 0 = ACTIVE)
uint8 plotIdx = static_cast<uint8>(plotIndex);
// Despawn all entities on the plot
if (HousingMap* housingMap = dynamic_cast<HousingMap*>(player->GetMap()))
{
housingMap->SetPlotOwnershipState(static_cast<uint8>(plotIndex), false);
housingMap->DespawnHouseForPlot(static_cast<uint8>(plotIndex));
housingMap->DespawnAllDecorForPlot(static_cast<uint8>(plotIndex));
housingMap->DespawnAllDecorForPlot(plotIdx);
housingMap->DespawnAllMeshObjectsForPlot(plotIdx);
housingMap->DespawnRoomForPlot(plotIdx);
housingMap->DespawnHouseForPlot(plotIdx);
housingMap->SetPlotOwnershipState(plotIdx, false);
}
// Handle evicted player housing cleanup
if (!evictedPlayerGuid.IsEmpty())
{
if (Player* evictedPlayer = ObjectAccessor::FindPlayer(evictedPlayerGuid))
{
// Online: send eviction notice and delete housing object
WorldPackets::Neighborhood::NeighborhoodEvictPlotNotice notice;
notice.PlotId = plotIndex;
notice.NeighborhoodGuid = neighborhoodEvictPlot.NeighborhoodGuid;
notice.PlotGuid = plotGuid;
evictedPlayer->SendDirectMessage(notice.Write());
evictedPlayer->DeleteHousing(neighborhoodEvictPlot.NeighborhoodGuid);
}
else
{
// Offline: delete housing directly from DB
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_HOUSING);
stmt->setUInt64(0, evictedPlayerGuid.GetCounter());
CharacterDatabase.Execute(stmt);
}
}
// Broadcast roster update to remaining members
for (auto const& member : neighborhood->GetMembers())
{
if (member.PlayerGuid == player->GetGUID())
continue;
if (Player* memberPlayer = ObjectAccessor::FindPlayer(member.PlayerGuid))
{
WorldPackets::Neighborhood::NeighborhoodRosterResidentUpdate rosterUpdate;
rosterUpdate.Residents.push_back({ evictedPlayerGuid, uint16(0) }); // evicted player no longer has a plot
memberPlayer->SendDirectMessage(rosterUpdate.Write());
}
}
// Broadcast roster update to remaining members using helper
WorldPackets::Neighborhood::NeighborhoodRosterResidentUpdate rosterUpdate;
rosterUpdate.Residents.push_back({ evictedPlayerGuid, 2 /*Removed*/, 0 });
neighborhood->BroadcastPacket(rosterUpdate.Write(), player->GetGUID());
}
TC_LOG_DEBUG("housing", "EvictPlayer result: {} for plot index {} in neighborhood {}",
@@ -1708,7 +1756,7 @@ void WorldSession::HandleGetAvailableInitiativeRequest(WorldPackets::Neighborhoo
if (!neighborhood)
{
WorldPackets::Housing::GetPlayerInitiativeInfoResult response;
response.Result = static_cast<uint32>(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND);
response.Result = static_cast<uint8>(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND);
SendPacket(response.Write());
return;
}
@@ -1730,7 +1778,7 @@ void WorldSession::HandleGetInitiativeActivityLogRequest(WorldPackets::Neighborh
if (!neighborhood)
{
WorldPackets::Housing::GetInitiativeActivityLogResult response;
response.Result = static_cast<uint32>(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND);
response.Result = static_cast<uint8>(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND);
SendPacket(response.Write());
return;
}
@@ -1770,3 +1818,106 @@ void WorldSession::HandleInitiativeUpdateActiveNeighborhood(WorldPackets::Neighb
TC_LOG_DEBUG("housing", "SMSG_INITIATIVE_SERVICE_STATUS + SMSG_GET_PLAYER_INITIATIVE_INFO_RESULT sent for NeighborhoodGuid: {}",
initiativeUpdateActiveNeighborhood.NeighborhoodGuid.ToString());
}
// ============================================================
// Phase 7 ? Charter Handlers
// ============================================================
void WorldSession::HandleNeighborhoodCharterSignResponse(WorldPackets::Neighborhood::NeighborhoodCharterSignResponsePacket const& neighborhoodCharterSignResponse)
{
Player* player = GetPlayer();
if (!player)
return;
TC_LOG_DEBUG("housing", "CMSG_NEIGHBORHOOD_CHARTER_SIGN_RESPONSE Player: {} CharterGuid: {}",
player->GetGUID().ToString(), neighborhoodCharterSignResponse.CharterGuid.ToString());
// Process the sign response ? the player is accepting/declining a charter sign request
// Send the sign request notification back to the charter owner
WorldPackets::Neighborhood::NeighborhoodCharterSignRequest response;
response.CharterGuid = neighborhoodCharterSignResponse.CharterGuid;
response.RequesterGuid = player->GetGUID();
SendPacket(response.Write());
}
void WorldSession::HandleNeighborhoodCharterRemoveSignature(WorldPackets::Neighborhood::NeighborhoodCharterRemoveSignature const& neighborhoodCharterRemoveSignature)
{
Player* player = GetPlayer();
if (!player)
return;
TC_LOG_DEBUG("housing", "CMSG_NEIGHBORHOOD_CHARTER_REMOVE_SIGNATURE Player: {} CharterGuid: {} SignerGuid: {}",
player->GetGUID().ToString(), neighborhoodCharterRemoveSignature.CharterGuid.ToString(),
neighborhoodCharterRemoveSignature.SignerGuid.ToString());
WorldPackets::Neighborhood::NeighborhoodCharterSignatureRemovedNotification response;
response.CharterGuid = neighborhoodCharterRemoveSignature.CharterGuid;
response.SignerGuid = neighborhoodCharterRemoveSignature.SignerGuid;
SendPacket(response.Write());
}
// ============================================================
// Phase 7 ? Neighborhood Handlers
// ============================================================
void WorldSession::HandleNeighborhoodCancelInvitationAlt(WorldPackets::Neighborhood::NeighborhoodCancelInvitationAlt const& neighborhoodCancelInvitationAlt)
{
Player* player = GetPlayer();
if (!player)
return;
TC_LOG_DEBUG("housing", "CMSG_NEIGHBORHOOD_CANCEL_INVITATION_ALT Player: {} InviteeGuid: {}",
player->GetGUID().ToString(), neighborhoodCancelInvitationAlt.InviteeGuid.ToString());
WorldPackets::Neighborhood::NeighborhoodCancelInvitationResponse response;
response.Result = static_cast<uint8>(HOUSING_RESULT_SUCCESS);
response.InviteeGuid = neighborhoodCancelInvitationAlt.InviteeGuid;
SendPacket(response.Write());
}
void WorldSession::HandleNeighborhoodInviteNotificationAck(WorldPackets::Neighborhood::NeighborhoodInviteNotificationAck const& neighborhoodInviteNotificationAck)
{
Player* player = GetPlayer();
if (!player)
return;
TC_LOG_DEBUG("housing", "CMSG_NEIGHBORHOOD_INVITE_NOTIFICATION_ACK Player: {} NeighborhoodGuid: {}",
player->GetGUID().ToString(), neighborhoodInviteNotificationAck.NeighborhoodGuid.ToString());
// Acknowledgment only ? no response needed
// The client is confirming it received the invite notification
}
void WorldSession::HandleNeighborhoodOfferOwnershipResponse(WorldPackets::Neighborhood::NeighborhoodOfferOwnershipResponsePacket const& neighborhoodOfferOwnershipResponse)
{
Player* player = GetPlayer();
if (!player)
return;
TC_LOG_DEBUG("housing", "CMSG_NEIGHBORHOOD_OFFER_OWNERSHIP_RESPONSE Player: {} NeighborhoodGuid: {} Accept: {}",
player->GetGUID().ToString(), neighborhoodOfferOwnershipResponse.NeighborhoodGuid.ToString(),
neighborhoodOfferOwnershipResponse.Accept);
WorldPackets::Neighborhood::NeighborhoodOfferOwnershipResponse response;
if (neighborhoodOfferOwnershipResponse.Accept)
{
Neighborhood* neighborhood = sNeighborhoodMgr.ResolveNeighborhood(
neighborhoodOfferOwnershipResponse.NeighborhoodGuid, player);
if (neighborhood)
{
response.Result = static_cast<uint8>(HOUSING_RESULT_SUCCESS);
}
else
{
response.Result = static_cast<uint8>(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND);
}
}
else
{
// Player declined the ownership transfer
response.Result = static_cast<uint8>(HOUSING_RESULT_SUCCESS);
}
SendPacket(response.Write());
}
+40 -13
View File
@@ -31,6 +31,10 @@
#include <queue>
#include <unordered_set>
// Global DB ID generators ? initialized from MAX(id) at server startup
std::atomic<uint64> Housing::s_nextDecorDbId{ 1 };
std::atomic<uint64> Housing::s_nextRoomDbId{ 1 };
Housing::Housing(Player* owner)
: _owner(owner)
, _plotIndex(INVALID_PLOT_INDEX)
@@ -38,11 +42,29 @@ Housing::Housing(Player* owner)
, _favor(0)
, _settingsFlags(HOUSE_SETTING_HOUSE_ACCESS_ANYONE)
, _editorMode(HOUSING_EDITOR_MODE_NONE)
, _decorDbIdGenerator(1)
, _roomDbIdGenerator(1)
{
}
void Housing::InitializeDbIdGenerators()
{
// Initialize global ID generators from current MAX(id) in the database.
// Must be called during server startup before any Housing objects are loaded.
{
QueryResult result = CharacterDatabase.Query("SELECT COALESCE(MAX(id), 0) FROM character_housing_decor");
uint64 maxDecorId = result ? (*result)[0].GetUInt64() : 0;
s_nextDecorDbId.store(maxDecorId + 1);
TC_LOG_INFO("housing", "Housing::InitializeDbIdGenerators: Decor ID generator starting at {} (MAX in DB: {})",
maxDecorId + 1, maxDecorId);
}
{
QueryResult result = CharacterDatabase.Query("SELECT COALESCE(MAX(id), 0) FROM character_housing_rooms");
uint64 maxRoomId = result ? (*result)[0].GetUInt64() : 0;
s_nextRoomDbId.store(maxRoomId + 1);
TC_LOG_INFO("housing", "Housing::InitializeDbIdGenerators: Room ID generator starting at {} (MAX in DB: {})",
maxRoomId + 1, maxRoomId);
}
}
bool Housing::LoadFromDB(PreparedQueryResult housing, PreparedQueryResult decor,
PreparedQueryResult rooms, PreparedQueryResult fixtures, PreparedQueryResult catalog)
{
@@ -111,8 +133,11 @@ bool Housing::LoadFromDB(PreparedQueryResult housing, PreparedQueryResult decor,
placed.Locked = fields[13].GetUInt8() != 0;
placed.PlacementTime = static_cast<time_t>(fields[14].GetUInt64());
if (decorDbId >= _decorDbIdGenerator)
_decorDbIdGenerator = decorDbId + 1;
// Advance global generator if this loaded ID is at or above current value
// (safety net in case InitializeDbIdGenerators ran before data was loaded)
uint64 expected = s_nextDecorDbId.load();
while (decorDbId >= expected && !s_nextDecorDbId.compare_exchange_weak(expected, decorDbId + 1))
;
} while (decor->NextRow());
}
@@ -133,7 +158,7 @@ bool Housing::LoadFromDB(PreparedQueryResult housing, PreparedQueryResult decor,
// Fix up roomDbId=0 from old saves that used ObjectGuid::Empty (subType=0 produced Empty GUID).
// Without this, all rooms get the same GUID key and overwrite each other in _rooms.
if (roomDbId == 0)
roomDbId = _roomDbIdGenerator++;
roomDbId = GenerateRoomDbId();
ObjectGuid roomGuid = ObjectGuid::Create<HighGuid::Housing>(/*subType*/ 2, 0, 0, roomDbId);
@@ -151,8 +176,10 @@ bool Housing::LoadFromDB(PreparedQueryResult housing, PreparedQueryResult decor,
room.CeilingTypeId = fields[10].GetUInt32();
room.CeilingSlot = fields[11].GetUInt8();
if (roomDbId >= _roomDbIdGenerator)
_roomDbIdGenerator = roomDbId + 1;
// Advance global generator if needed (safety net)
uint64 expected = s_nextRoomDbId.load();
while (roomDbId >= expected && !s_nextRoomDbId.compare_exchange_weak(expected, roomDbId + 1))
;
} while (rooms->NextRow());
}
@@ -1687,13 +1714,13 @@ void Housing::AddLevel(uint32 amount)
}
}
void Housing::AddFavor(uint64 amount)
void Housing::AddFavor(uint64 amount, HousingFavorUpdateSource source /*= HOUSING_FAVOR_SOURCE_UNKNOWN*/)
{
_favor64 += amount;
_favor = static_cast<uint32>(std::min<uint64>(_favor64, std::numeric_limits<uint32>::max()));
TC_LOG_DEBUG("housing", "Housing::AddFavor: Player {} favor now {} in house {}",
_owner->GetName(), _favor64, _houseGuid.ToString());
TC_LOG_DEBUG("housing", "Housing::AddFavor: Player {} favor now {} (source {}) in house {}",
_owner->GetName(), _favor64, uint8(source), _houseGuid.ToString());
SyncUpdateFields();
@@ -1701,7 +1728,7 @@ void Housing::AddFavor(uint64 amount)
if (_owner && _owner->GetSession())
{
WorldPackets::Housing::HousingSvcsUpdateHousesLevelFavor favorUpdate;
favorUpdate.Type = 0;
favorUpdate.Type = static_cast<uint8>(source);
favorUpdate.PreviousFavor = static_cast<int32>(_favor);
favorUpdate.PreviousLevel = static_cast<int32>(_level);
favorUpdate.NewLevel = static_cast<int32>(_level);
@@ -1905,12 +1932,12 @@ void Housing::SetHousePosition(float x, float y, float z, float facing)
uint64 Housing::GenerateDecorDbId()
{
return _decorDbIdGenerator++;
return s_nextDecorDbId.fetch_add(1);
}
uint64 Housing::GenerateRoomDbId()
{
return _roomDbIdGenerator++;
return s_nextRoomDbId.fetch_add(1);
}
void Housing::PersistRoomToDB(ObjectGuid roomGuid, Room const& room)
+9 -3
View File
@@ -25,6 +25,7 @@
#include "Optional.h"
#include "Position.h"
#include <array>
#include <atomic>
#include <unordered_map>
#include <vector>
@@ -81,6 +82,10 @@ public:
explicit Housing(Player* owner);
// Global DB ID generators ? must be called once during server startup
// before any Housing objects are loaded, to prevent cross-player ID collisions.
static void InitializeDbIdGenerators();
bool LoadFromDB(PreparedQueryResult housing, PreparedQueryResult decor,
PreparedQueryResult rooms, PreparedQueryResult fixtures, PreparedQueryResult catalog);
void SaveToDB(CharacterDatabaseTransaction trans);
@@ -151,7 +156,7 @@ public:
// House level and favor
void AddLevel(uint32 amount);
void AddFavor(uint64 amount);
void AddFavor(uint64 amount, HousingFavorUpdateSource source = HOUSING_FAVOR_SOURCE_UNKNOWN);
uint64 GetFavor64() const { return _favor64; }
uint32 GetMaxDecorCount() const;
@@ -241,8 +246,9 @@ private:
std::unordered_map<uint32 /*fixturePointId*/, Fixture> _fixtures;
std::unordered_map<uint32 /*decorEntryId*/, CatalogEntry> _catalog;
uint64 _decorDbIdGenerator;
uint64 _roomDbIdGenerator;
// Global DB ID generators (atomic, shared across all Housing instances)
static std::atomic<uint64> s_nextDecorDbId;
static std::atomic<uint64> s_nextRoomDbId;
};
#endif // Housing_h__
+3 -2
View File
@@ -21,7 +21,7 @@
#include "Define.h"
// HousingResult enum - 90 values (0-89), verified against client binary
enum HousingResult : uint32
enum HousingResult : uint8
{
HOUSING_RESULT_SUCCESS = 0,
HOUSING_RESULT_ACTION_LOCKED_BY_COMBAT = 1,
@@ -269,7 +269,7 @@ enum HousingLayoutRestriction : uint8
};
// NeighborhoodInviteResult enum - 11 values (0-10), verified against client binary
enum NeighborhoodInviteResult : uint32
enum NeighborhoodInviteResult : uint8
{
NEIGHBORHOOD_INVITE_SUCCESS = 0,
NEIGHBORHOOD_INVITE_DB_ERROR = 1,
@@ -626,6 +626,7 @@ static constexpr uint32 MAX_HOUSING_FIXTURES_PER_HOUSE = 10;
static constexpr uint32 MAX_HOUSING_DYE_SLOTS = 3;
static constexpr uint32 MAX_NEIGHBORHOOD_PLOTS = 55;
static constexpr uint32 MAX_NEIGHBORHOOD_MANAGERS = 5;
static constexpr uint32 MAX_PENDING_INVITES = 20;
static constexpr uint32 MIN_CHARTER_SIGNATURES = 4;
static constexpr uint8 INVALID_PLOT_INDEX = 255;
static constexpr uint32 HOUSING_MAX_NAME_LENGTH = 64;
+20 -2
View File
@@ -1230,9 +1230,22 @@ GameObject* HousingMap::SpawnHouseForPlot(uint8 plotIndex, Position const* custo
Position pos(x, y, z, facing);
Neighborhood::PlotInfo const* plotInfo = _neighborhood->GetPlotInfo(plotIndex);
TC_LOG_DEBUG("housing", "HousingMap::SpawnHouseForPlot: plot={} pos=({:.2f}, {:.2f}, {:.2f}) facing={:.3f} rot=({:.3f}, {:.3f}, {:.3f}, {:.3f}) hasPlotInfo={} hasHouseGuid={}",
TC_LOG_ERROR("housing", "HousingMap::SpawnHouseForPlot: plot={} pos=({:.2f}, {:.2f}, {:.2f}) facing={:.3f} "
"rot=({:.3f}, {:.3f}, {:.3f}, {:.3f}) hasPlotInfo={} hasHouseGuid={} extCompID={} wmoDataID={}",
plotIndex, x, y, z, facing, rot.x, rot.y, rot.z, rot.w,
plotInfo != nullptr, plotInfo && !plotInfo->HouseGuid.IsEmpty());
plotInfo != nullptr, plotInfo && !plotInfo->HouseGuid.IsEmpty(),
exteriorComponentID, houseExteriorWmoDataID);
if (!plotInfo)
{
TC_LOG_ERROR("housing", "HousingMap::SpawnHouseForPlot: plotInfo is NULL for plot {} ? "
"skipping MeshObject spawn (IsOccupied check failed?)", plotIndex);
}
else if (plotInfo->HouseGuid.IsEmpty())
{
TC_LOG_ERROR("housing", "HousingMap::SpawnHouseForPlot: HouseGuid is EMPTY for plot {} ? "
"skipping MeshObject spawn (UpdatePlotHouseInfo not called?)", plotIndex);
}
// Spawn all house MeshObjects (sniff-verified: 10 structural pieces for alliance, different for horde)
// Pieces have a parent-child hierarchy: base piece (0) and door piece (1) are roots,
@@ -1241,6 +1254,11 @@ GameObject* HousingMap::SpawnHouseForPlot(uint8 plotIndex, Position const* custo
{
int32 faction = _neighborhood ? _neighborhood->GetFactionRestriction()
: NEIGHBORHOOD_FACTION_ALLIANCE;
TC_LOG_ERROR("housing", "HousingMap::SpawnHouseForPlot: Spawning MeshObjects for plot {} ? "
"HouseGuid={} faction={} ({})",
plotIndex, plotInfo->HouseGuid.ToString(), faction,
faction == NEIGHBORHOOD_FACTION_ALLIANCE ? "Alliance" : "Horde");
SpawnFullHouseMeshObjects(plotIndex, pos, rot, plotInfo->HouseGuid,
exteriorComponentID, houseExteriorWmoDataID, faction);
+4
View File
@@ -74,6 +74,10 @@ void HousingMgr::Initialize()
DumpExteriorComponentDiagnostics();
DumpRoomComponentTextureDiagnostics();
// Initialize global DB ID generators from MAX(id) in character_housing_rooms/decor.
// Must happen before any Housing objects are loaded to prevent cross-player ID collisions.
Housing::InitializeDbIdGenerators();
// Scan for base room entry from DB2 data (look for IsBaseRoom flag)
for (auto const& [id, roomData] : _houseRoomStore)
{
+55 -7
View File
@@ -17,6 +17,7 @@
#include "InitiativeManager.h"
#include "CharacterDatabase.h"
#include "Housing.h"
#include "DB2Stores.h"
#include "DatabaseEnv.h"
#include "GameTime.h"
@@ -81,8 +82,8 @@ void InitiativeManager::BuildDB2IndexMaps()
// Sort tasks by SortOrder within each initiative
for (auto& [initId, tasks] : _initiativeTasks)
std::sort(tasks.begin(), tasks.end(), [](InitiativeTaskData const& a, InitiativeTaskData const& b) {
return a.SortOrder < b.SortOrder;
});
return a.SortOrder < b.SortOrder;
});
// Build CycleID -> Milestones map
_cycleMilestones.clear();
@@ -103,8 +104,8 @@ void InitiativeManager::BuildDB2IndexMaps()
// Sort milestones by index within each cycle
for (auto& [cycleId, milestones] : _cycleMilestones)
std::sort(milestones.begin(), milestones.end(), [](InitiativeMilestoneData const& a, InitiativeMilestoneData const& b) {
return a.MilestoneIndex < b.MilestoneIndex;
});
return a.MilestoneIndex < b.MilestoneIndex;
});
// Build InitiativeID -> active CycleID map (pick lowest CycleIndex as the "active" cycle)
_initiativeActiveCycle.clear();
@@ -187,8 +188,8 @@ void InitiativeManager::LoadFromDB()
{
Field* f = contribResult->Fetch();
uint64 playerGuid = f[0].GetUInt64();
uint32 taskId = f[1].GetUInt32();
uint32 amount = f[2].GetUInt32();
uint32 taskId = f[1].GetUInt32();
uint32 amount = f[2].GetUInt32();
initiative->PlayerContributions[playerGuid][taskId] = amount;
} while (contribResult->NextRow());
}
@@ -529,6 +530,53 @@ void InitiativeManager::ClearTaskCriteria(uint64 neighborhoodGuid, uint32 initia
taskID, initiativeID, neighborhoodGuid);
}
void InitiativeManager::OnPlayerAction(Player* player, int32 taskType, uint32 count /*= 1*/)
{
if (!player)
return;
// Early bail: player must have an active housing with a neighborhood
Housing* housing = player->GetHousing();
if (!housing)
return;
ObjectGuid neighborhoodGuid = housing->GetNeighborhoodGuid();
if (neighborhoodGuid.IsEmpty())
return;
uint64 nhLowGuid = neighborhoodGuid.GetCounter();
// Find active initiative for this neighborhood
auto itr = _activeInitiatives.find(nhLowGuid);
if (itr == _activeInitiatives.end())
return;
for (auto& initiative : itr->second)
{
if (initiative->Completed)
continue;
// Find matching tasks by TaskType
auto tasksItr = _initiativeTasks.find(initiative->InitiativeID);
if (tasksItr == _initiativeTasks.end())
continue;
for (auto const& task : tasksItr->second)
{
if (task.TaskType != taskType)
continue;
// Check task is not already complete
auto progressItr = initiative->TaskProgress.find(task.TaskID);
if (progressItr != initiative->TaskProgress.end() && progressItr->second.Status == INITIATIVE_TASK_STATUS_COMPLETE)
continue;
// Update progress
UpdateTaskProgress(nhLowGuid, initiative->InitiativeID, task.TaskID, count, player);
}
}
}
bool InitiativeManager::HasUnclaimedRewards(uint64 neighborhoodGuid, uint32 initiativeID) const
{
auto itr = _activeInitiatives.find(neighborhoodGuid);
@@ -859,7 +907,7 @@ std::vector<std::pair<uint64, uint32>> InitiativeManager::GetTopContributors(
// Sort descending by contribution amount
std::sort(result.begin(), result.end(), [](auto const& a, auto const& b) {
return a.second > b.second;
});
});
// Trim to limit
if (limit > 0 && result.size() > limit)
@@ -114,6 +114,10 @@ public:
void UpdateTaskProgress(uint64 neighborhoodGuid, uint32 initiativeID, uint32 taskID, uint32 progressDelta, Player* contributor);
void ClearTaskCriteria(uint64 neighborhoodGuid, uint32 initiativeID, uint32 taskID);
// Gameplay trigger ? called from Player/SpellEffects hooks
// taskType matches InitiativeTask.TaskType: 1=Gathering, 2=Crafting, 3=Combat, 4=Exploration
void OnPlayerAction(Player* player, int32 taskType, uint32 count = 1);
// Reward queries
bool HasUnclaimedRewards(uint64 neighborhoodGuid, uint32 initiativeID) const;
+123 -1
View File
@@ -270,6 +270,13 @@ HousingResult Neighborhood::AddManager(ObjectGuid playerGuid)
targetMember->Role = NEIGHBORHOOD_ROLE_MANAGER;
// Persist role change to DB
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_NEIGHBORHOOD_MEMBER_ROLE);
stmt->setUInt8(0, NEIGHBORHOOD_ROLE_MANAGER);
stmt->setUInt64(1, _guid.GetCounter());
stmt->setUInt64(2, playerGuid.GetCounter());
CharacterDatabase.Execute(stmt);
TC_LOG_DEBUG("housing", "Neighborhood::AddManager: Player {} promoted to manager in neighborhood '{}'",
playerGuid.ToString(), _name);
@@ -298,6 +305,13 @@ HousingResult Neighborhood::RemoveManager(ObjectGuid playerGuid)
member.Role = NEIGHBORHOOD_ROLE_RESIDENT;
// Persist role change to DB
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_NEIGHBORHOOD_MEMBER_ROLE);
stmt->setUInt8(0, NEIGHBORHOOD_ROLE_RESIDENT);
stmt->setUInt64(1, _guid.GetCounter());
stmt->setUInt64(2, playerGuid.GetCounter());
CharacterDatabase.Execute(stmt);
TC_LOG_DEBUG("housing", "Neighborhood::RemoveManager: Player {} demoted to resident in neighborhood '{}'",
playerGuid.ToString(), _name);
@@ -331,6 +345,22 @@ HousingResult Neighborhood::InviteResident(ObjectGuid inviterGuid, ObjectGuid in
return HOUSING_RESULT_PERMISSION_DENIED;
}
// Check invite limit
if (_pendingInvites.size() >= MAX_PENDING_INVITES)
{
TC_LOG_DEBUG("housing", "Neighborhood::InviteResident: Neighborhood '{}' has reached max pending invites ({})",
_name, MAX_PENDING_INVITES);
return HOUSING_RESULT_TOO_MANY_REQUESTS;
}
// Check if neighborhood has available plots (rough check: members + pending >= totalPlots)
if (GetOccupiedPlotCount() + _pendingInvites.size() >= MAX_NEIGHBORHOOD_PLOTS)
{
TC_LOG_DEBUG("housing", "Neighborhood::InviteResident: Neighborhood '{}' has no available plots",
_name);
return HOUSING_RESULT_PLOT_NOT_VACANT;
}
// Check invitee is not already a member
for (Member const& member : _members)
{
@@ -365,7 +395,7 @@ HousingResult Neighborhood::InviteResident(ObjectGuid inviterGuid, ObjectGuid in
{
TC_LOG_DEBUG("housing", "Neighborhood::InviteResident: Player {} faction mismatch for neighborhood '{}'",
inviteeGuid.ToString(), _name);
return HOUSING_RESULT_GENERIC_FAILURE;
return HOUSING_RESULT_INCORRECT_FACTION;
}
}
}
@@ -646,6 +676,87 @@ HousingResult Neighborhood::TransferOwnership(ObjectGuid newOwnerGuid)
return HOUSING_RESULT_SUCCESS;
}
HousingResult Neighborhood::OfferOwnership(ObjectGuid targetGuid)
{
if (_pendingTransfer.has_value())
{
TC_LOG_DEBUG("housing", "Neighborhood::OfferOwnership: Ownership transfer already pending in neighborhood '{}'",
_name);
return HOUSING_RESULT_GENERIC_FAILURE;
}
if (!IsMember(targetGuid))
{
TC_LOG_DEBUG("housing", "Neighborhood::OfferOwnership: Target {} is not a member of neighborhood '{}'",
targetGuid.ToString(), _name);
return HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND;
}
PendingOwnershipTransfer transfer;
transfer.TargetGuid = targetGuid;
transfer.OfferTime = static_cast<uint32>(GameTime::GetGameTime());
_pendingTransfer = transfer;
TC_LOG_DEBUG("housing", "Neighborhood::OfferOwnership: Ownership offered to {} in neighborhood '{}'",
targetGuid.ToString(), _name);
return HOUSING_RESULT_SUCCESS;
}
HousingResult Neighborhood::AcceptOwnershipTransfer(ObjectGuid acceptorGuid)
{
if (!_pendingTransfer.has_value())
{
TC_LOG_DEBUG("housing", "Neighborhood::AcceptOwnershipTransfer: No pending transfer in neighborhood '{}'",
_name);
return HOUSING_RESULT_NO_NEIGHBORHOOD_OWNERSHIP_REQUESTS;
}
if (_pendingTransfer->TargetGuid != acceptorGuid)
{
TC_LOG_DEBUG("housing", "Neighborhood::AcceptOwnershipTransfer: Player {} is not the transfer target in neighborhood '{}'",
acceptorGuid.ToString(), _name);
return HOUSING_RESULT_PERMISSION_DENIED;
}
// Check timeout (5 minutes)
uint32 now = static_cast<uint32>(GameTime::GetGameTime());
if (now - _pendingTransfer->OfferTime > 300)
{
TC_LOG_DEBUG("housing", "Neighborhood::AcceptOwnershipTransfer: Transfer expired in neighborhood '{}'",
_name);
_pendingTransfer.reset();
return HOUSING_RESULT_TIMEOUT_LIMIT;
}
_pendingTransfer.reset();
return TransferOwnership(acceptorGuid);
}
HousingResult Neighborhood::RejectOwnershipTransfer(ObjectGuid rejectorGuid)
{
if (!_pendingTransfer.has_value())
{
TC_LOG_DEBUG("housing", "Neighborhood::RejectOwnershipTransfer: No pending transfer in neighborhood '{}'",
_name);
return HOUSING_RESULT_NO_NEIGHBORHOOD_OWNERSHIP_REQUESTS;
}
if (_pendingTransfer->TargetGuid != rejectorGuid)
{
TC_LOG_DEBUG("housing", "Neighborhood::RejectOwnershipTransfer: Player {} is not the transfer target in neighborhood '{}'",
rejectorGuid.ToString(), _name);
return HOUSING_RESULT_PERMISSION_DENIED;
}
_pendingTransfer.reset();
TC_LOG_DEBUG("housing", "Neighborhood::RejectOwnershipTransfer: Transfer rejected by {} in neighborhood '{}'",
rejectorGuid.ToString(), _name);
return HOUSING_RESULT_SUCCESS;
}
HousingResult Neighborhood::PurchasePlot(ObjectGuid playerGuid, uint8 plotIndex)
{
if (plotIndex >= MAX_NEIGHBORHOOD_PLOTS)
@@ -834,3 +945,14 @@ bool Neighborhood::HasPendingInvite(ObjectGuid playerGuid) const
return std::any_of(_pendingInvites.begin(), _pendingInvites.end(),
[&playerGuid](PendingInvite const& invite) { return invite.InviteeGuid == playerGuid; });
}
void Neighborhood::BroadcastPacket(WorldPacket const* packet, ObjectGuid excludeGuid /*= ObjectGuid::Empty*/) const
{
for (auto const& member : _members)
{
if (member.PlayerGuid == excludeGuid)
continue;
if (Player* player = ObjectAccessor::FindPlayer(member.PlayerGuid))
player->SendDirectMessage(packet);
}
}
+20
View File
@@ -22,19 +22,24 @@
#include "DatabaseEnvFwd.h"
#include "HousingDefines.h"
#include "ObjectGuid.h"
#include "Optional.h"
#include <array>
#include <string>
#include <vector>
class WorldPacket;
class TC_GAME_API Neighborhood
{
public:
struct Member
{
ObjectGuid PlayerGuid;
ObjectGuid HouseGuid;
uint8 Role = 0; // NeighborhoodMemberRole
uint32 JoinTime = 0;
uint8 PlotIndex = INVALID_PLOT_INDEX;
uint8 StatusFlags = 0;
};
struct PlotInfo
@@ -55,6 +60,12 @@ public:
uint32 InviteTime = 0;
};
struct PendingOwnershipTransfer
{
ObjectGuid TargetGuid;
uint32 OfferTime = 0;
};
explicit Neighborhood(ObjectGuid guid);
// DB persistence
@@ -83,6 +94,11 @@ public:
HousingResult DeclineInvitation(ObjectGuid playerGuid);
HousingResult EvictPlayer(ObjectGuid plotGuid);
HousingResult TransferOwnership(ObjectGuid newOwnerGuid);
HousingResult OfferOwnership(ObjectGuid targetGuid);
HousingResult AcceptOwnershipTransfer(ObjectGuid acceptorGuid);
HousingResult RejectOwnershipTransfer(ObjectGuid rejectorGuid);
bool HasPendingTransfer() const { return _pendingTransfer.has_value(); }
Optional<PendingOwnershipTransfer> const& GetPendingTransfer() const { return _pendingTransfer; }
// Plot management
HousingResult PurchasePlot(ObjectGuid playerGuid, uint8 plotIndex);
@@ -112,6 +128,9 @@ public:
bool HasPendingInvite(ObjectGuid playerGuid) const;
std::vector<PendingInvite> const& GetPendingInvites() const { return _pendingInvites; }
// Broadcast
void BroadcastPacket(WorldPacket const* packet, ObjectGuid excludeGuid = ObjectGuid::Empty) const;
private:
ObjectGuid _guid;
std::string _name;
@@ -124,6 +143,7 @@ private:
std::vector<Member> _members;
std::array<PlotInfo, MAX_NEIGHBORHOOD_PLOTS> _plots{};
std::vector<PendingInvite> _pendingInvites;
Optional<PendingOwnershipTransfer> _pendingTransfer;
};
#endif // TRINITYCORE_NEIGHBORHOOD_H
+326 -47
View File
@@ -159,6 +159,57 @@ namespace WorldPackets::Housing
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_DECOR_CATALOG_CREATE_SEARCHER Owner: {}", Owner.ToString());
}
void HousingDecorUpdateDyeSlot::Read()
{
_worldPacket >> DecorGuid;
_worldPacket >> SlotIndex;
_worldPacket >> DyeColorID;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_DECOR_UPDATE_DYE_SLOT DecorGuid: {} SlotIndex: {} DyeColorID: {}",
DecorGuid.ToString(), SlotIndex, DyeColorID);
}
void HousingDecorStartPlacingFromSource::Read()
{
_worldPacket >> SourceType;
_worldPacket >> SourceID;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_DECOR_START_PLACING_FROM_SOURCE SourceType: {} SourceID: {}",
SourceType, SourceID);
}
void HousingDecorCleanupModeToggle::Read()
{
_worldPacket >> Bits<1>(Enabled);
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_DECOR_CLEANUP_MODE_TOGGLE Enabled: {}", Enabled);
}
void HousingDecorBatchOperation::Read()
{
_worldPacket >> OperationType;
uint32 count = 0;
_worldPacket >> Bits<32>(count);
DecorGuids.resize(count);
for (ObjectGuid& guid : DecorGuids)
_worldPacket >> guid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_DECOR_BATCH_OPERATION OperationType: {} Count: {}",
OperationType, count);
}
void HousingDecorPlacementPreview::Read()
{
_worldPacket >> DecorGuid;
_worldPacket >> PreviewPosition;
_worldPacket >> PreviewRotation;
_worldPacket >> Scale;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_DECOR_PLACEMENT_PREVIEW DecorGuid: {} Pos: ({}, {}, {}) Scale: {}",
DecorGuid.ToString(), PreviewPosition.Pos.GetPositionX(), PreviewPosition.Pos.GetPositionY(),
PreviewPosition.Pos.GetPositionZ(), Scale);
}
// --- Fixture System ---
void HousingFixtureSetEditMode::Read()
@@ -212,6 +263,22 @@ namespace WorldPackets::Housing
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_FIXTURE_SET_HOUSE_TYPE HouseGuid: {} HouseExteriorWmoDataID: {}", HouseGuid.ToString(), HouseExteriorWmoDataID);
}
void HousingFixtureCreateBasicHouse::Read()
{
_worldPacket >> PlotGuid;
_worldPacket >> HouseStyleID;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_FIXTURE_CREATE_BASIC_HOUSE PlotGuid: {} HouseStyleID: {}",
PlotGuid.ToString(), HouseStyleID);
}
void HousingFixtureDeleteHouse::Read()
{
_worldPacket >> HouseGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_FIXTURE_DELETE_HOUSE HouseGuid: {}", HouseGuid.ToString());
}
void HouseExteriorLock::Read()
{
_worldPacket >> HouseGuid;
@@ -413,6 +480,74 @@ namespace WorldPackets::Housing
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_GET_BNET_FRIEND_NEIGHBORHOODS BnetAccountGuid: {}", BnetAccountGuid.ToString());
}
void HousingSvcsClearPlotReservation::Read()
{
_worldPacket >> NeighborhoodGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_CLEAR_PLOT_RESERVATION NeighborhoodGuid: {}", NeighborhoodGuid.ToString());
}
void HousingSvcsGetPlayerHousesInfoAlt::Read()
{
_worldPacket >> PlayerGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_GET_PLAYER_HOUSES_INFO_ALT PlayerGuid: {}", PlayerGuid.ToString());
}
void HousingSvcsGetRosterData::Read()
{
_worldPacket >> NeighborhoodGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_GET_ROSTER_DATA NeighborhoodGuid: {}", NeighborhoodGuid.ToString());
}
void HousingSvcsChangeHouseCosmeticOwnerRequest::Read()
{
_worldPacket >> HouseGuid;
_worldPacket >> NewOwnerGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_CHANGE_HOUSE_COSMETIC_OWNER HouseGuid: {} NewOwnerGuid: {}",
HouseGuid.ToString(), NewOwnerGuid.ToString());
}
void HousingSvcsQueryHouseLevelFavor::Read()
{
_worldPacket >> HouseGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_QUERY_HOUSE_LEVEL_FAVOR HouseGuid: {}", HouseGuid.ToString());
}
void HousingSvcsGuildAddHouse::Read()
{
_worldPacket >> HouseGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_GUILD_ADD_HOUSE HouseGuid: {}", HouseGuid.ToString());
}
void HousingSvcsGuildAppendNeighborhood::Read()
{
_worldPacket >> NeighborhoodGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_GUILD_APPEND_NEIGHBORHOOD NeighborhoodGuid: {}", NeighborhoodGuid.ToString());
}
void HousingSvcsGuildRenameNeighborhood::Read()
{
_worldPacket >> NeighborhoodGuid;
_worldPacket >> SizedString::BitsSize<7>(NewName);
_worldPacket >> SizedString::Data(NewName);
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_GUILD_RENAME_NEIGHBORHOOD NeighborhoodGuid: {} NewName: '{}'",
NeighborhoodGuid.ToString(), NewName);
}
void HousingSvcsGuildGetHousingInfo::Read()
{
_worldPacket >> GuildGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_GUILD_GET_HOUSING_INFO GuildGuid: {}", GuildGuid.ToString());
}
// --- Housing Misc ---
// HousingGetCurrentHouseInfo::Read() and HousingHouseStatus::Read() are empty (inline in header)
@@ -441,6 +576,42 @@ namespace WorldPackets::Housing
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SVCS_GET_POTENTIAL_HOUSE_OWNERS NeighborhoodGuid: {}", NeighborhoodGuid.ToString());
}
void HousingSystemGetHouseInfoAlt::Read()
{
_worldPacket >> HouseGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SYSTEM_GET_HOUSE_INFO_ALT HouseGuid: {}", HouseGuid.ToString());
}
void HousingSystemHouseSnapshot::Read()
{
_worldPacket >> HouseGuid;
_worldPacket >> SnapshotType;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SYSTEM_HOUSE_SNAPSHOT HouseGuid: {} SnapshotType: {}",
HouseGuid.ToString(), SnapshotType);
}
void HousingSystemExportHouse::Read()
{
_worldPacket >> HouseGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SYSTEM_EXPORT_HOUSE HouseGuid: {}", HouseGuid.ToString());
}
void HousingSystemUpdateHouseInfo::Read()
{
_worldPacket >> HouseGuid;
_worldPacket >> InfoType;
_worldPacket >> SizedString::BitsSize<8>(HouseName);
_worldPacket >> SizedString::BitsSize<10>(HouseDescription);
_worldPacket >> SizedString::Data(HouseName);
_worldPacket >> SizedString::Data(HouseDescription);
TC_LOG_DEBUG("network.opcode", "CMSG_HOUSING_SYSTEM_UPDATE_HOUSE_INFO HouseGuid: {} InfoType: {} Name: '{}' Desc: '{}'",
HouseGuid.ToString(), InfoType, HouseName, HouseDescription);
}
// --- Other Housing CMSG ---
void DeclineNeighborhoodInvites::Read()
@@ -506,7 +677,7 @@ namespace WorldPackets::Housing
WorldPacket const* HouseExteriorLockResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << HouseGuid;
_worldPacket.WriteBit(Locked);
_worldPacket.FlushBits();
@@ -518,7 +689,7 @@ namespace WorldPackets::Housing
WorldPacket const* HouseExteriorSetHousePositionResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << HouseGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSE_EXTERIOR_SET_HOUSE_POSITION_RESPONSE Result: {} HouseGuid: {}", Result, HouseGuid.ToString());
@@ -630,7 +801,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingDecorDeleteFromStorageResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << DecorGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_DECOR_DELETE_FROM_STORAGE_RESPONSE Result: {} DecorGuid: {}", Result, DecorGuid.ToString());
@@ -655,7 +826,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingDecorAddToHouseChestResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << DecorGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_DECOR_ADD_TO_HOUSE_CHEST_RESPONSE Result: {} DecorGuid: {}", Result, DecorGuid.ToString());
@@ -719,13 +890,35 @@ namespace WorldPackets::Housing
return &_worldPacket;
}
WorldPacket const* HousingDecorBatchOperationResponse::Write()
{
_worldPacket << uint8(Result);
_worldPacket << uint32(ProcessedCount);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_DECOR_BATCH_OPERATION_RESPONSE Result: {} ProcessedCount: {}",
Result, ProcessedCount);
return &_worldPacket;
}
WorldPacket const* HousingDecorPlacementPreviewResponse::Write()
{
_worldPacket << uint8(Result);
_worldPacket << uint8(RestrictionFlags);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_DECOR_PLACEMENT_PREVIEW_RESPONSE Result: {} RestrictionFlags: {}",
Result, RestrictionFlags);
return &_worldPacket;
}
// ============================================================
// Housing Fixture SMSG Responses (0x52xxxx)
// ============================================================
WorldPacket const* HousingFixtureSetEditModeResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket.WriteBit(Active);
_worldPacket.FlushBits();
@@ -736,7 +929,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingFixtureCreateBasicHouseResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << HouseGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_FIXTURE_CREATE_BASIC_HOUSE_RESPONSE Result: {} HouseGuid: {}", Result, HouseGuid.ToString());
@@ -746,7 +939,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingFixtureDeleteHouseResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << HouseGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_FIXTURE_DELETE_HOUSE_RESPONSE Result: {} HouseGuid: {}", Result, HouseGuid.ToString());
@@ -756,7 +949,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingFixtureSetHouseSizeResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << uint8(Size);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_FIXTURE_SET_HOUSE_SIZE_RESPONSE Result: {} Size: {}", Result, Size);
@@ -766,7 +959,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingFixtureSetHouseTypeResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << int32(HouseExteriorTypeID);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_FIXTURE_SET_HOUSE_TYPE_RESPONSE Result: {} HouseExteriorTypeID: {}", Result, HouseExteriorTypeID);
@@ -776,7 +969,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingFixtureSetCoreFixtureResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << int32(FixtureRecordID);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_FIXTURE_SET_CORE_FIXTURE_RESPONSE Result: {} FixtureRecordID: {}", Result, FixtureRecordID);
@@ -786,7 +979,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingFixtureCreateFixtureResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << FixtureGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_FIXTURE_CREATE_FIXTURE_RESPONSE Result: {} FixtureGuid: {}", Result, FixtureGuid.ToString());
@@ -796,7 +989,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingFixtureDeleteFixtureResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << FixtureGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_FIXTURE_DELETE_FIXTURE_RESPONSE Result: {} FixtureGuid: {}", Result, FixtureGuid.ToString());
@@ -810,7 +1003,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingRoomSetLayoutEditModeResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket.WriteBit(Active);
_worldPacket.FlushBits();
@@ -821,7 +1014,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingRoomAddResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << RoomGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_ROOM_ADD_RESPONSE Result: {} RoomGuid: {}", Result, RoomGuid.ToString());
@@ -831,7 +1024,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingRoomRemoveResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << RoomGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_ROOM_REMOVE_RESPONSE Result: {} RoomGuid: {}", Result, RoomGuid.ToString());
@@ -841,7 +1034,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingRoomUpdateResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << RoomGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_ROOM_UPDATE_RESPONSE Result: {} RoomGuid: {}", Result, RoomGuid.ToString());
@@ -851,7 +1044,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingRoomSetComponentThemeResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << RoomGuid;
_worldPacket << int32(ComponentID);
_worldPacket << int32(ThemeSetID);
@@ -864,7 +1057,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingRoomApplyComponentMaterialsResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << RoomGuid;
_worldPacket << int32(ComponentID);
_worldPacket << int32(RoomComponentTextureRecordID);
@@ -877,7 +1070,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingRoomSetDoorTypeResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << RoomGuid;
_worldPacket << int32(ComponentID);
_worldPacket << uint8(DoorType);
@@ -890,7 +1083,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingRoomSetCeilingTypeResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << RoomGuid;
_worldPacket << int32(ComponentID);
_worldPacket << uint8(CeilingType);
@@ -907,9 +1100,10 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsNotifyPermissionsFailure::Write()
{
_worldPacket << uint16(Result);
_worldPacket << uint8(FailureType);
_worldPacket << uint8(ErrorCode);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SVCS_NOTIFY_PERMISSIONS_FAILURE Result: {}", Result);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SVCS_NOTIFY_PERMISSIONS_FAILURE FailureType: {} ErrorCode: {}", FailureType, ErrorCode);
return &_worldPacket;
}
@@ -925,7 +1119,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsCreateCharterNeighborhoodResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << NeighborhoodGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SVCS_CREATE_CHARTER_NEIGHBORHOOD_RESPONSE Result: {} NeighborhoodGuid: {}",
@@ -946,7 +1140,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsClearPlotReservationResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << NeighborhoodGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SVCS_CLEAR_PLOT_RESERVATION_RESPONSE Result: {} NeighborhoodGuid: {}",
@@ -957,7 +1151,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsRelinquishHouseResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << HouseGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SVCS_RELINQUISH_HOUSE_RESPONSE Result: {} HouseGuid: {}", Result, HouseGuid.ToString());
@@ -967,7 +1161,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsCancelRelinquishHouseResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << HouseGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SVCS_CANCEL_RELINQUISH_HOUSE_RESPONSE Result: {} HouseGuid: {}", Result, HouseGuid.ToString());
@@ -1005,7 +1199,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsPlayerViewHousesResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << uint32(Neighborhoods.size());
for (auto const& neighborhood : Neighborhoods)
{
@@ -1033,6 +1227,42 @@ namespace WorldPackets::Housing
return &_worldPacket;
}
WorldPacket const* AccountHousingRoomAdded::Write()
{
_worldPacket << RoomGuid;
return &_worldPacket;
}
WorldPacket const* AccountHousingFixtureAdded::Write()
{
_worldPacket << FixtureGuid;
_worldPacket.WriteBits(Name.size(), 7);
_worldPacket.WriteBit(false); // HasTextureComposition
_worldPacket.FlushBits();
_worldPacket.WriteString(Name);
return &_worldPacket;
}
WorldPacket const* AccountHousingThemeAdded::Write()
{
_worldPacket << ThemeGuid;
_worldPacket.WriteBits(Name.size(), 7);
_worldPacket.WriteBit(false); // HasTextureComposition
_worldPacket.FlushBits();
_worldPacket.WriteString(Name);
return &_worldPacket;
}
WorldPacket const* AccountHousingRoomComponentTextureAdded::Write()
{
_worldPacket << TextureGuid;
_worldPacket.WriteBits(Name.size(), 7);
_worldPacket.WriteBit(false); // HasTextureComposition
_worldPacket.FlushBits();
_worldPacket.WriteString(Name);
return &_worldPacket;
}
WorldPacket const* HousingSvcsUpdateHousesLevelFavor::Write()
{
_worldPacket << uint8(Type);
@@ -1093,7 +1323,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsGuildGetHousingInfoResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << NeighborhoodGuid;
_worldPacket << HouseGuid;
@@ -1105,7 +1335,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsAcceptNeighborhoodOwnershipResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << NeighborhoodGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SVCS_ACCEPT_NEIGHBORHOOD_OWNERSHIP_RESPONSE Result: {} NeighborhoodGuid: {}",
@@ -1116,7 +1346,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsRejectNeighborhoodOwnershipResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << NeighborhoodGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SVCS_REJECT_NEIGHBORHOOD_OWNERSHIP_RESPONSE Result: {} NeighborhoodGuid: {}",
@@ -1138,7 +1368,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsGetPotentialHouseOwnersResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << uint32(PotentialOwners.size());
for (auto const& owner : PotentialOwners)
{
@@ -1156,7 +1386,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsUpdateHouseSettingsResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << HouseGuid;
_worldPacket << uint32(AccessFlags);
@@ -1168,7 +1398,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsGetHouseFinderInfoResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << uint32(Entries.size());
for (auto const& entry : Entries)
{
@@ -1190,7 +1420,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsGetHouseFinderNeighborhoodResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << NeighborhoodGuid;
_worldPacket << uint32(Plots.size());
for (auto const& plot : Plots)
@@ -1215,7 +1445,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsGetBnetFriendNeighborhoodsResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << uint32(Neighborhoods.size());
for (auto const& neighborhood : Neighborhoods)
{
@@ -1248,7 +1478,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingSvcsDeleteAllNeighborhoodInvitesResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << NeighborhoodGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SVCS_DELETE_ALL_NEIGHBORHOOD_INVITES_RESPONSE Result: {} NeighborhoodGuid: {}",
@@ -1297,7 +1527,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingExportHouseResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << HouseGuid;
_worldPacket << SizedString::BitsSize<11>(ExportData);
_worldPacket.FlushBits();
@@ -1309,6 +1539,15 @@ namespace WorldPackets::Housing
return &_worldPacket;
}
WorldPacket const* HousingSystemHouseSnapshotResponse::Write()
{
_worldPacket << uint8(Result);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_SYSTEM_HOUSE_SNAPSHOT_RESPONSE Result: {}", Result);
return &_worldPacket;
}
WorldPacket const* HousingGetPlayerPermissionsResponse::Write()
{
_worldPacket << HouseGuid;
@@ -1484,7 +1723,7 @@ namespace WorldPackets::Housing
WorldPacket const* GetPlayerInitiativeInfoResult::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << uint32(Tasks.size());
for (auto const& task : Tasks)
{
@@ -1502,7 +1741,7 @@ namespace WorldPackets::Housing
WorldPacket const* GetInitiativeActivityLogResult::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << uint32(CompletedTasks.size());
for (auto const& entry : CompletedTasks)
{
@@ -1555,7 +1794,7 @@ namespace WorldPackets::Housing
WorldPacket const* GetInitiativeRewardsResult::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
TC_LOG_DEBUG("network.opcode", "SMSG_GET_INITIATIVE_REWARDS_RESULT Result: {}", Result);
@@ -1574,7 +1813,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingPhotoSharingAuthorizationResult::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_PHOTO_SHARING_AUTHORIZATION_RESULT Result: {}", Result);
@@ -1583,7 +1822,7 @@ namespace WorldPackets::Housing
WorldPacket const* HousingPhotoSharingAuthorizationClearedResult::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
TC_LOG_DEBUG("network.opcode", "SMSG_HOUSING_PHOTO_SHARING_AUTHORIZATION_CLEARED_RESULT Result: {}", Result);
@@ -1636,6 +1875,22 @@ namespace WorldPackets::Neighborhood
TC_LOG_DEBUG("network.opcode", "CMSG_NEIGHBORHOOD_CHARTER_SEND_SIGNATURE_REQUEST TargetPlayerGuid: {}", TargetPlayerGuid.ToString());
}
void NeighborhoodCharterSignResponsePacket::Read()
{
_worldPacket >> CharterGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_NEIGHBORHOOD_CHARTER_SIGN_RESPONSE CharterGuid: {}", CharterGuid.ToString());
}
void NeighborhoodCharterRemoveSignature::Read()
{
_worldPacket >> CharterGuid;
_worldPacket >> SignerGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_NEIGHBORHOOD_CHARTER_REMOVE_SIGNATURE CharterGuid: {} SignerGuid: {}",
CharterGuid.ToString(), SignerGuid.ToString());
}
// --- Neighborhood Management System ---
void NeighborhoodUpdateName::Read()
@@ -1739,13 +1994,36 @@ namespace WorldPackets::Neighborhood
TC_LOG_DEBUG("network.opcode", "CMSG_NEIGHBORHOOD_EVICT_PLOT PlotIndex: {} NeighborhoodGuid: {}", PlotIndex, NeighborhoodGuid.ToString());
}
void NeighborhoodCancelInvitationAlt::Read()
{
_worldPacket >> InviteeGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_NEIGHBORHOOD_CANCEL_INVITATION_ALT InviteeGuid: {}", InviteeGuid.ToString());
}
void NeighborhoodInviteNotificationAck::Read()
{
_worldPacket >> NeighborhoodGuid;
TC_LOG_DEBUG("network.opcode", "CMSG_NEIGHBORHOOD_INVITE_NOTIFICATION_ACK NeighborhoodGuid: {}", NeighborhoodGuid.ToString());
}
void NeighborhoodOfferOwnershipResponsePacket::Read()
{
_worldPacket >> NeighborhoodGuid;
_worldPacket >> Bits<1>(Accept);
TC_LOG_DEBUG("network.opcode", "CMSG_NEIGHBORHOOD_OFFER_OWNERSHIP_RESPONSE NeighborhoodGuid: {} Accept: {}",
NeighborhoodGuid.ToString(), Accept);
}
// ============================================================
// Neighborhood Charter SMSG Responses (0x5Bxxxx)
// ============================================================
WorldPacket const* NeighborhoodCharterUpdateResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << CharterGuid;
TC_LOG_DEBUG("network.opcode", "SMSG_NEIGHBORHOOD_CHARTER_UPDATE_RESPONSE Result: {} CharterGuid: {}", Result, CharterGuid.ToString());
@@ -1755,7 +2033,7 @@ namespace WorldPackets::Neighborhood
WorldPacket const* NeighborhoodCharterOpenUIResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << CharterGuid;
_worldPacket << uint32(NeighborhoodMapID);
_worldPacket << uint32(SignatureCount);
@@ -1782,7 +2060,7 @@ namespace WorldPackets::Neighborhood
WorldPacket const* NeighborhoodCharterAddSignatureResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << CharterGuid;
_worldPacket << SignerGuid;
@@ -1794,7 +2072,7 @@ namespace WorldPackets::Neighborhood
WorldPacket const* NeighborhoodCharterOpenConfirmationUIResponse::Write()
{
_worldPacket << uint32(Result);
_worldPacket << uint8(Result);
_worldPacket << CharterGuid;
_worldPacket << CharterOwnerGuid;
_worldPacket << SizedString::BitsSize<7>(NeighborhoodName);
@@ -2102,7 +2380,8 @@ namespace WorldPackets::Neighborhood
for (auto const& resident : Residents)
{
_worldPacket << resident.PlayerGuid;
_worldPacket << uint16(resident.StatusFlags);
_worldPacket << uint8(resident.UpdateType);
_worldPacket << uint8(resident.NewRole);
}
TC_LOG_DEBUG("network.opcode", "SMSG_NEIGHBORHOOD_ROSTER_RESIDENT_UPDATE ResidentCount: {}", Residents.size());
+352 -46
View File
@@ -267,6 +267,53 @@ namespace WorldPackets::Housing
ObjectGuid Owner;
};
class HousingDecorUpdateDyeSlot final : public ClientPacket
{
public:
explicit HousingDecorUpdateDyeSlot(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_DECOR_UPDATE_DYE_SLOT, std::move(packet)) {}
void Read() override;
ObjectGuid DecorGuid;
uint8 SlotIndex = 0;
uint32 DyeColorID = 0;
};
class HousingDecorStartPlacingFromSource final : public ClientPacket
{
public:
explicit HousingDecorStartPlacingFromSource(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_DECOR_START_PLACING_FROM_SOURCE, std::move(packet)) {}
void Read() override;
uint32 SourceType = 0;
uint32 SourceID = 0;
};
class HousingDecorCleanupModeToggle final : public ClientPacket
{
public:
explicit HousingDecorCleanupModeToggle(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_DECOR_CLEANUP_MODE_TOGGLE, std::move(packet)) {}
void Read() override;
bool Enabled = false;
};
class HousingDecorBatchOperation final : public ClientPacket
{
public:
explicit HousingDecorBatchOperation(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_DECOR_BATCH_OPERATION, std::move(packet)) {}
void Read() override;
uint8 OperationType = 0;
std::vector<ObjectGuid> DecorGuids;
};
class HousingDecorPlacementPreview final : public ClientPacket
{
public:
explicit HousingDecorPlacementPreview(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_DECOR_PLACEMENT_PREVIEW, std::move(packet)) {}
void Read() override;
ObjectGuid DecorGuid;
TaggedPosition<Position::XYZ> PreviewPosition;
TaggedPosition<Position::XYZ> PreviewRotation;
float Scale = 1.0f;
};
// ============================================================
// Fixture System (0x31xxxx)
// ============================================================
@@ -339,6 +386,23 @@ namespace WorldPackets::Housing
uint32 HouseExteriorWmoDataID = 0;
};
class HousingFixtureCreateBasicHouse final : public ClientPacket
{
public:
explicit HousingFixtureCreateBasicHouse(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_FIXTURE_CREATE_BASIC_HOUSE, std::move(packet)) {}
void Read() override;
ObjectGuid PlotGuid;
uint32 HouseStyleID = 0;
};
class HousingFixtureDeleteHouse final : public ClientPacket
{
public:
explicit HousingFixtureDeleteHouse(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_FIXTURE_DELETE_HOUSE, std::move(packet)) {}
void Read() override;
ObjectGuid HouseGuid;
};
// ============================================================
// Room System (0x32xxxx)
// ============================================================
@@ -615,6 +679,94 @@ namespace WorldPackets::Housing
void Read() override {}
};
class HousingSvcsRequestPermissionsCheck final : public ClientPacket
{
public:
explicit HousingSvcsRequestPermissionsCheck(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_REQUEST_PERMISSIONS_CHECK, std::move(packet)) {}
void Read() override {}
};
class HousingSvcsClearPlotReservation final : public ClientPacket
{
public:
explicit HousingSvcsClearPlotReservation(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_CLEAR_PLOT_RESERVATION, std::move(packet)) {}
void Read() override;
ObjectGuid NeighborhoodGuid;
};
class HousingSvcsGetPlayerHousesInfoAlt final : public ClientPacket
{
public:
explicit HousingSvcsGetPlayerHousesInfoAlt(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_GET_PLAYER_HOUSES_INFO_ALT, std::move(packet)) {}
void Read() override;
ObjectGuid PlayerGuid;
};
class HousingSvcsGetRosterData final : public ClientPacket
{
public:
explicit HousingSvcsGetRosterData(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_GET_ROSTER_DATA, std::move(packet)) {}
void Read() override;
ObjectGuid NeighborhoodGuid;
};
class HousingSvcsRosterUpdateSubscribe final : public ClientPacket
{
public:
explicit HousingSvcsRosterUpdateSubscribe(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_ROSTER_UPDATE_SUBSCRIBE, std::move(packet)) {}
void Read() override {}
};
class HousingSvcsChangeHouseCosmeticOwnerRequest final : public ClientPacket
{
public:
explicit HousingSvcsChangeHouseCosmeticOwnerRequest(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_CHANGE_HOUSE_COSMETIC_OWNER, std::move(packet)) {}
void Read() override;
ObjectGuid HouseGuid;
ObjectGuid NewOwnerGuid;
};
class HousingSvcsQueryHouseLevelFavor final : public ClientPacket
{
public:
explicit HousingSvcsQueryHouseLevelFavor(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_QUERY_HOUSE_LEVEL_FAVOR, std::move(packet)) {}
void Read() override;
ObjectGuid HouseGuid;
};
class HousingSvcsGuildAddHouse final : public ClientPacket
{
public:
explicit HousingSvcsGuildAddHouse(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_GUILD_ADD_HOUSE, std::move(packet)) {}
void Read() override;
ObjectGuid HouseGuid;
};
class HousingSvcsGuildAppendNeighborhood final : public ClientPacket
{
public:
explicit HousingSvcsGuildAppendNeighborhood(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_GUILD_APPEND_NEIGHBORHOOD, std::move(packet)) {}
void Read() override;
ObjectGuid NeighborhoodGuid;
};
class HousingSvcsGuildRenameNeighborhood final : public ClientPacket
{
public:
explicit HousingSvcsGuildRenameNeighborhood(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_GUILD_RENAME_NEIGHBORHOOD, std::move(packet)) {}
void Read() override;
ObjectGuid NeighborhoodGuid;
std::string NewName;
};
class HousingSvcsGuildGetHousingInfo final : public ClientPacket
{
public:
explicit HousingSvcsGuildGetHousingInfo(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SVCS_GUILD_GET_HOUSING_INFO, std::move(packet)) {}
void Read() override;
ObjectGuid GuildGuid;
};
// ============================================================
// Housing Misc (0x35xxxx)
// ============================================================
@@ -664,6 +816,49 @@ namespace WorldPackets::Housing
Optional<ObjectGuid> HouseGuid;
};
class HousingSystemHouseStatusQuery final : public ClientPacket
{
public:
explicit HousingSystemHouseStatusQuery(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SYSTEM_HOUSE_STATUS_QUERY, std::move(packet)) {}
void Read() override {}
};
class HousingSystemGetHouseInfoAlt final : public ClientPacket
{
public:
explicit HousingSystemGetHouseInfoAlt(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SYSTEM_GET_HOUSE_INFO_ALT, std::move(packet)) {}
void Read() override;
ObjectGuid HouseGuid;
};
class HousingSystemHouseSnapshot final : public ClientPacket
{
public:
explicit HousingSystemHouseSnapshot(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SYSTEM_HOUSE_SNAPSHOT, std::move(packet)) {}
void Read() override;
ObjectGuid HouseGuid;
uint8 SnapshotType = 0;
};
class HousingSystemExportHouse final : public ClientPacket
{
public:
explicit HousingSystemExportHouse(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SYSTEM_EXPORT_HOUSE, std::move(packet)) {}
void Read() override;
ObjectGuid HouseGuid;
};
class HousingSystemUpdateHouseInfo final : public ClientPacket
{
public:
explicit HousingSystemUpdateHouseInfo(WorldPacket&& packet) : ClientPacket(CMSG_HOUSING_SYSTEM_UPDATE_HOUSE_INFO, std::move(packet)) {}
void Read() override;
ObjectGuid HouseGuid;
uint32 InfoType = 0;
std::string HouseName;
std::string HouseDescription;
};
// ============================================================
// Photo Sharing Authorization (0x40019x)
// ============================================================
@@ -784,7 +979,7 @@ namespace WorldPackets::Housing
public:
HouseExteriorLockResponse() : ServerPacket(SMSG_HOUSE_EXTERIOR_LOCK_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid HouseGuid;
bool Locked = false;
};
@@ -794,7 +989,7 @@ namespace WorldPackets::Housing
public:
HouseExteriorSetHousePositionResponse() : ServerPacket(SMSG_HOUSE_EXTERIOR_SET_HOUSE_POSITION_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid HouseGuid;
};
@@ -874,7 +1069,7 @@ namespace WorldPackets::Housing
public:
HousingDecorDeleteFromStorageResponse() : ServerPacket(SMSG_HOUSING_DECOR_DELETE_FROM_STORAGE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid DecorGuid;
};
@@ -899,7 +1094,7 @@ namespace WorldPackets::Housing
public:
HousingDecorAddToHouseChestResponse() : ServerPacket(SMSG_HOUSING_DECOR_ADD_TO_HOUSE_CHEST_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid DecorGuid;
};
@@ -942,6 +1137,24 @@ namespace WorldPackets::Housing
uint8 Result = 0;
};
class HousingDecorBatchOperationResponse final : public ServerPacket
{
public:
HousingDecorBatchOperationResponse() : ServerPacket(SMSG_HOUSING_DECOR_BATCH_OPERATION_RESPONSE) {}
WorldPacket const* Write() override;
uint8 Result = 0;
uint32 ProcessedCount = 0;
};
class HousingDecorPlacementPreviewResponse final : public ServerPacket
{
public:
HousingDecorPlacementPreviewResponse() : ServerPacket(SMSG_HOUSING_DECOR_PLACEMENT_PREVIEW_RESPONSE) {}
WorldPacket const* Write() override;
uint8 Result = 0;
uint8 RestrictionFlags = 0;
};
class HousingFirstTimeDecorAcquisition final : public ServerPacket
{
public:
@@ -959,7 +1172,7 @@ namespace WorldPackets::Housing
public:
HousingFixtureSetEditModeResponse() : ServerPacket(SMSG_HOUSING_FIXTURE_SET_EDIT_MODE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
bool Active = false;
};
@@ -968,7 +1181,7 @@ namespace WorldPackets::Housing
public:
HousingFixtureCreateBasicHouseResponse() : ServerPacket(SMSG_HOUSING_FIXTURE_CREATE_BASIC_HOUSE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid HouseGuid;
};
@@ -977,7 +1190,7 @@ namespace WorldPackets::Housing
public:
HousingFixtureDeleteHouseResponse() : ServerPacket(SMSG_HOUSING_FIXTURE_DELETE_HOUSE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid HouseGuid;
};
@@ -986,7 +1199,7 @@ namespace WorldPackets::Housing
public:
HousingFixtureSetHouseSizeResponse() : ServerPacket(SMSG_HOUSING_FIXTURE_SET_HOUSE_SIZE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
uint8 Size = 0;
};
@@ -995,7 +1208,7 @@ namespace WorldPackets::Housing
public:
HousingFixtureSetHouseTypeResponse() : ServerPacket(SMSG_HOUSING_FIXTURE_SET_HOUSE_TYPE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
int32 HouseExteriorTypeID = 0;
};
@@ -1004,7 +1217,7 @@ namespace WorldPackets::Housing
public:
HousingFixtureSetCoreFixtureResponse() : ServerPacket(SMSG_HOUSING_FIXTURE_SET_CORE_FIXTURE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
int32 FixtureRecordID = 0;
};
@@ -1013,7 +1226,7 @@ namespace WorldPackets::Housing
public:
HousingFixtureCreateFixtureResponse() : ServerPacket(SMSG_HOUSING_FIXTURE_CREATE_FIXTURE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid FixtureGuid;
};
@@ -1022,7 +1235,7 @@ namespace WorldPackets::Housing
public:
HousingFixtureDeleteFixtureResponse() : ServerPacket(SMSG_HOUSING_FIXTURE_DELETE_FIXTURE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid FixtureGuid;
};
@@ -1035,7 +1248,7 @@ namespace WorldPackets::Housing
public:
HousingRoomSetLayoutEditModeResponse() : ServerPacket(SMSG_HOUSING_ROOM_SET_LAYOUT_EDIT_MODE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
bool Active = false;
};
@@ -1044,7 +1257,7 @@ namespace WorldPackets::Housing
public:
HousingRoomAddResponse() : ServerPacket(SMSG_HOUSING_ROOM_ADD_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid RoomGuid;
};
@@ -1053,7 +1266,7 @@ namespace WorldPackets::Housing
public:
HousingRoomRemoveResponse() : ServerPacket(SMSG_HOUSING_ROOM_REMOVE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid RoomGuid;
};
@@ -1062,7 +1275,7 @@ namespace WorldPackets::Housing
public:
HousingRoomUpdateResponse() : ServerPacket(SMSG_HOUSING_ROOM_UPDATE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid RoomGuid;
};
@@ -1071,7 +1284,7 @@ namespace WorldPackets::Housing
public:
HousingRoomSetComponentThemeResponse() : ServerPacket(SMSG_HOUSING_ROOM_SET_COMPONENT_THEME_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid RoomGuid;
int32 ComponentID = 0;
int32 ThemeSetID = 0;
@@ -1082,7 +1295,7 @@ namespace WorldPackets::Housing
public:
HousingRoomApplyComponentMaterialsResponse() : ServerPacket(SMSG_HOUSING_ROOM_APPLY_COMPONENT_MATERIALS_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid RoomGuid;
int32 ComponentID = 0;
int32 RoomComponentTextureRecordID = 0;
@@ -1093,7 +1306,7 @@ namespace WorldPackets::Housing
public:
HousingRoomSetDoorTypeResponse() : ServerPacket(SMSG_HOUSING_ROOM_SET_DOOR_TYPE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid RoomGuid;
int32 ComponentID = 0;
uint8 DoorType = 0;
@@ -1104,7 +1317,7 @@ namespace WorldPackets::Housing
public:
HousingRoomSetCeilingTypeResponse() : ServerPacket(SMSG_HOUSING_ROOM_SET_CEILING_TYPE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid RoomGuid;
int32 ComponentID = 0;
uint8 CeilingType = 0;
@@ -1119,7 +1332,8 @@ namespace WorldPackets::Housing
public:
HousingSvcsNotifyPermissionsFailure() : ServerPacket(SMSG_HOUSING_SVCS_NOTIFY_PERMISSIONS_FAILURE) {}
WorldPacket const* Write() override;
uint16 Result = 0; // Sniff-confirmed: 2-byte wire format (e.g. 0x0039 = 57)
uint8 FailureType = 0; // IDA-verified: 2 separate uint8 reads, not 1 uint16
uint8 ErrorCode = 0;
};
class HousingSvcsGuildCreateNeighborhoodNotification final : public ServerPacket
@@ -1135,7 +1349,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsCreateCharterNeighborhoodResponse() : ServerPacket(SMSG_HOUSING_SVCS_CREATE_CHARTER_NEIGHBORHOOD_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid NeighborhoodGuid;
};
@@ -1153,7 +1367,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsClearPlotReservationResponse() : ServerPacket(SMSG_HOUSING_SVCS_CLEAR_PLOT_RESERVATION_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid NeighborhoodGuid;
};
@@ -1162,7 +1376,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsRelinquishHouseResponse() : ServerPacket(SMSG_HOUSING_SVCS_RELINQUISH_HOUSE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid HouseGuid;
};
@@ -1171,7 +1385,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsCancelRelinquishHouseResponse() : ServerPacket(SMSG_HOUSING_SVCS_CANCEL_RELINQUISH_HOUSE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid HouseGuid;
};
@@ -1191,7 +1405,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsPlayerViewHousesResponse() : ServerPacket(SMSG_HOUSING_SVCS_PLAYER_VIEW_HOUSES_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
struct NeighborhoodInfoData
{
@@ -1211,6 +1425,46 @@ namespace WorldPackets::Housing
ObjectGuid NewOwnerGuid;
};
// Account-level housing collection notifications
class AccountHousingRoomAdded final : public ServerPacket
{
public:
AccountHousingRoomAdded() : ServerPacket(SMSG_ACCOUNT_HOUSING_ROOM_ADDED) {}
WorldPacket const* Write() override;
ObjectGuid RoomGuid;
};
class AccountHousingFixtureAdded final : public ServerPacket
{
public:
AccountHousingFixtureAdded() : ServerPacket(SMSG_ACCOUNT_HOUSING_FIXTURE_ADDED) {}
WorldPacket const* Write() override;
ObjectGuid FixtureGuid;
std::string Name;
};
class AccountHousingThemeAdded final : public ServerPacket
{
public:
AccountHousingThemeAdded() : ServerPacket(SMSG_ACCOUNT_HOUSING_THEME_ADDED) {}
WorldPacket const* Write() override;
ObjectGuid ThemeGuid;
std::string Name;
};
class AccountHousingRoomComponentTextureAdded final : public ServerPacket
{
public:
AccountHousingRoomComponentTextureAdded() : ServerPacket(SMSG_ACCOUNT_HOUSING_ROOM_COMPONENT_TEXTURE_ADDED) {}
WorldPacket const* Write() override;
ObjectGuid TextureGuid;
std::string Name;
};
class HousingSvcsUpdateHousesLevelFavor final : public ServerPacket
{
public:
@@ -1267,7 +1521,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsGuildGetHousingInfoResponse() : ServerPacket(SMSG_HOUSING_SVCS_GUILD_GET_HOUSING_INFO_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid NeighborhoodGuid;
ObjectGuid HouseGuid;
};
@@ -1277,7 +1531,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsAcceptNeighborhoodOwnershipResponse() : ServerPacket(SMSG_HOUSING_SVCS_ACCEPT_NEIGHBORHOOD_OWNERSHIP_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid NeighborhoodGuid;
};
@@ -1286,7 +1540,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsRejectNeighborhoodOwnershipResponse() : ServerPacket(SMSG_HOUSING_SVCS_REJECT_NEIGHBORHOOD_OWNERSHIP_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid NeighborhoodGuid;
};
@@ -1304,7 +1558,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsGetPotentialHouseOwnersResponse() : ServerPacket(SMSG_HOUSING_SVCS_GET_POTENTIAL_HOUSE_OWNERS_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
struct PotentialOwnerData
{
@@ -1319,7 +1573,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsUpdateHouseSettingsResponse() : ServerPacket(SMSG_HOUSING_SVCS_UPDATE_HOUSE_SETTINGS_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid HouseGuid;
uint32 AccessFlags = 0;
};
@@ -1329,7 +1583,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsGetHouseFinderInfoResponse() : ServerPacket(SMSG_HOUSING_SVCS_GET_HOUSE_FINDER_INFO_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
struct HouseFinderEntry
{
@@ -1348,7 +1602,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsGetHouseFinderNeighborhoodResponse() : ServerPacket(SMSG_HOUSING_SVCS_GET_HOUSE_FINDER_NEIGHBORHOOD_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
struct PlotEntry
{
@@ -1367,7 +1621,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsGetBnetFriendNeighborhoodsResponse() : ServerPacket(SMSG_HOUSING_SVCS_GET_BNET_FRIEND_NEIGHBORHOODS_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
struct BnetFriendNeighborhoodData
{
@@ -1397,7 +1651,7 @@ namespace WorldPackets::Housing
public:
HousingSvcsDeleteAllNeighborhoodInvitesResponse() : ServerPacket(SMSG_HOUSING_SVCS_DELETE_ALL_NEIGHBORHOOD_INVITES_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid NeighborhoodGuid;
};
@@ -1436,11 +1690,19 @@ namespace WorldPackets::Housing
public:
HousingExportHouseResponse() : ServerPacket(SMSG_HOUSING_EXPORT_HOUSE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid HouseGuid;
std::string ExportData;
};
class HousingSystemHouseSnapshotResponse final : public ServerPacket
{
public:
HousingSystemHouseSnapshotResponse() : ServerPacket(SMSG_HOUSING_SYSTEM_HOUSE_SNAPSHOT_RESPONSE) {}
WorldPacket const* Write() override;
uint8 Result = 0;
};
class HousingGetPlayerPermissionsResponse final : public ServerPacket
{
public:
@@ -1621,7 +1883,7 @@ namespace WorldPackets::Housing
public:
GetPlayerInitiativeInfoResult() : ServerPacket(SMSG_GET_PLAYER_INITIATIVE_INFO_RESULT) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
std::vector<JamPlayerInitiativeTaskInfo> Tasks;
};
@@ -1630,7 +1892,7 @@ namespace WorldPackets::Housing
public:
GetInitiativeActivityLogResult() : ServerPacket(SMSG_GET_INITIATIVE_ACTIVITY_LOG_RESULT) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
std::vector<NICompletedTasksEntry> CompletedTasks;
};
@@ -1665,7 +1927,7 @@ namespace WorldPackets::Housing
public:
GetInitiativeRewardsResult() : ServerPacket(SMSG_GET_INITIATIVE_REWARDS_RESULT) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
};
class InitiativeRewardAvailable final : public ServerPacket
@@ -1686,7 +1948,7 @@ namespace WorldPackets::Housing
public:
HousingPhotoSharingAuthorizationResult() : ServerPacket(SMSG_HOUSING_PHOTO_SHARING_AUTHORIZATION_RESULT) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
};
class HousingPhotoSharingAuthorizationClearedResult final : public ServerPacket
@@ -1694,7 +1956,7 @@ namespace WorldPackets::Housing
public:
HousingPhotoSharingAuthorizationClearedResult() : ServerPacket(SMSG_HOUSING_PHOTO_SHARING_AUTHORIZATION_CLEARED_RESULT) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
};
}
@@ -1764,6 +2026,23 @@ namespace WorldPackets::Neighborhood
ObjectGuid TargetPlayerGuid;
};
class NeighborhoodCharterSignResponsePacket final : public ClientPacket
{
public:
explicit NeighborhoodCharterSignResponsePacket(WorldPacket&& packet) : ClientPacket(CMSG_NEIGHBORHOOD_CHARTER_SIGN_RESPONSE, std::move(packet)) {}
void Read() override;
ObjectGuid CharterGuid;
};
class NeighborhoodCharterRemoveSignature final : public ClientPacket
{
public:
explicit NeighborhoodCharterRemoveSignature(WorldPacket&& packet) : ClientPacket(CMSG_NEIGHBORHOOD_CHARTER_REMOVE_SIGNATURE, std::move(packet)) {}
void Read() override;
ObjectGuid CharterGuid;
ObjectGuid SignerGuid;
};
// ============================================================
// Neighborhood Management System (0x38xxxx)
// ============================================================
@@ -1921,6 +2200,31 @@ namespace WorldPackets::Neighborhood
uint32 PlotIndex = 0;
};
class NeighborhoodCancelInvitationAlt final : public ClientPacket
{
public:
explicit NeighborhoodCancelInvitationAlt(WorldPacket&& packet) : ClientPacket(CMSG_NEIGHBORHOOD_CANCEL_INVITATION_ALT, std::move(packet)) {}
void Read() override;
ObjectGuid InviteeGuid;
};
class NeighborhoodInviteNotificationAck final : public ClientPacket
{
public:
explicit NeighborhoodInviteNotificationAck(WorldPacket&& packet) : ClientPacket(CMSG_NEIGHBORHOOD_INVITE_NOTIFICATION_ACK, std::move(packet)) {}
void Read() override;
ObjectGuid NeighborhoodGuid;
};
class NeighborhoodOfferOwnershipResponsePacket final : public ClientPacket
{
public:
explicit NeighborhoodOfferOwnershipResponsePacket(WorldPacket&& packet) : ClientPacket(CMSG_NEIGHBORHOOD_OFFER_OWNERSHIP_RESPONSE, std::move(packet)) {}
void Read() override;
ObjectGuid NeighborhoodGuid;
bool Accept = false;
};
// ============================================================
// Neighborhood Charter SMSG Responses (0x5Bxxxx)
// ============================================================
@@ -1930,7 +2234,7 @@ namespace WorldPackets::Neighborhood
public:
NeighborhoodCharterUpdateResponse() : ServerPacket(SMSG_NEIGHBORHOOD_CHARTER_UPDATE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid CharterGuid;
};
@@ -1939,7 +2243,7 @@ namespace WorldPackets::Neighborhood
public:
NeighborhoodCharterOpenUIResponse() : ServerPacket(SMSG_NEIGHBORHOOD_CHARTER_OPEN_UI_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid CharterGuid;
std::string NeighborhoodName;
uint32 NeighborhoodMapID = 0;
@@ -1960,7 +2264,7 @@ namespace WorldPackets::Neighborhood
public:
NeighborhoodCharterAddSignatureResponse() : ServerPacket(SMSG_NEIGHBORHOOD_CHARTER_ADD_SIGNATURE_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid CharterGuid;
ObjectGuid SignerGuid;
};
@@ -1970,7 +2274,7 @@ namespace WorldPackets::Neighborhood
public:
NeighborhoodCharterOpenConfirmationUIResponse() : ServerPacket(SMSG_NEIGHBORHOOD_CHARTER_OPEN_CONFIRMATION_UI_RESPONSE) {}
WorldPacket const* Write() override;
uint32 Result = 0;
uint8 Result = 0;
ObjectGuid CharterGuid;
ObjectGuid CharterOwnerGuid;
std::string NeighborhoodName;
@@ -2175,6 +2479,7 @@ namespace WorldPackets::Neighborhood
ObjectGuid BnetAccountGuid; // Usually empty
uint8 PlotIndex = 0xFF; // INVALID_PLOT_INDEX
uint32 JoinTime = 0;
uint8 ResidentType = 0; // NeighborhoodMemberRole (0=Resident, 1=Manager, 2=Owner)
bool IsOnline = false; // Controls status byte 2 bit 7 in roster UI
};
std::vector<RosterMemberData> Members;
@@ -2192,7 +2497,8 @@ namespace WorldPackets::Neighborhood
struct ResidentEntry
{
ObjectGuid PlayerGuid;
uint16 StatusFlags = 0;
uint8 UpdateType = 0; // 0=Added, 1=RoleChanged, 2=Removed
uint8 NewRole = 0; // NeighborhoodMemberRole
};
NeighborhoodRosterResidentUpdate() : ServerPacket(SMSG_NEIGHBORHOOD_ROSTER_RESIDENT_UPDATE) {}
@@ -490,10 +490,16 @@ void OpcodeTable::InitializeClientOpcodes()
DEFINE_HANDLER(CMSG_GET_ALL_LICENSED_DECOR_QUANTITIES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetAllLicensedDecorQuantities);
DEFINE_HANDLER(CMSG_GET_AVAILABLE_INITIATIVE_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetAvailableInitiativeRequest);
DEFINE_HANDLER(CMSG_GET_CHARACTER_CURRENCY_TRANSFER_LOG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetCharacterCurrencyTransferLog);
DEFINE_HANDLER(CMSG_GET_INITIATIVE_CLAIM_REWARD_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GET_INITIATIVE_LEADERBOARD_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GET_CLIENT_CHECKOUT_LICENSES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GET_DECOR_REFUND_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetDecorRefundList);
DEFINE_HANDLER(CMSG_GET_GARRISON_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetGarrisonInfo);
DEFINE_HANDLER(CMSG_GET_INITIATIVE_ACTIVITY_LOG_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetInitiativeActivityLogRequest);
DEFINE_HANDLER(CMSG_GET_INITIATIVE_OPEN_CHEST_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GET_INITIATIVE_TASK_ABANDON_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GET_INITIATIVE_TASK_ACCEPT_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GET_INITIATIVE_TASK_PROGRESS_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GET_ITEM_PURCHASE_DATA, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGetItemPurchaseData);
DEFINE_HANDLER(CMSG_GET_LANDING_PAGE_SHIPMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetLandingPageShipments);
DEFINE_HANDLER(CMSG_GET_LAST_CATALOG_FETCH, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
@@ -576,12 +582,19 @@ void OpcodeTable::InitializeClientOpcodes()
DEFINE_HANDLER(CMSG_HOUSING_DECOR_SET_DYE_SLOTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingDecorSetDyeSlots);
DEFINE_HANDLER(CMSG_HOUSING_DECOR_SET_EDIT_MODE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingDecorSetEditMode);
DEFINE_HANDLER(CMSG_HOUSING_DECOR_START_PLACING_NEW_DECOR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingDecorStartPlacingNewDecor);
DEFINE_HANDLER(CMSG_HOUSING_DECOR_UPDATE_DYE_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingDecorUpdateDyeSlot);
DEFINE_HANDLER(CMSG_HOUSING_DECOR_START_PLACING_FROM_SOURCE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingDecorStartPlacingFromSource);
DEFINE_HANDLER(CMSG_HOUSING_DECOR_CLEANUP_MODE_TOGGLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingDecorCleanupModeToggle);
DEFINE_HANDLER(CMSG_HOUSING_DECOR_BATCH_OPERATION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingDecorBatchOperation);
DEFINE_HANDLER(CMSG_HOUSING_DECOR_PLACEMENT_PREVIEW, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingDecorPlacementPreview);
DEFINE_HANDLER(CMSG_HOUSING_FIXTURE_CREATE_FIXTURE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingFixtureCreateFixture);
DEFINE_HANDLER(CMSG_HOUSING_FIXTURE_DELETE_FIXTURE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingFixtureDeleteFixture);
DEFINE_HANDLER(CMSG_HOUSING_FIXTURE_SET_CORE_FIXTURE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingFixtureSetCoreFixture);
DEFINE_HANDLER(CMSG_HOUSING_FIXTURE_SET_EDIT_MODE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingFixtureSetEditMode);
DEFINE_HANDLER(CMSG_HOUSING_FIXTURE_SET_HOUSE_SIZE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingFixtureSetHouseSize);
DEFINE_HANDLER(CMSG_HOUSING_FIXTURE_SET_HOUSE_TYPE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingFixtureSetHouseType);
DEFINE_HANDLER(CMSG_HOUSING_FIXTURE_CREATE_BASIC_HOUSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingFixtureCreateBasicHouse);
DEFINE_HANDLER(CMSG_HOUSING_FIXTURE_DELETE_HOUSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingFixtureDeleteHouse);
DEFINE_HANDLER(CMSG_HOUSING_GET_CURRENT_HOUSE_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingGetCurrentHouseInfo);
DEFINE_HANDLER(CMSG_HOUSING_GET_PLAYER_PERMISSIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingGetPlayerPermissions);
DEFINE_HANDLER(CMSG_HOUSING_HOUSE_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingHouseStatus);
@@ -589,6 +602,11 @@ void OpcodeTable::InitializeClientOpcodes()
DEFINE_HANDLER(CMSG_HOUSING_PHOTO_SHARING_COMPLETE_AUTHORIZATION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingPhotoSharingCompleteAuthorization);
DEFINE_HANDLER(CMSG_HOUSING_REQUEST_EDITOR_AVAILABILITY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingRequestEditorAvailability);
DEFINE_HANDLER(CMSG_HOUSING_RESET_KIOSK_MODE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingResetKioskMode);
DEFINE_HANDLER(CMSG_HOUSING_SYSTEM_HOUSE_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSystemHouseStatusQuery);
DEFINE_HANDLER(CMSG_HOUSING_SYSTEM_GET_HOUSE_INFO_ALT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSystemGetHouseInfoAlt);
DEFINE_HANDLER(CMSG_HOUSING_SYSTEM_HOUSE_SNAPSHOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSystemHouseSnapshot);
DEFINE_HANDLER(CMSG_HOUSING_SYSTEM_EXPORT_HOUSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSystemExportHouse);
DEFINE_HANDLER(CMSG_HOUSING_SYSTEM_UPDATE_HOUSE_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSystemUpdateHouseInfo);
DEFINE_HANDLER(CMSG_HOUSING_ROOM_ADD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingRoomAdd);
DEFINE_HANDLER(CMSG_HOUSING_ROOM_APPLY_COMPONENT_MATERIALS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingRoomApplyComponentMaterials);
DEFINE_HANDLER(CMSG_HOUSING_ROOM_MOVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingRoomMoveRoom);
@@ -613,10 +631,29 @@ void OpcodeTable::InitializeClientOpcodes()
DEFINE_HANDLER(CMSG_HOUSING_SVCS_RELINQUISH_HOUSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsRelinquishHouse);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_START_TUTORIAL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsStartTutorial);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_TELEPORT_TO_PLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsTeleportToPlot);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_REQUEST_PERMISSIONS_CHECK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsRequestPermissionsCheck);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_CLEAR_PLOT_RESERVATION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsClearPlotReservation);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_GET_PLAYER_HOUSES_INFO_ALT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsGetPlayerHousesInfoAlt);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_GET_ROSTER_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsGetRosterData);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_ROSTER_UPDATE_SUBSCRIBE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsRosterUpdateSubscribe);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_CHANGE_HOUSE_COSMETIC_OWNER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsChangeHouseCosmeticOwner);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_QUERY_HOUSE_LEVEL_FAVOR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsQueryHouseLevelFavor);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_GUILD_ADD_HOUSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsGuildAddHouse);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_GUILD_APPEND_NEIGHBORHOOD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsGuildAppendNeighborhood);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_GUILD_RENAME_NEIGHBORHOOD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsGuildRenameNeighborhood);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_GUILD_GET_HOUSING_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsGuildGetHousingInfo);
DEFINE_HANDLER(CMSG_HOUSING_SVCS_UPDATE_HOUSE_SETTINGS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHousingSvcsUpdateHouseSettings);
DEFINE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode);
DEFINE_HANDLER(CMSG_INITIATE_ROLE_POLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateRolePoll);
DEFINE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode);
DEFINE_HANDLER(CMSG_INITIATIVE_ACCEPT_MILESTONE_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_INITIATIVE_REPORT_PROGRESS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_INITIATIVE_UNKNOWN_0B, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_INITIATIVE_UNKNOWN_0C, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_INITIATIVE_UNKNOWN_0D, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_INITIATIVE_UNKNOWN_0E, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_INITIATIVE_UNKNOWN_0F, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_INITIATIVE_UNKNOWN_10, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_INITIATIVE_UPDATE_ACTIVE_NEIGHBORHOOD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiativeUpdateActiveNeighborhood);
DEFINE_HANDLER(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleInspectOpcode);
DEFINE_HANDLER(CMSG_INSTANCE_ABANDON_VOTE_RESPONSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
@@ -799,6 +836,8 @@ void OpcodeTable::InitializeClientOpcodes()
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_CHARTER_FINALIZE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodCharterFinalize);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_CHARTER_OPEN_CONFIRMATION_UI, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodCharterOpenConfirmationUI);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_CHARTER_SEND_SIGNATURE_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodCharterSendSignatureRequest);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_CHARTER_SIGN_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodCharterSignResponse);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_CHARTER_REMOVE_SIGNATURE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodCharterRemoveSignature);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_EVICT_PLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodEvictPlot);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_GET_INVITES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodGetInvites);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_GET_ROSTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodGetRoster);
@@ -811,6 +850,9 @@ void OpcodeTable::InitializeClientOpcodes()
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_PLAYER_GET_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodPlayerGetInvite);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_REMOVE_SECONDARY_OWNER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodRemoveSecondaryOwner);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_SET_PUBLIC_FLAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodSetPublicFlag);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_CANCEL_INVITATION_ALT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodCancelInvitationAlt);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_INVITE_NOTIFICATION_ACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodInviteNotificationAck);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_OFFER_OWNERSHIP_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodOfferOwnershipResponse);
DEFINE_HANDLER(CMSG_NEIGHBORHOOD_UPDATE_NAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNeighborhoodUpdateName);
DEFINE_HANDLER(CMSG_NEUTRAL_PLAYER_SELECT_FACTION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera);
@@ -1166,6 +1208,10 @@ void OpcodeTable::InitializeServerOpcodes()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_EXTERIOR_FIXTURE_COLLECTION_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HEIRLOOM_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HOUSE_TYPE_COLLECTION_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HOUSING_FIXTURE_ADDED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HOUSING_ROOM_ADDED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HOUSING_ROOM_COMPONENT_TEXTURE_ADDED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HOUSING_THEME_ADDED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_ITEM_COLLECTION_DATA, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1724,11 +1770,13 @@ void OpcodeTable::InitializeServerOpcodes()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSE_INTERIOR_ENTER_HOUSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSE_INTERIOR_LEAVE_HOUSE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_ADD_TO_HOUSE_CHEST_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_BATCH_OPERATION_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_CATALOG_CREATE_SEARCHER_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_DELETE_FROM_STORAGE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_LOCK_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_MOVE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_PLACE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_PLACEMENT_PREVIEW_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_REMOVE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_REQUEST_STORAGE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_DECOR_SET_EDIT_MODE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1760,6 +1808,7 @@ void OpcodeTable::InitializeServerOpcodes()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_ROOM_SET_DOOR_TYPE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_ROOM_SET_LAYOUT_EDIT_MODE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_ROOM_UPDATE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_SYSTEM_HOUSE_SNAPSHOT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_SVCS_ACCEPT_NEIGHBORHOOD_OWNERSHIP_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_SVCS_CANCEL_RELINQUISH_HOUSE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOUSING_SVCS_CHANGE_HOUSE_COSMETIC_OWNER, STATUS_NEVER, CONNECTION_TYPE_REALM);
+51 -2
View File
@@ -381,11 +381,17 @@ enum OpcodeClient : uint32
CMSG_GET_ACCOUNT_NOTIFICATIONS = 0x400162,
CMSG_GET_ALL_LICENSED_DECOR_QUANTITIES = 0x290034,
CMSG_GET_AVAILABLE_INITIATIVE_REQUEST = 0x380002,
CMSG_GET_INITIATIVE_CLAIM_REWARD_REQUEST = 0x380005,
CMSG_GET_INITIATIVE_LEADERBOARD_REQUEST = 0x380006,
CMSG_GET_CHARACTER_CURRENCY_TRANSFER_LOG = 0x29001F,
CMSG_GET_CLIENT_CHECKOUT_LICENSES = 0x400140,
CMSG_GET_DECOR_REFUND_LIST = 0x290031,
CMSG_GET_GARRISON_INFO = 0x3A01A8,
CMSG_GET_INITIATIVE_ACTIVITY_LOG_REQUEST = 0x380004,
CMSG_GET_INITIATIVE_OPEN_CHEST_REQUEST = 0x380007,
CMSG_GET_INITIATIVE_TASK_ACCEPT_REQUEST = 0x380008,
CMSG_GET_INITIATIVE_TASK_ABANDON_REQUEST = 0x380009,
CMSG_GET_INITIATIVE_TASK_PROGRESS_REQUEST = 0x38000A,
CMSG_GET_ITEM_PURCHASE_DATA = 0x3B00CE,
CMSG_GET_LANDING_PAGE_SHIPMENTS = 0x3A01E4,
CMSG_GET_LAST_CATALOG_FETCH = 0x290036,
@@ -467,17 +473,29 @@ enum OpcodeClient : uint32
CMSG_HOUSING_DECOR_REQUEST_STORAGE = 0x30000E,
CMSG_HOUSING_DECOR_SET_DYE_SLOTS = 0x300006,
CMSG_HOUSING_DECOR_SET_EDIT_MODE = 0x300000,
CMSG_HOUSING_DECOR_START_PLACING_NEW_DECOR = 0x300005,
CMSG_HOUSING_DECOR_START_PLACING_NEW_DECOR = 0x300005,
CMSG_HOUSING_DECOR_UPDATE_DYE_SLOT = 0x300008,
CMSG_HOUSING_DECOR_START_PLACING_FROM_SOURCE = 0x30000B,
CMSG_HOUSING_DECOR_CLEANUP_MODE_TOGGLE = 0x30000C,
CMSG_HOUSING_DECOR_BATCH_OPERATION = 0x30000D,
CMSG_HOUSING_DECOR_PLACEMENT_PREVIEW = 0x30000F,
CMSG_HOUSING_FIXTURE_CREATE_FIXTURE = 0x310006,
CMSG_HOUSING_FIXTURE_DELETE_FIXTURE = 0x310007,
CMSG_HOUSING_FIXTURE_SET_CORE_FIXTURE = 0x310005,
CMSG_HOUSING_FIXTURE_SET_EDIT_MODE = 0x310000,
CMSG_HOUSING_FIXTURE_SET_HOUSE_SIZE = 0x310003,
CMSG_HOUSING_FIXTURE_SET_HOUSE_TYPE = 0x310004,
CMSG_HOUSING_FIXTURE_CREATE_BASIC_HOUSE = 0x310001,
CMSG_HOUSING_FIXTURE_DELETE_HOUSE = 0x310002,
CMSG_HOUSING_GET_CURRENT_HOUSE_INFO = 0x350006,
CMSG_HOUSING_GET_PLAYER_PERMISSIONS = 0x350007,
CMSG_HOUSING_REQUEST_EDITOR_AVAILABILITY = 0x350009,
CMSG_HOUSING_HOUSE_STATUS = 0x350005,
CMSG_HOUSING_REQUEST_EDITOR_AVAILABILITY = 0x350009,
CMSG_HOUSING_SYSTEM_HOUSE_STATUS_QUERY = 0x350000,
CMSG_HOUSING_SYSTEM_GET_HOUSE_INFO_ALT = 0x350001,
CMSG_HOUSING_SYSTEM_HOUSE_SNAPSHOT = 0x350002,
CMSG_HOUSING_SYSTEM_EXPORT_HOUSE = 0x350003,
CMSG_HOUSING_SYSTEM_UPDATE_HOUSE_INFO = 0x350004,
CMSG_HOUSING_PHOTO_SHARING_CLEAR_AUTHORIZATION = 0x4001A0,
CMSG_HOUSING_PHOTO_SHARING_COMPLETE_AUTHORIZATION = 0x40019F,
CMSG_HOUSING_RESET_KIOSK_MODE = 0x350008,
@@ -505,10 +523,29 @@ enum OpcodeClient : uint32
CMSG_HOUSING_SVCS_RELINQUISH_HOUSE = 0x330009,
CMSG_HOUSING_SVCS_START_TUTORIAL = 0x330018,
CMSG_HOUSING_SVCS_TELEPORT_TO_PLOT = 0x330017,
CMSG_HOUSING_SVCS_REQUEST_PERMISSIONS_CHECK = 0x330000,
CMSG_HOUSING_SVCS_CLEAR_PLOT_RESERVATION = 0x330005,
CMSG_HOUSING_SVCS_GET_PLAYER_HOUSES_INFO_ALT = 0x33000B,
CMSG_HOUSING_SVCS_GET_ROSTER_DATA = 0x33000C,
CMSG_HOUSING_SVCS_ROSTER_UPDATE_SUBSCRIBE = 0x33000D,
CMSG_HOUSING_SVCS_CHANGE_HOUSE_COSMETIC_OWNER = 0x330010,
CMSG_HOUSING_SVCS_QUERY_HOUSE_LEVEL_FAVOR = 0x330012,
CMSG_HOUSING_SVCS_GUILD_ADD_HOUSE = 0x330013,
CMSG_HOUSING_SVCS_GUILD_APPEND_NEIGHBORHOOD = 0x330014,
CMSG_HOUSING_SVCS_GUILD_RENAME_NEIGHBORHOOD = 0x330015,
CMSG_HOUSING_SVCS_GUILD_GET_HOUSING_INFO = 0x330016,
CMSG_HOUSING_SVCS_UPDATE_HOUSE_SETTINGS = 0x33000A,
CMSG_IGNORE_TRADE = 0x3A0003,
CMSG_INITIATE_ROLE_POLL = 0x400006,
CMSG_INITIATE_TRADE = 0x3A0000,
CMSG_INITIATIVE_ACCEPT_MILESTONE_REQUEST = 0x380001,
CMSG_INITIATIVE_REPORT_PROGRESS = 0x380003,
CMSG_INITIATIVE_UNKNOWN_0B = 0x38000B,
CMSG_INITIATIVE_UNKNOWN_0C = 0x38000C,
CMSG_INITIATIVE_UNKNOWN_0D = 0x38000D,
CMSG_INITIATIVE_UNKNOWN_0E = 0x38000E,
CMSG_INITIATIVE_UNKNOWN_0F = 0x38000F,
CMSG_INITIATIVE_UNKNOWN_10 = 0x380010,
CMSG_INITIATIVE_UPDATE_ACTIVE_NEIGHBORHOOD = 0x3C0000,
CMSG_INSPECT = 0x3B00C8,
CMSG_INSTANCE_ABANDON_VOTE_RESPONSE = 0x400061,
@@ -691,6 +728,8 @@ enum OpcodeClient : uint32
CMSG_NEIGHBORHOOD_CHARTER_FINALIZE = 0x370004,
CMSG_NEIGHBORHOOD_CHARTER_OPEN_CONFIRMATION_UI = 0x370000,
CMSG_NEIGHBORHOOD_CHARTER_SEND_SIGNATURE_REQUEST = 0x370007,
CMSG_NEIGHBORHOOD_CHARTER_SIGN_RESPONSE = 0x370002,
CMSG_NEIGHBORHOOD_CHARTER_REMOVE_SIGNATURE = 0x370005,
CMSG_NEIGHBORHOOD_EVICT_PLOT = 0x39000F,
CMSG_NEIGHBORHOOD_GET_INVITES = 0x390008,
CMSG_NEIGHBORHOOD_GET_ROSTER = 0x39000E,
@@ -703,6 +742,9 @@ enum OpcodeClient : uint32
CMSG_NEIGHBORHOOD_PLAYER_GET_INVITE = 0x390007,
CMSG_NEIGHBORHOOD_REMOVE_SECONDARY_OWNER = 0x390003,
CMSG_NEIGHBORHOOD_SET_PUBLIC_FLAG = 0x390001,
CMSG_NEIGHBORHOOD_CANCEL_INVITATION_ALT = 0x39000C,
CMSG_NEIGHBORHOOD_INVITE_NOTIFICATION_ACK = 0x390010,
CMSG_NEIGHBORHOOD_OFFER_OWNERSHIP_RESPONSE = 0x390011,
CMSG_NEIGHBORHOOD_UPDATE_NAME = 0x390000,
CMSG_NEUTRAL_PLAYER_SELECT_FACTION = 0x3A008A,
CMSG_NEXT_CINEMATIC_CAMERA = 0x3B00E3,
@@ -1089,6 +1131,10 @@ enum OpcodeServer : uint32
SMSG_ACCOUNT_EXTERIOR_FIXTURE_COLLECTION_UPDATE = 0x420054,
SMSG_ACCOUNT_HEIRLOOM_UPDATE = 0x420049,
SMSG_ACCOUNT_HOUSE_TYPE_COLLECTION_UPDATE = 0x420057,
SMSG_ACCOUNT_HOUSING_FIXTURE_ADDED = 0x400050,
SMSG_ACCOUNT_HOUSING_ROOM_ADDED = 0x40004F,
SMSG_ACCOUNT_HOUSING_ROOM_COMPONENT_TEXTURE_ADDED = 0x400052,
SMSG_ACCOUNT_HOUSING_THEME_ADDED = 0x400051,
SMSG_ACCOUNT_ITEM_COLLECTION_DATA = 0x42035B,
SMSG_ACCOUNT_MOUNT_REMOVED = 0x420047,
SMSG_ACCOUNT_MOUNT_UPDATE = 0x420046,
@@ -1647,11 +1693,13 @@ enum OpcodeServer : uint32
SMSG_HOUSE_INTERIOR_ENTER_HOUSE = 0x2F0000,
SMSG_HOUSE_INTERIOR_LEAVE_HOUSE_RESPONSE = 0x2F0001,
SMSG_HOUSING_DECOR_ADD_TO_HOUSE_CHEST_RESPONSE = 0x510007,
SMSG_HOUSING_DECOR_BATCH_OPERATION_RESPONSE = 0x51000D,
SMSG_HOUSING_DECOR_CATALOG_CREATE_SEARCHER_RESPONSE = 0x51000C,
SMSG_HOUSING_DECOR_DELETE_FROM_STORAGE_RESPONSE = 0x510005,
SMSG_HOUSING_DECOR_LOCK_RESPONSE = 0x510004,
SMSG_HOUSING_DECOR_MOVE_RESPONSE = 0x510001,
SMSG_HOUSING_DECOR_PLACE_RESPONSE = 0x510002,
SMSG_HOUSING_DECOR_PLACEMENT_PREVIEW_RESPONSE = 0x51000F,
SMSG_HOUSING_DECOR_REMOVE_RESPONSE = 0x510003,
SMSG_HOUSING_DECOR_REQUEST_STORAGE_RESPONSE = 0x510006,
SMSG_HOUSING_DECOR_SET_EDIT_MODE_RESPONSE = 0x510000,
@@ -1684,6 +1732,7 @@ enum OpcodeServer : uint32
SMSG_HOUSING_ROOM_SET_DOOR_TYPE_RESPONSE = 0x530006,
SMSG_HOUSING_ROOM_SET_LAYOUT_EDIT_MODE_RESPONSE = 0x530000,
SMSG_HOUSING_ROOM_UPDATE_RESPONSE = 0x530003,
SMSG_HOUSING_SYSTEM_HOUSE_SNAPSHOT_RESPONSE = 0x550002,
SMSG_HOUSING_SVCS_ACCEPT_NEIGHBORHOOD_OWNERSHIP_RESPONSE = 0x540017,
SMSG_HOUSING_SVCS_CANCEL_RELINQUISH_HOUSE_RESPONSE = 0x540008,
SMSG_HOUSING_SVCS_CHANGE_HOUSE_COSMETIC_OWNER = 0x540010,
+70
View File
@@ -538,6 +538,29 @@ namespace WorldPackets
class GetAllLicensedDecorQuantities;
class GetDecorRefundList;
class HousingRequestEditorAvailability;
class HousingDecorUpdateDyeSlot;
class HousingDecorStartPlacingFromSource;
class HousingDecorCleanupModeToggle;
class HousingDecorBatchOperation;
class HousingDecorPlacementPreview;
class HousingFixtureCreateBasicHouse;
class HousingFixtureDeleteHouse;
class HousingSvcsRequestPermissionsCheck;
class HousingSvcsClearPlotReservation;
class HousingSvcsGetPlayerHousesInfoAlt;
class HousingSvcsGetRosterData;
class HousingSvcsRosterUpdateSubscribe;
class HousingSvcsChangeHouseCosmeticOwnerRequest;
class HousingSvcsQueryHouseLevelFavor;
class HousingSvcsGuildAddHouse;
class HousingSvcsGuildAppendNeighborhood;
class HousingSvcsGuildRenameNeighborhood;
class HousingSvcsGuildGetHousingInfo;
class HousingSystemHouseStatusQuery;
class HousingSystemGetHouseInfoAlt;
class HousingSystemHouseSnapshot;
class HousingSystemExportHouse;
class HousingSystemUpdateHouseInfo;
}
namespace Neighborhood
@@ -567,6 +590,11 @@ namespace WorldPackets
class GetAvailableInitiativeRequest;
class GetInitiativeActivityLogRequest;
class InitiativeUpdateActiveNeighborhood;
class NeighborhoodCharterSignResponsePacket;
class NeighborhoodCharterRemoveSignature;
class NeighborhoodCancelInvitationAlt;
class NeighborhoodInviteNotificationAck;
class NeighborhoodOfferOwnershipResponsePacket;
}
namespace Inspect
@@ -1695,6 +1723,38 @@ class TC_GAME_API WorldSession
void HandleHousingGetCurrentHouseInfo(WorldPackets::Housing::HousingGetCurrentHouseInfo const& housingGetCurrentHouseInfo);
void HandleHousingGetPlayerPermissions(WorldPackets::Housing::HousingGetPlayerPermissions const& housingGetPlayerPermissions);
void HandleHousingResetKioskMode(WorldPackets::Housing::HousingResetKioskMode const& housingResetKioskMode);
// Phase 7 Housing Decor handlers
void HandleHousingDecorUpdateDyeSlot(WorldPackets::Housing::HousingDecorUpdateDyeSlot const& housingDecorUpdateDyeSlot);
void HandleHousingDecorStartPlacingFromSource(WorldPackets::Housing::HousingDecorStartPlacingFromSource const& housingDecorStartPlacingFromSource);
void HandleHousingDecorCleanupModeToggle(WorldPackets::Housing::HousingDecorCleanupModeToggle const& housingDecorCleanupModeToggle);
void HandleHousingDecorBatchOperation(WorldPackets::Housing::HousingDecorBatchOperation const& housingDecorBatchOperation);
void HandleHousingDecorPlacementPreview(WorldPackets::Housing::HousingDecorPlacementPreview const& housingDecorPlacementPreview);
// Phase 7 Housing Fixture handlers
void HandleHousingFixtureCreateBasicHouse(WorldPackets::Housing::HousingFixtureCreateBasicHouse const& housingFixtureCreateBasicHouse);
void HandleHousingFixtureDeleteHouse(WorldPackets::Housing::HousingFixtureDeleteHouse const& housingFixtureDeleteHouse);
// Phase 7 Housing Services handlers
void HandleHousingSvcsRequestPermissionsCheck(WorldPackets::Housing::HousingSvcsRequestPermissionsCheck const& housingSvcsRequestPermissionsCheck);
void HandleHousingSvcsClearPlotReservation(WorldPackets::Housing::HousingSvcsClearPlotReservation const& housingSvcsClearPlotReservation);
void HandleHousingSvcsGetPlayerHousesInfoAlt(WorldPackets::Housing::HousingSvcsGetPlayerHousesInfoAlt const& housingSvcsGetPlayerHousesInfoAlt);
void HandleHousingSvcsGetRosterData(WorldPackets::Housing::HousingSvcsGetRosterData const& housingSvcsGetRosterData);
void HandleHousingSvcsRosterUpdateSubscribe(WorldPackets::Housing::HousingSvcsRosterUpdateSubscribe const& housingSvcsRosterUpdateSubscribe);
void HandleHousingSvcsChangeHouseCosmeticOwner(WorldPackets::Housing::HousingSvcsChangeHouseCosmeticOwnerRequest const& housingSvcsChangeHouseCosmeticOwner);
void HandleHousingSvcsQueryHouseLevelFavor(WorldPackets::Housing::HousingSvcsQueryHouseLevelFavor const& housingSvcsQueryHouseLevelFavor);
void HandleHousingSvcsGuildAddHouse(WorldPackets::Housing::HousingSvcsGuildAddHouse const& housingSvcsGuildAddHouse);
void HandleHousingSvcsGuildAppendNeighborhood(WorldPackets::Housing::HousingSvcsGuildAppendNeighborhood const& housingSvcsGuildAppendNeighborhood);
void HandleHousingSvcsGuildRenameNeighborhood(WorldPackets::Housing::HousingSvcsGuildRenameNeighborhood const& housingSvcsGuildRenameNeighborhood);
void HandleHousingSvcsGuildGetHousingInfo(WorldPackets::Housing::HousingSvcsGuildGetHousingInfo const& housingSvcsGuildGetHousingInfo);
// Phase 7 Housing System handlers
void HandleHousingSystemHouseStatusQuery(WorldPackets::Housing::HousingSystemHouseStatusQuery const& housingSystemHouseStatusQuery);
void HandleHousingSystemGetHouseInfoAlt(WorldPackets::Housing::HousingSystemGetHouseInfoAlt const& housingSystemGetHouseInfoAlt);
void HandleHousingSystemHouseSnapshot(WorldPackets::Housing::HousingSystemHouseSnapshot const& housingSystemHouseSnapshot);
void HandleHousingSystemExportHouse(WorldPackets::Housing::HousingSystemExportHouse const& housingSystemExportHouse);
void HandleHousingSystemUpdateHouseInfo(WorldPackets::Housing::HousingSystemUpdateHouseInfo const& housingSystemUpdateHouseInfo);
void HandleDeclineNeighborhoodInvites(WorldPackets::Housing::DeclineNeighborhoodInvites const& declineNeighborhoodInvites);
void HandleQueryNeighborhoodInfo(WorldPackets::Housing::QueryNeighborhoodInfo const& queryNeighborhoodInfo);
void HandleInvitePlayerToNeighborhood(WorldPackets::Housing::InvitePlayerToNeighborhood const& invitePlayerToNeighborhood);
@@ -1724,6 +1784,16 @@ class TC_GAME_API WorldSession
void HandleNeighborhoodOfferOwnership(WorldPackets::Neighborhood::NeighborhoodOfferOwnership const& neighborhoodOfferOwnership);
void HandleNeighborhoodGetRoster(WorldPackets::Neighborhood::NeighborhoodGetRoster const& neighborhoodGetRoster);
void HandleNeighborhoodEvictPlot(WorldPackets::Neighborhood::NeighborhoodEvictPlot const& neighborhoodEvictPlot);
// Phase 7 Neighborhood Charter handlers
void HandleNeighborhoodCharterSignResponse(WorldPackets::Neighborhood::NeighborhoodCharterSignResponsePacket const& neighborhoodCharterSignResponse);
void HandleNeighborhoodCharterRemoveSignature(WorldPackets::Neighborhood::NeighborhoodCharterRemoveSignature const& neighborhoodCharterRemoveSignature);
// Phase 7 Neighborhood handlers
void HandleNeighborhoodCancelInvitationAlt(WorldPackets::Neighborhood::NeighborhoodCancelInvitationAlt const& neighborhoodCancelInvitationAlt);
void HandleNeighborhoodInviteNotificationAck(WorldPackets::Neighborhood::NeighborhoodInviteNotificationAck const& neighborhoodInviteNotificationAck);
void HandleNeighborhoodOfferOwnershipResponse(WorldPackets::Neighborhood::NeighborhoodOfferOwnershipResponsePacket const& neighborhoodOfferOwnershipResponse);
void HandleNeighborhoodInitiativeServiceStatusCheck(WorldPackets::Neighborhood::NeighborhoodInitiativeServiceStatusCheck const& packet);
void HandleGetAvailableInitiativeRequest(WorldPackets::Neighborhood::GetAvailableInitiativeRequest const& getAvailableInitiativeRequest);
void HandleGetInitiativeActivityLogRequest(WorldPackets::Neighborhood::GetInitiativeActivityLogRequest const& getInitiativeActivityLogRequest);
+9
View File
@@ -94,6 +94,7 @@
#include "BattlePetPackets.h"
#include "DB2Structure.h"
#include "GarrisonMgr.h"
#include "InitiativeManager.h"
//WowCommunity
NonDefaultConstructible<SpellEffectHandlerFn> SpellEffectHandlers[TOTAL_SPELL_EFFECTS] =
@@ -1507,6 +1508,10 @@ void Spell::EffectCreateItem2()
}
/// @todo ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
// Housing initiative: crafting task (TaskType=2)
if (m_spellInfo->HasAttribute(SPELL_ATTR0_IS_TRADESKILL))
sInitiativeManager.OnPlayerAction(player, 2, 1);
}
void Spell::EffectCreateRandomItem()
@@ -1739,6 +1744,10 @@ void Spell::EffectOpenLock()
}
}
ExecuteLogEffectOpenLock(SpellEffectName(effectInfo->Effect), gameObjTarget ? (Object*)gameObjTarget : (Object*)itemTarget);
// Housing initiative: gathering task (TaskType=1)
if (Player* player = m_caster->ToPlayer())
sInitiativeManager.OnPlayerAction(player, 1, 1);
}
void Spell::EffectSummonChangeItem()