chore: move addon into Chatter/ + add standard .gitignore
Matches the Exiles fork-layout convention (each addon in its own folder).
This commit is contained in:
@@ -0,0 +1,352 @@
|
||||
local mod = Chatter:NewModule("Alt Linking", "AceHook-3.0", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Alt Linking"]
|
||||
|
||||
local NAMES
|
||||
local GUILDNOTES
|
||||
local pairs = _G.pairs
|
||||
local select = _G.select
|
||||
local setmetatable = _G.setmetatable
|
||||
local tinsert = _G.tinsert
|
||||
local tremove = _G.tremove
|
||||
local type = _G.type
|
||||
local unpack = _G.unpack
|
||||
local strlower= _G.string.lower
|
||||
local gmatch = _G.string.gmatch
|
||||
|
||||
local leftBracket, rightBracket
|
||||
|
||||
local defaults = {
|
||||
realm = {},
|
||||
profile = {
|
||||
guildNotes=true,
|
||||
altNotesFallback=true,
|
||||
colorMode = "COLOR_MOD",
|
||||
color = {0.6, 0.6, 0.6},
|
||||
leftBracket = "[",
|
||||
rightBracket = "]",
|
||||
}
|
||||
}
|
||||
local colorModes = {
|
||||
COLOR_MOD = L["Use PlayerNames coloring"],
|
||||
CUSTOM = L["Use custom color"],
|
||||
CHANNEL = L["Use channel color"]
|
||||
}
|
||||
|
||||
local customColorNames = setmetatable({}, {
|
||||
__index = function(t, v)
|
||||
local r, g, b = unpack(mod.db.profile.color)
|
||||
t[v] = ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, v)
|
||||
return t[v]
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
local options
|
||||
function mod:GetOptions()
|
||||
options = options or {
|
||||
guildNotes = {
|
||||
order=100,
|
||||
type = "toggle",
|
||||
name = L["Use guildnotes"],
|
||||
desc = L["Look in guildnotes for character names, unless a note is set manually"],
|
||||
get = function()
|
||||
return mod.db.profile.guildNotes
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.guildNotes = v
|
||||
mod:EnableGuildNotes(v)
|
||||
end,
|
||||
},
|
||||
altNotesFallback = {
|
||||
order=101,
|
||||
type = "toggle",
|
||||
name = L["Alt note fallback"],
|
||||
desc = L["If no name can be found for an 'alt' rank character, use entire note"],
|
||||
disabled = function()
|
||||
return not mod.db.profile.guildNotes
|
||||
end,
|
||||
get = function()
|
||||
return mod.db.profile.altNotesFallback
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.altNotesFallback = v
|
||||
mod:ScanGuildNotes()
|
||||
end,
|
||||
},
|
||||
colorMode = {
|
||||
order=110,
|
||||
type = "select",
|
||||
name = L["Name color"],
|
||||
desc = L["Set the coloring mode for alt names"],
|
||||
values = colorModes,
|
||||
get = function()
|
||||
return mod.db.profile.colorMode
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.colorMode = v
|
||||
end
|
||||
},
|
||||
color = {
|
||||
order=111,
|
||||
type = "color",
|
||||
name = L["Custom color"],
|
||||
desc = L["Select the custom color to use for alt names"],
|
||||
get = function()
|
||||
return unpack(mod.db.profile.color)
|
||||
end,
|
||||
set = function(info, r, g, b)
|
||||
mod.db.profile.color[1] = r
|
||||
mod.db.profile.color[2] = g
|
||||
mod.db.profile.color[3] = b
|
||||
for k, v in pairs(customColorNames) do
|
||||
customColorNames[k] = nil
|
||||
end
|
||||
end,
|
||||
disabled = function() return mod.db.profile.colorMode ~= "CUSTOM" end
|
||||
},
|
||||
leftbracket = {
|
||||
type = "input",
|
||||
name = L["Left Bracket"],
|
||||
desc = L["Character to use for the left bracket"],
|
||||
get = function() return mod.db.profile.leftBracket end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.leftBracket = v
|
||||
leftBracket = v
|
||||
end
|
||||
},
|
||||
rightbracket = {
|
||||
type = "input",
|
||||
name = L["Right Bracket"],
|
||||
desc = L["Character to use for the right bracket"],
|
||||
get = function() return mod.db.profile.rightBracket end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.rightBracket = v
|
||||
rightBracket = v
|
||||
end
|
||||
},
|
||||
}
|
||||
return options
|
||||
end
|
||||
|
||||
|
||||
|
||||
local accept = function(self, char)
|
||||
local editBox = _G[this:GetParent():GetName().."EditBox"]
|
||||
local main = editBox:GetText()
|
||||
mod:AddAlt(char, main)
|
||||
this:GetParent():Hide()
|
||||
end
|
||||
|
||||
StaticPopupDialogs['MENUITEM_SET_MAIN'] = {
|
||||
text = L["Who is %s's main?"],
|
||||
button1 = TEXT(ACCEPT),
|
||||
button2 = TEXT(CANCEL),
|
||||
hasEditBox = 1,
|
||||
maxLetters = 128,
|
||||
exclusive = 0,
|
||||
OnShow = function()
|
||||
_G[this:GetName().."EditBox"]:SetFocus()
|
||||
end,
|
||||
OnHide = function()
|
||||
if ( _G[this:GetName().."EditBox"]:IsShown() ) then
|
||||
_G[this:GetName().."EditBox"]:SetFocus();
|
||||
end
|
||||
_G[this:GetName().."EditBox"]:SetText("");
|
||||
end,
|
||||
OnAccept = accept,
|
||||
EditBoxOnEnterPressed = accept,
|
||||
EditBoxOnEscapePressed = function() this:GetParent():Hide() end,
|
||||
timeout = 0,
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1
|
||||
}
|
||||
|
||||
UnitPopupButtons["SET_MAIN"] = {
|
||||
text = L["Set Main"],
|
||||
dist = 0,
|
||||
func = mod.GetMainName
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("AltLinks", defaults)
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
if not self:IsHooked(frame,"AddMessage") then
|
||||
self:RawHook(frame, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
NAMES = self.db.realm
|
||||
UnitPopupButtons["SET_MAIN"].func = self.GetMainName
|
||||
tinsert(UnitPopupMenus["SELF"], #UnitPopupMenus["SELF"] - 1, "SET_MAIN")
|
||||
tinsert(UnitPopupMenus["PLAYER"], #UnitPopupMenus["PLAYER"] - 1, "SET_MAIN")
|
||||
tinsert(UnitPopupMenus["FRIEND"], #UnitPopupMenus["FRIEND"] - 1, "SET_MAIN")
|
||||
tinsert(UnitPopupMenus["PARTY"], #UnitPopupMenus["PARTY"] - 1, "SET_MAIN")
|
||||
self:SecureHook("UnitPopup_ShowMenu")
|
||||
|
||||
leftBracket, rightBracket = self.db.profile.leftBracket, self.db.profile.rightBracket
|
||||
|
||||
mod:EnableGuildNotes(mod.db.profile.guildNotes)
|
||||
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
if cf ~= COMBATLOG then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
self.colorMod = Chatter:GetModule("Player Class Colors")
|
||||
end
|
||||
|
||||
local types = {"SELF", "PLAYER", "FRIEND", "PARTY"}
|
||||
function mod:OnDisable()
|
||||
for j = 1, #types do
|
||||
local t = types[j]
|
||||
for i = 1, #UnitPopupMenus[t] do
|
||||
if UnitPopupMenus[t][i] == "SET_MAIN" then
|
||||
tremove(UnitPopupMenus[t], i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
mod:EnableGuildNotes(false)
|
||||
end
|
||||
|
||||
|
||||
function mod.GetMainName()
|
||||
local alt = UIDROPDOWNMENU_INIT_MENU.name
|
||||
local popup = StaticPopup_Show("MENUITEM_SET_MAIN", alt)
|
||||
if popup then
|
||||
popup.data = alt
|
||||
local editbox = getglobal(popup:GetName().."EditBox")
|
||||
editbox:SetText(NAMES[alt] or GUILDNOTES[alt] or "")
|
||||
editbox:HighlightText()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:UnitPopup_ShowMenu(dropdownMenu, which, unit, name, userData, ...)
|
||||
for i=1, UIDROPDOWNMENU_MAXBUTTONS do
|
||||
local button = _G["DropDownList"..UIDROPDOWNMENU_MENU_LEVEL.."Button"..i];
|
||||
if button.value == "SET_MAIN" then
|
||||
button.func = UnitPopupButtons["SET_MAIN"].func
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:AddAlt(alt, main)
|
||||
if #main == 0 then
|
||||
if GUILDNOTES[alt] then
|
||||
-- let the user store an empty note, meaning "dont show me this main"
|
||||
else
|
||||
main = nil
|
||||
end
|
||||
end
|
||||
NAMES[alt] = main
|
||||
end
|
||||
|
||||
local function pName(msg, name)
|
||||
if name and #name > 0 then
|
||||
local alt = NAMES[name] or GUILDNOTES[name]
|
||||
if alt and alt ~= "" then -- empty notes can be stored to override guildnote data
|
||||
local mode = mod.db.profile.colorMode
|
||||
if mode == "CUSTOM" then
|
||||
alt = customColorNames[alt]
|
||||
elseif mode == "COLOR_MOD" and mod.colorMod and mod.colorMod:IsEnabled() then
|
||||
alt = mod.colorMod:ColorName(alt)
|
||||
end
|
||||
return ("%s%s%s%s"):format( msg, leftBracket, alt, rightBracket )
|
||||
end
|
||||
end
|
||||
return msg
|
||||
end
|
||||
|
||||
function mod:AddMessage(frame, text, ...)
|
||||
if text and type(text) == "string" then
|
||||
--text = text:gsub("(|Hplayer:([^:]+)[:%d+]*|h.-|h)", pName)
|
||||
text = text:gsub("(|Hplayer:([^:]+).-|h.-|h)", pName)
|
||||
end
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Enables you to right-click a person's name in chat and set a note on them to be displayed in chat, such as their main character's name. Can also scan guild notes for character names to display, if no note has been manually set."]
|
||||
end
|
||||
|
||||
function mod:EnableGuildNotes(enable)
|
||||
GUILDNOTES={}
|
||||
if enable then
|
||||
mod:RegisterEvent("GUILD_ROSTER_UPDATE")
|
||||
if IsInGuild() then
|
||||
GuildRoster()
|
||||
end
|
||||
mod:ScanGuildNotes() -- Unfortunately we can't count on GuildRoster() triggering the event if someone else triggered it recently. So we try once at first straight off the bat.
|
||||
else
|
||||
mod:UnregisterEvent("GUILD_ROSTER_UPDATE")
|
||||
end
|
||||
end
|
||||
|
||||
local doscan=true -- always the first time we start up
|
||||
function mod:GUILD_ROSTER_UPDATE(event,arg1)
|
||||
-- arg1 gets set for SOME changes to the guild, but notably not for player notes.. doh (unless you're the one editing them yourself)
|
||||
-- we force a scan when the guild frame is actually visible (i.e. when we know the player is actually interested in seeing changes)
|
||||
-- i'd like to be able to not have the guildframe check there, but there's plenty of stupid-ass addons that spam GuildRoster() every 10/15/20 seconds, so ... no.
|
||||
if arg1 or GuildFrame:IsVisible() or doscan then
|
||||
doscan=false
|
||||
mod:ScanGuildNotes()
|
||||
end
|
||||
|
||||
if arg1 then
|
||||
-- but it appears that when arg1 is set, the player note change isn't available yet; that happens on the next arg1=nil update (about 0.1s later), so catch that one too. ghod this is messy.
|
||||
doscan=true
|
||||
end
|
||||
end
|
||||
|
||||
function mod:ScanGuildNotes()
|
||||
if not IsInGuild() then
|
||||
return
|
||||
end
|
||||
--DBG print("Scanning guildnotes!")
|
||||
--DBG local n,nFallback=0,0
|
||||
local names = {} -- ["playername"]="Playername" (note lowercase = uppercase) (yes, this works for 'foreign' letters too in WoW, even though it does not in standard Lua)
|
||||
GUILDNOTES = {} -- Yes, we do want to zap it, otherwise we end up storing notes for people being promoted/demoted through alt ranks and stuff
|
||||
|
||||
-- #1: find all names
|
||||
for i=1,GetNumGuildMembers(true) do
|
||||
local name = GetGuildRosterInfo(i)
|
||||
names[strlower(name or "?")] = name
|
||||
end
|
||||
|
||||
-- #2: scan all words in all guild notes, see if a name is mentioned
|
||||
for i=1,GetNumGuildMembers(true) do
|
||||
local name, rank, rankIndex, level, class, zone, note, officernote, online, status = GetGuildRosterInfo(i);
|
||||
local success
|
||||
for word in gmatch(strlower(note or ""), "[%a\128-\255]+") do
|
||||
if names[word] then
|
||||
GUILDNOTES[name] = names[word]
|
||||
success = true
|
||||
--DBG n=n+1
|
||||
break
|
||||
end
|
||||
end
|
||||
if not success and mod.db.profile.altNotesFallback and note and note~="" then
|
||||
-- #3: no joy? then if this is an 'alt' rank, use the entire note
|
||||
rank=strlower(rank or "")
|
||||
if strfind(rank, "alt") or
|
||||
strfind(rank, L["alt2"]) or
|
||||
strfind(rank, L["alt3"]) then
|
||||
GUILDNOTES[name] = note
|
||||
--DBG print("Fallback: ",note)
|
||||
--DBG nFallback=nFallback+1
|
||||
end
|
||||
end
|
||||
end
|
||||
--DBG print("Mapped",n,"names and",nFallback,"fallbacks!")
|
||||
end
|
||||
Reference in New Issue
Block a user