diff --git a/libs/libunitscan.lua b/libs/libunitscan.lua index 9133bdc6..60af9ff5 100644 --- a/libs/libunitscan.lua +++ b/libs/libunitscan.lua @@ -2,20 +2,17 @@ setfenv(1, pfUI:GetEnvironment()) --[[ libunitscan ]]-- --- A pfUI library that remembers the class, level and guild of every player it --- sees: in the friends, guild, raid and party rosters, in /who results, and as --- target, mouseover or nameplate. The data is persisted within pfUI_playerDB, --- for the places that only have a player's name, such as chat links and --- offline friends. Anything with a unit reads the unit itself instead. +-- A pfUI library that remembers the level of every player it sees: in the +-- friends, guild, raid and party rosters, in /who results, and as target, +-- mouseover or nameplate. The levels are persisted within pfUI_playerDB, for +-- the places that only have a player's name, such as chat links and offline +-- friends. Anything with a unit reads the unit itself instead. A player's +-- class comes from C_PlayerCache.GetPlayerInfoByName, not from here. -- -- External functions: --- GetUnitInfo(name) --- Returns information of the given player name. Returns nil if the player --- was never seen. --- --- class[String] - The class of the player --- level[Number] - The level of the player --- guild[String] - The guild name of the player +-- GetPlayerLevel(name) +-- Returns the last seen level of the given player name, or nil if it was +-- never seen. -- -- return instantly when another libunitscan is already active @@ -23,33 +20,33 @@ if pfUI.api.libunitscan then return end local players = {} --- Feed (guid, name, classToken) into ClassicAPI's persistent name --- cache when the unit's GUID is resolvable. Roster-style packets --- (party / raid / inspect on glance) carry class inline, so the --- engine often doesn't issue a separate name query and the DLL's --- NameCache hook never fires for them — this is where we close that gap. -local function RememberByUnit(unit, name, class) - if not (name and class) then return end +-- Feed a unit into ClassicAPI's persistent name cache. Roster-style packets +-- (party / raid / inspect on glance) carry class inline, so the engine often +-- doesn't issue a separate name query and the DLL's NameCache hook never +-- fires for them — this is where we close that gap. +local function RememberByUnit(unit) local guid = UnitGUID(unit) if not guid then return end - C_PlayerCache.RememberPlayer(guid, name, class, UnitRace(unit), UnitSex(unit)) + local _, race = UnitRace(unit) + C_PlayerCache.RememberPlayer(guid, UnitName(unit), UnitClassBase(unit), race, UnitSex(unit) - 2) end -function GetUnitInfo(name) - local ret = players[name] - if ret then - return ret.class, ret.level, ret.guild +function GetPlayerLevel(name) + local entry = players[name] + return entry and entry.level +end + +-- UnitLevel returns -1 for unknown levels, don't overwrite known values +local function AddLevel(name, level) + if not name or not level or level <= 0 then return end + local entry = players[name] + if entry then + entry.level = level + else + players[name] = { level = level } end end -local function AddData(name, class, level, guild) - if not name then return end - players[name] = players[name] or {} - players[name].class = class or players[name].class - players[name].level = level or players[name].level - players[name].guild = guild or players[name].guild -end - local libunitscan = CreateFrame("Frame", "pfUnitScan", UIParent) libunitscan:RegisterEvent("PLAYER_ENTERING_WORLD") libunitscan:RegisterEvent("FRIENDLIST_UPDATE") @@ -68,58 +65,45 @@ libunitscan:SetScript("OnEvent", function() players = pfUI_playerDB -- update own character details - local name = UnitName("player") - local class = UnitClassBase("player") - local level = UnitLevel("player") - local guild = GetGuildInfo("player") - AddData(name, class, level, guild) - RememberByUnit("player", name, class) + AddLevel(UnitName("player"), UnitLevel("player")) + RememberByUnit("player") elseif event == "FRIENDLIST_UPDATE" then for i = 1, GetNumFriends() do local info = C_FriendList.GetFriendInfoByIndex(i) if info then - local level = info.level > 0 and info.level or nil - AddData(info.name, info.classFilename, level) + AddLevel(info.name, info.level) end end elseif event == "GUILD_ROSTER_UPDATE" then - local guild = GetGuildInfo("player") - local name, class, level, _ + local name, level, _ for i = 1, GetNumGuildMembers() do - name, _, _, level, class = GetGuildRosterInfo(i) - class = L["class"][class] or nil - AddData(name, class, level, guild) + name, _, _, level = GetGuildRosterInfo(i) + AddLevel(name, level) end elseif event == "RAID_ROSTER_UPDATE" then - local name, class, level, unit, _ + local name, level, _ for i = 1, GetNumRaidMembers() do - unit = "raid" .. i - name, _, _, level, class = GetRaidRosterInfo(i) - class = L["class"][class] or nil - AddData(name, class, level) - RememberByUnit(unit, name, class) + name, _, _, level = GetRaidRosterInfo(i) + AddLevel(name, level) + RememberByUnit("raid" .. i) end elseif event == "PARTY_MEMBERS_CHANGED" then - local name, class, level, unit, guild + local unit for i = 1, GetNumPartyMembers() do unit = "party" .. i - class = UnitClassBase(unit) - name = UnitName(unit) - level = UnitLevel(unit) - guild = GetGuildInfo(unit) - AddData(name, class, level, guild) - RememberByUnit(unit, name, class) + AddLevel(UnitName(unit), UnitLevel(unit)) + RememberByUnit(unit) end elseif event == "WHO_LIST_UPDATE" or event == "CHAT_MSG_SYSTEM" then for i = 1, C_FriendList.GetNumWhoResults() do local info = C_FriendList.GetWhoInfo(i) if info then - AddData(info.fullName, info.filename, info.level, info.fullGuildName) + AddLevel(info.fullName, info.level) end end @@ -128,13 +112,8 @@ libunitscan:SetScript("OnEvent", function() or event == "NAME_PLATE_UNIT_ADDED" and arg1 or "mouseover" if UnitIsPlayer(scan) then - local name = UnitName(scan) - local class = UnitClassBase(scan) - -- UnitLevel returns -1 for unknown levels, don't overwrite known values - local level = UnitLevel(scan) - level = level > 0 and level or nil - AddData(name, class, level, GetGuildInfo(scan)) - RememberByUnit(scan, name, class) + AddLevel(UnitName(scan), UnitLevel(scan)) + RememberByUnit(scan) end end end) diff --git a/modules/chat.lua b/modules/chat.lua index 8d757f4c..a7a91f12 100644 --- a/modules/chat.lua +++ b/modules/chat.lua @@ -701,12 +701,6 @@ pfUI:RegisterModule("chat", function () local r,g,b = GetStringColor(C.chat.text.unknowncolor) local unknowncolorhex = rgbhex(r,g,b) - local function GetPlayerLevel(name) - if not pfUI_playerDB then return nil end - if not pfUI_playerDB[name] then return nil end - return pfUI_playerDB[name].level - end - -- the sender of the line AddMessage is reading, from its chat event local lineSender, lineSenderClass, lineSenderRace, lineSenderSex @@ -727,10 +721,7 @@ pfUI:RegisterModule("chat", function () else _, class, _, raceKey, sex = C_PlayerCache.GetPlayerInfoByName(real) end - if not class then - class = GetUnitInfo(real) - end - if class and class ~= UNKNOWN then + if class then color = "|c" .. PFUI_CLASS_COLORS[class].colorStr if C.chat.text.factionicons == "1" then icon = GetFactionIcon(raceKey) @@ -745,11 +736,8 @@ pfUI:RegisterModule("chat", function () local suffix = "" local level = C.chat.text.playerlevel == "1" and GetPlayerLevel(real) - if level and level > 0 then + if level then suffix = " " .. rgbhex(GetDifficultyColor(level)) .. level .. "|r" - elseif level then - -- Show ?? for unknown levels (e.g. -1 from UnitLevel) - suffix = " |cffff0000??|r" end if color == "" and suffix == "" then return link end diff --git a/modules/nameplates.lua b/modules/nameplates.lua index 7fbf216d..accd0238 100644 --- a/modules/nameplates.lua +++ b/modules/nameplates.lua @@ -492,8 +492,7 @@ pfUI:RegisterModule("nameplates", function () local elite = UnitClassification(unit) if level <= 0 then if plate.player then - local _, dblevel = GetUnitInfo(plate.rawname) - if dblevel and dblevel > 0 then level = dblevel end + level = GetPlayerLevel(plate.rawname) or level else -- UnitLevel answers -1 exactly where the engine shows the skull: a -- world boss, or a hostile ten or more levels above the player diff --git a/modules/socialmod.lua b/modules/socialmod.lua index f06b99af..4f210198 100644 --- a/modules/socialmod.lua +++ b/modules/socialmod.lua @@ -5,7 +5,7 @@ pfUI:RegisterModule("socialmod", function () pfUI.socialmod:SetScript("OnEvent", function() local name = cmatch(arg1, _G.ERR_FRIEND_ONLINE_SS) name = name or cmatch(arg1, _G.ERR_FRIEND_OFFLINE_S) - if name and playerdb[name] and playerdb[name].cname then + if name and playerdb[name] then playerdb[name].lastseen = date("%a %d-%b-%Y") end end) @@ -92,7 +92,6 @@ pfUI:RegisterModule("socialmod", function () local cname = ccolor:WrapTextInColorCode(name) if playerdb[name] then playerdb[name].lastseen = date("%a %d-%b-%Y") - playerdb[name].cname = cname end if friendName then @@ -106,11 +105,13 @@ pfUI:RegisterModule("socialmod", function () caption:SetVertexColor(1,1,1,.9) friendInfo:SetVertexColor(1,1,1,.9) else - if playerdb[name] and playerdb[name].cname and playerdb[name].level and playerdb[name].lastseen then - caption:SetFormattedText(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), playerdb[name].cname) - friendInfo:SetFormattedText(TEXT(FRIENDS_LEVEL_TEMPLATE), playerdb[name].level, playerdb[name].lastseen) + local _, class = C_PlayerCache.GetPlayerInfoByName(name) + caption:SetFormattedText(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), class and PFUI_CLASS_COLORS[class]:WrapTextInColorCode(name) or name.."|r") + + local entry = playerdb[name] + if entry and entry.level and entry.lastseen then + friendInfo:SetFormattedText(TEXT(FRIENDS_LEVEL_TEMPLATE), entry.level, entry.lastseen) else - caption:SetFormattedText(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), name.."|r") friendInfo:SetText(TEXT(UNKNOWN)) end