diff --git a/Source/items/validation.cpp b/Source/items/validation.cpp index 1762922ca..a04a15b86 100644 --- a/Source/items/validation.cpp +++ b/Source/items/validation.cpp @@ -10,6 +10,7 @@ #include "items.h" #include "monstdat.h" +#include "msg.h" #include "player.h" #include "spells.h" #include "utils/is_of.hpp" @@ -175,4 +176,22 @@ bool IsItemValid(const Player &player, const Item &item) return IsDungeonItemValid(item._iCreateInfo, item.dwBuff); } +bool IsItemDeltaValid(const TCmdPItem &itemDelta) +{ + if (itemDelta.bCmd == CMD_INVALID) + return true; + if (IsNoneOf(itemDelta.bCmd, TCmdPItem::FloorItem, TCmdPItem::PickedUpItem, TCmdPItem::DroppedItem)) + return false; + if (!InDungeonBounds({ itemDelta.x, itemDelta.y })) + return false; + _item_indexes idx = static_cast<_item_indexes>(SDL_SwapLE16(itemDelta.def.wIndx)); + if (idx == IDI_EAR) + return true; + if (!IsItemAvailable(idx)) + return false; + Item item = {}; + RecreateItem(*MyPlayer, itemDelta.item, item); + return IsItemValid(*MyPlayer, item); +} + } // namespace devilution diff --git a/Source/items/validation.h b/Source/items/validation.h index 98bbabc6b..1ef732d7d 100644 --- a/Source/items/validation.h +++ b/Source/items/validation.h @@ -7,17 +7,19 @@ #include +namespace devilution { + // Forward declared structs to avoid circular dependencies struct Item; +struct TCmdPItem; struct Player; -namespace devilution { - bool IsCreationFlagComboValid(uint16_t iCreateInfo); bool IsTownItemValid(uint16_t iCreateInfo, const Player &player); bool IsShopPriceValid(const Item &item); bool IsUniqueMonsterItemValid(uint16_t iCreateInfo, uint32_t dwBuff); bool IsDungeonItemValid(uint16_t iCreateInfo, uint32_t dwBuff); bool IsItemValid(const Player &player, const Item &item); +bool IsItemDeltaValid(const TCmdPItem &itemDelta); } // namespace devilution diff --git a/Source/msg.cpp b/Source/msg.cpp index c6c1f573e..35bca69d9 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -499,6 +499,8 @@ size_t DeltaImportItem(const std::byte *src, TCmdPItem *dst) size++; } else { memcpy(dst, &src[size], sizeof(TCmdPItem)); + if (!IsItemDeltaValid(*dst)) + memset(dst, 0xFF, sizeof(TCmdPItem)); size += sizeof(TCmdPItem); } }