Skip to content

Commit 13008ab

Browse files
committed
refactor(item): centralize passive item-cache peek in Item::PeekRecord
Add item/Record.{h,cpp} with Item::PeekRecord(itemID) -- the passive ItemStats_C cache peek (null callback, no network query). Route the three duplicate implementations through it: - the per-module GetItemRecord_t typedef + fn(cache,id,&zero,nullptr, nullptr,0) call in ~25 read-only item accessors - Item::StatAccum::FetchRecord (deleted; 7 callers repointed) - item/Tooltip.cpp's local PeekItemRecord (deleted) Behavior-identical: every converted call was already a passive peek with identical args (dedup flag is a no-op when the callback is null). item/Data.cpp is deliberately untouched -- it owns the ACTIVE fetch (CacheFetch passes a real callback to fire SMSG_ITEM_QUERY_SINGLE, the load-bearing cache-race path in CLAUDE.md) and keeps its own typedef.
1 parent 0df8885 commit 13008ab

34 files changed

Lines changed: 136 additions & 360 deletions

src/auctionhouse/PostItem.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#include "item/CGItem.h"
5959
#include "item/ID.h"
6060
#include "item/Location.h"
61+
#include "item/Record.h"
6162
#include "item/Swap.h"
6263
#include "tick/WorldTick.h"
6364

@@ -98,16 +99,6 @@ Job g_job{};
9899

99100
// --- small CGItem / cache readers ---------------------------------------
100101

101-
using GetItemRecord_t = const uint8_t *(__thiscall *)(void *cache, uint32_t itemID,
102-
const uint64_t *guid, void *callback,
103-
void *userData, int unused);
104-
const uint8_t *PeekItemRecord(uint32_t itemID) {
105-
auto fn = reinterpret_cast<GetItemRecord_t>(Offsets::FUN_DBCACHE_ITEMSTATS_GET_RECORD);
106-
auto *cache = reinterpret_cast<void *>(Offsets::VAR_ITEMDB_CACHE);
107-
const uint64_t zeroGuid = 0;
108-
return fn(cache, itemID, &zeroGuid, nullptr, nullptr, 0);
109-
}
110-
111102
int CGItemCount(const uint8_t *item) {
112103
auto *desc = Item::ObjectFields(item);
113104
if (desc == nullptr)
@@ -187,7 +178,7 @@ bool BagIsGeneral(int bag) {
187178
const int id = Item::ID::FromCGItem(bagItem);
188179
if (id == 0)
189180
return false;
190-
const uint8_t *rec = PeekItemRecord(static_cast<uint32_t>(id));
181+
const uint8_t *rec = Item::PeekRecord(static_cast<uint32_t>(id));
191182
if (rec == nullptr)
192183
return false;
193184
return *reinterpret_cast<const uint32_t *>(

src/container/FreeSlots.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,14 @@
1616
#include "item/BagFamily.h"
1717
#include "item/ID.h"
1818
#include "item/Location.h"
19+
#include "item/Record.h"
1920

2021
#include <cstdint>
2122

2223
namespace Container::FreeSlots {
2324

2425
namespace {
2526

26-
using GetItemRecord_t = const uint8_t *(__thiscall *)(void *cache, uint32_t itemID,
27-
const uint64_t *guid, void *callback,
28-
void *userData, int unused);
29-
30-
// Same `Peek the item cache without firing a query` shape as
31-
// `Item::Info::FetchItemRecord`. We don't share that helper because it's
32-
// file-static there; copying the four-line lookup is simpler than
33-
// promoting it to a header for one extra caller.
34-
const uint8_t *PeekItemRecord(uint32_t itemID) {
35-
auto fn = reinterpret_cast<GetItemRecord_t>(Offsets::FUN_DBCACHE_ITEMSTATS_GET_RECORD);
36-
auto *cache = reinterpret_cast<void *>(Offsets::VAR_ITEMDB_CACHE);
37-
const uint64_t zeroGuid = 0;
38-
return fn(cache, itemID, &zeroGuid, nullptr, nullptr, 0);
39-
}
40-
4127
// Resolves the bag's metadata: total slot count + BagFamily bitfield.
4228
//
4329
// - bagID 0 (backpack) → (16, 0). Vanilla 1.12 backpack is fixed at 16
@@ -68,7 +54,7 @@ BagInfo ResolveBagInfo(int bagID) {
6854
if (itemID == 0)
6955
return {0, 0};
7056

71-
auto *record = PeekItemRecord(static_cast<uint32_t>(itemID));
57+
auto *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
7258
if (record == nullptr)
7359
return {0, 0};
7460

src/container/ItemInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "item/ID.h"
5555
#include "item/Link.h"
5656
#include "item/Location.h"
57+
#include "item/Record.h"
5758
#include "item/StatAccum.h"
5859

5960
#include <cstdint>
@@ -107,7 +108,7 @@ int __fastcall Script_C_Container_GetContainerItemInfo(void *L) {
107108
// them off the half-built table avoids any stack interleaving. ---
108109
const int itemID = Item::ID::FromCGItem(item);
109110
const uint8_t *record = (itemID > 0)
110-
? Item::StatAccum::FetchRecord(static_cast<uint32_t>(itemID))
111+
? Item::PeekRecord(static_cast<uint32_t>(itemID))
111112
: nullptr;
112113

113114
// Live per-instance descriptor fields.

src/cursor/Info.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "item/Link.h"
5454
#include "item/Location.h"
5555
#include "item/QualityColor.h"
56+
#include "item/Record.h"
5657
#include "spell/Lookup.h"
5758

5859
#include <cstdint>
@@ -140,25 +141,14 @@ int PushBagItemCursor(void *L) {
140141
return PushItem(L, cgItem);
141142
}
142143

143-
using GetItemRecord_t = const uint8_t *(__thiscall *)(void *cache, uint32_t itemID,
144-
const uint64_t *guid, void *callback,
145-
void *userData, int unused);
146-
147-
const uint8_t *PeekItemRecord(uint32_t itemID) {
148-
auto fn = reinterpret_cast<GetItemRecord_t>(Offsets::FUN_DBCACHE_ITEMSTATS_GET_RECORD);
149-
auto *cache = reinterpret_cast<void *>(Offsets::VAR_ITEMDB_CACHE);
150-
const uint64_t zeroGuid = 0;
151-
return fn(cache, itemID, &zeroGuid, nullptr, nullptr, 0);
152-
}
153-
154144
// Builds a basic `"|cffRRGGBB|Hitem:N:0:0:0|h[Name]|h|r"` link from
155145
// the cached ItemStats record for `itemID`. No enchant / random-
156146
// suffix decoration — the cursor only stores the bare itemID for
157147
// drag-source items (types 6/7/9) with no live `CGItem *` to read
158148
// instance state from. Returns true and writes into `out` (size
159149
// `outSize`) on success; returns false if the item isn't cached.
160150
bool BuildBasicItemLink(uint32_t itemID, char *out, size_t outSize) {
161-
const uint8_t *record = PeekItemRecord(itemID);
151+
const uint8_t *record = Item::PeekRecord(itemID);
162152
if (record == nullptr) return false;
163153
const char *name = *reinterpret_cast<const char *const *>(
164154
record + Offsets::OFF_ITEMSTATS_NAME);

src/equipmentset/Tooltip.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "equipmentset/Data.h"
5353
#include "equipmentset/Locations.h"
5454
#include "equipmentset/Set.h"
55+
#include "item/Record.h"
5556

5657
#include <cstdint>
5758

@@ -108,17 +109,6 @@ struct Tally {
108109
uint32_t missingItemIDs[SLOT_COUNT];
109110
};
110111

111-
using GetItemRecord_t = const uint8_t *(__thiscall *)(void *cache, uint32_t itemID,
112-
const uint64_t *guid, void *callback,
113-
void *userData, int unused);
114-
115-
const uint8_t *PeekItemRecord(uint32_t itemID) {
116-
auto fn = reinterpret_cast<GetItemRecord_t>(Offsets::FUN_DBCACHE_ITEMSTATS_GET_RECORD);
117-
auto *cache = reinterpret_cast<void *>(Offsets::VAR_ITEMDB_CACHE);
118-
const uint64_t zeroGuid = 0;
119-
return fn(cache, itemID, &zeroGuid, nullptr, nullptr, 0);
120-
}
121-
122112
// Walks a set's slots, classifying each non-empty entry into the
123113
// equipped / in-inventory / ignored / missing buckets via
124114
// `Locations::FindGUID`. For missing slots, also records the saved
@@ -215,7 +205,7 @@ int __fastcall Script_GameTooltipSetEquipmentSet(void *L) {
215205
unnamedMissing++;
216206
continue;
217207
}
218-
auto *record = PeekItemRecord(id);
208+
auto *record = Item::PeekRecord(id);
219209
if (record == nullptr) {
220210
unnamedMissing++;
221211
continue;

src/item/AverageLevel.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include "item/Data.h"
5656
#include "item/ID.h"
5757
#include "item/Location.h"
58+
#include "item/Record.h"
5859
#include "object/Resolve.h"
5960
#include "unit/Identity.h"
6061

@@ -66,10 +67,6 @@ namespace Item::AverageLevel {
6667

6768
namespace {
6869

69-
using GetItemRecord_t = const uint8_t *(__thiscall *)(void *cache, uint32_t itemID,
70-
const uint64_t *guid, void *callback,
71-
void *userData, int unused);
72-
7370
// 1-based slot range used by both walks.
7471
constexpr int kFirstSlot = 1;
7572
constexpr int kLastSlot = 19;
@@ -120,13 +117,6 @@ constexpr uint32_t kSlotMaskByInvType[29] = {
120117
constexpr int kInvTypeMax = static_cast<int>(sizeof(kSlotMaskByInvType) /
121118
sizeof(kSlotMaskByInvType[0])) - 1;
122119

123-
const uint8_t *PeekItemRecord(uint32_t itemID) {
124-
auto fn = reinterpret_cast<GetItemRecord_t>(Offsets::FUN_DBCACHE_ITEMSTATS_GET_RECORD);
125-
auto *cache = reinterpret_cast<void *>(Offsets::VAR_ITEMDB_CACHE);
126-
const uint64_t zeroGuid = 0;
127-
return fn(cache, itemID, &zeroGuid, nullptr, nullptr, 0);
128-
}
129-
130120
// Returns (itemLevel, inventoryType) for the CGItem, or (0, 0) if
131121
// the itemID is unresolvable or the cache record hasn't loaded.
132122
struct ItemInfo {
@@ -140,7 +130,7 @@ ItemInfo ReadItemInfo(const uint8_t *cgItem) {
140130
const int itemID = Item::ID::FromCGItem(cgItem);
141131
if (itemID <= 0)
142132
return {0, 0};
143-
const uint8_t *record = PeekItemRecord(static_cast<uint32_t>(itemID));
133+
const uint8_t *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
144134
if (record == nullptr) {
145135
// Equipped or bagged item with no cache record yet — queue a
146136
// warmup so the next call gets populated data. Cheap on cache

src/item/Consumable.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,14 @@
3434
#include "Game.h"
3535
#include "Offsets.h"
3636
#include "item/Arg.h"
37+
#include "item/Record.h"
3738

3839
#include <cstdint>
3940

4041
namespace Item::Consumable {
4142

4243
namespace {
4344

44-
using GetItemRecord_t = const uint8_t *(__thiscall *)(void *cache, uint32_t itemID,
45-
const uint64_t *guid, void *callback,
46-
void *userData, int unused);
47-
48-
const uint8_t *PeekItemRecord(uint32_t itemID) {
49-
auto fn = reinterpret_cast<GetItemRecord_t>(Offsets::FUN_DBCACHE_ITEMSTATS_GET_RECORD);
50-
auto *cache = reinterpret_cast<void *>(Offsets::VAR_ITEMDB_CACHE);
51-
const uint64_t zeroGuid = 0;
52-
return fn(cache, itemID, &zeroGuid, nullptr, nullptr, 0);
53-
}
54-
5545
constexpr uint32_t kItemClassConsumable = 0;
5646
constexpr uint32_t kInvTypeAmmo = 24; // INVTYPE_AMMO
5747
constexpr uint32_t kInvTypeThrown = 25; // INVTYPE_THROWN
@@ -62,7 +52,7 @@ int __fastcall Script_C_Item_IsConsumableItem(void *L) {
6252
Game::Lua::PushBoolean(L, 0);
6353
return 1;
6454
}
65-
const uint8_t *record = PeekItemRecord(static_cast<uint32_t>(itemID));
55+
const uint8_t *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
6656
if (record == nullptr) {
6757
Game::Lua::PushBoolean(L, 0);
6858
return 1;

src/item/Equipment.cpp

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "item/Cursor.h"
1818
#include "item/ID.h"
1919
#include "item/Location.h"
20+
#include "item/Record.h"
2021
#include "item/Swap.h"
2122

2223
#include <cstdint>
@@ -25,20 +26,6 @@ namespace Item::Equipment {
2526

2627
namespace {
2728

28-
using GetItemRecord_t = const uint8_t *(__thiscall *)(void *cache, uint32_t itemID,
29-
const uint64_t *guid, void *callback,
30-
void *userData, int unused);
31-
32-
// Same item-cache peek pattern as `Item::Bag::PeekItemRecord` — we
33-
// don't share because each caller is one-line-different and the
34-
// helper isn't worth a header.
35-
const uint8_t *PeekItemRecord(uint32_t itemID) {
36-
auto fn = reinterpret_cast<GetItemRecord_t>(Offsets::FUN_DBCACHE_ITEMSTATS_GET_RECORD);
37-
auto *cache = reinterpret_cast<void *>(Offsets::VAR_ITEMDB_CACHE);
38-
const uint64_t zeroGuid = 0;
39-
return fn(cache, itemID, &zeroGuid, nullptr, nullptr, 0);
40-
}
41-
4229
// `OffhandHasWeapon()` — true iff the player has a one-handed
4330
// weapon (or off-hand-only weapon) equipped in the off-hand slot.
4431
// Returns false for empty off-hand, shields, and held items
@@ -64,7 +51,7 @@ int __fastcall Script_OffhandHasWeapon(void *L) {
6451
return 1;
6552
}
6653

67-
auto *record = PeekItemRecord(static_cast<uint32_t>(itemID));
54+
auto *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
6855
if (record == nullptr) {
6956
Game::Lua::PushBoolean(L, 0);
7057
return 1;
@@ -102,7 +89,7 @@ int __fastcall Script_C_Item_IsEquippableItem(void *L) {
10289
Game::Lua::PushBoolean(L, 0);
10390
return 1;
10491
}
105-
auto *record = PeekItemRecord(static_cast<uint32_t>(itemID));
92+
auto *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
10693
if (record == nullptr) {
10794
Game::Lua::PushBoolean(L, 0);
10895
return 1;

src/item/GetData.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "item/Arg.h"
2828
#include "item/ID.h"
2929
#include "item/Location.h"
30+
#include "item/Record.h"
3031
#include "item/Spell.h"
3132

3233
#include <cstdint>
@@ -36,17 +37,6 @@ namespace Item::GetData {
3637

3738
namespace {
3839

39-
using GetItemRecord_t = const uint8_t *(__thiscall *)(void *cache, uint32_t itemID,
40-
const uint64_t *guid, void *callback,
41-
void *userData, bool requestIfMissing);
42-
43-
const uint8_t *FetchItemRecord(uint32_t itemID) {
44-
auto fn = reinterpret_cast<GetItemRecord_t>(Offsets::FUN_DBCACHE_ITEMSTATS_GET_RECORD);
45-
auto *cache = reinterpret_cast<void *>(Offsets::VAR_ITEMDB_CACHE);
46-
const uint64_t zeroGuid = 0;
47-
return fn(cache, itemID, &zeroGuid, nullptr, nullptr, false);
48-
}
49-
5040
int CurrentLocaleIndex() {
5141
return *reinterpret_cast<int *>(Offsets::VAR_LOCALE_INDEX);
5242
}
@@ -377,7 +367,7 @@ int PushDataForItemID(void *L, int itemID) {
377367
Game::Lua::PushNil(L);
378368
return 1;
379369
}
380-
const uint8_t *record = FetchItemRecord(static_cast<uint32_t>(itemID));
370+
const uint8_t *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
381371
if (record == nullptr) {
382372
Game::Lua::PushNil(L);
383373
return 1;

src/item/Info.cpp

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,18 @@
2020
#include "item/ID.h"
2121
#include "item/Link.h"
2222
#include "item/Location.h"
23+
#include "item/Record.h"
2324

2425
#include <cstdint>
2526
#include <cstdio>
2627
#include <cstring>
2728

2829
namespace Item::Info {
2930

30-
using GetItemRecord_t = const uint8_t *(__thiscall *)(void *cache, uint32_t itemID,
31-
const uint64_t *guid, void *callback,
32-
void *userData, bool requestIfMissing);
33-
3431
static const char *PushedOrEmpty(const char *s) { return (s != nullptr && s[0] != 0) ? s : ""; }
3532

3633
static int CurrentLocaleIndex() { return *reinterpret_cast<int *>(Offsets::VAR_LOCALE_INDEX); }
3734

38-
static const uint8_t *FetchItemRecord(uint32_t itemID) {
39-
auto fn = reinterpret_cast<GetItemRecord_t>(Offsets::FUN_DBCACHE_ITEMSTATS_GET_RECORD);
40-
auto *cache = reinterpret_cast<void *>(Offsets::VAR_ITEMDB_CACHE);
41-
const uint64_t zeroGuid = 0;
42-
return fn(cache, itemID, &zeroGuid, nullptr, nullptr, false);
43-
}
44-
4535
static const char *LookupItemClassName(uint32_t classID) {
4636
return PushedOrEmpty(DBC::LocalizedField(
4737
Offsets::VAR_ITEMCLASS_RECORDS, Offsets::VAR_ITEMCLASS_COUNT,
@@ -114,7 +104,7 @@ static int __fastcall Script_GetItemInfoInstant(void *L) {
114104

115105
Game::Lua::PushNumber(L, static_cast<double>(itemID));
116106

117-
const uint8_t *record = FetchItemRecord(static_cast<uint32_t>(itemID));
107+
const uint8_t *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
118108
if (record == nullptr) {
119109
for (int i = 0; i < 6; ++i)
120110
Game::Lua::PushNil(L);
@@ -150,7 +140,7 @@ static int __fastcall Script_GetItemInfoInstant(void *L) {
150140
static int PushIconForItemID(void *L, int itemID) {
151141
if (itemID <= 0)
152142
return 0;
153-
const uint8_t *record = FetchItemRecord(static_cast<uint32_t>(itemID));
143+
const uint8_t *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
154144
if (record == nullptr)
155145
return 0;
156146
const uint32_t displayInfoID = *reinterpret_cast<const uint32_t *>(
@@ -229,7 +219,7 @@ static int __fastcall Script_C_Item_GetItemFamily(void *L) {
229219
const int itemID = Item::Arg::ResolveItemID(L, 1);
230220
if (itemID <= 0)
231221
return 0;
232-
const uint8_t *record = FetchItemRecord(static_cast<uint32_t>(itemID));
222+
const uint8_t *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
233223
if (record == nullptr) {
234224
Item::Data::WarmCache(static_cast<uint32_t>(itemID));
235225
return 0;
@@ -264,7 +254,7 @@ static int __fastcall Script_C_Item_GetItemInfo(void *L) {
264254
if (itemID <= 0)
265255
return 0;
266256

267-
const uint8_t *record = FetchItemRecord(static_cast<uint32_t>(itemID));
257+
const uint8_t *record = Item::PeekRecord(static_cast<uint32_t>(itemID));
268258
if (record == nullptr) {
269259
Item::Data::WarmCache(static_cast<uint32_t>(itemID));
270260
return 0; // nil this call; GET_ITEM_INFO_RECEIVED fires when ready

0 commit comments

Comments
 (0)