Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 30 additions & 25 deletions DataStore_Inventory/API/GuildComm.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,9 @@ local function GetThisGuild()
return guildID and guilds[guildID]
end

local function GetMemberKey(guild, member)
-- returns the appropriate key to address a guild member.
-- Either it's a known alt ==> point to the characters table
-- Or it's a guild member ==> point to the guild table
local main = DataStore:GetNameOfMain(member)

if main and main == UnitName("player") then
local key = format("%s.%s.%s", DataStore.ThisAccount, DataStore.ThisRealm, member)
local id = DataStore:GetCharacterID(key)

return DataStore_Inventory_Characters[id]
end

if not guild or not guild.Members then
return nil
end
return guild.Members[member]
local function GetGuildMemberInfo(guild, member)
-- data received over the guild channel, for a member who broadcast something about himself
return guild and guild.Members and guild.Members[member]
end

local function GetAIL(alts)
Expand All @@ -51,7 +37,11 @@ local function GetAIL(alts)

local character = DataStore:GetCharacter() -- this character
local ail = DataStore:GetAverageItemLevel(character)
TableInsert(out, format("%s:%d", UnitName("player"), ail))

-- a nil item level would error out of format(), taking the whole broadcast with it
if ail then
TableInsert(out, format("%s:%d", UnitName("player"), ail))
end

if strlen(alts) > 0 then
for _, name in pairs( { strsplit("|", alts) }) do -- then all his alts
Expand Down Expand Up @@ -105,7 +95,7 @@ local function _RequestGuildMemberEquipment(member)
if not main then -- player is offline, check if his equipment is in the DB
local thisGuild = GetThisGuild()

if thisGuild and thisGuild.Members[member] then -- player found
if thisGuild and thisGuild.Members and thisGuild.Members[member] then -- player found
if thisGuild.Members[member].Inventory then -- equipment found
AddonFactory:Broadcast("DATASTORE_PLAYER_EQUIPMENT_RECEIVED", player, member)
return
Expand All @@ -131,20 +121,33 @@ local function _RequestGuildMemberEquipment(member)
DataStore:GuildWhisper(commPrefix, main, MSG_EQUIPMENT_REQUEST, member)
end

--[[
A guild member may be one of our own characters: the one currently logged in, or an alt in the
same guild. Those are answered from our own data, which is always there and always fresher than
anything the guild channel may have carried. Everyone else is answered from the guild table.
Note that we resolve the name through DataStore:GetCharacter() rather than asking
GetNameOfMain() who the member belongs to: that one answers from the guild alts broadcast, so
until that arrives it does not even recognize ourselves.
--]]
local function _GetGuildMemberInventoryItem(guild, member, slotID)
local character = GetMemberKey(guild, member)

local character = DataStore:GetCharacter(member) -- this realm, this account
if character then
return character.Inventory[slotID]
return DataStore:GetInventoryItem(character, slotID)
end

-- a member known only through his item level broadcast has no inventory yet
local info = GetGuildMemberInfo(guild, member)
return info and info.Inventory and info.Inventory[slotID]
end

local function _GetGuildMemberAverageItemLevel(guild, member)
local character = GetMemberKey(guild, member)

local character = DataStore:GetCharacter(member) -- this realm, this account
if character then
return character.averageItemLvl
return (DataStore:GetAverageItemLevel(character))
end

local info = GetGuildMemberInfo(guild, member)
return info and info.averageItemLvl
end


Expand Down Expand Up @@ -182,6 +185,8 @@ local commCallbacks = {
[MSG_EQUIPMENT_TRANSFER] = function(sender, character, equipment)
local thisGuild = GetThisGuild()
if thisGuild then
thisGuild.Members = thisGuild.Members or {}
thisGuild.Members[character] = thisGuild.Members[character] or {}
thisGuild.Members[character].Inventory = equipment
thisGuild.Members[character].lastUpdate = time()
AddonFactory:Broadcast("DATASTORE_PLAYER_EQUIPMENT_RECEIVED", sender, character)
Expand Down
28 changes: 19 additions & 9 deletions DataStore_Inventory/DataStore_Inventory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,20 @@ local function ScanAverageItemLevel()
char.lastUpdate = time()
char.overallAIL = 0

-- GetAverageItemLevel only exists in retail
-- GetAverageItemLevel does not exist on every version, and where it does it may still return
-- zeroes (Classic Era). Only trust it when it answers with usable values, fall through to the
-- manual calculation otherwise, or the character ends up with no item level at all.
if type(GetAverageItemLevel) == "function" then

local overallAiL, AiL = GetAverageItemLevel()
if overallAiL and AiL and overallAiL > 0 and AiL > 0 then
char.overallAIL = overallAiL
char.averageItemLvl = AiL
return
end
return
end
-- if we get here, GetAverageItemLevel does not exist, we must calculate manually.

-- if we get here, GetAverageItemLevel is missing or unusable, we must calculate manually.
local totalItemLevel = 0
local itemCount = 0

Expand Down Expand Up @@ -91,13 +93,19 @@ local function ScanInventorySlot(slot)
local link = GetInventoryItemLink("player", slot)

local currentContent = inventory[slot]
if link then

if link then
if IsEnchanted(link) then -- if there's an enchant, save the full link
inventory[slot] = link
else -- .. otherwise, only save the id
inventory[slot] = tonumber(link:match("item:(%d+)"))
end
elseif GetInventoryItemID("player", slot) then
-- The slot holds an item, but its link cannot be built yet because the item is not in the
-- client cache (typically the first login after a patch, when the cache was invalidated).
-- Save the id rather than wiping a slot that is not actually empty. A later rescan, once
-- the cache is warm, replaces it with the full link if the item is enchanted.
inventory[slot] = GetInventoryItemID("player", slot)
else
inventory[slot] = nil
end
Expand Down Expand Up @@ -332,10 +340,12 @@ local function OnPlayerAlive()

if isRetail then
ScanTransmogSets()

-- Scan again after 5 seconds, no less, to ensure that item info has been properly updated.
C_Timer.After(5, ScanInventory)
end

-- Scan again after 5 seconds, no less, to ensure that item info has been properly updated.
-- Needed on every version, not just retail : the first scan runs early enough that the item
-- cache may still be cold, which is what leaves slots unresolved right after a patch.
C_Timer.After(5, ScanInventory)
end

local function OnPlayerEquipmentChanged(event, slot)
Expand Down