Compare with Previous | Blame | View Log
EventAnnouncer = LibStub("AceAddon-3.0"):NewAddon("EventAnnouncer", "AceEvent-3.0", "AceConsole-3.0", "AceTimer-3.0") local RED = "|cffff4040" local GREEN = "|cff40cd40" function EventAnnouncer:OnInitialize() self.db = LibStub("AceDB-3.0"):New("EventAnnouncerDB", self:GetDefaults(), true) self.options = self:GetOptions() self.options.args.Profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) self.options.args.Profiles.disabled = function() return not self.db.profile.enabled end LibStub("AceConfig-3.0"):RegisterOptionsTable("EventAnnouncer", self.options) self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("EventAnnouncer", "Event Announcer") self:RegisterChatCommand("ea", "Command") self.playerName = UnitName("player") self.guildThrottleTimer = {} self.pending = {} self.db.Test = "Dit is een test" self.db.Guild = {} self.db.Guild["Test data"] = { [0] = COLOR_HORDE, [1] = COLOR_ALLIANCE, } self:Print("Initialized") end function EventAnnouncer:OnEnable() self:RegisterEventConditional("ACHIEVEMENT_EARNED", (self.db.profile.events.ownachievement or self.db.profile.events.guildachievement)) self:RegisterEventConditional("CHAT_MSG_GUILD_ACHIEVEMENT", self.db.profile.events.guildmemberachievement) self:RegisterEventConditional("CHAT_MSG_SKILL", self.db.profile.events.skills) self:RegisterEventConditional("PLAYER_LEVEL_UP", self.db.profile.events.levelup) self:RegisterEventConditional("PET_BATTLE_LEVEL_CHANGED", self.db.profile.events.battlepetlevelup) self:RegisterEventConditional("UNIT_GUILD_LEVEL", self.db.profile.events.guildachievement) self:RegisterEventConditional("CHAT_MSG_SYSTEM", (self.db.profile.events.guildchanges or self.db.profile.events.faction)) -- Special case: during logon we cannot query the guild name at this point yet self:RegisterEventConditional("GUILD_ROSTER_UPDATE", IsInGuild() and self.currentGuild == nil) self:Debug("Enabled") end function EventAnnouncer:RegisterEventConditional(event, condition) if condition then self:RegisterEvent(event) self:Debug(GREEN .. event) end end function EventAnnouncer:OnDisable() self:UnregisterEvent("ACHIEVEMENT_EARNED") self:UnregisterEvent("PLAYER_LEVEL_UP") self:UnregisterEvent("PET_BATTLE_LEVEL_CHANGED") self:UnregisterEvent("UNIT_GUILD_LEVEL") self:UnregisterEvent("CHAT_MSG_GUILD_ACHIEVEMENT") self:UnregisterEvent("CHAT_MSG_SKILL") self:UnregisterEvent("CHAT_MSG_SYSTEM") self:Debug("Disabled") end function EventAnnouncer:ApplySettings() self:OnDisable() self:OnEnable() end function EventAnnouncer:GUILD_ROSTER_UPDATE() self.currentGuild = GetGuildInfo("player") self:Debug(string.format("Current guild name retrieved:%s", self.currentGuild or "(null)")) self:UnregisterEvent("GUILD_ROSTER_UPDATE") end function EventAnnouncer:ACHIEVEMENT_EARNED(event, id) local isGuildAchievement = select(12, GetAchievementInfo(id)) if isGuildAchievement then if self.db.profile.events.guildachievement then self:AnnounceGuildAchievement(GetGuildInfo("player"), GetAchievementLink(id)) end else if self.db.profile.events.ownachievement then self:AnnounceAchievement(self.playerName, GetAchievementLink(id)) end end end function EventAnnouncer:CHAT_MSG_GUILD_ACHIEVEMENT(event, msg, playername) -- Parse chat message to extract achievement string -- (.*) has earned the achievement (.*)! local pattern = self:FormatToPattern(ACHIEVEMENT_BROADCAST) local _, _, player, achievement = string.find(msg, pattern) if not achievement then self:Debug("Error: failed to parse ["..msg.."]") return end -- Filter friends, only if configured if self.db.profile.events.friendsonly and not self:IsFriend(playername) then self:Debug("Skipping, ["..playername.."] is not on friend list") return end -- Parse achievement string to extract id local _, _, id = string.find(achievement, "|Hachievement:(%d*):") if not id then self:Debug("Error: failed to parse ["..achievement.."]") return end id = tonumber(id) -- Stop any throttle timer associated with this achievement if self.guildThrottleTimer[id] then self:CancelTimer(self.guildThrottleTimer[id], true) end -- Create a new table for this achievement if it didn't exist if not self.pending[id] then self.pending[id] = {} -- And add the clickable link as first entry table.insert(self.pending[id], achievement) end -- Append player name to table table.insert(self.pending[id], playername) -- Schedule a flush table timer self.guildThrottleTimer[id] = self:ScheduleTimer("Flushguildmemberachievements", self.db.profile.guildThrottleDelay, id) end function EventAnnouncer:Flushguildmemberachievements(flushid) -- Grab (and remove) clickable achievement link from table local achievement = table.remove(self.pending[flushid], 1) -- Announce the achievement self:AnnounceMultiAchievement(self.pending[flushid], achievement) -- Clear the table self.pending[flushid] = table.wipe(self.pending[flushid]) -- Remove table & timer self.guildThrottleTimer[flushid] = nil self.pending[flushid] = nil end function EventAnnouncer:CHAT_MSG_SKILL(event, msg) -- You have gained the %s skill local pattern1 = self:FormatToPattern(ERR_SKILL_GAINED_S) local _, _, skillName = string.find(msg, pattern1) if skillName then self:AnnounceSkillNew(self.playerName, skillName) end -- Your skill in %s has increased to %d. local pattern2 = self:FormatToPattern(ERR_SKILL_UP_SI) local _, _, skillName, skillLevel = string.find(msg, pattern2) if skillName then local milestone = 75 if EventAnnouncer:IsWeaponSkill(skillName) then milestone = 50 skillName = string.format("weapon skill %s", skillName) end self:Debug("Skill ["..skillName.."] Milestone ["..milestone.."]") if skillLevel % milestone == 0 then self:AnnounceSkillMilestone(self.playerName, skillName, skillLevel) end end end function EventAnnouncer:PET_BATTLE_LEVEL_CHANGED(event, activePlayer, activePetSlot, newLevel) if (activePlayer == LE_BATTLE_PET_ALLY) then local petID, _, _ = C_PetJournal.GetPetLoadOutInfo(activePetSlot); -- speciesID, customName, petLevel, xp, maxXp, displayID, name, petIcon local speciesID, customName, _, _, _, _, name, _ = C_PetJournal.GetPetInfoByPetID(petID); self:AnnounceBattlePetLevel(self.playerName, name, customName, newLevel, abName) end end function EventAnnouncer:PLAYER_LEVEL_UP(event, lvl) --if (lvl > 9) then self:AnnounceLevel(self.playerName, lvl) --end end function EventAnnouncer:UNIT_GUILD_LEVEL(event, unit, lvl) if unit == "player" then self:AnnounceGuildLevel(GetGuildInfo(unit), lvl) end end function EventAnnouncer:CHAT_MSG_SYSTEM(event, msg) local pattern --self:Debug("CHAT_MSG_SYSTEM: "..msg) if self.db.profile.events.guildchanges then -- |Hplayer:%s|h[%s]|h invites you to join %s. pattern = self:FormatToPattern(ERR_INVITED_TO_GUILD_SSS) local _, _, _, _, joinguild = string.find(msg, pattern) if joinguild then self.invitedGuild = joinguild self:Debug("Invite received, about to join guild " .. joinguild) return end -- %s has joined the guild. pattern = self:FormatToPattern(ERR_GUILD_JOIN_S) local _, _, invitee = string.find(msg, pattern) if invitee == self.playerName then self.currentGuild = self.invitedGuild self:AnnounceGuildChange(self.playerName, "joined", self.currentGuild) return end -- %s has left the guild. pattern = self:FormatToPattern(ERR_GUILD_LEAVE_S) local _, _, leaver = string.find(msg, pattern) if leaver == self.playerName then self:AnnounceGuildChange(self.playerName, "left", self.currentGuild) self.currentGuild = nil return end -- %s has been kicked out of the guild by %s. pattern = self:FormatToPattern(ERR_GUILD_REMOVE_SS) local _, _, victim = string.find(msg, pattern) if victim == self.playerName then self:AnnounceGuildChange(self.playerName, "was kicked from", self.currentGuild) self.currentGuild = nil return end -- Congratulations, you are a founding member of %s! pattern = self:FormatToPattern(ERR_GUILD_FOUNDER_S) local _, _, newguild = string.find(msg, pattern) if (newguild) then self.currentGuild = newguild self:AnnounceGuildChange(self.playerName, "created", self.currentGuild) return end end if self.db.profile.events.faction then -- You are now %s with %s. pattern = self:FormatToPattern(FACTION_STANDING_CHANGED) local _, _, standing, factionName = string.find(msg, pattern) if standing then self:AnnounceFaction(self.playerName, standing, factionName) return end end end -- From FizzWidget's FactionFriend function EventAnnouncer:FormatToPattern(formatString) local patternString = formatString; patternString = string.gsub(patternString, "%%%d+%$([diouXxfgbcsq])", "%%%1"); -- reordering specifiers (e.g. %2$s) stripped patternString = string.gsub(patternString, "([%$%(%)%.%[%]%*%+%-%?%^])", "%%%1"); -- convert regex special characters patternString = string.gsub(patternString, "%%c", "(.)"); -- %c to (.) patternString = string.gsub(patternString, "%%s", "(.+)"); -- %s to (.+) patternString = string.gsub(patternString, "%%[du]", "(%%d+)"); -- %d to (%d+) patternString = string.gsub(patternString, "%%([gf])", "(%%d+%%.*%%d*)"); -- %g or %f to (%d+%.*%d*) return patternString; end function EventAnnouncer:IsFriend(player) local name -- Check for regular characters for i = 1, GetNumFriends() do name = GetFriendInfo(i) if name == player then self:Debug("IsFriend: " .. player .. " is a normal friend") return true end end -- Check for real-id friends for i = 1, BNGetNumFriends() do for j = 1, BNGetNumFriendToons(i) do _, toonName, client, realmName = BNGetFriendToonInfo(i, j) if client == BNET_CLIENT_WOW and toonName == player and realmName == GetRealmName() then self:Debug("IsFriend: " .. player .. " is a real-id friend") return true end end end return false end local weaponSkills = { "Axes", "Bows", "Crossbows", "Daggers", "Guns", "Maces", "Swords", "Staves", "Unarmed", "Defense", "Polearms", "Two-Handed Swords", "Two-Handed Maces", "Two-Handed Axes" } function EventAnnouncer:IsWeaponSkill(skill) for k, val in pairs(weaponSkills) do if val == skill then return true end end return false end function EventAnnouncer:AnnounceAchievement(who, what) self:BroadcastMessage( string.format("%s earned by %s", what, who) ) end function EventAnnouncer:AnnounceGuildAchievement(who, what) self:BroadcastMessage( string.format("%s earned by guild [%s]", what, who) ) end function EventAnnouncer:AnnounceMultiAchievement(who, what) local txt if table.getn(who) > self.db.profile.guildMaxNames then local cutoff = math.max(self.db.profile.guildMaxNames - 2, 1) txt = table.concat(who, ", ", 1, cutoff) .. " and " .. (table.getn(who) - cutoff) .. " more" else txt = table.concat(who, ", ") end self:BroadcastMessage( string.format("%s earned by %s", what, txt) ) end function EventAnnouncer:AnnounceFaction(who, what, withwhom) if withwhom == GetGuildInfo("player") then self:BroadcastMessage( string.format("%s just hit %s with guild [%s]", who, what, withwhom) ) else self:BroadcastMessage( string.format("%s just hit %s with %s", who, what, withwhom) ) end end function EventAnnouncer:AnnounceSkillNew(who, what) self:BroadcastMessage( string.format("%s just gained the %s skill", who, what) ) end function EventAnnouncer:AnnounceSkillMilestone(who, what, howhigh) self:BroadcastMessage( string.format("%s levelled %s to %d", who, what, howhigh) ) end function EventAnnouncer:AnnounceLevel(who, whatlevel) self:BroadcastMessage( string.format("Ding! %s has reached level %d", who, whatlevel) ) end function EventAnnouncer:AnnounceGuildLevel(whatguild, whatlevel) self:BroadcastMessage( string.format("Ding! Guild [%s] reached level %d", whatguild, whatlevel) ) end function EventAnnouncer:AnnounceBattlePetLevel(who, petname, customname, whatlevel) local fullpetname = petname if customname then fullpetname = string.format("%s the %s", customname, petname) end self:BroadcastMessage( string.format("Ding! %s's battle pet [%s] reached level %d", who, fullpetname, whatlevel) ) end function EventAnnouncer:AnnounceGuildChange(who, didwhat, whatguild) if (whatguild ~= nil) then self:BroadcastMessage( string.format("%s %s the guild [%s]", who, didwhat, whatguild) ) else self:BroadcastMessage( string.format("%s %s some guild", who, didwhat) ) end end function EventAnnouncer:BroadcastMessage(msg) if self.db.profile.output.guild then SendChatMessage(msg, "GUILD") end if self.db.profile.output.self then self:Print(msg) end for key, val in pairs(self.db.profile.output.channel) do if val then local chnr = GetChannelName(key) if chnr then SendChatMessage(msg, "CHANNEL", nil, chnr) end end end end ----- DEBUGGING function EventAnnouncer:Debug(msg) if self.db.profile.debug then self:Print("[DEBUG] ".. msg.."|r") end end function EventAnnouncer:test1() self:ACHIEVEMENT_EARNED("DUMMY", 412) end function EventAnnouncer:test2() local msg = string.format(FACTION_STANDING_INCREASED, "Argent Dawn", 1500) self:CHAT_MSG_COMBAT_FACTION_CHANGE("DUMMY", msg) end function EventAnnouncer:test3(n,i) local name local id if n then name = n else name = "Testplayer" end if i then id = i else id = 412 end local msg = string.format("%s has earned the achievement %s!", name, GetAchievementLink(id)) self:CHAT_MSG_GUILD_ACHIEVEMENT("DUMMY", msg, name) end function EventAnnouncer:Command(param) --if param == "config" then InterfaceOptionsFrame_OpenToCategory(self.optionsFrame) --end end ----- CONFIG function EventAnnouncer:GetDefaults() -- declare defaults to be used in the DB return { profile = { debug = false, enabled = true, guildThrottleDelay = 1, guildMaxNames = 8, events = { ownachievement = true, guildachievement = true, guildmemberachievement = false, friendsonly = true, faction = true, skills = true, quest = true, levelup = true, battlepetlevelup = true, guildchanges = true, }, output = { guild = false, self = false, channel = { }, }, } } end function EventAnnouncer:GetOptions() return { name = "Event Announcer", type = "group", args = { enabled = { name = "Enabled", desc = "Enable or disable the addon", type = "toggle", order = 1, get = function(key) return self.db.profile.enabled end, set = function(key, value) self.db.profile.enabled = value if self.db.profile.enabled then self:Enable() else self:Disable() end end, }, debug = { name = "Debug", desc = "Enable or disable debug output", type = "toggle", order = 2, get = function(key) return self.db.profile.debug end, set = function(key, value) self.db.profile.debug = value end, }, events = { name = "Events", type = "group", disabled = function() return not self.db.profile.enabled end, get = function(key) return self.db.profile.events[key.arg] end, set = function(key, value) self.db.profile.events[key.arg] = value if self.db.profile.enabled then self:ApplySettings() end end, args = { ownachievement = { name = "Own achievements", desc = "Send an alert when you gain an achievement", order = 1, type = "toggle", width = "full", arg = "ownachievement", }, guildachievement = { name = "Guild achievements", desc = "Send an alert when your guild gains an achievement or level", order = 2, type = "toggle", width = "full", arg = "guildachievement", }, guildmemberachievement = { name = "Guildmember achievements", desc = "Send an alert when anyone in your guild gains an achievement", order = 3, type = "toggle", width = "full", arg = "guildmemberachievement", }, friendsonly = { name = "...but friends only", desc = "Limit the alerts on guildmember achievements to friends only", disabled = function() return not ( self.db.profile.events.guildmemberachievement and self.db.profile.enabled ) end, order = 4, type = "toggle", width = "full", arg = "friendsonly", }, faction = { name = "Faction standing changes", desc = "Send an alert when your status with any faction changes", order = 5, type = "toggle", width = "full", arg = "faction", }, skills = { name = "Skill/Tradeskill milestones", desc = "Send an alert when you gain a new skill or reach a milestone", order = 6, type = "toggle", width = "full", arg = "skills", }, levelup = { name = "Level-ups", desc = "Send an alert when you gain a level", order = 7, type = "toggle", width = "full", arg = "levelup", }, battlepetlevelup = { name = "Battle pet level-ups", desc = "Send an alert when your battle pet gains a level", order = 8, type = "toggle", width = "full", arg = "battlepetlevelup", }, guildchanges = { name = "Guild joins/quits", desc = "Send an alert when you join or leave a guild", order = 9, type = "toggle", width = "full", arg = "guildchanges", }, }, }, output = { name = "Output", type = "group", disabled = function() return not self.db.profile.enabled end, get = function(key) return self.db.profile.output[key.arg] end, set = function(key, value) self.db.profile.output[key.arg] = value end, args = { self = { name = "Chat frame", desc = "Outputs a message to the default chat frame", order = 1, type = "toggle", arg = "self", width = "full", }, guild = { name = "Guild", desc = "Sends a message to guild chat", order = 2, confirm = true, confirmText = "This could cause a lot of spam in guild chat, are you sure you want this?", type = "toggle", arg = "guild", width = "full", }, custom = { name = "Custom channel", order = 3, type = "multiselect", width = "full", values = function() return self:GetCustomChannelList() end, get = function(info, nr) local _,name = GetChannelName(nr) return self:IsChannelEnabled(name) end, set = function(info, nr, value) local _,name = GetChannelName(nr) self:EnableChannel(name, value) end, }, }, }, }, } end function EventAnnouncer:GetCustomChannelList() local channels = { GetChannelList() } local out = {} for i = 1, table.getn(channels), 2 do out[channels[i]] = channels[i] .. ". " .. channels[i+1] end return out end function EventAnnouncer:IsChannelEnabled(name) return self.db.profile.output.channel[name] end function EventAnnouncer:EnableChannel(name, value) if value and not self.db.profile.output.channel[name] then self.db.profile.output.channel[name] = true elseif not value and self.db.profile.output.channel[name] then self.db.profile.output.channel[name] = false end end