305 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			305 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local _, shared = ...
 | 
						|
---@cast shared HeimdallShared
 | 
						|
local ModuleName = "Noter"
 | 
						|
 | 
						|
---@class HeimdallNoterConfig
 | 
						|
---@field enabled boolean
 | 
						|
---@field debug boolean
 | 
						|
---@field channels string[]
 | 
						|
---@field lastNotes number
 | 
						|
 | 
						|
---@class Note
 | 
						|
---@field source string
 | 
						|
---@field for string
 | 
						|
---@field date string
 | 
						|
---@field note string
 | 
						|
 | 
						|
---@class Noter
 | 
						|
shared.Noter = {
 | 
						|
	Init = function()
 | 
						|
		-- ---Hopefully this will not be necessary
 | 
						|
		-- ---@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 array any[]
 | 
						|
		---@return any[]
 | 
						|
		local function Compact(array)
 | 
						|
			local compacted = {}
 | 
						|
			for _, v in pairs(array) do
 | 
						|
				compacted[#compacted + 1] = v
 | 
						|
			end
 | 
						|
			return compacted
 | 
						|
		end
 | 
						|
 | 
						|
		---@param name string
 | 
						|
		---@param args string[]
 | 
						|
		local function DeleteNotes(name, args)
 | 
						|
			if Heimdall_Data.config.noter.debug then
 | 
						|
				print(string.format("[%s] Delete note command received for: %s", ModuleName, name))
 | 
						|
			end
 | 
						|
			local range = args[4]
 | 
						|
			if range then
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(string.format("[%s] Range received for delete note: %s", ModuleName, range))
 | 
						|
				end
 | 
						|
				local indices = shared.Split(range, "..")
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(string.format("[%s] Indices for range deletion: %s", ModuleName, table.concat(indices, ", ")))
 | 
						|
					shared.dumpTable(indices)
 | 
						|
				end
 | 
						|
				local start = tonumber(indices[1])
 | 
						|
				local finish = tonumber(indices[2])
 | 
						|
 | 
						|
				if not start then
 | 
						|
					if Heimdall_Data.config.noter.debug then
 | 
						|
						print(
 | 
						|
							string.format("[%s] Invalid start range for delete note: %s", ModuleName, tostring(start))
 | 
						|
						)
 | 
						|
					end
 | 
						|
					return
 | 
						|
				end
 | 
						|
 | 
						|
				if not finish then finish = start end
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(string.format("[%s] Deleting note range %s to %s for: %s", ModuleName, start, finish, name))
 | 
						|
				end
 | 
						|
 | 
						|
				-- Here, because we are deleting random notes, we lose the "iterative" index property
 | 
						|
				-- Ie it's not longer 1..100, it might be 1..47, 50, 68..100
 | 
						|
				-- Which means that we cannot use ipairs, bad!
 | 
						|
				for i = start, finish do
 | 
						|
					if not Heimdall_Data.config.notes[name] then Heimdall_Data.config.notes[name] = {} end
 | 
						|
					if not Heimdall_Data.config.notes[name][i] then
 | 
						|
						if Heimdall_Data.config.noter.debug then
 | 
						|
							print(string.format("[%s] Note at index %s does not exist", ModuleName, i))
 | 
						|
						end
 | 
						|
					else
 | 
						|
						if Heimdall_Data.config.noter.debug then
 | 
						|
							print(string.format("[%s] Deleting note %s at index %s", ModuleName, name, i))
 | 
						|
							shared.dumpTable(Heimdall_Data.config.notes[name][i])
 | 
						|
						end
 | 
						|
						Heimdall_Data.config.notes[name][i] = nil
 | 
						|
					end
 | 
						|
				end
 | 
						|
				Heimdall_Data.config.notes[name] = Compact(Heimdall_Data.config.notes[name])
 | 
						|
			end
 | 
						|
		end
 | 
						|
 | 
						|
		---@param channel string
 | 
						|
		---@param index number
 | 
						|
		---@param note Note
 | 
						|
		local function PrintNote(channel, index, note)
 | 
						|
			if Heimdall_Data.config.noter.debug then
 | 
						|
				print(string.format("[%s] Printing note at index %d for: %s", ModuleName, index, note.source))
 | 
						|
				print(string.format("[%s] [%s][%d] %s: %s", ModuleName, note.source, index, note.date, note.note))
 | 
						|
			end
 | 
						|
			---@type Message
 | 
						|
			local msg = {
 | 
						|
				channel = "C",
 | 
						|
				data = channel,
 | 
						|
				message = string.format("[%s][%d] %s: %s", note.source, index, note.date, note.note),
 | 
						|
			}
 | 
						|
			--table.insert(shared.messenger.queue, msg)
 | 
						|
			table.insert(shared.networkMessenger.queue, msg)
 | 
						|
		end
 | 
						|
		---@param name string
 | 
						|
		---@param args string[]
 | 
						|
		local function PrintNotes(channel, name, args)
 | 
						|
			if Heimdall_Data.config.noter.debug then
 | 
						|
				print(string.format("[%s] Print note command received for: %s", ModuleName, name))
 | 
						|
			end
 | 
						|
			local range = args[3]
 | 
						|
			if not range then
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(
 | 
						|
						string.format(
 | 
						|
							"[%s] No range specified for print note, defaulting to last %d notes",
 | 
						|
							ModuleName,
 | 
						|
							Heimdall_Data.config.noter.lastNotes
 | 
						|
						)
 | 
						|
					)
 | 
						|
				end
 | 
						|
				local notes = Heimdall_Data.config.notes[name] or {}
 | 
						|
				local start = math.max(1, #notes - Heimdall_Data.config.noter.lastNotes + 1)
 | 
						|
				local finish = #notes
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(string.format("[%s] Printing notes from %d to %d for: %s", ModuleName, start, finish, name))
 | 
						|
				end
 | 
						|
				for i = start, finish do
 | 
						|
					PrintNote(channel, i, notes[i])
 | 
						|
				end
 | 
						|
				return
 | 
						|
			end
 | 
						|
			if range then
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(string.format("[%s] Range received for print note: %s", ModuleName, range))
 | 
						|
				end
 | 
						|
				local indices = shared.Split(range, "..")
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(string.format("[%s] Indices for range printing: %s", ModuleName, table.concat(indices, ", ")))
 | 
						|
					shared.dumpTable(indices)
 | 
						|
				end
 | 
						|
				local start = tonumber(indices[1])
 | 
						|
				local finish = tonumber(indices[2])
 | 
						|
 | 
						|
				if not start then
 | 
						|
					if Heimdall_Data.config.noter.debug then
 | 
						|
						print(string.format("[%s] Invalid start range for print note: %s", ModuleName, tostring(start)))
 | 
						|
					end
 | 
						|
					return
 | 
						|
				end
 | 
						|
 | 
						|
				if not finish then finish = start end
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(string.format("[%s] Printing note range %s to %s for: %s", ModuleName, start, finish, name))
 | 
						|
				end
 | 
						|
 | 
						|
				for i = start, finish do
 | 
						|
					if not Heimdall_Data.config.notes[name] then Heimdall_Data.config.notes[name] = {} end
 | 
						|
					if not Heimdall_Data.config.notes[name][i] then
 | 
						|
						if Heimdall_Data.config.noter.debug then
 | 
						|
							print(string.format("[%s] Note at index %s does not exist", ModuleName, i))
 | 
						|
						end
 | 
						|
					else
 | 
						|
						if Heimdall_Data.config.noter.debug then
 | 
						|
							print(string.format("[%s] Printing note %s at index %s", ModuleName, name, i))
 | 
						|
							shared.dumpTable(Heimdall_Data.config.notes[name][i])
 | 
						|
						end
 | 
						|
						PrintNote(channel, i, Heimdall_Data.config.notes[name][i])
 | 
						|
					end
 | 
						|
				end
 | 
						|
			end
 | 
						|
		end
 | 
						|
 | 
						|
		---@param name string
 | 
						|
		---@param sender string
 | 
						|
		---@param args string[]
 | 
						|
		local function AddNote(name, sender, args)
 | 
						|
			if not Heimdall_Data.config.notes[name] then Heimdall_Data.config.notes[name] = {} end
 | 
						|
			if Heimdall_Data.config.noter.debug then
 | 
						|
				print(string.format("[%s] Adding note for: %s from: %s", ModuleName, name, sender))
 | 
						|
				shared.dumpTable(args)
 | 
						|
			end
 | 
						|
			local msgparts = {}
 | 
						|
			for i = 3, #args do
 | 
						|
				msgparts[#msgparts + 1] = args[i]
 | 
						|
			end
 | 
						|
			local msg = table.concat(msgparts, " ")
 | 
						|
 | 
						|
			if Heimdall_Data.config.noter.debug then
 | 
						|
				print(string.format("[%s] Adding note for: %s from: %s", ModuleName, name, sender))
 | 
						|
				print(string.format("[%s] Note: %s", ModuleName, msg))
 | 
						|
			end
 | 
						|
 | 
						|
			local note = {
 | 
						|
				source = sender,
 | 
						|
				date = date("%Y-%m-%dT%H:%M:%S"),
 | 
						|
				note = msg,
 | 
						|
			}
 | 
						|
 | 
						|
			if Heimdall_Data.config.noter.debug then
 | 
						|
				print(string.format("[%s] Adding note", ModuleName))
 | 
						|
				shared.dumpTable(note)
 | 
						|
			end
 | 
						|
			table.insert(Heimdall_Data.config.notes[name], note)
 | 
						|
		end
 | 
						|
 | 
						|
		-- Here's the plan:
 | 
						|
		-- Implement a "note" command, that will do everything
 | 
						|
		-- Saying "note <name> <note>" will add a note to the list for the character
 | 
						|
		-- Saying "note <name>" will list last N notes
 | 
						|
		-- Saying "note <name> i" will list the i-th note
 | 
						|
		-- Saying "note <name> i..j" will list notes from i to j
 | 
						|
		-- Saying "note <name> delete i" will delete the i-th note
 | 
						|
		-- Saying "note <name> delete i..j" will delete notes from i to j
 | 
						|
		local noterChannelFrame = CreateFrame("Frame")
 | 
						|
		noterChannelFrame:RegisterEvent("CHAT_MSG_CHANNEL")
 | 
						|
		noterChannelFrame:SetScript("OnEvent", function(self, event, msg, sender, ...)
 | 
						|
			--if Heimdall_Data.config.noter.debug then
 | 
						|
			--	print(string.format("[%s] Event received", ModuleName))
 | 
						|
			--	shared.dumpTable(Heimdall_Data.config.noter)
 | 
						|
			--end
 | 
						|
			if not Heimdall_Data.config.noter.enabled then
 | 
						|
				--if Heimdall_Data.config.noter.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.noter.channels) do
 | 
						|
				if channelname == channel then
 | 
						|
					ok = true
 | 
						|
					break
 | 
						|
				end
 | 
						|
			end
 | 
						|
			if not ok then
 | 
						|
				--if Heimdall_Data.config.noter.debug then
 | 
						|
				--	print(string.format("[%s] Channel %s does not match the master channel %s", ModuleName, channelname, Heimdall_Data.config.noter.masterChannel))
 | 
						|
				--end
 | 
						|
				return
 | 
						|
			end
 | 
						|
 | 
						|
			sender = string.match(sender, "^[^-]+")
 | 
						|
			if Heimdall_Data.config.noter.debug then
 | 
						|
				print(string.format("[%s] Message from: %s", ModuleName, sender))
 | 
						|
				shared.dumpTable(Heimdall_Data.config.noter)
 | 
						|
			end
 | 
						|
 | 
						|
			if not msg or msg == "" then
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(string.format("[%s] Empty message, ignoring", ModuleName))
 | 
						|
				end
 | 
						|
				return
 | 
						|
			end
 | 
						|
 | 
						|
			local args = { strsplit(" ", msg) }
 | 
						|
			if Heimdall_Data.config.noter.debug then
 | 
						|
				print(string.format("[%s] Arguments received: %s", ModuleName, table.concat(args, ", ")))
 | 
						|
				shared.dumpTable(args)
 | 
						|
			end
 | 
						|
			local command = args[1]
 | 
						|
			if command == "note" then
 | 
						|
				local name = strtrim(string.lower(args[2] or ""))
 | 
						|
				if Heimdall_Data.config.noter.debug then
 | 
						|
					print(string.format("[%s] Note command received for: %s", ModuleName, name))
 | 
						|
				end
 | 
						|
				local note = strtrim(args[3] or "")
 | 
						|
				if Heimdall_Data.config.noter.debug then print(string.format("[%s] Note: %s", ModuleName, note)) end
 | 
						|
				if note == "delete" then
 | 
						|
					DeleteNotes(name, args)
 | 
						|
				elseif string.find(note, "^[%d%.]*$") then
 | 
						|
					PrintNotes(channelname, name, args)
 | 
						|
				else
 | 
						|
					AddNote(name, sender, args)
 | 
						|
				end
 | 
						|
			end
 | 
						|
		end)
 | 
						|
 | 
						|
		print("[Heimdall] Commander module loaded")
 | 
						|
	end,
 | 
						|
}
 |