From 7462acab8ca10d67463a2d66edeabd4876c9e6e1 Mon Sep 17 00:00:00 2001 From: Florian Berthold Date: Sun, 24 May 2026 17:38:31 +0200 Subject: [PATCH] fix: nil-guard GetChannelName, GetGuildRosterInfo, InterfaceOptions* on CoA client PlayerNames.lua:94 - GetChannelName can return nil on the CoA-Beta client when the active channel target is not joined; capture into a local and fall back to empty string instead of chaining :lower() on nil. PlayerNames.lua:344 - GetGuildRosterInfo(i) returns nil name/class on this client (same family as the AltNames.lua fix in 1c4a7e8). Skip the iteration when name is nil to avoid indexing channels.GUILD[nil] and passing nil into AddPlayer. Chatter.lua:204 OpenConfig and Chatter.lua:21 inline func - the Blizzard InterfaceOptionsFrame globals are absent on CoA-Beta, so calling IsResizable() or InterfaceOptionsFrame_OpenToCategory() throws. Guard both call sites and fall back to opening the standalone AceConfigDialog window. ChatScroll.lua:53 - InterfaceOptionsSocialPanelChatMouseScroll_SetScrolling is also missing on this client; only hook it when the global exists, otherwise AceHook errors out at OnInitialize. --- Chatter.lua | 31 ++++++++++++++++++++----------- Modules/ChatScroll.lua | 4 +++- Modules/PlayerNames.lua | 21 ++++++++++++--------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/Chatter.lua b/Chatter.lua index c1ef21e..d61232e 100644 --- a/Chatter.lua +++ b/Chatter.lua @@ -19,9 +19,14 @@ local options = { name = L["Standalone Config"], desc = L["Open a standalone config window. You might consider installing |cffffff00BetterBlizzOptions|r to make the Blizzard UI options panel resizable."], func = function() - InterfaceOptionsFrame:Hide() - AceConfigDialog:SetDefaultSize("Chatter", 500, 550) - AceConfigDialog:Open("Chatter") + if InterfaceOptionsFrame and InterfaceOptionsFrame_OpenToCategory then + InterfaceOptionsFrame:Hide() + AceConfigDialog:SetDefaultSize("Chatter", 500, 550) + AceConfigDialog:Open("Chatter") + else + AceConfigDialog:SetDefaultSize("Chatter", 500, 550) + AceConfigDialog:Open("Chatter") + end end } } @@ -202,15 +207,19 @@ function Chatter:FCF_OpenTemporaryWindow(chatType, chatTarget, sourceChatFrame, end function Chatter:OpenConfig(input) - if input == "config" or not InterfaceOptionsFrame:IsResizable() then - options.args.defaultArgs.guiHidden = true - InterfaceOptionsFrame:Hide() - AceConfigDialog:SetDefaultSize("Chatter", 500, 550) - AceConfigDialog:Open("Chatter") + if InterfaceOptionsFrame and InterfaceOptionsFrame_OpenToCategory then + if input == "config" or not InterfaceOptionsFrame:IsResizable() then + options.args.defaultArgs.guiHidden = true + InterfaceOptionsFrame:Hide() + AceConfigDialog:SetDefaultSize("Chatter", 500, 550) + AceConfigDialog:Open("Chatter") + else + InterfaceOptionsFrame_OpenToCategory(Chatter.lastConfig) + options.args.defaultArgs.guiHidden = false + InterfaceOptionsFrame_OpenToCategory(optFrame) + end else - InterfaceOptionsFrame_OpenToCategory(Chatter.lastConfig) - options.args.defaultArgs.guiHidden = false - InterfaceOptionsFrame_OpenToCategory(optFrame) + LibStub("AceConfigDialog-3.0"):Open("Chatter") end end diff --git a/Modules/ChatScroll.lua b/Modules/ChatScroll.lua index 3f068f8..36a8ed4 100644 --- a/Modules/ChatScroll.lua +++ b/Modules/ChatScroll.lua @@ -50,7 +50,9 @@ local options = { function mod:OnInitialize() self.db = Chatter.db:RegisterNamespace(self:GetName(), defaults) self:RegisterEvent("CVAR_UPDATE", "ChangedVars") - self:RawHook("InterfaceOptionsSocialPanelChatMouseScroll_SetScrolling",true) + if _G.InterfaceOptionsSocialPanelChatMouseScroll_SetScrolling then + self:RawHook("InterfaceOptionsSocialPanelChatMouseScroll_SetScrolling",true) + end end function mod:InterfaceOptionsSocialPanelChatMouseScroll_SetScrolling() diff --git a/Modules/PlayerNames.lua b/Modules/PlayerNames.lua index 962d8cd..260e03e 100644 --- a/Modules/PlayerNames.lua +++ b/Modules/PlayerNames.lua @@ -91,7 +91,8 @@ do local cf = ChatEdit_GetActiveWindow() local channel = cf:GetAttribute("chatType") if channel == "CHANNEL" then - channel = select(2, GetChannelName(cf:GetAttribute("channelTarget"))):lower() + local cn = select(2, GetChannelName(cf:GetAttribute("channelTarget"))) + channel = cn and cn:lower() or "" elseif channel == "OFFICER" then channel = "GUILD" elseif channel == "RAID_WARNING" or channel == "RAID_LEADER" or channel == "BATTLEGROUND" or channel == "BATTLEGROUND_LEADER" then @@ -344,14 +345,16 @@ end function mod:GUILD_ROSTER_UPDATE(evt) if not IsInGuild() then return end wipe( channels.GUILD ) - for i = 1, GetNumGuildMembers() do - local name, _, _, level, _, _, _, _, online, _, class = GetGuildRosterInfo(i) - if online then - channels.GUILD[name] = name - end - self:AddPlayer(name, class, level, self.db.profile.saveGuild) - end -end + for i = 1, GetNumGuildMembers() do + local name, _, _, level, _, _, _, _, online, _, class = GetGuildRosterInfo(i) + if name then + if online then + channels.GUILD[name] = name + end + self:AddPlayer(name, class, level, self.db.profile.saveGuild) + end + end +end function mod:RAID_ROSTER_UPDATE(evt) wipe(channels.RAID)