Files
wow-Heimdall/Modules/Noter.lua
PhatPhuckDave 1da1e7bf9f
Some checks failed
Release Workflow / release (push) Failing after 23s
Code format
2025-05-04 15:09:47 +02:00

297 lines
9.5 KiB
Lua

local addonname, shared = ...
---@cast shared HeimdallShared
---@cast addonname string
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.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