Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
VoidStorageHandler.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Common.h"
7#include "Log.h"
8#include "ObjectAccessor.h"
9#include "ObjectMgr.h"
10#include "Opcodes.h"
11#include "Player.h"
12#include "World.h"
13#include "WorldPacket.h"
14#include "WorldSession.h"
15#include <list>
16#include <utility>
17#include <vector>
18
25
27{
28 SF_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_UNLOCK");
29 Player* player = GetPlayer();
30
31 ObjectGuid npcGuid;
32
33 recvData.ReadGuidMask(npcGuid, 3, 1, 5, 6, 4, 0, 7, 2);
34 recvData.ReadGuidBytes(npcGuid, 4, 3, 6, 2, 1, 5, 7, 0);
35
37 if (!unit)
38 {
39 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageUnlock - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid));
40 return;
41 }
42
43 if (player->IsVoidStorageUnlocked())
44 {
45 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageUnlock - Player (GUID: %u, name: %s) tried to unlock void storage a 2nd time.", player->GetGUIDLow(), player->GetName().c_str());
46 return;
47 }
48
50 player->UnlockVoidStorage();
51}
52
54{
55 SF_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_QUERY");
56 Player* player = GetPlayer();
57
58 ObjectGuid npcGuid;
59 recvData.ReadGuidMask(npcGuid, 1, 5, 6, 0, 7, 2, 3, 4);
60 recvData.ReadGuidBytes(npcGuid, 1, 6, 4, 3, 7, 0, 2, 5);
61
63 if (!unit)
64 {
65 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid));
66 return;
67 }
68
69 if (!player->IsVoidStorageUnlocked())
70 {
71 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName().c_str());
72 return;
73 }
74
75 uint8 count = 0;
76 for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i)
77 if (player->GetVoidStorageItem(i))
78 ++count;
79
80 WorldPacket data(SMSG_VOID_STORAGE_CONTENTS, 2 * count + (14 + 4 + 4 + 4 + 4) * count);
81
82 data.WriteBits(count, 7);
83
84 ByteBuffer itemData((14 + 4 + 4 + 4 + 4) * count);
85
86 for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i)
87 {
88 VoidStorageItem* item = player->GetVoidStorageItem(i);
89 if (!item)
90 continue;
91
92 ObjectGuid itemId = item->ItemId;
93 ObjectGuid creatorGuid = item->CreatorGuid;
94
95 data.WriteGuidMask(creatorGuid, 1, 3);
96 data.WriteGuidMask(itemId, 1);
97 data.WriteGuidMask(creatorGuid, 2);
98 data.WriteGuidMask(itemId, 2);
99 data.WriteGuidMask(creatorGuid, 2, 0);
100 data.WriteGuidMask(itemId, 6, 5);
101 data.WriteGuidMask(creatorGuid, 2);
102 data.WriteGuidMask(itemId, 7, 3, 4, 0);
103 data.WriteGuidMask(creatorGuid, 6, 7);
104
105 itemData.WriteGuidBytes(creatorGuid, 4, 7);
106 itemData.WriteGuidBytes(itemId, 6);
107 itemData.WriteGuidBytes(creatorGuid, 6);
108 itemData.WriteGuidBytes(itemId, 2);
109
110 itemData << uint32(item->ItemSuffixFactor); //= 32
111
112 itemData.WriteGuidBytes(itemId, 7, 3);
113 itemData.WriteGuidBytes(creatorGuid, 0);
114
115 itemData << uint32(0); //= 16 - UpgradeID
116
117 itemData.WriteGuidBytes(itemId, 0);
118
119 itemData << uint32(item->ItemRandomPropertyId); //= 24
120
121 itemData.WriteGuidBytes(creatorGuid, 2, 5, 3);
122
123 itemData << uint32(item->ItemEntry); //= 28
124
125 itemData.WriteGuidBytes(itemId, 5, 1);
126
127 itemData << uint32(i); //= 20
128
129 itemData.WriteGuidBytes(itemId, 4);
130 itemData.WriteGuidBytes(creatorGuid, 1);
131 }
132
133 data.FlushBits();
134 data.append(itemData);
135
136 SendPacket(&data);
137}
138
140{
141 SF_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_TRANSFER");
142 Player* player = GetPlayer();
143
144 ObjectGuid npcGuid;
145 recvData.ReadGuidMask(npcGuid, 7, 4);
146
147 uint32 countDeposit = recvData.ReadBits(24); //40
148
149 if (countDeposit > 9)
150 {
151 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to deposit more than 9 items (%u).", player->GetGUIDLow(), player->GetName().c_str(), countDeposit);
152 recvData.rfinish();
153 return;
154 }
155
156 std::vector<ObjectGuid> itemGuids(countDeposit);
157 for (uint32 i = 0; i < countDeposit; ++i)
158 {
159 recvData.ReadGuidMask(itemGuids[i], 0, 3, 6, 5, 4, 2, 1, 7);
160 }
161
162 uint32 countWithdraw = recvData.ReadBits(24);
163
164 if (countWithdraw > 9)
165 {
166 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to withdraw more than 9 items (%u).", player->GetGUIDLow(), player->GetName().c_str(), countWithdraw);
167 recvData.rfinish();
168 return;
169 }
170
171 std::vector<ObjectGuid> itemIds(countWithdraw);
172 for (uint32 i = 0; i < countWithdraw; ++i)
173 {
174 recvData.ReadGuidMask(itemIds[i], 4, 0, 5, 7, 6, 1, 2, 3);
175 }
176
177 recvData.ReadGuidMask(npcGuid, 6, 0, 3, 1, 2, 5);
178
179 for (uint32 i = 0; i < countDeposit; ++i)
180 {
181 recvData.ReadGuidBytes(itemGuids[i], 5, 6, 3, 4, 1, 7, 2, 0);
182 }
183
184 recvData.ReadGuidBytes(npcGuid, 5);
185
186 for (uint32 i = 0; i < countWithdraw; ++i)
187 {
188 recvData.ReadGuidBytes(itemIds[i], 0, 4, 1, 2, 6, 3, 7, 5);
189 }
190
191 recvData.ReadGuidBytes(npcGuid, 1, 7, 4, 3, 2, 0, 6);
192
194 if (!unit)
195 {
196 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid));
197 return;
198 }
199
200 if (!player->IsVoidStorageUnlocked())
201 {
202 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName().c_str());
203 return;
204 }
205
206 if (itemGuids.size() > player->GetNumOfVoidStorageFreeSlots())
207 {
209 return;
210 }
211
212 uint32 freeBagSlots = 0;
213 if (itemIds.size() != 0)
214 {
215 // make this a Player function
217 if (Bag* bag = player->GetBagByPos(i))
218 freeBagSlots += bag->GetFreeSlots();
220 if (!player->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
221 ++freeBagSlots;
222 }
223
224 if (itemIds.size() > freeBagSlots)
225 {
227 return;
228 }
229
230 if (!player->HasEnoughMoney(uint64(itemGuids.size() * VOID_STORAGE_STORE_ITEM)))
231 {
233 return;
234 }
235
236 std::pair<VoidStorageItem, uint8> depositItems[VOID_STORAGE_MAX_DEPOSIT];
237 uint8 depositCount = 0;
238 for (std::vector<ObjectGuid>::iterator itr = itemGuids.begin(); itr != itemGuids.end(); ++itr)
239 {
240 Item* item = player->GetItemByGuid(*itr);
241 if (!item)
242 {
243 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to deposit an invalid item (item guid: " UI64FMTD ").", player->GetGUIDLow(), player->GetName().c_str(), uint64(*itr));
244 continue;
245 }
246
247 VoidStorageItem itemVS(sObjectMgr->GenerateVoidStorageItemId(), item->GetEntry(), item->GetUInt64Value(ITEM_FIELD_CREATOR), item->GetItemRandomPropertyId(), item->GetItemSuffixFactor());
248
249 uint8 slot = player->AddVoidStorageItem(itemVS);
250
251 depositItems[depositCount++] = std::make_pair(itemVS, slot);
252
253 player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
254 }
255
256 int64 cost = depositCount * VOID_STORAGE_STORE_ITEM;
257
258 player->ModifyMoney(-cost);
259
261 uint8 withdrawCount = 0;
262 for (std::vector<ObjectGuid>::iterator itr = itemIds.begin(); itr != itemIds.end(); ++itr)
263 {
264 uint8 slot;
265 VoidStorageItem* itemVS = player->GetVoidStorageItem(*itr, slot);
266 if (!itemVS)
267 {
268 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) tried to withdraw an invalid item (id: " UI64FMTD ")", player->GetGUIDLow(), player->GetName().c_str(), uint64(*itr));
269 continue;
270 }
271
272 ItemPosCountVec dest;
273 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemVS->ItemEntry, 1);
274 if (msg != EQUIP_ERR_OK)
275 {
277 SF_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) couldn't withdraw item id " UI64FMTD " because inventory was full.", player->GetGUIDLow(), player->GetName().c_str(), uint64(*itr));
278 return;
279 }
280
281 Item* item = player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId);
283 item->SetBinding(true);
284 player->SendNewItem(item, 1, false, false, false);
285
286 withdrawItems[withdrawCount++] = *itemVS;
287
288 player->DeleteVoidStorageItem(slot);
289 }
290
291 WorldPacket data(SMSG_VOID_STORAGE_TRANSFER_CHANGES, ((5 + 5 + (7 + 7) * depositCount +
292 7 * withdrawCount) / 8) + 7 * withdrawCount + (7 + 7 + 4 * 4) * depositCount);
293
294 data.WriteBits(withdrawCount, 4);
295
296 for (uint8 i = 0; i < withdrawCount; ++i)
297 {
298 ObjectGuid itemId = withdrawItems[i].ItemId;
299 data.WriteGuidMask(itemId, 1, 6, 7, 3, 2, 0, 4, 5);
300 }
301
302 data.WriteBits(depositCount, 4);
303
304 for (uint8 i = 0; i < depositCount; ++i)
305 {
306 ObjectGuid itemId = depositItems[i].first.ItemId;
307 ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid;
308 data.WriteGuidMask(itemId, 0);
309 data.WriteGuidMask(creatorGuid, 6, 4);
310 data.WriteGuidMask(itemId, 3);
311 data.WriteGuidMask(creatorGuid, 3);
312 data.WriteGuidMask(itemId, 5, 7);
313 data.WriteGuidMask(creatorGuid, 0, 5, 7);
314 data.WriteGuidMask(itemId, 6, 4);
315 data.WriteGuidMask(creatorGuid, 1);
316 data.WriteGuidMask(itemId, 1);
317 data.WriteGuidMask(creatorGuid, 2);
318 }
319
320 data.FlushBits();
321
322 for (uint8 i = 0; i < depositCount; ++i)
323 {
324 ObjectGuid itemId = depositItems[i].first.ItemId;
325 ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid;
326 data << uint32(depositItems[i].second); // slot
327 data.WriteGuidBytes(creatorGuid, 5);
328 data << uint32(depositItems[i].first.ItemEntry);
329 data.WriteGuidBytes(creatorGuid, 6, 3);
330 data << uint32(depositItems[i].first.ItemSuffixFactor);
331 data.WriteGuidBytes(creatorGuid, 2);
332 data.WriteGuidBytes(itemId, 5);
333 data << uint32(depositItems[i].first.ItemRandomPropertyId);
334 data.WriteGuidBytes(itemId, 3);
335 data.WriteGuidBytes(creatorGuid, 7, 4, 1);
336 data.WriteGuidBytes(itemId, 0, 4, 6);
337 data << uint32(0); // Item Upgrade Level
338 data.WriteGuidBytes(itemId, 1, 2);
339 data.WriteGuidBytes(creatorGuid, 0);
340 data.WriteGuidBytes(itemId, 7);
341 }
342
343 for (uint8 i = 0; i < withdrawCount; ++i)
344 {
345 ObjectGuid itemId = withdrawItems[i].ItemId;
346
347 data.WriteGuidBytes(itemId, 7, 3, 1, 5, 4, 0, 6, 2);
348 }
349
350 SendPacket(&data);
351
353}
354
356{
357 SF_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_SWAP_ITEM");
358
359 Player* player = GetPlayer();
360 uint32 newSlot;
361 ObjectGuid npcGuid;
362 ObjectGuid itemId;
363
364 recvData >> newSlot;
365
366 recvData.ReadGuidMask(npcGuid, 6);
367 recvData.ReadGuidMask(itemId, 4, 7, 3, 2);
368 recvData.ReadGuidMask(npcGuid, 4, 2);
369 recvData.ReadGuidMask(itemId, 0, 1);
370 recvData.ReadGuidMask(npcGuid, 7, 1);
371 recvData.ReadGuidMask(itemId, 6);
372 recvData.ReadGuidMask(npcGuid, 3, 5);
373 recvData.ReadGuidMask(itemId, 5);
374 recvData.ReadGuidMask(npcGuid, 0);
375
376 recvData.ReadGuidBytes(npcGuid, 3, 5);
377 recvData.ReadGuidBytes(itemId, 6);
378 recvData.ReadGuidBytes(npcGuid, 4);
379 recvData.ReadGuidBytes(itemId, 4);
380 recvData.ReadGuidBytes(npcGuid, 0);
381 recvData.ReadGuidBytes(itemId, 5, 7);
382 recvData.ReadGuidBytes(npcGuid, 7, 2, 1);
383 recvData.ReadGuidBytes(itemId, 1, 3);
384 recvData.ReadGuidBytes(npcGuid, 6);
385 recvData.ReadGuidBytes(itemId, 0, 2);
386
388 if (!unit)
389 {
390 SF_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid));
391 return;
392 }
393
394 if (!player->IsVoidStorageUnlocked())
395 {
396 SF_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName().c_str());
397 return;
398 }
399
400 uint8 oldSlot;
401 if (!player->GetVoidStorageItem(itemId, oldSlot))
402 {
403 SF_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Player (GUID: %u, name: %s) requested swapping an invalid item (slot: %u, itemid: " UI64FMTD ").", player->GetGUIDLow(), player->GetName().c_str(), newSlot, uint64(itemId));
404 return;
405 }
406
407 bool usedSrcSlot = player->GetVoidStorageItem(oldSlot) != NULL; // should be always true
408 bool usedDestSlot = player->GetVoidStorageItem(newSlot) != NULL;
409
410 ObjectGuid itemIdDest;
411 if (usedDestSlot)
412 itemIdDest = player->GetVoidStorageItem(newSlot)->ItemId;
413
414 if (!player->SwapVoidStorageItem(oldSlot, newSlot))
415 {
417 return;
418 }
419
420 WorldPacket data(SMSG_VOID_ITEM_SWAP_RESPONSE, 1 + (usedSrcSlot + usedDestSlot) * (1 + 7 + 4));
421
422 data.WriteBit(!usedSrcSlot);
423
424 data.WriteGuidMask(itemId, 4, 1, 6, 0, 3, 7, 2, 5);
425
426 data.WriteBit(!usedDestSlot);
427
428 data.WriteGuidMask(itemIdDest, 6, 0, 3, 2, 1, 5, 7, 4);
429
430 data.WriteBit(!false); //VoidItemSlotA
431 data.WriteBit(!usedDestSlot);
432
433 data.FlushBits();
434
435 data.WriteGuidBytes(itemIdDest, 3, 7, 2, 5, 0, 1, 4, 6);
436 data.WriteGuidBytes(itemId, 0, 2, 7, 5, 6, 4, 3, 1);
437
438 //if (VoidItemSlotA)
439 // data << uint32(VoidItemSlotA);
440
441 if (usedDestSlot)
442 data << uint32(newSlot);
443
444 SendPacket(&data);
445}
#define UI64FMTD
Definition Define.h:64
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
std::int64_t int64
Definition Define.h:72
InventoryResult
Definition Item.h:27
@ EQUIP_ERR_OK
Definition Item.h:28
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
uint32 GUID_LOPART(uint64 x)
#define sObjectMgr
Definition ObjectMgr.h:1617
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:777
@ INVENTORY_SLOT_ITEM_START
Definition Player.h:719
@ INVENTORY_SLOT_ITEM_END
Definition Player.h:720
@ INVENTORY_SLOT_BAG_START
Definition Player.h:713
@ INVENTORY_SLOT_BAG_END
Definition Player.h:714
#define INVENTORY_SLOT_BAG_0
Definition Player.h:684
#define VOID_STORAGE_STORE_ITEM
#define VOID_STORAGE_MAX_DEPOSIT
#define VOID_STORAGE_MAX_SLOT
VoidTransferError
#define VOID_STORAGE_UNLOCK
#define VOID_STORAGE_MAX_WITHDRAW
@ UNIT_NPC_FLAG_VAULTKEEPER
Definition Unit.h:715
@ NULL_BAG
Definition Unit.h:336
@ NULL_SLOT
Definition Unit.h:337
@ ITEM_FIELD_CREATOR
Definition Bag.h:16
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
uint32 ReadBits(size_t bits)
Definition ByteBuffer.h:198
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:256
void append(T value)
Definition ByteBuffer.h:147
void rfinish()
Definition ByteBuffer.h:478
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:240
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void FlushBits()
Definition ByteBuffer.h:154
Definition Item.h:202
uint8 GetSlot() const
Definition Item.h:265
void SetBinding(bool val)
Definition Item.h:217
int32 GetItemRandomPropertyId() const
Definition Item.h:278
uint32 GetItemSuffixFactor() const
Definition Item.h:279
uint8 GetBagSlot() const
Definition Item.cpp:734
uint32 GetGUIDLow() const
Definition Object.h:120
uint32 GetEntry() const
Definition Object.h:125
uint64 GetUInt64Value(uint16 index) const
Definition Object.cpp:331
void SetUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1079
bool ModifyMoney(int64 amount, bool sendError=true)
Definition Player.cpp:18342
Bag * GetBagByPos(uint8 slot) const
Item * GetItemByGuid(uint64 guid) const
Item * GetItemByPos(uint16 pos) const
void DestroyItem(uint8 bag, uint8 slot, bool update)
void DeleteVoidStorageItem(uint8 slot)
Definition Player.cpp:22542
uint8 GetNumOfVoidStorageFreeSlots() const
Definition Player.cpp:22497
void UnlockVoidStorage()
Definition Player.h:3179
Creature * GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
Definition Player.cpp:2836
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=NULL) const
VoidStorageItem * GetVoidStorageItem(uint8 slot) const
Definition Player.cpp:22563
bool IsVoidStorageUnlocked() const
Definition Player.h:3175
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, AllowedLooterSet const &allowedLooters=AllowedLooterSet())
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false)
Definition Player.cpp:11604
bool SwapVoidStorageItem(uint8 oldSlot, uint8 newSlot)
Definition Player.cpp:22554
bool HasEnoughMoney(uint64 amount) const
Definition Player.h:1950
uint8 AddVoidStorageItem(const VoidStorageItem &item)
Definition Player.cpp:22508
std::string const & GetName() const
Definition Object.h:664
void HandleVoidSwapItem(WorldPacket &recvData)
Player * GetPlayer() const
void HandleVoidStorageQuery(WorldPacket &recvData)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void SendVoidStorageTransferResult(VoidTransferError result)
void HandleVoidStorageTransfer(WorldPacket &recvData)
void HandleVoidStorageUnlock(WorldPacket &recvData)
@ SMSG_VOID_TRANSFER_RESULT
Definition Opcodes.h:1063
@ SMSG_VOID_STORAGE_TRANSFER_CHANGES
Definition Opcodes.h:1062
@ SMSG_VOID_STORAGE_CONTENTS
Definition Opcodes.h:1061
@ SMSG_VOID_ITEM_SWAP_RESPONSE
Definition Opcodes.h:1060
uint32 ItemRandomPropertyId
Definition Player.h:1056
uint64 ItemId
Definition Player.h:1053
uint32 CreatorGuid
Definition Player.h:1055
uint32 ItemEntry
Definition Player.h:1054
uint32 ItemSuffixFactor
Definition Player.h:1057