yellowfive@57: local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot") yellowfive@57: local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true) yellowfive@57: local AceGUI = LibStub("AceGUI-3.0") yellowfive@57: yellowfive@133: local _lblLogging = nil yellowfive@57: local _btnToggle = nil yellowfive@57: local _panelUndoWipe = nil yellowfive@57: local _chkAutoAll = nil yellowfive@57: local _autoChecks = nil yellowfive@57: yellowfive@159: local function createDifficultyCheckBox(instanceId, difficultyId, container) yellowfive@57: local chk = AceGUI:Create("AmrUiCheckBox") yellowfive@159: container:AddChild(chk) yellowfive@57: chk:SetText(L.DifficultyNames[difficultyId]) yellowfive@57: chk:SetCallback("OnClick", function(widget) yellowfive@57: Amr:ToggleAutoLog(instanceId, difficultyId) yellowfive@57: end) yellowfive@57: yellowfive@57: _autoChecks[instanceId][difficultyId] = chk yellowfive@57: return chk yellowfive@57: end yellowfive@57: yellowfive@57: -- render a group of controls for auto-logging of a raid zone yellowfive@137: local function renderAutoLogSection(instanceId, container, i, autoLbls, autoChks) yellowfive@57: _autoChecks[instanceId] = {} yellowfive@57: yellowfive@57: local lbl = AceGUI:Create("AmrUiLabel") yellowfive@124: container:AddChild(lbl) yellowfive@57: lbl:SetWidth(200) yellowfive@57: lbl:SetText(L.InstanceNames[instanceId]) yellowfive@57: lbl:SetFont(Amr.CreateFont("Regular", 20, Amr.Colors.White)) yellowfive@57: yellowfive@137: if i == 1 then yellowfive@137: lbl:SetPoint("TOPLEFT", _chkAutoAll.frame, "BOTTOMLEFT", -1, -15) yellowfive@137: elseif i % 2 == 0 then yellowfive@137: lbl:SetPoint("TOPLEFT", autoLbls[i - 1].frame, "TOPRIGHT", 40, 0) yellowfive@137: else yellowfive@137: lbl:SetPoint("TOPLEFT", autoChks[i - 2].frame, "BOTTOMLEFT", 0, -30) yellowfive@137: end yellowfive@137: yellowfive@57: local line = AceGUI:Create("AmrUiPanel") yellowfive@137: container:AddChild(line) yellowfive@57: line:SetHeight(1) yellowfive@57: line:SetBackgroundColor(Amr.Colors.White) yellowfive@57: line:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 1, -7) yellowfive@57: line:SetPoint("TOPRIGHT", lbl.frame, "BOTTOMRIGHT", 0, -7) yellowfive@57: yellowfive@159: local chkMythic = createDifficultyCheckBox(instanceId, Amr.Difficulties.Mythic, container) yellowfive@57: chkMythic:SetPoint("TOPLEFT", line.frame, "BOTTOMLEFT", 0, -8) yellowfive@159: yellowfive@159: local chkNormal = createDifficultyCheckBox(instanceId, Amr.Difficulties.Normal, container) yellowfive@57: chkNormal:SetPoint("TOPLEFT", line.frame, "BOTTOMLEFT", 0, -30) yellowfive@137: yellowfive@57: -- find the widest of mythic/normal yellowfive@57: local w = math.max(chkMythic:GetWidth(), chkNormal:GetWidth()) yellowfive@57: yellowfive@159: local chkHeroic = createDifficultyCheckBox(instanceId, Amr.Difficulties.Heroic, container) yellowfive@57: chkHeroic:SetPoint("TOPLEFT", line.frame, "BOTTOMLEFT", w + 20, -8) yellowfive@57: yellowfive@159: local chkLfr = createDifficultyCheckBox(instanceId, Amr.Difficulties.Lfr, container) yellowfive@57: chkLfr:SetPoint("TOPLEFT", line.frame, "BOTTOMLEFT", w + 20, -30) yellowfive@137: yellowfive@61: return lbl, chkNormal yellowfive@57: end yellowfive@57: yellowfive@57: -- renders the main UI for the Combat Log tab yellowfive@57: function Amr:RenderTabLog(container) yellowfive@57: yellowfive@57: -- main commands yellowfive@57: _btnToggle = AceGUI:Create("AmrUiButton") yellowfive@159: container:AddChild(_btnToggle) yellowfive@57: _btnToggle:SetText(L.LogButtonStartText) yellowfive@57: _btnToggle:SetBackgroundColor(Amr.Colors.Green) yellowfive@57: _btnToggle:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White)) yellowfive@57: _btnToggle:SetWidth(200) yellowfive@57: _btnToggle:SetHeight(26) yellowfive@57: _btnToggle:SetCallback("OnClick", function() Amr:ToggleLogging() end) yellowfive@124: _btnToggle:SetPoint("TOPLEFT", container.content, "TOPLEFT", 0, -40) yellowfive@57: yellowfive@57: _lblLogging = AceGUI:Create("AmrUiLabel") yellowfive@124: container:AddChild(_lblLogging) yellowfive@57: _lblLogging:SetText(L.LogNote) yellowfive@57: _lblLogging:SetWidth(200) yellowfive@57: _lblLogging:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.BrightGreen)) yellowfive@57: _lblLogging:SetJustifyH("MIDDLE") yellowfive@57: _lblLogging:SetPoint("TOP", _btnToggle.frame, "BOTTOM", 0, -5) yellowfive@57: yellowfive@57: local btnReload = AceGUI:Create("AmrUiButton") yellowfive@159: container:AddChild(btnReload) yellowfive@57: btnReload:SetText(L.LogButtonReloadText) yellowfive@57: btnReload:SetBackgroundColor(Amr.Colors.Blue) yellowfive@57: btnReload:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White)) yellowfive@57: btnReload:SetWidth(200) yellowfive@57: btnReload:SetHeight(26) yellowfive@57: btnReload:SetCallback("OnClick", ReloadUI) yellowfive@124: btnReload:SetPoint("TOPLEFT", _btnToggle.frame, "TOPRIGHT", 40, 0) yellowfive@57: yellowfive@91: --[[ yellowfive@57: local lbl = AceGUI:Create("AmrUiLabel") yellowfive@57: lbl:SetText(L.LogReloadNote) yellowfive@57: lbl:SetWidth(200) yellowfive@57: lbl:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan)) yellowfive@57: lbl:SetJustifyH("MIDDLE") yellowfive@57: lbl:SetPoint("TOP", btnReload.frame, "BOTTOM", 0, -5) yellowfive@57: container:AddChild(lbl) yellowfive@57: yellowfive@57: -- container for undo wipe so we can hide/show it all yellowfive@57: _panelUndoWipe = AceGUI:Create("AmrUiPanel") yellowfive@57: _panelUndoWipe:SetLayout("None") yellowfive@57: _panelUndoWipe:SetBackgroundColor(Amr.Colors.Black, 0) yellowfive@57: _panelUndoWipe:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -40) yellowfive@57: container:AddChild(_panelUndoWipe) yellowfive@57: yellowfive@57: local btnUndoWipe = AceGUI:Create("AmrUiButton") yellowfive@57: btnUndoWipe:SetText(L.LogButtonUndoWipeText) yellowfive@57: btnUndoWipe:SetBackgroundColor(Amr.Colors.Orange) yellowfive@57: btnUndoWipe:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White)) yellowfive@57: btnUndoWipe:SetWidth(200) yellowfive@57: btnUndoWipe:SetHeight(26) yellowfive@57: btnUndoWipe:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -40) yellowfive@57: btnUndoWipe:SetCallback("OnClick", function() Amr:UndoWipe() end) yellowfive@57: _panelUndoWipe:AddChild(btnUndoWipe) yellowfive@57: yellowfive@57: lbl = AceGUI:Create("AmrUiLabel") yellowfive@57: lbl:SetText(L.LogUndoWipeNote) yellowfive@57: lbl:SetWidth(200) yellowfive@57: lbl:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan)) yellowfive@57: lbl:SetJustifyH("MIDDLE") yellowfive@57: lbl:SetPoint("TOP", btnUndoWipe.frame, "BOTTOM", 0, -5) yellowfive@57: _panelUndoWipe:AddChild(lbl) yellowfive@57: yellowfive@57: local lbl2 = AceGUI:Create("AmrUiLabel") yellowfive@57: lbl2:SetText(L.LogUndoWipeDate(date("%B %d", time()), date("%I:%M %p", time()))) yellowfive@57: lbl2:SetWidth(200) yellowfive@57: lbl2:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan)) yellowfive@57: lbl2:SetJustifyH("MIDDLE") yellowfive@57: lbl2:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -2) yellowfive@57: _panelUndoWipe:AddChild(lbl2) yellowfive@57: yellowfive@57: local btnWipe = AceGUI:Create("AmrUiButton") yellowfive@57: btnWipe:SetText(L.LogButtonWipeText) yellowfive@57: btnWipe:SetBackgroundColor(Amr.Colors.Orange) yellowfive@57: btnWipe:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White)) yellowfive@57: btnWipe:SetWidth(200) yellowfive@57: btnWipe:SetHeight(26) yellowfive@57: btnWipe:SetPoint("TOPRIGHT", btnUndoWipe.frame, "TOPLEFT", -40, 0) yellowfive@57: btnWipe:SetCallback("OnClick", function() Amr:Wipe() end) yellowfive@57: container:AddChild(btnWipe) yellowfive@91: yellowfive@57: lbl = AceGUI:Create("AmrUiLabel") yellowfive@57: lbl:SetText(L.LogWipeNote) yellowfive@57: lbl:SetWidth(200) yellowfive@57: lbl:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan)) yellowfive@57: lbl:SetJustifyH("MIDDLE") yellowfive@57: lbl:SetPoint("TOP", btnWipe.frame, "BOTTOM", 0, -5) yellowfive@57: container:AddChild(lbl) yellowfive@57: yellowfive@57: lbl2 = AceGUI:Create("AmrUiLabel") yellowfive@57: lbl2:SetText(L.LogWipeNote2("/amr wipe")) yellowfive@57: lbl2:SetWidth(200) yellowfive@57: lbl2:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan)) yellowfive@57: lbl2:SetJustifyH("MIDDLE") yellowfive@57: lbl2:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -2) yellowfive@57: container:AddChild(lbl2) yellowfive@91: ]] yellowfive@57: yellowfive@57: -- auto-logging controls yellowfive@91: local lbl = AceGUI:Create("AmrUiLabel") yellowfive@124: container:AddChild(lbl) yellowfive@57: lbl:SetWidth(600) yellowfive@57: lbl:SetText(L.LogAutoTitle) yellowfive@57: lbl:SetFont(Amr.CreateFont("Bold", 24, Amr.Colors.TextHeaderActive)) yellowfive@91: lbl:SetPoint("TOPLEFT", _btnToggle.frame, "BOTTOMLEFT", 0, -40) yellowfive@57: yellowfive@57: _chkAutoAll = AceGUI:Create("AmrUiCheckBox") yellowfive@159: container:AddChild(_chkAutoAll) yellowfive@57: _chkAutoAll:SetText(L.LogAutoAllText) yellowfive@57: _chkAutoAll:SetCallback("OnClick", function(widget) Amr:ToggleAllAutoLog() end) yellowfive@124: _chkAutoAll:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 1, -15) yellowfive@57: yellowfive@57: _autoChecks = {} yellowfive@57: yellowfive@57: -- go through all supported instances, rendering in a left->right pattern, 2 per row yellowfive@61: local autoLbls = {} yellowfive@61: local autoChks = {} yellowfive@57: for i, instanceId in ipairs(Amr.InstanceIdsOrdered) do yellowfive@137: local autoLbl, autoChk = renderAutoLogSection(instanceId, container, i, autoLbls, autoChks) yellowfive@57: yellowfive@61: table.insert(autoLbls, autoLbl) yellowfive@61: table.insert(autoChks, autoChk) yellowfive@57: end yellowfive@124: autoLbls = nil yellowfive@124: autoChks = nil yellowfive@124: yellowfive@57: -- instructions yellowfive@91: --[[ yellowfive@57: lbl = AceGUI:Create("AmrUiLabel") yellowfive@57: lbl:SetText(L.LogInstructionsTitle) yellowfive@57: lbl:SetWidth(480) yellowfive@57: lbl:SetFont(Amr.CreateFont("Italic", 24, Amr.Colors.Text)) yellowfive@57: lbl:SetPoint("TOPRIGHT", container.content, "TOPRIGHT", 0, -40) yellowfive@57: container:AddChild(lbl) yellowfive@57: yellowfive@57: lbl2 = AceGUI:Create("AmrUiLabel") yellowfive@57: lbl2:SetText(L.LogInstructions) yellowfive@57: lbl2:SetWidth(480) yellowfive@57: lbl2:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.Text)) yellowfive@57: lbl2:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -10) yellowfive@57: container:AddChild(lbl2) yellowfive@91: ]] yellowfive@57: yellowfive@57: -- initialize state of controls yellowfive@57: Amr:RefreshLogUi() yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:ReleaseTabLog() yellowfive@133: _lblLogging = nil yellowfive@57: _btnToggle = nil yellowfive@57: _panelUndoWipe = nil yellowfive@57: _chkAutoAll = nil yellowfive@57: _autoChecks = nil yellowfive@57: end yellowfive@57: yellowfive@69: -- update the game's logging state yellowfive@69: local function updateGameLogging(enabled) yellowfive@69: if enabled then yellowfive@69: -- always enable advanced combat logging via our addon, gathers more detailed data for better analysis yellowfive@69: SetCVar("advancedCombatLogging", 1) yellowfive@69: LoggingCombat(true) yellowfive@69: else yellowfive@69: LoggingCombat(false) yellowfive@69: end yellowfive@69: end yellowfive@69: yellowfive@69: local function isAnyAutoLoggingEnabled() yellowfive@69: local anyChecked = false yellowfive@69: for i, instanceId in ipairs(Amr.InstanceIdsOrdered) do yellowfive@69: for k, difficultyId in pairs(Amr.Difficulties) do yellowfive@69: if Amr.db.profile.Logging.Auto[instanceId][difficultyId] then yellowfive@69: anyChecked = true yellowfive@69: break yellowfive@69: end yellowfive@69: end yellowfive@69: if anyChecked then break end yellowfive@69: end yellowfive@69: yellowfive@69: return anyChecked yellowfive@69: end yellowfive@69: yellowfive@57: local function isAllAutoLoggingEnabled() yellowfive@57: -- see if all auto-logging options are enabled yellowfive@57: local allChecked = true yellowfive@57: for i, instanceId in ipairs(Amr.InstanceIdsOrdered) do yellowfive@57: for k, difficultyId in pairs(Amr.Difficulties) do yellowfive@57: if not Amr.db.profile.Logging.Auto[instanceId][difficultyId] then yellowfive@57: allChecked = false yellowfive@57: break yellowfive@57: end yellowfive@57: end yellowfive@57: if not allChecked then break end yellowfive@57: end yellowfive@57: yellowfive@57: return allChecked yellowfive@57: end yellowfive@57: yellowfive@57: -- check current zone and auto-logging settings, and enable logging if appropriate yellowfive@69: local function updateAutoLogging(force, noWait) yellowfive@69: yellowfive@69: local hasAuto = isAnyAutoLoggingEnabled() yellowfive@69: yellowfive@69: -- before doing anything, make sure logging matches the user's current setting, deals with any inconsistency due to a crash or disconnect yellowfive@69: if hasAuto then yellowfive@69: updateGameLogging(Amr:IsLogging()) yellowfive@69: end yellowfive@57: yellowfive@57: -- get the info about the instance yellowfive@57: local zone, _, difficultyId, _, _, _, _, instanceId = GetInstanceInfo() yellowfive@57: yellowfive@69: if Amr.IsSupportedInstanceId(instanceId) and difficultyId == 0 and not noWait then yellowfive@69: -- the game is sometimes returning no difficulty id for raid zones... not sure why, wait 10 seconds and check again yellowfive@69: Amr.Wait(10, function() yellowfive@69: updateAutoLogging(false, false) yellowfive@69: end) yellowfive@69: return yellowfive@69: end yellowfive@69: yellowfive@57: if not force and zone == Amr.db.char.Logging.LastZone and difficultyId == Amr.db.char.Logging.LastDiff then yellowfive@57: -- do nothing if the zone hasn't actually changed, otherwise we may override the user's manual enable/disable yellowfive@57: return yellowfive@57: end yellowfive@57: yellowfive@57: Amr.db.char.Logging.LastZone = zone yellowfive@57: Amr.db.char.Logging.LastDiff = difficultyId yellowfive@57: yellowfive@137: if Amr.IsSupportedInstanceId(instanceId) then yellowfive@137: if not Amr.db.profile.Logging.Auto[tonumber(instanceId)] then yellowfive@137: Amr.db.profile.Logging.Auto[tonumber(instanceId)] = {} yellowfive@137: end yellowfive@91: end yellowfive@91: yellowfive@57: if Amr.IsSupportedInstanceId(instanceId) and Amr.db.profile.Logging.Auto[tonumber(instanceId)][tonumber(difficultyId)] then yellowfive@57: -- we are in a supported zone that we want to auto-log, turn logging on yellowfive@69: yellowfive@57: -- (supported check is probably redundant, but just in case someone has old settings lying around) yellowfive@57: if not Amr:IsLogging() then yellowfive@57: Amr:StartLogging() yellowfive@57: end yellowfive@69: elseif hasAuto then yellowfive@57: -- not in a zone that we want to auto-log, turn logging off yellowfive@57: if Amr:IsLogging() then yellowfive@57: Amr:StopLogging() yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@189: -- sometimes the game doesn't repaint checkboxes when it should... doing this forces it to do so yellowfive@189: local function setCheckboxChecked(chk, val) yellowfive@189: chk:SetChecked(val) yellowfive@189: chk:SetChecked(not val) yellowfive@189: chk:SetChecked(val) yellowfive@189: chk:SetText(chk:GetText()) yellowfive@189: end yellowfive@189: yellowfive@57: -- refresh the state of the tab based on current settings yellowfive@57: function Amr:RefreshLogUi() yellowfive@57: if not _btnToggle then return end yellowfive@57: yellowfive@57: -- set state of logging button based on whether it is on or off yellowfive@57: if self:IsLogging() then yellowfive@57: _btnToggle:SetBackgroundColor(Amr.Colors.Red) yellowfive@57: _btnToggle:SetText(L.LogButtonStopText) yellowfive@57: else yellowfive@57: _btnToggle:SetBackgroundColor(Amr.Colors.Green) yellowfive@57: _btnToggle:SetText(L.LogButtonStartText) yellowfive@57: end yellowfive@57: yellowfive@57: _lblLogging:SetVisible(self:IsLogging()) yellowfive@57: yellowfive@57: -- hide/show undo wipe button based on whether a wipe has been called recently yellowfive@91: if _panelUndoWipe then yellowfive@91: _panelUndoWipe:SetVisible(Amr.db.char.Logging.LastWipe and true or false) yellowfive@91: end yellowfive@57: yellowfive@57: local all = isAllAutoLoggingEnabled() yellowfive@189: --setCheckboxChecked(_chkAutoAll, all) yellowfive@57: _chkAutoAll:SetChecked(all) yellowfive@57: yellowfive@57: for i, instanceId in ipairs(Amr.InstanceIdsOrdered) do yellowfive@91: if not Amr.db.profile.Logging.Auto[instanceId] then yellowfive@91: Amr.db.profile.Logging.Auto[instanceId] = {} yellowfive@91: end yellowfive@57: for k, difficultyId in pairs(Amr.Difficulties) do yellowfive@189: setCheckboxChecked(_autoChecks[instanceId][difficultyId], Amr.db.profile.Logging.Auto[instanceId][difficultyId]) yellowfive@189: --_autoChecks[instanceId][difficultyId]:SetChecked(Amr.db.profile.Logging.Auto[instanceId][difficultyId]) yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:IsLogging() yellowfive@57: return Amr.db.char.Logging.Enabled yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:ToggleLogging() yellowfive@57: if not Amr.db.char.Logging.Enabled then yellowfive@57: Amr:StartLogging() yellowfive@57: else yellowfive@57: Amr:StopLogging() yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:StartLogging() yellowfive@57: yellowfive@91: --[[ yellowfive@57: local now = time() yellowfive@57: local oldDuration = 60 * 60 * 24 * 10 yellowfive@57: yellowfive@57: -- prune out entries in log data that are more than 10 days old yellowfive@57: yellowfive@57: -- player data yellowfive@57: local playerData = Amr.db.global.Logging.PlayerData yellowfive@57: if playerData then yellowfive@57: for name, timeList in pairs(playerData) do yellowfive@57: for timestamp, dataString in pairs(timeList) do yellowfive@57: if difftime(now, tonumber(timestamp)) > oldDuration then yellowfive@57: timeList[timestamp] = nil yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: if next(timeList) == nil then yellowfive@57: playerData[name] = nil yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- same idea with extra info (auras, pets, whatever we end up adding to it) yellowfive@57: local extraData = Amr.db.global.Logging.PlayerExtras yellowfive@57: if extraData then yellowfive@57: for name, timeList in pairs(extraData) do yellowfive@57: for timestamp, dataString in pairs(timeList) do yellowfive@57: if difftime(now, tonumber(timestamp)) > oldDuration then yellowfive@57: timeList[timestamp] = nil yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: if next(timeList) == nil then yellowfive@57: extraData[name] = nil yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- delete wipes that are more than 10 days old yellowfive@57: if Amr.db.global.Logging.Wipes then yellowfive@57: local wipes = Amr.db.global.Logging.Wipes yellowfive@57: local i = 1 yellowfive@57: while i <= #wipes do yellowfive@57: local t = wipes[i] yellowfive@57: if difftime(now, t) > oldDuration then yellowfive@57: table.remove(wipes, i) yellowfive@57: else yellowfive@57: i = i + 1 yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- delete the last wipe date if it is more than 10 days old yellowfive@57: if Amr.db.char.Logging.LastWipe and difftime(now, Amr.db.char.Logging.LastWipe) > oldDuration then yellowfive@57: Amr.db.char.Logging.LastWipe = nil yellowfive@57: end yellowfive@91: ]] yellowfive@91: yellowfive@69: -- enable game log file yellowfive@69: updateGameLogging(true) yellowfive@57: Amr.db.char.Logging.Enabled = true yellowfive@57: yellowfive@57: self:Print(L.LogChatStart) yellowfive@57: yellowfive@57: self:UpdateMinimap() yellowfive@57: self:RefreshLogUi() yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:StopLogging() yellowfive@57: yellowfive@69: updateGameLogging(false) yellowfive@57: Amr.db.char.Logging.Enabled = false yellowfive@57: yellowfive@57: self:Print(L.LogChatStop) yellowfive@57: yellowfive@57: self:UpdateMinimap() yellowfive@57: self:RefreshLogUi() yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:Wipe() yellowfive@91: yellowfive@91: --[[ yellowfive@57: local t = time() yellowfive@57: table.insert(Amr.db.global.Logging.Wipes, t) yellowfive@57: Amr.db.char.Logging.LastWipe = t yellowfive@57: yellowfive@57: self:Print(L.LogChatWipe(date('%I:%M %p', t))) yellowfive@57: yellowfive@57: self:RefreshLogUi() yellowfive@91: ]] yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:UndoWipe() yellowfive@57: yellowfive@91: --[[ yellowfive@57: local t = Amr.db.char.Logging.LastWipe yellowfive@57: local wipes = Amr.db.global.Logging.Wipes yellowfive@57: yellowfive@57: if not t then yellowfive@57: self:Print(L.LogChatNoWipes) yellowfive@57: else yellowfive@57: -- find this wipe and remove it, may not be the last one if this person is raiding on multiple characters yellowfive@57: for i = #wipes, 1, -1 do yellowfive@57: if wipes[i] == t then yellowfive@57: table.remove(wipes, i) yellowfive@57: break yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: Amr.db.char.Logging.LastWipe = nil yellowfive@57: self:Print(L.LogChatUndoWipe(date('%I:%M %p', t))) yellowfive@57: end yellowfive@57: yellowfive@57: self:RefreshLogUi() yellowfive@91: ]] yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:ToggleAutoLog(instanceId, difficultyId) yellowfive@57: yellowfive@57: local byDiff = Amr.db.profile.Logging.Auto[instanceId] yellowfive@57: byDiff[difficultyId] = not byDiff[difficultyId] yellowfive@57: yellowfive@57: self:RefreshLogUi() yellowfive@57: yellowfive@57: -- see if we should turn logging on right now yellowfive@57: updateAutoLogging(true) yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:ToggleAllAutoLog() yellowfive@57: yellowfive@57: local val = not isAllAutoLoggingEnabled() yellowfive@57: yellowfive@57: for i, instanceId in ipairs(Amr.InstanceIdsOrdered) do yellowfive@57: for k, difficultyId in pairs(Amr.Difficulties) do yellowfive@57: Amr.db.profile.Logging.Auto[instanceId][difficultyId] = val yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: self:RefreshLogUi() yellowfive@57: yellowfive@57: -- see if we should turn logging on right now yellowfive@57: updateAutoLogging(true) yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:ProcessPlayerSnapshot(msg) yellowfive@91: --[[ yellowfive@57: if not self:IsLogging() then return end yellowfive@57: yellowfive@57: -- message will be of format: timestamp\nregion\nrealm\nname\n[stuff] yellowfive@57: local parts = {} yellowfive@57: for part in string.gmatch(msg, "([^\n]+)") do yellowfive@57: table.insert(parts, part) yellowfive@57: end yellowfive@57: yellowfive@57: local timestamp = tonumber(parts[1]) yellowfive@57: local name = parts[2] .. ":" .. parts[3] .. ":" .. parts[4] yellowfive@57: local setup = parts[5] yellowfive@57: yellowfive@57: -- initialize the player's table yellowfive@57: local playerList = Amr.db.global.Logging.PlayerData[name] yellowfive@57: if not playerList then yellowfive@57: playerList = {} yellowfive@57: Amr.db.global.Logging.PlayerData[name] = playerList yellowfive@57: end yellowfive@57: yellowfive@57: -- find the most recent setup already recorded for this player yellowfive@57: local previousSetup = nil yellowfive@57: local previousTime = 0 yellowfive@57: for t, v in pairs(playerList) do yellowfive@57: if t > previousTime then yellowfive@57: previousSetup = v yellowfive@57: previousTime = t yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- if the previous setup is more than 12 hours old, don't consider it yellowfive@57: if previousSetup and difftime(timestamp, previousTime) > 60 * 60 * 12 then yellowfive@57: previousSetup = nil yellowfive@57: end yellowfive@57: yellowfive@57: -- we only need to keep this setup if it is different than the previous yellowfive@57: if setup ~= previousSetup then yellowfive@57: playerList[timestamp] = setup yellowfive@57: end yellowfive@91: ]] yellowfive@57: end yellowfive@57: yellowfive@57: -- read auras and pet mapping info (pet may not be necessary anymore... but doesn't hurt) yellowfive@57: local function getPlayerExtraData(data, unitId, petId) yellowfive@91: --[[ yellowfive@57: local guid = UnitGUID(unitId) yellowfive@57: if guid == nil then return end yellowfive@57: yellowfive@57: local fields = {} yellowfive@57: yellowfive@57: local buffs = {} yellowfive@57: for i=1,40 do yellowfive@57: local _,_,_,count,_,_,_,_,_,_,spellId = UnitAura(unitId, i, "HELPFUL") yellowfive@57: table.insert(buffs, spellId) yellowfive@57: end yellowfive@57: if not buffs or #buffs == 0 then yellowfive@57: table.insert(fields, "_") yellowfive@57: else yellowfive@57: table.insert(fields, Amr.Serializer:ToCompressedNumberList(buffs)) yellowfive@57: end yellowfive@57: yellowfive@57: local petGuid = UnitGUID(petId) yellowfive@57: if petGuid then yellowfive@57: table.insert(fields, guid .. "," .. petGuid) yellowfive@57: else yellowfive@57: table.insert(fields, '_') yellowfive@57: end yellowfive@57: yellowfive@57: local name = GetUnitName(unitId, true) -- GetRaidRosterInfo(rosterIndex) yellowfive@57: local realm = GetRealmName() yellowfive@57: local region = Amr.RegionNames[GetCurrentRegion()] yellowfive@57: local splitPos = string.find(name, "-") yellowfive@57: if splitPos ~= nil then yellowfive@57: realm = string.sub(name, splitPos + 1) yellowfive@57: name = string.sub(name, 1, splitPos - 1) yellowfive@57: end yellowfive@57: yellowfive@57: data[region .. ":" .. realm .. ":" .. name] = table.concat(fields, ";") yellowfive@91: ]] yellowfive@57: end yellowfive@57: yellowfive@57: local function logPlayerExtraData() yellowfive@91: --[[ yellowfive@57: if not Amr:IsLogging() or not Amr:IsSupportedInstance() then return end yellowfive@57: yellowfive@57: local timestamp = time() yellowfive@57: local units = {} yellowfive@57: local petUnits = {} yellowfive@57: yellowfive@57: if IsInRaid() then yellowfive@57: for i = 1,40 do yellowfive@57: table.insert(units, "raid" .. i) yellowfive@57: table.insert(petUnits, "raidpet" .. i) yellowfive@57: end yellowfive@57: elseif IsInGroup() then yellowfive@57: table.insert(units, "player") yellowfive@57: table.insert(petUnits, "pet") yellowfive@57: for i = 1,4 do yellowfive@57: table.insert(units, "party" .. i) yellowfive@57: table.insert(petUnits, "partypet" .. i) yellowfive@57: end yellowfive@57: else yellowfive@57: return yellowfive@57: end yellowfive@57: yellowfive@57: local data = {} yellowfive@57: for i = 1,#units do yellowfive@57: getPlayerExtraData(data, units[i], petUnits[i]) yellowfive@57: end yellowfive@57: yellowfive@57: for name, val in pairs(data) do yellowfive@57: -- record aura stuff, we never check for duplicates, need to know it at each point in time yellowfive@57: if Amr.db.global.Logging.PlayerExtras[name] == nil then yellowfive@57: Amr.db.global.Logging.PlayerExtras[name] = {} yellowfive@57: end yellowfive@57: Amr.db.global.Logging.PlayerExtras[name][timestamp] = val yellowfive@57: end yellowfive@91: ]] yellowfive@57: end yellowfive@57: yellowfive@57: function Amr:InitializeCombatLog() yellowfive@137: updateAutoLogging() yellowfive@57: end yellowfive@57: yellowfive@57: Amr:AddEventHandler("UPDATE_INSTANCE_INFO", updateAutoLogging) yellowfive@57: Amr:AddEventHandler("PLAYER_DIFFICULTY_CHANGED", updateAutoLogging) yellowfive@65: Amr:AddEventHandler("ENCOUNTER_START", updateAutoLogging) yellowfive@122: --Amr:AddEventHandler("PLAYER_REGEN_DISABLED", logPlayerExtraData)