--------------------------------------------------------------------------------- -- -- Prat - A framework for World of Warcraft chat mods -- -- Copyright (C) 2006-2018 Prat Development Team -- -- This program is free software; you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation; either version 2 -- of the License, or (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to: -- -- Free Software Foundation, Inc., -- 51 Franklin Street, Fifth Floor, -- Boston, MA 02110-1301, USA. -- -- ------------------------------------------------------------------------------- Prat:AddModuleExtension(function() local function dbg(...) end --[==[@debug@ function dbg(...) Prat:PrintLiteral(...) end --@end-debug@]==] local module = Prat.Addon:GetModule("History", true) if not module then return end local PL = module.PL module.pluginopts["GlobalPatterns"] = { scrollbackhistheader = { name = PL["Scrollback Options"], type = "header", order = 124, }, scrollback = { type = "toggle", name = PL["Scrollback"], desc = PL["Store the chat lines between sessions"], order = 125 }, scrollbackduration = { name = PL.scrollbackduration_name, desc = PL.scrollbackduration_desc, type = "range", order = 126, min = 0, max = 168, step = 1, bigStep = 24, disabled = function() return not module.db.profile.scrollback end }, removespam = { name = PL.removespam_name, desc = PL.removespam_desc, type = "toggle", order = 127, disabled = function() return not module.db.profile.scrollback end } } local orgOME = module.OnModuleEnable function module:OnModuleEnable(...) orgOME(self, ...) Prat3HighCPUPerCharDB = Prat3HighCPUPerCharDB Prat3HighCPUPerCharDB = Prat3HighCPUPerCharDB or {} Prat3HighCPUPerCharDB.scrollback = Prat3HighCPUPerCharDB.scrollback or {} self.scrollback = Prat3HighCPUPerCharDB.scrollback if self.db.profile.scrollback then self:RestoreLastSession() for k, v in pairs(Prat.HookedFrames) do self.scrollback[k] = v.historyBuffer if not self:IsHooked(v, "AddMessage") then self:SecureHook(v, "AddMessage") end end end Prat.RegisterChatEvent(self, Prat.Events.FRAMES_UPDATED) Prat.RegisterChatEvent(self, Prat.Events.FRAMES_REMOVED) end local orgOMD = module.OnModuleDisable function module:OnModuleDisable(...) orgOMD(self, ...) for name, v in pairs(Prat.HookedFrames) do if self:IsHooked(v, "AddMessage") then self:Unhook(v, "AddMessage") end self.scrollback[name] = nil end end function module:OnValueChanged(info, b) for k, v in pairs(Prat.HookedFrames) do if self.db.profile.scrollback then if not v.isTemporary then self.scrollback[k] = v.historyBuffer else self.scrollback[k] = nil end else self.scrollback[k] = nil end end end function module:Prat_FramesUpdated(_, name, chatFrame) if self.db.profile.scrollback and not chatFrame.isTemporary then self.scrollback[name] = chatFrame.historyBuffer end if not self:IsHooked(chatFrame, "AddMessage") then self:SecureHook(chatFrame, "AddMessage") end end function module:Prat_FramesRemoved(_, name, chatFrame) self.scrollback[name] = nil if self:IsHooked(chatFrame, "AddMessage") then self:Unhook(chatFrame, "AddMessage") end end function module:AddMessage(frame, text, ...) if self.db.profile.on and self.scrollback and self.scrollback[frame:GetName()] then if frame.historyBuffer:GetEntryAtIndex(1) then frame.historyBuffer:GetEntryAtIndex(1).serverTime = GetServerTime() end end end function module:GetEntryAtIndex(scrollback, index) if index > 0 and index <= #scrollback.elements then local globalIndex = scrollback.headIndex - index + 1; local elementIndex = (globalIndex - 1) % scrollback.maxElements + 1 return scrollback.elements[elementIndex]; end end local function isRealChatMessage(message) return message.extraData and message.extraData.n == #message.extraData end function getBattlettagLookupTable() local lookup = {} local numBNet = BNGetNumFriends(); for i = 1, numBNet do if C_BattleNet and C_BattleNet.GetFriendAccountInfo then local accountInfo = C_BattleNet.GetFriendAccountInfo(i); if accountInfo then lookup[accountInfo.battleTag] = accountInfo end else local bnetAccountID, accountName, battleTag = BNGetFriendInfo(i) local accountInfo = { bnetAccountID = bnetAccountID, accountName = accountName } if battleTag then lookup[battleTag] = accountInfo end end end return lookup end local battleTagLookup local function getBNPlayerLink(name, linkDisplayText, bnetIDAccount, lineID, chatType, chatTarget, battleTag) return Prat.FormatLink("BNplayer", linkDisplayText, name, bnetIDAccount, lineID or 0, chatType, chatTarget, battleTag); end local function updateBnet(data, display) battleTagLookup = battleTagLookup or getBattlettagLookupTable() local name, bnetIDAccount, _, chatType, chatTarget, battleTag = strsplit(":", data) if battleTag then local info = battleTagLookup[battleTag] if info then name, bnetIDAccount = info.accountName, info.bnetAccountID display = display:gsub(PL.bnet_removed, name) chatTarget = chatTarget:gsub(PL.bnet_removed, name) end end return getBNPlayerLink(name, display, bnetIDAccount, 0, chatType, chatTarget, battleTag) end function module:RestoreLastSession() local now, uptime, maxTime = GetServerTime(), GetTime(), self.db.profile.scrollbackduration * 60 * 60 for frame, scrollback in pairs(self.scrollback) do local f = _G[frame] if scrollback.elements and scrollback.headIndex and scrollback.maxElements and frame ~= "ChatFrame2" then if f and #scrollback.elements then local timeShown = false for i = 1, #scrollback.elements do local line = self:GetEntryAtIndex(scrollback, i) if line and type(line.message) == "string" and (not self.db.profile.removespam or isRealChatMessage(line)) then line.serverTime = line.serverTime or now line.timestamp = uptime if maxTime == 0 or (now - line.serverTime) <= maxTime then if not timeShown then f:BackFillMessage(PL.divider) f:BackFillMessage(format(TIME_DAYHOURMINUTESECOND, ChatFrame_TimeBreakDown(now - line.serverTime))) timeShown = true end line.message = line.message:gsub("|K.-|k", PL.bnet_removed) line.message = line.message:gsub([[|HBNplayer:(.-)|h(.-)|h]], updateBnet) f.historyBuffer:PushBack(line) end end end f:ResetAllFadeTimes() end end end end end)