346 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			346 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local _, shared = ...
 | 
						||
---@cast shared HeimdallShared
 | 
						||
local ModuleName = "Commander"
 | 
						||
 | 
						||
local helpMessages = {
 | 
						||
	ru = {
 | 
						||
		"1) who - пишет вам никнеймы текущих врагов и локу.",
 | 
						||
		"2) classes - покажет классы врагов и число.",
 | 
						||
		"3) howmany - общее число врагов (дурик 4 . огри 2 ) ",
 | 
						||
		"4) + - атоинвайт в сбор пати и сброса кд.",
 | 
						||
		"5) ++ -автоинвайт в пати аликов (если нужен рефрак)",
 | 
						||
		"6 ) note Никнейм текст - добавление заметки.",
 | 
						||
		"7) note Никнейм - посмотреть последние заметки.",
 | 
						||
		"8) note Никнейм 5 - посмотреть конкретную заметку.",
 | 
						||
		"9) note Никнейм 1..5 - посмотреть заметки от 1 до 5",
 | 
						||
		"10) note Никнейм delete 1 - удалить заметку номер 1",
 | 
						||
		"11) note Никнейм delete 1..5 - удалить заметки 1 до 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",
 | 
						||
		"6) note <name> <note> - adds a note for the specified character.",
 | 
						||
		"7) note <name> - lists the last N notes for the character.",
 | 
						||
		"8) note <name> i - lists the i-th note for the character.",
 | 
						||
		"9) note <name> i..j - lists notes from i to j for the character.",
 | 
						||
		"10) note <name> delete i - deletes the i-th note for the character.",
 | 
						||
		"11) note <name> delete i..j - deletes notes from i to j for the character.",
 | 
						||
	},
 | 
						||
}
 | 
						||
 | 
						||
---@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 shared.Whoer.ShouldNotifyForZone(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 = {}
 | 
						||
		---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
 | 
						||
		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 shared.Whoer.ShouldNotifyForZone(player.zone) then
 | 
						||
				ret[#ret + 1] = string.format(
 | 
						||
					"%s/%s (%s) %s",
 | 
						||
					player.name,
 | 
						||
					player.class,
 | 
						||
					player.zone,
 | 
						||
					player.stinky and "(!!!!)" or ""
 | 
						||
				)
 | 
						||
			end
 | 
						||
		end
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			print(string.format("[%s] Command result: %s", ModuleName, strjoin(", ", unpack(ret))))
 | 
						||
		end
 | 
						||
		return ret
 | 
						||
	end
 | 
						||
	---@param arr table<string, Player>
 | 
						||
	---@return string[]
 | 
						||
	local function WhoPartitioned(arr)
 | 
						||
		local who = Who(arr)
 | 
						||
		local text = {}
 | 
						||
		---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
 | 
						||
		for _, line in pairs(Partition(strjoin(", ", unpack(who)), 200)) do
 | 
						||
			text[#text + 1] = "who: " .. 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 shared.Whoer.ShouldNotifyForZone(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
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			print(string.format("[%s] Message text: %s", ModuleName, strjoin(", ", unpack(text))))
 | 
						||
		end
 | 
						||
		return text
 | 
						||
	end
 | 
						||
	---@param arr table<string, Player>
 | 
						||
	---@return string[]
 | 
						||
	local function CountClassPartitioned(arr)
 | 
						||
		local countClass = CountClass(arr)
 | 
						||
		local text = {}
 | 
						||
		---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
 | 
						||
		for _, line in pairs(Partition(strjoin(", ", unpack(countClass)), 200)) do
 | 
						||
			text[#text + 1] = line
 | 
						||
		end
 | 
						||
		return text
 | 
						||
	end
 | 
						||
	local function CountClassPartitionedStinkies()
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			print(string.format("[%s] Executing: CountClassPartitionedStinkies", ModuleName))
 | 
						||
		end
 | 
						||
		local res = CountClassPartitioned(HeimdallStinkies)
 | 
						||
		if #res == 0 then return { "No stinkies found" } end
 | 
						||
		return res
 | 
						||
	end
 | 
						||
	local function WhoPartitionedStinkies()
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			print(string.format("[%s] Executing: WhoPartitionedStinkies", ModuleName))
 | 
						||
			shared.dumpTable(HeimdallStinkies)
 | 
						||
		end
 | 
						||
		local res = WhoPartitioned(HeimdallStinkies)
 | 
						||
		if #res == 0 then return { "No stinkies found" } end
 | 
						||
		return res
 | 
						||
	end
 | 
						||
	local function CountPartitionedStinkies()
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			print(string.format("[%s] Executing: CountPartitionedStinkies", ModuleName))
 | 
						||
		end
 | 
						||
		local res = CountPartitioned(HeimdallStinkies)
 | 
						||
		if #res == 0 then return { "No stinkies found" } end
 | 
						||
		return res
 | 
						||
	end
 | 
						||
	local function HelpRu()
 | 
						||
		if Heimdall_Data.config.commander.debug then print(string.format("[%s] Executing: HelpRu", ModuleName)) end
 | 
						||
		return helpMessages.ru
 | 
						||
	end
 | 
						||
	local function HelpEn()
 | 
						||
		if Heimdall_Data.config.commander.debug then print(string.format("[%s] Executing: HelpEn", ModuleName)) end
 | 
						||
		return helpMessages.en
 | 
						||
	end
 | 
						||
	local groupInviteFrame = CreateFrame("Frame")
 | 
						||
	groupInviteFrame:SetScript("OnEvent", function(self, event, ...)
 | 
						||
		if Heimdall_Data.config.commander.debug then print(string.format("[%s] Event received", ModuleName)) end
 | 
						||
		AcceptGroup()
 | 
						||
		groupInviteFrame:UnregisterEvent("PARTY_INVITE_REQUEST")
 | 
						||
		C_Timer.NewTimer(0.1, function()
 | 
						||
			if Heimdall_Data.config.commander.debug then
 | 
						||
				print(string.format("[%s] Click event triggered", ModuleName))
 | 
						||
			end
 | 
						||
			_G["StaticPopup1Button1"]:Click()
 | 
						||
		end, 1)
 | 
						||
	end)
 | 
						||
	local function JoinGroup()
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			print(string.format("[%s] JoinGroup command received", ModuleName))
 | 
						||
		end
 | 
						||
		groupInviteFrame:RegisterEvent("PARTY_INVITE_REQUEST")
 | 
						||
		C_Timer.NewTimer(10, function() groupInviteFrame:UnregisterEvent("PARTY_INVITE_REQUEST") end, 1)
 | 
						||
		return { "+" }
 | 
						||
	end
 | 
						||
	local function LeaveGroup()
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			print(string.format("[%s] LeaveGroup command received", ModuleName))
 | 
						||
		end
 | 
						||
		LeaveParty()
 | 
						||
		return {}
 | 
						||
	end
 | 
						||
	---@param target string
 | 
						||
	local function FollowTarget(target)
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			print(string.format("[%s] Following target: %s", ModuleName, target))
 | 
						||
		end
 | 
						||
		if not target then return end
 | 
						||
		FollowUnit(target)
 | 
						||
		return {}
 | 
						||
	end
 | 
						||
 | 
						||
	---@param args string[]
 | 
						||
	local function MacroTarget(args)
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
 | 
						||
			print(string.format("[%s] Macroing: %s", ModuleName, strjoin(" ", unpack(args))))
 | 
						||
		end
 | 
						||
		if #args < 2 or #args % 2 ~= 0 then
 | 
						||
			if #args < 2 or #args % 2 ~= 0 then
 | 
						||
				if Heimdall_Data.config.commander.debug then
 | 
						||
					print(string.format("[%s] Invalid number of arguments for MacroTarget", ModuleName))
 | 
						||
				end
 | 
						||
				return {}
 | 
						||
			end
 | 
						||
		end
 | 
						||
		table.remove(args, 1)
 | 
						||
 | 
						||
		for i = 1, #args do
 | 
						||
			local stinky = strtrim(args[i])
 | 
						||
			local name = stinky:match("([^/]+)")
 | 
						||
			local class = stinky:match("/([^ $]+)")
 | 
						||
			if Heimdall_Data.config.commander.debug then
 | 
						||
				print(string.format("[%s] Adding stinky: %s/%s", ModuleName, name, tostring(class)))
 | 
						||
			end
 | 
						||
			shared.stinkyTracker.stinkies[name] = {
 | 
						||
				name = name,
 | 
						||
				class = class or "unknown",
 | 
						||
				seenAt = GetTime(),
 | 
						||
				hostile = true,
 | 
						||
			}
 | 
						||
		end
 | 
						||
		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 },
 | 
						||
		{ keywordRe = "^macro", commanderOnly = false, callback = MacroTarget },
 | 
						||
	}
 | 
						||
 | 
						||
	local commanderChannelFrame = CreateFrame("Frame")
 | 
						||
	commanderChannelFrame:RegisterEvent("CHAT_MSG_CHANNEL")
 | 
						||
	commanderChannelFrame:SetScript("OnEvent", function(self, event, msg, sender, ...)
 | 
						||
		--if Heimdall_Data.config.commander.debug then
 | 
						||
		--	print(string.format("[%s] Event received", ModuleName))
 | 
						||
		--	shared.dumpTable(Heimdall_Data.config.commander)
 | 
						||
		--end
 | 
						||
		if not Heimdall_Data.config.commander.enabled then
 | 
						||
			--if Heimdall_Data.config.commander.debug then
 | 
						||
			--	print(string.format("[%s] Module disabled, ignoring event", ModuleName))
 | 
						||
			--end
 | 
						||
			return
 | 
						||
		end
 | 
						||
		local channelId = select(6, ...)
 | 
						||
		local _, channelname = GetChannelName(channelId)
 | 
						||
		local ok = false
 | 
						||
		for _, channel in pairs(Heimdall_Data.config.commander.channels) do
 | 
						||
			if channel == channelname then
 | 
						||
				ok = true
 | 
						||
				break
 | 
						||
			end
 | 
						||
		end
 | 
						||
		if not ok then
 | 
						||
			if Heimdall_Data.config.commander.debug then
 | 
						||
				print(
 | 
						||
					string.format(
 | 
						||
						"[%s] Channel name '%s' does not match any of the channels '%s'",
 | 
						||
						ModuleName,
 | 
						||
						channelname,
 | 
						||
						table.concat(Heimdall_Data.config.commander.channels, ", ")
 | 
						||
					)
 | 
						||
				)
 | 
						||
			end
 | 
						||
			return
 | 
						||
		end
 | 
						||
 | 
						||
		sender = string.match(sender, "^[^-]+")
 | 
						||
		if Heimdall_Data.config.commander.debug then
 | 
						||
			print(string.format("[%s] Message from: %s", ModuleName, sender))
 | 
						||
			shared.dumpTable(Heimdall_Data.config.commander)
 | 
						||
		end
 | 
						||
 | 
						||
		for _, command in ipairs(commands) do
 | 
						||
			local enabled = Heimdall_Data.config.commander.commands[command.keywordRe] == true or false
 | 
						||
			if Heimdall_Data.config.commander.debug then
 | 
						||
				print(string.format("[%s] Command match: %s = %s", ModuleName, command.keywordRe, tostring(enabled)))
 | 
						||
			end
 | 
						||
			if
 | 
						||
				enabled
 | 
						||
				and (
 | 
						||
					not command.commanderOnly
 | 
						||
					or (command.commanderOnly and sender == Heimdall_Data.config.commander.commander)
 | 
						||
				)
 | 
						||
			then
 | 
						||
				if msg:match(command.keywordRe) then
 | 
						||
					---@diagnostic disable-next-line: redundant-parameter Currently luals does not support variadic functions as a @field
 | 
						||
					local messages = command.callback({ strsplit(",", msg) })
 | 
						||
					if Heimdall_Data.config.commander.debug then
 | 
						||
						---@diagnostic disable-next-line: param-type-mismatch
 | 
						||
						print(string.format("[%s] Messages to send: %s", ModuleName, strjoin(", ", unpack(messages))))
 | 
						||
					end
 | 
						||
					for _, message in ipairs(messages) do
 | 
						||
						---@type Message
 | 
						||
						local returnmsg = {
 | 
						||
							channel = "C",
 | 
						||
							data = channelname,
 | 
						||
							message = message,
 | 
						||
						}
 | 
						||
						if Heimdall_Data.config.commander.debug then
 | 
						||
							print(string.format("[%s] Queuing message", ModuleName))
 | 
						||
							shared.dumpTable(msg)
 | 
						||
						end
 | 
						||
						--table.insert(shared.messenger.queue, msg)
 | 
						||
						table.insert(shared.networkMessenger.queue, returnmsg)
 | 
						||
					end
 | 
						||
				end
 | 
						||
			end
 | 
						||
		end
 | 
						||
	end)
 | 
						||
 | 
						||
	print("[Heimdall] Commander module loaded")
 | 
						||
end
 |