Stored equipment on a cold cache, item level on Classic Era, and the guild broadcast - #11
Open
uga wants to merge 5 commits into
Open
Stored equipment on a cold cache, item level on Classic Era, and the guild broadcast#11uga wants to merge 5 commits into
uga wants to merge 5 commits into
Conversation
ScanInventorySlot() cleared a slot whenever GetInventoryItemLink() returned nil, without distinguishing an empty slot from an item whose link cannot be built yet because it is not in the client cache. On the first login after a patch this erased the character's whole stored inventory, which then got written to SavedVariables on logout, leaving the alt's grid column blank until the next login. Falls back to GetInventoryItemID(), which reads local inventory data and stays valid while the cache is cold. Also runs the delayed rescan on every version, not just retail, so an unresolved link is picked up once the cache warms up.
ScanAverageItemLevel() returned as soon as GetAverageItemLevel() existed, whether or not it answered anything usable. On Classic Era the function is there but returns zeroes, so the guard rejected the values, the early return skipped the manual calculation, and averageItemLvl was never set at all - which is why every AiL in the guild pane reads 0.0 while the same equipment shows up fine under Grids. The early return now happens only when the API actually produced an item level, so an unusable answer falls through to the loop over the 18 equipped slots that already exists for versions without the function. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GetAIL() passed the current character's item level straight to format("%d"),
which errors on nil - so a character without a stored item level did not just
broadcast a wrong value, it threw out of the login broadcast and no guild mate
received anything. The alt branch right below already guarded for this.
Three more nil paths on the same road, reachable now that item levels are
stored again: GetMemberKey() gave up when GetNameOfMain() returned nil, even
for our own character, where RequestGuildMemberEquipment() already falls back
to the member name; a member known only through his item level has no Inventory
table, which the slot lookup indexed blindly; and an equipment transfer for a
member never seen before indexed Members[character] before creating it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GetMemberKey() asked GetNameOfMain() who a guild member belongs to, and only took the local path when the answer was our own name. GetNameOfMain() answers from onlineMembers and the guild alts broadcast, so before that traffic arrives it does not recognize even the character currently logged in. The lookup then fell through to guild.Members[member], which holds nothing for a character that never broadcast anything about itself, and the whole method returned no value - which is what left the AiL column at 0.0 for the logged in character and for an alt in the same guild, while the very same item level was correctly stored and readable through GetAverageItemLevel(). The member name is now matched against our own characters on this realm and account first, and only what does not resolve locally is looked up in the guild table. Reading data we already have no longer depends on a broadcast having arrived, and our own data wins over a possibly stale copy received earlier. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The previous attempt still resolved our characters by hand: it rebuilt the character key from DataStore.ThisAccount and ThisRealm, asked GetCharacterID() for an id, then indexed DataStore_Inventory_Characters directly. Three assumptions, none of them verified from inside this file, and the AiL column stayed at 0.0. Both getters now go through the same public methods any other consumer uses: DataStore:GetCharacter(name) to tell whether the member is one of ours, then GetInventoryItem() / GetAverageItemLevel() on the returned key. Those are the calls that are known to answer correctly for the logged in character, so the guild pane now reads exactly what the rest of the addon reads. GetMemberKey() is gone, replaced by a small helper that only looks up the guild table. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Five fixes in
DataStore_Inventory, around stored equipment and the guild item level broadcast. Verified in game on Classic Era and TBC Anniversary.1. Do not wipe stored equipment when the item cache is cold
ScanInventorySlot()cleared a slot wheneverGetInventoryItemLink()returned nil, without distinguishing an empty slot from an item whose link cannot be built yet because it is not in the client cache. On the first login after a patch this erased the character's whole stored inventory, which was then written to saved variables on logout, leaving the alt's grid column blank until the next login.Falls back to
GetInventoryItemID(), which reads local inventory data and stays valid while the cache is cold, and runs the delayed rescan on every version rather than retail only, so an unresolved link is picked up once the cache warms.2. Compute the item level manually when the API returns zeroes
GetAverageItemLevel()does not exist on every version, and where it does it can still answer with zeroes on Classic Era. It is now only trusted when both values are usable, otherwise the manual calculation runs, instead of the character ending up with no item level at all.3. Harden the guild item level broadcast against missing data
A nil item level would error out of
format(), taking the whole broadcast with it, so one character without a usable value silenced the item level of every alt in the same message.4 & 5. Answer for our own characters from our own data
A guild member may be one of our own characters: the one currently logged in, or an alt in the same guild. Those are now answered from our own data, which is always present and always fresher than anything the guild channel may have carried, and everyone else from the guild table.
The name is resolved through
DataStore:GetCharacter()rather than askingGetNameOfMain()who the member belongs to: that one answers from the guild alts broadcast, so until that arrives it does not even recognise ourselves, and reading data we already have should not depend on the network.Applicability
GetAverageItemLevel()answers with zeroes on Classic Era; the change is version independent and simply falls through when the API is usableNote
The guild pane also needs the
DataStorePR to show anything at all when the guild is homed on another realm of a connected group: the readers and the writers were resolving two different guild ids, and the guild-based dispatch returned early before these functions were ever called.Related PRs
This is one change set spread over the repos it touches. Account sharing needs the first two together; the others are independent of each other.