diff --git a/Heimdall.lua b/Heimdall.lua index ca8b69f..0fb509f 100644 --- a/Heimdall.lua +++ b/Heimdall.lua @@ -263,6 +263,7 @@ local function init() ---@field texture string ---@field offsetX number ---@field offsetY number + ---@field rescan boolean --- Data --- ---@class HeimdallMessengerData @@ -520,6 +521,7 @@ local function init() texture = shared.GetOrDefault(Heimdall_Data, { "config", "achievementSniffer", "texture" }, "Aura53.tga"), offsetX = shared.GetOrDefault(Heimdall_Data, { "config", "achievementSniffer", "offsetX" }, 0), offsetY = shared.GetOrDefault(Heimdall_Data, { "config", "achievementSniffer", "offsetY" }, 0), + rescan = shared.GetOrDefault(Heimdall_Data, { "config", "achievementSniffer", "rescan" }, false), }, addonPrefix = shared.GetOrDefault(Heimdall_Data, { "config", "addonPrefix" }, "HEIMDALL"), channelLocale = shared.GetOrDefault(Heimdall_Data, { "config", "channelLocale" }, {}), diff --git a/Modules/AchievementSniffer.lua b/Modules/AchievementSniffer.lua index d588cf8..f65a9ea 100644 --- a/Modules/AchievementSniffer.lua +++ b/Modules/AchievementSniffer.lua @@ -6,12 +6,195 @@ local ModuleName = "AchievementSniffer" local HeimdallRoot = "Interface\\AddOns\\Heimdall\\" local TextureRoot = HeimdallRoot .. "Texture\\" +local Achievements = { + 15, + 153, + 245, + 506, + 507, + 513, + 524, + 648, + 649, + 651, + 655, + 657, + 660, + 661, + 667, + 668, + 669, + 671, + 676, + 678, + 681, + 682, + 697, + 777, + 958, + 974, + 975, + 1017, + 1266, + 1556, + 1557, + 1558, + 1576, + 2078, + 2141, + 2200, + 4477, + 4478, + 4624, + 4914, + 4958, + 4960, + 5455, + 5456, + 5749, + 5752, + 6456, + 6460, + 6753, + 6757, + 6758, + 6835, + 7382, + 7383, + 7384, + 7437, + 7948, + 8929, + 8952, + 8956, + 8966, + 8967, + 8969, + 8978, + 8979, + 8980, + 8981, + 8982, + 8983, + 9017, + 9038, + 9132, + 9493, + 9507, + 10059, + 10079, + 10278, + 10460, + 10581, + 10585, + 10595, + 10597, + 10617, + 10657, + 10666, + 10667, + 10668, + 10672, + 10682, + 10684, + 10688, + 10689, + 10692, + 10693, + 10698, + 10706, + 10746, + 10755, + 10756, + 10763, + 10772, + 10775, + 10790, + 10800, + 10818, + 10819, + 10820, + 10875, + 10994, + 11124, + 11126, + 11127, + 11128, + 11153, + 11157, + 11164, + 11188, + 11189, + 11190, + 11214, + 11220, + 11298, + 11338, + 11394, + 11446, + 11473, + 11545, + 11559, + 11610, + 11611, + 11653, + 11657, + 11658, + 11659, + 11660, + 11674, + 11773, + 11787, + 11789, + 11790, + 11796, + 11992, + 11993, + 11994, + 11995, + 11996, + 11997, + 11998, + 11999, + 12000, + 12001, + 12008, + 12015, + 12020, + 12026, + 12028, + 12030, + 12072, + 12074, + 12085, + 12086, + 12103, + 12110, + 12445, + 12447, + 12448, +} + ---@diagnostic disable-next-line: missing-fields shared.AchievementSniffer = {} function shared.AchievementSniffer.Init() if Heimdall_Data.config.achievementSniffer.debug then print(string.format("[%s] Module initialized", ModuleName)) end + local guidMap = {} + + ---@class AchievementData + ---@field id number + ---@field date string + ---@field completed boolean + + ---@class Heimdall_Achievements + ---@field players table> + ---@field alreadySeen table + ---@field rescan boolean + if not Heimdall_Achievements then Heimdall_Achievements = {} end + if not Heimdall_Achievements.players then Heimdall_Achievements.players = {} end + if not Heimdall_Achievements.alreadySeen then Heimdall_Achievements.alreadySeen = {} end local framePool = {} for i = 1, 40 do @@ -23,5 +206,111 @@ function shared.AchievementSniffer.Init() table.insert(framePool, frame) end + ---@param name string + local function Scan(name) + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Scanning achievements for %s", ModuleName, name)) + end + Heimdall_Achievements.players[name] = {} + for i, aid in ipairs(Achievements) do + local completed, month, day, year = GetAchievementComparisonInfo(aid) + if completed then + ---@type string + local yearstr = "" .. year + if year < 100 then yearstr = "20" .. year end + + local date = string.format("%04d-%02d-%02d", yearstr, month, day) + + local data = { + id = aid, + date = date, + completed = completed, + } + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Achievement %d completed on %s", ModuleName, aid, date)) + end + Heimdall_Achievements.players[name][aid] = data + end + end + end + + ---@param unit string + local function TryInspect(unit) + local targetPlayer = UnitIsPlayer(unit) + if not targetPlayer then return end + local targetName = UnitName(unit) + local targetGuid = UnitGUID(unit) + guidMap[targetGuid] = targetName + + local should = false + if not Heimdall_Achievements.players[targetName] then + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Player %s does not have prior achievement data", ModuleName, targetName)) + end + should = true + end + if Heimdall_Achievements.alreadySeen[targetName] then + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Player %s has already been seen", ModuleName, targetName)) + end + should = false + end + if Heimdall_Data.config.achievementSniffer.rescan then + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Rescan is enabled", ModuleName)) + end + should = true + end + + if not should then + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Not inspecting player: %s", ModuleName, targetName)) + end + return + end + + local canInspect = CheckInteractDistance(unit, 1) + if canInspect then + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Inspecting player: %s", ModuleName, targetName)) + end + SetAchievementComparisonUnit(unit) + else + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Cannot inspect player (too far?): %s", ModuleName, targetName)) + end + end + end + + local nameplateFrame = CreateFrame("Frame") + nameplateFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED") + nameplateFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED") + nameplateFrame:SetScript("OnEvent", function(self, event, unit) + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Event triggered: %s for unit: %s", ModuleName, event, unit)) + end + if event == "NAME_PLATE_UNIT_ADDED" then + TryInspect(unit) + elseif event == "NAME_PLATE_UNIT_REMOVED" then + print("NAME_PLATE_UNIT_REMOVED", unit) + end + end) + + local inspectFrame = CreateFrame("Frame") + inspectFrame:RegisterEvent("INSPECT_ACHIEVEMENT_READY") + inspectFrame:SetScript("OnEvent", function(self, event, guid) + local name = guidMap[guid] + if not name then + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] No name found for guid: %s", ModuleName, guid)) + end + return + end + if Heimdall_Data.config.achievementSniffer.debug then + print(string.format("[%s] Event triggered: %s for player: %s", ModuleName, event, name)) + end + Scan(name) + end) + print("[Heimdall] AchievementSniffer loaded") end