diff --git a/2/3/4/5/6/7/ElvUI/Core/ClassCache.lua b/2/3/4/5/6/7/ElvUI/Core/ClassCache.lua
new file mode 100644
index 0000000..c28d86e
--- /dev/null
+++ b/2/3/4/5/6/7/ElvUI/Core/ClassCache.lua
@@ -0,0 +1,463 @@
+local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
+local CC = E:NewModule("ClassCache", "AceEvent-3.0");
+local LW = LibStub:GetLibrary("LibWho-2.0");
+
+--Cache global variables
+--Lua functions
+local split, upper = string.split, string.upper
+local wipe = table.wipe
+local pairs = pairs
+local select = select
+--WoW API / Variables
+local GetBattlefieldScore = GetBattlefieldScore
+local GetFriendInfo = GetFriendInfo
+local GetGuildRosterInfo = GetGuildRosterInfo
+local GetNumBattlefieldScores = GetNumBattlefieldScores
+local GetNumFriends = GetNumFriends
+local GetNumGuildMembers = GetNumGuildMembers
+local GetNumPartyMembers = GetNumPartyMembers
+local GetNumRaidMembers = GetNumRaidMembers
+local GetTime = GetTime
+local IsInGuild = IsInGuild
+local UnitClass = UnitClass
+local UnitExists = UnitExists
+local UnitIsPlayer = UnitIsPlayer
+local UnitName = UnitName
+
+local UNKNOWN = UNKNOWN
+
+local GAME_LOCALE = GetLocale()
+local ENGLISH_CLASS_NAMES
+
+local function GetEnglishClassName(class)
+ if class == UNKNOWN then
+ return class
+ elseif GAME_LOCALE == "enUS" then
+ return upper(class)
+ end
+
+ if not ENGLISH_CLASS_NAMES then
+ ENGLISH_CLASS_NAMES = {}
+
+ for english, localized in pairs(LOCALIZED_CLASS_NAMES_MALE) do
+ ENGLISH_CLASS_NAMES[localized] = english
+ end
+ for english, localized in pairs(LOCALIZED_CLASS_NAMES_FEMALE) do
+ ENGLISH_CLASS_NAMES[localized] = english
+ end
+ end
+
+ return ENGLISH_CLASS_NAMES[class]
+end
+
+local function WhoCallback(result)
+ if result then
+ if result.NoLocaleClass then
+ CC:CachePlayer(result.Name, result.NoLocaleClass)
+ CC:SendMessage("ClassCacheQueryResult", result.Name, result.NoLocaleClass)
+ end
+ end
+end
+
+function CC:GetClassByName(name, realm)
+ if not name or name == "" then return end
+ if realm and realm == "" then return end
+
+ if E.db.general.classCacheStoreInDB then
+ if realm then
+ if self.cache[realm] and self.cache[realm][name] then
+ return self.cache[realm][name]
+ else
+ return
+ end
+ else
+ if self.cache[E.myrealm][name] then
+ return self.cache[E.myrealm][name]
+ end
+ end
+ else
+ if realm then
+ if self.tempCache[realm] and self.tempCache[realm][name] then
+ return self.tempCache[realm][name]
+ else
+ return
+ end
+ else
+ if self.tempCache[E.myrealm][name] then
+ return self.tempCache[E.myrealm][name]
+ end
+ end
+ end
+
+ if E.db.general.classCacheRequestInfo then
+ local result = LW:UserInfo(name, {
+ queue = LW.WHOLIB_QUEUE_QUIET,
+ timeout = 0,
+ callback = function(result)
+ WhoCallback(result)
+ end
+ })
+
+ if result and result.NoLocaleClass then
+ self:CachePlayer(result.Name, result.NoLocaleClass)
+ return result.NoLocaleClass
+ end
+ end
+end
+
+function CC:CachePlayer(name, class, realm)
+ if not (name and class and class ~= UNKNOWN) then return end
+
+ if realm and realm == "" then return end
+
+ if E.db.general.classCacheStoreInDB then
+ if realm and not self.cache[realm] then
+ self.cache[realm] = {}
+ end
+
+ if realm then
+ self.cache[realm][name] = class
+ else
+ self.cache[E.myrealm][name] = class
+ end
+ else
+ if realm and not self.tempCache[realm] then
+ self.tempCache[realm] = {}
+ end
+
+ if realm then
+ self.tempCache[realm][name] = class
+ else
+ self.tempCache[E.myrealm][name] = class
+ end
+ end
+end
+
+function CC:SwitchCacheType(init)
+ if E.db.general.classCacheStoreInDB then
+ if not self.cache[E.myrealm] then
+ self.cache[E.myrealm] = {}
+ end
+
+ if not self.cache[E.myrealm][E.myname] then
+ self.cache[E.myrealm][E.myname] = E.myclass
+ end
+
+ if not init then
+ for realm in pairs(self.tempCache) do
+ if not self.cache[realm] then
+ self.cache[realm] = {}
+ end
+
+ for name, class in pairs(self.tempCache[realm]) do
+ self.cache[realm][name] = class
+ end
+ end
+ end
+ else
+ if not self.tempCache[E.myrealm] then
+ self.tempCache[E.myrealm] = {}
+ end
+
+ if not self.tempCache[E.myrealm][E.myname] then
+ self.tempCache[E.myrealm][E.myname] = E.myclass
+ end
+
+ if not init then
+ for realm in pairs(self.cache) do
+ if not self.cache[realm] then
+ self.tempCache[realm] = {}
+ end
+
+ for name, class in pairs(self.cache[realm]) do
+ self.tempCache[realm][name] = class
+ end
+ end
+ end
+ end
+end
+
+function CC:GetCacheTable()
+ if E.db.general.classCacheStoreInDB then
+ return self.cache
+ else
+ return self.tempCache
+ end
+end
+
+function CC:GetCacheSize(global)
+ if global and not (self.cacheDBCalculationTime + 30 < GetTime()) then
+ return self.cacheDBSize > 1, self.cacheDBSize
+ elseif not global and not (self.cacheLocalCalculationTime + 30 < GetTime()) then
+ return self.cacheLocalSize > 1, self.cacheLocalSize
+ end
+
+ local size = 0
+
+ if global then
+ for realm in pairs(self.cache) do
+ for name in pairs(self.cache[realm]) do
+ size = size + 1
+ end
+ end
+
+ self.cacheDBSize = size
+ self.cacheDBCalculationTime = GetTime()
+ else
+ for realm in pairs(self.tempCache) do
+ for name in pairs(self.tempCache[realm]) do
+ size = size + 1
+ end
+ end
+
+ self.cacheLocalSize = size
+ self.cacheLocalCalculationTime = GetTime()
+ end
+
+ return size > 1, size
+end
+
+function CC:WipeCache(global)
+ if global then
+ for realm in pairs(self.cache) do
+ wipe(realm)
+ end
+
+ wipe(self.cache)
+ self:SwitchCacheType(true)
+ self.cacheDBCalculationTime = 0
+
+ E:Print(L["Class DB cache wiped."])
+ else
+ for realm in pairs(self.tempCache) do
+ wipe(realm)
+ end
+
+ wipe(self.tempCache)
+ self:SwitchCacheType(true)
+ self.cacheLocalCalculationTime = 0
+
+ E:Print(L["Class session cache wiped."])
+ end
+end
+
+function CC:PLAYER_ENTERING_WORLD()
+ local inInstance, instanceType = IsInInstance()
+ self.inInstance = inInstance
+
+ if instanceType == "arena" or instanceType == "pvp" then
+ self.inBattleground = true
+ else
+ self.inBattleground = false
+ end
+
+ if self.inInstance or self.inBattleground then
+ self.lastNumPlayers = 0
+
+ self:UnregisterEvent("PLAYER_TARGET_CHANGED")
+ self:UnregisterEvent("UPDATE_MOUSEOVER_UNIT")
+
+ self:UnregisterEvent("PARTY_MEMBERS_CHANGED")
+ self:UnregisterEvent("RAID_ROSTER_UPDATE")
+
+
+ self:RegisterEvent("UPDATE_BATTLEFIELD_SCORE")
+
+ if self.inBattleground then
+ self:UPDATE_BATTLEFIELD_SCORE()
+ end
+ else
+ self.lastNumPlayers = 0
+
+ self:RegisterEvent("PLAYER_TARGET_CHANGED")
+ self:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
+
+ self:RegisterEvent("PARTY_MEMBERS_CHANGED")
+ self:RegisterEvent("RAID_ROSTER_UPDATE")
+
+ self:UnregisterEvent("UPDATE_BATTLEFIELD_SCORE")
+ end
+
+ self:PLAYER_GUILD_UPDATE()
+
+ if not self.initUpdate then
+ if GetNumRaidMembers() > 0 then
+ self:RAID_ROSTER_UPDATE()
+ elseif GetNumPartyMembers() > 0 then
+ self:PARTY_MEMBERS_CHANGED()
+ end
+
+ self:GUILD_ROSTER_UPDATE(nil, true)
+
+ self.initUpdate = true
+ end
+end
+
+function CC:PLAYER_GUILD_UPDATE()
+ if IsInGuild() then
+ self:RegisterEvent("GUILD_ROSTER_UPDATE")
+ else
+ self:UnregisterEvent("RAID_ROSTER_UPDATE")
+ end
+end
+
+function CC:FRIENDLIST_UPDATE()
+ local name, class, _
+
+ for i = 1, GetNumFriends() do
+ name, _, class = GetFriendInfo(i)
+
+ if class then
+ self:CachePlayer(name, GetEnglishClassName(class))
+ end
+ end
+end
+
+function CC:GUILD_ROSTER_UPDATE(_, update)
+ if not update then return end
+
+ local name, class, _
+
+ for i = 1, GetNumGuildMembers() do
+ name, _, _, _, _, _, _, _, _, _, class = GetGuildRosterInfo(i)
+
+ if class then
+ self:CachePlayer(name, class)
+ end
+ end
+end
+
+function CC:PARTY_MEMBERS_CHANGED()
+ local name, realm, class, _
+
+ for i = 1, GetNumPartyMembers() do
+ name, realm = UnitName("party"..i)
+ _, class = UnitClass("party"..i)
+
+ if not class then return end
+
+ if self.inBattleground then
+ self:CachePlayer(name, class, realm)
+ else
+ self:CachePlayer(name, class)
+ end
+ end
+end
+
+function CC:RAID_ROSTER_UPDATE()
+ local name, realm, class, _
+
+ for i = 1, GetNumRaidMembers() do
+ name, realm = UnitName("raid"..i)
+ _, class = UnitClass("raid"..i)
+
+ if not class then return end
+
+ if self.inBattleground then
+ self:CachePlayer(name, class, realm)
+ else
+ self:CachePlayer(name, class)
+ end
+ end
+end
+
+function CC:PLAYER_TARGET_CHANGED()
+ if not UnitExists("target") or not UnitIsPlayer("target") then return end
+
+ local _, class = UnitClass("target")
+ if not class then return end
+
+ local name, realm = UnitName("target")
+
+ if self.inBattleground then
+ self:CachePlayer(name, class, realm)
+ else
+ self:CachePlayer(name, class)
+ end
+end
+
+function CC:UPDATE_MOUSEOVER_UNIT()
+ if not UnitExists("mouseover") or not UnitIsPlayer("mouseover") then return end
+
+ local _, class = UnitClass("mouseover")
+ if not class then return end
+
+ local name, realm = UnitName("mouseover")
+
+ if self.inBattleground then
+ self:CachePlayer(name, class, realm)
+ else
+ self:CachePlayer(name, class)
+ end
+end
+
+function CC:UPDATE_BATTLEFIELD_SCORE()
+ local numPlayers = GetNumBattlefieldScores() or 0
+
+ if self.lastNumPlayers == numPlayers then
+ return
+ elseif self.lastNumPlayers > numPlayers then
+ self.lastNumPlayers = numPlayers
+ return
+ end
+
+ local name, realm, class, _
+
+ for i = 1, numPlayers do
+ name, _, _, _, _, _, _, _, _, class = GetBattlefieldScore(i)
+
+ if name and class then
+ name, realm = split("-", name)
+ self:CachePlayer(name, class, realm)
+ end
+ end
+end
+
+function CC:WHOLIB_QUERY_RESULT(_, query, results, complete)
+ for _, result in pairs(results) do
+ if result and result.NoLocaleClass then
+ self:CachePlayer(result.Name, result.NoLocaleClass)
+ end
+ end
+end
+
+function CC:ToggleModule()
+ if E.private.general.classCache then
+ if not self.initialized then
+ self:SwitchCacheType(true)
+ self.initialized = true
+ end
+
+ self:RegisterEvent("PLAYER_ENTERING_WORLD")
+ self:RegisterEvent("PLAYER_GUILD_UPDATE")
+
+ self:RegisterEvent("FRIENDLIST_UPDATE")
+ self:RegisterEvent("PARTY_MEMBERS_CHANGED")
+ self:RegisterEvent("RAID_ROSTER_UPDATE")
+
+ LW.RegisterCallback(self, "WHOLIB_QUERY_RESULT", "WHOLIB_QUERY_RESULT")
+ else
+ self:UnregisterAllEvents()
+ LW.UnregisterAllCallbacks(self)
+ end
+end
+
+function CC:Initialize()
+ self.cache = E.global.classCache
+ self.tempCache = {}
+
+ self.cacheLocalCalculationTime = 0
+ self.cacheDBCalculationTime = 0
+
+ LW:SetWhoLibDebug(false)
+
+ if E.private.general.classCache then
+ self:ToggleModule()
+ end
+end
+
+local function InitializeCallback()
+ CC:Initialize()
+end
+
+E:RegisterModule(CC:GetName(), InitializeCallback)
\ No newline at end of file
diff --git a/2/3/4/5/6/7/ElvUI/Core/Load_Core.xml b/2/3/4/5/6/7/ElvUI/Core/Load_Core.xml
index 799e0f9..2a74520 100644
--- a/2/3/4/5/6/7/ElvUI/Core/Load_Core.xml
+++ b/2/3/4/5/6/7/ElvUI/Core/Load_Core.xml
@@ -14,4 +14,5 @@
+
\ No newline at end of file
diff --git a/2/3/4/5/6/7/ElvUI/Libraries/LibWho-2.0/LibWho-2.0.lua b/2/3/4/5/6/7/ElvUI/Libraries/LibWho-2.0/LibWho-2.0.lua
new file mode 100644
index 0000000..f840125
--- /dev/null
+++ b/2/3/4/5/6/7/ElvUI/Libraries/LibWho-2.0/LibWho-2.0.lua
@@ -0,0 +1,939 @@
+---
+--- check for an already loaded old WhoLib
+---
+
+if WhoLibByALeX or WhoLib then
+ -- the WhoLib-1.0 (WhoLibByALeX) or WhoLib (by Malex) is loaded -> fail!
+ error("an other WhoLib is already running - disable them first!\n")
+ return
+end -- if
+
+---
+--- check version
+---
+
+assert(LibStub, "LibWho-2.0 requires LibStub")
+
+
+local major_version = 'LibWho-2.0'
+local minor_version = tonumber("154") or 99999
+
+local lib = LibStub:NewLibrary(major_version, minor_version)
+
+
+if not lib then
+ return -- already loaded and no upgrade necessary
+end
+
+lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)
+local callbacks = lib.callbacks
+
+local am = {}
+local om = getmetatable(lib)
+if om then
+ for k, v in pairs(om) do am[k] = v end
+end
+am.__tostring = function() return major_version end
+setmetatable(lib, am)
+
+local function dbgfunc(...) if lib.Debug then print(unpack(arg)) end end
+local function NOP() return end
+local dbg = NOP
+
+---
+--- initalize base
+---
+
+if type(lib['hooked']) ~= 'table' then
+ lib['hooked'] = {}
+end -- if
+
+if type(lib['hook']) ~= 'table' then
+ lib['hook'] = {}
+end -- if
+
+if type(lib['events']) ~= 'table' then
+ lib['events'] = {}
+end -- if
+
+if type(lib['embeds']) ~= 'table' then
+ lib['embeds'] = {}
+end -- if
+
+if type(lib['frame']) ~= 'table' then
+ lib['frame'] = CreateFrame('Frame', major_version);
+end -- if
+lib['frame']:Hide()
+
+lib.Queue = {[1]={}, [2]={}, [3]={}}
+lib.WhoInProgress = false
+lib.Result = nil
+lib.Args = nil
+lib.Total = nil
+lib.Quiet = nil
+lib.Debug = false
+lib.Cache = {}
+lib.CacheQueue = {}
+lib.SetWhoToUIState = false
+
+
+lib.MinInterval = 2.5
+lib.MaxInterval = 10
+
+---
+--- locale
+---
+
+if (GetLocale() == "ruRU") then
+ lib.L = {
+ ['console_queued'] = 'Добавлено в очередь "/who %s"',
+ ['console_query'] = 'Результат "/who %s"',
+ ['gui_wait'] = '- Пожалуйста подождите -',
+ }
+else
+ -- enUS is the default
+ lib.L = {
+ ['console_queued'] = 'Added "/who %s" to queue',
+ ['console_query'] = 'Result of "/who %s"',
+ ['gui_wait'] = '- Please Wait -',
+ }
+end -- if
+
+
+---
+--- external functions/constants
+---
+
+lib['external'] = {
+ 'WHOLIB_QUEUE_USER',
+ 'WHOLIB_QUEUE_QUIET',
+ 'WHOLIB_QUEUE_SCANNING',
+ 'WHOLIB_FLAG_ALWAYS_CALLBACK',
+ 'Who',
+ 'UserInfo',
+ 'CachedUserInfo',
+ 'GetWhoLibDebug',
+ 'SetWhoLibDebug',
+-- 'RegisterWhoLibEvent',
+}
+
+-- queues
+lib['WHOLIB_QUEUE_USER'] = 1
+lib['WHOLIB_QUEUE_QUIET'] = 2
+lib['WHOLIB_QUEUE_SCANNING'] = 3
+
+
+
+local queue_all = {
+ [1] = 'WHOLIB_QUEUE_USER',
+ [2] = 'WHOLIB_QUEUE_QUIET',
+ [3] = 'WHOLIB_QUEUE_SCANNING',
+}
+
+local queue_quiet = {
+ [2] = 'WHOLIB_QUEUE_QUIET',
+ [3] = 'WHOLIB_QUEUE_SCANNING',
+}
+
+-- bit masks!
+lib['WHOLIB_FLAG_ALWAYS_CALLBACK'] = 1
+
+function lib:Reset()
+ self.Queue = {[1]={}, [2]={}, [3]={}}
+ self.Cache = {}
+ self.CacheQueue = {}
+end
+
+function lib.Who(defhandler, query, opts)
+ local self, args, usage = lib, {}, 'Who(query, [opts])'
+
+ args.query = self:CheckArgument(usage, 'query', 'string', query)
+ opts = self:CheckArgument(usage, 'opts', 'table', opts, {})
+ args.queue = self:CheckPreset(usage, 'opts.queue', queue_all, opts.queue, self.WHOLIB_QUEUE_SCANNING)
+ args.flags = self:CheckArgument(usage, 'opts.flags', 'number', opts.flags, 0)
+ args.callback, args.handler = self:CheckCallback(usage, 'opts.', opts.callback, opts.handler, defhandler)
+ -- now args - copied and verified from opts
+
+ if args.queue == self.WHOLIB_QUEUE_USER then
+ if WhoFrame:IsShown() then
+ self:GuiWho(args.query)
+ else
+ self:ConsoleWho(args.query)
+ end
+ else
+ self:AskWho(args)
+ end
+end
+
+function lib.UserInfo(defhandler, name, opts)
+ local self, args, usage = lib, {}, 'UserInfo(name, [opts])'
+ local now = time()
+
+ name = self:CheckArgument(usage, 'name', 'string', name)
+ if strlen(name) == 0 then return end
+
+ if string.find(name, "%-") then --[[dbg("ignoring xrealm: "..name)]] return end
+
+ args.name = self:CapitalizeInitial(name)
+ opts = self:CheckArgument(usage, 'opts', 'table', opts, {})
+ args.queue = self:CheckPreset(usage, 'opts.queue', queue_quiet, opts.queue, self.WHOLIB_QUEUE_SCANNING)
+ args.flags = self:CheckArgument(usage, 'opts.flags', 'number', opts.flags, 0)
+ args.timeout = self:CheckArgument(usage, 'opts.timeout', 'number', opts.timeout, 5)
+ args.callback, args.handler = self:CheckCallback(usage, 'opts.', opts.callback, opts.handler, defhandler)
+
+ -- now args - copied and verified from opts
+ local cachedName = self.Cache[args.name]
+
+ if(cachedName ~= nil)then
+ -- user is in cache
+ if(cachedName.valid == true and (args.timeout < 0 or cachedName.last + args.timeout*60 > now))then
+ -- cache is valid and timeout is in range
+ --dbg('Info(' .. args.name ..') returned immedeatly')
+ if(bit.band(args.flags, self.WHOLIB_FLAG_ALWAYS_CALLBACK) ~= 0)then
+ self:RaiseCallback(args, cachedName.data)
+ return false
+ else
+ return self:DupAll(self:ReturnUserInfo(args.name))
+ end
+ elseif(cachedName.valid == false)then
+ -- query is already running (first try)
+ if(args.callback ~= nil)then
+ tinsert(cachedName.callback, args)
+ end
+ --dbg('Info(' .. args.name ..') returned cause it\'s already searching')
+ return nil
+ end
+ else
+ self.Cache[args.name] = {valid=false, inqueue=false, callback={}, data={Name = args.name}, last=now }
+ end
+
+ local cachedName = self.Cache[args.name]
+
+ if(cachedName.inqueue)then
+ -- query is running!
+ if(args.callback ~= nil)then
+ tinsert(cachedName.callback, args)
+ end
+ dbg('Info(' .. args.name ..') returned cause it\'s already searching')
+ return nil
+ end
+ if (GetLocale() == "ruRU") then -- in ruRU with n- not show information about player in WIM addon
+ if args.name and strlen(args.name) > 0 then
+ local query = 'и-"' .. args.name .. '"'
+ cachedName.inqueue = true
+ if(args.callback ~= nil)then
+ tinsert(cachedName.callback, args)
+ end
+ self.CacheQueue[query] = args.name
+ dbg('Info(' .. args.name ..') added to queue')
+ self:AskWho( { query = query, queue = args.queue, flags = 0, info = args.name } )
+ end
+ else
+ if args.name and strlen(args.name) > 0 then
+ local query = 'n-"' .. args.name .. '"'
+ cachedName.inqueue = true
+ if(args.callback ~= nil)then
+ tinsert(cachedName.callback, args)
+ end
+ self.CacheQueue[query] = args.name
+ dbg('Info(' .. args.name ..') added to queue')
+ self:AskWho( { query = query, queue = args.queue, flags = 0, info = args.name } )
+ end
+ end
+ return nil
+end
+
+function lib.CachedUserInfo(_, name)
+ local self, usage = lib, 'CachedUserInfo(name)'
+
+ name = self:CapitalizeInitial(self:CheckArgument(usage, 'name', 'string', name))
+
+ if self.Cache[name] == nil then
+ return nil
+ else
+ return self:DupAll(self:ReturnUserInfo(name))
+ end
+end
+
+function lib.GetWhoLibDebug(_, mode)
+ return lib.Debug
+end
+
+function lib.SetWhoLibDebug(_, mode)
+ lib.Debug = mode
+ dbg = mode and dbgfunc or NOP
+end
+
+--function lib.RegisterWhoLibEvent(defhandler, event, callback, handler)
+-- local self, usage = lib, 'RegisterWhoLibEvent(event, callback, [handler])'
+--
+-- self:CheckPreset(usage, 'event', self.events, event)
+-- local callback, handler = self:CheckCallback(usage, '', callback, handler, defhandler, true)
+-- table.insert(self.events[event], {callback=callback, handler=handler})
+--end
+
+-- non-embedded externals
+
+function lib.Embed(_, handler)
+ local self, usage = lib, 'Embed(handler)'
+
+ self:CheckArgument(usage, 'handler', 'table', handler)
+
+ for _,name in pairs(self.external) do
+ handler[name] = self[name]
+ end -- do
+ self['embeds'][handler] = true
+
+ return handler
+end
+
+function lib.Library(_)
+ local self = lib
+
+ return self:Embed({})
+end
+
+---
+--- internal functions
+---
+
+function lib:AllQueuesEmpty()
+ local queueCount = getn(self.Queue[1]) + getn(self.Queue[2]) + getn(self.Queue[3]) + getn(self.CacheQueue)
+
+ -- Be sure that we have cleared the in-progress status
+ if self.WhoInProgress then
+ queueCount = queueCount + 1
+ end
+
+ return queueCount == 0
+end
+
+local queryInterval = 5
+
+function lib:GetQueryInterval() return queryInterval end
+
+function lib:AskWhoNextIn5sec()
+ if self.frame:IsShown() then return end
+
+ dbg("Waiting to send next who")
+ self.Timeout_time = queryInterval
+ self['frame']:Show()
+end
+
+function lib:CancelPendingWhoNext()
+ lib['frame']:Hide()
+end
+
+lib['frame']:SetScript("OnUpdate", function()
+ lib.Timeout_time = lib.Timeout_time - arg1
+ if lib.Timeout_time <= 0 then
+ lib['frame']:Hide()
+ lib:AskWhoNext()
+ end -- if
+end);
+
+
+-- queue scheduler
+local queue_weights = { [1] = 0.6, [2] = 0.2, [3] = 0.2 }
+local queue_bounds = { [1] = 0.6, [2] = 0.2, [3] = 0.2 }
+
+-- allow for single queries from the user to get processed faster
+local lastInstantQuery = time()
+local INSTANT_QUERY_MIN_INTERVAL = 60 -- only once every 1 min
+
+function lib:UpdateWeights()
+ local weightsum, sum, count = 0, 0, 0
+ for k,v in pairs(queue_weights) do
+ sum = sum + v
+ weightsum = weightsum + v * getn(self.Queue[k])
+ end
+
+ if weightsum == 0 then
+ for k,v in pairs(queue_weights) do queue_bounds[k] = v end
+ return
+ end
+
+ local adjust = sum / weightsum
+
+ for k,v in pairs(queue_bounds) do
+ queue_bounds[k] = queue_weights[k] * adjust * getn(self.Queue[k])
+ end
+end
+
+function lib:GetNextFromScheduler()
+ self:UpdateWeights()
+
+ -- Since an addon could just fill up the user q for instant processing
+ -- we have to limit instants to 1 per INSTANT_QUERY_MIN_INTERVAL
+ -- and only try instant fulfilment if it will empty the user queue
+ if getn(self.Queue[1]) == 1 then
+ if time() - lastInstantQuery > INSTANT_QUERY_MIN_INTERVAL then
+ dbg("INSTANT")
+ lastInstantQuery = time()
+ return 1, self.Queue[1]
+ end
+ end
+
+ local n,i = math.random(),0
+ repeat
+ i=i+1
+ n = n - queue_bounds[i]
+ until i >= getn(self.Queue) or n <= 0
+
+ dbg(string.format("Q=%d, bound=%d", i, queue_bounds[i]))
+
+ if getn(self.Queue[i]) > 0 then
+ dbg(string.format("Q=%d, bound=%d", i, queue_bounds[i]))
+ return i, self.Queue[i]
+ else
+ dbg("Queues empty, waiting")
+ end
+end
+
+lib.queue_bounds = queue_bounds
+
+function lib:AskWhoNext()
+ if lib.frame:IsShown() then
+ dbg("Already waiting")
+ return
+ end
+
+ self:CancelPendingWhoNext()
+
+ if self.WhoInProgress then
+ -- if we had a who going, it didnt complete
+ dbg("TIMEOUT: "..self.Args.query)
+ local args = self.Args
+ self.Args = nil
+-- if args.info and self.CacheQueue[args.query] ~= nil then
+ dbg("Requeing "..args.query)
+ tinsert(self.Queue[args.queue], args)
+ if args.console_show ~= nil then
+ DEFAULT_CHAT_FRAME:AddMessage(string.format("Timeout on result of '%s' - retrying...", args.query), 1, 1, 0)
+ args.console_show = true
+ end
+-- end
+
+ if queryInterval < lib.MaxInterval then
+ queryInterval = queryInterval + 0.5
+ dbg("--Throttling down to 1 who per " .. queryInterval .. "s")
+ end
+ end
+
+
+ self.WhoInProgress = false
+
+ local v,k,args = nil
+ local kludge = 10
+ repeat
+ k, v = self:GetNextFromScheduler()
+ if not k then break end
+ if WhoFrame:IsShown() and k > self.WHOLIB_QUEUE_QUIET then
+ break
+ end
+ if getn(v) > 0 then
+ args = tremove(v, 1)
+ break
+ end
+ kludge = kludge - 1
+ until kludge <= 0
+
+ if args then
+ self.WhoInProgress = true
+ self.Result = {}
+ self.Args = args
+ self.Total = -1
+ if(args.console_show == true)then
+ DEFAULT_CHAT_FRAME:AddMessage(string.format(self.L['console_query'], args.query), 1, 1, 0)
+
+ end
+
+ if args.queue == self.WHOLIB_QUEUE_USER then
+ WhoFrameEditBox:SetText(args.query)
+ self.Quiet = false
+
+ if args.whotoui then
+ self.hooked.SetWhoToUI(args.whotoui)
+ else
+ self.hooked.SetWhoToUI(args.gui and true or false)
+ end
+ else
+ -- self.hooked.SetWhoToUI(true)
+ self.Quiet = true
+ end
+
+ dbg("QUERY: "..args.query)
+ -- self.hooked.SendWho(args.query)
+ else
+ self.Args = nil
+ self.WhoInProgress = false
+ end
+
+ -- Keep processing the who queue if there is more work
+ if not self:AllQueuesEmpty() then
+ self:AskWhoNextIn5sec()
+ else
+ dbg("*** Done processing requests ***")
+ end
+end
+
+function lib:AskWho(args)
+ tinsert(self.Queue[args.queue], args)
+ dbg('[' .. args.queue .. '] added "' .. args.query .. '", queues=' .. getn(self.Queue[1]) .. '/'.. getn(self.Queue[2]) .. '/'.. getn(self.Queue[3]))
+ self:TriggerEvent('WHOLIB_QUERY_ADDED')
+
+ self:AskWhoNext()
+end
+
+function lib:ReturnWho()
+ if not self.Args then
+ self.Quiet = nil
+ return
+ end
+
+ if(self.Args.queue == self.WHOLIB_QUEUE_QUIET or self.Args.queue == self.WHOLIB_QUEUE_SCANNING)then
+ self.Quiet = nil
+ end
+
+ if queryInterval > self.MinInterval then
+ queryInterval = queryInterval - 0.5
+ dbg("--Throttling up to 1 who per " .. queryInterval .. "s")
+ end
+
+ self.WhoInProgress = false
+ dbg("RESULT: "..self.Args.query)
+ dbg('[' .. self.Args.queue .. '] returned "' .. self.Args.query .. '", total=' .. self.Total ..' , queues=' .. getn(self.Queue[1]) .. '/'.. getn(self.Queue[2]) .. '/'.. getn(self.Queue[3]))
+ local now = time()
+ local complete = (self.Total == getn(self.Result)) and (self.Total < MAX_WHOS_FROM_SERVER)
+ for _,v in pairs(self.Result)do
+ if v.Name then
+ if(self.Cache[v.Name] == nil)then
+ self.Cache[v.Name] = { inqueue = false, callback = {} }
+ end
+
+ local cachedName = self.Cache[v.Name]
+
+ cachedName.valid = true -- is now valid
+ cachedName.data = v -- update data
+ cachedName.data.Online = true -- player is online
+ cachedName.last = now -- update timestamp
+ if(cachedName.inqueue)then
+ if(self.Args.info and self.CacheQueue[self.Args.query] == v.Name)then
+ -- found by the query which was created to -> remove us from query
+ self.CacheQueue[self.Args.query] = nil
+ else
+ -- found by another query
+ for k2,v2 in pairs(self.CacheQueue) do
+ if(v2 == v.Name)then
+ for i=self.WHOLIB_QUEUE_QUIET, self.WHOLIB_QUEUE_SCANNING do
+ for k3,v3 in pairs(self.Queue[i]) do
+ if(v3.query == k2 and v3.info)then
+ -- remove the query which was generated for this user, cause another query was faster...
+ dbg("Found '"..v.Name.."' early via query '"..self.Args.query.."'")
+ table.remove(self.Queue[i], k3)
+ self.CacheQueue[k2] = nil
+ end
+ end
+ end
+ end
+ end
+ end
+ dbg('Info(' .. v.Name ..') returned: on')
+ for _,v2 in pairs(cachedName.callback) do
+ self:RaiseCallback(v2, self:ReturnUserInfo(v.Name))
+ end
+ cachedName.callback = {}
+ end
+ cachedName.inqueue = false -- query is done
+ end
+ end
+ if(self.Args.info and self.CacheQueue[self.Args.query])then
+ -- the query did not deliver the result => not online!
+ local name = self.CacheQueue[self.Args.query]
+ local cachedName = self.Cache[name]
+ if (cachedName.inqueue)then
+ -- nothing found (yet)
+ cachedName.valid = true -- is now valid
+ cachedName.inqueue = false -- query is done?
+ cachedName.last = now -- update timestamp
+ if(complete)then
+ cachedName.data.Online = false -- player is offline
+ else
+ cachedName.data.Online = nil -- player is unknown (more results from who than can be displayed)
+ end
+ end
+ dbg('Info(' .. name ..') returned: ' .. (cachedName.data.Online == false and 'off' or 'unkn'))
+ for _,v in pairs(cachedName.callback) do
+ self:RaiseCallback(v, self:ReturnUserInfo(name))
+ end
+ cachedName.callback = {}
+ self.CacheQueue[self.Args.query] = nil
+ end
+ self:RaiseCallback(self.Args, self.Args.query, self.Result, complete, self.Args.info)
+ self:TriggerEvent('WHOLIB_QUERY_RESULT', self.Args.query, self.Result, complete, self.Args.info)
+
+ if not self:AllQueuesEmpty() then
+ self:AskWhoNextIn5sec()
+ end
+end
+
+function lib:GuiWho(msg)
+ if(msg == self.L['gui_wait'])then
+ return
+ end
+
+ for _,v in pairs(self.Queue[self.WHOLIB_QUEUE_USER]) do
+ if(v.gui == true)then
+ return
+ end
+ end
+ if(self.WhoInProgress)then
+ WhoFrameEditBox:SetText(self.L['gui_wait'])
+ end
+ self.savedText = msg
+ self:AskWho({query = msg, queue = self.WHOLIB_QUEUE_USER, flags = 0, gui = true})
+ WhoFrameEditBox:ClearFocus();
+end
+
+function lib:ConsoleWho(msg)
+ --WhoFrameEditBox:SetText(msg)
+ local console_show = false
+ local q1 = self.Queue[self.WHOLIB_QUEUE_USER]
+ local q1count = getn(q1)
+
+ if(q1count > 0 and q1[q1count].query == msg)then -- last query is itdenical: drop
+ return
+ end
+
+ if(q1count > 0 and q1[q1count].console_show == false)then -- display 'queued' if console and not yet shown
+ DEFAULT_CHAT_FRAME:AddMessage(string.format(self.L['console_queued'], q1[q1count].query), 1, 1, 0)
+ q1[q1count].console_show = true
+ end
+ if(q1count > 0 or self.WhoInProgress)then
+ DEFAULT_CHAT_FRAME:AddMessage(string.format(self.L['console_queued'], msg), 1, 1, 0)
+ console_show = true
+ end
+ self:AskWho({query = msg, queue = self.WHOLIB_QUEUE_USER, flags = 0, console_show = console_show})
+end
+
+function lib:ReturnUserInfo(name)
+ if(name ~= nil and self ~= nil and self.Cache ~= nil and self.Cache[name] ~= nil) then
+ return self.Cache[name].data, (time() - self.Cache[name].last) / 60
+ end
+end
+
+function lib:RaiseCallback(args, ...)
+ if type(args.callback) == 'function' then
+ args.callback(self:DupAll(unpack(args)))
+ elseif args.callback then -- must be a string
+ args.handler[args.callback](args.handler, self:DupAll(unpack(args)))
+ end -- if
+end
+
+-- Argument checking
+
+function lib:CheckArgument(func, name, argtype, arg, defarg)
+ if arg == nil and defarg ~= nil then
+ return defarg
+ elseif type(arg) == argtype then
+ return arg
+ else
+ error(string.format("%s: '%s' - %s%s expected got %s", func, name, (defarg ~= nil) and 'nil or ' or '', argtype, type(arg)), 3)
+ end -- if
+end
+
+function lib:CheckPreset(func, name, preset, arg, defarg)
+ if arg == nil and defarg ~= nil then
+ return defarg
+ elseif arg ~= nil and preset[arg] ~= nil then
+ return arg
+ else
+ local p = {}
+ for k,v in pairs(preset) do
+ if type(v) ~= 'string' then
+ table.insert(p, k)
+ else
+ table.insert(p, v)
+ end -- if
+ end -- for
+ error(string.format("%s: '%s' - one of %s%s expected got %s", func, name, (defarg ~= nil) and 'nil, ' or '', table.concat(p, ', '), self:simple_dump(arg)), 3)
+ end -- if
+end
+
+function lib:CheckCallback(func, prefix, callback, handler, defhandler, nonil)
+ if not nonil and callback == nil then
+ -- no callback: ignore handler
+ return nil, nil
+ elseif type(callback) == 'function' then
+ -- simple function
+ if handler ~= nil then
+ error(string.format("%s: '%shandler' - nil expected got %s", func, prefix, type(arg)), 3)
+ end -- if
+ elseif type(callback) == 'string' then
+ -- method
+ if handler == nil then
+ handler = defhandler
+ end -- if
+ if type(handler) ~= 'table' or type(handler[callback]) ~= 'function' or handler == self then
+ error(string.format("%s: '%shandler' - nil or function expected got %s", func, prefix, type(arg)), 3)
+ end -- if
+ else
+ error(string.format("%s: '%scallback' - %sfunction or string expected got %s", func, prefix, nonil and 'nil or ' or '', type(arg)), 3)
+ end -- if
+
+ return callback, handler
+end
+
+-- helpers
+
+function lib:simple_dump(x)
+ if type(x) == 'string' then
+ return 'string \''..x..'\''
+ elseif type(x) == 'number' then
+ return 'number '..x
+ else
+ return type(x)
+ end
+end
+
+function lib:Dup(from)
+ local to = {}
+
+ for k,v in pairs(from) do
+ if type(v) == 'table' then
+ to[k] = self:Dup(v)
+ else
+ to[k] = v
+ end -- if
+ end -- for
+
+ return to
+end
+
+function lib:DupAll(x, ...)
+ if type(x) == 'table' then
+ return self:Dup(x), self:DupAll(unpack(args))
+ elseif x ~= nil then
+ return x, self:DupAll(unpack(args))
+ else
+ return nil
+ end -- if
+end
+
+local MULTIBYTE_FIRST_CHAR = "^([\192-\255]?%a?[\128-\191]*)"
+
+function lib:CapitalizeInitial(name)
+ return string.gsub(name, MULTIBYTE_FIRST_CHAR, string.upper, 1)
+end
+
+---
+--- user events (Using CallbackHandler)
+---
+
+lib.PossibleEvents = {
+ 'WHOLIB_QUERY_RESULT',
+ 'WHOLIB_QUERY_ADDED',
+}
+
+function lib:TriggerEvent(...)
+ callbacks:Fire(event, unpack(arg))
+end
+
+---
+--- slash commands
+---
+
+SlashCmdList['WHO'] = function(msg)
+ dbg("console /who: "..msg)
+ -- new /who function
+ --local self = lib
+
+ if(msg == '')then
+ lib:GuiWho(WhoFrame_GetDefaultWhoCommand())
+ elseif(WhoFrame:IsVisible())then
+ lib:GuiWho(msg)
+ else
+ lib:ConsoleWho(msg)
+ end
+end
+
+SlashCmdList['WHOLIB_DEBUG'] = function()
+ -- /wholibdebug: toggle debug on/off
+ local self = lib
+
+ self:SetWhoLibDebug(not self.Debug)
+end
+
+SLASH_WHOLIB_DEBUG1 = '/wholibdebug'
+
+
+---
+--- hook activation
+---
+
+-- functions to hook
+local hooks = {
+ -- 'SendWho',
+ -- 'WhoFrameEditBox_OnEnterPressed',
+-- 'FriendsFrame_OnEvent',
+ -- 'SetWhoToUI',
+}
+
+-- hook all functions (which are not yet hooked)
+for _, name in pairs(hooks) do
+ if not lib['hooked'][name] then
+ lib['hooked'][name] = _G[name]
+ _G[name] = function(...)
+ lib.hook[name](lib, unpack(arg))
+ end -- function
+ end -- if
+end -- for
+
+-- fake 'WhoFrame:Hide' as hooked
+table.insert(hooks, 'WhoFrame_Hide')
+
+-- check for unused hooks -> remove function
+for name, _ in pairs(lib['hook']) do
+ if not hooks[name] then
+ lib['hook'][name] = function() end
+ end -- if
+end -- for
+
+-- secure hook 'WhoFrame:Hide'
+if not lib['hooked']['WhoFrame_Hide'] then
+ lib['hooked']['WhoFrame_Hide'] = true
+ hooksecurefunc(WhoFrame, 'Hide', function(...)
+ lib['hook']['WhoFrame_Hide'](lib, unpack(arg))
+ end -- function
+ )
+end -- if
+
+
+
+----- Coroutine based implementation (future)
+--function lib:sendWhoResult(val)
+-- coroutine.yield(val)
+--end
+--
+--function lib:sendWaitState(val)
+-- coroutine.yield(val)
+--end
+--
+--function lib:producer()
+-- return coroutine.create(
+-- function()
+-- lib:AskWhoNext()
+-- lib:sendWaitState(true)
+--
+-- -- Resumed look for data
+--
+-- end)
+--end
+
+
+
+
+
+---
+--- hook replacements
+---
+
+function lib.hook.SendWho(self, msg)
+ dbg("SendWho: "..msg)
+ lib.AskWho(self, {query = msg, queue = lib.WHOLIB_QUEUE_USER, whotoui = lib.SetWhoToUIState, flags = 0})
+end
+
+function lib.hook.WhoFrameEditBox_OnEnterPressed(self)
+ lib:GuiWho(WhoFrameEditBox:GetText())
+end
+
+--[[
+function lib.hook.FriendsFrame_OnEvent(self, ...)
+ if event ~= 'WHO_LIST_UPDATE' or not lib.Quiet then
+ lib.hooked.FriendsFrame_OnEvent(...)
+ end
+end
+]]
+
+hooksecurefunc(FriendsFrame, 'RegisterEvent', function(self, event)
+ if(event == "WHO_LIST_UPDATE") then
+ self:UnregisterEvent("WHO_LIST_UPDATE");
+ end
+ end);
+
+
+function lib.hook.SetWhoToUI(self, state)
+ lib.SetWhoToUIState = state
+end
+
+function lib.hook.WhoFrame_Hide(self)
+ if(not lib.WhoInProgress)then
+ lib:AskWhoNextIn5sec()
+ end
+end
+
+
+---
+--- WoW events
+---
+
+local who_pattern = string.gsub(WHO_NUM_RESULTS, '%%d', '%%d%+')
+
+
+function lib:CHAT_MSG_SYSTEM(arg1)
+ if arg1 and string.find(arg1, who_pattern) then
+ lib:ProcessWhoResults()
+ end
+end
+
+FriendsFrame:UnregisterEvent("WHO_LIST_UPDATE")
+
+function lib:WHO_LIST_UPDATE()
+ if not lib.Quiet then
+ WhoList_Update()
+ FriendsFrame_Update()
+ end
+
+ lib:ProcessWhoResults()
+end
+
+function lib:ProcessWhoResults()
+ self.Result = self.Result and table.wipe(self.Result) or {}
+
+ local num
+ self.Total, num = GetNumWhoResults()
+ for i=1, num do
+ local charname, guildname, level, race, class, zone, nonlocalclass, sex = GetWhoInfo(i)
+ self.Result[i] = {Name=charname, Guild=guildname, Level=level, Race=race, Class=class, Zone=zone, NoLocaleClass=nonlocalclass, Sex=sex }
+ end
+
+ self:ReturnWho()
+end
+
+---
+--- event activation
+---
+
+lib['frame']:UnregisterAllEvents();
+
+lib['frame']:SetScript("OnEvent", function(...)
+ lib[event](lib, unpack(arg))
+end);
+
+for _,name in pairs({
+ 'CHAT_MSG_SYSTEM',
+ 'WHO_LIST_UPDATE',
+}) do
+ lib['frame']:RegisterEvent(name);
+end -- for
+
+
+---
+--- re-embed
+---
+
+for target,_ in pairs(lib['embeds']) do
+ if type(target) == 'table' then
+ lib:Embed(target)
+ end -- if
+end -- for
\ No newline at end of file
diff --git a/2/3/4/5/6/7/ElvUI/Libraries/LibWho-2.0/LibWho-2.0.xml b/2/3/4/5/6/7/ElvUI/Libraries/LibWho-2.0/LibWho-2.0.xml
new file mode 100644
index 0000000..8c9955e
--- /dev/null
+++ b/2/3/4/5/6/7/ElvUI/Libraries/LibWho-2.0/LibWho-2.0.xml
@@ -0,0 +1,4 @@
+
+
+
\ No newline at end of file
diff --git a/2/3/4/5/6/7/ElvUI/Libraries/Load_Libraries.xml b/2/3/4/5/6/7/ElvUI/Libraries/Load_Libraries.xml
index 270a952..765eb07 100644
--- a/2/3/4/5/6/7/ElvUI/Libraries/Load_Libraries.xml
+++ b/2/3/4/5/6/7/ElvUI/Libraries/Load_Libraries.xml
@@ -20,6 +20,7 @@
+
\ No newline at end of file
diff --git a/2/3/4/5/6/7/ElvUI/Modules/Chat/Chat.lua b/2/3/4/5/6/7/ElvUI/Modules/Chat/Chat.lua
index 32b42db..8539dc3 100644
--- a/2/3/4/5/6/7/ElvUI/Modules/Chat/Chat.lua
+++ b/2/3/4/5/6/7/ElvUI/Modules/Chat/Chat.lua
@@ -1,6 +1,6 @@
local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local CH = E:NewModule("Chat", "AceTimer-3.0", "AceHook-3.0", "AceEvent-3.0");
---local CC = E:GetModule("ClassCache")
+local CC = E:GetModule("ClassCache");
local LSM = LibStub("LibSharedMedia-3.0");
--Cache global variables
@@ -212,6 +212,45 @@ local function ChatFrame_OnMouseScroll(frame, delta)
end
end
+local function ChatFrame_AddMessageEventFilter(event, filter)
+ assert(event and filter)
+
+ if chatFilters[event] then
+ -- Only allow a filter to be added once
+ for index, filterFunc in next, chatFilters[event] do
+ if filterFunc == filter then
+ return
+ end
+ end
+ else
+ chatFilters[event] = {}
+ end
+
+ tinsert(chatFilters[event], filter)
+end
+
+local function ChatFrame_RemoveMessageEventFilter(event, filter)
+ assert(event and filter)
+
+ if chatFilters[event] then
+ for index, filterFunc in next, chatFilters[event] do
+ if filterFunc == filter then
+ tremove(chatFilters[event], index)
+ end
+ end
+
+ if getn(chatFilters[event]) == 0 then
+ chatFilters[event] = nil
+ end
+ end
+end
+
+local function ChatFrame_GetMessageEventFilters(event)
+ assert(event)
+
+ return chatFilters[event]
+end
+
function CH:GetGroupDistribution()
local inInstance, kind = IsInInstance()
if inInstance and kind == "pvp" then
@@ -228,7 +267,7 @@ end
function CH:InsertEmotions(msg)
for k,v in pairs(smileyKeys) do
- msg = gsub(msg,k,"|T"..smileyPack[v]..":16|t")
+ -- msg = gsub(msg,k,"|T"..smileyPack[v]..":16|t")
end
return msg
end
@@ -362,7 +401,7 @@ end
local function removeIconFromLine(text)
text = gsub(text, "|TInterface\\TargetingFrame\\UI%-RaidTargetingIcon_(%d+):0|t", function(x)
- x = _G["RAID_TARGET_"..x];return "{"..strlower(x).."}"
+ x = _G["RAID_TARGET_"..x]; return "{"..strlower(x).."}"
end)
text = gsub(text, "|H.-|h(.-)|h", "%1")
@@ -712,8 +751,8 @@ function CH:OnHyperlinkLeave()
end
end
-function CH:OnMessageScrollChanged(frame)
- if hyperLinkEntered == frame then
+function CH:OnMessageScrollChanged()
+ if hyperLinkEntered == this then
HideUIPanel(GameTooltip)
hyperLinkEntered = false
end
@@ -750,7 +789,7 @@ function CH.ShortChannel()
end
function CH:ConcatenateTimeStamp(msg)
- if (CH.db.timeStampFormat and CH.db.timeStampFormat ~= "NONE" ) then
+ if CH.db.timeStampFormat and CH.db.timeStampFormat ~= "NONE" then
local timeStamp = BetterDate(CH.db.timeStampFormat, CH.timeOverride or time())
timeStamp = gsub(timeStamp, " ", "")
timeStamp = gsub(timeStamp, "AM", " AM")
@@ -773,7 +812,7 @@ function GetColoredName(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, a
if arg2 and arg2 ~= "" then
local name, realm = strsplit("-", arg2)
- --local englishClass = CC:GetClassByName(name, realm)
+ local englishClass = CC:GetClassByName(name, realm)
if englishClass then
local classColorTable = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[englishClass] or RAID_CLASS_COLORS[englishClass]
@@ -802,112 +841,112 @@ end
function CH:ChatFrame_MessageEventHandler(event, ...)
if event == "UPDATE_CHAT_WINDOWS" then
- local name, fontSize, r, g, b, a, shown, locked = GetChatWindowInfo(self:GetID());
- if ( fontSize > 0 ) then
- local fontFile, unused, fontFlags = self:GetFont();
- self:SetFont(fontFile, fontSize, fontFlags);
+ local name, fontSize, r, g, b, a, shown, locked = GetChatWindowInfo(self:GetID())
+ if fontSize > 0 then
+ local fontFile, unused, fontFlags = self:GetFont()
+ self:SetFont(fontFile, fontSize, fontFlags)
end
- if ( shown ) then
- self:Show();
+ if shown then
+ self:Show()
end
-- Do more stuff!!!
- ChatFrame_RegisterForMessages(GetChatWindowMessages(self:GetID()));
- ChatFrame_RegisterForChannels(GetChatWindowChannels(self:GetID()));
- return;
+ ChatFrame_RegisterForMessages(GetChatWindowMessages(self:GetID()))
+ ChatFrame_RegisterForChannels(GetChatWindowChannels(self:GetID()))
+ return
end
- if ( event == "PLAYER_ENTERING_WORLD" ) then
- self.defaultLanguage = GetDefaultLanguage();
- return;
+ if event == "PLAYER_ENTERING_WORLD" then
+ self.defaultLanguage = GetDefaultLanguage()
+ return
end
- if ( event == "TIME_PLAYED_MSG" ) then
- ChatFrame_DisplayTimePlayed(arg1, arg2);
- return;
+ if event == "TIME_PLAYED_MSG" then
+ ChatFrame_DisplayTimePlayed(arg1, arg2)
+ return
end
- if ( event == "PLAYER_LEVEL_UP" ) then
+ if event == "PLAYER_LEVEL_UP" then
-- Level up
- local info = ChatTypeInfo["SYSTEM"];
+ local info = ChatTypeInfo["SYSTEM"]
- local string = format(TEXT(LEVEL_UP), arg1);
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ local string = format(TEXT(LEVEL_UP), arg1)
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
- if ( arg3 > 0 ) then
- string = format(TEXT(LEVEL_UP_HEALTH_MANA), arg2, arg3);
+ if arg3 > 0 then
+ string = format(TEXT(LEVEL_UP_HEALTH_MANA), arg2, arg3)
else
- string = format(TEXT(LEVEL_UP_HEALTH), arg2);
+ string = format(TEXT(LEVEL_UP_HEALTH), arg2)
end
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
- if ( arg4 > 0 ) then
- string = format(GetText("LEVEL_UP_CHAR_POINTS", nil, arg4), arg4);
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ if arg4 > 0 then
+ string = format(GetText("LEVEL_UP_CHAR_POINTS", nil, arg4), arg4)
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
end
- if ( arg5 > 0 ) then
- string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT0_NAME), arg5);
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ if arg5 > 0 then
+ string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT0_NAME), arg5)
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
end
- if ( arg6 > 0 ) then
- string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT1_NAME), arg6);
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ if arg6 > 0 then
+ string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT1_NAME), arg6)
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
end
- if ( arg7 > 0 ) then
- string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT2_NAME), arg7);
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ if arg7 > 0 then
+ string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT2_NAME), arg7)
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
end
- if ( arg8 > 0 ) then
- string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT3_NAME), arg8);
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ if arg8 > 0 then
+ string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT3_NAME), arg8)
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
end
- if ( arg9 > 0 ) then
- string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT4_NAME), arg9);
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ if arg9 > 0 then
+ string = format(TEXT(LEVEL_UP_STAT), TEXT(SPELL_STAT4_NAME), arg9)
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
end
- return;
+ return
end
- if ( event == "CHARACTER_POINTS_CHANGED" ) then
- local info = ChatTypeInfo["SYSTEM"];
- if ( arg2 > 0 ) then
- local cp1, cp2 = UnitCharacterPoints("player");
- if ( cp2 ) then
- local string = format(GetText("LEVEL_UP_SKILL_POINTS", nil, cp2), cp2);
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ if event == "CHARACTER_POINTS_CHANGED" then
+ local info = ChatTypeInfo["SYSTEM"]
+ if arg2 > 0 then
+ local cp1, cp2 = UnitCharacterPoints("player")
+ if cp2 then
+ local string = format(GetText("LEVEL_UP_SKILL_POINTS", nil, cp2), cp2)
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
end
end
- return;
+ return
end
- if ( event == "GUILD_MOTD" ) then
- if ( arg1 and (strlen(arg1) > 0) ) then
- local info = ChatTypeInfo["GUILD"];
- local string = format(TEXT(GUILD_MOTD_TEMPLATE), arg1);
- self:AddMessage(string, info.r, info.g, info.b, info.id);
+ if event == "GUILD_MOTD" then
+ if arg1 and (strlen(arg1) > 0) then
+ local info = ChatTypeInfo["GUILD"]
+ local string = format(TEXT(GUILD_MOTD_TEMPLATE), arg1)
+ self:AddMessage(string, info.r, info.g, info.b, info.id)
end
- return;
+ return
end
- if ( event == "EXECUTE_CHAT_LINE" ) then
- self.editBox:SetText(arg1);
- ChatEdit_SendText(self.editBox);
- ChatEdit_OnEscapePressed(self.editBox);
- return;
+ if event == "EXECUTE_CHAT_LINE" then
+ self.editBox:SetText(arg1)
+ ChatEdit_SendText(self.editBox)
+ ChatEdit_OnEscapePressed(self.editBox)
+ return
end
- if ( event == "UPDATE_CHAT_COLOR" ) then
- local info = ChatTypeInfo[strupper(arg1)];
- if ( info ) then
- info.r = arg2;
- info.g = arg3;
- info.b = arg4;
- self:UpdateColorByID(info.id, info.r, info.g, info.b);
+ if event == "UPDATE_CHAT_COLOR" then
+ local info = ChatTypeInfo[strupper(arg1)]
+ if info then
+ info.r = arg2
+ info.g = arg3
+ info.b = arg4
+ self:UpdateColorByID(info.id, info.r, info.g, info.b)
- if ( strupper(arg1) == "WHISPER" ) then
- info = ChatTypeInfo["REPLY"];
- if ( info ) then
- info.r = arg2;
- info.g = arg3;
- info.b = arg4;
- self:UpdateColorByID(info.id, info.r, info.g, info.b);
+ if strupper(arg1) == "WHISPER" then
+ info = ChatTypeInfo["REPLY"]
+ if info then
+ info.r = arg2
+ info.g = arg3
+ info.b = arg4
+ self:UpdateColorByID(info.id, info.r, info.g, info.b)
end
end
end
- return;
+ return
end
if strsub(event, 1, 8) == "CHAT_MSG" then
local type = strsub(event, 10)
@@ -954,7 +993,7 @@ function CH:ChatFrame_MessageEventHandler(event, ...)
end
end
end
- if (found == 0) or not info then
+ if found == 0 or not info then
return true
end
end
@@ -1031,15 +1070,15 @@ function CH:ChatFrame_MessageEventHandler(event, ...)
arg1 = gsub(arg1, "%%", "%%%%")
end
- local showLink = 1;
- if ( strsub(type, 1, 7) == "MONSTER" or type == "RAID_BOSS_EMOTE" ) then
- showLink = nil;
+ local showLink = 1
+ if strsub(type, 1, 7) == "MONSTER" or type == "RAID_BOSS_EMOTE" then
+ showLink = nil
else
- arg1 = gsub(arg1, "%%", "%%%%");
+ arg1 = gsub(arg1, "%%", "%%%%")
end
if (strlen(arg3) > 0) and (arg3 ~= "Universal") and (arg3 ~= GetDefaultLanguage()) then
local languageHeader = "["..arg3.."] "
- if ( showLink and (strlen(arg2) > 0) ) then
+ if showLink and (strlen(arg2) > 0) then
body = format(_G["CHAT_"..type.."_GET"]..languageHeader..arg1, pflag.."|Hplayer:"..arg2.."|h".."["..arg2.."]".."|h")
else
body = format(_G["CHAT_"..type.."_GET"]..languageHeader..arg1, pflag..arg2)
@@ -1122,7 +1161,7 @@ local function OnTextChanged(self)
if strsub(text, 1, 4) == "/tt " then
local unitname, realm = UnitName("target")
if unitname and realm then
- unitname = unitname .. "-" .. realm:gsub(" ", "")
+ unitname = unitname .. "-" .. gsub(realm, " ", "")
end
ChatFrame_SendTell((unitname or L["Invalid Target"]), ChatFrame1)
end
@@ -1135,7 +1174,7 @@ local function OnTextChanged(self)
local new, found = gsub(text, "|Kf(%S+)|k(%S+)%s(%S+)|k", "%2 %3")
if found > 0 then
- new = new:gsub("|", "")
+ new = gsub(new, "|", "")
self:SetText(new)
end
end
@@ -1287,8 +1326,8 @@ end
local protectLinks = {}
function CH:CheckKeyword(message)
- for itemLink in message:gmatch("|%x+|Hitem:.-|h.-|h|r") do
- protectLinks[itemLink] = itemLink:gsub("%s","|s")
+ for itemLink in gmatch(message, "|%x+|Hitem:.-|h.-|h|r") do
+ protectLinks[itemLink] = gsub(itemLink, "%s","|s")
for keyword, _ in pairs(CH.Keywords) do
if itemLink == keyword then
if self.db.keywordSound ~= "None" and not self.SoundPlayed then
@@ -1301,17 +1340,17 @@ function CH:CheckKeyword(message)
end
for itemLink, tempLink in pairs(protectLinks) do
- message = message:gsub(itemLink:gsub("([%(%)%.%%%+%-%*%?%[%^%$])","%%%1"), tempLink)
+ message = gsub(message, gsub(itemLink, "([%(%)%.%%%+%-%*%?%[%^%$])","%%%1"), tempLink)
end
local classColorTable, tempWord, rebuiltString, lowerCaseWord, wordMatch, classMatch
local isFirstWord = true
- for word in message:gmatch("%s-[^%s]+%s*") do
- tempWord = word:gsub("[%s%p]", "")
- lowerCaseWord = tempWord:lower()
+ for word in gmatch(message, "%s-[^%s]+%s*") do
+ tempWord = gsub(word, "[%s%p]", "")
+ lowerCaseWord = strlower(tempWord)
for keyword, _ in pairs(CH.Keywords) do
- if lowerCaseWord == keyword:lower() then
- word = word:gsub(tempWord, format("%s%s|r", E.media.hexvaluecolor, tempWord))
+ if lowerCaseWord == strlower(keyword) then
+ word = gsub(word, tempWord, format("%s%s|r", E.media.hexvaluecolor, tempWord))
if self.db.keywordSound ~= "None" and not self.SoundPlayed then
PlaySoundFile(LSM:Fetch("sound", self.db.keywordSound), "Master")
self.SoundPlayed = true
@@ -1321,14 +1360,14 @@ function CH:CheckKeyword(message)
end
if self.db.classColorMentionsChat and E.private.general.classCache then
- tempWord = word:gsub("^[%s%p]-([^%s%p]+)([%-]?[^%s%p]-)[%s%p]*$","%1%2")
+ tempWord = gsub(word, "^[%s%p]-([^%s%p]+)([%-]?[^%s%p]-)[%s%p]*$","%1%2")
- --classMatch = CC:GetCacheTable()[E.myrealm][tempWord]
+ classMatch = CC:GetCacheTable()[E.myrealm][tempWord]
wordMatch = classMatch and lowerCaseWord
if wordMatch and not E.global.chat.classColorMentionExcludedNames[wordMatch] then
classColorTable = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[classMatch] or RAID_CLASS_COLORS[classMatch]
- word = word:gsub(tempWord:gsub("%-","%%-"), format("\124cff%.2x%.2x%.2x%s\124r", classColorTable.r*255, classColorTable.g*255, classColorTable.b*255, tempWord))
+ word = gsub(word, gsub(tempWord, "%-","%%-"), format("\124cff%.2x%.2x%.2x%s\124r", classColorTable.r*255, classColorTable.g*255, classColorTable.b*255, tempWord))
end
end
@@ -1341,7 +1380,7 @@ function CH:CheckKeyword(message)
end
for itemLink, tempLink in pairs(protectLinks) do
- rebuiltString = rebuiltString:gsub(tempLink:gsub("([%(%)%.%%%+%-%*%?%[%^%$])","%%%1"), itemLink)
+ rebuiltString = gsub(rebuiltString, gsub(tempLink, "([%(%)%.%%%+%-%*%?%[%^%$])","%%%1"), itemLink)
protectLinks[itemLink] = nil
end
@@ -1652,34 +1691,34 @@ function CH:Initialize()
end
--First get all pre-existing filters and copy them to our version of chatFilters using ChatFrame_GetMessageEventFilters
- --for name, _ in pairs(ChatTypeGroup) do
- -- for i = 1, getn(ChatTypeGroup[name]) do
- -- local filterFuncTable = ChatFrame_GetMessageEventFilters(ChatTypeGroup[name][i])
- -- if filterFuncTable then
- -- chatFilters[ChatTypeGroup[name][i]] = {}
- --
- -- for j = 1, getn(filterFuncTable) do
- -- local filterFunc = filterFuncTable[j]
- -- tinsert(chatFilters[ChatTypeGroup[name][i]], filterFunc)
- -- end
- -- end
- -- end
- --end
+ for name, _ in pairs(ChatTypeGroup) do
+ for i = 1, getn(ChatTypeGroup[name]) do
+ local filterFuncTable = ChatFrame_GetMessageEventFilters(ChatTypeGroup[name][i])
+ if filterFuncTable then
+ chatFilters[ChatTypeGroup[name][i]] = {}
+
+ for j = 1, getn(filterFuncTable) do
+ local filterFunc = filterFuncTable[j]
+ tinsert(chatFilters[ChatTypeGroup[name][i]], filterFunc)
+ end
+ end
+ end
+ end
--CHAT_MSG_CHANNEL isn't located inside ChatTypeGroup
- --local filterFuncTable = ChatFrame_GetMessageEventFilters("CHAT_MSG_CHANNEL")
- --if filterFuncTable then
- -- chatFilters["CHAT_MSG_CHANNEL"] = {}
- --
- -- for j = 1, getn(filterFuncTable) do
- -- local filterFunc = filterFuncTable[j]
- -- tinsert(chatFilters["CHAT_MSG_CHANNEL"], filterFunc)
- -- end
- --end
+ local filterFuncTable = ChatFrame_GetMessageEventFilters("CHAT_MSG_CHANNEL")
+ if filterFuncTable then
+ chatFilters["CHAT_MSG_CHANNEL"] = {}
+
+ for j = 1, getn(filterFuncTable) do
+ local filterFunc = filterFuncTable[j]
+ tinsert(chatFilters["CHAT_MSG_CHANNEL"], filterFunc)
+ end
+ end
--Now hook onto Blizzards functions for other addons
- --self:SecureHook("ChatFrame_AddMessageEventFilter")
- --self:SecureHook("ChatFrame_RemoveMessageEventFilter")
+ hooksecurefunc(self, "ChatFrame_AddMessageEventFilter", ChatFrame_AddMessageEventFilter)
+ hooksecurefunc(self, "ChatFrame_RemoveMessageEventFilter", ChatFrame_RemoveMessageEventFilter)
self:SecureHook("FCF_SetWindowAlpha")
@@ -1700,7 +1739,7 @@ function CH:Initialize()
end
for _, event in pairs(FindURL_Events) do
- --ChatFrame_AddMessageEventFilter(event, CH[event] or CH.FindURL)
+ ChatFrame_AddMessageEventFilter(event, CH[event] or CH.FindURL)
local nType = strsub(event, 10)
if nType ~= "AFK" and nType ~= "DND" then
self:RegisterEvent(event, "SaveChatHistory")
diff --git a/2/3/4/5/6/7/ElvUI/Modules/Misc/ChatBubbles.lua b/2/3/4/5/6/7/ElvUI/Modules/Misc/ChatBubbles.lua
index 8936812..0a86ef3 100644
--- a/2/3/4/5/6/7/ElvUI/Modules/Misc/ChatBubbles.lua
+++ b/2/3/4/5/6/7/ElvUI/Modules/Misc/ChatBubbles.lua
@@ -1,12 +1,12 @@
local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local M = E:GetModule("Misc");
--- local CH = E:GetModule("Chat");
--- local CC = E:GetModule("ClassCache");
+local CH = E:GetModule("Chat");
+local CC = E:GetModule("ClassCache");
--Cache global variables
--Lua functions
local select, unpack, type = select, unpack, type
-local format, gsub = string.format, string.gsub
+local format, gsub, match, gmatch = string.format, string.gsub, string.match, string.gmatch
local strlower = strlower
--WoW API / Variables
local CreateFrame = CreateFrame
@@ -29,17 +29,17 @@ function M:UpdateBubbleBorder()
if E.private.chat.enable and E.private.general.classCache and E.private.general.classColorMentionsSpeech then
local classColorTable, isFirstWord, rebuiltString, lowerCaseWord, tempWord, wordMatch, classMatch
local text = this.text:GetText()
- if text and text:match("%s-[^%s]+%s*") then
- for word in text:gmatch("%s-[^%s]+%s*") do
- tempWord = word:gsub("^[%s%p]-([^%s%p]+)([%-]?[^%s%p]-)[%s%p]*$","%1%2")
- lowerCaseWord = tempWord:lower()
+ if text and match(text, "%s-[^%s]+%s*") then
+ for word in gmatch(text, "%s-[^%s]+%s*") do
+ tempWord = gsub(word, "^[%s%p]-([^%s%p]+)([%-]?[^%s%p]-)[%s%p]*$","%1%2")
+ lowerCaseWord = strlower(tempWord)
classMatch = CC:GetCacheTable()[E.myrealm][tempWord]
wordMatch = classMatch and lowerCaseWord
if wordMatch and not E.global.chat.classColorMentionExcludedNames[wordMatch] then
classColorTable = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[classMatch] or RAID_CLASS_COLORS[classMatch]
- word = word:gsub(tempWord:gsub("%-","%%-"), format("\124cff%.2x%.2x%.2x%s\124r", classColorTable.r*255, classColorTable.g*255, classColorTable.b*255, tempWord))
+ word = gsub(word, gsub(tempWord, "%-","%%-"), format("\124cff%.2x%.2x%.2x%s\124r", classColorTable.r*255, classColorTable.g*255, classColorTable.b*255, tempWord))
end
if not isFirstWord then
diff --git a/2/3/4/5/6/7/ElvUI/Modules/NamePlates/NamePlates.lua b/2/3/4/5/6/7/ElvUI/Modules/NamePlates/NamePlates.lua
index 19a83eb..7eef647 100644
--- a/2/3/4/5/6/7/ElvUI/Modules/NamePlates/NamePlates.lua
+++ b/2/3/4/5/6/7/ElvUI/Modules/NamePlates/NamePlates.lua
@@ -1,13 +1,15 @@
-local E, L, V, P, G = unpack(ElvUI)
-local mod = E:NewModule("NamePlates", "AceHook-3.0", "AceEvent-3.0", "AceTimer-3.0")
---local CC = E:GetModule("ClassCache")
+local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
+local mod = E:NewModule("NamePlates", "AceHook-3.0", "AceEvent-3.0", "AceTimer-3.0");
+local CC = E:GetModule("ClassCache");
+--Cache global variables
+--Lua functions
local _G = _G
local pairs, tonumber = pairs, tonumber
local select = select
local gsub, match, split = string.gsub, string.match, string.split
local twipe = table.wipe
-
+--WoW API / Variables
local CreateFrame = CreateFrame
local GetBattlefieldScore = GetBattlefieldScore
local GetNumBattlefieldScores = GetNumBattlefieldScores
@@ -21,7 +23,7 @@ local WorldGetNumChildren, WorldGetChildren = WorldFrame.GetNumChildren, WorldFr
local numChildren = 0
local isTarget = false
local BORDER = "Interface\\Tooltips\\Nameplate-Border"
-local FSPAT = "%s*"
+local FSPAT = "^%s*$"
local queryList = {}
local RaidIconCoordinate = {
@@ -269,21 +271,21 @@ function mod:RoundColors(r, g, b)
end
function mod:UnitClass(name, type)
- if E.private.general.classCache then
+ --[[if E.private.general.classCache then
if type == "FRIENDLY_PLAYER" then
local _, class = UnitClass(name)
if class then
return class
else
local name, realm = split("-", name)
- --return CC:GetClassByName(name, realm)
+ return CC:GetClassByName(name, realm)
end
end
else
if type == "FRIENDLY_PLAYER" then
- --return select(2, UnitClass(name))
+ return select(2, UnitClass(name))
end
- end
+ end--]]
end
function mod:UnitDetailedThreatSituation(frame)
@@ -300,7 +302,7 @@ function mod:UnitLevel(frame)
end
function mod:GetUnitInfo(frame)
- --[[if UnitExists("target") == 1 and frame:GetParent():IsShown() and frame:GetParent():GetAlpha() == 1 then
+ if UnitExists("target") == 1 and frame:GetParent():IsShown() and frame:GetParent():GetAlpha() == 1 then
if UnitIsPlayer("target") then
if UnitIsEnemy("target", "player") then
return 2, "ENEMY_PLAYER"
@@ -316,7 +318,7 @@ function mod:GetUnitInfo(frame)
return 5, "FRIENDLY_NPC"
end
end
- end]]
+ end
local r, g, b = mod:RoundColors(frame.oldHealthBar:GetStatusBarColor())
if r == 1 and g == 0 and b == 0 then
@@ -708,7 +710,7 @@ function mod:PLAYER_REGEN_ENABLED()
end
end
---[[function mod:ClassCacheQueryResult(_, name, class)
+function mod:ClassCacheQueryResult(_, name, class)
if queryList[name] then
local frame = queryList[name]
@@ -726,7 +728,7 @@ end
queryList[name] = nil
end
-end]]
+end
function mod:Initialize()
self.db = E.db["nameplates"]
@@ -744,7 +746,7 @@ function mod:Initialize()
--self:RegisterEvent("UNIT_AURA")
--self:RegisterEvent("PLAYER_COMBO_POINTS")
- --self:RegisterMessage("ClassCacheQueryResult")
+ self:RegisterMessage("ClassCacheQueryResult")
E.NamePlates = self
end
diff --git a/2/3/4/5/6/7/ElvUI/Settings/Global.lua b/2/3/4/5/6/7/ElvUI/Settings/Global.lua
index 3fbfa44..672e99f 100644
--- a/2/3/4/5/6/7/ElvUI/Settings/Global.lua
+++ b/2/3/4/5/6/7/ElvUI/Settings/Global.lua
@@ -15,6 +15,16 @@ G["general"] = {
["versionCheck"] = true
}
+G["classCache"] = {}
+
+G["classtimer"] = {}
+
+G["nameplates"] = {}
+
+G["chat"] = {
+ ["classColorMentionExcludedNames"] = {}
+}
+
G["bags"] = {
["ignoredItems"] = {}
}
\ No newline at end of file
diff --git a/2/3/4/5/6/7/ElvUI/Settings/Private.lua b/2/3/4/5/6/7/ElvUI/Settings/Private.lua
index 46b5109..03bb53a 100644
--- a/2/3/4/5/6/7/ElvUI/Settings/Private.lua
+++ b/2/3/4/5/6/7/ElvUI/Settings/Private.lua
@@ -21,6 +21,8 @@ V["general"] = {
["hideCalendar"] = true,
["zoomLevel"] = 0,
},
+ ["classCache"] = true,
+ ["classColorMentionsSpeech"] = true,
}
V["bags"] = {
diff --git a/2/3/4/5/6/7/ElvUI/Settings/Profile.lua b/2/3/4/5/6/7/ElvUI/Settings/Profile.lua
index 5f65729..7c97da0 100644
--- a/2/3/4/5/6/7/ElvUI/Settings/Profile.lua
+++ b/2/3/4/5/6/7/ElvUI/Settings/Profile.lua
@@ -28,6 +28,9 @@ P["general"] = {
["backdropfadecolor"] = {r = .06, g = .06, b = .06, a = 0.8},
["valuecolor"] = {r = 254/255, g = 123/255, b = 44/255},
+ ["classCacheStoreInDB"] = true,
+ ["classCacheRequestInfo"] = false,
+
["minimap"] = {
["size"] = 176,
["locationText"] = "MOUSEOVER",
diff --git a/2/3/4/5/6/7/ElvUI_Config/General.lua b/2/3/4/5/6/7/ElvUI_Config/General.lua
index 07e4be0..4459811 100644
--- a/2/3/4/5/6/7/ElvUI_Config/General.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/General.lua
@@ -1,4 +1,5 @@
local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
+local CC = E:GetModule("ClassCache");
E.Options.args.general = {
type = "group",
@@ -208,7 +209,66 @@ E.Options.args.general = {
min = 0, max = 4, step = 1,
get = function(info) return E.db.general.decimalLength end,
set = function(info, value) E.db.general.decimalLength = value; E:StaticPopup_Show("GLOBAL_RL") end
- }
+ },
+ classCacheHeader = {
+ order = 51,
+ type = "header",
+ name = L["Class Cache"]
+ },
+ classCacheEnable = {
+ order = 52,
+ type = "toggle",
+ name = L["Enable"],
+ desc = L["Enable class caching to colorize names in chat and nameplates."],
+ get = function(info) return E.private.general.classCache end,
+ set = function(info, value)
+ E.private.general.classCache = value
+ CC:ToggleModule()
+ end
+ },
+ classCacheStoreInDB = {
+ order = 53,
+ type = "toggle",
+ name = L["Store cache in DB"],
+ desc = L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."],
+ get = function(info) return E.db.general.classCacheStoreInDB end,
+ set = function(info, value)
+ E.db.general.classCacheStoreInDB = value
+ CC:SwitchCacheType()
+ end,
+ disabled = function() return not E.private.general.classCache end
+ },
+ classCacheRequestInfo = {
+ order = 54,
+ type = "toggle",
+ name = L["Request info for class cache"],
+ desc = L["Use LibWho to cache class info"],
+ get = function(info) return E.db.general.classCacheRequestInfo end,
+ set = function(info, value)
+ E.db.general.classCacheRequestInfo = value
+ end,
+ disabled = function() return not E.private.general.classCache end
+ },
+ wipeClassCacheGlobal = {
+ order = 55,
+ type = "execute",
+ name = L["Wipe DB Cache"],
+ func = function()
+ CC:WipeCache(true)
+ GameTooltip:Hide()
+ end,
+ disabled = function() return not CC:GetCacheSize(true) end
+ },
+ wipeClassCacheLocal = {
+ order = 56,
+ type = "execute",
+ name = L["Wipe Session Cache"],
+ func = function()
+ CC:WipeCache()
+ GameTooltip:Hide()
+ end,
+ disabled = function() return not CC:GetCacheSize() end
+ }
}
},
media = {
diff --git a/2/3/4/5/6/7/ElvUI_Config/Locales/Chinese_Config.lua b/2/3/4/5/6/7/ElvUI_Config/Locales/Chinese_Config.lua
index 3aae474..35d19b2 100644
--- a/2/3/4/5/6/7/ElvUI_Config/Locales/Chinese_Config.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/Locales/Chinese_Config.lua
@@ -310,6 +310,16 @@ Or for most users it would be easier to simply put a tga file into your WoW fold
对多数玩家来说, 较简易的方式是将 tga 档放入 WoW 资料夹中, 然后在此处输入档案名称.]]
+--Class Cache
+L["Class Cache"] = true;
+L["Enable class caching to colorize names in chat and nameplates."] = true;
+L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."] = true;
+L["Request info for class cache"] = true;
+L["Store cache in DB"] = true;
+L["Use LibWho to cache class info"] = true;
+L["Wipe DB Cache"] = true;
+L["Wipe Session Cache"] = true;
+
--Credits
L["Coding:"] = "编码:"
L["Credits"] = "呜谢"
diff --git a/2/3/4/5/6/7/ElvUI_Config/Locales/English_Config.lua b/2/3/4/5/6/7/ElvUI_Config/Locales/English_Config.lua
index 28d9fe2..991c65c 100644
--- a/2/3/4/5/6/7/ElvUI_Config/Locales/English_Config.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/Locales/English_Config.lua
@@ -299,6 +299,16 @@ Example: Interface\AddOns\ElvUI\media\textures\copy
Or for most users it would be easier to simply put a tga file into your WoW folder, then type the name of the file here.]] ] = true;
+--Class Cache
+L["Class Cache"] = true;
+L["Enable class caching to colorize names in chat and nameplates."] = true;
+L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."] = true;
+L["Request info for class cache"] = true;
+L["Store cache in DB"] = true;
+L["Use LibWho to cache class info"] = true;
+L["Wipe DB Cache"] = true;
+L["Wipe Session Cache"] = true;
+
--Credits
L["Coding:"] = true;
L["Credits"] = true;
diff --git a/2/3/4/5/6/7/ElvUI_Config/Locales/French_Config.lua b/2/3/4/5/6/7/ElvUI_Config/Locales/French_Config.lua
index 853d490..54c6fbc 100644
--- a/2/3/4/5/6/7/ElvUI_Config/Locales/French_Config.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/Locales/French_Config.lua
@@ -310,6 +310,16 @@ Exemple: Interface\AddOns\ElvUI\media\textures\copy
Ou pour la majorité des utilsateurs, il serait plus simple de mettre le fichier tga dans le dossier de World of Warcraft puis de taper son nom ici.]]
+--Class Cache
+L["Class Cache"] = true;
+L["Enable class caching to colorize names in chat and nameplates."] = true;
+L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."] = true;
+L["Request info for class cache"] = true;
+L["Store cache in DB"] = true;
+L["Use LibWho to cache class info"] = true;
+L["Wipe DB Cache"] = true;
+L["Wipe Session Cache"] = true;
+
--Credits
L["Coding:"] = "Codage: "
L["Credits"] = "Crédits"
diff --git a/2/3/4/5/6/7/ElvUI_Config/Locales/German_Config.lua b/2/3/4/5/6/7/ElvUI_Config/Locales/German_Config.lua
index 3d2888a..d5f9cc1 100644
--- a/2/3/4/5/6/7/ElvUI_Config/Locales/German_Config.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/Locales/German_Config.lua
@@ -310,6 +310,16 @@ Zum Beispiel: Interface\AddOns\ElvUI\media\textures\copy
Für die meisten Anwender ist es allerdigns einfacher, eine tga-Datei in ihren WoW-Ordner abzulegen. Anschließend kann man den Namen der Datei hier eingeben.]]
+--Class Cache
+L["Class Cache"] = true;
+L["Enable class caching to colorize names in chat and nameplates."] = true;
+L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."] = true;
+L["Request info for class cache"] = true;
+L["Store cache in DB"] = true;
+L["Use LibWho to cache class info"] = true;
+L["Wipe DB Cache"] = true;
+L["Wipe Session Cache"] = true;
+
--Credits
L["Coding:"] = "Programmierung:"
L["Credits"] = "Danksagung"
diff --git a/2/3/4/5/6/7/ElvUI_Config/Locales/Korean_Config.lua b/2/3/4/5/6/7/ElvUI_Config/Locales/Korean_Config.lua
index 399afc7..f4fa42c 100644
--- a/2/3/4/5/6/7/ElvUI_Config/Locales/Korean_Config.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/Locales/Korean_Config.lua
@@ -358,6 +358,16 @@ Or for most users it would be easier to simply put a tga file into your WoW fold
간단히는 그림을 와우 설치 폴더에 넣은후 파일명만 적으세요.]]
+--Class Cache
+L["Class Cache"] = true;
+L["Enable class caching to colorize names in chat and nameplates."] = true;
+L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."] = true;
+L["Request info for class cache"] = true;
+L["Store cache in DB"] = true;
+L["Use LibWho to cache class info"] = true;
+L["Wipe DB Cache"] = true;
+L["Wipe Session Cache"] = true;
+
--Credits
L["Coding:"] = "|cff2eb7e4< 개발자 >|r"
L["Credits"] = "제작자"
diff --git a/2/3/4/5/6/7/ElvUI_Config/Locales/Portuguese_Config.lua b/2/3/4/5/6/7/ElvUI_Config/Locales/Portuguese_Config.lua
index cc802d0..dd37227 100644
--- a/2/3/4/5/6/7/ElvUI_Config/Locales/Portuguese_Config.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/Locales/Portuguese_Config.lua
@@ -310,6 +310,16 @@ Example: Interface\AddOns\ElvUI\media\textures\copy
Para a maioria dos usuários seria mais fácil simplesmente copiar o ficheiro tga na pasta do WoW e depois escrever o nome dele aqui.]]
+--Class Cache
+L["Class Cache"] = true;
+L["Enable class caching to colorize names in chat and nameplates."] = true;
+L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."] = true;
+L["Request info for class cache"] = true;
+L["Store cache in DB"] = true;
+L["Use LibWho to cache class info"] = true;
+L["Wipe DB Cache"] = true;
+L["Wipe Session Cache"] = true;
+
--Credits
L["Coding:"] = "Codificação:"
L["Credits"] = "Créditos"
diff --git a/2/3/4/5/6/7/ElvUI_Config/Locales/Russian_Config.lua b/2/3/4/5/6/7/ElvUI_Config/Locales/Russian_Config.lua
index a1b11ab..354128d 100644
--- a/2/3/4/5/6/7/ElvUI_Config/Locales/Russian_Config.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/Locales/Russian_Config.lua
@@ -310,6 +310,16 @@ Or for most users it would be easier to simply put a tga file into your WoW fold
Для большинства пользователей будет легче просто положить tga файл в папку игры, а затем написать имя файла здесь.]]
+--Class Cache
+L["Class Cache"] = true;
+L["Enable class caching to colorize names in chat and nameplates."] = true;
+L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."] = true;
+L["Request info for class cache"] = true;
+L["Store cache in DB"] = true;
+L["Use LibWho to cache class info"] = true;
+L["Wipe DB Cache"] = true;
+L["Wipe Session Cache"] = true;
+
--Credits
L["Coding:"] = "Написание кода:"
L["Credits"] = "Благодарности"
diff --git a/2/3/4/5/6/7/ElvUI_Config/Locales/Spanish_Config.lua b/2/3/4/5/6/7/ElvUI_Config/Locales/Spanish_Config.lua
index 8a5873a..1629bb9 100644
--- a/2/3/4/5/6/7/ElvUI_Config/Locales/Spanish_Config.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/Locales/Spanish_Config.lua
@@ -310,6 +310,16 @@ Ejemplo: Interface\AddOns\ElvUI\media\textures\copy
O también puedes simplemente colocar un archivo tga en la carpeta de WoW, y escribir aquí el nombre del archivo.]]
+--Class Cache
+L["Class Cache"] = true;
+L["Enable class caching to colorize names in chat and nameplates."] = true;
+L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."] = true;
+L["Request info for class cache"] = true;
+L["Store cache in DB"] = true;
+L["Use LibWho to cache class info"] = true;
+L["Wipe DB Cache"] = true;
+L["Wipe Session Cache"] = true;
+
--Credits
L["Coding:"] = "Codificación:"
L["Credits"] = "Créditos"
diff --git a/2/3/4/5/6/7/ElvUI_Config/Locales/Taiwanese_Config.lua b/2/3/4/5/6/7/ElvUI_Config/Locales/Taiwanese_Config.lua
index b1b627b..ddb36f3 100644
--- a/2/3/4/5/6/7/ElvUI_Config/Locales/Taiwanese_Config.lua
+++ b/2/3/4/5/6/7/ElvUI_Config/Locales/Taiwanese_Config.lua
@@ -310,6 +310,16 @@ Or for most users it would be easier to simply put a tga file into your WoW fold
對多數玩家來說, 較簡易的方式是將 tga 檔放入 WoW 資料夾中, 然後在此處輸入檔案名稱.]]
+--Class Cache
+L["Class Cache"] = true;
+L["Enable class caching to colorize names in chat and nameplates."] = true;
+L["If cache stored in DB it will be available between game sessions but increase memory usage.\nIn other way it will be wiped on relog or UI reload."] = true;
+L["Request info for class cache"] = true;
+L["Store cache in DB"] = true;
+L["Use LibWho to cache class info"] = true;
+L["Wipe DB Cache"] = true;
+L["Wipe Session Cache"] = true;
+
--Credits
L["Coding:"] = "編碼:"
L["Credits"] = "嗚謝"