local _, shared = ... ---@cast shared HeimdallShared local ModuleName = "Noter" ---@class Note ---@field source string ---@field for string ---@field date string ---@field note string ---@diagnostic disable-next-line: missing-fields shared.Noter = {} function shared.Noter.Init() -- ---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.dump(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.dump(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.dump(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.dump(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.dump(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.dump(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 " will add a note to the list for the character -- Saying "note " will list last N notes -- Saying "note i" will list the i-th note -- Saying "note i..j" will list notes from i to j -- Saying "note delete i" will delete the i-th note -- Saying "note 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.dump(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.dump(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.dump(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