local MAJOR, MINOR = "LibGuildInfo-1.0", 2 local LibGuildInfo, oldminor = LibStub:NewLibrary(MAJOR, MINOR) if not LibGuildInfo then return end --the same or newer version of this lib is already loaded into memory local Classes = {[1] = "Dragon Knight", [2]="Sorcerer", [3]="Nightblade", [6]="Templar"} local Alliances = {[1] = "Aldmeri Dominion", [2] = "Ebonhart Pact", [3] = "Daggerfall Convenant"} -- API -- -- If the table for the name is empty, that means the member has left the guild (thus the 'next' usage) -- All future API should funnel through this function, or be aware of the limitations function LibGuildInfo:GetGuildMemberByMemberName(name) local member = name:find("@") and self.DisplayNames[name:lower()] or self.CharacterNames[name:lower()] if member and next(member) then return member end end function LibGuildInfo:GetClassNumByMemberName(name) local member = self:GetGuildMemberByMemberName(name) if member then return member.class end end function LibGuildInfo:GetClassNameByMemberName(name) local classNum = self:GetClassNumByMemberName(name) if classNum and Classes[classNum] then return Classes[classNum] end end function LibGuildInfo:GetLevelByMemberName(name) local member = self:GetGuildMemberByMemberName(name) if member then if member.level < 50 then return member.level end return "V" .. member.veteranRank end end function LibGuildInfo:GetAllianceNumByMemberName(name) local member = self:GetGuildMemberByMemberName(name) if member then return member.alliance end end function LibGuildInfo:GetAllianceNameByMemberName(name) local allianceNum = self:GetAllianceNumByMemberName(name) if allianceNum and Alliances[allianceNum] then return Alliances[allianceNum] end end function LibGuildInfo:GetGuildRankIndexByMemberName(name) local member = self:GetGuildMemberByMemberName(name) if member then return member.rankIndex end end function LibGuildInfo:GetGuildRankByMemberName(name) local rankIndex = self:GetGuildRankIndexByMemberName(name) if rankIndex == 1 then return "GL" else return "R"..rankIndex end end -- Setup functions -- -- This is my deep table copy function, that bypasses previously copied tables -- to avoid infinite loops when it comes to recursive copying. Essentially a copy -- of the ZO_DeepCopyTable, but without the game locking local visitedTables = {} function LibGuildInfo:DeepTableCopy(source, subCall) local dest = {} for k, v in pairs(source) do if type(v) == "table" and not visitedTables[v] then visitedTables[v] = true dest[k] = self:DeepTableCopy(v, true) else dest[k] = v end end if not subCall then visitedTables = {} end return dest end function LibGuildInfo:DataLoaded() if self.GuildDataLoaded then return end self.GuildDataLoaded = true local currentGuildId = GUILD_ROSTER.guildId self.GuildRoster = {} for i=1, GetNumGuilds() do GUILD_ROSTER:SetGuildId(i) self.GuildRoster[i] = self:DeepTableCopy(GUILD_ROSTER["masterList"]) end GUILD_ROSTER:SetGuildId(currentGuildId) self:ProcessData() end function LibGuildInfo:ProcessData() self.DisplayNames = self.DisplayNames or {} ZO_ClearTable(self.DisplayNames) for i,roster in pairs(self.GuildRoster) do for i,v in pairs(roster) do self.DisplayNames[v.displayName:lower()] = v end end self.CharacterNames = self.CharacterNames or {} ZO_ClearTable(self.CharacterNames) for i, roster in pairs(self.GuildRoster) do for i,v in pairs(roster) do self.CharacterNames[v.characterName:lower()] = v end end end function LibGuildInfo:FindInCurrentRoster(name) for i,v in pairs(GUILD_ROSTER["masterList"]) do if name:find("@") and v.displayName:lower() == name:lower() or v.characterName == name:lower() then return v end end end function LibGuildInfo:OnGuildMemberAdded(guildId, displayName) if not self.GuildDataLoaded then return end local currentGuildId = GUILD_ROSTER.guildId GUILD_ROSTER:SetGuildId(guildId) local v = self:DeepTableCopy(self:FindInCurrentRoster(displayName)) table.insert(self.GuildRoster[guildId], v) self.DisplayNames[v.displayName:lower()] = v self.CharacterNames[v.characterName:lower()] = v GUILD_ROSTER:SetGuildId(currentGuildId) end -- If they're removed from the guild, empty the table out function LibGuildInfo:OnGuildMemberRemoved(guildId, displayName) if not self.GuildDataLoaded then return end local v = self.DisplayNames[displayName:lower()] ZO_ClearTable(v) end -- We just shallow copy into the existing table so as not to lose the -- table references everywhere by replacing it function LibGuildInfo:OnGuildMemberCharacterUpdated(guildId, displayName) if not self.GuildDataLoaded then return end local currentGuildId = GUILD_ROSTER.guildId GUILD_ROSTER:SetGuildId(guildId) local v = self:FindInCurrentRoster(displayName) ZO_ShallowTableCopy(v,self.DisplayNames[displayName:lower()]) GUILD_ROSTER:SetGuildId(currentGuildId) end EVENT_MANAGER:RegisterForEvent(MAJOR, EVENT_PLAYER_ACTIVATED, function() LibGuildInfo:DataLoaded() end) EVENT_MANAGER:RegisterForEvent(MAJOR, EVENT_GUILD_MEMBER_ADDED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberAdded(guildId, displayName) end) EVENT_MANAGER:RegisterForEvent(MAJOR, EVENT_GUILD_MEMBER_REMOVED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberRemoved(guildId, displayName) end) EVENT_MANAGER:RegisterForEvent(MAJOR, EVENT_GUILD_MEMBER_CHARACTER_UPDATED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberCharacterUpdated(guildId, displayName) end) EVENT_MANAGER:RegisterForEvent(MAJOR, EVENT_GUILD_MEMBER_CHARACTER_LEVEL_CHANGED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberCharacterUpdated(guildId, displayName) end) EVENT_MANAGER:RegisterForEvent(MAJOR, EVENT_GUILD_MEMBER_CHARACTER_VETERAN_RANK_CHANGED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberCharacterUpdated(guildId, displayName) end) EVENT_MANAGER:RegisterForEvent(MAJOR, EVENT_GUILD_MEMBER_RANK_CHANGED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberCharacterUpdated(guildId, displayName) end)