224 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local addonname, shared = ...
 | 
						||
---@cast shared HeimdallShared
 | 
						||
---@cast addonname string
 | 
						||
 | 
						||
local helpMessages = {
 | 
						||
	ru = {
 | 
						||
		"1) who - пишет вам никнеймы текущих врагов в отслеживаемых локациях по порядку и локацию.",
 | 
						||
		"2) classes = пишет какие классы. (например 1 паладин 1 прист 1 рога.",
 | 
						||
		"3) howmany - общее число врагов (например дуротар 4 . оргримар 2 ) ",
 | 
						||
		"4) + - автоматическое приглашение в группу с дуельным рогой для сброса кд и общего сбора. ",
 | 
						||
		"5) ++ - автоматическое приглашение в группу альянса. (если нужен рефрак)",
 | 
						||
	},
 | 
						||
	en = {
 | 
						||
		"1) who - reports currently tracked stinkies in orgrimmar and durotar",
 | 
						||
		"2) classes - reports stinkies grouped by class",
 | 
						||
		"3) howmany - reports stinkies grouped by zone",
 | 
						||
		"4) + - automatically invites to group with duel rogue for cd reset",
 | 
						||
		"5) ++ - automatically invites to alliance group",
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
---@diagnostic disable-next-line: missing-fields
 | 
						||
shared.Commander = {}
 | 
						||
function shared.Commander.Init()
 | 
						||
	---@param text string
 | 
						||
	---@param size number
 | 
						||
	---@return string[]
 | 
						||
	local function Partition(text, size)
 | 
						||
		local words = {}
 | 
						||
		for word in text:gmatch("[^,]+") do
 | 
						||
			words[#words + 1] = word
 | 
						||
		end
 | 
						||
 | 
						||
		local ret = {}
 | 
						||
		local currentChunk = ""
 | 
						||
 | 
						||
		for _, word in ipairs(words) do
 | 
						||
			if #currentChunk + #word + 1 <= size then
 | 
						||
				currentChunk = currentChunk .. (currentChunk == "" and word or " " .. word)
 | 
						||
			else
 | 
						||
				if #currentChunk > 0 then
 | 
						||
					ret[#ret + 1] = currentChunk
 | 
						||
				end
 | 
						||
				currentChunk = word
 | 
						||
			end
 | 
						||
		end
 | 
						||
 | 
						||
		if #currentChunk > 0 then
 | 
						||
			ret[#ret + 1] = currentChunk
 | 
						||
		end
 | 
						||
 | 
						||
		return ret
 | 
						||
	end
 | 
						||
	---@param arr table<string, Player>
 | 
						||
	---@return string[]
 | 
						||
	local function Count(arr)
 | 
						||
		local ret = {}
 | 
						||
		for _, player in pairs(arr) do
 | 
						||
			if Heimdall_Data.config.who.zoneNotifyFor[player.zone] then
 | 
						||
				ret[player.zone] = (ret[player.zone] or 0) + 1
 | 
						||
			end
 | 
						||
		end
 | 
						||
		local text = {}
 | 
						||
		for zone, count in pairs(ret) do
 | 
						||
			text[#text + 1] = string.format("%s: %d", zone, count)
 | 
						||
		end
 | 
						||
		return text
 | 
						||
	end
 | 
						||
	---@param arr table<string, Player>
 | 
						||
	---@return string[]
 | 
						||
	local function CountPartitioned(arr)
 | 
						||
		local count = Count(arr)
 | 
						||
		local text = {}
 | 
						||
		for _, line in pairs(Partition(strjoin(", ", unpack(count)), 200)) do
 | 
						||
			text[#text + 1] = line
 | 
						||
		end
 | 
						||
		return text
 | 
						||
	end
 | 
						||
	---@param arr table<string, Player>
 | 
						||
	---@return string[]
 | 
						||
	local function Who(arr)
 | 
						||
		local ret = {}
 | 
						||
		for _, player in pairs(arr) do
 | 
						||
			if Heimdall_Data.config.who.zoneNotifyFor[player.zone] then
 | 
						||
				ret[#ret + 1] = string.format("%s/%s (%s) %s", player.name, player.class, player.zone,
 | 
						||
					player.stinky and "(!!!!)" or "")
 | 
						||
			end
 | 
						||
		end
 | 
						||
		return ret
 | 
						||
	end
 | 
						||
	---@param arr table<string, Player>
 | 
						||
	---@return string[]
 | 
						||
	local function WhoPartitioned(arr)
 | 
						||
		local who = Who(arr)
 | 
						||
		local text = {}
 | 
						||
		for _, line in pairs(Partition(strjoin(", ", unpack(who)), 200)) do
 | 
						||
			text[#text + 1] = line
 | 
						||
		end
 | 
						||
		return text
 | 
						||
	end
 | 
						||
	---@param arr table<string, Player>
 | 
						||
	---@return string[]
 | 
						||
	local function CountClass(arr)
 | 
						||
		local ret = {}
 | 
						||
		for _, player in pairs(arr) do
 | 
						||
			if Heimdall_Data.config.who.zoneNotifyFor[player.zone] then
 | 
						||
				ret[player.class] = (ret[player.class] or 0) + 1
 | 
						||
			end
 | 
						||
		end
 | 
						||
		local text = {}
 | 
						||
		for class, count in pairs(ret) do
 | 
						||
			text[#text + 1] = string.format("%s: %d", class, count)
 | 
						||
		end
 | 
						||
		return text
 | 
						||
	end
 | 
						||
	---@param arr table<string, Player>
 | 
						||
	---@return string[]
 | 
						||
	local function CountClassPartitioned(arr)
 | 
						||
		local countClass = CountClass(arr)
 | 
						||
		local text = {}
 | 
						||
		for _, line in pairs(Partition(strjoin(", ", unpack(countClass)), 200)) do
 | 
						||
			text[#text + 1] = line
 | 
						||
		end
 | 
						||
		return text
 | 
						||
	end
 | 
						||
	local function CountClassPartitionedStinkies()
 | 
						||
		local res = CountClassPartitioned(HeimdallStinkies)
 | 
						||
		if #res == 0 then
 | 
						||
			return { "No stinkies found" }
 | 
						||
		end
 | 
						||
		return res
 | 
						||
	end
 | 
						||
	local function WhoPartitionedStinkies()
 | 
						||
		local res = WhoPartitioned(HeimdallStinkies)
 | 
						||
		if #res == 0 then
 | 
						||
			return { "No stinkies found" }
 | 
						||
		end
 | 
						||
		return res
 | 
						||
	end
 | 
						||
	local function CountPartitionedStinkies()
 | 
						||
		local res = CountPartitioned(HeimdallStinkies)
 | 
						||
		if #res == 0 then
 | 
						||
			return { "No stinkies found" }
 | 
						||
		end
 | 
						||
		return res
 | 
						||
	end
 | 
						||
	local function HelpRu() return helpMessages.ru end
 | 
						||
	local function HelpEn() return helpMessages.en end
 | 
						||
	local groupInviteFrame = CreateFrame("Frame")
 | 
						||
	groupInviteFrame:SetScript("OnEvent", function(self, event, ...)
 | 
						||
		AcceptGroup()
 | 
						||
		groupInviteFrame:UnregisterEvent("PARTY_INVITE_REQUEST")
 | 
						||
		C_Timer.NewTimer(0.1, function()
 | 
						||
			_G["StaticPopup1Button1"]:Click()
 | 
						||
		end, 1)
 | 
						||
	end)
 | 
						||
	local function JoinGroup()
 | 
						||
		groupInviteFrame:RegisterEvent("PARTY_INVITE_REQUEST")
 | 
						||
		C_Timer.NewTimer(10, function()
 | 
						||
			groupInviteFrame:UnregisterEvent("PARTY_INVITE_REQUEST")
 | 
						||
		end, 1)
 | 
						||
		return { "+" }
 | 
						||
	end
 | 
						||
	local function LeaveGroup()
 | 
						||
		LeaveParty()
 | 
						||
		return {}
 | 
						||
	end
 | 
						||
	---@param target string
 | 
						||
	local function FollowTarget(target)
 | 
						||
		if not target then return end
 | 
						||
		FollowUnit(target)
 | 
						||
		return {}
 | 
						||
	end
 | 
						||
 | 
						||
	---@class Command
 | 
						||
	---@field keywordRe string
 | 
						||
	---@field commanderOnly boolean
 | 
						||
	---@field callback fun(...: any): string[]
 | 
						||
 | 
						||
	local commands = {
 | 
						||
		{ keywordRe = "^who",        commanderOnly = false, callback = WhoPartitionedStinkies },
 | 
						||
		{ keywordRe = "^howmany",    commanderOnly = false, callback = CountPartitionedStinkies },
 | 
						||
		{ keywordRe = "^classes",    commanderOnly = false, callback = CountClassPartitionedStinkies },
 | 
						||
		{ keywordRe = "^help",       commanderOnly = false, callback = HelpRu },
 | 
						||
		{ keywordRe = "^helpen",     commanderOnly = false, callback = HelpEn },
 | 
						||
		{ keywordRe = "^joingroup",  commanderOnly = false,  callback = JoinGroup },
 | 
						||
		{ keywordRe = "^leavegroup", commanderOnly = false,  callback = LeaveGroup },
 | 
						||
		{ keywordRe = "^follow",     commanderOnly = false,  callback = FollowTarget },
 | 
						||
	}
 | 
						||
 | 
						||
	local commanderChannelFrame = CreateFrame("Frame")
 | 
						||
	commanderChannelFrame:RegisterEvent("CHAT_MSG_CHANNEL")
 | 
						||
	commanderChannelFrame:SetScript("OnEvent", function(self, event, msg, sender, ...)
 | 
						||
		if not Heimdall_Data.config.commander.enabled then return end
 | 
						||
		local channelId = select(6, ...)
 | 
						||
		local _, channelname = GetChannelName(channelId)
 | 
						||
		if channelname ~= Heimdall_Data.config.commander.masterChannel then return end
 | 
						||
		sender = string.match(sender, "^[^-]+")
 | 
						||
 | 
						||
		for _, command in ipairs(commands) do
 | 
						||
			local enabled = Heimdall_Data.config.commander.commands[command.keywordRe] == true or false
 | 
						||
			if enabled and
 | 
						||
				(not command.commanderOnly
 | 
						||
					or (command.commanderOnly
 | 
						||
						and sender == Heimdall_Data.config.commander.commander)) then
 | 
						||
				if msg:match(command.keywordRe) then
 | 
						||
					local messages = command.callback({ strsplit(" ", msg) })
 | 
						||
					for _, message in ipairs(messages) do
 | 
						||
						---@type Message
 | 
						||
						local msg = {
 | 
						||
							channel = "CHANNEL",
 | 
						||
							data = channelname,
 | 
						||
							message = message
 | 
						||
						}
 | 
						||
						table.insert(shared.messenger.queue, msg)
 | 
						||
					end
 | 
						||
				end
 | 
						||
			end
 | 
						||
		end
 | 
						||
	end)
 | 
						||
 | 
						||
	print("Heimdall - Commander loaded")
 | 
						||
end
 |