Rework stinky detector to be a little more simple and a lot more functional

This commit is contained in:
2024-12-13 13:54:37 +01:00
parent de08a1e9df
commit 5ef92b23de
4 changed files with 56 additions and 443 deletions

View File

@@ -1,14 +1,12 @@
-- COMBAT_LOG_EVENT_UNFILTERED
---@param e string
function(e, ...)
-- /run RegisterAddonMessagePrefix("STINKY_DETECTOR")
-- RegisterAddonMessagePrefix(aura_env.addonprefix)
local detected = false
local stinky = ""
local source, err = CLEUParser.GetSourceName(...)
if not err then
if WeakAurasSaved.Cyka.stinkies[source] then
if aura_env.stinkies[source] then
stinky = source
detected = true
end
@@ -16,7 +14,7 @@ function(e, ...)
if not detected then
local destination, err = CLEUParser.GetDestName(...)
if not err then
if WeakAurasSaved.Cyka.stinkies[destination] then
if aura_env.stinkies[destination] then
stinky = destination
detected = true
end
@@ -27,36 +25,5 @@ function(e, ...)
aura_env.StinkyDetected(stinky)
end
local overkill, err = CLEUParser.GetOverkill(...)
if err == nil then
local source, err = CLEUParser.GetSourceName(...)
if err ~= nil then source = "unknown" end
local destination, err = CLEUParser.GetDestName(...)
if err ~= nil then destination = "unknown" end
local spellName, err = CLEUParser.GetSpellName(...)
if err ~= nil then spellName = "unknown" end
local sourceid, err = CLEUParser.GetSourceGUID(...)
if err and aura_env.config.debug then
print("Could not get source id for " .. source)
print(...)
return true
end
local destid, err = CLEUParser.GetDestGUID(...)
if err and aura_env.config.debug then
print("Could not get destination id for " .. destination)
print(...)
return true
end
if not string.match(sourceid, "Player") then
-- print("Source is not a player, nevermind...")
return true
end
if not string.match(destid, "Player") then
-- print("Destination is not a player, nevermind...")
return true
end
aura_env.RegisterKill(source, destination, spellName, overkill)
end
return true
end

View File

@@ -1,18 +1,44 @@
-- TICKER_100
function()
---@type Message
local message = aura_env.messageQueue[1]
if message == nil then return end
table.remove(aura_env.messageQueue, 1)
if aura_env.config.debug then
print(string.format("Processing message; %d in queue", #aura_env.messageQueue))
DevTools_Dump(message)
-- TICKER_1000
---@param allstates allstates
---@param e string
---@param prefix string
---@param msg string
function(allstates, e, prefix, msg, ...)
for i = 1, 40 do
if UnitIsPlayer("nameplate" .. i) then
local name = UnitName("nameplate" .. i)
if aura_env.stinkies[name] then
aura_env.StinkyDetected(name)
end
end
end
if message.addon then
SendAddonMessage(aura_env.addonprefix, message.message, message.channel, message.to)
else
SendChatMessage(message.message, message.channel, nil, message.to)
local ttl = aura_env.config.ttl or 10
for stinky, data in pairs(aura_env.detectedStinkies) do
local elapsed = GetTime() - data.seen
if allstates[stinky] then
if elapsed > ttl then
allstates[stinky].show = false
allstates[stinky].changed = true
aura_env.detectedStinkies[stinky] = nil
else
allstates[stinky].progress = string.format("%20s", elapsed)
allstates[stinky].changed = true
end
else
allstates[stinky] = {
show = true,
changed = true,
name = string.format("%-20s", stinky),
progressType = "timed",
duration = ttl,
expirationTime = GetTime() + ttl,
autohide = true,
index = GetTime(),
progress = string.format("%20s", elapsed)
}
end
end
end
return true
end

View File

@@ -1,114 +0,0 @@
-- CHAT_MSG_ADDON TICKER_1000
---@param allstates allstates
---@param e string
---@param prefix string
---@param msg string
function(allstates, e, prefix, msg, ...)
if e == "TICKER_1000" then
local ttl = aura_env.config.ttl or 120
for _, state in pairs(allstates) do
if state.progress then
local elapsedTime = GetTime() - state.index
if elapsedTime > ttl then
state.show = false
state.changed = true
else
local prettyTime = ""
local minutes = 0
while elapsedTime > 60 do
elapsedTime = elapsedTime - 60
minutes = minutes + 1
end
if minutes > 0 then
prettyTime = string.format("%s%dm", prettyTime, minutes)
end
if elapsedTime > 0 then
prettyTime = string.format("%s %ds", prettyTime, elapsedTime)
end
state.progress = string.format("%20s", prettyTime)
state.changed = true
end
end
end
for i = 1, 40 do
if UnitIsPlayer("nameplate" .. i) then
local name = UnitName("nameplate" .. i)
local faction = UnitFactionGroup("nameplate" .. i)
local _, race = UnitRace("nameplate" .. i)
local raceFaction = aura_env.raceFactions[race]
if not raceFaction and aura_env.config.debug then
print("Unknown race faction", race)
else
faction = raceFaction
end
WeakAurasSaved.Cyka.PlayerFactionCache[name] = faction
end
end
return true
end
if not prefix or prefix ~= aura_env.addonprefix then return end
local parts = {}
for part in string.gmatch(msg, "([^" .. aura_env.separator .. "]+)") do
table.insert(parts, part)
end
local name = parts[1]
local threat = tonumber(parts[2])
local note = parts[3]
if not name then
if aura_env.config.debug then
print(string.format("Could not get name for %s (%s) with deliminer '%s'", msg, name or "nil", aura_env.separator))
end
return
end
if not threat then
if aura_env.config.debug then
print(string.format("Could not get threat for %s (%s) with deliminer '%s'", msg, threat or "nil", aura_env.separator))
end
return
end
if not note then
if aura_env.config.debug then
print(string.format("Could not get note for %s (%s) with deliminer '%s'", msg, note or "nil", aura_env.separator))
end
end
if threat < aura_env.config.threatThreshold then
if aura_env.config.debug then
print(string.format("Skipping notify due to low threat (%d < %d)", threat, aura_env.config.threatThreshold))
end
return
end
local stinky = WeakAurasSaved.Cyka.stinkies[name]
if not stinky then
if aura_env.config.debug then
print(string.format("Could not find stinky for %s", name))
end
return false
end
if not aura_env.soundNotifyTimer[name] or aura_env.soundNotifyTimer[name] < GetTime() then
PlaySoundFile("Interface\\Sounds\\Domination.ogg", "Master")
aura_env.soundNotifyTimer[name] = GetTime() + aura_env.config.alertThrottle
end
allstates[name] = {
show = true,
changed = true,
name = string.format("%-20s%2d%35s", name, stinky.threat, note),
progressType = "timed",
duration = 60,
expirationTime = GetTime() + aura_env.config.alertThrottle,
autohide = true,
index = GetTime(),
progress = string.format("%20s", "0s"),
}
return true
end

View File

@@ -1,21 +1,10 @@
---@class aura_env
---@field messageQueue Message[]
---@field separator string
---@field addonprefix string
---@field config table<string, any>
---@field stinkies Stinky[]
---@field raceFactions table<string, string>
---@field localStinkies table<string, Stinky>
---@field soundNotifyTimer table<string, number>
---@field GetZone fun(): string
---@field RegisterKill fun(source: string, destination: string, spellName: string, overkill: number)
---@field stinkies table<string, boolean>
---@field detectedStinkies table<string, {seen: number, soundPlayed: number?}>
---@field StinkyDetected fun(name: string)
aura_env.soundNotifyTimer = {}
aura_env.messageQueue = {}
aura_env.separator = "ž"
aura_env.addonprefix = "STINKY_DETECTOR"
RegisterAddonMessagePrefix(aura_env.addonprefix)
aura_env.stinkies = {}
aura_env.detectedStinkies = {}
---@param input string
---@param deliminer string
@@ -30,273 +19,18 @@ local function StrSplit(input, deliminer)
return parts, nil
end
---@type string[]
local toNotify = StrSplit(aura_env.config.notify, ",")
for i, part in ipairs(toNotify) do
toNotify[i] = strtrim(part)
end
WeakAurasSaved.Cyka.stinkies = {}
if not WeakAurasSaved.Cyka.PlayerFactionCache then WeakAurasSaved.Cyka.PlayerFactionCache = {} end
---@class Message
---@field message string
---@field to string
---@field channel string
---@field addon boolean
Message = {
message = "",
to = "",
channel = "",
addon = false,
---@param message string
---@param to string
---@param channel string
---@param addon? boolean
---@return Message
new = function(message, to, channel, addon)
local self = setmetatable({}, {
__index = Message
})
self.message = message
self.to = to
self.channel = channel
self.addon = addon or false
return self
end,
---@param stinky Stinky
QueueNotifyGuild = function(stinky)
if not aura_env.config.stinkyNotifyGuild then return end
if aura_env.config.debug then print("Queueing notify guild:") end
local message = Message.new(stinky:FormMessage(), nil, "GUILD")
if aura_env.config.debug then DevTools_Dump(message) end
table.insert(aura_env.messageQueue, message)
end,
---@param stinky Stinky
QueueNotifyWhisper = function(stinky)
if not aura_env.config.stinkyNotifyWhisper then return end
if aura_env.config.debug then print("Queueing notify whisper:") end
local text = stinky:FormMessage()
for _, to in ipairs(toNotify) do
local message = Message.new(text, to, "WHISPER")
if aura_env.config.debug then DevTools_Dump(message) end
table.insert(aura_env.messageQueue, message)
end
end,
---@param stinky Stinky
QueueNotifyAddonGuild = function(stinky)
if not aura_env.config.stinkyNotifyAddonGuild then return end
if aura_env.config.debug then print("Queueing notify addon guild:") end
local message = Message.new(stinky:FormAddonMessage(), nil, "GUILD", true)
if aura_env.config.debug then DevTools_Dump(message) end
table.insert(aura_env.messageQueue, message)
end,
---@param stinky Stinky
QueueNotifyAddonWhisper = function(stinky)
if not aura_env.config.stinkyNotifyAddonWhisper then return end
if aura_env.config.debug then print("Queueing notify addon whisper:") end
local text = stinky:FormAddonMessage()
for _, to in ipairs(toNotify) do
local message = Message.new(text, to, "WHISPER", true)
if aura_env.config.debug then DevTools_Dump(message) end
table.insert(aura_env.messageQueue, message)
end
end,
---@param faction string
---@param source string
---@param destination string
---@param spellName string
QueueNotifyKilledAddonGuild = function(faction, source, destination, spellName)
if not aura_env.config.killNotifyAddonGuild then return end
if aura_env.config.debug then print("Queueing notify addon guild:") end
local text = table.concat({ faction, source, spellName }, aura_env.separator)
local message = Message.new(text, nil, "GUILD", true)
if aura_env.config.debug then DevTools_Dump(message) end
table.insert(aura_env.messageQueue, message)
end,
---@param faction string
---@param source string
---@param destination string
---@param spellName string
QueueNotifyKilledAddonWhisper = function(faction, source, destination, spellName)
if not aura_env.config.killNotifyAddonWhisper then return end
if aura_env.config.debug then print("Queueing notify addon whisper:") end
local text = table.concat({ faction, source, destination, spellName }, aura_env.separator)
for _, to in ipairs(toNotify) do
local message = Message.new(text, to, "WHISPER", true)
if aura_env.config.debug then DevTools_Dump(message) end
table.insert(aura_env.messageQueue, message)
end
end,
---@param faction string
---@param source string
---@param destination string
---@param spellName string
QueueNotifyKilledGuild = function(faction, source, destination, spellName)
if not aura_env.config.killNotifyGuild then return end
if aura_env.config.debug then print("Queueing notify guild:") end
local text = string.format("%s %s убил %s с помощью %s", faction, source, destination, spellName)
local message = Message.new(text, nil, "GUILD")
if aura_env.config.debug then DevTools_Dump(message) end
table.insert(aura_env.messageQueue, message)
end,
---@param faction string
---@param source string
---@param destination string
---@param spellName string
QueueNotifyKilledWhisper = function(faction, source, destination, spellName)
if not aura_env.config.killNotifyWhisper then return end
if aura_env.config.debug then print("Queueing notify whisper:") end
local text = string.format("%s %s убил %s с помощью %s", faction, source, destination, spellName)
for _, to in ipairs(toNotify) do
local message = Message.new(text, to, "WHISPER")
if aura_env.config.debug then DevTools_Dump(message) end
table.insert(aura_env.messageQueue, message)
end
end
}
---@class Stinky
---@field name string
---@field threat number 1-10 10 being maxima threat
---@field note string|nil
Stinky = {
name = "",
threat = 0,
note = "",
---@param name string
---@param threat number
---@param note string|nil
---@return Stinky
new = function(name, threat, note)
local self = setmetatable({}, {
__index = Stinky
})
self.name = name
self.threat = threat
self.note = note
return self
end,
---@param self Stinky
---@return string
FormMessage = function(self)
return string.format("%s in %s!", self.name, aura_env.GetZone())
end,
---@param self Stinky
---@return string
FormAddonMessage = function(self)
return table.concat({ self.name, self.threat, aura_env.GetZone() }, aura_env.separator)
end,
}
aura_env.raceFactions = {
["Orc"] = "Horde",
["Undead"] = "Horde",
["Tauren"] = "Horde",
["Troll"] = "Horde",
["BloodElf"] = "Horde",
["Goblin"] = "Horde",
["Human"] = "Alliance",
["Dwarf"] = "Alliance",
["NightElf"] = "Alliance",
["Gnome"] = "Alliance",
["Draenei"] = "Alliance",
["Worgen"] = "Alliance",
}
aura_env.GetZone = function()
return string.format("%s (%s)", GetZoneText(), GetSubZoneText())
end
local stinkies = StrSplit(aura_env.config.stinkies, ",")
for i, part in ipairs(stinkies) do
local datum = StrSplit(part, ":")
local name = strtrim(datum[1])
if name then
local threat = tonumber(strtrim(datum[2] or "5"))
WeakAurasSaved.Cyka.stinkies[name] = Stinky.new(name, threat)
end
for _, name in ipairs(stinkies) do
aura_env.stinkies[name] = true
end
local killSpamTime = 10
local recentlyKilled = {}
aura_env.RegisterKill = function(source, destination, spellName, overkill)
if recentlyKilled[source] and recentlyKilled[source] > GetTime() - killSpamTime then
print("Death already reported")
return
end
if overkill <= 0 then return end
local faction = "Неизвестная фракция"
if WeakAurasSaved.Cyka.PlayerFactionCache[source] then
faction = WeakAurasSaved.Cyka.PlayerFactionCache[source]
end
Message.QueueNotifyKilledGuild(faction, source, destination, spellName)
Message.QueueNotifyKilledWhisper(faction, source, destination, spellName)
Message.QueueNotifyKilledAddonGuild(faction, source, destination, spellName)
Message.QueueNotifyKilledAddonWhisper(faction, source, destination, spellName)
recentlyKilled[source] = GetTime()
end
aura_env.localStinkies = {}
---@param name string
aura_env.StinkyDetected = function(name)
if aura_env.config.debug then print(string.format("StinkyDetected (%s)", name)) end
local stinky = WeakAurasSaved.Cyka.stinkies[name]
if not aura_env.localStinkies[name] or aura_env.localStinkies[name] <
GetTime() - aura_env.config.messageThrottle then
Message.QueueNotifyGuild(stinky)
Message.QueueNotifyWhisper(stinky)
print("StinkyDetected", name)
DevTools_Dump(aura_env.detectedStinkies)
aura_env.detectedStinkies[name] = { seen = GetTime() }
if not aura_env.detectedStinkies[name].soundPlayed or
aura_env.detectedStinkies[name].soundPlayed < GetTime() - aura_env.config.soundThrottle then
PlaySoundFile("Interface\\Sounds\\Domination.ogg", "Master")
aura_env.detectedStinkies[name].soundPlayed = GetTime()
end
if not aura_env.localStinkies[name] or aura_env.localStinkies[name] <
GetTime() - aura_env.config.messageThrottleAddon then
Message.QueueNotifyAddonGuild(stinky)
Message.QueueNotifyAddonWhisper(stinky)
end
WeakAuras.ScanEvents("CHAT_MSG_ADDON", aura_env.addonprefix, stinky:FormAddonMessage())
aura_env.localStinkies[name] = GetTime()
end
if aura_env.config.addFriends and not aura_env.config.addFriends2 then
local friends = {}
local numfriends = GetNumFriends()
for i = 1, numfriends do
local name = GetFriendInfo(i)
friends[name] = true
end
for k, v in pairs(WeakAurasSaved.Cyka.stinkies) do
if not friends[k] then
AddFriend(k)
end
end
C_Timer.After(1, function()
local numfriends = GetNumFriends()
for i = 1, numfriends do
local name = GetFriendInfo(i)
if WeakAurasSaved.Cyka.stinkies[name] then
C_Timer.After(1, function()
-- print(name .. " " .. i .. " Stinky!")
SetFriendNotes(i, "STINKY")
end)
else
C_Timer.After(1, function()
-- print(name .. " " .. i .. " Not stinky")
SetFriendNotes(i, "Not stinky?")
end)
end
end
end)
end
--/run WeakAurasSaved.Cyka.Stinkies["Totleta"] = true
-- /dump WeakAurasSaved.Cyka.Stinkies