local mod = klhtm local me = { } mod.netin = me me.myevents = { "CHAT_MSG_CHANNEL", "CHAT_MSG_SYSTEM", "CHAT_MSG_ADDON" } -- Special onevent function from Core.lua me.onevent = function() if event == "CHAT_MSG_ADDON" then -- check the message is KLHTM, and comes from the party or raid if (arg1 ~= "KLHTM") or ((arg3 ~= "PARTY") and (arg3 ~= "RAID")) then me.logmessage("nonklhtm", string.len(arg1)) return end -- ok me.messagein(arg4, arg2, 1) elseif event == "CHAT_MSG_CHANNEL" then -- ignore messages outside our channel if arg8 ~= mod.net.channelnumber then return end -- ignore non-KLHTM messages if string.sub(arg1, 1, 6) ~= "KLHTM " then me.logmessage("nonklhtm", string.len(arg1)) return end -- ignore messages from people outside the raid group if mod.unit.isplayeringroup(arg2) == nil then me.logmessage("nonklhtm", string.len(arg1)) return end -- remove " ...hic!" suffix, and localisations local start local finish start, finish, body = string.find(arg1, "(.-) ?%.%.%..+") if finish == string.len(arg1) then if mod.out.checktrace("info", me, "drunk") then mod.out.printtrace(string.format("Trimming from this message: %s", arg1)) end arg1 = body end -- to get here, it's fine me.messagein(arg2, arg1, 7) elseif event == "CHAT_MSG_SYSTEM" then -- in 0.12 and higher, the mod is sending ADDON_MESSAGEs, so we don't care about afk if mod.isnewwowversion == nil then if string.find(arg1, string.format(MARKED_AFK_MESSAGE, "")) then mod.my.setstate("afk", true) elseif string.find(arg1, CLEARED_AFK) then mod.my.setstate("afk", false) end end else return end end --[[ me.messagein(author, message, startindex) Processes a message from the chat channel. is the name of the player who sent the message. is the original string sent. is the 1-based string index where the message starts. ]] me.messagein = function(author, message, startindex) -- get first bit and rest local command local data _, _, command, data = string.find(message, "(%a+)(.*)", startindex) if (command == nil) or (me.commands[command] == nil) then -- log as invalid me.logmessage("invalid", string.len(message)) if mod.out.checktrace("warning", me, "badmessage") then mod.out.printtrace(string.format("Received the invalid message '|cffffff00%s|r' from %s.", message, author)) end else if me.commands[command](author, message, startindex + string.len(command)) then -- log as good me.logmessage("good", string.len(message)) else -- log as invalid me.logmessage("invalid", string.len(message)) if mod.out.checktrace("warning", me, "badmessage") then mod.out.printtrace(string.format("Received the invalid message '|cffffff00%s|r' from %s.", message, author)) end end end end --[[ me.officercheck(author, message) Checks if the author of an officer-only command is an officer. Otherwise, prints an error to trace. is the name of the player who sent the message. is the complete text of the message. Returns: non-nil iff is an officer. ]] me.officercheck = function(author, message) if mod.unit.isplayerofficer(author) then return true else if mod.out.checktrace("warning", me, "badmessage") then mod.out.printtrace(string.format("|cffffff00%s|r is not an officer, but sent the message |cffffff00%s|r.", author, message)) end return nil end end --[[ each function is called with 1) author, 2) message, 3) index of first character after the command (probably a space) they should return non-nil if the message was good, nil otherwise ]] me.commands = { -- clearing the raid threat ["clear"] = function(author, message) -- author must be officer if me.officercheck(author, message) then mod.out.print(string.format(mod.string.get("print", "network", "threatreset"), author)) mod.table.resetraidthreat() mod.table.clearraidtable() return true end end, -- updating your threat value ["threat"] = function(author, message, start) local value = tonumber(string.sub(message, start + 1)) -- check for validity if value == nil then return end mod.table.updateplayerthreat(author, value) KLHTM_RequestRedraw("raid") return true end, -- 1.12: "t" is a synonym for "threat" ["t"] = function(author, message, start) local value = tonumber(string.sub(message, start + 1)) -- check for validity if value == nil then return end mod.table.updateplayerthreat(author, value) KLHTM_RequestRedraw("raid") return true end, -- setting the master target ["target"] = function(author, message, start) -- check player is an officer if me.officercheck(author, message) then local newmt = string.sub(message, start + 1) -- check newmt makes sense if newmt ~= nil and string.len(newmt) > 0 then mod.boss.newmastertarget(author, newmt) KLHTM_RequestRedraw("raid") -- update poll values mod.net.lastmtstring = newmt mod.net.lastmtsender = author mod.net.lastmttime = GetTime() return true end end end, -- polling the master target ["mtpoll"] = function(author, message, start) -- check player is an officer if me.officercheck(author, message) then local newmt = string.sub(message, start + 1) -- check newmt makes sense if newmt ~= nil and string.len(newmt) > 0 then -- check if this is different if newmt ~= mod.net.lastmtstring then -- set the string as MT, but with a caution mod.boss.mastertarget = newmt mod.out.print(string.format(mod.string.get("print", "network", "mtpollwarning"), newmt, author)) KLHTM_RequestRedraw("raid") -- update poll values mod.net.lastmtstring = newmt mod.net.lastmtsender = author mod.net.lastmttime = GetTime() end -- message was valid so return true return true end end end, -- clearing the master target ["cleartarget"] = function(author, message) -- check player is an officer if me.officercheck(author, message) then -- ignore polls / repeated clears if mod.net.lastmtstring == "clear" then -- do nothing else mod.boss.clearmastertarget() mod.out.print(string.format(mod.string.get("print", "network", "mtclear"), author)) KLHTM_RequestRedraw("raid") -- update poll values mod.net.lastmtstring = "clear" mod.net.lastmtsender = author mod.net.lastmttime = GetTime() end -- message was valid so return true return true end end, -- starting knockback discovery ["spellstart"] = function(author, message) -- check author is an officer if me.officercheck(author, message) == nil then return end mod.boss.isspellreportingactive = true if author == UnitName("player") then mod.boss.istrackingspells = true end -- only print out if you are a tracker if mod.boss.istrackingspells == true then mod.out.print(string.format(mod.string.get("print", "network", "knockbackstart"), author)) end return true end, -- stopping knockback discovery ["spellstop"] = function(author, message) -- check author is an officer if me.officercheck(author, message) == nil then return end mod.boss.isspellreportingactive = false if mod.boss.istrackingspells == true then mod.out.print(string.format(mod.string.get("print", "network", "knockbackstop"), author)) end return true end, -- When boss spell reporting is enabled and someone suffers a boss spell ["spelleffect"] = function(author, message, start) -- if we aren't monitoring reports, ignore if mod.boss.istrackingspells == false then return true -- we don't actually check correctness. end local _, _, spell, mob, result, data = string.find(message, "\"(.+)\" \"(.*)\" (%l+) ?(.*)", start + 1) if spell == nil then return end if result == "miss" then mod.out.print(string.format(mod.string.get("print", "boss", "reportmiss"), author, mob, spell)) else local value1, value2 _, _, value1, value2 = string.find(tostring(data), "(-?%d+) (-?%d+)") if (tostring(number) == nil) or (tostring(number) == nil) then return end if result == "proc" then mod.out.print(string.format(mod.string.get("print", "boss", "reportproc"), author, mob, spell, value1, value2)) elseif result == "tick" then mod.out.print(string.format(mod.string.get("print", "boss", "reporttick"), author, mob, spell, value1, value2)) else return end end return true end, -- when someone changes a parameter of a boss spell ["spellvalue"] = function(author, message, start) -- check author is an officer if me.officercheck(author, message) == nil then return end -- argh!! Memory creation! 64 bytes for this method! ... local arglist = {} local x for x in string.gfind(message, "[^ ]+") do table.insert(arglist, x) end table.remove(arglist, 1) -- parse local value, errormsg = mod.net.checkspellvaluesyntax(arglist) -- did it work? if value then if arglist[2] == "default" then --[[ suppose we receive the message "spellvalue timelapse default ticks 6". Then this would print out "Kenco sets the ticks parameter of the Time Lapse ability to 6." ]] mod.out.print(string.format(mod.string.get("print", "boss", "spellsetall"), author, "|cffffff00" .. arglist[3] .. "|r", mod.string.get("boss", "spell", arglist[1]), value, mod.boss.bossattacks[arglist[1]][arglist[2]][arglist[3]])) else mod.out.print(string.format(mod.string.get("print", "boss", "spellsetmob"), author, "|cffffff00" .. arglist[3] .. "|r", mod.string.get("boss", "spell", arglist[2]), mod.string.get("boss", "spell", arglist[1]), value, mod.boss.bossattacks[arglist[1]][arglist[2]][arglist[3]])) end mod.boss.bossattacks[arglist[1]][arglist[2]][arglist[3]] = value return true else if mod.out.checktrace("warning", me, "spellvalue") then mod.out.printtrace(string.format("The error message was '%s'.", errormsg)) end return end end, -- telling people to upgrade to a new version ["version"] = function(author, message, start) -- check author is an officer if me.officercheck(author, message) == nil then return end -- next argument should be the version number local release, revision _, _, release, revision = string.find(message, "(%d+)%.?(%d*)", start + 1) release = tonumber(release) revision = tonumber(revision) if release == nil then return end -- previously, only the release was sent as the version code. Therefore if someone sends in this format, -- their version must be old. if revision == nil then mod.out.print(string.format(mod.string.get("print", "network", "remoteoldversion"), author, release .. ".x", mod.release .. "." .. mod.revision)) else -- newer versions send their release and revision numbers, in a dot delimited string. if (release < mod.release) or (release == mod.release and revision < mod.revision) then -- other guy has an old version mod.out.print(string.format(mod.string.get("print", "network", "remoteoldversion"), author, release .. "." .. revision, mod.release .. "." .. mod.revision)) elseif (release == mod.release) and (revision == mod.revision) then -- we have the same version; do nothing else -- we have an older version - upgrade! mod.out.print(string.format(mod.string.get("print", "network", "upgraderequest"), author, release .. "." .. revision, mod.release .. "." .. mod.revision)) end end return true end, -- asking the raid group what versions they are using ["versionquery"] = function(author, message) -- check author is an officer if me.officercheck(author, message) == nil then return end -- send our version mod.net.sendmessage("versionresponse " .. mod.release .. "." .. mod.revision) return true end, -- response to versionquery ["versionresponse"] = function(author, message, start) -- next argument should be the version number local value = tonumber(string.sub(message, start + 1)) if value == nil then return end mod.net.addversionresponse(author, value) return true end, -- Boss Spell Event ["event"] = function(author, message, start) local eventid = string.sub(message, start + 1) -- check the event is valid if (eventid == nil) or (mod.boss.bossevents[eventid] == nil) then return end -- it is valid. send it to boss handler mod.boss.reportevent(eventid, author) return true end } ------------------------------------------------------------------------ --------------------------------- -- lololol Message Logging -- --------------------------------- me.messagelog = { ["nonklhtm"] = { ["count"] = 0, ["bytes"] = 0, }, ["invalid"] = { ["count"] = 0, ["bytes"] = 0, }, ["good"] = { ["count"] = 0, ["bytes"] = 0, }, ["total"] = { ["count"] = 0, ["bytes"] = 0, }, } --[[ me.logmessage(category, length) Record a message from the mod's chat channel. is one of the keys in me.messagelog. is the lenght in bytes of the complete message. ]] me.logmessage = function(category, length) me.messagelog[category].count = me.messagelog[category].count + 1 me.messagelog[category].bytes = me.messagelog[category].bytes + length me.messagelog["total"].count = me.messagelog["total"].count + 1 me.messagelog["total"].bytes = me.messagelog["total"].bytes + length end