Show main names on alts
This commit is contained in:
+238
@@ -0,0 +1,238 @@
|
||||
-- AltNames: Display main character names from guild public notes
|
||||
-- Reads @Mainname from guild officer/public notes and appends (Mainname)
|
||||
-- Hooks into pfUI unit frames/nameplates (if installed), Blizzard chat and raid UI
|
||||
|
||||
AltNames = CreateFrame("Frame")
|
||||
|
||||
-- Lookup table: lowercase charname -> main name (proper case)
|
||||
AltNames.cache = {}
|
||||
|
||||
-- Scan guild roster and build the cache
|
||||
function AltNames:ScanGuildRoster()
|
||||
local num = GetNumGuildMembers(true)
|
||||
if num == 0 then return end
|
||||
|
||||
local newcache = {}
|
||||
for i = 1, num do
|
||||
local name, _, _, _, _, _, note = GetGuildRosterInfo(i)
|
||||
if name and note then
|
||||
local main = string.gsub(note, "^.*@(%w+).*$", "%1")
|
||||
-- Only store if the pattern actually matched (main ~= note means it matched)
|
||||
if main ~= note and main ~= "" then
|
||||
newcache[string.lower(name)] = main
|
||||
end
|
||||
end
|
||||
end
|
||||
self.cache = newcache
|
||||
end
|
||||
|
||||
-- Get main name for a character name, returns nil if none
|
||||
function AltNames:GetMain(name)
|
||||
if not name or name == "" then return nil end
|
||||
return self.cache[string.lower(name)]
|
||||
end
|
||||
|
||||
-- Append " (Main)" to a name string if alt is found
|
||||
function AltNames:AppendMain(name)
|
||||
if not name or name == "" then return name end
|
||||
local main = self:GetMain(name)
|
||||
if main then
|
||||
return name .. " (" .. main .. ")"
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Event handling: scan guild roster on relevant events
|
||||
---------------------------------------------------------------------------
|
||||
AltNames:RegisterEvent("GUILD_ROSTER_UPDATE")
|
||||
AltNames:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
AltNames:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
|
||||
AltNames:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
-- Request guild roster data
|
||||
if IsInGuild() then
|
||||
GuildRoster()
|
||||
end
|
||||
end
|
||||
-- Scan on any guild roster event
|
||||
if IsInGuild() then
|
||||
AltNames:ScanGuildRoster()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Also rescan periodically (every 30s) to catch updates
|
||||
AltNames.elapsed = 0
|
||||
AltNames:SetScript("OnUpdate", function()
|
||||
AltNames.elapsed = AltNames.elapsed + arg1
|
||||
if AltNames.elapsed > 30 then
|
||||
AltNames.elapsed = 0
|
||||
if IsInGuild() then
|
||||
GuildRoster()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- HOOK 1: pfUI unit frames (raid frames, group frames, player, target, etc.)
|
||||
-- Hook pfUI.uf:GetNameString to append main name
|
||||
---------------------------------------------------------------------------
|
||||
local function HookUnitFrames()
|
||||
if not pfUI or not pfUI.uf or not pfUI.uf.GetNameString then return end
|
||||
|
||||
local origGetNameString = pfUI.uf.GetNameString
|
||||
|
||||
pfUI.uf.GetNameString = function(self, unitstr)
|
||||
local name = origGetNameString(self, unitstr)
|
||||
if not name or not unitstr then return name end
|
||||
|
||||
-- Only modify for players
|
||||
if not UnitIsPlayer(unitstr) then return name end
|
||||
|
||||
local main = AltNames:GetMain(name)
|
||||
if main then
|
||||
return name .. " (" .. main .. ")"
|
||||
end
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- HOOK 2: pfUI nameplates
|
||||
-- The nameplate module uses a local GetNameString, so we hook the SetText
|
||||
-- on the nameplate name FontString after OnDataChanged runs
|
||||
---------------------------------------------------------------------------
|
||||
local function HookNameplates()
|
||||
if not pfUI or not pfUI.nameplates or not pfUI.nameplates.OnDataChanged then return end
|
||||
|
||||
local origOnDataChanged = pfUI.nameplates.OnDataChanged
|
||||
|
||||
pfUI.nameplates.OnDataChanged = function(self, plate)
|
||||
origOnDataChanged(self, plate)
|
||||
|
||||
-- After pfUI sets the name, append main name if applicable
|
||||
if plate and plate.name then
|
||||
local text = plate.name:GetText()
|
||||
if text and text ~= "" then
|
||||
-- Only modify if not already modified (avoid double-appending)
|
||||
if not string.find(text, " %(") then
|
||||
local main = AltNames:GetMain(text)
|
||||
if main then
|
||||
plate.name:SetText(text .. " (" .. main .. ")")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- HOOK 3: Chat messages
|
||||
-- Hook each ChatFrame's AddMessage to inject main names into player links
|
||||
---------------------------------------------------------------------------
|
||||
local function HookChat()
|
||||
-- Hook each ChatFrame's AddMessage
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
if cf and cf.AddMessage then
|
||||
local prevAddMessage = cf.AddMessage
|
||||
|
||||
cf.AddMessage = function(frame, text, a1, a2, a3, a4, a5)
|
||||
if text then
|
||||
-- Match player links: |Hplayer:Name|h<color>Name|h or |Hplayer:Name|h[Name]|h
|
||||
-- Append (Main) after the displayed name inside the link
|
||||
text = string.gsub(text, "(|Hplayer:)([^|:]+)([^|]*|h)([^|]-)(|h)", function(pre, pname, mid, display, post)
|
||||
local real = pname
|
||||
local dashpos = string.find(real, "%-")
|
||||
if dashpos then
|
||||
real = string.sub(real, 1, dashpos - 1)
|
||||
end
|
||||
local main = AltNames:GetMain(real)
|
||||
if main and not string.find(display, "%(" .. main .. "%)") then
|
||||
return pre .. pname .. mid .. display .. " (" .. main .. ")" .. post
|
||||
else
|
||||
return pre .. pname .. mid .. display .. post
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
return prevAddMessage(frame, text, a1, a2, a3, a4, a5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- HOOK 4: Blizzard Raid UI (Blizzard_RaidUI)
|
||||
-- Hook the raid member name buttons in the default raid window
|
||||
---------------------------------------------------------------------------
|
||||
local function HookBlizzardRaidUI()
|
||||
-- Hook RaidGroupFrame name updates
|
||||
local origRaidGroupFrame_Update = _G.RaidGroupFrame_Update
|
||||
if origRaidGroupFrame_Update then
|
||||
_G.RaidGroupFrame_Update = function()
|
||||
origRaidGroupFrame_Update()
|
||||
-- After the default update, modify displayed names
|
||||
for i = 1, 40 do
|
||||
local btn = _G["RaidGroupButton" .. i]
|
||||
if btn and btn:IsVisible() then
|
||||
local nameLabel = _G["RaidGroupButton" .. i .. "Name"]
|
||||
if nameLabel then
|
||||
local text = nameLabel:GetText()
|
||||
if text and text ~= "" and not string.find(text, " %(") then
|
||||
local main = AltNames:GetMain(text)
|
||||
if main then
|
||||
nameLabel:SetText(text .. " (" .. main .. ")")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Also hook RaidGroup_Update for the group sub-frames
|
||||
local origRaidGroup_Update = _G.RaidGroup_Update
|
||||
if origRaidGroup_Update then
|
||||
_G.RaidGroup_Update = function(a1, a2, a3, a4, a5)
|
||||
origRaidGroup_Update(a1, a2, a3, a4, a5)
|
||||
for group = 1, 8 do
|
||||
for slot = 1, 5 do
|
||||
local fname = "RaidGroup" .. group .. "Slot" .. slot
|
||||
local nameLabel = _G[fname .. "Name"]
|
||||
if nameLabel then
|
||||
local text = nameLabel:GetText()
|
||||
if text and text ~= "" and not string.find(text, " %(") then
|
||||
local main = AltNames:GetMain(text)
|
||||
if main then
|
||||
nameLabel:SetText(text .. " (" .. main .. ")")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Initialize hooks after pfUI has loaded
|
||||
---------------------------------------------------------------------------
|
||||
local initFrame = CreateFrame("Frame")
|
||||
initFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
initFrame:SetScript("OnEvent", function()
|
||||
-- Delay to ensure addon modules are loaded
|
||||
initFrame.timer = 0
|
||||
initFrame:SetScript("OnUpdate", function()
|
||||
initFrame.timer = initFrame.timer + arg1
|
||||
if initFrame.timer > 2 then
|
||||
initFrame:SetScript("OnUpdate", nil)
|
||||
HookUnitFrames()
|
||||
HookNameplates()
|
||||
HookChat()
|
||||
HookBlizzardRaidUI()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
+3
-2
@@ -7,7 +7,7 @@
|
||||
## X-Website: https://github.com/cinecom/shootyepgp/
|
||||
## X-Category: Guild
|
||||
## X-Credits: shooty, Qcat(zhCN)
|
||||
## Version: 10.19.11 <ERROR>
|
||||
## Version: 10.19.12 <ERROR>
|
||||
## X-Alpha:
|
||||
## OptionalDeps: Ace2
|
||||
## SavedVariables: sepgp_saychannel, sepgp_groupbyclass, sepgp_groupbyarmor, sepgp_groupbyrole, sepgp_raidonly, sepgp_dbver, sepgp_debug, sepgp_fubar, sepgp_sound, RaidStrikeDB, RaidStrikeResetTime
|
||||
@@ -48,4 +48,5 @@ logs.lua
|
||||
matrix.lua
|
||||
raidstrike.lua
|
||||
bench.lua
|
||||
snowball.lua
|
||||
snowball.lua
|
||||
altnames.lua
|
||||
Reference in New Issue
Block a user