From 4b90509e1b946a47f98b2ab68352186539b34f84 Mon Sep 17 00:00:00 2001 From: Peter Eliasson Date: Fri, 16 Jan 2015 17:53:16 +0100 Subject: [PATCH] Refactored the dependency on Skada to be replacable. * Changed to using a module-based approach for the parses. This means that it should be possible to support additional damage mods in the future, like Recount. * Added a parse provider module for Skada, with much the same functionallity as was previously done in the main file. * Changed from ending encounters after Skada's EndSegment to using the ENCOUNTER_END event. The ENCOUNTER_END should be reliable (the ENCOUNTER_START does seem to have issues still though). --- GuildSkadaHighScore.toc | 4 +- src/main.lua | 79 +++++++------------- src/parse_modules/parse_modules_core.lua | 105 +++++++++++++++++++++++++++ src/parse_modules/parse_modules_include.xml | 4 + src/parse_modules/skada.lua | 88 ++++++++++++++++++++++ src/src_include.xml | 1 + 6 files changed, 228 insertions(+), 53 deletions(-) create mode 100644 src/parse_modules/parse_modules_core.lua create mode 100644 src/parse_modules/parse_modules_include.xml create mode 100644 src/parse_modules/skada.lua diff --git a/GuildSkadaHighScore.toc b/GuildSkadaHighScore.toc index c6c6c00..70c0f0a 100644 --- a/GuildSkadaHighScore.toc +++ b/GuildSkadaHighScore.toc @@ -1,10 +1,10 @@ ## Interface: 60000 ## Author: Verath (Peter Eliasson) -## Version: 0.0.2 +## Version: 0.0.3 ## Title: Guild Skada High Score ## Notes: Tracking and ranking of dps/hps in a guild. ## SavedVariables: GuildSkadaHighScoreDB -## Dependencies: Skada +## Dependencies: lib\lib_include.xml src\src_include.xml diff --git a/src/main.lua b/src/main.lua index 1bbcf1a..c9360a7 100644 --- a/src/main.lua +++ b/src/main.lua @@ -4,7 +4,7 @@ local tinsert = tinsert; local tremove = tremove; -- Create ACE3 addon -local addon = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0") +local addon = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceConsole-3.0", "AceEvent-3.0") tinsert(addonTable, addon); _G[addonName] = addon @@ -130,16 +130,33 @@ function addon:GetGuildPlayersFromSet(skadaSet) return players end -function addon:SetRoleForPlayers(players) - for _, player in ipairs(players) do - player.role = UnitGroupRolesAssigned(player.name); +function addon:OnEncounterEndSuccess() + self:Debug("OnEncounterEndSuccess") + + local guildName = self.guildName; + if not guildName then + self:Debug("Not in a guild"); + return; end -end -function addon:SetClassForPlayers(players) - for _, player in ipairs(players) do - player.class = UnitClass(player.name); + local encounter = self.currentEncounter; + if not encounter then + self:Debug("No current encounter"); + return end + + local pmc = self.parseModulesCore; + pmc:GetParsesForEncounter(encounter, function(success, startTime, duration, players) + if not success then return end; + + encounter.startTime = startTime; + encounter.duration = duration; + self.inspect:GetInspectDataForPlayers(players, function() + self.highscore:AddEncounterParsesForPlayers(guildName, encounter, players); + end) + end) + + self:UnsetCurrentEncounter(); end function addon:PLAYER_GUILD_UPDATE(evt, unitId) @@ -156,9 +173,10 @@ end function addon:ENCOUNTER_END(evt, encounterId, encounterName, difficultyId, raidSize, endStatus) self:Debug("ENCOUNTER_END", encounterId, encounterName, difficultyId, raidSize, endStatus) if endStatus == 1 then -- Success - self:SetCurrentEncounter(encounterId, encounterName, difficultyId, raidSize) + self:SetCurrentEncounter(encounterId, encounterName, difficultyId, raidSize); + self:OnEncounterEndSuccess(); else - self:UnsetCurrentEncounter() + self:UnsetCurrentEncounter(); end end @@ -166,43 +184,6 @@ function addon:ZONE_CHANGED_NEW_AREA(evt) self:UpdateCurrentZone(); end -function addon:EndSegment() - self:Debug("EndSegment") - - -- Find the skada set matching the encounter - -- Looking only at the lastest set should make sense, - -- as that set should be the boss segment we just ended. - local _, skadaSet = next(Skada:GetSets()); - local encounter = self.currentEncounter; - - if not self.guildName then - self:Debug("Not in a guild"); - return; - end - - if not encounter then - self:Debug("No current encounter"); - return - end - - if not skadaSet or not skadaSet.gotboss or skadaSet.mobname ~= encounter.name then - self:Debug("No Skada set found for boss"); - return; - end - - encounter.duration = skadaSet.time; - encounter.startTime = skadaSet.starttime; - - local players = self:GetGuildPlayersFromSet(skadaSet); - self:SetRoleForPlayers(players); - self:SetClassForPlayers(players); - self.inspect:GetInspectDataForPlayers(players, function() - self.highscore:AddEncounterParsesForPlayers(self.guildName, encounter, players); - end) - - self:UnsetCurrentEncounter(); -end - function addon:OnInitialize() self.db = LibStub("AceDB-3.0"):New("GuildSkadaHighScoreDB", addon.dbDefaults, true) @@ -237,8 +218,6 @@ function addon:OnEnable() self:RegisterEvent("PLAYER_GUILD_UPDATE") self:RegisterEvent("ZONE_CHANGED_NEW_AREA") - self:SecureHook(Skada, "EndSegment") - self:RegisterChatCommand("gshs", function() self.gui:ShowMainFrame(); end) @@ -257,7 +236,5 @@ function addon:OnDisable() self:UnregisterEvent("PLAYER_GUILD_UPDATE") self:UnregisterEvent("ZONE_CHANGED_NEW_AREA") - self:UnHook(Skada, "EndSegment"); - self:UnregisterChatCommand("gshs"); end diff --git a/src/parse_modules/parse_modules_core.lua b/src/parse_modules/parse_modules_core.lua new file mode 100644 index 0000000..ff21f3f --- /dev/null +++ b/src/parse_modules/parse_modules_core.lua @@ -0,0 +1,105 @@ +-- +-- The parseModulesCore is a container module for our +-- parse provider modules. +-- + +local addonName, addonTable = ... +local addon = addonTable[1]; + +-- Global functions for faster access +local tinsert = tinsert; + +-- Create the parseModulesCore +local pmc = addon:NewModule("parseModulesCore") +addon.parseModulesCore = pmc; + +-- Set up the prototype for parse providers +do + local proto = {} + + function proto:Debug(...) + pmc:Debug(...); + end + + -- Function called by the Parse Module Core to determine + -- if this module can be enabled or not. Should test that + -- all dependencies are loaded. + function proto:IsActivatable() + return false; + end + + -- Function that must be called for each player before it + -- can be included in the parses returned. + -- Returns true if the player should be included. + function proto:ShouldIncludePlayer(playerId, playerName) + return addon:IsInMyGuild(playerName); + end + + -- Should get a list of player parses for the specified encounter. + -- + -- The callback function should be called with (success, startTime, duration, parses) + -- success - boolean indicating if parses were found. + -- startTime - the time when the encounter started. + -- duration - the time in seconds of the encounter. + -- players - list of player parse objects ({id="", name="", damage=0, healing=0}) + -- of players passing the ShouldIncludePlayer test. + -- + -- Params: + -- encounter - An object describing the encounter with the following keys: + -- zoneId, zoneName, id, name, difficultyId, difficultyName, raidSize + -- callback - The function to be called when the parse is ready. + function proto:GetParsesForEncounter(encounter, callback) + callback(false); + end + + pmc:SetDefaultModulePrototype(proto); + -- Parse provider modules are disabled by default, + -- as only one should be used at a time + pmc:SetDefaultModuleState(false); +end + + +local function setAdditionalDataForPlayers(players) + for _, player in ipairs(players) do + player.role = UnitGroupRolesAssigned(player.name); + player.class = UnitClass(player.name); + end +end + +-- Function for getting parses for an encounter. This +-- function will forward the call to the selected parse +-- provider if available. Will also add additional information +-- like spec and role to successful parse fetches +function pmc:GetParsesForEncounter(encounter, callback) + local parseProvider = self.selectedParseProvider + if parseProvider then + parseProvider:GetParsesForEncounter(encounter, function(success, startTime, duration, players) + if success then + setAdditionalDataForPlayers(players); + end + callback(success, startTime, duration, players); + end); + else + callback(false); + end +end + +function pmc:SelectParseProvider() + for name, mod in self:IterateModules() do + if mod:IsActivatable() then + self:Debug("Using " .. name .. " as parse provider."); + self.selectedParseProvider = mod; + mod:Enable(); + break; + end + end +end + +function pmc:OnEnable() + self.selectedParseProvider = nil; + self:SelectParseProvider(); +end + +function pmc:OnDisable() + self.selectedParseProvider = nil; +end \ No newline at end of file diff --git a/src/parse_modules/parse_modules_include.xml b/src/parse_modules/parse_modules_include.xml new file mode 100644 index 0000000..747f042 --- /dev/null +++ b/src/parse_modules/parse_modules_include.xml @@ -0,0 +1,4 @@ + +