local addonname, shared = ... ---@cast shared HeimdallShared ---@cast addonname string local ModuleName = "Inviter" ---@diagnostic disable-next-line: missing-fields shared.Inviter = {} function shared.Inviter.Init() ---@type Timer local updateTimer = nil local function FixGroup() if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Checking and fixing group configuration", ModuleName)) end if not IsInRaid() then if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Converting party to raid", ModuleName)) end ConvertToRaid() end if Heimdall_Data.config.inviter.allAssist then if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Setting all members to assistant", ModuleName)) end SetEveryoneIsAssistant() end if Heimdall_Data.config.inviter.agentsAssist then if Heimdall_Data.config.inviter.debug then local agentCount = 0 for _ in pairs(Heimdall_Data.config.agents) do agentCount = agentCount + 1 end print(string.format("[%s] Processing %d agents for assistant promotion", ModuleName, agentCount)) end for name, _ in pairs(Heimdall_Data.config.agents) do if UnitInParty(name) and not UnitIsGroupLeader(name) and not UnitIsRaidOfficer(name) then if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Promoting agent to assistant: %s", ModuleName, name)) end PromoteToAssistant(name, true) elseif Heimdall_Data.config.inviter.debug then if not UnitInParty(name) then print(string.format("[%s] Agent not in party: %s", ModuleName, name)) elseif UnitIsGroupLeader(name) then print(string.format("[%s] Agent is already leader: %s", ModuleName, name)) elseif UnitIsRaidOfficer(name) then print(string.format("[%s] Agent is already assistant: %s", ModuleName, name)) end end end end if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Group configuration update complete", ModuleName)) end end ---@param name string ---Kicking people or othwerise people leaving will fuck up the buttons ---We should make them reactive to GROUP_ROSTER_UPDATE ---But that is currently not trivial and would require some work ---Since I'm the only one currently using this - I don't care where the buttons are local function OverlayKickButtonElvUI(name) if Heimdall_Data.config.inviter.debug then print(string.format("[%s] OverlayKickButtonElvUI", ModuleName)) shared.dumpTable(Heimdall_Data.config.inviter) end for group = 1, 8 do for player = 1, 5 do local button = _G[string.format("ElvUF_RaidGroup%dUnitButton%d", group, player)] if Heimdall_Data.config.inviter.debug then print(string.format("[%s] button = %s", ModuleName, button)) end local unitName = button and button.unit and UnitName(button.unit) if Heimdall_Data.config.inviter.debug then print(string.format("[%s] unitName = %s", ModuleName, unitName)) end if unitName == name then if Heimdall_Data.config.inviter.debug then print(string.format("[%s] unitName == name", ModuleName)) end local overlayButton = framePool[button.unit] or CreateFrame("Button", string.format("HeimdallKickButton%s", button.unit, button, "SecureActionButtonTemplate")) framePool[button.unit] = overlayButton overlayButton:SetSize(button.UNIT_WIDTH / 2, button.UNIT_HEIGHT / 2) overlayButton:SetPoint("CENTER", button, "CENTER", 0, 0) overlayButton:SetNormalTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon") overlayButton:SetHighlightTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon") overlayButton:SetPushedTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon") overlayButton:SetDisabledTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon") overlayButton:SetAlpha(0.5) overlayButton:Show() overlayButton:SetScript("OnClick", function() UninviteUnit(name) overlayButton:Hide() end) -- button:SetAttribute("type", "macro") -- button:SetAttribute("macrotext", "/kick " .. unit) return end end end end ---@type table local groupMembers = {} local function CleanGroups() if not Heimdall_Data.config.inviter.kickOffline then return end print("Cleaning groups") local now = GetTime() for i = 1, 40 do local unit = "raid" .. i if UnitExists(unit) then local name = UnitName(unit) if name then -- When we load (into game) we want to consider everyone "online" -- In other words everyone we haven't seen before is "online" the first time we see them -- This is to avoid kicking people who might not be offline which we don't know because we just logged in if not groupMembers[name] then groupMembers[name] = now else local online = UnitIsConnected(unit) if online then groupMembers[name] = now end end end end end for name, time in pairs(groupMembers) do if time < now - Heimdall_Data.config.inviter.afkThreshold then print(string.format("Kicking %s for being offline", name)) -- Blyat this is protected... -- UninviteUnit(name) OverlayKickButtonElvUI(name) end if not UnitInParty(name) then print(string.format("%s no longer in party", name)) groupMembers[name] = nil end end end local function Tick() CleanGroups() C_Timer.NewTimer(Heimdall_Data.config.inviter.cleanupInterval, Tick, 1) end Tick() local groupRosterUpdateFrame = CreateFrame("Frame") groupRosterUpdateFrame:RegisterEvent("GROUP_ROSTER_UPDATE") groupRosterUpdateFrame:SetScript("OnEvent", function(self, event, ...) if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Event received: %s", ModuleName, event)) end if not Heimdall_Data.config.inviter.enabled then if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Module disabled, ignoring event", ModuleName)) end return end if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Group roster changed - Checking configuration", ModuleName)) end if updateTimer then updateTimer:Cancel() end updateTimer = C_Timer.NewTimer(Heimdall_Data.config.inviter.throttle, FixGroup) end) local inviterChannelFrame = CreateFrame("Frame") inviterChannelFrame:RegisterEvent("CHAT_MSG_CHANNEL") inviterChannelFrame:SetScript("OnEvent", function(self, event, msg, sender, ...) -- if Heimdall_Data.config.inviter.debug then -- print(string.format("[%s] Chat message received: %s", ModuleName, msg)) -- shared.dumpTable(Heimdall_Data.config.inviter) -- end if not Heimdall_Data.config.inviter.enabled then return end local channelId = select(6, ...) local _, channelname = GetChannelName(channelId) if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Channel name: %s", ModuleName, channelname)) end if channelname ~= Heimdall_Data.config.inviter.listeningChannel then if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Channel name does not match listening channel", ModuleName)) end return end if msg == Heimdall_Data.config.inviter.keyword then if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Inviting %s", ModuleName, sender)) end InviteUnit(sender) else if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Message does not match keyword", ModuleName)) end end end) if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Module initialized - All assist: %s, Agents assist: %s", ModuleName, tostring(Heimdall_Data.config.inviter.allAssist), tostring(Heimdall_Data.config.inviter.agentsAssist))) end if Heimdall_Data.config.inviter.debug then print(string.format("[%s] Module initialized - All assist: %s, Agents assist: %s", ModuleName, tostring(Heimdall_Data.config.inviter.allAssist), tostring(Heimdall_Data.config.inviter.agentsAssist))) end print("[Heimdall] Inviter loaded") end