local lib = LibStub:NewLibrary("LibGUID", 6) if not lib then return end local COMBATLOG_OBJECT_AFFILIATION_OUTSIDER = COMBATLOG_OBJECT_AFFILIATION_OUTSIDER local guid_methods = guid_methods or {} local mixins = {'CreateGUIDObject', 'RegisterPrune', 'PruneGUIDCache', 'UpdateGUID', 'IsGUID', 'GetGroupGuid'} --[[ UNITNAME_SUMMON_TITLE1 = "Begleiter von %s"; UNITNAME_SUMMON_TITLE10 = "Reittier von %s"; UNITNAME_SUMMON_TITLE11 = "Lichtbrunnen von %s"; UNITNAME_SUMMON_TITLE12 = "Butler von %s"; UNITNAME_SUMMON_TITLE13 = "%s'aka"; UNITNAME_SUMMON_TITLE14 = "Portal von %s"; UNITNAME_SUMMON_TITLE15 = "Hass von %s"; UNITNAME_SUMMON_TITLE16 = "Statue von %s"; UNITNAME_SUMMON_TITLE17 = "Geist von %s"; UNITNAME_SUMMON_TITLE18 = "Kriegsbanner von %s"; UNITNAME_SUMMON_TITLE19 = "Herzerwärmer von %s"; UNITNAME_SUMMON_TITLE2 = "Wächter von %s"; UNITNAME_SUMMON_TITLE20 = "Angeheuert von %s"; UNITNAME_SUMMON_TITLE21 = "Gekauft von %s"; UNITNAME_SUMMON_TITLE22 = "Stolz von %s"; UNITNAME_SUMMON_TITLE23 = "Verzerrtes Abbild von %s"; UNITNAME_SUMMON_TITLE24 = "Nudelwagen von %s"; UNITNAME_SUMMON_TITLE25 = "Innerer Dämon von %s"; UNITNAME_SUMMON_TITLE26 = "Leibwächter von %s"; UNITNAME_SUMMON_TITLE27 = "%s"; UNITNAME_SUMMON_TITLE28 = "Knappe von %s"; UNITNAME_SUMMON_TITLE29 = "Champion von %s"; UNITNAME_SUMMON_TITLE3 = "Diener von %s"; UNITNAME_SUMMON_TITLE30 = "Der Verräter"; UNITNAME_SUMMON_TITLE31 = "Eruptive Reflexion von %s"; UNITNAME_SUMMON_TITLE32 = "Hoffnungslose Reflexion von %s"; UNITNAME_SUMMON_TITLE33 = "Bösartige Reflexion von %s"; UNITNAME_SUMMON_TITLE34 = "Klagende Reflexion von %s"; UNITNAME_SUMMON_TITLE35 = "Assistentin von %s"; UNITNAME_SUMMON_TITLE36 = "Vollstrecker von %s"; UNITNAME_SUMMON_TITLE37 = "Rekrut von %s"; UNITNAME_SUMMON_TITLE38 = "Fan von %s"; UNITNAME_SUMMON_TITLE39 = "Böser Zwilling von %s"; UNITNAME_SUMMON_TITLE4 = "Totem von %s"; UNITNAME_SUMMON_TITLE40 = "Gier von %s"; UNITNAME_SUMMON_TITLE41 = "Verlorener Verstand von %s"; UNITNAME_SUMMON_TITLE42 = "Paktgebundener Beschützer von %s"; UNITNAME_SUMMON_TITLE43 = "Mechanoid von %s"; UNITNAME_SUMMON_TITLE44 = "%s, Diener von N'Zoth"; UNITNAME_SUMMON_TITLE45 = "Assassine von %s"; UNITNAME_SUMMON_TITLE46 = "Wildsamen von %s"; UNITNAME_SUMMON_TITLE47 = "Provost von %s"; UNITNAME_SUMMON_TITLE48 = "Repariert von %s"; UNITNAME_SUMMON_TITLE5 = "Gefährte von %s"; UNITNAME_SUMMON_TITLE6 = "Runenklinge von %s"; UNITNAME_SUMMON_TITLE7 = "Konstrukt von %s"; UNITNAME_SUMMON_TITLE8 = "Gegner von %s"; UNITNAME_SUMMON_TITLE9 = "Fahrzeug von %s"; ]] local function assocOwner(guid, petguid) local gio = lib:CreateGUIDObject({guid}) local gip = lib:CreateGUIDObject({petguid}) gip:SetOwner(gio) end local function group_helper(guids, endcount, unitbase) for i = 1, endcount do local guid = UnitGUID(format("%s%i", unitbase, i)) if(guid) then guids[guid] = true local petguid = UnitGUID(format("%s%ipet", unitbase, i)) if(petguid) then assocOwner(guid, petguid) guids[petguid] = true end end end return guids end function lib:GetGroupGuid(guids) guids = guids or {} local grpguids = {} if(IsInRaid()) then grpguids = group_helper(grpguids, MAX_RAID_MEMBERS, 'raid') elseif(IsInGroup()) then grpguids = group_helper(grpguids, 4, 'party') local guid = UnitGUID('player') if(guid) then grpguids[guid] = true local petguid = UnitGUID('pet') if(petguid) then assocOwner(guid, petguid) grpguids[petguid] = true end end else local guid = UnitGUID('player') if(guid) then grpguids[guid] = true local petguid = UnitGUID('pet') if(petguid) then assocOwner(guid, petguid) grpguids[petguid] = true end end end for guid, v in pairs(grpguids) do local plr = self:CreateGUIDObject(guid) plr['isParty'] = true guids[guid] = true end return guids end lib.events = lib.events or CreateFrame("FRAME") local events = lib.events local roster = {} function events:RAID_ROSTER_UPDATE(event,...) -- print(event) roster = lib:GetGroupGuid() end function events:GROUP_ROSTER_UPDATE(event,...) -- print(event) roster = lib:GetGroupGuid() end function events:UNIT_TARGET(event, unit) --print(event) local trg = format("%starget", unit) local guid = UnitGUID(trg) if(guid) then local _, class = UnitClass(trg) -- print(class) -- local fullName, realm = UnitFullName(trg) local gi = lib:CreateGUIDObject({guid,['class'] = class, ['unit'] = trg}) if(gi['isBoss'] == nil) then local clf = UnitClassification(trg) -- print(trg, clf, UnitLevel(trg)) gi['isBoss'] = false if(clf == 'elite') then if(UnitLevel(trg) == -1) then gi['isBoss'] = true end end end end end function events:UNIT_NAME_UPDATE(event, unit) if(strsub(unit,1,9) == 'nameplate') then return end print(event, unit, UnitName(unit),strsub(unit,1,9)) local gi = lib:CreateGUIDObject(UnitGUID(unit)) if(gi) then gi:SetName(UnitName(unit)) end end for event, func in pairs(events) do -- if(not events:IsRegistered(event)) then if(type(func) == 'function') then events:RegisterEvent(event) end -- end end events:SetScript("OnEvent", function(self, event, ...) self[event](self, event, ...) end) local scanIds = { 1, 2, 3, 7, 9, 26, 29} lib.scanTip = lib.scanTip or CreateFrame("GameTooltip", "LibGUID_ScanTooltip", nil, "GameTooltipTemplate") local scanTip = lib.scanTip scanTip:SetOwner( WorldFrame, "ANCHOR_NONE" ) lib.mixinTargets = lib.mixinTargets or {} lib.guidCache = lib.guidCache or {} lib.pruneInfo = lib.pruneInfo or {} lib.newGUID = lib.newGUID or {} local guidCache = lib.guidCache local pruneInfo = lib.pruneInfo local newGUID = lib.newGUID local guidTypes = { ["Player"] = true, ["Creature"] = true, ["Pet"] = true, ["GameObject"] = true, ["Vehicle"] = true, ["Vignette"] = true } local function scanTooltip(guid) local text = _G["LibGUID_ScanTooltipTextLeft2"] if(guid and text) then scanTip:SetOwner(WorldFrame, 'ANCHOR_NONE') scanTip:SetHyperlink('unit:' .. guid or '') local text2 = text:GetText() if(text2) then for i = 1, #scanIds do local check = _G[format("UNITNAME_SUMMON_TITLE%i",scanIds[i])]:gsub("%%s", "(.+)"):gsub("[%[%]]", "%%%1") if(string.find(text2, check)) then local a,b,c = string.find(text2, check) if(c) then local g = UnitGUID(c) if(g) then return g end end end -- print(text:GetText(), check, guid) end end end end local function isGUID(guid) if(guid) then local typ = strsplit("-", guid) if(typ and guidTypes[typ]) then return typ end end end local function fireNewGUID(guid) for k, v in pairs(newGUID) do k[v](k, guid) end end function guid_methods:Touch() self['lastModified'] = GetTime() end function guid_methods:SetUnit(unit) local unitName, unitRealm = UnitFullName(unit) local _, unitClass = UnitClass(unit) if(unitName) then self['name'] = unitName end if(unitRealm) then self['realm'] = unitRealm end if(unitClass) then self['class'] = unitClass end self['unit'] = unit end function guid_methods:SetName(newName) self[2] = newName local nameSplit, serverSplit = strsplit('-',self[2],2) if(not serverSplit) then serverSplit = GetNormalizedRealmName() end self['shortName'] = nameSplit self['shortRealm'] = serverSplit end function guid_methods:HasOwner() return self['ownerGuid'] and true or false end function guid_methods:SetOwner(gi) -- print("set owner", self['name'], gi['name']) self['isPet'] = true if(gi) then self['ownerName'] = gi[2] self['ownerGuid'] = gi[1] if(gi:IsParty())then self['isParty'] = true end end end function guid_methods:Refresh() if(self['type'] == 'Player') then local localizedClass, englishClass, localizedRace, englishRace, sex, name, realm = GetPlayerInfoByGUID(self[1]) if(name and name ~= self['name']) then self[2] = name self['localizedClass'] = localizedClass self['englishClass'] = englishClass self['localizedRace'] = localizedRace self['englishRace'] = englishRace self['sex'] = sex self['name'] = name self['realm'] = realm end else if(self['isPet'] == nil) then self['ownerGuid'] = scanTooltip(self[1]) if(self['ownerGuid']) then self['isPet'] = true local owner = lib:CreateGUIDObject(self['ownerGuid']) if(owner) then self['ownerName'] = owner[2] or "" end end end end self:Touch() end function guid_methods:IsParty() if(not roster[self[1]] and self[3]) then -- print(self[2], self[3],bit.band(self[3], COMBATLOG_OBJECT_AFFILIATION_OUTSIDER)) if(bit.band(self[3], COMBATLOG_OBJECT_AFFILIATION_OUTSIDER) == 0) then return true end end return roster[self[1]] end local namespace_methods = namespace_methods or {} function namespace_methods:GetNamespace(ns) ns = format("namespace_%s", ns) self[ns] = self[ns] or {} for k, v in pairs(namespace_methods) do self[ns][k] = v end end function namespace_methods:Get(setting) return self[setting] end function namespace_methods:Set(setting, value) self[setting] = value end guid_methods.GetNamespace = namespace_methods.GetNamespace function lib:IsGUID(guid) return isGUID(guid) end function lib:CreateGUIDObject(obj) if(obj) then if(type(obj) == 'string') then obj = {obj} end local guid = obj[1] if(not guidCache[guid]) then local typ = isGUID(guid) if(typ) then obj['type'] = typ for k, v in pairs(guid_methods) do obj[k] = v end obj:Refresh() guidCache[guid] = obj fireNewGUID(guid) end else for k, v in pairs(obj) do if(type(v) ~= 'table') then guidCache[guid][k] = v end end obj = guidCache[guid] end return guidCache[guid] end end function lib:RegisterNewGUID(func) newGUID[self] = func end function lib:RegisterPrune(func) pruneInfo[self] = func end function lib:UpdateGUID(guid, data) if(not data and type(guid) == 'table') then data = guid guid = data[1] end if(guid and data) then if(not guidCache[guid]) then guidCache[guid] = self:CreateGUIDObject(data) else for k, v in pairs(data) do guidCache[guid][k] = v end end return guidCache[guid] end end function lib:PruneGUIDCache(maxAge) for k, v in pairs(pruneInfo) do -- print("pi",k,v) v(k) end local maxAge = maxAge or 360 local t = GetTime() - maxAge local del = 0 local cnt = 0 for guid, obj in pairs(guidCache) do cnt = cnt + 1 if(obj['lastModified'] < t) then guidCache[guid] = nil del = del + 1 end end -- print("del", cnt, "/", del) end for guid, obj in pairs(guidCache)do obj:Refresh() end function lib:Embed(target) target = target or CreateFrame("FRAME") for _,name in pairs(mixins) do target[name] = lib[name] end lib.mixinTargets[target] = true return target end for target, _ in pairs(lib.mixinTargets) do lib:Embed(target) end