Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b3fe60a657 | ||
ed5c5089b3 |
87
.github/workflows/release.yml
vendored
Normal file
87
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
name: Release Workflow
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Install zip
|
||||||
|
run: sudo apt-get install zip
|
||||||
|
|
||||||
|
- name: Configure Git
|
||||||
|
run: |
|
||||||
|
git config --global user.name "Git Admin"
|
||||||
|
git config --global user.email "gitadmin@quack-lab.dev"
|
||||||
|
|
||||||
|
- name: Run deploy script
|
||||||
|
run: bash deploy.sh
|
||||||
|
|
||||||
|
- name: Check for Existing Release Commit
|
||||||
|
id: check_release_commit
|
||||||
|
run: |
|
||||||
|
# Check if the latest commit is a release commit
|
||||||
|
if git log -1 --pretty=%B | grep -q "Release"; then
|
||||||
|
echo "Release commit found. Skipping version bump."
|
||||||
|
echo "::set-output name=release_commit::true"
|
||||||
|
else
|
||||||
|
echo "No release commit found. Proceeding with version bump."
|
||||||
|
echo "::set-output name=release_commit::false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Run Release Script
|
||||||
|
if: steps.check_release_commit.outputs.release_commit == 'false'
|
||||||
|
run: bash release.sh
|
||||||
|
|
||||||
|
- name: Push Changes
|
||||||
|
if: steps.check_release_commit.outputs.release_commit == 'false'
|
||||||
|
run: |
|
||||||
|
git push origin HEAD:refs/heads/master --tags
|
||||||
|
|
||||||
|
- name: Determine Tag
|
||||||
|
id: determine_tag
|
||||||
|
run: |
|
||||||
|
# Check if the last commit has a tag
|
||||||
|
TAG=$(git describe --tags --exact-match 2>/dev/null || echo "")
|
||||||
|
if [ -z "$TAG" ]; then
|
||||||
|
# Get the latest tag
|
||||||
|
LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||||
|
# Increment the minor version
|
||||||
|
IFS='.' read -r -a VERSION_PARTS <<< "$LATEST_TAG"
|
||||||
|
VERSION_PARTS[2]=$((VERSION_PARTS[2]+1))
|
||||||
|
TAG="${VERSION_PARTS[0]}.${VERSION_PARTS[1]}.${VERSION_PARTS[2]}"
|
||||||
|
# Create a new tag
|
||||||
|
git tag $TAG
|
||||||
|
git push origin $TAG
|
||||||
|
fi
|
||||||
|
echo "::set-output name=tag::$TAG"
|
||||||
|
|
||||||
|
- name: Create Release
|
||||||
|
id: create_release
|
||||||
|
run: |
|
||||||
|
curl -X POST \
|
||||||
|
-H "Authorization: token ${{ secrets.JEBENI_TOKEN }}" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"tag_name": "${{ steps.determine_tag.outputs.tag }}",
|
||||||
|
"name": "${{ steps.determine_tag.outputs.tag }}",
|
||||||
|
"draft": false,
|
||||||
|
"prerelease": false
|
||||||
|
}' \
|
||||||
|
http://srv-captain--git:3000/api/v1/repos/dave/wow-Heimdall/releases
|
||||||
|
|
||||||
|
- name: Upload Release Asset
|
||||||
|
run: |
|
||||||
|
RELEASE_ID=$(curl -s \
|
||||||
|
-H "Authorization: token ${{ secrets.JEBENI_TOKEN }}" \
|
||||||
|
http://srv-captain--git:3000/api/v1/repos/dave/wow-Heimdall/releases/tags/${{ steps.determine_tag.outputs.tag }} | jq -r '.id')
|
||||||
|
curl -X POST \
|
||||||
|
-H "Authorization: token ${{ secrets.JEBENI_TOKEN }}" \
|
||||||
|
-H "Content-Type: application/zip" \
|
||||||
|
--data-binary @Heimdall.zip \
|
||||||
|
http://srv-captain--git:3000/api/v1/repos/dave/wow-Heimdall/releases/${RELEASE_ID}/assets
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
scratch.lua
|
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
globals = { "CykaPersistentData", "CreateFrame", "GetItemInfo", "aura_env" }
|
|
||||||
unused_args = false
|
|
||||||
max_line_length = 500
|
|
||||||
exclude_files = { "Meta/" }
|
|
||||||
global = false
|
|
14
.luarc.json
14
.luarc.json
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"workspace": {
|
|
||||||
"library": [
|
|
||||||
"./Meta"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"diagnostics.disable": [
|
|
||||||
"unused-local",
|
|
||||||
"unused-vararg"
|
|
||||||
],
|
|
||||||
"diagnostics.globals": [
|
|
||||||
"aura_env"
|
|
||||||
]
|
|
||||||
}
|
|
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"Lua.diagnostics.globals": [
|
||||||
|
"UIParent",
|
||||||
|
"BattlefieldMinimap"
|
||||||
|
]
|
||||||
|
}
|
1278
Heimdall.lua
1278
Heimdall.lua
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
|||||||
## Interface: 70300
|
## Interface: 70300
|
||||||
## Title: Heimdall
|
## Title: Heimdall
|
||||||
## Version: 3.12.0
|
## Version: 3.10.1
|
||||||
## Notes: Watches over areas and alerts when hostiles spotted
|
## Notes: Watches over areas and alerts when hostiles spotted
|
||||||
## Author: Cyka
|
## Author: Cyka
|
||||||
## SavedVariables: Heimdall_Data, Heimdall_Achievements, Heimdall_Chat
|
## SavedVariables: Heimdall_Data, Heimdall_Achievements
|
||||||
|
|
||||||
_L.lua
|
_L.lua
|
||||||
Modules/CLEUParser.lua
|
Modules/CLEUParser.lua
|
||||||
@@ -33,5 +33,4 @@ Modules/NetworkMessenger.lua
|
|||||||
Modules/StinkyCache.lua
|
Modules/StinkyCache.lua
|
||||||
Modules/Configurator.lua
|
Modules/Configurator.lua
|
||||||
Modules/AchievementSniffer.lua
|
Modules/AchievementSniffer.lua
|
||||||
Modules/ChatSniffer.lua
|
|
||||||
Heimdall.lua
|
Heimdall.lua
|
||||||
|
2
Meta
2
Meta
Submodule Meta updated: eee043a846...c0337ef97f
@@ -1,19 +1,10 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "AchievementSniffer"
|
local ModuleName = "AchievementSniffer"
|
||||||
|
|
||||||
---@class HeimdallAchievementSnifferConfig
|
local HeimdallRoot = "Interface\\AddOns\\Heimdall\\"
|
||||||
---@field enabled boolean
|
local TextureRoot = HeimdallRoot .. "Texture\\"
|
||||||
---@field debug boolean
|
|
||||||
-----@field texture string
|
|
||||||
-----@field offsetX number
|
|
||||||
-----@field offsetY number
|
|
||||||
---@field rescan boolean
|
|
||||||
---@field scanInterval number
|
|
||||||
-----@field iconScale number
|
|
||||||
|
|
||||||
-- local HeimdallRoot = "Interface\\AddOns\\Heimdall\\"
|
|
||||||
-- local TextureRoot = HeimdallRoot .. "Texture\\"
|
|
||||||
|
|
||||||
local Achievements = {
|
local Achievements = {
|
||||||
15,
|
15,
|
||||||
@@ -84,221 +75,223 @@ local Achievements = {
|
|||||||
12448,
|
12448,
|
||||||
}
|
}
|
||||||
|
|
||||||
---@class AchievementSniffer
|
---@diagnostic disable-next-line: missing-fields
|
||||||
shared.AchievementSniffer = {
|
shared.AchievementSniffer = {}
|
||||||
Init = function()
|
function shared.AchievementSniffer.Init()
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
|
||||||
end
|
|
||||||
local guidMap = {}
|
|
||||||
|
|
||||||
---@class AchievementData
|
|
||||||
---@field id number
|
|
||||||
---@field date string
|
|
||||||
---@field completed boolean
|
|
||||||
|
|
||||||
---@class Heimdall_Achievements
|
|
||||||
---@field players table<string, table<number, AchievementData>>
|
|
||||||
---@field alreadySeen table<string, boolean>
|
|
||||||
---@field rescan boolean
|
|
||||||
if not Heimdall_Achievements then Heimdall_Achievements = {} end
|
|
||||||
if not Heimdall_Achievements.players then Heimdall_Achievements.players = {} end
|
|
||||||
if not Heimdall_Achievements.alreadySeen then Heimdall_Achievements.alreadySeen = {} end
|
|
||||||
|
|
||||||
--local framePool = {}
|
|
||||||
--for i = 1, 40 do
|
|
||||||
-- local frame = CreateFrame("Frame", "HeimdallAchievementSnifferNameplate" .. i, UIParent)
|
|
||||||
-- local texture = frame:CreateTexture(nil, "ARTWORK")
|
|
||||||
-- texture:SetAllPoints(frame)
|
|
||||||
-- texture:SetTexture(TextureRoot .. Heimdall_Data.config.achievementSniffer.texture)
|
|
||||||
-- frame.texture = texture
|
|
||||||
-- frame:Hide()
|
|
||||||
-- table.insert(framePool, frame)
|
|
||||||
--end
|
|
||||||
|
|
||||||
---@param name string
|
|
||||||
---@return boolean
|
|
||||||
local function ShouldInspect(name)
|
|
||||||
local should = false
|
|
||||||
if not Heimdall_Achievements.players[name] then
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Player %s does not have prior achievement data", ModuleName, name))
|
|
||||||
end
|
|
||||||
should = true
|
|
||||||
end
|
|
||||||
if Heimdall_Achievements.alreadySeen[name] then
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Player %s has already been seen", ModuleName, name))
|
|
||||||
end
|
|
||||||
-- Save some memory
|
|
||||||
Heimdall_Achievements.players[name] = nil
|
|
||||||
should = false
|
|
||||||
end
|
|
||||||
if Heimdall_Data.config.achievementSniffer.rescan then
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Rescan is enabled", ModuleName))
|
|
||||||
end
|
|
||||||
should = true
|
|
||||||
end
|
|
||||||
return should
|
|
||||||
end
|
|
||||||
|
|
||||||
-- It's not working well AT ALL
|
|
||||||
-- I don't know how to do it better
|
|
||||||
-- It simply just does not work...
|
|
||||||
--local function UpdateFrames()
|
|
||||||
-- for i, frame in ipairs(framePool) do
|
|
||||||
-- local unit = "nameplate" .. i
|
|
||||||
-- if not UnitExists(unit) then
|
|
||||||
-- --if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
-- -- print(string.format("[%s] Unit %s does not exist, hiding frame", ModuleName, unit))
|
|
||||||
-- --end
|
|
||||||
-- frame:Hide()
|
|
||||||
-- else
|
|
||||||
-- --local unitFrame = _G[string.format("ElvUI_NamePlate%dHealthBar", i)]
|
|
||||||
-- local unitFrame = _G[string.format("NamePlate%d", i)]
|
|
||||||
-- if unitFrame == nil then
|
|
||||||
-- if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
-- print(string.format("[%s] Unit frame for %s not found", ModuleName, unit))
|
|
||||||
-- end
|
|
||||||
-- frame:Hide()
|
|
||||||
-- else
|
|
||||||
-- local unitName = UnitName(unit)
|
|
||||||
-- if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
-- print(string.format("[%s] Unit frame found for %s (%s)", ModuleName, unit, unitName))
|
|
||||||
-- end
|
|
||||||
-- frame:Show()
|
|
||||||
-- frame:SetSize(32, 32)
|
|
||||||
-- frame:SetFrameStrata("HIGH")
|
|
||||||
-- frame:SetFrameLevel(100)
|
|
||||||
-- frame:SetScale(Heimdall_Data.config.achievementSniffer.iconScale)
|
|
||||||
-- frame.texture:SetTexture(TextureRoot .. Heimdall_Data.config.achievementSniffer.texture)
|
|
||||||
-- frame:SetPoint("CENTER", unitFrame, "CENTER",
|
|
||||||
-- Heimdall_Data.config.achievementSniffer.offsetX,
|
|
||||||
-- Heimdall_Data.config.achievementSniffer.offsetY)
|
|
||||||
-- frame:SetParent(unitFrame)
|
|
||||||
-- frame:SetAlpha(1)
|
|
||||||
-- local exists = ShouldInspect(unitName)
|
|
||||||
-- if exists then
|
|
||||||
-- frame.texture:SetVertexColor(1, 0, 0, 1)
|
|
||||||
-- else
|
|
||||||
-- frame.texture:SetVertexColor(0, 1, 0, 1)
|
|
||||||
-- end
|
|
||||||
-- if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
-- print(string.format("[%s] Frame updated for %s", ModuleName, unitName))
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
--end
|
|
||||||
|
|
||||||
---@param unit string
|
|
||||||
local function TryInspect(unit)
|
|
||||||
local targetPlayer = UnitIsPlayer(unit)
|
|
||||||
if not targetPlayer then return end
|
|
||||||
local targetName = UnitName(unit)
|
|
||||||
local targetGuid = UnitGUID(unit)
|
|
||||||
guidMap[targetGuid] = targetName
|
|
||||||
|
|
||||||
if not ShouldInspect(targetName) then
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Not inspecting player: %s", ModuleName, targetName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local canInspect = CheckInteractDistance(unit, 1)
|
|
||||||
if canInspect then
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Inspecting player: %s", ModuleName, targetName))
|
|
||||||
end
|
|
||||||
SetAchievementComparisonUnit(unit)
|
|
||||||
else
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Cannot inspect player (too far?): %s", ModuleName, targetName))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param name string
|
|
||||||
local function Scan(name)
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Scanning achievements for %s", ModuleName, name))
|
|
||||||
end
|
|
||||||
Heimdall_Achievements.players[name] = {}
|
|
||||||
for i, aid in ipairs(Achievements) do
|
|
||||||
local completed, month, day, year = GetAchievementComparisonInfo(aid)
|
|
||||||
if completed then
|
|
||||||
---@type string
|
|
||||||
local yearstr = "" .. year
|
|
||||||
if year < 100 then yearstr = "20" .. year end
|
|
||||||
|
|
||||||
local date = string.format("%04d-%02d-%02d", yearstr, month, day)
|
|
||||||
|
|
||||||
local data = {
|
|
||||||
id = aid,
|
|
||||||
date = date,
|
|
||||||
completed = completed,
|
|
||||||
}
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Achievement %d completed on %s", ModuleName, aid, date))
|
|
||||||
end
|
|
||||||
Heimdall_Achievements.players[name][aid] = data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--UpdateFrames()
|
|
||||||
end
|
|
||||||
|
|
||||||
local nameplateFrame = CreateFrame("Frame")
|
|
||||||
nameplateFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
|
||||||
nameplateFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
|
|
||||||
nameplateFrame:SetScript("OnEvent", function(self, event, unit)
|
|
||||||
if not Heimdall_Data.config.achievementSniffer.enabled then return end
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Event triggered: %s for unit: %s", ModuleName, event, unit))
|
|
||||||
end
|
|
||||||
if event == "NAME_PLATE_UNIT_ADDED" then TryInspect(unit) end
|
|
||||||
--UpdateFrames()
|
|
||||||
end)
|
|
||||||
|
|
||||||
local inspectFrame = CreateFrame("Frame")
|
|
||||||
inspectFrame:RegisterEvent("INSPECT_ACHIEVEMENT_READY")
|
|
||||||
inspectFrame:SetScript("OnEvent", function(self, event, guid)
|
|
||||||
if not Heimdall_Data.config.achievementSniffer.enabled then return end
|
|
||||||
local name = guidMap[guid]
|
|
||||||
if not name then
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] No name found for guid: %s", ModuleName, guid))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Event triggered: %s for player: %s", ModuleName, event, name))
|
|
||||||
end
|
|
||||||
Scan(name)
|
|
||||||
end)
|
|
||||||
|
|
||||||
local function Tick()
|
|
||||||
C_Timer.NewTimer(Heimdall_Data.config.achievementSniffer.scanInterval, Tick)
|
|
||||||
if not Heimdall_Data.config.achievementSniffer.enabled then return end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
print(string.format("[%s] Scanning achievements for everyone on screen", ModuleName))
|
|
||||||
end
|
|
||||||
for i = 1, 40 do
|
|
||||||
local unit = "nameplate" .. i
|
|
||||||
if UnitExists(unit) then
|
|
||||||
TryInspect(unit)
|
|
||||||
--else
|
|
||||||
-- if Heimdall_Data.config.achievementSniffer.debug then
|
|
||||||
-- print(string.format("[%s] Unit %s does not exist, nothing to inspect", ModuleName, unit))
|
|
||||||
-- end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--UpdateFrames()
|
|
||||||
end
|
|
||||||
Tick()
|
|
||||||
|
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Module initialized", ModuleName))
|
||||||
end,
|
end
|
||||||
}
|
local guidMap = {}
|
||||||
|
|
||||||
|
---@class AchievementData
|
||||||
|
---@field id number
|
||||||
|
---@field date string
|
||||||
|
---@field completed boolean
|
||||||
|
|
||||||
|
---@class Heimdall_Achievements
|
||||||
|
---@field players table<string, table<number, AchievementData>>
|
||||||
|
---@field alreadySeen table<string, boolean>
|
||||||
|
---@field rescan boolean
|
||||||
|
if not Heimdall_Achievements then Heimdall_Achievements = {} end
|
||||||
|
if not Heimdall_Achievements.players then Heimdall_Achievements.players = {} end
|
||||||
|
if not Heimdall_Achievements.alreadySeen then Heimdall_Achievements.alreadySeen = {} end
|
||||||
|
|
||||||
|
--local framePool = {}
|
||||||
|
--for i = 1, 40 do
|
||||||
|
-- local frame = CreateFrame("Frame", "HeimdallAchievementSnifferNameplate" .. i, UIParent)
|
||||||
|
-- local texture = frame:CreateTexture(nil, "ARTWORK")
|
||||||
|
-- texture:SetAllPoints(frame)
|
||||||
|
-- texture:SetTexture(TextureRoot .. Heimdall_Data.config.achievementSniffer.texture)
|
||||||
|
-- frame.texture = texture
|
||||||
|
-- frame:Hide()
|
||||||
|
-- table.insert(framePool, frame)
|
||||||
|
--end
|
||||||
|
|
||||||
|
---@param name string
|
||||||
|
---@return boolean
|
||||||
|
local function ShouldInspect(name)
|
||||||
|
local should = false
|
||||||
|
if not Heimdall_Achievements.players[name] then
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Player %s does not have prior achievement data", ModuleName, name))
|
||||||
|
end
|
||||||
|
should = true
|
||||||
|
end
|
||||||
|
if Heimdall_Achievements.alreadySeen[name] then
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Player %s has already been seen", ModuleName, name))
|
||||||
|
end
|
||||||
|
-- Save some memory
|
||||||
|
Heimdall_Achievements.players[name] = nil
|
||||||
|
should = false
|
||||||
|
end
|
||||||
|
if Heimdall_Data.config.achievementSniffer.rescan then
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Rescan is enabled", ModuleName))
|
||||||
|
end
|
||||||
|
should = true
|
||||||
|
end
|
||||||
|
return should
|
||||||
|
end
|
||||||
|
|
||||||
|
-- It's not working well AT ALL
|
||||||
|
-- I don't know how to do it better
|
||||||
|
-- It simply just does not work...
|
||||||
|
--local function UpdateFrames()
|
||||||
|
-- for i, frame in ipairs(framePool) do
|
||||||
|
-- local unit = "nameplate" .. i
|
||||||
|
-- if not UnitExists(unit) then
|
||||||
|
-- --if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
-- -- print(string.format("[%s] Unit %s does not exist, hiding frame", ModuleName, unit))
|
||||||
|
-- --end
|
||||||
|
-- frame:Hide()
|
||||||
|
-- else
|
||||||
|
-- --local unitFrame = _G[string.format("ElvUI_NamePlate%dHealthBar", i)]
|
||||||
|
-- local unitFrame = _G[string.format("NamePlate%d", i)]
|
||||||
|
-- if unitFrame == nil then
|
||||||
|
-- if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
-- print(string.format("[%s] Unit frame for %s not found", ModuleName, unit))
|
||||||
|
-- end
|
||||||
|
-- frame:Hide()
|
||||||
|
-- else
|
||||||
|
-- local unitName = UnitName(unit)
|
||||||
|
-- if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
-- print(string.format("[%s] Unit frame found for %s (%s)", ModuleName, unit, unitName))
|
||||||
|
-- end
|
||||||
|
-- frame:Show()
|
||||||
|
-- frame:SetSize(32, 32)
|
||||||
|
-- frame:SetFrameStrata("HIGH")
|
||||||
|
-- frame:SetFrameLevel(100)
|
||||||
|
-- frame:SetScale(Heimdall_Data.config.achievementSniffer.iconScale)
|
||||||
|
-- frame.texture:SetTexture(TextureRoot .. Heimdall_Data.config.achievementSniffer.texture)
|
||||||
|
-- frame:SetPoint("CENTER", unitFrame, "CENTER",
|
||||||
|
-- Heimdall_Data.config.achievementSniffer.offsetX,
|
||||||
|
-- Heimdall_Data.config.achievementSniffer.offsetY)
|
||||||
|
-- frame:SetParent(unitFrame)
|
||||||
|
-- frame:SetAlpha(1)
|
||||||
|
-- local exists = ShouldInspect(unitName)
|
||||||
|
-- if exists then
|
||||||
|
-- frame.texture:SetVertexColor(1, 0, 0, 1)
|
||||||
|
-- else
|
||||||
|
-- frame.texture:SetVertexColor(0, 1, 0, 1)
|
||||||
|
-- end
|
||||||
|
-- if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
-- print(string.format("[%s] Frame updated for %s", ModuleName, unitName))
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
--end
|
||||||
|
|
||||||
|
---@param unit string
|
||||||
|
local function TryInspect(unit)
|
||||||
|
local targetPlayer = UnitIsPlayer(unit)
|
||||||
|
if not targetPlayer then return end
|
||||||
|
local targetName = UnitName(unit)
|
||||||
|
local targetGuid = UnitGUID(unit)
|
||||||
|
guidMap[targetGuid] = targetName
|
||||||
|
|
||||||
|
if not ShouldInspect(targetName) then
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Not inspecting player: %s", ModuleName, targetName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local canInspect = CheckInteractDistance(unit, 1)
|
||||||
|
if canInspect then
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Inspecting player: %s", ModuleName, targetName))
|
||||||
|
end
|
||||||
|
SetAchievementComparisonUnit(unit)
|
||||||
|
else
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Cannot inspect player (too far?): %s", ModuleName, targetName))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param name string
|
||||||
|
local function Scan(name)
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Scanning achievements for %s", ModuleName, name))
|
||||||
|
end
|
||||||
|
Heimdall_Achievements.players[name] = {}
|
||||||
|
for i, aid in ipairs(Achievements) do
|
||||||
|
local completed, month, day, year = GetAchievementComparisonInfo(aid)
|
||||||
|
if completed then
|
||||||
|
---@type string
|
||||||
|
local yearstr = "" .. year
|
||||||
|
if year < 100 then yearstr = "20" .. year end
|
||||||
|
|
||||||
|
local date = string.format("%04d-%02d-%02d", yearstr, month, day)
|
||||||
|
|
||||||
|
local data = {
|
||||||
|
id = aid,
|
||||||
|
date = date,
|
||||||
|
completed = completed,
|
||||||
|
}
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Achievement %d completed on %s", ModuleName, aid, date))
|
||||||
|
end
|
||||||
|
Heimdall_Achievements.players[name][aid] = data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--UpdateFrames()
|
||||||
|
end
|
||||||
|
|
||||||
|
local nameplateFrame = CreateFrame("Frame")
|
||||||
|
nameplateFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
||||||
|
nameplateFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
|
||||||
|
nameplateFrame:SetScript("OnEvent", function(self, event, unit)
|
||||||
|
if not Heimdall_Data.config.achievementSniffer.enabled then return end
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Event triggered: %s for unit: %s", ModuleName, event, unit))
|
||||||
|
end
|
||||||
|
if event == "NAME_PLATE_UNIT_ADDED" then
|
||||||
|
TryInspect(unit)
|
||||||
|
end
|
||||||
|
--UpdateFrames()
|
||||||
|
end)
|
||||||
|
|
||||||
|
local inspectFrame = CreateFrame("Frame")
|
||||||
|
inspectFrame:RegisterEvent("INSPECT_ACHIEVEMENT_READY")
|
||||||
|
inspectFrame:SetScript("OnEvent", function(self, event, guid)
|
||||||
|
if not Heimdall_Data.config.achievementSniffer.enabled then return end
|
||||||
|
local name = guidMap[guid]
|
||||||
|
if not name then
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] No name found for guid: %s", ModuleName, guid))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Event triggered: %s for player: %s", ModuleName, event, name))
|
||||||
|
end
|
||||||
|
Scan(name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
local function Tick()
|
||||||
|
C_Timer.NewTimer(Heimdall_Data.config.achievementSniffer.scanInterval, Tick)
|
||||||
|
if not Heimdall_Data.config.achievementSniffer.enabled then return end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
print(string.format("[%s] Scanning achievements for everyone on screen", ModuleName))
|
||||||
|
end
|
||||||
|
for i = 1, 40 do
|
||||||
|
local unit = "nameplate" .. i
|
||||||
|
if UnitExists(unit) then
|
||||||
|
TryInspect(unit)
|
||||||
|
--else
|
||||||
|
-- if Heimdall_Data.config.achievementSniffer.debug then
|
||||||
|
-- print(string.format("[%s] Unit %s does not exist, nothing to inspect", ModuleName, unit))
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--UpdateFrames()
|
||||||
|
end
|
||||||
|
Tick()
|
||||||
|
|
||||||
|
print("[Heimdall] AchievementSniffer loaded")
|
||||||
|
end
|
||||||
|
@@ -1,144 +1,109 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "AgentTracker"
|
local ModuleName = "AgentTracker"
|
||||||
|
|
||||||
---@class AgentTrackerData
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field agents ReactiveValue<table<string, string>>
|
shared.AgentTracker = {}
|
||||||
|
function shared.AgentTracker.Init()
|
||||||
---@class HeimdallAgentTrackerConfig
|
--/run Heimdall_Data.config.agents["Cyheuraeth"]=date("%Y-%m-%dT%H:%M:%S")
|
||||||
---@field enabled boolean
|
---@type table<string, boolean>
|
||||||
---@field debug boolean
|
local channelRosterFrame = CreateFrame("Frame")
|
||||||
---@field channels string[]
|
channelRosterFrame:RegisterEvent("CHANNEL_ROSTER_UPDATE")
|
||||||
|
channelRosterFrame:SetScript("OnEvent", function(self, event, index)
|
||||||
---@class AgentTracker
|
|
||||||
shared.AgentTracker = {
|
|
||||||
---@param name string
|
|
||||||
---@return boolean
|
|
||||||
Track = function(name)
|
|
||||||
if not name then return false end
|
|
||||||
local exists = shared.AgentTracker.IsAgent(name)
|
|
||||||
if exists then return false end
|
|
||||||
shared.agentTracker.agents[name] = date("%Y-%m-%dT%H:%M:%S")
|
|
||||||
-- Heimdall_Data.config.agents[name] = date("%Y-%m-%dT%H:%M:%S")
|
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
print(string.format("[%s] Tracking new agent: %s", ModuleName, name))
|
print(string.format("[%s] Channel roster update received", ModuleName))
|
||||||
shared.dump(shared.agentTracker.agents)
|
|
||||||
end
|
end
|
||||||
return true
|
if not Heimdall_Data.config.agentTracker.enabled then
|
||||||
end,
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
---@param name string
|
print(string.format("[%s] Module disabled, ignoring roster update", ModuleName))
|
||||||
---@return boolean
|
end
|
||||||
IsAgent = function(name)
|
return
|
||||||
if not name then return false end
|
|
||||||
return shared.agentTracker.agents[name] ~= nil
|
|
||||||
end,
|
|
||||||
---@param callback fun(agent: string)
|
|
||||||
OnChange = function(callback) shared.agentTracker.agents:onChange(callback) end,
|
|
||||||
---@param callback fun(agent: string)
|
|
||||||
ForEach = function(callback)
|
|
||||||
---@type table<string, string>
|
|
||||||
local agents = shared.agentTracker.agents:get()
|
|
||||||
for name, _ in pairs(agents) do
|
|
||||||
callback(name)
|
|
||||||
end
|
end
|
||||||
end,
|
local name = GetChannelDisplayInfo(index)
|
||||||
---@return nil
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
Init = function()
|
print(string.format("[%s] Processing channel update: %s (index: %d)", ModuleName, name or "nil", index))
|
||||||
shared.agentTracker = {
|
end
|
||||||
agents = ReactiveValue.new(Heimdall_Data.config.agents),
|
if name ~= Heimdall_Data.config.agentTracker.masterChannel then
|
||||||
}
|
|
||||||
|
|
||||||
--/run Heimdall_Data.config.agents["Cyheuraeth"]=date("%Y-%m-%dT%H:%M:%S")
|
|
||||||
---@type table<string, boolean>
|
|
||||||
local channelRosterFrame = CreateFrame("Frame")
|
|
||||||
channelRosterFrame:RegisterEvent("CHANNEL_ROSTER_UPDATE")
|
|
||||||
channelRosterFrame:SetScript("OnEvent", function(self, event, index)
|
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
print(string.format("[%s] Channel roster update received", ModuleName))
|
print(string.format("[%s] Ignoring non-master channel: %s", ModuleName, name or "nil"))
|
||||||
end
|
end
|
||||||
if not Heimdall_Data.config.agentTracker.enabled then
|
return
|
||||||
|
end
|
||||||
|
local count = select(5, GetChannelDisplayInfo(index))
|
||||||
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
|
print(string.format("[%s] Processing %d members in channel", ModuleName, count))
|
||||||
|
end
|
||||||
|
|
||||||
|
local newAgents = 0
|
||||||
|
for i = 1, count do
|
||||||
|
local name = GetChannelRosterInfo(index, i)
|
||||||
|
if name then
|
||||||
|
local isNewAgent = not Heimdall_Data.config.agents[name]
|
||||||
|
Heimdall_Data.config.agents[name] = date("%Y-%m-%dT%H:%M:%S")
|
||||||
|
if isNewAgent then
|
||||||
|
newAgents = newAgents + 1
|
||||||
|
end
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
print(string.format("[%s] Module disabled, ignoring roster update", ModuleName))
|
print(string.format("[%s] %s agent: %s", ModuleName, isNewAgent and "Added new" or "Updated existing",
|
||||||
end
|
name))
|
||||||
return
|
|
||||||
end
|
|
||||||
local name = GetChannelDisplayInfo(index)
|
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
|
||||||
print(string.format("[%s] Processing channel update: %s (index: %d)", ModuleName, name or "nil", index))
|
|
||||||
end
|
|
||||||
if name ~= Heimdall_Data.config.agentTracker.masterChannel then
|
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
|
||||||
print(string.format("[%s] Ignoring non-master channel: %s", ModuleName, name or "nil"))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local count = select(5, GetChannelDisplayInfo(index))
|
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
|
||||||
print(string.format("[%s] Processing %d members in channel", ModuleName, count))
|
|
||||||
end
|
|
||||||
|
|
||||||
local newAgents = 0
|
|
||||||
for i = 1, count do
|
|
||||||
name = GetChannelRosterInfo(index, i)
|
|
||||||
shared.AgentTracker.Track(name)
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
|
||||||
print(string.format("[%s] Roster update complete - Added %d new agents", ModuleName, newAgents))
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local agentTrackerChannelSniffer = CreateFrame("Frame")
|
|
||||||
agentTrackerChannelSniffer:RegisterEvent("CHAT_MSG_CHANNEL")
|
|
||||||
agentTrackerChannelSniffer:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
|
||||||
-- if Heimdall_Data.config.agentTracker.debug then
|
|
||||||
-- print(string.format("[%s] Channel message received from: %s", ModuleName, sender))
|
|
||||||
-- end
|
|
||||||
if not Heimdall_Data.config.agentTracker.enabled then
|
|
||||||
-- if Heimdall_Data.config.agentTracker.debug then
|
|
||||||
-- print(string.format("[%s] Module disabled, ignoring channel message", ModuleName))
|
|
||||||
-- end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local channelId = select(6, ...)
|
|
||||||
local _, channelname = GetChannelName(channelId)
|
|
||||||
local ok = false
|
|
||||||
for _, channel in pairs(Heimdall_Data.config.agentTracker.channels) do
|
|
||||||
if channel == channelname then
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not ok then
|
end
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
|
||||||
print(string.format("[%s] Channel name does not match any of the channels", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
|
||||||
print(string.format("[%s] Processing message from master channel: %s", ModuleName, sender))
|
|
||||||
end
|
|
||||||
|
|
||||||
sender = string.match(sender, "^[^-]+")
|
|
||||||
local new = shared.AgentTracker.Track(sender)
|
|
||||||
|
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] %s agent from message: %s",
|
|
||||||
ModuleName,
|
|
||||||
new and "Added new" or "Updated existing",
|
|
||||||
sender
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
if Heimdall_Data.config.agentTracker.debug then
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Roster update complete - Added %d new agents", ModuleName, newAgents))
|
||||||
shared.dump(shared.agentTracker.agents:get(), "Agents")
|
|
||||||
end
|
end
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
end)
|
||||||
end,
|
|
||||||
}
|
local agentTrackerChannelSniffer = CreateFrame("Frame")
|
||||||
|
agentTrackerChannelSniffer:RegisterEvent("CHAT_MSG_CHANNEL")
|
||||||
|
agentTrackerChannelSniffer:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
||||||
|
-- if Heimdall_Data.config.agentTracker.debug then
|
||||||
|
-- print(string.format("[%s] Channel message received from: %s", ModuleName, sender))
|
||||||
|
-- end
|
||||||
|
if not Heimdall_Data.config.agentTracker.enabled then
|
||||||
|
-- if Heimdall_Data.config.agentTracker.debug then
|
||||||
|
-- print(string.format("[%s] Module disabled, ignoring channel message", ModuleName))
|
||||||
|
-- end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local channelId = select(6, ...)
|
||||||
|
local _, channelname = GetChannelName(channelId)
|
||||||
|
local ok = false
|
||||||
|
for _, channel in pairs(Heimdall_Data.config.agentTracker.channels) do
|
||||||
|
if channel == channelname then
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not ok then
|
||||||
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
|
print(string.format("[%s] Channel name does not match any of the channels", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
|
print(string.format("[%s] Processing message from master channel: %s", ModuleName, sender))
|
||||||
|
shared.dumpTable(Heimdall_Data.config.agentTracker)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
sender = string.match(sender, "^[^-]+")
|
||||||
|
local isNewAgent = not Heimdall_Data.config.agents[sender]
|
||||||
|
Heimdall_Data.config.agents[sender] = date("%Y-%m-%dT%H:%M:%S")
|
||||||
|
|
||||||
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
|
print(string.format("[%s] %s agent from message: %s", ModuleName,
|
||||||
|
isNewAgent and "Added new" or "Updated existing", sender))
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
if Heimdall_Data.config.agentTracker.debug then
|
||||||
|
local count = 0
|
||||||
|
for _ in pairs(Heimdall_Data.config.agents) do count = count + 1 end
|
||||||
|
print(string.format("[%s] Module initialized - Tracking %d agents", ModuleName, count))
|
||||||
|
end
|
||||||
|
print("[Heimdall] AgentTracker loaded")
|
||||||
|
end
|
||||||
|
@@ -1,142 +1,107 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "BonkDetector"
|
local ModuleName = "BonkDetector"
|
||||||
|
|
||||||
---@class HeimdallBonkDetectorConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.BonkDetector = {}
|
||||||
---@field debug boolean
|
function shared.BonkDetector.Init()
|
||||||
---@field channels string[]
|
---@type table<string, number>
|
||||||
---@field throttle number
|
local lastReportTime = {}
|
||||||
|
|
||||||
---@class BonkDetector
|
local frame = CreateFrame("Frame")
|
||||||
shared.BonkDetector = {
|
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||||
---@return nil
|
frame:SetScript("OnEvent", function(self, event, ...)
|
||||||
Init = function()
|
-- if Heimdall_Data.config.bonkDetector.debug then
|
||||||
---@type table<string, number>
|
-- print(string.format("[%s] Combat log event received", ModuleName))
|
||||||
local lastReportTime = {}
|
-- end
|
||||||
|
if not Heimdall_Data.config.bonkDetector.enabled then
|
||||||
local frame = CreateFrame("Frame")
|
-- if Heimdall_Data.config.bonkDetector.debug then
|
||||||
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
-- print(string.format("[%s] Module disabled, ignoring combat event", ModuleName))
|
||||||
frame:SetScript("OnEvent", function(self, event, ...)
|
-- end
|
||||||
-- if Heimdall_Data.config.bonkDetector.debug then
|
return
|
||||||
-- print(string.format("[%s] Combat log event received", ModuleName))
|
end
|
||||||
-- end
|
|
||||||
if not Heimdall_Data.config.bonkDetector.enabled then
|
|
||||||
-- if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
-- print(string.format("[%s] Module disabled, ignoring combat event", ModuleName))
|
|
||||||
-- end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local subevent = select(2, ...)
|
|
||||||
if not subevent:find("_DAMAGE") then
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
print(string.format("[%s] Not a damage event, ignoring: %s", ModuleName, subevent))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
---@type string|nil, string, string, string, string
|
|
||||||
local err, source, sourceGUID, destination, destinationGUID
|
|
||||||
|
|
||||||
source, err = CLEUParser.GetSourceName(...)
|
|
||||||
if err then
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
print(string.format("[%s] Error getting source name: %s", ModuleName, err))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
sourceGUID, err = CLEUParser.GetSourceGUID(...)
|
|
||||||
if err then
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
print(string.format("[%s] Error getting source GUID: %s", ModuleName, err))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not string.find(sourceGUID, "Player") then
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
print(string.format("[%s] Source %s is not a player, nothing to do", ModuleName, source))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
destination, err = CLEUParser.GetDestName(...)
|
|
||||||
if err then
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
print(string.format("[%s] Error getting destination name: %s", ModuleName, err))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
destinationGUID, err = CLEUParser.GetDestGUID(...)
|
|
||||||
if err then
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
print(string.format("[%s] Error getting destination GUID: %s", ModuleName, err))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not string.find(destinationGUID, "Player") then
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
print(string.format("[%s] Destination %s is not a player, nothing to do", ModuleName, destination))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if source == destination then
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
print(string.format("[%s] Source and destination are the same, ignoring event", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local currentTime = GetTime()
|
|
||||||
local throttle = Heimdall_Data.config.bonkDetector.throttle
|
|
||||||
|
|
||||||
if lastReportTime[source] and (currentTime - lastReportTime[source]) < throttle then
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
local timeLeft = throttle - (currentTime - lastReportTime[source])
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Damage report throttled for %s (%.1f seconds remaining)",
|
|
||||||
ModuleName,
|
|
||||||
source,
|
|
||||||
timeLeft
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
lastReportTime[source] = currentTime
|
|
||||||
|
|
||||||
|
local subevent = select(2, ...)
|
||||||
|
if not subevent:find("_DAMAGE") then
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
if Heimdall_Data.config.bonkDetector.debug then
|
||||||
print(
|
print(string.format("[%s] Not a damage event, ignoring: %s", ModuleName, subevent))
|
||||||
string.format(
|
|
||||||
"[%s] Processing damage event - Source: %s, Target: %s, Type: %s",
|
|
||||||
ModuleName,
|
|
||||||
source,
|
|
||||||
destination,
|
|
||||||
subevent
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
for _, channel in pairs(Heimdall_Data.config.bonkDetector.channels) do
|
local source, err = CLEUParser.GetSourceName(...)
|
||||||
local locale = shared.GetLocaleForChannel(channel)
|
if err then
|
||||||
local msg = string.format(shared._L("bonkDetected", locale), source, destination, subevent)
|
if Heimdall_Data.config.bonkDetector.debug then
|
||||||
---@type Message
|
print(string.format("[%s] Error getting source name: %s", ModuleName, err))
|
||||||
local message = {
|
|
||||||
channel = "C",
|
|
||||||
data = channel,
|
|
||||||
message = msg,
|
|
||||||
}
|
|
||||||
if Heimdall_Data.config.bonkDetector.debug then
|
|
||||||
print(string.format("[%s] Queuing bonk detector message", ModuleName))
|
|
||||||
shared.dump(message)
|
|
||||||
end
|
|
||||||
table.insert(shared.messenger.queue, message)
|
|
||||||
end
|
end
|
||||||
end)
|
return
|
||||||
|
end
|
||||||
|
local sourceGUID = CLEUParser.GetSourceGUID(...)
|
||||||
|
if not string.find(sourceGUID, "Player") then
|
||||||
|
if Heimdall_Data.config.bonkDetector.debug then
|
||||||
|
print(string.format("[%s] Source %s is not a player, nothing to do", ModuleName, source))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
local destination, err = CLEUParser.GetDestName(...)
|
||||||
end,
|
if err then
|
||||||
}
|
if Heimdall_Data.config.bonkDetector.debug then
|
||||||
|
print(string.format("[%s] Error getting destination name: %s", ModuleName, err))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local destinationGUID = CLEUParser.GetDestGUID(...)
|
||||||
|
if not string.find(destinationGUID, "Player") then
|
||||||
|
if Heimdall_Data.config.bonkDetector.debug then
|
||||||
|
print(string.format("[%s] Destination %s is not a player, nothing to do", ModuleName, destination))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if source == destination then
|
||||||
|
if Heimdall_Data.config.bonkDetector.debug then
|
||||||
|
print(string.format("[%s] Source and destination are the same, ignoring event", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local currentTime = GetTime()
|
||||||
|
local throttle = Heimdall_Data.config.bonkDetector.throttle
|
||||||
|
|
||||||
|
if lastReportTime[source] and (currentTime - lastReportTime[source]) < throttle then
|
||||||
|
if Heimdall_Data.config.bonkDetector.debug then
|
||||||
|
local timeLeft = throttle - (currentTime - lastReportTime[source])
|
||||||
|
print(string.format("[%s] Damage report throttled for %s (%.1f seconds remaining)",
|
||||||
|
ModuleName, source, timeLeft))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
lastReportTime[source] = currentTime
|
||||||
|
|
||||||
|
if Heimdall_Data.config.bonkDetector.debug then
|
||||||
|
print(string.format("[%s] Processing damage event - Source: %s, Target: %s, Type: %s",
|
||||||
|
ModuleName, source, destination, subevent))
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, channel in pairs(Heimdall_Data.config.bonkDetector.channels) do
|
||||||
|
local locale = shared.GetLocaleForChannel(channel)
|
||||||
|
local msg = string.format(shared._L("bonkDetected", locale), source, destination, subevent)
|
||||||
|
---@type Message
|
||||||
|
local message = {
|
||||||
|
channel = "C",
|
||||||
|
data = channel,
|
||||||
|
message = msg,
|
||||||
|
}
|
||||||
|
if Heimdall_Data.config.bonkDetector.debug then
|
||||||
|
print(string.format("[%s] Queuing bonk detector message", ModuleName))
|
||||||
|
shared.dumpTable(message)
|
||||||
|
end
|
||||||
|
table.insert(shared.messenger.queue, message)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
print("[Heimdall] BonkDetector loaded")
|
||||||
|
end
|
||||||
|
@@ -1,16 +1,13 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Bully"
|
local ModuleName = "Bully"
|
||||||
|
|
||||||
---@class HeimdallBullyConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Bully = {}
|
||||||
---@field debug boolean
|
function shared.Bully.Init()
|
||||||
|
if Heimdall_Data.config.bully.debug then
|
||||||
---@class Bully
|
|
||||||
shared.Bully = {
|
|
||||||
---@return nil
|
|
||||||
Init = function()
|
|
||||||
if Heimdall_Data.config.bully.debug then print(string.format("[%s] Module initialized", ModuleName)) end
|
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Module initialized", ModuleName))
|
||||||
end,
|
end
|
||||||
}
|
print("[Heimdall] Bully loaded")
|
||||||
|
end
|
||||||
|
@@ -12,12 +12,12 @@ local function Init()
|
|||||||
["destGUID"] = 8,
|
["destGUID"] = 8,
|
||||||
["destName"] = 9,
|
["destName"] = 9,
|
||||||
["destFlags"] = 10,
|
["destFlags"] = 10,
|
||||||
["destRaidFlags"] = 11,
|
["destRaidFlags"] = 11
|
||||||
},
|
},
|
||||||
["GENERIC_SPELL"] = {
|
["GENERIC_SPELL"] = {
|
||||||
["spellId"] = 12,
|
["spellId"] = 12,
|
||||||
["spellName"] = 13,
|
["spellName"] = 13,
|
||||||
["spellSchool"] = 14,
|
["spellSchool"] = 14
|
||||||
},
|
},
|
||||||
["GENERIC_DAMAGE"] = {
|
["GENERIC_DAMAGE"] = {
|
||||||
["amount"] = 15,
|
["amount"] = 15,
|
||||||
@@ -29,19 +29,19 @@ local function Init()
|
|||||||
["critical"] = 21,
|
["critical"] = 21,
|
||||||
["glancing"] = 22,
|
["glancing"] = 22,
|
||||||
["crushing"] = 23,
|
["crushing"] = 23,
|
||||||
["isOffHand"] = 24,
|
["isOffHand"] = 24
|
||||||
},
|
},
|
||||||
["GENERIC_MISSED"] = {
|
["GENERIC_MISSED"] = {
|
||||||
["missType"] = 15,
|
["missType"] = 15,
|
||||||
["isOffHand"] = 16,
|
["isOffHand"] = 16,
|
||||||
["amountMissed"] = 17,
|
["amountMissed"] = 17,
|
||||||
["critical"] = 18,
|
["critical"] = 18
|
||||||
},
|
},
|
||||||
["GENERIC_HEAL"] = {
|
["GENERIC_HEAL"] = {
|
||||||
["amount"] = 15,
|
["amount"] = 15,
|
||||||
["overhealing"] = 16,
|
["overhealing"] = 16,
|
||||||
["absorbed"] = 17,
|
["absorbed"] = 17,
|
||||||
["critical"] = 18,
|
["critical"] = 18
|
||||||
},
|
},
|
||||||
["GENERIC_HEAL_ABSORBED"] = {
|
["GENERIC_HEAL_ABSORBED"] = {
|
||||||
["extraGUID"] = 15,
|
["extraGUID"] = 15,
|
||||||
@@ -52,44 +52,44 @@ local function Init()
|
|||||||
["extraSpellName"] = 20,
|
["extraSpellName"] = 20,
|
||||||
["extraSchool"] = 21,
|
["extraSchool"] = 21,
|
||||||
["absorbedAmount"] = 22,
|
["absorbedAmount"] = 22,
|
||||||
["totalAmount"] = 23,
|
["totalAmount"] = 23
|
||||||
},
|
},
|
||||||
["GENERIC_ENERGIZE"] = {
|
["GENERIC_ENERGIZE"] = {
|
||||||
["amount"] = 15,
|
["amount"] = 15,
|
||||||
["overEnergize"] = 16,
|
["overEnergize"] = 16,
|
||||||
["powerType"] = 17,
|
["powerType"] = 17
|
||||||
},
|
},
|
||||||
["GENERIC_DRAIN"] = {
|
["GENERIC_DRAIN"] = {
|
||||||
["amount"] = 15,
|
["amount"] = 15,
|
||||||
["powerType"] = 16,
|
["powerType"] = 16,
|
||||||
["extraAmount"] = 17,
|
["extraAmount"] = 17
|
||||||
},
|
},
|
||||||
["GENERIC_LEECH"] = {
|
["GENERIC_LEECH"] = {
|
||||||
["amount"] = 15,
|
["amount"] = 15,
|
||||||
["powerType"] = 16,
|
["powerType"] = 16,
|
||||||
["extraAmount"] = 17,
|
["extraAmount"] = 17
|
||||||
},
|
},
|
||||||
["GENERIC_INTERRUPT"] = {
|
["GENERIC_INTERRUPT"] = {
|
||||||
["extraSpellId"] = 15,
|
["extraSpellId"] = 15,
|
||||||
["extraSpellName"] = 16,
|
["extraSpellName"] = 16,
|
||||||
["extraSchool"] = 17,
|
["extraSchool"] = 17
|
||||||
},
|
},
|
||||||
["GENERIC_DISPEL"] = {
|
["GENERIC_DISPEL"] = {
|
||||||
["extraSpellId"] = 15,
|
["extraSpellId"] = 15,
|
||||||
["extraSpellName"] = 16,
|
["extraSpellName"] = 16,
|
||||||
["extraSchool"] = 17,
|
["extraSchool"] = 17,
|
||||||
["auraType"] = 18,
|
["auraType"] = 18
|
||||||
},
|
},
|
||||||
["GENERIC_DISPEL_FAILED"] = {
|
["GENERIC_DISPEL_FAILED"] = {
|
||||||
["extraSpellId"] = 15,
|
["extraSpellId"] = 15,
|
||||||
["extraSpellName"] = 16,
|
["extraSpellName"] = 16,
|
||||||
["extraSchool"] = 17,
|
["extraSchool"] = 17
|
||||||
},
|
},
|
||||||
["GENERIC_STOLEN"] = {
|
["GENERIC_STOLEN"] = {
|
||||||
["extraSpellId"] = 15,
|
["extraSpellId"] = 15,
|
||||||
["extraSpellName"] = 16,
|
["extraSpellName"] = 16,
|
||||||
["extraSchool"] = 17,
|
["extraSchool"] = 17,
|
||||||
["auraType"] = 18,
|
["auraType"] = 18
|
||||||
},
|
},
|
||||||
["GENERIC_EXTRA_ATTACKS"] = { ["amount"] = 15 },
|
["GENERIC_EXTRA_ATTACKS"] = { ["amount"] = 15 },
|
||||||
["GENERIC_AURA_APPLIED"] = { ["auraType"] = 15, ["amount"] = 16 },
|
["GENERIC_AURA_APPLIED"] = { ["auraType"] = 15, ["amount"] = 16 },
|
||||||
@@ -102,32 +102,38 @@ local function Init()
|
|||||||
["extraSpellId"] = 15,
|
["extraSpellId"] = 15,
|
||||||
["extraSpellName"] = 16,
|
["extraSpellName"] = 16,
|
||||||
["extraSchool"] = 17,
|
["extraSchool"] = 17,
|
||||||
["auraType"] = 18,
|
["auraType"] = 18
|
||||||
},
|
},
|
||||||
["GENERIC_CAST_START"] = {},
|
["GENERIC_CAST_START"] = {},
|
||||||
["GENERIC_CAST_SUCCESS"] = {},
|
["GENERIC_CAST_SUCCESS"] = {},
|
||||||
["GENERIC_CAST_FAILED"] = {},
|
["GENERIC_CAST_FAILED"] = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEUEventInfo["SWING_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"]
|
CLEUEventInfo["SWING_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"]
|
||||||
CLEUEventInfo["SWING_MISSED"] = CLEUEventInfo["GENERIC_MISSED"]
|
CLEUEventInfo["SWING_MISSED"] = CLEUEventInfo["GENERIC_MISSED"]
|
||||||
CLEUEventInfo["SWING_HEAL"] = CLEUEventInfo["GENERIC_HEAL"]
|
CLEUEventInfo["SWING_HEAL"] = CLEUEventInfo["GENERIC_HEAL"]
|
||||||
CLEUEventInfo["SWING_HEAL_ABSORBED"] = CLEUEventInfo["GENERIC_HEAL_ABSORBED"]
|
CLEUEventInfo["SWING_HEAL_ABSORBED"] =
|
||||||
|
CLEUEventInfo["GENERIC_HEAL_ABSORBED"]
|
||||||
CLEUEventInfo["SWING_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"]
|
CLEUEventInfo["SWING_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"]
|
||||||
CLEUEventInfo["SWING_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"]
|
CLEUEventInfo["SWING_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"]
|
||||||
CLEUEventInfo["SWING_LEECH"] = CLEUEventInfo["GENERIC_LEECH"]
|
CLEUEventInfo["SWING_LEECH"] = CLEUEventInfo["GENERIC_LEECH"]
|
||||||
CLEUEventInfo["SWING_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"]
|
CLEUEventInfo["SWING_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"]
|
||||||
CLEUEventInfo["SWING_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"]
|
CLEUEventInfo["SWING_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"]
|
||||||
CLEUEventInfo["SWING_DISPEL_FAILED"] = CLEUEventInfo["GENERIC_DISPEL_FAILED"]
|
CLEUEventInfo["SWING_DISPEL_FAILED"] =
|
||||||
|
CLEUEventInfo["GENERIC_DISPEL_FAILED"]
|
||||||
CLEUEventInfo["SWING_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"]
|
CLEUEventInfo["SWING_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"]
|
||||||
CLEUEventInfo["SWING_EXTRA_ATTACKS"] = CLEUEventInfo["GENERIC_EXTRA_ATTACKS"]
|
CLEUEventInfo["SWING_EXTRA_ATTACKS"] =
|
||||||
|
CLEUEventInfo["GENERIC_EXTRA_ATTACKS"]
|
||||||
CLEUEventInfo["SWING_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"]
|
CLEUEventInfo["SWING_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"]
|
||||||
CLEUEventInfo["SWING_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"]
|
CLEUEventInfo["SWING_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"]
|
||||||
CLEUEventInfo["SWING_AURA_APPLIED_DOSE"] = CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"]
|
CLEUEventInfo["SWING_AURA_APPLIED_DOSE"] =
|
||||||
CLEUEventInfo["SWING_AURA_REMOVED_DOSE"] = CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"]
|
CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"]
|
||||||
|
CLEUEventInfo["SWING_AURA_REMOVED_DOSE"] =
|
||||||
|
CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"]
|
||||||
CLEUEventInfo["SWING_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"]
|
CLEUEventInfo["SWING_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"]
|
||||||
CLEUEventInfo["SWING_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"]
|
CLEUEventInfo["SWING_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"]
|
||||||
CLEUEventInfo["SWING_AURA_BROKEN_SPELL"] = CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"]
|
CLEUEventInfo["SWING_AURA_BROKEN_SPELL"] =
|
||||||
|
CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"]
|
||||||
CLEUEventInfo["SWING_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"]
|
CLEUEventInfo["SWING_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"]
|
||||||
CLEUEventInfo["SWING_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"]
|
CLEUEventInfo["SWING_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"]
|
||||||
CLEUEventInfo["SWING_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"]
|
CLEUEventInfo["SWING_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"]
|
||||||
@@ -135,22 +141,28 @@ local function Init()
|
|||||||
CLEUEventInfo["RANGE_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"]
|
CLEUEventInfo["RANGE_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"]
|
||||||
CLEUEventInfo["RANGE_MISSED"] = CLEUEventInfo["GENERIC_MISSED"]
|
CLEUEventInfo["RANGE_MISSED"] = CLEUEventInfo["GENERIC_MISSED"]
|
||||||
CLEUEventInfo["RANGE_HEAL"] = CLEUEventInfo["GENERIC_HEAL"]
|
CLEUEventInfo["RANGE_HEAL"] = CLEUEventInfo["GENERIC_HEAL"]
|
||||||
CLEUEventInfo["RANGE_HEAL_ABSORBED"] = CLEUEventInfo["GENERIC_HEAL_ABSORBED"]
|
CLEUEventInfo["RANGE_HEAL_ABSORBED"] =
|
||||||
|
CLEUEventInfo["GENERIC_HEAL_ABSORBED"]
|
||||||
CLEUEventInfo["RANGE_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"]
|
CLEUEventInfo["RANGE_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"]
|
||||||
CLEUEventInfo["RANGE_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"]
|
CLEUEventInfo["RANGE_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"]
|
||||||
CLEUEventInfo["RANGE_LEECH"] = CLEUEventInfo["GENERIC_LEECH"]
|
CLEUEventInfo["RANGE_LEECH"] = CLEUEventInfo["GENERIC_LEECH"]
|
||||||
CLEUEventInfo["RANGE_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"]
|
CLEUEventInfo["RANGE_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"]
|
||||||
CLEUEventInfo["RANGE_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"]
|
CLEUEventInfo["RANGE_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"]
|
||||||
CLEUEventInfo["RANGE_DISPEL_FAILED"] = CLEUEventInfo["GENERIC_DISPEL_FAILED"]
|
CLEUEventInfo["RANGE_DISPEL_FAILED"] =
|
||||||
|
CLEUEventInfo["GENERIC_DISPEL_FAILED"]
|
||||||
CLEUEventInfo["RANGE_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"]
|
CLEUEventInfo["RANGE_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"]
|
||||||
CLEUEventInfo["RANGE_EXTRA_ATTACKS"] = CLEUEventInfo["GENERIC_EXTRA_ATTACKS"]
|
CLEUEventInfo["RANGE_EXTRA_ATTACKS"] =
|
||||||
|
CLEUEventInfo["GENERIC_EXTRA_ATTACKS"]
|
||||||
CLEUEventInfo["RANGE_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"]
|
CLEUEventInfo["RANGE_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"]
|
||||||
CLEUEventInfo["RANGE_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"]
|
CLEUEventInfo["RANGE_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"]
|
||||||
CLEUEventInfo["RANGE_AURA_APPLIED_DOSE"] = CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"]
|
CLEUEventInfo["RANGE_AURA_APPLIED_DOSE"] =
|
||||||
CLEUEventInfo["RANGE_AURA_REMOVED_DOSE"] = CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"]
|
CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"]
|
||||||
|
CLEUEventInfo["RANGE_AURA_REMOVED_DOSE"] =
|
||||||
|
CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"]
|
||||||
CLEUEventInfo["RANGE_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"]
|
CLEUEventInfo["RANGE_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"]
|
||||||
CLEUEventInfo["RANGE_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"]
|
CLEUEventInfo["RANGE_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"]
|
||||||
CLEUEventInfo["RANGE_AURA_BROKEN_SPELL"] = CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"]
|
CLEUEventInfo["RANGE_AURA_BROKEN_SPELL"] =
|
||||||
|
CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"]
|
||||||
CLEUEventInfo["RANGE_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"]
|
CLEUEventInfo["RANGE_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"]
|
||||||
CLEUEventInfo["RANGE_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"]
|
CLEUEventInfo["RANGE_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"]
|
||||||
CLEUEventInfo["RANGE_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"]
|
CLEUEventInfo["RANGE_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"]
|
||||||
@@ -158,22 +170,28 @@ local function Init()
|
|||||||
CLEUEventInfo["SPELL_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"]
|
CLEUEventInfo["SPELL_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"]
|
||||||
CLEUEventInfo["SPELL_MISSED"] = CLEUEventInfo["GENERIC_MISSED"]
|
CLEUEventInfo["SPELL_MISSED"] = CLEUEventInfo["GENERIC_MISSED"]
|
||||||
CLEUEventInfo["SPELL_HEAL"] = CLEUEventInfo["GENERIC_HEAL"]
|
CLEUEventInfo["SPELL_HEAL"] = CLEUEventInfo["GENERIC_HEAL"]
|
||||||
CLEUEventInfo["SPELL_HEAL_ABSORBED"] = CLEUEventInfo["GENERIC_HEAL_ABSORBED"]
|
CLEUEventInfo["SPELL_HEAL_ABSORBED"] =
|
||||||
|
CLEUEventInfo["GENERIC_HEAL_ABSORBED"]
|
||||||
CLEUEventInfo["SPELL_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"]
|
CLEUEventInfo["SPELL_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"]
|
||||||
CLEUEventInfo["SPELL_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"]
|
CLEUEventInfo["SPELL_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"]
|
||||||
CLEUEventInfo["SPELL_LEECH"] = CLEUEventInfo["GENERIC_LEECH"]
|
CLEUEventInfo["SPELL_LEECH"] = CLEUEventInfo["GENERIC_LEECH"]
|
||||||
CLEUEventInfo["SPELL_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"]
|
CLEUEventInfo["SPELL_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"]
|
||||||
CLEUEventInfo["SPELL_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"]
|
CLEUEventInfo["SPELL_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"]
|
||||||
CLEUEventInfo["SPELL_DISPEL_FAILED"] = CLEUEventInfo["GENERIC_DISPEL_FAILED"]
|
CLEUEventInfo["SPELL_DISPEL_FAILED"] =
|
||||||
|
CLEUEventInfo["GENERIC_DISPEL_FAILED"]
|
||||||
CLEUEventInfo["SPELL_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"]
|
CLEUEventInfo["SPELL_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"]
|
||||||
CLEUEventInfo["SPELL_EXTRA_ATTACKS"] = CLEUEventInfo["GENERIC_EXTRA_ATTACKS"]
|
CLEUEventInfo["SPELL_EXTRA_ATTACKS"] =
|
||||||
|
CLEUEventInfo["GENERIC_EXTRA_ATTACKS"]
|
||||||
CLEUEventInfo["SPELL_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"]
|
CLEUEventInfo["SPELL_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"]
|
||||||
CLEUEventInfo["SPELL_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"]
|
CLEUEventInfo["SPELL_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"]
|
||||||
CLEUEventInfo["SPELL_AURA_APPLIED_DOSE"] = CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"]
|
CLEUEventInfo["SPELL_AURA_APPLIED_DOSE"] =
|
||||||
CLEUEventInfo["SPELL_AURA_REMOVED_DOSE"] = CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"]
|
CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"]
|
||||||
|
CLEUEventInfo["SPELL_AURA_REMOVED_DOSE"] =
|
||||||
|
CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"]
|
||||||
CLEUEventInfo["SPELL_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"]
|
CLEUEventInfo["SPELL_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"]
|
||||||
CLEUEventInfo["SPELL_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"]
|
CLEUEventInfo["SPELL_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"]
|
||||||
CLEUEventInfo["SPELL_AURA_BROKEN_SPELL"] = CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"]
|
CLEUEventInfo["SPELL_AURA_BROKEN_SPELL"] =
|
||||||
|
CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"]
|
||||||
CLEUEventInfo["SPELL_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"]
|
CLEUEventInfo["SPELL_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"]
|
||||||
CLEUEventInfo["SPELL_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"]
|
CLEUEventInfo["SPELL_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"]
|
||||||
CLEUEventInfo["SPELL_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"]
|
CLEUEventInfo["SPELL_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"]
|
||||||
@@ -181,25 +199,39 @@ local function Init()
|
|||||||
CLEUEventInfo["SPELL_PERIODIC_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"]
|
CLEUEventInfo["SPELL_PERIODIC_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_MISSED"] = CLEUEventInfo["GENERIC_MISSED"]
|
CLEUEventInfo["SPELL_PERIODIC_MISSED"] = CLEUEventInfo["GENERIC_MISSED"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_HEAL"] = CLEUEventInfo["GENERIC_HEAL"]
|
CLEUEventInfo["SPELL_PERIODIC_HEAL"] = CLEUEventInfo["GENERIC_HEAL"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_HEAL_ABSORBED"] = CLEUEventInfo["GENERIC_HEAL_ABSORBED"]
|
CLEUEventInfo["SPELL_PERIODIC_HEAL_ABSORBED"] =
|
||||||
|
CLEUEventInfo["GENERIC_HEAL_ABSORBED"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"]
|
CLEUEventInfo["SPELL_PERIODIC_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"]
|
CLEUEventInfo["SPELL_PERIODIC_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_LEECH"] = CLEUEventInfo["GENERIC_LEECH"]
|
CLEUEventInfo["SPELL_PERIODIC_LEECH"] = CLEUEventInfo["GENERIC_LEECH"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"]
|
CLEUEventInfo["SPELL_PERIODIC_INTERRUPT"] =
|
||||||
|
CLEUEventInfo["GENERIC_INTERRUPT"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"]
|
CLEUEventInfo["SPELL_PERIODIC_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_DISPEL_FAILED"] = CLEUEventInfo["GENERIC_DISPEL_FAILED"]
|
CLEUEventInfo["SPELL_PERIODIC_DISPEL_FAILED"] =
|
||||||
|
CLEUEventInfo["GENERIC_DISPEL_FAILED"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"]
|
CLEUEventInfo["SPELL_PERIODIC_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_EXTRA_ATTACKS"] = CLEUEventInfo["GENERIC_EXTRA_ATTACKS"]
|
CLEUEventInfo["SPELL_PERIODIC_EXTRA_ATTACKS"] =
|
||||||
CLEUEventInfo["SPELL_PERIODIC_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"]
|
CLEUEventInfo["GENERIC_EXTRA_ATTACKS"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"]
|
CLEUEventInfo["SPELL_PERIODIC_AURA_APPLIED"] =
|
||||||
CLEUEventInfo["SPELL_PERIODIC_AURA_APPLIED_DOSE"] = CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"]
|
CLEUEventInfo["GENERIC_AURA_APPLIED"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_AURA_REMOVED_DOSE"] = CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"]
|
CLEUEventInfo["SPELL_PERIODIC_AURA_REMOVED"] =
|
||||||
CLEUEventInfo["SPELL_PERIODIC_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"]
|
CLEUEventInfo["GENERIC_AURA_REMOVED"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"]
|
CLEUEventInfo["SPELL_PERIODIC_AURA_APPLIED_DOSE"] =
|
||||||
CLEUEventInfo["SPELL_PERIODIC_AURA_BROKEN_SPELL"] = CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"]
|
CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"]
|
CLEUEventInfo["SPELL_PERIODIC_AURA_REMOVED_DOSE"] =
|
||||||
CLEUEventInfo["SPELL_PERIODIC_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"]
|
CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"]
|
||||||
CLEUEventInfo["SPELL_PERIODIC_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"]
|
CLEUEventInfo["SPELL_PERIODIC_AURA_REFRESH"] =
|
||||||
|
CLEUEventInfo["GENERIC_AURA_REFRESH"]
|
||||||
|
CLEUEventInfo["SPELL_PERIODIC_AURA_BROKEN"] =
|
||||||
|
CLEUEventInfo["GENERIC_AURA_BROKEN"]
|
||||||
|
CLEUEventInfo["SPELL_PERIODIC_AURA_BROKEN_SPELL"] =
|
||||||
|
CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"]
|
||||||
|
CLEUEventInfo["SPELL_PERIODIC_CAST_START"] =
|
||||||
|
CLEUEventInfo["GENERIC_CAST_START"]
|
||||||
|
CLEUEventInfo["SPELL_PERIODIC_CAST_SUCCESS"] =
|
||||||
|
CLEUEventInfo["GENERIC_CAST_SUCCESS"]
|
||||||
|
CLEUEventInfo["SPELL_PERIODIC_CAST_FAILED"] =
|
||||||
|
CLEUEventInfo["GENERIC_CAST_FAILED"]
|
||||||
|
|
||||||
---@class CLEUParser
|
---@class CLEUParser
|
||||||
CLEUParser = {
|
CLEUParser = {
|
||||||
@@ -207,88 +239,132 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetTimestamp = function(...)
|
GetTimestamp = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["timestamp"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["timestamp"], ...)
|
||||||
if val == nil then return 0, "Timestamp is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "Timestamp is not a number" end
|
return 0, "Timestamp is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "Timestamp is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetSubevent = function(...)
|
GetSubevent = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["subevent"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["subevent"], ...)
|
||||||
if val == nil then return "", "Subevent is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "Subevent is not a string" end
|
return "", "Subevent is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "Subevent is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return boolean, nil|string
|
---@return boolean, nil|string
|
||||||
GetHideCaster = function(...)
|
GetHideCaster = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["hideCaster"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["hideCaster"], ...)
|
||||||
if val == nil then return false, "HideCaster is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "boolean" then return false, "HideCaster is not a boolean" end
|
return false, "HideCaster is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "boolean" then
|
||||||
|
return false, "HideCaster is not a boolean"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetSourceGUID = function(...)
|
GetSourceGUID = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["sourceGUID"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["sourceGUID"], ...)
|
||||||
if val == nil then return "", "SourceGUID is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "SourceGUID is not a string" end
|
return "", "SourceGUID is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "SourceGUID is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetSourceName = function(...)
|
GetSourceName = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["sourceName"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["sourceName"], ...)
|
||||||
if val == nil then return "", "SourceName is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "SourceName is not a string" end
|
return "", "SourceName is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "SourceName is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetSourceFlags = function(...)
|
GetSourceFlags = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["sourceFlags"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["sourceFlags"], ...)
|
||||||
if val == nil then return 0, "SourceFlags is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "SourceFlags is not a number" end
|
return 0, "SourceFlags is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "SourceFlags is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetSourceRaidFlags = function(...)
|
GetSourceRaidFlags = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["sourceRaidFlags"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["sourceRaidFlags"], ...)
|
||||||
if val == nil then return 0, "SourceRaidFlags is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "SourceRaidFlags is not a number" end
|
return 0, "SourceRaidFlags is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "SourceRaidFlags is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetDestGUID = function(...)
|
GetDestGUID = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["destGUID"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["destGUID"], ...)
|
||||||
if val == nil then return "", "DestGUID is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "DestGUID is not a string" end
|
return "", "DestGUID is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "DestGUID is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetDestName = function(...)
|
GetDestName = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["destName"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["destName"], ...)
|
||||||
if val == nil then return "", "DestName is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "DestName is not a string" end
|
return "", "DestName is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "DestName is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetDestFlags = function(...)
|
GetDestFlags = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["destFlags"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["destFlags"], ...)
|
||||||
if val == nil then return 0, "DestFlags is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "DestFlags is not a number" end
|
return 0, "DestFlags is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "DestFlags is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
---@param ... any
|
---@param ... any
|
||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetDestRaidFlags = function(...)
|
GetDestRaidFlags = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC"]["destRaidFlags"], ...)
|
local val = select(CLEUEventInfo["GENERIC"]["destRaidFlags"], ...)
|
||||||
if val == nil then return 0, "DestRaidFlags is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "DestRaidFlags is not a number" end
|
return 0, "DestRaidFlags is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "DestRaidFlags is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -304,7 +380,9 @@ local function Init()
|
|||||||
GetSpellId = function(...)
|
GetSpellId = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC_SPELL"]["spellId"], ...)
|
local val = select(CLEUEventInfo["GENERIC_SPELL"]["spellId"], ...)
|
||||||
if val == nil then return 0, "SpellId is nil or missing" end
|
if val == nil then return 0, "SpellId is nil or missing" end
|
||||||
if type(val) ~= "number" then return 0, "SpellId is not a number" end
|
if type(val) ~= "number" then
|
||||||
|
return 0, "SpellId is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -318,8 +396,12 @@ local function Init()
|
|||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetSpellName = function(...)
|
GetSpellName = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC_SPELL"]["spellName"], ...)
|
local val = select(CLEUEventInfo["GENERIC_SPELL"]["spellName"], ...)
|
||||||
if val == nil then return "", "SpellName is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "SpellName is not a string" end
|
return "", "SpellName is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "SpellName is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -332,9 +414,14 @@ local function Init()
|
|||||||
---@param ... any
|
---@param ... any
|
||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetSpellSchool = function(...)
|
GetSpellSchool = function(...)
|
||||||
local val = select(CLEUEventInfo["GENERIC_SPELL"]["spellSchool"], ...)
|
local val = select(CLEUEventInfo["GENERIC_SPELL"]["spellSchool"],
|
||||||
if val == nil then return 0, "SpellSchool is nil or missing" end
|
...)
|
||||||
if type(val) ~= "number" then return 0, "SpellSchool is not a number" end
|
if val == nil then
|
||||||
|
return 0, "SpellSchool is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "SpellSchool is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -364,10 +451,15 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetAmount = function(...)
|
GetAmount = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["amount"], ...)
|
local val = select(CLEUEventInfo[subevent]["amount"], ...)
|
||||||
if val == nil then return 0, "Amount is nil or missing" end
|
if val == nil then return 0, "Amount is nil or missing" end
|
||||||
if type(val) ~= "number" then return 0, "Amount is not a number" end
|
if type(val) ~= "number" then
|
||||||
|
return 0, "Amount is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -387,12 +479,21 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetOverkill = function(...)
|
GetOverkill = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
if not CLEUEventInfo[subevent] then return 0, "Subevent is not a valid event" end
|
return 0,
|
||||||
if not CLEUEventInfo[subevent]["overkill"] then return 0, "Overkill is nil or missing" end
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
|
if not CLEUEventInfo[subevent] then
|
||||||
|
return 0, "Subevent is not a valid event"
|
||||||
|
end
|
||||||
|
if not CLEUEventInfo[subevent]["overkill"] then
|
||||||
|
return 0, "Overkill is nil or missing"
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["overkill"], ...)
|
local val = select(CLEUEventInfo[subevent]["overkill"], ...)
|
||||||
if val == nil then return 0, "Overkill is nil or missing" end
|
if val == nil then return 0, "Overkill is nil or missing" end
|
||||||
if type(val) ~= "number" then return 0, "Overkill is not a number" end
|
if type(val) ~= "number" then
|
||||||
|
return 0, "Overkill is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -412,10 +513,15 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetSchool = function(...)
|
GetSchool = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["school"], ...)
|
local val = select(CLEUEventInfo[subevent]["school"], ...)
|
||||||
if val == nil then return 0, "School is nil or missing" end
|
if val == nil then return 0, "School is nil or missing" end
|
||||||
if type(val) ~= "number" then return 0, "School is not a number" end
|
if type(val) ~= "number" then
|
||||||
|
return 0, "School is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -437,10 +543,17 @@ local function Init()
|
|||||||
---@return boolean, nil|string
|
---@return boolean, nil|string
|
||||||
GetResisted = function(...)
|
GetResisted = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return false, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return false,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["resisted"], ...)
|
local val = select(CLEUEventInfo[subevent]["resisted"], ...)
|
||||||
if val == nil then return false, "Resisted is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "boolean" then return false, "Resisted is not a boolean" end
|
return false, "Resisted is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "boolean" then
|
||||||
|
return false, "Resisted is not a boolean"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -462,10 +575,17 @@ local function Init()
|
|||||||
---@return boolean, nil|string
|
---@return boolean, nil|string
|
||||||
GetBlocked = function(...)
|
GetBlocked = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return false, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return false,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["blocked"], ...)
|
local val = select(CLEUEventInfo[subevent]["blocked"], ...)
|
||||||
if val == nil then return false, "Blocked is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "boolean" then return false, "Blocked is not a boolean" end
|
return false, "Blocked is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "boolean" then
|
||||||
|
return false, "Blocked is not a boolean"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -488,10 +608,17 @@ local function Init()
|
|||||||
---@return boolean, nil|string
|
---@return boolean, nil|string
|
||||||
GetAbsorbed = function(...)
|
GetAbsorbed = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return false, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return false,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["absorbed"], ...)
|
local val = select(CLEUEventInfo[subevent]["absorbed"], ...)
|
||||||
if val == nil then return false, "Absorbed is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "boolean" then return false, "Absorbed is not a boolean" end
|
return false, "Absorbed is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "boolean" then
|
||||||
|
return false, "Absorbed is not a boolean"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -513,10 +640,17 @@ local function Init()
|
|||||||
---@return boolean, nil|string
|
---@return boolean, nil|string
|
||||||
GetCritical = function(...)
|
GetCritical = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return false, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return false,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["critical"], ...)
|
local val = select(CLEUEventInfo[subevent]["critical"], ...)
|
||||||
if val == nil then return false, "Critical is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "boolean" then return false, "Critical is not a boolean" end
|
return false, "Critical is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "boolean" then
|
||||||
|
return false, "Critical is not a boolean"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -536,10 +670,17 @@ local function Init()
|
|||||||
---@return boolean, nil|string
|
---@return boolean, nil|string
|
||||||
GetGlancing = function(...)
|
GetGlancing = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return false, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return false,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["glancing"], ...)
|
local val = select(CLEUEventInfo[subevent]["glancing"], ...)
|
||||||
if val == nil then return false, "Glancing is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "boolean" then return false, "Glancing is not a boolean" end
|
return false, "Glancing is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "boolean" then
|
||||||
|
return false, "Glancing is not a boolean"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -559,10 +700,17 @@ local function Init()
|
|||||||
---@return boolean, nil|string
|
---@return boolean, nil|string
|
||||||
GetCrushing = function(...)
|
GetCrushing = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return false, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return false,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["crushing"], ...)
|
local val = select(CLEUEventInfo[subevent]["crushing"], ...)
|
||||||
if val == nil then return false, "Crushing is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "boolean" then return false, "Crushing is not a boolean" end
|
return false, "Crushing is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "boolean" then
|
||||||
|
return false, "Crushing is not a boolean"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
--- Specific to subevents prefixed by:
|
--- Specific to subevents prefixed by:
|
||||||
@@ -583,10 +731,17 @@ local function Init()
|
|||||||
---@return boolean, nil|string
|
---@return boolean, nil|string
|
||||||
GetIsOffHand = function(...)
|
GetIsOffHand = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return false, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return false,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["isOffHand"], ...)
|
local val = select(CLEUEventInfo[subevent]["isOffHand"], ...)
|
||||||
if val == nil then return false, "IsOffHand is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "boolean" then return false, "IsOffHand is not a boolean" end
|
return false, "IsOffHand is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "boolean" then
|
||||||
|
return false, "IsOffHand is not a boolean"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -609,10 +764,17 @@ local function Init()
|
|||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetMissType = function(...)
|
GetMissType = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return "", string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return "",
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["missType"], ...)
|
local val = select(CLEUEventInfo[subevent]["missType"], ...)
|
||||||
if val == nil then return "", "MissType is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "MissType is not a string" end
|
return "", "MissType is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "MissType is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -635,10 +797,17 @@ local function Init()
|
|||||||
--- return type is unconfirmed!
|
--- return type is unconfirmed!
|
||||||
GetAmountMissed = function(...)
|
GetAmountMissed = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["amountMissed"], ...)
|
local val = select(CLEUEventInfo[subevent]["amountMissed"], ...)
|
||||||
if val == nil then return 0, "AmountMissed is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "AmountMissed is not a number" end
|
return 0, "AmountMissed is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "AmountMissed is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -661,10 +830,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetOverhealing = function(...)
|
GetOverhealing = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["overhealing"], ...)
|
local val = select(CLEUEventInfo[subevent]["overhealing"], ...)
|
||||||
if val == nil then return 0, "Overhealing is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "Overhealing is not a number" end
|
return 0, "Overhealing is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "Overhealing is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -685,10 +861,17 @@ local function Init()
|
|||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetExtraGUID = function(...)
|
GetExtraGUID = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return "", string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return "",
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["extraGUID"], ...)
|
local val = select(CLEUEventInfo[subevent]["extraGUID"], ...)
|
||||||
if val == nil then return "", "ExtraGUID is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "ExtraGUID is not a string" end
|
return "", "ExtraGUID is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "ExtraGUID is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -709,10 +892,17 @@ local function Init()
|
|||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetExtraName = function(...)
|
GetExtraName = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return "", string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return "",
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["extraName"], ...)
|
local val = select(CLEUEventInfo[subevent]["extraName"], ...)
|
||||||
if val == nil then return "", "ExtraName is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "ExtraName is not a string" end
|
return "", "ExtraName is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "ExtraName is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -733,10 +923,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetExtraFlags = function(...)
|
GetExtraFlags = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["extraFlags"], ...)
|
local val = select(CLEUEventInfo[subevent]["extraFlags"], ...)
|
||||||
if val == nil then return 0, "ExtraFlags is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "ExtraFlags is not a number" end
|
return 0, "ExtraFlags is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "ExtraFlags is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -757,10 +954,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetExtraRaidFlags = function(...)
|
GetExtraRaidFlags = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["extraRaidFlags"], ...)
|
local val = select(CLEUEventInfo[subevent]["extraRaidFlags"], ...)
|
||||||
if val == nil then return 0, "ExtraRaidFlags is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "ExtraRaidFlags is not a number" end
|
return 0, "ExtraRaidFlags is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "ExtraRaidFlags is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -785,10 +989,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetExtraSpellID = function(...)
|
GetExtraSpellID = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["extraSpellID"], ...)
|
local val = select(CLEUEventInfo[subevent]["extraSpellID"], ...)
|
||||||
if val == nil then return 0, "ExtraSpellID is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "ExtraSpellID is not a number" end
|
return 0, "ExtraSpellID is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "ExtraSpellID is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -814,10 +1025,17 @@ local function Init()
|
|||||||
---@return string, nil|string
|
---@return string, nil|string
|
||||||
GetExtraSpellName = function(...)
|
GetExtraSpellName = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return "", string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return "",
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["extraSpellName"], ...)
|
local val = select(CLEUEventInfo[subevent]["extraSpellName"], ...)
|
||||||
if val == nil then return "", "extraSpellName is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "string" then return "", "extraSpellName is not a string" end
|
return "", "extraSpellName is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "string" then
|
||||||
|
return "", "extraSpellName is not a string"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -843,10 +1061,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetExtraSchool = function(...)
|
GetExtraSchool = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["extraSchool"], ...)
|
local val = select(CLEUEventInfo[subevent]["extraSchool"], ...)
|
||||||
if val == nil then return 0, "ExtraSchool is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "ExtraSchool is not a number" end
|
return 0, "ExtraSchool is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "ExtraSchool is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -867,10 +1092,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetAbsorbedAmount = function(...)
|
GetAbsorbedAmount = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["absorbedAmount"], ...)
|
local val = select(CLEUEventInfo[subevent]["absorbedAmount"], ...)
|
||||||
if val == nil then return 0, "AbsorbedAmount is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "AbsorbedAmount is not a number" end
|
return 0, "AbsorbedAmount is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "AbsorbedAmount is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -891,10 +1123,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetOverEnergize = function(...)
|
GetOverEnergize = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["overEnergize"], ...)
|
local val = select(CLEUEventInfo[subevent]["overEnergize"], ...)
|
||||||
if val == nil then return 0, "OverEnergize is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "OverEnergize is not a number" end
|
return 0, "OverEnergize is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "OverEnergize is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -919,10 +1158,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetPowerType = function(...)
|
GetPowerType = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["powerType"], ...)
|
local val = select(CLEUEventInfo[subevent]["powerType"], ...)
|
||||||
if val == nil then return 0, "PowerType is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "PowerType is not a number" end
|
return 0, "PowerType is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "PowerType is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -944,10 +1190,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetExtraAmount = function(...)
|
GetExtraAmount = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["extraAmount"], ...)
|
local val = select(CLEUEventInfo[subevent]["extraAmount"], ...)
|
||||||
if val == nil then return 0, "ExtraAmount is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "ExtraAmount is not a number" end
|
return 0, "ExtraAmount is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "ExtraAmount is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -976,10 +1229,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetExtraSpellId = function(...)
|
GetExtraSpellId = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["extraSpellId"], ...)
|
local val = select(CLEUEventInfo[subevent]["extraSpellId"], ...)
|
||||||
if val == nil then return 0, "ExtraSpellId is nil or missing" end
|
if val == nil then
|
||||||
if type(val) ~= "number" then return 0, "ExtraSpellId is not a number" end
|
return 0, "ExtraSpellId is nil or missing"
|
||||||
|
end
|
||||||
|
if type(val) ~= "number" then
|
||||||
|
return 0, "ExtraSpellId is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -1008,12 +1268,17 @@ local function Init()
|
|||||||
---@return number, nil|string
|
---@return number, nil|string
|
||||||
GetExtraAuraType = function(...)
|
GetExtraAuraType = function(...)
|
||||||
local subevent, err = CLEUParser.GetSubevent(...)
|
local subevent, err = CLEUParser.GetSubevent(...)
|
||||||
if err then return 0, string.format("Failed getting subevent due to: %s", err) end
|
if err then
|
||||||
|
return 0,
|
||||||
|
string.format("Failed getting subevent due to: %s", err)
|
||||||
|
end
|
||||||
local val = select(CLEUEventInfo[subevent]["auraType"], ...)
|
local val = select(CLEUEventInfo[subevent]["auraType"], ...)
|
||||||
if val == nil then return 0, "AuraType is nil or missing" end
|
if val == nil then return 0, "AuraType is nil or missing" end
|
||||||
if type(val) ~= "number" then return 0, "AuraType is not a number" end
|
if type(val) ~= "number" then
|
||||||
|
return 0, "AuraType is not a number"
|
||||||
|
end
|
||||||
return val, nil
|
return val, nil
|
||||||
end,
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1021,5 +1286,7 @@ local frame = CreateFrame("Frame")
|
|||||||
frame:RegisterEvent("PLAYER_LOGIN")
|
frame:RegisterEvent("PLAYER_LOGIN")
|
||||||
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
frame:RegisterEvent("GUILD_ROSTER_UPDATE")
|
frame:RegisterEvent("GUILD_ROSTER_UPDATE")
|
||||||
frame:SetScript("OnEvent", function(self, event, ...) Init() end)
|
frame:SetScript("OnEvent", function(self, event, ...)
|
||||||
|
Init()
|
||||||
|
end)
|
||||||
Init()
|
Init()
|
||||||
|
@@ -1,49 +0,0 @@
|
|||||||
local _, shared = ...
|
|
||||||
---@cast shared HeimdallShared
|
|
||||||
local ModuleName = "ChatSniffer"
|
|
||||||
|
|
||||||
---@class HeimdallChatSnifferConfig
|
|
||||||
---@field enabled boolean
|
|
||||||
---@field debug boolean
|
|
||||||
|
|
||||||
---@class ChatSniffer
|
|
||||||
shared.ChatSniffer = {
|
|
||||||
Init = function()
|
|
||||||
Heimdall_Chat = Heimdall_Chat or {}
|
|
||||||
local frame = CreateFrame("Frame")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_SAY")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_YELL")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_CHANNEL")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_WHISPER")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_CHANNEL_JOIN")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_CHANNEL_LEAVE")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_EMOTE")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_PARTY")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_PARTY_LEADER")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_RAID")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_RAID_LEADER")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_RAID_WARNING")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_SYSTEM")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_TEXT_EMOTE")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_YELL")
|
|
||||||
frame:SetScript("OnEvent", function(self, event, msg, sender, language, channel)
|
|
||||||
if not Heimdall_Data.config.chatSniffer.enabled then return end
|
|
||||||
if not Heimdall_Data.config.chatSniffer.debug then
|
|
||||||
shared.dump(string.format("[%s] got message", { event, msg, sender, language, channel }))
|
|
||||||
end
|
|
||||||
local timestamp = date("%Y-%m-%d %H:%M:%S")
|
|
||||||
local log = string.format(
|
|
||||||
"%s|%s|%s|%s|%s|%s",
|
|
||||||
tostring(timestamp),
|
|
||||||
tostring(event),
|
|
||||||
tostring(sender),
|
|
||||||
tostring(msg),
|
|
||||||
tostring(language),
|
|
||||||
tostring(channel)
|
|
||||||
)
|
|
||||||
Heimdall_Chat[#Heimdall_Chat + 1] = log
|
|
||||||
end)
|
|
||||||
|
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
|
||||||
end,
|
|
||||||
}
|
|
@@ -1,141 +1,118 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "CombatAlerter"
|
local ModuleName = "CombatAlerter"
|
||||||
|
|
||||||
---@class HeimdallCombatAlerterConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.CombatAlerter = {}
|
||||||
---@field debug boolean
|
function shared.CombatAlerter.Init()
|
||||||
---@field channels string[]
|
local alerted = {}
|
||||||
|
local combatAlerterFrame = CreateFrame("Frame")
|
||||||
---@class CombatAlerter
|
combatAlerterFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||||
shared.CombatAlerter = {
|
combatAlerterFrame:SetScript("OnEvent", function(self, event, ...)
|
||||||
Init = function()
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
local alerted = {}
|
print(string.format("[%s] Combat log event received", ModuleName))
|
||||||
local combatAlerterFrame = CreateFrame("Frame")
|
end
|
||||||
combatAlerterFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
if not Heimdall_Data.config.combatAlerter.enabled then
|
||||||
combatAlerterFrame:SetScript("OnEvent", function(self, event, ...)
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
print(string.format("[%s] Combat log event received", ModuleName))
|
print(string.format("[%s] Module disabled, ignoring combat event", ModuleName))
|
||||||
end
|
|
||||||
if not Heimdall_Data.config.combatAlerter.enabled then
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
|
||||||
print(string.format("[%s] Module disabled, ignoring combat event", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
---@type string|nil, string, string
|
local destination, err = CLEUParser.GetDestName(...)
|
||||||
local err, source, destination
|
if err then
|
||||||
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
destination, err = CLEUParser.GetDestName(...)
|
print(string.format("[%s] Error getting destination: %s", ModuleName, err))
|
||||||
if err then
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
|
||||||
print(string.format("[%s] Error getting destination: %s", ModuleName, err))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
|
print(string.format("[%s] Combat event destination: %s", ModuleName, destination))
|
||||||
|
end
|
||||||
|
|
||||||
|
if destination ~= UnitName("player") then
|
||||||
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
|
print(string.format("[%s] Ignoring event - not targeted at player", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local source, err = CLEUParser.GetSourceName(...)
|
||||||
|
if err then
|
||||||
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
|
print(string.format("[%s] Error getting source, using 'unknown': %s", ModuleName, err))
|
||||||
|
end
|
||||||
|
source = "unknown"
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
|
print(string.format("[%s] Combat event source: %s", ModuleName, source))
|
||||||
|
end
|
||||||
|
|
||||||
|
if shared.stinkyTracker.stinkies and shared.stinkyTracker.stinkies[source] then
|
||||||
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
|
print(string.format("[%s] Source is tracked stinky: %s (Already alerted: %s)", ModuleName, source,
|
||||||
|
tostring(alerted[source] or false)))
|
||||||
|
end
|
||||||
|
if alerted[source] then return end
|
||||||
|
|
||||||
|
alerted[source] = true
|
||||||
|
local x, y = GetPlayerMapPosition("player")
|
||||||
|
local zone, subZone = GetZoneText(), GetSubZoneText()
|
||||||
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
print(string.format("[%s] Combat event destination: %s", ModuleName, destination))
|
print(string.format("[%s] Player location: %s/%s at %.2f,%.2f", ModuleName, zone, subZone, x * 100,
|
||||||
|
y * 100))
|
||||||
end
|
end
|
||||||
|
|
||||||
if destination ~= UnitName("player") then
|
SetMapToCurrentZone()
|
||||||
|
SetMapByID(GetCurrentMapAreaID())
|
||||||
|
local areaId = GetCurrentMapAreaID()
|
||||||
|
|
||||||
|
for _, channel in pairs(Heimdall_Data.config.combatAlerter.channels) do
|
||||||
|
local locale = shared.GetLocaleForChannel(channel)
|
||||||
|
local text = string.format(shared._L("combatAlerterInCombat", locale),
|
||||||
|
source,
|
||||||
|
shared._L("zone", locale), shared._L("subZone", locale),
|
||||||
|
tostring(areaId),
|
||||||
|
x * 100, y * 100
|
||||||
|
)
|
||||||
|
---@type Message
|
||||||
|
local msg = {
|
||||||
|
channel = "C",
|
||||||
|
data = channel,
|
||||||
|
message = text,
|
||||||
|
}
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
print(string.format("[%s] Ignoring event - not targeted at player", ModuleName))
|
print(string.format("[%s] Queuing alert message", ModuleName))
|
||||||
|
shared.dumpTable(msg)
|
||||||
end
|
end
|
||||||
return
|
table.insert(shared.messenger.queue, msg)
|
||||||
end
|
end
|
||||||
|
elseif Heimdall_Data.config.combatAlerter.debug then
|
||||||
|
print(string.format("[%s] Source not in stinky list, ignoring: %s", ModuleName, source))
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
source, err = CLEUParser.GetSourceName(...)
|
local combatTriggerFrame = CreateFrame("Frame")
|
||||||
if err then
|
combatTriggerFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
combatTriggerFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||||
print(string.format("[%s] Error getting source, using 'unknown': %s", ModuleName, err))
|
combatTriggerFrame:SetScript("OnEvent", function(self, event, ...)
|
||||||
end
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
source = "unknown"
|
print(string.format("[%s] Combat state changed: %s", ModuleName, event))
|
||||||
|
if event == "PLAYER_REGEN_DISABLED" then
|
||||||
|
print(string.format("[%s] Entered combat - Resetting alerts", ModuleName))
|
||||||
|
else
|
||||||
|
print(string.format("[%s] Left combat - Resetting alerts", ModuleName))
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
alerted = {}
|
||||||
|
end)
|
||||||
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
if Heimdall_Data.config.combatAlerter.debug then
|
||||||
print(string.format("[%s] Combat event source: %s", ModuleName, source))
|
|
||||||
end
|
|
||||||
|
|
||||||
if shared.StinkyTracker.IsStinky(source) then
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Source is tracked stinky: %s (Already alerted: %s)",
|
|
||||||
ModuleName,
|
|
||||||
source,
|
|
||||||
tostring(alerted[source] or false)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
if alerted[source] then return end
|
|
||||||
|
|
||||||
alerted[source] = true
|
|
||||||
local x, y = GetPlayerMapPosition("player")
|
|
||||||
local zone, subZone = GetZoneText(), GetSubZoneText()
|
|
||||||
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Player location: %s/%s at %.2f,%.2f",
|
|
||||||
ModuleName,
|
|
||||||
zone,
|
|
||||||
subZone,
|
|
||||||
x * 100,
|
|
||||||
y * 100
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
SetMapToCurrentZone()
|
|
||||||
SetMapByID(GetCurrentMapAreaID())
|
|
||||||
local areaId = GetCurrentMapAreaID()
|
|
||||||
|
|
||||||
for _, channel in pairs(Heimdall_Data.config.combatAlerter.channels) do
|
|
||||||
local locale = shared.GetLocaleForChannel(channel)
|
|
||||||
local text = string.format(
|
|
||||||
shared._L("combatAlerterInCombat", locale),
|
|
||||||
source,
|
|
||||||
shared._L("zone", locale),
|
|
||||||
shared._L("subZone", locale),
|
|
||||||
tostring(areaId),
|
|
||||||
x * 100,
|
|
||||||
y * 100
|
|
||||||
)
|
|
||||||
---@type Message
|
|
||||||
local msg = {
|
|
||||||
channel = "C",
|
|
||||||
data = channel,
|
|
||||||
message = text,
|
|
||||||
}
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
|
||||||
print(string.format("[%s] Queuing alert message", ModuleName))
|
|
||||||
shared.dump(msg)
|
|
||||||
end
|
|
||||||
table.insert(shared.messenger.queue, msg)
|
|
||||||
end
|
|
||||||
elseif Heimdall_Data.config.combatAlerter.debug then
|
|
||||||
print(string.format("[%s] Source not in stinky list, ignoring: %s", ModuleName, source))
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local combatTriggerFrame = CreateFrame("Frame")
|
|
||||||
combatTriggerFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
|
||||||
combatTriggerFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
|
||||||
combatTriggerFrame:SetScript("OnEvent", function(self, event, ...)
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then
|
|
||||||
print(string.format("[%s] Combat state changed: %s", ModuleName, event))
|
|
||||||
if event == "PLAYER_REGEN_DISABLED" then
|
|
||||||
print(string.format("[%s] Entered combat - Resetting alerts", ModuleName))
|
|
||||||
else
|
|
||||||
print(string.format("[%s] Left combat - Resetting alerts", ModuleName))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
alerted = {}
|
|
||||||
end)
|
|
||||||
|
|
||||||
if Heimdall_Data.config.combatAlerter.debug then print(string.format("[%s] Module initialized", ModuleName)) end
|
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Module initialized", ModuleName))
|
||||||
end,
|
end
|
||||||
}
|
print("[Heimdall] CombatAlerter loaded")
|
||||||
|
end
|
||||||
|
@@ -1,14 +1,8 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Commander"
|
local ModuleName = "Commander"
|
||||||
|
|
||||||
---@class HeimdallCommanderConfig
|
|
||||||
---@field enabled boolean
|
|
||||||
---@field debug boolean
|
|
||||||
---@field channels string[]
|
|
||||||
---@field commander string
|
|
||||||
---@field commands table<string, boolean>
|
|
||||||
|
|
||||||
local helpMessages = {
|
local helpMessages = {
|
||||||
ru = {
|
ru = {
|
||||||
"1) who - пишет вам никнеймы текущих врагов и локу.",
|
"1) who - пишет вам никнеймы текущих врагов и локу.",
|
||||||
@@ -35,404 +29,311 @@ local helpMessages = {
|
|||||||
"9) note <name> i..j - lists notes from i to j for the character.",
|
"9) note <name> i..j - lists notes from i to j for the character.",
|
||||||
"10) note <name> delete i - deletes the i-th note for the character.",
|
"10) note <name> delete i - deletes the i-th note for the character.",
|
||||||
"11) note <name> delete i..j - deletes notes from i to j for the character.",
|
"11) note <name> delete i..j - deletes notes from i to j for the character.",
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
---@class Commander
|
---@diagnostic disable-next-line: missing-fields
|
||||||
shared.Commander = {
|
shared.Commander = {}
|
||||||
Init = function()
|
function shared.Commander.Init()
|
||||||
---@param text string
|
---@param text string
|
||||||
---@param size number
|
---@param size number
|
||||||
---@return string[]
|
---@return string[]
|
||||||
local function Partition(text, size)
|
local function Partition(text, size)
|
||||||
local words = {}
|
local words = {}
|
||||||
for word in text:gmatch("[^,]+") do
|
for word in text:gmatch("[^,]+") do
|
||||||
words[#words + 1] = word
|
words[#words + 1] = word
|
||||||
end
|
end
|
||||||
|
|
||||||
local ret = {}
|
local ret = {}
|
||||||
local currentChunk = ""
|
local currentChunk = ""
|
||||||
|
|
||||||
for _, word in ipairs(words) do
|
for _, word in ipairs(words) do
|
||||||
if #currentChunk + #word + 1 <= size then
|
if #currentChunk + #word + 1 <= size then
|
||||||
currentChunk = currentChunk .. (currentChunk == "" and word or " " .. word)
|
currentChunk = currentChunk .. (currentChunk == "" and word or " " .. word)
|
||||||
else
|
else
|
||||||
if #currentChunk > 0 then ret[#ret + 1] = currentChunk end
|
if #currentChunk > 0 then
|
||||||
currentChunk = word
|
ret[#ret + 1] = currentChunk
|
||||||
end
|
end
|
||||||
|
currentChunk = word
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if #currentChunk > 0 then ret[#ret + 1] = currentChunk end
|
if #currentChunk > 0 then
|
||||||
|
ret[#ret + 1] = currentChunk
|
||||||
|
end
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
end
|
||||||
|
---@param arr table<string, Player>
|
||||||
|
---@return string[]
|
||||||
|
local function Count(arr)
|
||||||
|
local ret = {}
|
||||||
|
for _, player in pairs(arr) do
|
||||||
|
if shared.Whoer.ShouldNotifyForZone(player.zone) then
|
||||||
|
ret[player.zone] = (ret[player.zone] or 0) + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
---@param arr table<string, Player>
|
local text = {}
|
||||||
---@return string[]
|
for zone, count in pairs(ret) do
|
||||||
local function Count(arr)
|
text[#text + 1] = string.format("%s: %d", zone, count)
|
||||||
local ret = {}
|
|
||||||
for _, player in pairs(arr) do
|
|
||||||
if shared.Whoer.ShouldNotifyForZone(player.zone) then ret[player.zone] = (ret[player.zone] or 0) + 1 end
|
|
||||||
end
|
|
||||||
local text = {}
|
|
||||||
for zone, count in pairs(ret) do
|
|
||||||
text[#text + 1] = string.format("%s: %d", zone, count)
|
|
||||||
end
|
|
||||||
return text
|
|
||||||
end
|
end
|
||||||
---@param arr table<string, Player>
|
return text
|
||||||
---@return string[]
|
end
|
||||||
local function CountPartitioned(arr)
|
---@param arr table<string, Player>
|
||||||
local count = Count(arr)
|
---@return string[]
|
||||||
local text = {}
|
local function CountPartitioned(arr)
|
||||||
---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
|
local count = Count(arr)
|
||||||
for _, line in pairs(Partition(strjoin(", ", unpack(count)), 200)) do
|
local text = {}
|
||||||
text[#text + 1] = line
|
for _, line in pairs(Partition(strjoin(", ", unpack(count)), 200)) do
|
||||||
end
|
text[#text + 1] = line
|
||||||
return text
|
|
||||||
end
|
end
|
||||||
---@param arr table<string, Player>
|
return text
|
||||||
---@return string[]
|
end
|
||||||
local function Who(arr)
|
---@param arr table<string, Player>
|
||||||
local ret = {}
|
---@return string[]
|
||||||
for _, player in pairs(arr) do
|
local function Who(arr)
|
||||||
if shared.Whoer.ShouldNotifyForZone(player.zone) then
|
local ret = {}
|
||||||
ret[#ret + 1] = string.format(
|
for _, player in pairs(arr) do
|
||||||
"%s/%s (%s) %s",
|
if shared.Whoer.ShouldNotifyForZone(player.zone) then
|
||||||
player.name,
|
ret[#ret + 1] = string.format("%s/%s (%s) %s", player.name, player.class, player.zone,
|
||||||
player.class,
|
player.stinky and "(!!!!)" or "")
|
||||||
player.zone,
|
|
||||||
player.stinky and "(!!!!)" or ""
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(string.format("[%s] Command result: %s", ModuleName, strjoin(", ", unpack(ret))))
|
|
||||||
end
|
|
||||||
return ret
|
|
||||||
end
|
end
|
||||||
-- This is really ugly, duplicating methods like this
|
if Heimdall_Data.config.commander.debug then
|
||||||
-- But I have no better idea
|
print(string.format("[%s] Command result: %s", ModuleName, strjoin(", ", unpack(ret))))
|
||||||
-- We would have to drag reference channel all the way here
|
|
||||||
-- And then in here do some kind of deciding based on the fucking channel locale
|
|
||||||
-- That's also a nasty solution... I guess adding "kto" is better
|
|
||||||
---@param arr table<string, Player>
|
|
||||||
---@return string[]
|
|
||||||
local function WhoRu(arr)
|
|
||||||
local ret = {}
|
|
||||||
for _, player in pairs(arr) do
|
|
||||||
if shared.Whoer.ShouldNotifyForZone(player.zone) then
|
|
||||||
shared.dump(player)
|
|
||||||
ret[#ret + 1] = string.format(
|
|
||||||
"%s/%s (%s) %s",
|
|
||||||
player.name,
|
|
||||||
shared._L(player.class, "ru"),
|
|
||||||
shared._L(player.zone, "ru"),
|
|
||||||
player.stinky and "(!!!!)" or ""
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(string.format("[%s] Command result: %s", ModuleName, strjoin(", ", unpack(ret))))
|
|
||||||
end
|
|
||||||
return ret
|
|
||||||
end
|
end
|
||||||
---@param arr table<string, Player>
|
return ret
|
||||||
---@return string[]
|
end
|
||||||
local function WhoPartitioned(arr)
|
---@param arr table<string, Player>
|
||||||
local who = Who(arr)
|
---@return string[]
|
||||||
local text = {}
|
local function WhoPartitioned(arr)
|
||||||
---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
|
local who = Who(arr)
|
||||||
for _, line in pairs(Partition(strjoin(", ", unpack(who)), 200)) do
|
local text = {}
|
||||||
text[#text + 1] = "who: " .. line
|
for _, line in pairs(Partition(strjoin(", ", unpack(who)), 200)) do
|
||||||
end
|
text[#text + 1] = "who: " .. line
|
||||||
return text
|
|
||||||
end
|
end
|
||||||
---@param arr table<string, Player>
|
return text
|
||||||
---@return string[]
|
end
|
||||||
local function WhoPartitionedRu(arr)
|
---@param arr table<string, Player>
|
||||||
local who = WhoRu(arr)
|
---@return string[]
|
||||||
local text = {}
|
local function CountClass(arr)
|
||||||
---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
|
local ret = {}
|
||||||
for _, line in pairs(Partition(strjoin(", ", unpack(who)), 200)) do
|
for _, player in pairs(arr) do
|
||||||
text[#text + 1] = "кто: " .. line
|
if shared.Whoer.ShouldNotifyForZone(player.zone) then
|
||||||
|
ret[player.class] = (ret[player.class] or 0) + 1
|
||||||
end
|
end
|
||||||
return text
|
|
||||||
end
|
end
|
||||||
---@param arr table<string, Player>
|
local text = {}
|
||||||
---@return string[]
|
for class, count in pairs(ret) do
|
||||||
local function CountClass(arr)
|
text[#text + 1] = string.format("%s: %d", class, count)
|
||||||
local ret = {}
|
|
||||||
for _, player in pairs(arr) do
|
|
||||||
if shared.Whoer.ShouldNotifyForZone(player.zone) then
|
|
||||||
ret[player.class] = (ret[player.class] or 0) + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local text = {}
|
|
||||||
for class, count in pairs(ret) do
|
|
||||||
text[#text + 1] = string.format("%s: %d", class, count)
|
|
||||||
end
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(string.format("[%s] Message text: %s", ModuleName, strjoin(", ", unpack(text))))
|
|
||||||
end
|
|
||||||
return text
|
|
||||||
end
|
end
|
||||||
---@param arr table<string, Player>
|
if Heimdall_Data.config.commander.debug then
|
||||||
---@return string[]
|
print(string.format("[%s] Message text: %s", ModuleName, strjoin(", ", unpack(text))))
|
||||||
local function CountClassPartitioned(arr)
|
|
||||||
local countClass = CountClass(arr)
|
|
||||||
local text = {}
|
|
||||||
---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
|
|
||||||
for _, line in pairs(Partition(strjoin(", ", unpack(countClass)), 200)) do
|
|
||||||
text[#text + 1] = line
|
|
||||||
end
|
|
||||||
return text
|
|
||||||
end
|
end
|
||||||
local function CountClassPartitionedStinkies()
|
return text
|
||||||
if Heimdall_Data.config.commander.debug then
|
end
|
||||||
print(string.format("[%s] Executing: CountClassPartitionedStinkies", ModuleName))
|
---@param arr table<string, Player>
|
||||||
end
|
---@return string[]
|
||||||
local res = CountClassPartitioned(HeimdallStinkies)
|
local function CountClassPartitioned(arr)
|
||||||
if #res == 0 then return { "No stinkies found" } end
|
local countClass = CountClass(arr)
|
||||||
return res
|
local text = {}
|
||||||
|
for _, line in pairs(Partition(strjoin(", ", unpack(countClass)), 200)) do
|
||||||
|
text[#text + 1] = line
|
||||||
end
|
end
|
||||||
local function WhoPartitionedStinkies()
|
return text
|
||||||
if Heimdall_Data.config.commander.debug then
|
end
|
||||||
print(string.format("[%s] Executing: WhoPartitionedStinkies", ModuleName))
|
local function CountClassPartitionedStinkies()
|
||||||
shared.dump(HeimdallStinkies)
|
if Heimdall_Data.config.commander.debug then
|
||||||
end
|
print(string.format("[%s] Executing: CountClassPartitionedStinkies",
|
||||||
local res = WhoPartitioned(HeimdallStinkies)
|
ModuleName))
|
||||||
if #res == 0 then return { "No stinkies found" } end
|
|
||||||
return res
|
|
||||||
end
|
end
|
||||||
local function WhoPartitionedStinkiesRu()
|
local res = CountClassPartitioned(HeimdallStinkies)
|
||||||
if Heimdall_Data.config.commander.debug then
|
if #res == 0 then
|
||||||
print(string.format("[%s] Executing: WhoPartitionedStinkies", ModuleName))
|
return { "No stinkies found" }
|
||||||
shared.dump(HeimdallStinkies)
|
|
||||||
end
|
|
||||||
local res = WhoPartitionedRu(HeimdallStinkies)
|
|
||||||
if #res == 0 then return { "No stinkies found" } end
|
|
||||||
return res
|
|
||||||
end
|
end
|
||||||
local function CountPartitionedStinkies()
|
return res
|
||||||
if Heimdall_Data.config.commander.debug then
|
end
|
||||||
print(string.format("[%s] Executing: CountPartitionedStinkies", ModuleName))
|
local function WhoPartitionedStinkies()
|
||||||
end
|
if Heimdall_Data.config.commander.debug then
|
||||||
local res = CountPartitioned(HeimdallStinkies)
|
print(string.format("[%s] Executing: WhoPartitionedStinkies",
|
||||||
if #res == 0 then return { "No stinkies found" } end
|
ModuleName))
|
||||||
return res
|
shared.dumpTable(HeimdallStinkies)
|
||||||
end
|
end
|
||||||
local function HelpRu()
|
local res = WhoPartitioned(HeimdallStinkies)
|
||||||
if Heimdall_Data.config.commander.debug then print(string.format("[%s] Executing: HelpRu", ModuleName)) end
|
if #res == 0 then
|
||||||
return helpMessages.ru
|
return { "No stinkies found" }
|
||||||
end
|
end
|
||||||
local function HelpEn()
|
return res
|
||||||
if Heimdall_Data.config.commander.debug then print(string.format("[%s] Executing: HelpEn", ModuleName)) end
|
end
|
||||||
return helpMessages.en
|
local function CountPartitionedStinkies()
|
||||||
|
if Heimdall_Data.config.commander.debug then
|
||||||
|
print(string.format("[%s] Executing: CountPartitionedStinkies",
|
||||||
|
ModuleName))
|
||||||
end
|
end
|
||||||
local groupInviteFrame = CreateFrame("Frame")
|
local res = CountPartitioned(HeimdallStinkies)
|
||||||
groupInviteFrame:SetScript("OnEvent", function(self, event, ...)
|
if #res == 0 then
|
||||||
if Heimdall_Data.config.commander.debug then print(string.format("[%s] Event received", ModuleName)) end
|
return { "No stinkies found" }
|
||||||
AcceptGroup()
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
local function HelpRu()
|
||||||
|
if Heimdall_Data.config.commander.debug then print(string.format("[%s] Executing: HelpRu", ModuleName)) end
|
||||||
|
return helpMessages.ru
|
||||||
|
end
|
||||||
|
local function HelpEn()
|
||||||
|
if Heimdall_Data.config.commander.debug then print(string.format("[%s] Executing: HelpEn", ModuleName)) end
|
||||||
|
return helpMessages.en
|
||||||
|
end
|
||||||
|
local groupInviteFrame = CreateFrame("Frame")
|
||||||
|
groupInviteFrame:SetScript("OnEvent", function(self, event, ...)
|
||||||
|
if Heimdall_Data.config.commander.debug then print(string.format("[%s] Event received", ModuleName)) end
|
||||||
|
AcceptGroup()
|
||||||
|
groupInviteFrame:UnregisterEvent("PARTY_INVITE_REQUEST")
|
||||||
|
C_Timer.NewTimer(0.1, function()
|
||||||
|
if Heimdall_Data.config.commander.debug then print(string.format("[%s] Click event triggered", ModuleName)) end
|
||||||
|
_G["StaticPopup1Button1"]:Click()
|
||||||
|
end, 1)
|
||||||
|
end)
|
||||||
|
local function JoinGroup()
|
||||||
|
if Heimdall_Data.config.commander.debug then print(string.format("[%s] JoinGroup command received", ModuleName)) end
|
||||||
|
groupInviteFrame:RegisterEvent("PARTY_INVITE_REQUEST")
|
||||||
|
C_Timer.NewTimer(10, function()
|
||||||
groupInviteFrame:UnregisterEvent("PARTY_INVITE_REQUEST")
|
groupInviteFrame:UnregisterEvent("PARTY_INVITE_REQUEST")
|
||||||
C_Timer.NewTimer(0.1, function()
|
end, 1)
|
||||||
if Heimdall_Data.config.commander.debug then
|
return { "+" }
|
||||||
print(string.format("[%s] Click event triggered", ModuleName))
|
end
|
||||||
end
|
local function LeaveGroup()
|
||||||
_G["StaticPopup1Button1"]:Click()
|
if Heimdall_Data.config.commander.debug then print(string.format("[%s] LeaveGroup command received", ModuleName)) end
|
||||||
end, 1)
|
LeaveParty()
|
||||||
end)
|
return {}
|
||||||
local function JoinGroup()
|
end
|
||||||
if Heimdall_Data.config.commander.debug then
|
---@param target string
|
||||||
print(string.format("[%s] JoinGroup command received", ModuleName))
|
local function FollowTarget(target)
|
||||||
end
|
if Heimdall_Data.config.commander.debug then print(string.format("[%s] Following target: %s", ModuleName, target)) end
|
||||||
groupInviteFrame:RegisterEvent("PARTY_INVITE_REQUEST")
|
if not target then return end
|
||||||
C_Timer.NewTimer(10, function() groupInviteFrame:UnregisterEvent("PARTY_INVITE_REQUEST") end, 1)
|
FollowUnit(target)
|
||||||
return { "+" }
|
return {}
|
||||||
end
|
end
|
||||||
local function LeaveGroup()
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(string.format("[%s] LeaveGroup command received", ModuleName))
|
|
||||||
end
|
|
||||||
LeaveParty()
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
---@param target string
|
|
||||||
local function FollowTarget(target)
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(string.format("[%s] Following target: %s", ModuleName, target))
|
|
||||||
end
|
|
||||||
if not target then return end
|
|
||||||
FollowUnit(target)
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param args string[]
|
---@param args string[]
|
||||||
local function MacroTarget(args)
|
local function MacroTarget(args)
|
||||||
if Heimdall_Data.config.commander.debug then
|
if Heimdall_Data.config.commander.debug then
|
||||||
---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
|
print(string.format("[%s] Macroing: %s", ModuleName,
|
||||||
print(string.format("[%s] Macroing: %s", ModuleName, strjoin(" ", unpack(args))))
|
strjoin(" ", unpack(args))))
|
||||||
end
|
end
|
||||||
|
if #args < 2 or #args % 2 ~= 0 then
|
||||||
if #args < 2 or #args % 2 ~= 0 then
|
if #args < 2 or #args % 2 ~= 0 then
|
||||||
if #args < 2 or #args % 2 ~= 0 then
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(string.format("[%s] Invalid number of arguments for MacroTarget", ModuleName))
|
|
||||||
end
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.remove(args, 1)
|
|
||||||
|
|
||||||
for i = 1, #args do
|
|
||||||
local stinky = strtrim(args[i])
|
|
||||||
local name = stinky:match("([^/]+)")
|
|
||||||
local class = stinky:match("/([^ $]+)")
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
if Heimdall_Data.config.commander.debug then
|
||||||
print(string.format("[%s] Adding stinky: %s/%s", ModuleName, name, tostring(class)))
|
print(string.format(
|
||||||
end
|
"[%s] Invalid number of arguments for MacroTarget", ModuleName))
|
||||||
shared.StinkyTracker.Track({
|
|
||||||
name = name,
|
|
||||||
class = class or "unknown",
|
|
||||||
seenAt = GetTime(),
|
|
||||||
hostile = true,
|
|
||||||
})
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(string.format("[%s] Added stinky: %s/%s", ModuleName, name, tostring(class)))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param args string[]
|
|
||||||
local function IgnoreMacroTarget(args)
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
---@diagnostic disable-next-line: param-type-mismatch something wrong with luals, it's picking up the "wrong" unpack
|
|
||||||
print(string.format("[%s] Macroing: %s", ModuleName, strjoin(" ", unpack(args))))
|
|
||||||
end
|
|
||||||
if #args < 1 then
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(string.format("[%s] Invalid number of arguments for IgnoreMacroTarget", ModuleName))
|
|
||||||
end
|
end
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
table.remove(args, 1)
|
end
|
||||||
|
table.remove(args, 1)
|
||||||
|
|
||||||
for i = 1, #args do
|
for i = 1, #args do
|
||||||
local stinky = strtrim(args[i])
|
local stinky = strtrim(args[i])
|
||||||
local name = stinky:match("([^/]+)")
|
local name = stinky:match("([^/]+)")
|
||||||
if Heimdall_Data.config.commander.debug then
|
local class = stinky:match("/([^ $]+)")
|
||||||
print(string.format("[%s] Ignoring stinky: %s", ModuleName, name))
|
if Heimdall_Data.config.commander.debug then
|
||||||
end
|
print(string.format("[%s] Adding stinky: %s/%s", ModuleName, name, tostring(class)))
|
||||||
shared.StinkyTracker.Ignore(name)
|
|
||||||
end
|
end
|
||||||
return {}
|
shared.stinkyTracker.stinkies[name] = {
|
||||||
|
name = name,
|
||||||
|
class = class or "unknown",
|
||||||
|
seenAt = GetTime(),
|
||||||
|
hostile = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@class Command
|
||||||
|
---@field keywordRe string
|
||||||
|
---@field commanderOnly boolean
|
||||||
|
---@field callback fun(...: any): string[]
|
||||||
|
|
||||||
|
local commands = {
|
||||||
|
{ keywordRe = "^who$", commanderOnly = false, callback = WhoPartitionedStinkies },
|
||||||
|
{ keywordRe = "^howmany$", commanderOnly = false, callback = CountPartitionedStinkies },
|
||||||
|
{ keywordRe = "^classes$", commanderOnly = false, callback = CountClassPartitionedStinkies },
|
||||||
|
{ keywordRe = "^help$", commanderOnly = false, callback = HelpRu },
|
||||||
|
{ keywordRe = "^helpen$", commanderOnly = false, callback = HelpEn },
|
||||||
|
{ keywordRe = "^joingroup$", commanderOnly = false, callback = JoinGroup },
|
||||||
|
{ keywordRe = "^leavegroup$", commanderOnly = false, callback = LeaveGroup },
|
||||||
|
{ keywordRe = "^follow$", commanderOnly = false, callback = FollowTarget },
|
||||||
|
{ keywordRe = "^macro", commanderOnly = false, callback = MacroTarget },
|
||||||
|
}
|
||||||
|
|
||||||
|
local commanderChannelFrame = CreateFrame("Frame")
|
||||||
|
commanderChannelFrame:RegisterEvent("CHAT_MSG_CHANNEL")
|
||||||
|
commanderChannelFrame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
||||||
|
--if Heimdall_Data.config.commander.debug then
|
||||||
|
-- print(string.format("[%s] Event received", ModuleName))
|
||||||
|
-- shared.dumpTable(Heimdall_Data.config.commander)
|
||||||
|
--end
|
||||||
|
if not Heimdall_Data.config.commander.enabled then
|
||||||
|
--if Heimdall_Data.config.commander.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.commander.channels) do
|
||||||
|
if channel == channelname then
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not ok then
|
||||||
|
if Heimdall_Data.config.commander.debug then
|
||||||
|
print(string.format("[%s] Channel name '%s' does not match any of the channels '%s'", ModuleName,
|
||||||
|
channelname, table.concat(Heimdall_Data.config.commander.channels, ", ")))
|
||||||
|
end
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
---@class Command
|
sender = string.match(sender, "^[^-]+")
|
||||||
---@field keywordRe string
|
if Heimdall_Data.config.commander.debug then
|
||||||
---@field commanderOnly boolean
|
print(string.format("[%s] Message from: %s", ModuleName, sender))
|
||||||
---@field callback fun(...: any): string[]
|
shared.dumpTable(Heimdall_Data.config.commander)
|
||||||
|
end
|
||||||
|
|
||||||
local commands = {
|
for _, command in ipairs(commands) do
|
||||||
{ keywordRe = "^who$", commanderOnly = false, callback = WhoPartitionedStinkies },
|
local enabled = Heimdall_Data.config.commander.commands[command.keywordRe] == true or false
|
||||||
{ keywordRe = "^кто$", commanderOnly = false, callback = WhoPartitionedStinkiesRu },
|
|
||||||
{ keywordRe = "^howmany$", commanderOnly = false, callback = CountPartitionedStinkies },
|
|
||||||
{ keywordRe = "^classes$", commanderOnly = false, callback = CountClassPartitionedStinkies },
|
|
||||||
{ keywordRe = "^help$", commanderOnly = false, callback = HelpRu },
|
|
||||||
{ keywordRe = "^helpen$", commanderOnly = false, callback = HelpEn },
|
|
||||||
{ keywordRe = "^joingroup$", commanderOnly = false, callback = JoinGroup },
|
|
||||||
{ keywordRe = "^leavegroup$", commanderOnly = false, callback = LeaveGroup },
|
|
||||||
{ keywordRe = "^follow$", commanderOnly = false, callback = FollowTarget },
|
|
||||||
{ keywordRe = "^macro", commanderOnly = false, callback = MacroTarget },
|
|
||||||
{ keywordRe = "^ignore", commanderOnly = false, callback = IgnoreMacroTarget },
|
|
||||||
}
|
|
||||||
|
|
||||||
local commanderChannelFrame = CreateFrame("Frame")
|
|
||||||
commanderChannelFrame:RegisterEvent("CHAT_MSG_CHANNEL")
|
|
||||||
commanderChannelFrame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
|
||||||
--if Heimdall_Data.config.commander.debug then
|
|
||||||
-- print(string.format("[%s] Event received", ModuleName))
|
|
||||||
-- shared.dump(Heimdall_Data.config.commander)
|
|
||||||
--end
|
|
||||||
if not Heimdall_Data.config.commander.enabled then
|
|
||||||
--if Heimdall_Data.config.commander.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.commander.channels) do
|
|
||||||
if channel == channelname then
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not ok then
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Channel name '%s' does not match any of the channels '%s'",
|
|
||||||
ModuleName,
|
|
||||||
channelname,
|
|
||||||
table.concat(Heimdall_Data.config.commander.channels, ", ")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
sender = string.match(sender, "^[^-]+")
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
if Heimdall_Data.config.commander.debug then
|
||||||
print(string.format("[%s] Message from: %s", ModuleName, sender))
|
print(string.format("[%s] Command match: %s = %s", ModuleName, command.keywordRe, tostring(enabled)))
|
||||||
shared.dump(Heimdall_Data.config.commander)
|
|
||||||
end
|
end
|
||||||
|
if enabled and
|
||||||
for _, command in ipairs(commands) do
|
(not command.commanderOnly
|
||||||
local enabled = Heimdall_Data.config.commander.commands[command.keywordRe] == true or false
|
or (command.commanderOnly
|
||||||
if Heimdall_Data.config.commander.debug then
|
and sender == Heimdall_Data.config.commander.commander)) then
|
||||||
print(
|
if msg:match(command.keywordRe) then
|
||||||
string.format("[%s] Command match: %s = %s", ModuleName, command.keywordRe, tostring(enabled))
|
local messages = command.callback({ strsplit(",", msg) })
|
||||||
)
|
if Heimdall_Data.config.commander.debug then
|
||||||
end
|
print(string.format("[%s] Messages to send: %s", ModuleName, strjoin(", ", unpack(messages))))
|
||||||
if
|
end
|
||||||
enabled
|
for _, message in ipairs(messages) do
|
||||||
and (
|
---@type Message
|
||||||
not command.commanderOnly
|
local msg = {
|
||||||
-- if Heimdall_Data.config.commander.debug then print(string.format("[%s] Ignoring command, sender %s not commander %s", ModuleName, sender, Heimdall_Data.config.commander.commander)) end
|
channel = "C",
|
||||||
|
data = channelname,
|
||||||
or (command.commanderOnly and sender == Heimdall_Data.config.commander.commander)
|
message = message
|
||||||
)
|
}
|
||||||
then
|
|
||||||
if msg:match(command.keywordRe) then
|
|
||||||
---@diagnostic disable-next-line: redundant-parameter Currently luals does not support variadic functions as a @field
|
|
||||||
local messages = command.callback({ strsplit(",", msg) })
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
if Heimdall_Data.config.commander.debug then
|
||||||
print(string.format("[%s] Messages to send: %s", ModuleName, #messages))
|
print(string.format("[%s] Queuing message", ModuleName))
|
||||||
shared.dump(messages)
|
shared.dumpTable(msg)
|
||||||
end
|
|
||||||
for _, message in ipairs(messages) do
|
|
||||||
---@type Message
|
|
||||||
local returnmsg = {
|
|
||||||
channel = "C",
|
|
||||||
data = channelname,
|
|
||||||
message = message,
|
|
||||||
}
|
|
||||||
if Heimdall_Data.config.commander.debug then
|
|
||||||
print(string.format("[%s] Queuing message", ModuleName))
|
|
||||||
shared.dump(msg)
|
|
||||||
end
|
|
||||||
if Heimdall_Data.config.networkMessenger.enabled then
|
|
||||||
shared.NetworkMessenger.Enqueue(returnmsg)
|
|
||||||
elseif Heimdall_Data.config.messenger.enabled then
|
|
||||||
shared.Messenger.Enqueue(returnmsg)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
--table.insert(shared.messenger.queue, msg)
|
||||||
|
table.insert(shared.networkMessenger.queue, msg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print("[Heimdall] Commander module loaded")
|
||||||
end,
|
end
|
||||||
}
|
|
||||||
|
4726
Modules/Config.lua
4726
Modules/Config.lua
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,10 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Configurator"
|
local ModuleName = "Configurator"
|
||||||
|
|
||||||
---@class HeimdallConfiguratorConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Configurator = {}
|
||||||
---@field debug boolean
|
function shared.Configurator.Init()
|
||||||
|
print("[Heimdall] Configurator module loaded")
|
||||||
---@class Configurator
|
end
|
||||||
shared.Configurator = {
|
|
||||||
Init = function() print(string.format("[%s] Module initialized", ModuleName)) end,
|
|
||||||
}
|
|
||||||
|
@@ -1,268 +1,185 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "DeathReporter"
|
local ModuleName = "DeathReporter"
|
||||||
|
|
||||||
---@class HeimdallDeathReporterConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.DeathReporter = {}
|
||||||
---@field debug boolean
|
function shared.DeathReporter.Init()
|
||||||
---@field throttle number
|
---@type table<string, number>
|
||||||
---@field doWhisper boolean
|
local recentDeaths = {}
|
||||||
---@field channels string[]
|
---@type table<string, number>
|
||||||
---@field zoneOverride string?
|
local recentDuels = {}
|
||||||
---@field duelThrottle number
|
|
||||||
|
|
||||||
---@class DeathReporter
|
---@param source string
|
||||||
shared.DeathReporter = {
|
---@param destination string
|
||||||
Init = function()
|
---@param spellName string
|
||||||
---@type table<string, number>
|
local function RegisterDeath(source, destination, spellName)
|
||||||
local recentDeaths = {}
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
---@type table<string, number>
|
print(string.format("[%s] Processing death event - Source: %s, Target: %s, Spell: %s",
|
||||||
local recentDuels = {}
|
ModuleName, source, destination, spellName))
|
||||||
|
|
||||||
---@param source string
|
|
||||||
---@param destination string
|
|
||||||
---@param spellName string
|
|
||||||
local function RegisterDeath(source, destination, spellName)
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Processing death event - Source: %s, Target: %s, Spell: %s",
|
|
||||||
ModuleName,
|
|
||||||
source,
|
|
||||||
destination,
|
|
||||||
spellName
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not Heimdall_Data.config.deathReporter.enabled then
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(string.format("[%s] Module disabled, ignoring death event", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if
|
|
||||||
recentDeaths[destination]
|
|
||||||
and GetTime() - recentDeaths[destination] < Heimdall_Data.config.deathReporter.throttle
|
|
||||||
then
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
local timeLeft = Heimdall_Data.config.deathReporter.throttle
|
|
||||||
- (GetTime() - recentDeaths[destination])
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Death report throttled for %s (%.1f seconds remaining)",
|
|
||||||
ModuleName,
|
|
||||||
destination,
|
|
||||||
timeLeft
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if
|
|
||||||
recentDuels[destination]
|
|
||||||
and GetTime() - recentDuels[destination] < Heimdall_Data.config.deathReporter.duelThrottle
|
|
||||||
then
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Ignoring death report - Recent duel detected for target: %s",
|
|
||||||
ModuleName,
|
|
||||||
destination
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if
|
|
||||||
recentDuels[source]
|
|
||||||
and GetTime() - recentDuels[source] < Heimdall_Data.config.deathReporter.duelThrottle
|
|
||||||
then
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Ignoring death report - Recent duel detected for source: %s",
|
|
||||||
ModuleName,
|
|
||||||
source
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(string.format("[%s] Recording death for %s", ModuleName, destination))
|
|
||||||
end
|
|
||||||
recentDeaths[destination] = GetTime()
|
|
||||||
|
|
||||||
C_Timer.NewTimer(3, function()
|
|
||||||
if
|
|
||||||
recentDuels[destination]
|
|
||||||
and GetTime() - recentDuels[destination] < Heimdall_Data.config.deathReporter.duelThrottle
|
|
||||||
then
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Cancelling delayed death report - Recent duel detected for: %s",
|
|
||||||
ModuleName,
|
|
||||||
destination
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if
|
|
||||||
recentDuels[source]
|
|
||||||
and GetTime() - recentDuels[source] < Heimdall_Data.config.deathReporter.duelThrottle
|
|
||||||
then
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Cancelling delayed death report - Recent duel detected for: %s",
|
|
||||||
ModuleName,
|
|
||||||
source
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Sending death report - %s killed %s with %s",
|
|
||||||
ModuleName,
|
|
||||||
source,
|
|
||||||
destination,
|
|
||||||
spellName
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
local zone, subzone = GetZoneText() or "Unknown", GetSubZoneText() or "Unknown"
|
|
||||||
if Heimdall_Data.config.spotter.zoneOverride then
|
|
||||||
zone = Heimdall_Data.config.spotter.zoneOverride or ""
|
|
||||||
subzone = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local x, y = GetPlayerMapPosition("player")
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(string.format("[%s] Player coordinates: %.2f, %.2f", ModuleName, x * 100, y * 100))
|
|
||||||
end
|
|
||||||
SetMapToCurrentZone()
|
|
||||||
SetMapByID(GetCurrentMapAreaID())
|
|
||||||
local zoneId = GetCurrentMapAreaID()
|
|
||||||
|
|
||||||
for _, channel in pairs(Heimdall_Data.config.deathReporter.channels) do
|
|
||||||
local locale = shared.GetLocaleForChannel(channel)
|
|
||||||
local text = string.format(
|
|
||||||
shared._L("killed", locale),
|
|
||||||
source,
|
|
||||||
destination,
|
|
||||||
shared._L(spellName, locale),
|
|
||||||
shared._L(zone, locale),
|
|
||||||
shared._L(subzone, locale),
|
|
||||||
zoneId,
|
|
||||||
x * 100,
|
|
||||||
y * 100
|
|
||||||
)
|
|
||||||
---@type Message
|
|
||||||
local msg = {
|
|
||||||
channel = "C",
|
|
||||||
data = channel,
|
|
||||||
message = text,
|
|
||||||
}
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(string.format("[%s] Queuing death report message", ModuleName))
|
|
||||||
shared.dump(msg)
|
|
||||||
end
|
|
||||||
table.insert(shared.messenger.queue, msg)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local cleuFrame = CreateFrame("Frame")
|
if not Heimdall_Data.config.deathReporter.enabled then
|
||||||
cleuFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
|
||||||
cleuFrame:SetScript("OnEvent", function(self, event, ...)
|
|
||||||
-- if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
-- print(string.format("[%s] Received combat log event", ModuleName))
|
|
||||||
-- end
|
|
||||||
if not Heimdall_Data.config.deathReporter.enabled then return end
|
|
||||||
local overkill, source, destination, spellName, sourceGUID, destinationGUID, err
|
|
||||||
overkill, err = CLEUParser.GetOverkill(...)
|
|
||||||
if not err and overkill > 0 then
|
|
||||||
source, err = CLEUParser.GetSourceName(...)
|
|
||||||
if err then
|
|
||||||
source = "unknown"
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(string.format("[%s] Error getting source name", ModuleName))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
destination, err = CLEUParser.GetDestName(...)
|
|
||||||
if err then
|
|
||||||
destination = "unknown"
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(string.format("[%s] Error getting destination name", ModuleName))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
spellName, err = CLEUParser.GetSpellName(...)
|
|
||||||
if err then
|
|
||||||
spellName = "unknown"
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
|
||||||
print(string.format("[%s] Error getting spell name", ModuleName))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
sourceGUID, err = CLEUParser.GetSourceGUID(...)
|
|
||||||
if err or not string.match(sourceGUID, "Player") then return end
|
|
||||||
destinationGUID, err = CLEUParser.GetDestGUID(...)
|
|
||||||
if err or not string.match(destinationGUID, "Player") then return end
|
|
||||||
RegisterDeath(source, destination, spellName)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local systemMessageFrame = CreateFrame("Frame")
|
|
||||||
systemMessageFrame:RegisterEvent("CHAT_MSG_SYSTEM")
|
|
||||||
systemMessageFrame:SetScript("OnEvent", function(self, event, msg)
|
|
||||||
if not Heimdall_Data.config.deathReporter.enabled then return end
|
|
||||||
local source, destination = string.match(msg, "([^ ]+) has defeated ([^ ]+) in a duel")
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
print(string.format("[%s] Received system message: %s", ModuleName, msg))
|
print(string.format("[%s] Module disabled, ignoring death event", ModuleName))
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Source: %s, Destination: %s",
|
|
||||||
ModuleName,
|
|
||||||
tostring(source),
|
|
||||||
tostring(destination)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
if not source or not destination then return end
|
return
|
||||||
source = string.match(source, "([^-]+)")
|
end
|
||||||
destination = string.match(destination, "([^-]+)")
|
|
||||||
if source and destination then
|
if recentDeaths[destination] and GetTime() - recentDeaths[destination] < Heimdall_Data.config.deathReporter.throttle then
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
print(string.format("[%s] Detected duel between %s and %s", ModuleName, source, destination))
|
local timeLeft = Heimdall_Data.config.deathReporter.throttle - (GetTime() - recentDeaths[destination])
|
||||||
end
|
print(string.format("[%s] Death report throttled for %s (%.1f seconds remaining)",
|
||||||
local now = GetTime()
|
ModuleName, destination, timeLeft))
|
||||||
recentDuels[source] = now
|
|
||||||
recentDuels[destination] = now
|
|
||||||
end
|
end
|
||||||
end)
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if recentDuels[destination] and GetTime() - recentDuels[destination] < Heimdall_Data.config.deathReporter.duelThrottle then
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Ignoring death report - Recent duel detected for target: %s", ModuleName,
|
||||||
|
destination))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if recentDuels[source] and GetTime() - recentDuels[source] < Heimdall_Data.config.deathReporter.duelThrottle then
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Ignoring death report - Recent duel detected for source: %s", ModuleName,
|
||||||
|
source))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if Heimdall_Data.config.deathReporter.debug then
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
print(
|
print(string.format("[%s] Recording death for %s", ModuleName, destination))
|
||||||
string.format(
|
|
||||||
"[%s] Module initialized with throttle: %.1fs, duel throttle: %.1fs",
|
|
||||||
ModuleName,
|
|
||||||
Heimdall_Data.config.deathReporter.throttle,
|
|
||||||
Heimdall_Data.config.deathReporter.duelThrottle
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
recentDeaths[destination] = GetTime()
|
||||||
end,
|
|
||||||
}
|
C_Timer.NewTimer(3, function()
|
||||||
|
if recentDuels[destination] and GetTime() - recentDuels[destination] < Heimdall_Data.config.deathReporter.duelThrottle then
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Cancelling delayed death report - Recent duel detected for: %s", ModuleName,
|
||||||
|
destination))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if recentDuels[source] and GetTime() - recentDuels[source] < Heimdall_Data.config.deathReporter.duelThrottle then
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Cancelling delayed death report - Recent duel detected for: %s", ModuleName,
|
||||||
|
source))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Sending death report - %s killed %s with %s",
|
||||||
|
ModuleName, source, destination, spellName))
|
||||||
|
end
|
||||||
|
|
||||||
|
local zone, subzone = GetZoneText() or "Unknown", GetSubZoneText() or "Unknown"
|
||||||
|
if Heimdall_Data.config.spotter.zoneOverride then
|
||||||
|
zone = Heimdall_Data.config.spotter.zoneOverride or ""
|
||||||
|
subzone = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local x, y = GetPlayerMapPosition("player")
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Player coordinates: %.2f, %.2f", ModuleName, x * 100, y * 100))
|
||||||
|
end
|
||||||
|
SetMapToCurrentZone()
|
||||||
|
SetMapByID(GetCurrentMapAreaID())
|
||||||
|
local zoneId = GetCurrentMapAreaID()
|
||||||
|
|
||||||
|
for _, channel in pairs(Heimdall_Data.config.deathReporter.channels) do
|
||||||
|
local locale = shared.GetLocaleForChannel(channel)
|
||||||
|
local text = string.format(shared._L("killed", locale),
|
||||||
|
source,
|
||||||
|
destination,
|
||||||
|
shared._L(spellName, locale),
|
||||||
|
shared._L(zone, locale), shared._L(subzone, locale),
|
||||||
|
zoneId,
|
||||||
|
x * 100, y * 100)
|
||||||
|
---@type Message
|
||||||
|
local msg = {
|
||||||
|
channel = "C",
|
||||||
|
data = channel,
|
||||||
|
message = text
|
||||||
|
}
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Queuing death report message", ModuleName))
|
||||||
|
shared.dumpTable(msg)
|
||||||
|
end
|
||||||
|
table.insert(shared.messenger.queue, msg)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local cleuFrame = CreateFrame("Frame")
|
||||||
|
cleuFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||||
|
cleuFrame:SetScript("OnEvent", function(self, event, ...)
|
||||||
|
-- if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
-- print(string.format("[%s] Received combat log event", ModuleName))
|
||||||
|
-- end
|
||||||
|
if not Heimdall_Data.config.deathReporter.enabled then return end
|
||||||
|
local overkill, err = CLEUParser.GetOverkill(...)
|
||||||
|
if not err and overkill > 0 then
|
||||||
|
local source, err = CLEUParser.GetSourceName(...)
|
||||||
|
if err then
|
||||||
|
source = "unknown"
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Error getting source name", ModuleName))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local destination, err = CLEUParser.GetDestName(...)
|
||||||
|
if err then
|
||||||
|
destination = "unknown"
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Error getting destination name", ModuleName))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local spellName, err = CLEUParser.GetSpellName(...)
|
||||||
|
if err then
|
||||||
|
spellName = "unknown"
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Error getting spell name", ModuleName))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local sourceGUID, err = CLEUParser.GetSourceGUID(...)
|
||||||
|
if err or not string.match(sourceGUID, "Player") then return end
|
||||||
|
local destinationGUID, err = CLEUParser.GetDestGUID(...)
|
||||||
|
if err or not string.match(destinationGUID, "Player") then return end
|
||||||
|
RegisterDeath(source, destination, spellName)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
local systemMessageFrame = CreateFrame("Frame")
|
||||||
|
systemMessageFrame:RegisterEvent("CHAT_MSG_SYSTEM")
|
||||||
|
systemMessageFrame:SetScript("OnEvent", function(self, event, msg)
|
||||||
|
if not Heimdall_Data.config.deathReporter.enabled then return end
|
||||||
|
local source, destination = string.match(msg, "([^ ]+) has defeated ([^ ]+) in a duel")
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Received system message: %s", ModuleName, msg))
|
||||||
|
print(string.format("[%s] Source: %s, Destination: %s", ModuleName, tostring(source), tostring(destination)))
|
||||||
|
end
|
||||||
|
if not source or not destination then return end
|
||||||
|
source = string.match(source, "([^-]+)")
|
||||||
|
destination = string.match(destination, "([^-]+)")
|
||||||
|
if source and destination then
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Detected duel between %s and %s", ModuleName, source, destination))
|
||||||
|
end
|
||||||
|
local now = GetTime()
|
||||||
|
recentDuels[source] = now
|
||||||
|
recentDuels[destination] = now
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
if Heimdall_Data.config.deathReporter.debug then
|
||||||
|
print(string.format("[%s] Module initialized with throttle: %.1fs, duel throttle: %.1fs",
|
||||||
|
ModuleName, Heimdall_Data.config.deathReporter.throttle, Heimdall_Data.config.deathReporter.duelThrottle))
|
||||||
|
end
|
||||||
|
print("[Heimdall] DeathReporter loaded")
|
||||||
|
end
|
||||||
|
@@ -1,63 +1,51 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Dueler"
|
local ModuleName = "Dueler"
|
||||||
|
|
||||||
---@class HeimdallDuelerConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Dueler = {}
|
||||||
---@field debug boolean
|
function shared.Dueler.Init()
|
||||||
---@field declineOther boolean
|
local frame = CreateFrame("Frame")
|
||||||
|
frame:RegisterEvent("DUEL_REQUESTED")
|
||||||
---@class Dueler
|
frame:SetScript("OnEvent", function(self, event, sender)
|
||||||
shared.Dueler = {
|
if Heimdall_Data.config.dueler.debug then
|
||||||
Init = function()
|
print(string.format("[%s] Duel request received from: %s", ModuleName, sender))
|
||||||
local frame = CreateFrame("Frame")
|
end
|
||||||
frame:RegisterEvent("DUEL_REQUESTED")
|
if not Heimdall_Data.config.dueler.enabled then
|
||||||
frame:SetScript("OnEvent", function(self, event, sender)
|
|
||||||
if Heimdall_Data.config.dueler.debug then
|
if Heimdall_Data.config.dueler.debug then
|
||||||
print(string.format("[%s] Duel request received from: %s", ModuleName, sender))
|
print(string.format("[%s] Module disabled, ignoring duel request", ModuleName))
|
||||||
end
|
end
|
||||||
if not Heimdall_Data.config.dueler.enabled then
|
return
|
||||||
if Heimdall_Data.config.dueler.debug then
|
end
|
||||||
print(string.format("[%s] Module disabled, ignoring duel request", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.dueler.debug then
|
|
||||||
print(string.format("[%s] Checking if sender '%s' is in agents list", ModuleName, sender))
|
|
||||||
end
|
|
||||||
|
|
||||||
local allow = shared.AgentTracker.IsAgent(sender)
|
|
||||||
if allow then
|
|
||||||
if Heimdall_Data.config.dueler.debug then
|
|
||||||
print(string.format("[%s] Accepting duel from trusted agent: %s", ModuleName, sender))
|
|
||||||
end
|
|
||||||
AcceptDuel()
|
|
||||||
else
|
|
||||||
if Heimdall_Data.config.dueler.declineOther then
|
|
||||||
if Heimdall_Data.config.dueler.debug then
|
|
||||||
print(string.format("[%s] Auto-declining duel from untrusted sender: %s", ModuleName, sender))
|
|
||||||
end
|
|
||||||
CancelDuel()
|
|
||||||
else
|
|
||||||
if Heimdall_Data.config.dueler.debug then
|
|
||||||
print(
|
|
||||||
string.format("[%s] Leaving duel request from %s for manual response", ModuleName, sender)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
if Heimdall_Data.config.dueler.debug then
|
if Heimdall_Data.config.dueler.debug then
|
||||||
print(
|
print(string.format("[%s] Checking if sender '%s' is in agents list", ModuleName, sender))
|
||||||
string.format(
|
|
||||||
"[%s] Module initialized with auto-decline: %s",
|
|
||||||
ModuleName,
|
|
||||||
tostring(Heimdall_Data.config.dueler.declineOther)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
|
||||||
end,
|
local allow = Heimdall_Data.config.agents[sender]
|
||||||
}
|
if allow then
|
||||||
|
if Heimdall_Data.config.dueler.debug then
|
||||||
|
print(string.format("[%s] Accepting duel from trusted agent: %s", ModuleName, sender))
|
||||||
|
end
|
||||||
|
AcceptDuel()
|
||||||
|
else
|
||||||
|
if Heimdall_Data.config.dueler.declineOther then
|
||||||
|
if Heimdall_Data.config.dueler.debug then
|
||||||
|
print(string.format("[%s] Auto-declining duel from untrusted sender: %s", ModuleName, sender))
|
||||||
|
end
|
||||||
|
CancelDuel()
|
||||||
|
else
|
||||||
|
if Heimdall_Data.config.dueler.debug then
|
||||||
|
print(string.format("[%s] Leaving duel request from %s for manual response", ModuleName, sender))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
if Heimdall_Data.config.dueler.debug then
|
||||||
|
print(string.format("[%s] Module initialized with auto-decline: %s", ModuleName,
|
||||||
|
tostring(Heimdall_Data.config.dueler.declineOther)))
|
||||||
|
end
|
||||||
|
print("[Heimdall] Dueler loaded")
|
||||||
|
end
|
||||||
|
@@ -1,31 +1,28 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
|
|
||||||
if not shared.dump then
|
if not shared.dumpTable then
|
||||||
---@param value any
|
---@param table table
|
||||||
---@param msg string?
|
|
||||||
---@param depth number?
|
---@param depth number?
|
||||||
shared.dump = function(value, msg, depth)
|
shared.dumpTable = function(table, depth)
|
||||||
if not value then
|
if not table then
|
||||||
print(tostring(value))
|
print(tostring(table))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if type(value) ~= "table" then
|
if depth == nil then
|
||||||
print(tostring(value))
|
depth = 0
|
||||||
|
end
|
||||||
|
if (depth > 200) then
|
||||||
|
print("Error: Depth > 200 in dumpTable()")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if msg then print(msg) end
|
for k, v in pairs(table) do
|
||||||
if depth == nil then depth = 0 end
|
if (type(v) == "table") then
|
||||||
if depth > 200 then
|
print(string.rep(" ", depth) .. k .. ":")
|
||||||
print("Error: Depth > 200 in dump()")
|
shared.dumpTable(v, depth + 1)
|
||||||
return
|
|
||||||
end
|
|
||||||
for k, v in pairs(value) do
|
|
||||||
if type(v) == "table" then
|
|
||||||
print(string.rep(" ", depth) .. tostring(k) .. ":")
|
|
||||||
shared.dump(v, msg, depth + 1)
|
|
||||||
else
|
else
|
||||||
print(string.rep(" ", depth) .. tostring(k) .. ": " .. tostring(v))
|
print(string.rep(" ", depth) .. k .. ": ", v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@@ -1,65 +1,61 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Echoer"
|
local ModuleName = "Echoer"
|
||||||
|
|
||||||
---@class HeimdallEchoerConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Echoer = {}
|
||||||
---@field debug boolean
|
function shared.Echoer.Init()
|
||||||
---@field channels string[]
|
local frame = CreateFrame("Frame")
|
||||||
---@field prefix string
|
frame:RegisterEvent("CHAT_MSG_CHANNEL")
|
||||||
|
frame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
||||||
|
--if Heimdall_Data.config.echoer.debug then
|
||||||
|
-- print(string.format("[%s] Channel message received from: %s", ModuleName, sender))
|
||||||
|
--end
|
||||||
|
|
||||||
---@class Echoer
|
if not Heimdall_Data.config.echoer.enabled then
|
||||||
shared.Echoer = {
|
|
||||||
Init = function()
|
|
||||||
local frame = CreateFrame("Frame")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_CHANNEL")
|
|
||||||
frame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
|
||||||
--if Heimdall_Data.config.echoer.debug then
|
--if Heimdall_Data.config.echoer.debug then
|
||||||
-- print(string.format("[%s] Channel message received from: %s", ModuleName, sender))
|
-- print(string.format("[%s] Module disabled, ignoring message", ModuleName))
|
||||||
--end
|
--end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if not Heimdall_Data.config.echoer.enabled then
|
local channelId = select(6, ...)
|
||||||
--if Heimdall_Data.config.echoer.debug then
|
local _, channelname = GetChannelName(channelId)
|
||||||
-- print(string.format("[%s] Module disabled, ignoring message", ModuleName))
|
local ok = false
|
||||||
--end
|
for _, channel in pairs(Heimdall_Data.config.echoer.channels) do
|
||||||
return
|
if channel == channelname then
|
||||||
end
|
ok = true
|
||||||
|
break
|
||||||
local channelId = select(6, ...)
|
|
||||||
local _, channelname = GetChannelName(channelId)
|
|
||||||
local ok = false
|
|
||||||
for _, channel in pairs(Heimdall_Data.config.echoer.channels) do
|
|
||||||
if channel == channelname then
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not ok then
|
|
||||||
if Heimdall_Data.config.echoer.debug then
|
|
||||||
print(string.format("[%s] Channel name does not match any of the channels", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
if not ok then
|
||||||
if Heimdall_Data.config.echoer.debug then
|
if Heimdall_Data.config.echoer.debug then
|
||||||
print(string.format("[%s] Processing message from master channel: %s", ModuleName, sender))
|
print(string.format("[%s] Channel name does not match any of the channels", ModuleName))
|
||||||
shared.dump(Heimdall_Data.config.echoer)
|
|
||||||
end
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if Heimdall_Data.config.echoer.debug then
|
||||||
|
print(string.format("[%s] Processing message from master channel: %s", ModuleName, sender))
|
||||||
|
shared.dumpTable(Heimdall_Data.config.echoer)
|
||||||
|
end
|
||||||
|
|
||||||
if string.find(msg, "^" .. Heimdall_Data.config.echoer.prefix) then
|
if string.find(msg, "^" .. Heimdall_Data.config.echoer.prefix) then
|
||||||
if Heimdall_Data.config.echoer.debug then
|
if Heimdall_Data.config.echoer.debug then
|
||||||
print(string.format("[%s] Found echo command in message: %s", ModuleName, msg))
|
print(string.format("[%s] Found echo command in message: %s", ModuleName, msg))
|
||||||
end
|
|
||||||
local echomsg = string.sub(msg, string.len(Heimdall_Data.config.echoer.prefix) + 1)
|
|
||||||
if Heimdall_Data.config.echoer.debug then
|
|
||||||
print(string.format("[%s] Echoing message: %s", ModuleName, echomsg))
|
|
||||||
end
|
|
||||||
SendChatMessage(echomsg, "SAY")
|
|
||||||
elseif Heimdall_Data.config.echoer.debug then
|
|
||||||
print(string.format("[%s] Message does not start with echo prefix", ModuleName))
|
|
||||||
end
|
end
|
||||||
end)
|
local msg = string.sub(msg, string.len(Heimdall_Data.config.echoer.prefix) + 1)
|
||||||
|
if Heimdall_Data.config.echoer.debug then
|
||||||
|
print(string.format("[%s] Echoing message: %s", ModuleName, msg))
|
||||||
|
end
|
||||||
|
SendChatMessage(msg, "SAY")
|
||||||
|
elseif Heimdall_Data.config.echoer.debug then
|
||||||
|
print(string.format("[%s] Message does not start with echo prefix", ModuleName))
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
if Heimdall_Data.config.echoer.debug then print(string.format("[%s] Module initialized", ModuleName)) end
|
if Heimdall_Data.config.echoer.debug then
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Module initialized", ModuleName))
|
||||||
end,
|
end
|
||||||
}
|
print("[Heimdall] Echoer loaded")
|
||||||
|
end
|
||||||
|
@@ -1,66 +1,62 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Emoter"
|
local ModuleName = "Emoter"
|
||||||
|
|
||||||
---@class HeimdallEmoterConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Emoter = {}
|
||||||
---@field debug boolean
|
function shared.Emoter.Init()
|
||||||
---@field channels string[]
|
local frame = CreateFrame("Frame")
|
||||||
---@field prefix string
|
frame:RegisterEvent("CHAT_MSG_CHANNEL")
|
||||||
|
frame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
||||||
|
--if Heimdall_Data.config.emoter.debug then
|
||||||
|
-- print(string.format("[%s] Channel message received from: %s", ModuleName, sender))
|
||||||
|
--end
|
||||||
|
|
||||||
---@class Emoter
|
if not Heimdall_Data.config.emoter.enabled then
|
||||||
shared.Emoter = {
|
|
||||||
Init = function()
|
|
||||||
local frame = CreateFrame("Frame")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_CHANNEL")
|
|
||||||
frame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
|
||||||
--if Heimdall_Data.config.emoter.debug then
|
--if Heimdall_Data.config.emoter.debug then
|
||||||
-- print(string.format("[%s] Channel message received from: %s", ModuleName, sender))
|
-- print(string.format("[%s] Module disabled, ignoring message", ModuleName))
|
||||||
--end
|
--end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if not Heimdall_Data.config.emoter.enabled then
|
local channelId = select(6, ...)
|
||||||
--if Heimdall_Data.config.emoter.debug then
|
local _, channelname = GetChannelName(channelId)
|
||||||
-- print(string.format("[%s] Module disabled, ignoring message", ModuleName))
|
local ok = false
|
||||||
--end
|
for _, channel in pairs(Heimdall_Data.config.emoter.channels) do
|
||||||
return
|
if channel == channelname then
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
end
|
end
|
||||||
|
end
|
||||||
local channelId = select(6, ...)
|
if not ok then
|
||||||
local _, channelname = GetChannelName(channelId)
|
|
||||||
local ok = false
|
|
||||||
for _, channel in pairs(Heimdall_Data.config.emoter.channels) do
|
|
||||||
if channel == channelname then
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not ok then
|
|
||||||
if Heimdall_Data.config.emoter.debug then
|
|
||||||
print(string.format("[%s] Channel name does not match any of the channels", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.emoter.debug then
|
if Heimdall_Data.config.emoter.debug then
|
||||||
print(string.format("[%s] Processing message from master channel: %s", ModuleName, sender))
|
print(string.format("[%s] Channel name does not match any of the channels", ModuleName))
|
||||||
shared.dump(Heimdall_Data.config.emoter)
|
|
||||||
end
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if string.find(msg, "^" .. Heimdall_Data.config.emoter.prefix) then
|
if Heimdall_Data.config.emoter.debug then
|
||||||
if Heimdall_Data.config.emoter.debug then
|
print(string.format("[%s] Processing message from master channel: %s", ModuleName, sender))
|
||||||
print(string.format("[%s] Found emote command in message: %s", ModuleName, msg))
|
shared.dumpTable(Heimdall_Data.config.emoter)
|
||||||
end
|
end
|
||||||
local emote = string.sub(msg, string.len(Heimdall_Data.config.emoter.prefix) + 1)
|
|
||||||
if Heimdall_Data.config.emoter.debug then
|
if string.find(msg, "^" .. Heimdall_Data.config.emoter.prefix) then
|
||||||
print(string.format("[%s] Performing emote: %s", ModuleName, emote))
|
if Heimdall_Data.config.emoter.debug then
|
||||||
end
|
print(string.format("[%s] Found emote command in message: %s", ModuleName, msg))
|
||||||
DoEmote(emote)
|
|
||||||
elseif Heimdall_Data.config.emoter.debug then
|
|
||||||
print(string.format("[%s] Message does not start with emote prefix", ModuleName))
|
|
||||||
end
|
end
|
||||||
end)
|
local emote = string.sub(msg, string.len(Heimdall_Data.config.emoter.prefix) + 1)
|
||||||
|
if Heimdall_Data.config.emoter.debug then
|
||||||
|
print(string.format("[%s] Performing emote: %s", ModuleName, emote))
|
||||||
|
end
|
||||||
|
DoEmote(emote)
|
||||||
|
elseif Heimdall_Data.config.emoter.debug then
|
||||||
|
print(string.format("[%s] Message does not start with emote prefix", ModuleName))
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
if Heimdall_Data.config.emoter.debug then print(string.format("[%s] Module initialized", ModuleName)) end
|
if Heimdall_Data.config.emoter.debug then
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Module initialized", ModuleName))
|
||||||
end,
|
end
|
||||||
}
|
print("[Heimdall] Emoter loaded")
|
||||||
|
end
|
||||||
|
@@ -1,275 +1,249 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Inviter"
|
local ModuleName = "Inviter"
|
||||||
|
|
||||||
---@class HeimdallInviterConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Inviter = {}
|
||||||
---@field debug boolean
|
function shared.Inviter.Init()
|
||||||
---@field channels string[]
|
if type(Heimdall_Data.config.inviter.listeningChannel) == "string" then
|
||||||
---@field keyword string
|
Heimdall_Data.config.inviter.listeningChannel = {
|
||||||
---@field allAssist boolean
|
[Heimdall_Data.config.inviter.listeningChannel] = true
|
||||||
---@field agentsAssist boolean
|
}
|
||||||
---@field throttle number
|
end
|
||||||
---@field kickOffline boolean
|
---@type Timer
|
||||||
---@field cleanupInterval number
|
local updateTimer = nil
|
||||||
---@field afkThreshold number
|
|
||||||
---@field listeningChannel table<string, boolean>
|
|
||||||
|
|
||||||
---@class Inviter
|
local function FixGroup()
|
||||||
shared.Inviter = {
|
if Heimdall_Data.config.inviter.debug then
|
||||||
Init = function()
|
print(string.format("[%s] Checking and fixing group configuration", ModuleName))
|
||||||
-- Fallback for old config
|
|
||||||
if type(Heimdall_Data.config.inviter.listeningChannel) == "string" then
|
|
||||||
Heimdall_Data.config.inviter.listeningChannel = {
|
|
||||||
[Heimdall_Data.config.inviter.listeningChannel] = true,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
---@type Timer
|
|
||||||
local updateTimer = nil
|
|
||||||
|
|
||||||
local function FixGroup()
|
if not IsInRaid() then
|
||||||
if Heimdall_Data.config.inviter.debug then
|
if Heimdall_Data.config.inviter.debug then
|
||||||
print(string.format("[%s] Checking and fixing group configuration", ModuleName))
|
print(string.format("[%s] Converting party to raid", ModuleName))
|
||||||
|
end
|
||||||
|
ConvertToRaid()
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.inviter.allAssist then
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] Setting all members to assistant", ModuleName))
|
||||||
|
end
|
||||||
|
SetEveryoneIsAssistant()
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.inviter.agentsAssist then
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
local agentCount = 0
|
||||||
|
for _ in pairs(Heimdall_Data.config.agents) do agentCount = agentCount + 1 end
|
||||||
|
print(string.format("[%s] Processing %d agents for assistant promotion", ModuleName, agentCount))
|
||||||
end
|
end
|
||||||
|
|
||||||
if not IsInRaid() then
|
for name, _ in pairs(Heimdall_Data.config.agents) do
|
||||||
if Heimdall_Data.config.inviter.debug then
|
if UnitInParty(name) and not UnitIsGroupLeader(name) and not UnitIsRaidOfficer(name) then
|
||||||
print(string.format("[%s] Converting party to raid", ModuleName))
|
if Heimdall_Data.config.inviter.debug then
|
||||||
end
|
print(string.format("[%s] Promoting agent to assistant: %s", ModuleName, name))
|
||||||
ConvertToRaid()
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.inviter.allAssist then
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Setting all members to assistant", ModuleName))
|
|
||||||
end
|
|
||||||
SetEveryoneIsAssistant()
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.inviter.agentsAssist then
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Processing agents for assistant promotion", ModuleName))
|
|
||||||
end
|
|
||||||
|
|
||||||
shared.AgentTracker.ForEach(function(agent)
|
|
||||||
if UnitInParty(agent) and not UnitIsGroupLeader(agent) and not UnitIsRaidOfficer(agent) then
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Promoting agent to assistant: %s", ModuleName, agent))
|
|
||||||
end
|
|
||||||
PromoteToAssistant(agent, true)
|
|
||||||
elseif Heimdall_Data.config.inviter.debug then
|
|
||||||
if not UnitInParty(agent) then
|
|
||||||
print(string.format("[%s] Agent not in party: %s", ModuleName, agent))
|
|
||||||
elseif UnitIsGroupLeader(agent) then
|
|
||||||
print(string.format("[%s] Agent is already leader: %s", ModuleName, agent))
|
|
||||||
elseif UnitIsRaidOfficer(agent) then
|
|
||||||
print(string.format("[%s] Agent is already assistant: %s", ModuleName, agent))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
PromoteToAssistant(name, true)
|
||||||
|
elseif Heimdall_Data.config.inviter.debug then
|
||||||
|
if not UnitInParty(name) then
|
||||||
|
print(string.format("[%s] Agent not in party: %s", ModuleName, name))
|
||||||
|
elseif UnitIsGroupLeader(name) then
|
||||||
|
print(string.format("[%s] Agent is already leader: %s", ModuleName, name))
|
||||||
|
elseif UnitIsRaidOfficer(name) then
|
||||||
|
print(string.format("[%s] Agent is already assistant: %s", ModuleName, name))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] Group configuration update complete", ModuleName))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param name string
|
||||||
|
---@return Frame?
|
||||||
|
local function FindPlayerRaidFrame(name)
|
||||||
|
for group = 1, 8 do
|
||||||
|
for player = 1, 5 do
|
||||||
|
local button = _G[string.format("ElvUF_RaidGroup%dUnitButton%d", group, player)]
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] button = %s", ModuleName, tostring(button)))
|
||||||
|
end
|
||||||
|
|
||||||
|
local unitName = button and button.unit and UnitName(button.unit)
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] unitName = %s", ModuleName, tostring(unitName)))
|
||||||
|
end
|
||||||
|
if unitName == name then
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] unitName == name", ModuleName))
|
||||||
|
end
|
||||||
|
return button
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local framePool = {}
|
||||||
|
local playerButtons = {}
|
||||||
|
setmetatable(playerButtons, { __mode = "kv" })
|
||||||
|
---@param players string[]
|
||||||
|
local function OverlayKickButtons(players)
|
||||||
|
for _, frame in pairs(framePool) do
|
||||||
|
frame:Hide()
|
||||||
|
end
|
||||||
|
for _, name in pairs(players) do
|
||||||
|
local frame = FindPlayerRaidFrame(name)
|
||||||
|
if frame then
|
||||||
|
playerButtons[name] = frame
|
||||||
|
local button = framePool[frame.unit] or CreateFrame("Button",
|
||||||
|
string.format("HeimdallKickButton%s", frame.unit, frame, "SecureActionButtonTemplate"))
|
||||||
|
framePool[frame.unit] = button
|
||||||
|
|
||||||
|
button:SetSize(frame.UNIT_WIDTH / 2, frame.UNIT_HEIGHT / 2)
|
||||||
|
button:SetPoint("CENTER", frame, "CENTER", 0, 0)
|
||||||
|
button:SetNormalTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon")
|
||||||
|
button:SetHighlightTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon")
|
||||||
|
button:SetPushedTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon")
|
||||||
|
button:SetDisabledTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon")
|
||||||
|
button:SetAlpha(0.5)
|
||||||
|
button:Show()
|
||||||
|
button:SetScript("OnClick", function()
|
||||||
|
UninviteUnit(name)
|
||||||
|
button:Hide()
|
||||||
end)
|
end)
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Group configuration update complete", ModuleName))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param name string
|
|
||||||
---@return Frame?
|
|
||||||
local function FindPlayerRaidFrame(name)
|
|
||||||
for group = 1, 8 do
|
|
||||||
for player = 1, 5 do
|
|
||||||
local button = _G[string.format("ElvUF_RaidGroup%dUnitButton%d", group, player)]
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] button = %s", ModuleName, tostring(button)))
|
|
||||||
end
|
|
||||||
|
|
||||||
local unitName = button and button.unit and UnitName(button.unit)
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] unitName = %s", ModuleName, tostring(unitName)))
|
|
||||||
end
|
|
||||||
if unitName == name then
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] unitName == name", ModuleName))
|
|
||||||
end
|
|
||||||
return button
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local framePool = {}
|
|
||||||
local playerButtons = {}
|
|
||||||
setmetatable(playerButtons, { __mode = "kv" })
|
|
||||||
---@param players string[]
|
|
||||||
local function OverlayKickButtons(players)
|
|
||||||
for _, frame in pairs(framePool) do
|
|
||||||
frame:Hide()
|
|
||||||
end
|
|
||||||
for _, name in pairs(players) do
|
|
||||||
local frame = FindPlayerRaidFrame(name)
|
|
||||||
if frame then
|
|
||||||
playerButtons[name] = frame
|
|
||||||
-- All of these are ELVUI specific so they won't be in our meta...
|
|
||||||
---@diagnostic disable-next-line: undefined-field
|
|
||||||
local button = framePool[frame.unit]
|
|
||||||
or CreateFrame(
|
|
||||||
"Button",
|
|
||||||
---@diagnostic disable-next-line: undefined-field
|
|
||||||
string.format("HeimdallKickButton%s", frame.unit, frame, "SecureActionButtonTemplate")
|
|
||||||
)
|
|
||||||
---@diagnostic disable-next-line: undefined-field
|
|
||||||
framePool[frame.unit] = button
|
|
||||||
|
|
||||||
---@diagnostic disable-next-line: undefined-field
|
|
||||||
button:SetSize(frame.UNIT_WIDTH / 2, frame.UNIT_HEIGHT / 2)
|
|
||||||
button:SetPoint("CENTER", frame, "CENTER", 0, 0)
|
|
||||||
button:SetNormalTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon")
|
|
||||||
button:SetHighlightTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon")
|
|
||||||
button:SetPushedTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon")
|
|
||||||
button:SetDisabledTexture("Interface\\Buttons\\UI-GroupLoot-KickIcon")
|
|
||||||
button:SetAlpha(0.5)
|
|
||||||
button:Show()
|
|
||||||
button:SetScript("OnClick", function()
|
|
||||||
UninviteUnit(name)
|
|
||||||
button:Hide()
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Frame for player %s not found", ModuleName, name))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@type table<string, number>
|
|
||||||
local groupMembers = {}
|
|
||||||
local function CleanGroups()
|
|
||||||
if not Heimdall_Data.config.inviter.kickOffline then return end
|
|
||||||
print("Cleaning groups")
|
|
||||||
local now = GetTime()
|
|
||||||
for i = 1, 40 do
|
|
||||||
local unit = "raid" .. i
|
|
||||||
if UnitExists(unit) then
|
|
||||||
local name = UnitName(unit)
|
|
||||||
if name then
|
|
||||||
-- When we load (into game) we want to consider everyone "online"
|
|
||||||
-- In other words everyone we haven't seen before is "online" the first time we see them
|
|
||||||
-- This is to avoid kicking people who might not be offline which we don't know because we just logged in
|
|
||||||
if not groupMembers[name] then
|
|
||||||
groupMembers[name] = now
|
|
||||||
else
|
|
||||||
local online = UnitIsConnected(unit)
|
|
||||||
if online then groupMembers[name] = now end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local afkPlayers = {}
|
|
||||||
for name, time in pairs(groupMembers) do
|
|
||||||
if not UnitInParty(name) then
|
|
||||||
print(string.format("%s no longer in party", name))
|
|
||||||
groupMembers[name] = nil
|
|
||||||
else
|
|
||||||
if time < now - Heimdall_Data.config.inviter.afkThreshold then
|
|
||||||
print(string.format("Kicking %s for being offline", name))
|
|
||||||
afkPlayers[#afkPlayers + 1] = name
|
|
||||||
-- Blyat this is protected...
|
|
||||||
-- UninviteUnit(name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
OverlayKickButtons(afkPlayers)
|
|
||||||
end
|
|
||||||
local function Tick()
|
|
||||||
CleanGroups()
|
|
||||||
C_Timer.NewTimer(Heimdall_Data.config.inviter.cleanupInterval, Tick, 1)
|
|
||||||
end
|
|
||||||
Tick()
|
|
||||||
|
|
||||||
local groupRosterUpdateFrame = CreateFrame("Frame")
|
|
||||||
groupRosterUpdateFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
|
|
||||||
groupRosterUpdateFrame:SetScript("OnEvent", function(self, event, ...)
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Event received: %s", ModuleName, event))
|
|
||||||
end
|
|
||||||
|
|
||||||
if not Heimdall_Data.config.inviter.enabled then
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Group roster changed - Checking configuration", ModuleName))
|
|
||||||
end
|
|
||||||
if updateTimer then updateTimer:Cancel() end
|
|
||||||
updateTimer = C_Timer.NewTimer(Heimdall_Data.config.inviter.throttle, FixGroup)
|
|
||||||
end)
|
|
||||||
|
|
||||||
local inviterChannelFrame = CreateFrame("Frame")
|
|
||||||
inviterChannelFrame:RegisterEvent("CHAT_MSG_CHANNEL")
|
|
||||||
inviterChannelFrame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
|
||||||
--if Heimdall_Data.config.inviter.debug then
|
|
||||||
-- print(string.format("[%s] Chat message received: %s", ModuleName, msg))
|
|
||||||
-- shared.dump(Heimdall_Data.config.inviter)
|
|
||||||
--end
|
|
||||||
if not Heimdall_Data.config.inviter.enabled then return end
|
|
||||||
local channelId = select(6, ...)
|
|
||||||
local _, channelname = GetChannelName(channelId)
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Channel name: %s", ModuleName, channelname))
|
|
||||||
end
|
|
||||||
|
|
||||||
local ok = false
|
|
||||||
for _, channel in pairs(Heimdall_Data.config.inviter.channels) do
|
|
||||||
if channel == channelname then
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not ok then
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Channel name does not match any of the channels", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if msg == Heimdall_Data.config.inviter.keyword then
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
|
||||||
print(string.format("[%s] Inviting %s", ModuleName, sender))
|
|
||||||
end
|
|
||||||
InviteUnit(sender)
|
|
||||||
else
|
else
|
||||||
if Heimdall_Data.config.inviter.debug then
|
if Heimdall_Data.config.inviter.debug then
|
||||||
print(string.format("[%s] Message does not match keyword", ModuleName))
|
print(string.format("[%s] Frame for player %s not found", ModuleName, name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@type table<string, number>
|
||||||
|
local groupMembers = {}
|
||||||
|
local function CleanGroups()
|
||||||
|
if not Heimdall_Data.config.inviter.kickOffline then return end
|
||||||
|
print("Cleaning groups")
|
||||||
|
local now = GetTime()
|
||||||
|
for i = 1, 40 do
|
||||||
|
local unit = "raid" .. i
|
||||||
|
if UnitExists(unit) then
|
||||||
|
local name = UnitName(unit)
|
||||||
|
if name then
|
||||||
|
-- When we load (into game) we want to consider everyone "online"
|
||||||
|
-- In other words everyone we haven't seen before is "online" the first time we see them
|
||||||
|
-- This is to avoid kicking people who might not be offline which we don't know because we just logged in
|
||||||
|
if not groupMembers[name] then
|
||||||
|
groupMembers[name] = now
|
||||||
|
else
|
||||||
|
local online = UnitIsConnected(unit)
|
||||||
|
if online then
|
||||||
|
groupMembers[name] = now
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local afkPlayers = {}
|
||||||
|
for name, time in pairs(groupMembers) do
|
||||||
|
if not UnitInParty(name) then
|
||||||
|
print(string.format("%s no longer in party", name))
|
||||||
|
groupMembers[name] = nil
|
||||||
|
else
|
||||||
|
if time < now - Heimdall_Data.config.inviter.afkThreshold then
|
||||||
|
print(string.format("Kicking %s for being offline", name))
|
||||||
|
afkPlayers[#afkPlayers + 1] = name
|
||||||
|
-- Blyat this is protected...
|
||||||
|
-- UninviteUnit(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
OverlayKickButtons(afkPlayers)
|
||||||
|
end
|
||||||
|
local function Tick()
|
||||||
|
CleanGroups()
|
||||||
|
C_Timer.NewTimer(Heimdall_Data.config.inviter.cleanupInterval, Tick, 1)
|
||||||
|
end
|
||||||
|
Tick()
|
||||||
|
|
||||||
|
local groupRosterUpdateFrame = CreateFrame("Frame")
|
||||||
|
groupRosterUpdateFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
|
||||||
|
groupRosterUpdateFrame:SetScript("OnEvent", function(self, event, ...)
|
||||||
if Heimdall_Data.config.inviter.debug then
|
if Heimdall_Data.config.inviter.debug then
|
||||||
print(
|
print(string.format("[%s] Event received: %s", ModuleName, event))
|
||||||
string.format(
|
end
|
||||||
"[%s] Module initialized - All assist: %s, Agents assist: %s",
|
|
||||||
ModuleName,
|
if not Heimdall_Data.config.inviter.enabled then
|
||||||
tostring(Heimdall_Data.config.inviter.allAssist),
|
if Heimdall_Data.config.inviter.debug then
|
||||||
tostring(Heimdall_Data.config.inviter.agentsAssist)
|
print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
||||||
)
|
end
|
||||||
)
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if Heimdall_Data.config.inviter.debug then
|
if Heimdall_Data.config.inviter.debug then
|
||||||
print(
|
print(string.format("[%s] Group roster changed - Checking configuration", ModuleName))
|
||||||
string.format(
|
|
||||||
"[%s] Module initialized - All assist: %s, Agents assist: %s",
|
|
||||||
ModuleName,
|
|
||||||
tostring(Heimdall_Data.config.inviter.allAssist),
|
|
||||||
tostring(Heimdall_Data.config.inviter.agentsAssist)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
if updateTimer then updateTimer:Cancel() end
|
||||||
end,
|
updateTimer = C_Timer.NewTimer(Heimdall_Data.config.inviter.throttle, FixGroup)
|
||||||
}
|
end)
|
||||||
|
|
||||||
|
local inviterChannelFrame = CreateFrame("Frame")
|
||||||
|
inviterChannelFrame:RegisterEvent("CHAT_MSG_CHANNEL")
|
||||||
|
inviterChannelFrame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
||||||
|
--if Heimdall_Data.config.inviter.debug then
|
||||||
|
-- print(string.format("[%s] Chat message received: %s", ModuleName, msg))
|
||||||
|
-- shared.dumpTable(Heimdall_Data.config.inviter)
|
||||||
|
--end
|
||||||
|
if not Heimdall_Data.config.inviter.enabled then return end
|
||||||
|
local channelId = select(6, ...)
|
||||||
|
local _, channelname = GetChannelName(channelId)
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] Channel name: %s", ModuleName, channelname))
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok = false
|
||||||
|
for _, channel in pairs(Heimdall_Data.config.inviter.channels) do
|
||||||
|
if channel == channelname then
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] Channel name does not match any of the channels", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if msg == Heimdall_Data.config.inviter.keyword then
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] Inviting %s", ModuleName, sender))
|
||||||
|
end
|
||||||
|
InviteUnit(sender)
|
||||||
|
else
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] Message does not match keyword", ModuleName))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] Module initialized - All assist: %s, Agents assist: %s",
|
||||||
|
ModuleName,
|
||||||
|
tostring(Heimdall_Data.config.inviter.allAssist),
|
||||||
|
tostring(Heimdall_Data.config.inviter.agentsAssist)))
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.inviter.debug then
|
||||||
|
print(string.format("[%s] Module initialized - All assist: %s, Agents assist: %s",
|
||||||
|
ModuleName,
|
||||||
|
tostring(Heimdall_Data.config.inviter.allAssist),
|
||||||
|
tostring(Heimdall_Data.config.inviter.agentsAssist)))
|
||||||
|
end
|
||||||
|
print("[Heimdall] Inviter loaded")
|
||||||
|
end
|
||||||
|
@@ -1,101 +1,107 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Macroer"
|
local ModuleName = "Macroer"
|
||||||
|
|
||||||
---@class HeimdallMacroerConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Macroer = {}
|
||||||
---@field debug boolean
|
function shared.Macroer.Init()
|
||||||
---@field priority string[]
|
---@class stinky
|
||||||
|
---@field name string
|
||||||
|
---@field class string
|
||||||
|
---@field seenAt number
|
||||||
|
---@field hostile boolean
|
||||||
|
|
||||||
---@class Macroer
|
local function FindOrCreateMacro(macroName)
|
||||||
shared.Macroer = {
|
if Heimdall_Data.config.macroer.debug then
|
||||||
Init = function()
|
print(string.format("[%s] Finding or creating macro: %s", ModuleName, macroName))
|
||||||
local function FindOrCreateMacro(macroName)
|
end
|
||||||
if Heimdall_Data.config.macroer.debug then
|
local idx = GetMacroIndexByName(macroName)
|
||||||
print(string.format("[%s] Finding or creating macro: %s", ModuleName, macroName))
|
if idx == 0 then
|
||||||
end
|
if Heimdall_Data.config.macroer.debug then
|
||||||
local idx = GetMacroIndexByName(macroName)
|
print(string.format("[%s] Creating new macro: %s", ModuleName, macroName))
|
||||||
if idx == 0 then
|
end
|
||||||
if Heimdall_Data.config.macroer.debug then
|
CreateMacro(macroName, "INV_Misc_QuestionMark", "")
|
||||||
print(string.format("[%s] Creating new macro: %s", ModuleName, macroName))
|
end
|
||||||
end
|
idx = GetMacroIndexByName(macroName)
|
||||||
CreateMacro(macroName, "INV_Misc_QuestionMark", "")
|
if Heimdall_Data.config.macroer.debug then
|
||||||
end
|
print(string.format("[%s] Macro index: %d", ModuleName, idx))
|
||||||
idx = GetMacroIndexByName(macroName)
|
end
|
||||||
if Heimdall_Data.config.macroer.debug then print(string.format("[%s] Macro index: %d", ModuleName, idx)) end
|
return idx
|
||||||
return idx
|
end
|
||||||
end
|
|
||||||
|
|
||||||
---@param stinkies table<string, Stinky>
|
---@param stinkies table<string, stinky>
|
||||||
local function FixMacro(stinkies)
|
local function FixMacro(stinkies)
|
||||||
if Heimdall_Data.config.macroer.debug then
|
if Heimdall_Data.config.macroer.debug then
|
||||||
print(string.format("[%s] Fixing macro with %d stinkies", ModuleName, #stinkies))
|
print(string.format("[%s] Fixing macro with %d stinkies", ModuleName, #stinkies))
|
||||||
end
|
end
|
||||||
if not Heimdall_Data.config.macroer.enabled then
|
if not Heimdall_Data.config.macroer.enabled then
|
||||||
if Heimdall_Data.config.macroer.debug then
|
if Heimdall_Data.config.macroer.debug then
|
||||||
print(string.format("[%s] Module disabled, skipping macro update", ModuleName))
|
print(string.format("[%s] Module disabled, skipping macro update", ModuleName))
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if InCombatLockdown() then
|
if InCombatLockdown() then
|
||||||
if Heimdall_Data.config.macroer.debug then
|
if Heimdall_Data.config.macroer.debug then
|
||||||
print(string.format("[%s] In combat, skipping macro update", ModuleName))
|
print(string.format("[%s] In combat, skipping macro update", ModuleName))
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local priorityMap = {}
|
local priorityMap = {}
|
||||||
for priority, className in ipairs(Heimdall_Data.config.macroer.priority) do
|
for priority, className in ipairs(Heimdall_Data.config.macroer.priority) do
|
||||||
priorityMap[className] = priority
|
priorityMap[className] = priority
|
||||||
end
|
end
|
||||||
local minPriority = #Heimdall_Data.config.macroer.priority + 1
|
local minPriority = #Heimdall_Data.config.macroer.priority + 1
|
||||||
|
|
||||||
local sortedStinkies = {}
|
local sortedStinkies = {}
|
||||||
for _, stinky in pairs(stinkies) do
|
for _, stinky in pairs(stinkies) do
|
||||||
if not shared.AgentTracker.IsAgent(stinky.name) then sortedStinkies[#sortedStinkies + 1] = stinky end
|
if not Heimdall_Data.config.agents[stinky.name] then
|
||||||
end
|
sortedStinkies[#sortedStinkies + 1] = stinky
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if Heimdall_Data.config.macroer.debug then
|
if Heimdall_Data.config.macroer.debug then
|
||||||
print(string.format("[%s] Processing %d non-agent stinkies", ModuleName, #sortedStinkies))
|
print(string.format("[%s] Processing %d non-agent stinkies", ModuleName, #sortedStinkies))
|
||||||
end
|
end
|
||||||
|
|
||||||
table.sort(sortedStinkies, function(a, b)
|
table.sort(sortedStinkies, function(a, b)
|
||||||
local aPriority = priorityMap[a.class] or minPriority
|
local aPriority = priorityMap[a.class] or minPriority
|
||||||
local bPriority = priorityMap[b.class] or minPriority
|
local bPriority = priorityMap[b.class] or minPriority
|
||||||
return aPriority > bPriority
|
return aPriority > bPriority
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if Heimdall_Data.config.macroer.debug then
|
if Heimdall_Data.config.macroer.debug then
|
||||||
print(string.format("[%s] Sorted stinkies: %d", ModuleName, #sortedStinkies))
|
print(string.format("[%s] Sorted stinkies: %d", ModuleName, #sortedStinkies))
|
||||||
shared.dump(sortedStinkies)
|
shared.dumpTable(sortedStinkies)
|
||||||
end
|
end
|
||||||
local lines = { "/targetenemy" }
|
local lines = { "/targetenemy" }
|
||||||
for _, stinky in pairs(sortedStinkies) do
|
for _, stinky in pairs(sortedStinkies) do
|
||||||
if stinky.seenAt > GetTime() - 600 then
|
if stinky.seenAt > GetTime() - 600 then
|
||||||
if Heimdall_Data.config.macroer.debug then
|
if Heimdall_Data.config.macroer.debug then
|
||||||
print(string.format("[%s] Adding target macro for: %s", ModuleName, stinky.name))
|
print(string.format("[%s] Adding target macro for: %s", ModuleName, stinky.name))
|
||||||
end
|
end
|
||||||
lines[#lines + 1] = string.format("/tar %s", stinky.name)
|
lines[#lines + 1] = string.format("/tar %s", stinky.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local idx = FindOrCreateMacro("HeimdallTarget")
|
local idx = FindOrCreateMacro("HeimdallTarget")
|
||||||
---@diagnostic disable-next-line: param-type-mismatch
|
local body = strjoin("\n", unpack(lines))
|
||||||
local body = strjoin("\n", unpack(lines))
|
if Heimdall_Data.config.macroer.debug then
|
||||||
if Heimdall_Data.config.macroer.debug then
|
print(string.format("[%s] Updating macro with %d lines", ModuleName, #lines))
|
||||||
print(string.format("[%s] Updating macro with %d lines", ModuleName, #lines))
|
end
|
||||||
end
|
EditMacro(idx, "HeimdallTarget", "INV_Misc_QuestionMark", body)
|
||||||
EditMacro(idx, "HeimdallTarget", "INV_Misc_QuestionMark", body)
|
end
|
||||||
end
|
|
||||||
|
|
||||||
shared.StinkyTracker.OnChange(function(stinkies)
|
shared.stinkyTracker.stinkies:onChange(function(value)
|
||||||
if Heimdall_Data.config.macroer.debug then
|
if Heimdall_Data.config.macroer.debug then
|
||||||
print(string.format("[%s] Stinkies changed, updating macro", ModuleName))
|
print(string.format("[%s] Stinkies changed, updating macro", ModuleName))
|
||||||
shared.dump(stinkies)
|
end
|
||||||
end
|
FixMacro(value)
|
||||||
FixMacro(stinkies)
|
end)
|
||||||
end)
|
|
||||||
if Heimdall_Data.config.macroer.debug then print(string.format("[%s] Module initialized", ModuleName)) end
|
if Heimdall_Data.config.macroer.debug then
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Module initialized", ModuleName))
|
||||||
end,
|
end
|
||||||
}
|
print("[Heimdall] Macroer loaded")
|
||||||
|
end
|
||||||
|
@@ -1,176 +1,137 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Messenger"
|
local ModuleName = "Messenger"
|
||||||
|
|
||||||
---@class HeimdallMessengerConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Messenger = {}
|
||||||
---@field debug boolean
|
function shared.Messenger.Init()
|
||||||
---@field interval number
|
---@class Message
|
||||||
|
---@field message string
|
||||||
|
---@field channel string
|
||||||
|
---@field data string
|
||||||
|
|
||||||
---@class HeimdallMessengerData
|
local function FindOrJoinChannel(channelName, password)
|
||||||
---@field queue ReactiveValue<table<string, Message>>
|
local channelId = GetChannelName(channelName)
|
||||||
---@field ticker Timer?
|
if channelId == 0 then
|
||||||
|
|
||||||
---@class Message
|
|
||||||
---@field message string
|
|
||||||
---@field channel string
|
|
||||||
---@field data string
|
|
||||||
|
|
||||||
---@class Messenger
|
|
||||||
shared.Messenger = {
|
|
||||||
---@param message Message
|
|
||||||
Enqueue = function(message) table.insert(shared.messenger.queue, message) end,
|
|
||||||
Init = function()
|
|
||||||
shared.messenger = {
|
|
||||||
queue = ReactiveValue.new({}),
|
|
||||||
}
|
|
||||||
|
|
||||||
local function FindOrJoinChannel(channelName, password)
|
|
||||||
local channelId = GetChannelName(channelName)
|
|
||||||
if channelId == 0 then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
print(string.format("[%s] Channel not found, joining: %s", ModuleName, channelName))
|
|
||||||
end
|
|
||||||
if password then
|
|
||||||
JoinPermanentChannel(channelName, password)
|
|
||||||
else
|
|
||||||
JoinPermanentChannel(channelName)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
channelId = GetChannelName(channelName)
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
if Heimdall_Data.config.messenger.debug then
|
||||||
print(string.format("[%s] Channel found with ID: %s (%s)", ModuleName, channelId, channelName))
|
print(string.format("[%s] Channel not found, joining: %s", ModuleName, channelName))
|
||||||
|
end
|
||||||
|
if password then
|
||||||
|
JoinPermanentChannel(channelName, password)
|
||||||
|
else
|
||||||
|
JoinPermanentChannel(channelName)
|
||||||
end
|
end
|
||||||
return channelId
|
|
||||||
end
|
end
|
||||||
|
channelId = GetChannelName(channelName)
|
||||||
if not shared.messenger.ticker then
|
|
||||||
local function DoMessage()
|
|
||||||
-- if Heimdall_Data.config.messenger.debug then
|
|
||||||
-- print(
|
|
||||||
-- string.format(
|
|
||||||
-- "[%s] Processing message queue - Size: %d",
|
|
||||||
-- ModuleName,
|
|
||||||
-- #shared.messenger.queue:get()
|
|
||||||
-- )
|
|
||||||
-- )
|
|
||||||
-- end
|
|
||||||
|
|
||||||
if not Heimdall_Data.config.messenger.enabled then
|
|
||||||
-- if Heimdall_Data.config.messenger.debug then
|
|
||||||
-- print(string.format("[%s] Module disabled, skipping message processing", ModuleName))
|
|
||||||
-- end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
---@type Message
|
|
||||||
local message = shared.messenger.queue[1]
|
|
||||||
if not message then
|
|
||||||
-- if Heimdall_Data.config.messenger.debug then
|
|
||||||
-- print(string.format("[%s] Message queue empty", ModuleName))
|
|
||||||
-- end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.messenger.debug then shared.dump(message, "[%s] Processing message:") end
|
|
||||||
|
|
||||||
if not message.message or message.message == "" then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(message, string.format("[%s] Invalid message: empty content", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if not message.channel or message.channel == "" then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(message, string.format("[%s] Invalid message: no channel specified", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if string.find(message.channel, "^C") then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(
|
|
||||||
message,
|
|
||||||
string.format("[%s] Converting channel type from C to CHANNEL", ModuleName)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
message.channel = "CHANNEL"
|
|
||||||
elseif string.find(message.channel, "^W") then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(
|
|
||||||
message,
|
|
||||||
string.format("[%s] Converting channel type from W to WHISPER", ModuleName)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
message.channel = "WHISPER"
|
|
||||||
end
|
|
||||||
|
|
||||||
if message.channel == "CHANNEL" and message.data and string.match(message.data, "%D") then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(message, string.format("[%s] Processing channel message:", ModuleName))
|
|
||||||
end
|
|
||||||
local channelId = GetChannelName(message.data)
|
|
||||||
if channelId == 0 then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(message, string.format("[%s] Channel not found, joining:", ModuleName))
|
|
||||||
end
|
|
||||||
channelId = FindOrJoinChannel(message.data)
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
print(string.format("[%s] Channel join result - ID: %s", ModuleName, channelId))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
message.data = tostring(channelId)
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(shared.messenger.queue, 1)
|
|
||||||
if not message.message or message.message == "" then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(message, string.format("[%s] Skipping empty message", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not message.channel or message.channel == "" then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(message, string.format("[%s] Skipping message with no channel", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not message.data or message.data == "" then
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(message, string.format("[%s] Skipping message with no data", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
|
||||||
shared.dump(message, string.format("[%s] Sending message:", ModuleName))
|
|
||||||
end
|
|
||||||
if string.len(message.message) > 255 then
|
|
||||||
shared.dump(message, string.format("[%s] Message too long!!!!: %s", ModuleName, message.message))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
SendChatMessage(message.message, message.channel, nil, message.data)
|
|
||||||
end
|
|
||||||
local function Tick()
|
|
||||||
-- if Heimdall_Data.config.messenger.debug then
|
|
||||||
-- print(string.format("[%s] Tick - Queue size: %d", ModuleName, #shared.messenger.queue:get()))
|
|
||||||
-- end
|
|
||||||
DoMessage()
|
|
||||||
shared.messenger.ticker = C_Timer.NewTimer(Heimdall_Data.config.messenger.interval, Tick, 1)
|
|
||||||
end
|
|
||||||
Tick()
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.messenger.debug then
|
if Heimdall_Data.config.messenger.debug then
|
||||||
print(
|
print(string.format("[%s] Channel found with ID: %s (%s)", ModuleName, channelId, channelName))
|
||||||
string.format(
|
|
||||||
"[%s] Module initialized with interval: %s",
|
|
||||||
ModuleName,
|
|
||||||
Heimdall_Data.config.messenger.interval
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
return channelId
|
||||||
end,
|
end
|
||||||
}
|
|
||||||
|
---@diagnostic disable-next-line: missing-fields
|
||||||
|
if not shared.messenger then shared.messenger = {} end
|
||||||
|
if not shared.messenger.queue then shared.messenger.queue = {} end
|
||||||
|
if not shared.messenger.ticker then
|
||||||
|
local function DoMessage()
|
||||||
|
--if Heimdall_Data.config.messenger.debug then
|
||||||
|
-- print(string.format("[%s] Processing message queue", ModuleName))
|
||||||
|
--end
|
||||||
|
if not Heimdall_Data.config.messenger.enabled then
|
||||||
|
--if Heimdall_Data.config.messenger.debug then
|
||||||
|
-- print(string.format("[%s] Module disabled, skipping message processing", ModuleName))
|
||||||
|
--end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
---@type Message
|
||||||
|
local message = shared.messenger.queue[1]
|
||||||
|
if not message then
|
||||||
|
--if Heimdall_Data.config.messenger.debug then
|
||||||
|
-- print(string.format("[%s] Message queue empty", ModuleName))
|
||||||
|
--end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not message.message or message.message == "" then
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Invalid message: empty content", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not message.channel or message.channel == "" then
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Invalid message: no channel specified", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if string.find(message.channel, "^C") then
|
||||||
|
message.channel = "CHANNEL"
|
||||||
|
elseif string.find(message.channel, "^W") then
|
||||||
|
message.channel = "WHISPER"
|
||||||
|
end
|
||||||
|
|
||||||
|
if message.channel == "CHANNEL" and message.data and string.match(message.data, "%D") then
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Processing channel message: '%s' to '%s'", ModuleName, message.message,
|
||||||
|
message.data))
|
||||||
|
end
|
||||||
|
local channelId = GetChannelName(message.data)
|
||||||
|
if channelId == 0 then
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Channel not found, attempting to join: %s", ModuleName, message.data))
|
||||||
|
end
|
||||||
|
channelId = FindOrJoinChannel(message.data)
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Channel join result - ID: %s", ModuleName, channelId))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
message.data = tostring(channelId)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.remove(shared.messenger.queue, 1)
|
||||||
|
if not message.message or message.message == "" then
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Skipping empty message", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not message.channel or message.channel == "" then
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Skipping message with no channel", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not message.data or message.data == "" then
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Skipping message with no data", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Sending message: '%s' to %s:%s", ModuleName, message.message, message.channel,
|
||||||
|
message.data))
|
||||||
|
end
|
||||||
|
if string.len(message.message) > 255 then
|
||||||
|
print(string.format("[%s] Message too long!!!!: %s", ModuleName, message.message))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
SendChatMessage(message.message, message.channel, nil, message.data)
|
||||||
|
end
|
||||||
|
local function Tick()
|
||||||
|
--if Heimdall_Data.config.messenger.debug then
|
||||||
|
-- local queueSize = #shared.messenger.queue
|
||||||
|
-- print(string.format("[%s] Queue check - Messages pending: %d", ModuleName, queueSize))
|
||||||
|
--end
|
||||||
|
DoMessage()
|
||||||
|
shared.messenger.ticker = C_Timer.NewTimer(Heimdall_Data.config.messenger.interval, Tick, 1)
|
||||||
|
end
|
||||||
|
Tick()
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.messenger.debug then
|
||||||
|
print(string.format("[%s] Module initialized with interval: %s", ModuleName,
|
||||||
|
Heimdall_Data.config.messenger.interval))
|
||||||
|
end
|
||||||
|
print("[Heimdall] Messenger loaded")
|
||||||
|
end
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,85 +1,76 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Network"
|
local ModuleName = "Network"
|
||||||
|
|
||||||
---@class HeimdallNetworkConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Network = {}
|
||||||
---@field debug boolean
|
function shared.Network.Init()
|
||||||
---@field members string[]
|
if not shared.network then shared.network = {} end
|
||||||
---@field updateInterval number
|
local updatePending = false
|
||||||
|
|
||||||
---@class HeimdallNetworkData
|
local function FriendListUpdate()
|
||||||
---@field ticker Timer?
|
updatePending = false
|
||||||
|
if not Heimdall_Data.config.network.enabled then return end
|
||||||
---@class Network
|
---@type table<string, boolean>
|
||||||
shared.Network = {
|
local friends = {}
|
||||||
Init = function()
|
for i = 1, GetNumFriends() do
|
||||||
if not shared.network then shared.network = {} end
|
local name, level, class, area, connected, status, note, RAF = GetFriendInfo(i)
|
||||||
local updatePending = false
|
if name then
|
||||||
|
friends[name] = connected
|
||||||
local function FriendListUpdate()
|
if Heimdall_Data.config.network.debug then
|
||||||
updatePending = false
|
print(string.format("[%s] Friend %s is %s", ModuleName, name, connected and "online" or "offline"))
|
||||||
if not Heimdall_Data.config.network.enabled then return end
|
|
||||||
---@type table<string, boolean>
|
|
||||||
local friends = {}
|
|
||||||
for i = 1, GetNumFriends() do
|
|
||||||
local name, _, _, _, connected, _, _, _ = GetFriendInfo(i)
|
|
||||||
if name then
|
|
||||||
friends[name] = connected
|
|
||||||
if Heimdall_Data.config.network.debug then
|
|
||||||
print(
|
|
||||||
string.format("[%s] Friend %s is %s", ModuleName, name, connected and "online" or "offline")
|
|
||||||
)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if Heimdall_Data.config.network.debug then
|
|
||||||
print(string.format("[%s] Friend %s is nil", ModuleName, i))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
else
|
||||||
|
if Heimdall_Data.config.network.debug then
|
||||||
for _, member in ipairs(Heimdall_Data.config.network.members) do
|
print(string.format("[%s] Friend %s is nil", ModuleName, i))
|
||||||
if friends[member] == nil and member ~= UnitName("player") then
|
|
||||||
if Heimdall_Data.config.network.debug then
|
|
||||||
print(string.format("[%s] Adding friend %s", ModuleName, member))
|
|
||||||
end
|
|
||||||
AddFriend(member)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
friends[UnitName("player")] = true
|
|
||||||
|
|
||||||
shared.networkNodes = {}
|
|
||||||
-- Why are we skipping this again...?
|
|
||||||
-- if false then shared.networkNodes[#shared.networkNodes + 1] = UnitName("player") end
|
|
||||||
for _, player in ipairs(Heimdall_Data.config.network.members) do
|
|
||||||
if friends[player] then
|
|
||||||
shared.networkNodes[#shared.networkNodes + 1] = player
|
|
||||||
if Heimdall_Data.config.network.debug then
|
|
||||||
print(string.format("[%s] Adding network node %s", ModuleName, player))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if Heimdall_Data.config.network.debug then
|
|
||||||
print(string.format("[%s] Network nodes:", ModuleName))
|
|
||||||
shared.dump(shared.networkNodes)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local friendsFrame = CreateFrame("Frame")
|
for _, member in ipairs(Heimdall_Data.config.network.members) do
|
||||||
friendsFrame:RegisterEvent("FRIENDLIST_UPDATE")
|
if friends[member] == nil and member ~= UnitName("player") then
|
||||||
friendsFrame:SetScript("OnEvent", function(self, event, ...) end)
|
if Heimdall_Data.config.network.debug then
|
||||||
|
print(string.format("[%s] Adding friend %s", ModuleName, member))
|
||||||
local function NetworkTick()
|
end
|
||||||
if Heimdall_Data.config.network.debug then print("Network module is updating.") end
|
AddFriend(member)
|
||||||
ShowFriends()
|
end
|
||||||
updatePending = true
|
|
||||||
C_Timer.After(1, function()
|
|
||||||
if updatePending then FriendListUpdate() end
|
|
||||||
end)
|
|
||||||
shared.network.ticker = C_Timer.NewTimer(Heimdall_Data.config.network.updateInterval, NetworkTick, 1)
|
|
||||||
end
|
end
|
||||||
|
friends[UnitName("player")] = true
|
||||||
|
|
||||||
NetworkTick()
|
shared.networkNodes = {}
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
if false then shared.networkNodes[#shared.networkNodes + 1] = UnitName("player") end
|
||||||
end,
|
for _, player in ipairs(Heimdall_Data.config.network.members) do
|
||||||
}
|
if friends[player] then
|
||||||
|
shared.networkNodes[#shared.networkNodes + 1] = player
|
||||||
|
if Heimdall_Data.config.network.debug then
|
||||||
|
print(string.format("[%s] Adding network node %s", ModuleName, player))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if Heimdall_Data.config.network.debug then
|
||||||
|
print(string.format("[%s] Network nodes:", ModuleName))
|
||||||
|
shared.dumpTable(shared.networkNodes)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local friendsFrame = CreateFrame("Frame")
|
||||||
|
friendsFrame:RegisterEvent("FRIENDLIST_UPDATE")
|
||||||
|
friendsFrame:SetScript("OnEvent", function(self, event, ...)
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function NetworkTick()
|
||||||
|
if Heimdall_Data.config.network.debug then
|
||||||
|
print("Network module is updating.")
|
||||||
|
end
|
||||||
|
ShowFriends()
|
||||||
|
updatePending = true
|
||||||
|
C_Timer.After(1, function()
|
||||||
|
if updatePending then FriendListUpdate() end
|
||||||
|
end)
|
||||||
|
shared.network.ticker = C_Timer.NewTimer(Heimdall_Data.config.network.updateInterval, NetworkTick, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
NetworkTick()
|
||||||
|
print("[Heimdall] Network module loaded")
|
||||||
|
end
|
||||||
|
@@ -1,204 +1,178 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "NetworkMessenger"
|
local ModuleName = "NetworkMessenger"
|
||||||
|
|
||||||
---@class HeimdallNetworkMessengerConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.NetworkMessenger = {}
|
||||||
---@field debug boolean
|
function shared.NetworkMessenger.Init()
|
||||||
---@field interval number
|
RegisterAddonMessagePrefix(Heimdall_Data.config.addonPrefix)
|
||||||
|
|
||||||
---@class HeimdallNetworkMessengerData
|
if not shared.networkMessenger then shared.networkMessenger = {} end
|
||||||
---@field queue table<string, Message>
|
if not shared.networkMessenger.queue then shared.networkMessenger.queue = {} end
|
||||||
---@field ticker Timer?
|
if not shared.networkMessenger.ticker then
|
||||||
|
local function DoMessage()
|
||||||
---@class NetworkMessenger
|
--if Heimdall_Data.config.networkMessenger.debug then
|
||||||
shared.NetworkMessenger = {
|
-- print(string.format("[%s] Processing network message queue", ModuleName))
|
||||||
---@param message Message
|
--end
|
||||||
Enqueue = function(message) table.insert(shared.networkMessenger.queue, message) end,
|
if not Heimdall_Data.config.networkMessenger.enabled then
|
||||||
Init = function()
|
|
||||||
RegisterAddonMessagePrefix(Heimdall_Data.config.addonPrefix)
|
|
||||||
|
|
||||||
shared.networkMessenger = {
|
|
||||||
queue = ReactiveValue.new({}),
|
|
||||||
}
|
|
||||||
|
|
||||||
if not shared.networkMessenger.ticker then
|
|
||||||
local function DoMessage()
|
|
||||||
--if Heimdall_Data.config.networkMessenger.debug then
|
--if Heimdall_Data.config.networkMessenger.debug then
|
||||||
-- print(string.format("[%s] Processing network message queue", ModuleName))
|
-- print(string.format("[%s] Module disabled, skipping network message processing", ModuleName))
|
||||||
--end
|
--end
|
||||||
if not Heimdall_Data.config.networkMessenger.enabled then
|
return
|
||||||
--if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
-- print(string.format("[%s] Module disabled, skipping network message processing", ModuleName))
|
|
||||||
--end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
---@type Message
|
|
||||||
local message = shared.networkMessenger.queue[1]
|
|
||||||
if not message then
|
|
||||||
--if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
-- print(string.format("[%s] Network message queue empty", ModuleName))
|
|
||||||
--end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not message.message or message.message == "" then
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(string.format("[%s] Invalid network message: empty content", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not message.channel or message.channel == "" then
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(string.format("[%s] Invalid network message: no channel specified", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(shared.networkMessenger.queue, 1)
|
|
||||||
if not message.message or message.message == "" then
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(string.format("[%s] Skipping empty network message", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not message.channel or message.channel == "" then
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(string.format("[%s] Skipping network message with no channel", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not message.data or message.data == "" then
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(string.format("[%s] Skipping network message with no data", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Sending network message: '%s' to %s:%s",
|
|
||||||
ModuleName,
|
|
||||||
message.message,
|
|
||||||
message.channel,
|
|
||||||
message.data
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
local payload = string.format("dmessage|%s|%s|%s", message.message, message.channel, message.data)
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(string.format("[%s] Payload: %s", ModuleName, payload))
|
|
||||||
end
|
|
||||||
if not shared.networkNodes or #shared.networkNodes == 0 then
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(string.format("[%s] No network nodes found, wtf????", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local target = shared.networkNodes[1]
|
|
||||||
SendAddonMessage(Heimdall_Data.config.addonPrefix, payload, "WHISPER", target)
|
|
||||||
end
|
end
|
||||||
local function Tick()
|
---@type Message
|
||||||
|
local message = shared.networkMessenger.queue[1]
|
||||||
|
if not message then
|
||||||
--if Heimdall_Data.config.networkMessenger.debug then
|
--if Heimdall_Data.config.networkMessenger.debug then
|
||||||
-- local queueSize = #shared.networkMessenger.queue
|
-- print(string.format("[%s] Network message queue empty", ModuleName))
|
||||||
-- print(string.format("[%s] Queue check - Network messages pending: %d", ModuleName, queueSize))
|
|
||||||
--end
|
--end
|
||||||
DoMessage()
|
return
|
||||||
shared.networkMessenger.ticker =
|
end
|
||||||
C_Timer.NewTimer(Heimdall_Data.config.networkMessenger.interval, Tick, 1)
|
if not message.message or message.message == "" then
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
print(string.format("[%s] Invalid network message: empty content", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not message.channel or message.channel == "" then
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
print(string.format("[%s] Invalid network message: no channel specified", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
end
|
end
|
||||||
Tick()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- If we are the leader then we delegate messages (dmessage)
|
table.remove(shared.networkMessenger.queue, 1)
|
||||||
-- If we get a "message" command from leader then we send the message
|
if not message.message or message.message == "" then
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
local nextIdx = 1
|
print(string.format("[%s] Skipping empty network message", ModuleName))
|
||||||
local addonMsgFrame = CreateFrame("Frame")
|
end
|
||||||
addonMsgFrame:RegisterEvent("CHAT_MSG_ADDON")
|
return
|
||||||
addonMsgFrame:SetScript("OnEvent", function(self, event, prefix, message, channel, source)
|
end
|
||||||
if not Heimdall_Data.config.networkMessenger.enabled then return end
|
if not message.channel or message.channel == "" then
|
||||||
if prefix ~= Heimdall_Data.config.addonPrefix then return end
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
source = string.match(source, "[^%-]+")
|
print(string.format("[%s] Skipping network message with no channel", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not message.data or message.data == "" then
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
print(string.format("[%s] Skipping network message with no data", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
print(string.format("[%s] Received message from %s: %s", ModuleName, source, message))
|
print(string.format("[%s] Sending network message: '%s' to %s:%s", ModuleName, message.message,
|
||||||
|
message.channel,
|
||||||
|
message.data))
|
||||||
end
|
end
|
||||||
if #shared.networkNodes == 0 then
|
local payload = string.format("dmessage|%s|%s|%s", message.message, message.channel, message.data)
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
print(string.format("[%s] Payload: %s", ModuleName, payload))
|
||||||
|
end
|
||||||
|
if not shared.networkNodes or #shared.networkNodes == 0 then
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
print(string.format("[%s] No network nodes found, wtf????", ModuleName))
|
print(string.format("[%s] No network nodes found, wtf????", ModuleName))
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
local target = shared.networkNodes[1]
|
||||||
-- There should always be at least one network node ergo should always exist a leader
|
SendAddonMessage(Heimdall_Data.config.addonPrefix, payload, "WHISPER", target)
|
||||||
-- Because the us, the player, is also a node
|
end
|
||||||
--local networkLeader = shared.networkNodes[1]
|
local function Tick()
|
||||||
--if source ~= networkLeader then
|
--if Heimdall_Data.config.networkMessenger.debug then
|
||||||
-- if Heimdall_Data.config.networkMessenger.debug then
|
-- local queueSize = #shared.networkMessenger.queue
|
||||||
-- print(string.format("[%s] Message from %s is not from the network leader (%s)", ModuleName, source,
|
-- print(string.format("[%s] Queue check - Network messages pending: %d", ModuleName, queueSize))
|
||||||
-- networkLeader))
|
|
||||||
-- end
|
|
||||||
-- return
|
|
||||||
--end
|
--end
|
||||||
|
DoMessage()
|
||||||
|
shared.networkMessenger.ticker = C_Timer.NewTimer(Heimdall_Data.config.networkMessenger.interval, Tick, 1)
|
||||||
|
end
|
||||||
|
Tick()
|
||||||
|
end
|
||||||
|
|
||||||
local parts = shared.Split(message, "|")
|
-- If we are the leader then we delegate messages (dmessage)
|
||||||
|
-- If we get a "message" command from leader then we send the message
|
||||||
|
|
||||||
|
local nextIdx = 1
|
||||||
|
local addonMsgFrame = CreateFrame("Frame")
|
||||||
|
addonMsgFrame:RegisterEvent("CHAT_MSG_ADDON")
|
||||||
|
addonMsgFrame:SetScript("OnEvent", function(self, event, prefix, message, channel, source)
|
||||||
|
if not Heimdall_Data.config.networkMessenger.enabled then return end
|
||||||
|
if prefix ~= Heimdall_Data.config.addonPrefix then return end
|
||||||
|
source = string.match(source, "[^%-]+")
|
||||||
|
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
print(string.format("[%s] Received message from %s: %s", ModuleName, source, message))
|
||||||
|
end
|
||||||
|
if #shared.networkNodes == 0 then
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
print(string.format("[%s] Received message parts:", ModuleName))
|
print(string.format("[%s] No network nodes found, wtf????", ModuleName))
|
||||||
shared.dump(parts)
|
|
||||||
end
|
|
||||||
local command = strtrim(parts[1])
|
|
||||||
if command == "message" then
|
|
||||||
local content = strtrim(tostring(parts[2]))
|
|
||||||
local targetchannel = strtrim(tostring(parts[3]))
|
|
||||||
local target = strtrim(tostring(parts[4]))
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Received message command: %s %s %s",
|
|
||||||
ModuleName,
|
|
||||||
content,
|
|
||||||
targetchannel,
|
|
||||||
target
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
---@type Message
|
|
||||||
local msg = {
|
|
||||||
channel = targetchannel,
|
|
||||||
message = content,
|
|
||||||
data = target,
|
|
||||||
}
|
|
||||||
table.insert(shared.messenger.queue, msg)
|
|
||||||
elseif command == "dmessage" then
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(string.format("[%s] Received dmessage command", ModuleName))
|
|
||||||
end
|
|
||||||
parts[1] = "message"
|
|
||||||
local content = table.concat(parts, "|")
|
|
||||||
|
|
||||||
if nextIdx > #shared.networkNodes then nextIdx = 1 end
|
|
||||||
local recipient = shared.networkNodes[nextIdx]
|
|
||||||
nextIdx = nextIdx + 1
|
|
||||||
if Heimdall_Data.config.networkMessenger.debug then
|
|
||||||
print(string.format("[%s] Sending message %s to %s", ModuleName, content, recipient))
|
|
||||||
end
|
|
||||||
SendAddonMessage(Heimdall_Data.config.addonPrefix, content, "WHISPER", recipient)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--/run Heimdall_Data.Test()
|
|
||||||
Heimdall_Data.Test = function()
|
|
||||||
local testmsg = {
|
|
||||||
channel = "W",
|
|
||||||
message = "Hi, mom!",
|
|
||||||
data = "Secundus",
|
|
||||||
}
|
|
||||||
for i = 1, 36 do
|
|
||||||
table.insert(shared.networkMessenger.queue, testmsg)
|
|
||||||
end
|
end
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
-- There should always be at least one network node ergo should always exist a leader
|
||||||
end,
|
-- Because the us, the player, is also a node
|
||||||
}
|
--local networkLeader = shared.networkNodes[1]
|
||||||
|
--if source ~= networkLeader then
|
||||||
|
-- if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
-- print(string.format("[%s] Message from %s is not from the network leader (%s)", ModuleName, source,
|
||||||
|
-- networkLeader))
|
||||||
|
-- end
|
||||||
|
-- return
|
||||||
|
--end
|
||||||
|
|
||||||
|
local parts = shared.Split(message, "|")
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
print(string.format("[%s] Received message parts:", ModuleName))
|
||||||
|
shared.dumpTable(parts)
|
||||||
|
end
|
||||||
|
local command = strtrim(parts[1])
|
||||||
|
if command == "message" then
|
||||||
|
local message = strtrim(tostring(parts[2]))
|
||||||
|
local channel = strtrim(tostring(parts[3]))
|
||||||
|
local target = strtrim(tostring(parts[4]))
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
print(string.format("[%s] Received message command: %s %s %s", ModuleName, message, channel, target))
|
||||||
|
end
|
||||||
|
---@type Message
|
||||||
|
local msg = {
|
||||||
|
channel = channel,
|
||||||
|
message = message,
|
||||||
|
data = target
|
||||||
|
}
|
||||||
|
table.insert(shared.messenger.queue, msg)
|
||||||
|
elseif command == "dmessage" then
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
print(string.format("[%s] Received dmessage command", ModuleName))
|
||||||
|
end
|
||||||
|
parts[1] = "message"
|
||||||
|
local message = table.concat(parts, "|")
|
||||||
|
|
||||||
|
if nextIdx > #shared.networkNodes then
|
||||||
|
nextIdx = 1
|
||||||
|
end
|
||||||
|
local recipient = shared.networkNodes[nextIdx]
|
||||||
|
nextIdx = nextIdx + 1
|
||||||
|
if Heimdall_Data.config.networkMessenger.debug then
|
||||||
|
print(string.format("[%s] Sending message %s to %s", ModuleName, message, recipient))
|
||||||
|
end
|
||||||
|
SendAddonMessage(Heimdall_Data.config.addonPrefix, message, "WHISPER", recipient)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--/run Heimdall_Data.Test()
|
||||||
|
Heimdall_Data.Test = function()
|
||||||
|
local testmsg = {
|
||||||
|
channel = "W",
|
||||||
|
message = "Hi, mom!",
|
||||||
|
data = "Secundus"
|
||||||
|
}
|
||||||
|
for i = 1, 36 do
|
||||||
|
table.insert(shared.networkMessenger.queue, testmsg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("[Heimdall] NetworkMessenger module loaded")
|
||||||
|
end
|
||||||
|
@@ -1,307 +1,301 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Noter"
|
local ModuleName = "Noter"
|
||||||
|
|
||||||
---@class HeimdallNoterConfig
|
|
||||||
---@field enabled boolean
|
|
||||||
---@field debug boolean
|
|
||||||
---@field channels string[]
|
|
||||||
---@field lastNotes number
|
|
||||||
|
|
||||||
---@class Note
|
---@class Note
|
||||||
---@field source string
|
---@field source string
|
||||||
---@field for string
|
---@field for string
|
||||||
---@field date string
|
---@field date string
|
||||||
---@field note string
|
---@field note string
|
||||||
|
|
||||||
---@class Noter
|
---@diagnostic disable-next-line: missing-fields
|
||||||
shared.Noter = {
|
shared.Noter = {}
|
||||||
Init = function()
|
function shared.Noter.Init()
|
||||||
-- ---Hopefully this will not be necessary
|
---Hopefully this will not be necessary
|
||||||
-- ---@param text string
|
---@param text string
|
||||||
-- ---@param size number
|
---@param size number
|
||||||
-- ---@return string[]
|
---@return string[]
|
||||||
-- local function Partition(text, size)
|
local function Partition(text, size)
|
||||||
-- local words = {}
|
local words = {}
|
||||||
-- for word in text:gmatch("[^,]+") do
|
for word in text:gmatch("[^,]+") do
|
||||||
-- words[#words + 1] = word
|
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
|
end
|
||||||
|
|
||||||
---@param name string
|
local ret = {}
|
||||||
---@param args string[]
|
local currentChunk = ""
|
||||||
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
|
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
|
if Heimdall_Data.config.noter.debug then
|
||||||
print(
|
print(string.format("[%s] Note at index %s does not exist", ModuleName, i))
|
||||||
string.format("[%s] Invalid start range for delete note: %s", ModuleName, tostring(start))
|
|
||||||
)
|
|
||||||
end
|
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),
|
|
||||||
}
|
|
||||||
if Heimdall_Data.config.networkMessenger.enabled then
|
|
||||||
shared.NetworkMessenger.Enqueue(msg)
|
|
||||||
elseif Heimdall_Data.config.messenger.enabled then
|
|
||||||
shared.Messenger.Enqueue(msg)
|
|
||||||
end
|
|
||||||
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 <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.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
|
else
|
||||||
AddNote(name, sender, args)
|
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
|
||||||
end
|
end
|
||||||
end)
|
Heimdall_Data.config.notes[name] = Compact(Heimdall_Data.config.notes[name])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
---@param channel string
|
||||||
end,
|
---@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
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,92 +1,90 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Sniffer"
|
local ModuleName = "Sniffer"
|
||||||
|
|
||||||
---@class HeimdallSnifferConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Sniffer = {}
|
||||||
---@field debug boolean
|
function shared.Sniffer.Init()
|
||||||
---@field channels string[]
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
---@field throttle number -- throttleTime in the original code, matching config name now
|
print(string.format("[%s] Module initializing", ModuleName))
|
||||||
---@field zoneOverride string?
|
end
|
||||||
---@field stinky boolean
|
local smellThrottle = {}
|
||||||
|
local SmellStinky = function(stinky)
|
||||||
---@class Sniffer
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
shared.Sniffer = {
|
print(string.format("%s: SmellStinky", ModuleName))
|
||||||
Init = function()
|
shared.dumpTable(Heimdall_Data.config.sniffer)
|
||||||
if Heimdall_Data.config.sniffer.debug then print(string.format("[%s] Module initializing", ModuleName)) end
|
|
||||||
local smellThrottle = {}
|
|
||||||
local SmellStinky = function(stinky)
|
|
||||||
if Heimdall_Data.config.sniffer.debug then
|
|
||||||
print(string.format("%s: SmellStinky", ModuleName))
|
|
||||||
shared.dump(Heimdall_Data.config.sniffer)
|
|
||||||
end
|
|
||||||
if not Heimdall_Data.config.sniffer.enabled then return end
|
|
||||||
if Heimdall_Data.config.sniffer.stinky and not shared.IsStinky(stinky) then
|
|
||||||
if Heimdall_Data.config.sniffer.debug then
|
|
||||||
print(string.format("%s: Stinky not found in config", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if smellThrottle[stinky] and GetTime() - smellThrottle[stinky] < Heimdall_Data.config.sniffer.throttle then
|
|
||||||
if Heimdall_Data.config.sniffer.debug then print(string.format("%s: Throttled", ModuleName)) end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
smellThrottle[stinky] = GetTime()
|
|
||||||
|
|
||||||
for _, channel in pairs(Heimdall_Data.config.sniffer.channels) do
|
|
||||||
local locale = shared.GetLocaleForChannel(channel)
|
|
||||||
local text = string.format(shared._L("snifferStinky", locale), stinky)
|
|
||||||
---@type Message
|
|
||||||
local msg = {
|
|
||||||
channel = "C",
|
|
||||||
data = channel,
|
|
||||||
message = text,
|
|
||||||
}
|
|
||||||
if Heimdall_Data.config.sniffer.debug then
|
|
||||||
print(string.format("[%s] Queuing sniffer message", ModuleName))
|
|
||||||
shared.dump(msg)
|
|
||||||
end
|
|
||||||
table.insert(shared.messenger.queue, msg)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
if not Heimdall_Data.config.sniffer.enabled then return end
|
||||||
|
if Heimdall_Data.config.sniffer.stinky and
|
||||||
|
not shared.IsStinky(stinky) then
|
||||||
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
|
print(string.format("%s: Stinky not found in config", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if smellThrottle[stinky] and GetTime() - smellThrottle[stinky] < Heimdall_Data.config.sniffer.throttleTime then
|
||||||
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
|
print(string.format("%s: Throttled", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
smellThrottle[stinky] = GetTime()
|
||||||
|
|
||||||
local cleuFrame = CreateFrame("Frame")
|
for _, channel in pairs(Heimdall_Data.config.sniffer.channels) do
|
||||||
cleuFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
local locale = shared.GetLocaleForChannel(channel)
|
||||||
cleuFrame:SetScript("OnEvent", function(self, event, ...)
|
local text = string.format(shared._L("snifferStinky", locale), stinky)
|
||||||
|
---@type Message
|
||||||
|
local msg = {
|
||||||
|
channel = "C",
|
||||||
|
data = channel,
|
||||||
|
message = text,
|
||||||
|
}
|
||||||
if Heimdall_Data.config.sniffer.debug then
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
print(string.format("[%s] Received event: %s", ModuleName, event))
|
print(string.format("[%s] Queuing sniffer message", ModuleName))
|
||||||
|
shared.dumpTable(msg)
|
||||||
end
|
end
|
||||||
if not Heimdall_Data.config.sniffer.enabled then
|
table.insert(shared.messenger.queue, msg)
|
||||||
if Heimdall_Data.config.sniffer.debug then
|
end
|
||||||
print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
end
|
||||||
end
|
|
||||||
return
|
local cleuFrame = CreateFrame("Frame")
|
||||||
end
|
cleuFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||||
local source, destination, err
|
cleuFrame:SetScript("OnEvent", function(self, event, ...)
|
||||||
source, err = CLEUParser.GetSourceName(...)
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
|
print(string.format("[%s] Received event: %s", ModuleName, event))
|
||||||
|
end
|
||||||
|
if not Heimdall_Data.config.sniffer.enabled then
|
||||||
if Heimdall_Data.config.sniffer.debug then
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
print(string.format("[%s] Processing source: %s", ModuleName, source))
|
print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
||||||
end
|
end
|
||||||
if err then
|
return
|
||||||
if Heimdall_Data.config.sniffer.debug then
|
end
|
||||||
print(string.format("[%s] Error parsing source: %s", ModuleName, err))
|
local source, err = CLEUParser.GetSourceName(...)
|
||||||
end
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
return
|
print(string.format("[%s] Processing source: %s", ModuleName, source))
|
||||||
end
|
end
|
||||||
SmellStinky(source)
|
if err then
|
||||||
destination, err = CLEUParser.GetDestName(...)
|
|
||||||
if Heimdall_Data.config.sniffer.debug then
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
print(string.format("[%s] Processing destination: %s", ModuleName, destination))
|
print(string.format("[%s] Error parsing source: %s", ModuleName, err))
|
||||||
end
|
end
|
||||||
if err then
|
return
|
||||||
if Heimdall_Data.config.sniffer.debug then
|
end
|
||||||
print(string.format("[%s] Error parsing destination: %s", ModuleName, err))
|
SmellStinky(source)
|
||||||
end
|
local destination, err = CLEUParser.GetDestName(...)
|
||||||
return
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
|
print(string.format("[%s] Processing destination: %s", ModuleName, destination))
|
||||||
|
end
|
||||||
|
if err then
|
||||||
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
|
print(string.format("[%s] Error parsing destination: %s", ModuleName, err))
|
||||||
end
|
end
|
||||||
SmellStinky(destination)
|
return
|
||||||
end)
|
end
|
||||||
if Heimdall_Data.config.sniffer.debug then print(string.format("[%s] Module initialized", ModuleName)) end
|
SmellStinky(destination)
|
||||||
|
end)
|
||||||
|
if Heimdall_Data.config.sniffer.debug then
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Module initialized", ModuleName))
|
||||||
end,
|
end
|
||||||
}
|
print("[Heimdall] Sniffer loaded")
|
||||||
|
end
|
||||||
|
@@ -1,238 +1,220 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "Spotter"
|
local ModuleName = "Spotter"
|
||||||
|
|
||||||
---@class HeimdallSpotterConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.Spotter = {}
|
||||||
---@field debug boolean
|
function shared.Spotter.Init()
|
||||||
---@field everyone boolean
|
local function FormatHP(hp)
|
||||||
---@field hostile boolean
|
if hp > 1e9 then
|
||||||
---@field alliance boolean
|
return string.format("%.1fB", hp / 1e9)
|
||||||
---@field stinky boolean
|
elseif hp > 1e6 then
|
||||||
---@field channels string[]
|
return string.format("%.1fM", hp / 1e6)
|
||||||
---@field zoneOverride string?
|
elseif hp > 1e3 then
|
||||||
---@field throttleTime number
|
return string.format("%.1fK", hp / 1e3)
|
||||||
|
else
|
||||||
|
return hp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---@class Spotter
|
---@type table<string, number>
|
||||||
shared.Spotter = {
|
local throttleTable = {}
|
||||||
Init = function()
|
|
||||||
local function FormatHP(hp)
|
---@param unit string
|
||||||
if hp > 1e9 then
|
---@param name string
|
||||||
return string.format("%.1fB", hp / 1e9)
|
---@param faction string
|
||||||
elseif hp > 1e6 then
|
---@param hostile boolean
|
||||||
return string.format("%.1fM", hp / 1e6)
|
---@return boolean
|
||||||
elseif hp > 1e3 then
|
---@return string? error
|
||||||
return string.format("%.1fK", hp / 1e3)
|
local function ShouldNotify(unit, name, faction, hostile)
|
||||||
else
|
if Heimdall_Data.config.spotter.debug then
|
||||||
return hp
|
print(string.format("[%s] Checking notification criteria for %s (%s)", ModuleName, name, faction))
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.agents[name] then
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Skipping agent: %s", ModuleName, name))
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.spotter.stinky then
|
||||||
|
if shared.IsStinky(name) then
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Notifying - Found stinky: %s", ModuleName, name))
|
||||||
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type table<string, number>
|
if Heimdall_Data.config.spotter.alliance then
|
||||||
local throttleTable = {}
|
if faction == "Alliance" then
|
||||||
|
|
||||||
---@param unit string
|
|
||||||
---@param name string
|
|
||||||
---@param faction string
|
|
||||||
---@param hostile boolean
|
|
||||||
---@return boolean
|
|
||||||
---@return string? error
|
|
||||||
local function ShouldNotify(unit, name, faction, hostile)
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Checking notification criteria for %s (%s)", ModuleName, name, faction))
|
|
||||||
end
|
|
||||||
|
|
||||||
if shared.AgentTracker.IsAgent(name) then
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
if Heimdall_Data.config.spotter.debug then
|
||||||
print(string.format("[%s] Skipping agent: %s", ModuleName, name))
|
print(string.format("[%s] Notifying - Found Alliance player: %s", ModuleName, name))
|
||||||
end
|
end
|
||||||
return false
|
return true
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.spotter.stinky then
|
|
||||||
if shared.IsStinky(name) then
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Notifying - Found stinky: %s", ModuleName, name))
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.spotter.alliance then
|
|
||||||
if faction == "Alliance" then
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Notifying - Found Alliance player: %s", ModuleName, name))
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.spotter.hostile then
|
|
||||||
if hostile then
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Notifying - Found hostile player: %s", ModuleName, name))
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Using everyone setting: %s",
|
|
||||||
ModuleName,
|
|
||||||
tostring(Heimdall_Data.config.spotter.everyone)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
return Heimdall_Data.config.spotter.everyone
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param unit string
|
|
||||||
---@return string?
|
|
||||||
local function NotifySpotted(unit)
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Processing spotted unit: %s", ModuleName, unit))
|
|
||||||
end
|
|
||||||
|
|
||||||
if not unit then return string.format("Could not find unit %s", tostring(unit)) end
|
|
||||||
if not UnitIsPlayer(unit) then
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Ignoring non-player unit: %s", ModuleName, unit))
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local name = UnitName(unit)
|
|
||||||
if not name then return string.format("Could not find name for unit %s", tostring(unit)) end
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Processing player: %s", ModuleName, name))
|
|
||||||
end
|
|
||||||
|
|
||||||
local time = GetTime()
|
|
||||||
if throttleTable[name] and time - throttleTable[name] < Heimdall_Data.config.spotter.throttleTime then
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
local remainingTime = Heimdall_Data.config.spotter.throttleTime - (time - throttleTable[name])
|
|
||||||
print(
|
|
||||||
string.format("[%s] Player %s throttled for %.1f more seconds", ModuleName, name, remainingTime)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
return string.format("Throttled %s", tostring(name))
|
|
||||||
end
|
|
||||||
throttleTable[name] = time
|
|
||||||
|
|
||||||
local race = UnitRace(unit)
|
|
||||||
if not race then return string.format("Could not find race for unit %s", tostring(unit)) end
|
|
||||||
local faction = shared.raceMap[race]
|
|
||||||
if not faction then return string.format("Could not find faction for race %s", tostring(race)) end
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Player %s is %s (%s)", ModuleName, name, race, faction))
|
|
||||||
end
|
|
||||||
|
|
||||||
local hostile = UnitCanAttack("player", unit)
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Player %s is %s", ModuleName, name, hostile and "hostile" or "friendly"))
|
|
||||||
end
|
|
||||||
|
|
||||||
local doNotify = ShouldNotify(unit, name, faction, hostile)
|
|
||||||
if not doNotify then
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Skipping notification for %s", ModuleName, name))
|
|
||||||
end
|
|
||||||
return string.format("Not notifying for %s", tostring(name))
|
|
||||||
end
|
|
||||||
|
|
||||||
local hp = UnitHealth(unit)
|
|
||||||
if not hp then return string.format("Could not find hp for unit %s", tostring(unit)) end
|
|
||||||
local maxHp = UnitHealthMax(unit)
|
|
||||||
if not maxHp then return string.format("Could not find maxHp for unit %s", tostring(unit)) end
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Player %s health: %s/%s", ModuleName, name, FormatHP(hp), FormatHP(maxHp)))
|
|
||||||
end
|
|
||||||
|
|
||||||
local class = UnitClass(unit)
|
|
||||||
if not class then return string.format("Could not find class for unit %s", tostring(unit)) end
|
|
||||||
|
|
||||||
local zone, subzone = GetZoneText() or "Unknown", GetSubZoneText() or "Unknown"
|
|
||||||
if Heimdall_Data.config.spotter.zoneOverride then
|
|
||||||
zone = Heimdall_Data.config.spotter.zoneOverride or ""
|
|
||||||
subzone = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local x, y = GetPlayerMapPosition("player")
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Player %s coordinates: %.2f, %.2f", ModuleName, name, x * 100, y * 100))
|
|
||||||
end
|
|
||||||
|
|
||||||
local pvpOn = UnitIsPVP(unit)
|
|
||||||
local stinky = shared.IsStinky(name) or false
|
|
||||||
SetMapToCurrentZone()
|
|
||||||
SetMapByID(GetCurrentMapAreaID())
|
|
||||||
local areaId = tostring(GetCurrentMapAreaID())
|
|
||||||
|
|
||||||
for _, channel in pairs(Heimdall_Data.config.spotter.channels) do
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Processing channel: %s", ModuleName, channel))
|
|
||||||
end
|
|
||||||
local locale = shared.GetLocaleForChannel(channel)
|
|
||||||
local text = string.format(
|
|
||||||
shared._L("spotterSpotted", locale),
|
|
||||||
hostile and shared._L("hostile", locale) or shared._L("friendly", locale),
|
|
||||||
name,
|
|
||||||
shared._L(class, locale),
|
|
||||||
stinky and string.format("(%s)", "!!!!") or "",
|
|
||||||
shared._L(race, locale),
|
|
||||||
shared._L(faction, locale),
|
|
||||||
pvpOn and shared._L("pvpOn", locale) or shared._L("pvpOff", locale),
|
|
||||||
string.gsub(FormatHP(hp), "M", "kk"),
|
|
||||||
string.gsub(FormatHP(maxHp), "M", "kk"),
|
|
||||||
shared._L(zone, locale),
|
|
||||||
shared._L(subzone, locale),
|
|
||||||
areaId,
|
|
||||||
x * 100,
|
|
||||||
y * 100
|
|
||||||
)
|
|
||||||
|
|
||||||
---@type Message
|
|
||||||
local msg = {
|
|
||||||
channel = "C",
|
|
||||||
data = channel,
|
|
||||||
message = text,
|
|
||||||
}
|
|
||||||
if Heimdall_Data.config.spotter.debug then
|
|
||||||
print(string.format("[%s] Queuing spotter message", ModuleName))
|
|
||||||
shared.dump(msg)
|
|
||||||
end
|
|
||||||
table.insert(shared.messenger.queue, msg)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local frame = CreateFrame("Frame")
|
if Heimdall_Data.config.spotter.hostile then
|
||||||
frame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
if hostile then
|
||||||
frame:RegisterEvent("UNIT_TARGET")
|
if Heimdall_Data.config.spotter.debug then
|
||||||
frame:SetScript("OnEvent", function(self, event, unit)
|
print(string.format("[%s] Notifying - Found hostile player: %s", ModuleName, name))
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Using everyone setting: %s", ModuleName,
|
||||||
|
tostring(Heimdall_Data.config.spotter.everyone)))
|
||||||
|
end
|
||||||
|
return Heimdall_Data.config.spotter.everyone
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param unit string
|
||||||
|
---@return string?
|
||||||
|
local function NotifySpotted(unit)
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Processing spotted unit: %s", ModuleName, unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
if not unit then return string.format("Could not find unit %s", tostring(unit)) end
|
||||||
|
if not UnitIsPlayer(unit) then
|
||||||
if Heimdall_Data.config.spotter.debug then
|
if Heimdall_Data.config.spotter.debug then
|
||||||
print(string.format("[%s] Event received: %s for unit: %s", ModuleName, event, unit or "target"))
|
print(string.format("[%s] Ignoring non-player unit: %s", ModuleName, unit))
|
||||||
end
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
if not Heimdall_Data.config.spotter.enabled then
|
local name = UnitName(unit)
|
||||||
if Heimdall_Data.config.spotter.debug then
|
if not name then return string.format("Could not find name for unit %s", tostring(unit)) end
|
||||||
print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
if Heimdall_Data.config.spotter.debug then
|
||||||
end
|
print(string.format("[%s] Processing player: %s", ModuleName, name))
|
||||||
return
|
end
|
||||||
|
|
||||||
|
local time = GetTime()
|
||||||
|
if throttleTable[name] and time - throttleTable[name] < Heimdall_Data.config.spotter.throttleTime then
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
local remainingTime = Heimdall_Data.config.spotter.throttleTime - (time - throttleTable[name])
|
||||||
|
print(string.format("[%s] Player %s throttled for %.1f more seconds", ModuleName, name, remainingTime))
|
||||||
end
|
end
|
||||||
|
return string.format("Throttled %s", tostring(name))
|
||||||
|
end
|
||||||
|
throttleTable[name] = time
|
||||||
|
|
||||||
if event == "UNIT_TARGET" then unit = "target" end
|
local race = UnitRace(unit)
|
||||||
|
if not race then return string.format("Could not find race for unit %s", tostring(unit)) end
|
||||||
|
local faction = shared.raceMap[race]
|
||||||
|
if not faction then return string.format("Could not find faction for race %s", tostring(race)) end
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Player %s is %s (%s)", ModuleName, name, race, faction))
|
||||||
|
end
|
||||||
|
|
||||||
local err = NotifySpotted(unit)
|
local hostile = UnitCanAttack("player", unit)
|
||||||
if err then
|
if Heimdall_Data.config.spotter.debug then
|
||||||
if Heimdall_Data.config.spotter.debug then
|
print(string.format("[%s] Player %s is %s", ModuleName, name, hostile and "hostile" or "friendly"))
|
||||||
print(string.format("[%s] Error processing unit %s: %s", ModuleName, unit, err))
|
end
|
||||||
end
|
|
||||||
|
local doNotify = ShouldNotify(unit, name, faction, hostile)
|
||||||
|
if not doNotify then
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Skipping notification for %s", ModuleName, name))
|
||||||
end
|
end
|
||||||
end)
|
return string.format("Not notifying for %s", tostring(name))
|
||||||
|
end
|
||||||
|
|
||||||
if Heimdall_Data.config.spotter.debug then print(string.format("[%s] Module initialized", ModuleName)) end
|
local hp = UnitHealth(unit)
|
||||||
|
if not hp then return string.format("Could not find hp for unit %s", tostring(unit)) end
|
||||||
|
local maxHp = UnitHealthMax(unit)
|
||||||
|
if not maxHp then return string.format("Could not find maxHp for unit %s", tostring(unit)) end
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Player %s health: %s/%s", ModuleName, name, FormatHP(hp), FormatHP(maxHp)))
|
||||||
|
end
|
||||||
|
|
||||||
|
local class = UnitClass(unit)
|
||||||
|
if not class then return string.format("Could not find class for unit %s", tostring(unit)) end
|
||||||
|
|
||||||
|
local zone, subzone = GetZoneText() or "Unknown", GetSubZoneText() or "Unknown"
|
||||||
|
if Heimdall_Data.config.spotter.zoneOverride then
|
||||||
|
zone = Heimdall_Data.config.spotter.zoneOverride or ""
|
||||||
|
subzone = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local x, y = GetPlayerMapPosition("player")
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Player %s coordinates: %.2f, %.2f", ModuleName, name, x * 100, y * 100))
|
||||||
|
end
|
||||||
|
|
||||||
|
local pvpOn = UnitIsPVP(unit)
|
||||||
|
local stinky = shared.IsStinky(name) or false
|
||||||
|
SetMapToCurrentZone()
|
||||||
|
SetMapByID(GetCurrentMapAreaID())
|
||||||
|
local areaId = tostring(GetCurrentMapAreaID())
|
||||||
|
|
||||||
|
for _, channel in pairs(Heimdall_Data.config.spotter.channels) do
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Processing channel: %s", ModuleName, channel))
|
||||||
|
end
|
||||||
|
local locale = shared.GetLocaleForChannel(channel)
|
||||||
|
local text = string.format(shared._L("spotterSpotted", locale),
|
||||||
|
hostile and shared._L("hostile", locale) or shared._L("friendly", locale),
|
||||||
|
name,
|
||||||
|
shared._L(class, locale),
|
||||||
|
stinky and string.format("(%s)", "!!!!") or "",
|
||||||
|
shared._L(race, locale),
|
||||||
|
shared._L(faction, locale),
|
||||||
|
pvpOn and shared._L("pvpOn", locale) or shared._L("pvpOff", locale),
|
||||||
|
string.gsub(FormatHP(hp), "M", "kk"),
|
||||||
|
string.gsub(FormatHP(maxHp), "M", "kk"),
|
||||||
|
shared._L(zone, locale), shared._L(subzone, locale),
|
||||||
|
areaId,
|
||||||
|
x * 100, y * 100)
|
||||||
|
|
||||||
|
---@type Message
|
||||||
|
local msg = {
|
||||||
|
channel = "C",
|
||||||
|
data = channel,
|
||||||
|
message = text
|
||||||
|
}
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Queuing spotter message", ModuleName))
|
||||||
|
shared.dumpTable(msg)
|
||||||
|
end
|
||||||
|
table.insert(shared.messenger.queue, msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local frame = CreateFrame("Frame")
|
||||||
|
frame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
||||||
|
frame:RegisterEvent("UNIT_TARGET")
|
||||||
|
frame:SetScript("OnEvent", function(self, event, unit)
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Event received: %s for unit: %s", ModuleName, event, unit or "target"))
|
||||||
|
end
|
||||||
|
|
||||||
|
if not Heimdall_Data.config.spotter.enabled then
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if event == "UNIT_TARGET" then
|
||||||
|
unit = "target"
|
||||||
|
end
|
||||||
|
|
||||||
|
local err = NotifySpotted(unit)
|
||||||
|
if err then
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
|
print(string.format("[%s] Error processing unit %s: %s", ModuleName, unit, err))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
if Heimdall_Data.config.spotter.debug then
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Module initialized", ModuleName))
|
||||||
end,
|
end
|
||||||
}
|
print("[Heimdall] Spotter loaded")
|
||||||
|
end
|
||||||
|
@@ -1,83 +1,60 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "StinkyCache"
|
local ModuleName = "StinkyCache"
|
||||||
|
|
||||||
---@class HeimdallStinkyCacheConfig
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field enabled boolean
|
shared.StinkyCache = {}
|
||||||
---@field debug boolean
|
function shared.StinkyCache.Init()
|
||||||
---@field commander string
|
shared.stinkyCache = {
|
||||||
---@field ttl number
|
stinkies = {},
|
||||||
|
}
|
||||||
|
|
||||||
---@class HeimdallStinkyCacheData
|
---@param name string
|
||||||
---@field stinkies table<string, {value: number, timestamp: number}>
|
local function AskCommander(name)
|
||||||
|
if Heimdall_Data.config.stinkyCache.debug then
|
||||||
---@class StinkyCache
|
print(string.format("[%s] Asking commander %s about %s", ModuleName,
|
||||||
shared.StinkyCache = {
|
Heimdall_Data.config.stinkyCache.commander, name))
|
||||||
Init = function()
|
|
||||||
shared.stinkyCache = {
|
|
||||||
stinkies = {},
|
|
||||||
}
|
|
||||||
|
|
||||||
---@param name string
|
|
||||||
local function AskCommander(name)
|
|
||||||
if Heimdall_Data.config.stinkyCache.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Asking commander %s about %s",
|
|
||||||
ModuleName,
|
|
||||||
Heimdall_Data.config.stinkyCache.commander,
|
|
||||||
name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
local messageParts = { "isstinky", name }
|
|
||||||
local message = table.concat(messageParts, "|")
|
|
||||||
SendAddonMessage(
|
|
||||||
Heimdall_Data.config.addonPrefix,
|
|
||||||
message,
|
|
||||||
"WHISPER",
|
|
||||||
Heimdall_Data.config.stinkyCache.commander
|
|
||||||
)
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
local messageParts = { "isstinky", name }
|
||||||
|
local message = table.concat(messageParts, "|")
|
||||||
|
SendAddonMessage(Heimdall_Data.config.addonPrefix,
|
||||||
|
message, "WHISPER",
|
||||||
|
Heimdall_Data.config.stinkyCache.commander)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local addonMessageFrame = CreateFrame("Frame")
|
local addonMessageFrame = CreateFrame("Frame")
|
||||||
addonMessageFrame:RegisterEvent("CHAT_MSG_ADDON")
|
addonMessageFrame:RegisterEvent("CHAT_MSG_ADDON")
|
||||||
addonMessageFrame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
addonMessageFrame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
||||||
if sender == Heimdall_Data.config.stinkyCache.commander then
|
if sender == Heimdall_Data.config.stinkyCache.commander then
|
||||||
if Heimdall_Data.config.stinkyCache.debug then
|
if Heimdall_Data.config.stinkyCache.debug then
|
||||||
print(
|
print(string.format("[%s] Received stinky from commander %s: %s", ModuleName,
|
||||||
string.format(
|
Heimdall_Data.config.stinkyCache.commander, msg))
|
||||||
"[%s] Received stinky from commander %s: %s",
|
|
||||||
ModuleName,
|
|
||||||
Heimdall_Data.config.stinkyCache.commander,
|
|
||||||
msg
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
local parts = { strsplit("|", msg) }
|
|
||||||
local name, value = parts[1], parts[2]
|
|
||||||
shared.stinkyCache.stinkies[name] = { value = value, timestamp = time() }
|
|
||||||
else
|
|
||||||
if Heimdall_Data.config.stinkyCache.debug then
|
|
||||||
print(string.format("[%s] Received stinky from non-commander %s: %s", ModuleName, sender, msg))
|
|
||||||
end
|
|
||||||
local parts = { strsplit("|", msg) }
|
|
||||||
local command, name = parts[1], parts[2]
|
|
||||||
if parts[1] == "isstinky" then local res = Heimdall_Data.config.stinkies[parts[2]] end
|
|
||||||
end
|
end
|
||||||
end)
|
local name, value = {strsplit("|", msg)}
|
||||||
|
shared.stinkyCache.stinkies[name] = { value = value, timestamp = time() }
|
||||||
|
else
|
||||||
|
if Heimdall_Data.config.stinkyCache.debug then
|
||||||
|
print(string.format("[%s] Received stinky from non-commander %s: %s", ModuleName, sender, msg))
|
||||||
|
end
|
||||||
|
local parts = {strsplit("|", msg)}
|
||||||
|
local command, name = parts[1], parts[2]
|
||||||
|
if parts[1] == "isstinky" then
|
||||||
|
local res = Heimdall_Data.config.stinkies[parts[2]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
setmetatable(shared.stinkyCache.stinkies, {
|
setmetatable(shared.stinkyCache.stinkies, {
|
||||||
__index = function(self, key)
|
__index = function(self, key)
|
||||||
local value = rawget(self, key)
|
local value = rawget(self, key)
|
||||||
local now = GetTime()
|
local now = GetTime()
|
||||||
if value == nil or now - value.timestamp > Heimdall_Data.config.stinkyCache.ttl then
|
if value == nil or now - value.timestamp > Heimdall_Data.config.stinkyCache.ttl then
|
||||||
AskCommander(key)
|
AskCommander(key)
|
||||||
end
|
end
|
||||||
return rawget(self, key)
|
return rawget(self, key)
|
||||||
end,
|
end
|
||||||
})
|
})
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print("[Heimdall] StinkyCache module loaded")
|
||||||
end,
|
end
|
||||||
}
|
|
||||||
|
@@ -1,364 +1,261 @@
|
|||||||
local _, shared = ...
|
local addonname, shared = ...
|
||||||
---@cast shared HeimdallShared
|
---@cast shared HeimdallShared
|
||||||
|
---@cast addonname string
|
||||||
local ModuleName = "StinkyTracker"
|
local ModuleName = "StinkyTracker"
|
||||||
|
|
||||||
---@class Stinky
|
---@diagnostic disable-next-line: missing-fields
|
||||||
---@field name string
|
shared.StinkyTracker = {}
|
||||||
---@field class string
|
function shared.StinkyTracker.Init()
|
||||||
---@field seenAt number
|
shared.stinkyTracker = {
|
||||||
---@field hostile boolean
|
stinkies = ReactiveValue.new({})
|
||||||
|
}
|
||||||
|
|
||||||
---@class HeimdallStinkyTrackerConfig
|
local whoRegex = "([^ -/]+)-?%w*/(%w+)"
|
||||||
---@field enabled boolean
|
---@param msg string
|
||||||
---@field debug boolean
|
---@return table<string, stinky>
|
||||||
---@field ignoredTimeout number
|
local function ParseWho(msg)
|
||||||
---@field channels string[]
|
|
||||||
|
|
||||||
---@class StinkyTrackerData
|
|
||||||
---@field stinkies ReactiveValue<table<string, Stinky>>
|
|
||||||
---@field ignored ReactiveValue<table<string, number>>
|
|
||||||
|
|
||||||
---@class StinkyTracker
|
|
||||||
shared.StinkyTracker = {
|
|
||||||
---@param stinky Stinky
|
|
||||||
---@return boolean
|
|
||||||
Track = function(stinky)
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Request to track stinky: %s (%s)", ModuleName, stinky.name, stinky.class))
|
print(string.format("[%s] Parsing WHO message: '%s'", ModuleName, msg))
|
||||||
end
|
end
|
||||||
local ignored = shared.stinkyTracker.ignored[stinky.name]
|
local stinkies = {}
|
||||||
-- TODO: Add a config option for the ignored timeout
|
for name, class in string.gmatch(msg, whoRegex) do
|
||||||
if ignored and ignored > GetTime() - 60 then
|
stinkies[name] = {
|
||||||
|
name = name,
|
||||||
|
class = class,
|
||||||
|
seenAt = GetTime(),
|
||||||
|
hostile = true
|
||||||
|
}
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(
|
print(string.format("[%s] Found hostile player: %s (%s) at %s", ModuleName, name, class,
|
||||||
string.format(
|
date("%H:%M:%S", time())))
|
||||||
"[%s] Stinky is ignored, not tracking: %s (%s)",
|
shared.dumpTable(stinkies)
|
||||||
ModuleName,
|
|
||||||
stinky.name,
|
|
||||||
stinky.class
|
|
||||||
)
|
|
||||||
)
|
|
||||||
shared.dump(shared.stinkyTracker.ignored:get())
|
|
||||||
shared.dump(shared.stinkyTracker.stinkies:get())
|
|
||||||
end
|
end
|
||||||
return false
|
|
||||||
else
|
|
||||||
-- Timed out or was never ignored
|
|
||||||
shared.stinkyTracker.stinkies[stinky.name] = nil
|
|
||||||
end
|
end
|
||||||
|
return stinkies
|
||||||
|
end
|
||||||
|
|
||||||
shared.stinkyTracker.stinkies[stinky.name] = stinky
|
local seeRegex = "I see %((%w+)%) ([^ -/]+)-?%w*/(%w+)"
|
||||||
|
---@param msg string
|
||||||
|
---@return table<string, stinky>
|
||||||
|
local function ParseSee(msg)
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Stinky is now tracked: %s (%s)", ModuleName, stinky.name, stinky.class))
|
print(string.format("[%s] Parsing SEE message: '%s'", ModuleName, msg))
|
||||||
shared.dump(shared.stinkyTracker.stinkies:get())
|
|
||||||
shared.dump(shared.stinkyTracker.ignored:get())
|
|
||||||
end
|
end
|
||||||
return true
|
local stinkies = {}
|
||||||
end,
|
local aggression, name, class = string.match(msg, seeRegex)
|
||||||
|
if not name or not class then
|
||||||
---@param name string
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
---@return nil
|
print(string.format("[%s] Error: Invalid SEE message format", ModuleName))
|
||||||
Ignore = function(name)
|
end
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
return stinkies
|
||||||
print(string.format("[%s] Request to ignore stinky: %s", ModuleName, name))
|
|
||||||
end
|
end
|
||||||
shared.stinkyTracker.ignored[name] = GetTime()
|
local stinky = {
|
||||||
shared.stinkyTracker.stinkies[name] = nil
|
name = name,
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
class = class,
|
||||||
print(string.format("[%s] Stinky is now ignored: %s", ModuleName, name))
|
seenAt = GetTime(),
|
||||||
shared.dump(shared.stinkyTracker.ignored:get())
|
hostile = aggression == "hostile"
|
||||||
shared.dump(shared.stinkyTracker.stinkies:get())
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
---@param name string
|
|
||||||
---@return boolean
|
|
||||||
IsStinky = function(name)
|
|
||||||
if not shared.stinkyTracker.stinkies then return false end
|
|
||||||
if not shared.stinkyTracker.stinkies[name] then return false end
|
|
||||||
if shared.stinkyTracker.ignored[name] then return false end
|
|
||||||
return true
|
|
||||||
end,
|
|
||||||
|
|
||||||
---@param callback fun(stinkies: table<string, Stinky>)
|
|
||||||
---@return nil
|
|
||||||
OnChange = function(callback) shared.stinkyTracker.stinkies:onChange(callback) end,
|
|
||||||
|
|
||||||
---@param callback fun(name: string, stinky: Stinky)
|
|
||||||
---@return nil
|
|
||||||
ForEach = function(callback)
|
|
||||||
---@type table<string, Stinky>
|
|
||||||
local stinkies = shared.stinkyTracker.stinkies:get()
|
|
||||||
for name, stinky in pairs(stinkies) do
|
|
||||||
callback(name, stinky)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
Init = function()
|
|
||||||
shared.stinkyTracker = {
|
|
||||||
stinkies = ReactiveValue.new({}),
|
|
||||||
ignored = ReactiveValue.new({}),
|
|
||||||
}
|
}
|
||||||
|
stinkies[name] = stinky
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Found stinky in SEE: %s (%s) - %s at %s", ModuleName, name, class, aggression,
|
||||||
|
date("%H:%M:%S", time())))
|
||||||
|
shared.dumpTable(stinkies)
|
||||||
|
end
|
||||||
|
return stinkies
|
||||||
|
end
|
||||||
|
|
||||||
local whoRegex = "([^ -/]+)-?%w*/(%w+)"
|
local arrivedRegex = "([^ -/]+)-?%w*; c:([^;]+)"
|
||||||
---@param msg string
|
local arrivedRegexAlt = "([^ -/]+)-?%w*%(!!!!%); c:([^;]+)"
|
||||||
---@return table<string, Stinky>
|
---@param msg string
|
||||||
local function ParseWho(msg)
|
---@return table<string, stinky>
|
||||||
|
local function ParseArrived(msg)
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("%s: Parsing arrived message: %s", ModuleName, msg))
|
||||||
|
end
|
||||||
|
local stinkies = {}
|
||||||
|
local name, class = string.match(msg, arrivedRegex)
|
||||||
|
if not name or not class then
|
||||||
|
name, class = string.match(msg, arrivedRegexAlt)
|
||||||
|
end
|
||||||
|
if not name or not class then
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Parsing WHO message: '%s'", ModuleName, msg))
|
print(string.format("%s: No valid stinky found in arrived message", ModuleName))
|
||||||
end
|
|
||||||
local stinkies = {}
|
|
||||||
for name, class in string.gmatch(msg, whoRegex) do
|
|
||||||
stinkies[name] = {
|
|
||||||
name = name,
|
|
||||||
class = class,
|
|
||||||
seenAt = GetTime(),
|
|
||||||
hostile = true,
|
|
||||||
}
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Found hostile player: %s (%s) at %s",
|
|
||||||
ModuleName,
|
|
||||||
name,
|
|
||||||
class,
|
|
||||||
date("%H:%M:%S", time())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
shared.dump(stinkies)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return stinkies
|
return stinkies
|
||||||
end
|
end
|
||||||
|
local stinky = {
|
||||||
local seeRegex = "I see %((%w+)%) ([^ -/]+)-?%w*/(%w+)"
|
name = name,
|
||||||
---@param msg string
|
class = class,
|
||||||
---@return table<string, Stinky>
|
seenAt = GetTime(),
|
||||||
local function ParseSee(msg)
|
hostile = true
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
}
|
||||||
print(string.format("[%s] Parsing SEE message: '%s'", ModuleName, msg))
|
stinkies[name] = stinky
|
||||||
end
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
local stinkies = {}
|
print(string.format("%s: Found stinky in arrived: %s/%s", ModuleName, name, class))
|
||||||
local aggression, name, class = string.match(msg, seeRegex)
|
shared.dumpTable(stinkies)
|
||||||
if not name or not class then
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Error: Invalid SEE message format", ModuleName))
|
|
||||||
end
|
|
||||||
return stinkies
|
|
||||||
end
|
|
||||||
local stinky = {
|
|
||||||
name = name,
|
|
||||||
class = class,
|
|
||||||
seenAt = GetTime(),
|
|
||||||
hostile = aggression == "hostile",
|
|
||||||
}
|
|
||||||
stinkies[name] = stinky
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(
|
|
||||||
string.format(
|
|
||||||
"[%s] Found stinky in SEE: %s (%s) - %s at %s",
|
|
||||||
ModuleName,
|
|
||||||
name,
|
|
||||||
class,
|
|
||||||
aggression,
|
|
||||||
date("%H:%M:%S", time())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
shared.dump(stinkies)
|
|
||||||
end
|
|
||||||
return stinkies
|
|
||||||
end
|
end
|
||||||
|
return stinkies
|
||||||
|
end
|
||||||
|
|
||||||
local arrivedRegex = "([^ -/]+)-?%w*; c:([^;]+)"
|
local frame = CreateFrame("Frame")
|
||||||
local arrivedRegexAlt = "([^ -/]+)-?%w*%(!!!!%); c:([^;]+)"
|
frame:RegisterEvent("CHAT_MSG_CHANNEL")
|
||||||
---@param msg string
|
frame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
||||||
---@return table<string, Stinky>
|
--if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
local function ParseArrived(msg)
|
-- print(string.format("[%s] Event received: %s from %s", ModuleName, event, sender))
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
--end
|
||||||
print(string.format("%s: Parsing arrived message: %s", ModuleName, msg))
|
if not Heimdall_Data.config.stinkyTracker.enabled then
|
||||||
end
|
|
||||||
local stinkies = {}
|
|
||||||
local name, class = string.match(msg, arrivedRegex)
|
|
||||||
if not name or not class then
|
|
||||||
name, class = string.match(msg, arrivedRegexAlt)
|
|
||||||
end
|
|
||||||
if not name or not class then
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("%s: No valid stinky found in arrived message", ModuleName))
|
|
||||||
end
|
|
||||||
return stinkies
|
|
||||||
end
|
|
||||||
local stinky = {
|
|
||||||
name = name,
|
|
||||||
class = class,
|
|
||||||
seenAt = GetTime(),
|
|
||||||
hostile = true,
|
|
||||||
}
|
|
||||||
stinkies[name] = stinky
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("%s: Found stinky in arrived: %s/%s", ModuleName, name, class))
|
|
||||||
shared.dump(stinkies)
|
|
||||||
end
|
|
||||||
return stinkies
|
|
||||||
end
|
|
||||||
|
|
||||||
local frame = CreateFrame("Frame")
|
|
||||||
frame:RegisterEvent("CHAT_MSG_CHANNEL")
|
|
||||||
frame:SetScript("OnEvent", function(self, event, msg, sender, ...)
|
|
||||||
--if Heimdall_Data.config.stinkyTracker.debug then
|
--if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
-- print(string.format("[%s] Event received: %s from %s", ModuleName, event, sender))
|
-- print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
||||||
--end
|
--end
|
||||||
if not Heimdall_Data.config.stinkyTracker.enabled then
|
return
|
||||||
--if Heimdall_Data.config.stinkyTracker.debug then
|
end
|
||||||
-- print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
local channelId = select(6, ...)
|
||||||
--end
|
local _, channelname = GetChannelName(channelId)
|
||||||
return
|
local ok = false
|
||||||
end
|
for _, channel in pairs(Heimdall_Data.config.stinkyTracker.channels) do
|
||||||
local channelId = select(6, ...)
|
if channel == channelname then
|
||||||
local _, channelname = GetChannelName(channelId)
|
ok = true
|
||||||
local ok = false
|
break
|
||||||
for _, channel in pairs(Heimdall_Data.config.stinkyTracker.channels) do
|
|
||||||
if channel == channelname then
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not ok then
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Ignoring message from non-master channel: %s", ModuleName, channelname))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
if not ok then
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Processing message from master channel: %s", ModuleName, sender))
|
print(string.format("[%s] Ignoring message from non-master channel: %s", ModuleName, channelname))
|
||||||
shared.dump(Heimdall_Data.config.stinkyTracker)
|
|
||||||
end
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Processing message from master channel: %s", ModuleName, sender))
|
||||||
|
shared.dumpTable(Heimdall_Data.config.stinkyTracker)
|
||||||
|
end
|
||||||
|
|
||||||
local stinkies = {}
|
if string.find(msg, "^who:") then
|
||||||
if string.find(msg, "^who:") then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
print(string.format("[%s] Processing WHO message from %s", ModuleName, sender))
|
||||||
print(string.format("[%s] Processing WHO message from %s", ModuleName, sender))
|
|
||||||
end
|
|
||||||
local whoStinkies = ParseWho(msg)
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Found stinkies in WHO message", ModuleName))
|
|
||||||
shared.dump(whoStinkies)
|
|
||||||
end
|
|
||||||
for name, stinky in pairs(whoStinkies) do
|
|
||||||
stinkies[name] = stinky
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
if string.find(msg, "^I see") then
|
local whoStinkies = ParseWho(msg)
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Processing SEE message from %s", ModuleName, sender))
|
print(string.format("[%s] Found stinkies in WHO message", ModuleName))
|
||||||
end
|
|
||||||
local seeStinkies = ParseSee(msg)
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Found stinkies in SEE message", ModuleName))
|
|
||||||
shared.dump(seeStinkies)
|
|
||||||
end
|
|
||||||
for name, stinky in pairs(seeStinkies) do
|
|
||||||
stinkies[name] = stinky
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
if string.find(msg, "arrived to") or string.find(msg, "moved to") then
|
for name, stinky in pairs(whoStinkies) do
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if stinky.hostile then
|
||||||
print(string.format("[%s] Processing ARRIVED message from %s", ModuleName, sender))
|
|
||||||
end
|
|
||||||
local arrivedStinkies = ParseArrived(msg)
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Found stinkies in ARRIVED message", ModuleName))
|
|
||||||
shared.dump(arrivedStinkies)
|
|
||||||
end
|
|
||||||
for name, stinky in pairs(arrivedStinkies) do
|
|
||||||
stinkies[name] = stinky
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for name, stinky in pairs(stinkies) do
|
|
||||||
if shared.stinkyTracker.ignored[name] then
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Ignoring stinky: %s (%s)", ModuleName, name, stinky.class))
|
|
||||||
end
|
|
||||||
shared.stinkyTracker.ignored[name] = nil
|
|
||||||
else
|
|
||||||
shared.stinkyTracker.stinkies[name] = stinky
|
shared.stinkyTracker.stinkies[name] = stinky
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Added stinky: %s (%s)", ModuleName, name, stinky.class))
|
print(string.format("[%s] Added hostile stinky from WHO: %s (%s)", ModuleName, name, stinky
|
||||||
|
.class))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
-- Log total stinky count after processing
|
if string.find(msg, "^I see") then
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
local count = 0
|
print(string.format("[%s] Processing SEE message from %s", ModuleName, sender))
|
||||||
for _ in pairs(shared.stinkyTracker.stinkies:get()) do
|
|
||||||
count = count + 1
|
|
||||||
end
|
|
||||||
print(string.format("[%s] Current total stinkies tracked: %d", ModuleName, count))
|
|
||||||
end
|
end
|
||||||
|
local seeStinkies = ParseSee(msg)
|
||||||
shared.StinkyTracker.ForEach(function(name, stinky)
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
if shared.AgentTracker.IsAgent(name) then
|
print(string.format("[%s] Found stinkies in SEE message", ModuleName))
|
||||||
|
end
|
||||||
|
for name, stinky in pairs(seeStinkies) do
|
||||||
|
if stinky.hostile then
|
||||||
|
shared.stinkyTracker.stinkies[name] = stinky
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Added hostile stinky from SEE: %s (%s)", ModuleName, name, stinky
|
||||||
|
.class))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not stinky.hostile then
|
||||||
shared.stinkyTracker.stinkies[name] = nil
|
shared.stinkyTracker.stinkies[name] = nil
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Removed agent from stinkies: %s", ModuleName, name))
|
print(string.format("[%s] Removed non-hostile stinky from SEE: %s", ModuleName, name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end
|
||||||
end)
|
end
|
||||||
|
if string.find(msg, "arrived to") or string.find(msg, "moved to") then
|
||||||
local targetFrame = CreateFrame("Frame")
|
|
||||||
targetFrame:RegisterEvent("UNIT_TARGET")
|
|
||||||
targetFrame:SetScript("OnEvent", function(self, event, unit)
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Event received: %s for unit: %s", ModuleName, event, unit or "target"))
|
print(string.format("[%s] Processing ARRIVED message from %s", ModuleName, sender))
|
||||||
end
|
end
|
||||||
unit = "target"
|
local arrivedStinkies = ParseArrived(msg)
|
||||||
|
|
||||||
if not Heimdall_Data.config.stinkyTracker.enabled then
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local name = UnitName(unit)
|
|
||||||
if not UnitIsPlayer(unit) then
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Target %s is not a player, nothing to do", ModuleName, name))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local enemy = UnitCanAttack("player", unit)
|
|
||||||
if enemy then
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Target %s is enemy - tracking as stinky", ModuleName, name))
|
|
||||||
end
|
|
||||||
shared.stinkyTracker.stinkies[name] = {
|
|
||||||
name = name,
|
|
||||||
class = UnitClass(unit),
|
|
||||||
seenAt = GetTime(),
|
|
||||||
hostile = true,
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if not shared.stinkyTracker.stinkies[name] then
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
|
||||||
print(string.format("[%s] Target %s is friendly and not stinky, nothing to do", ModuleName, name))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Target %s is friendly and stinky - removing from stinkies", ModuleName, name))
|
print(string.format("[%s] Found stinkies in ARRIVED message", ModuleName))
|
||||||
end
|
end
|
||||||
shared.stinkyTracker.stinkies[name] = nil
|
for name, stinky in pairs(arrivedStinkies) do
|
||||||
end)
|
shared.stinkyTracker.stinkies[name] = stinky
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Added stinky from ARRIVED: %s (%s)", ModuleName, name, stinky.class))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if Heimdall_Data.config.stinkyTracker.debug then print(string.format("[%s] Module initialized", ModuleName)) end
|
-- Log total stinky count after processing
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
local count = 0
|
||||||
|
for _ in pairs(shared.stinkyTracker.stinkies:get()) do count = count + 1 end
|
||||||
|
print(string.format("[%s] Current total stinkies tracked: %d", ModuleName, count))
|
||||||
|
end
|
||||||
|
|
||||||
|
for name, stinky in pairs(shared.stinkyTracker.stinkies) do
|
||||||
|
if Heimdall_Data.config.agents[name] then
|
||||||
|
shared.stinkyTracker.stinkies[name] = nil
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Removed agent from stinkies: %s", ModuleName, name))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
local targetFrame = CreateFrame("Frame")
|
||||||
|
targetFrame:RegisterEvent("UNIT_TARGET")
|
||||||
|
targetFrame:SetScript("OnEvent", function(self, event, unit)
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Event received: %s for unit: %s", ModuleName, event, unit or "target"))
|
||||||
|
end
|
||||||
|
local unit = "target"
|
||||||
|
|
||||||
|
if not Heimdall_Data.config.stinkyTracker.enabled then
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = UnitName(unit)
|
||||||
|
if not UnitIsPlayer(unit) then
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Target %s is not a player, nothing to do", ModuleName, name))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local enemy = UnitCanAttack("player", unit)
|
||||||
|
if enemy then
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Target %s is enemy - tracking as stinky", ModuleName, name))
|
||||||
|
end
|
||||||
|
shared.stinkyTracker.stinkies[name] = {
|
||||||
|
name = name,
|
||||||
|
class = UnitClass(unit),
|
||||||
|
seenAt = GetTime(),
|
||||||
|
hostile = true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if not shared.stinkyTracker.stinkies[name] then
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Target %s is friendly and not stinky, nothing to do", ModuleName, name))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
|
print(string.format("[%s] Target %s is friendly and stinky - removing from stinkies", ModuleName, name))
|
||||||
|
end
|
||||||
|
shared.stinkyTracker.stinkies[name] = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
if Heimdall_Data.config.stinkyTracker.debug then
|
||||||
print(string.format("[%s] Module initialized", ModuleName))
|
print(string.format("[%s] Module initialized", ModuleName))
|
||||||
end,
|
end
|
||||||
}
|
print("[Heimdall] StinkyTracker loaded")
|
||||||
|
end
|
||||||
|
1219
Modules/Whoer.lua
1219
Modules/Whoer.lua
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,9 @@ local function StringToMap(str, deliminer)
|
|||||||
local parts = { strsplit(deliminer, str) }
|
local parts = { strsplit(deliminer, str) }
|
||||||
for _, line in ipairs(parts) do
|
for _, line in ipairs(parts) do
|
||||||
line = strtrim(line)
|
line = strtrim(line)
|
||||||
if line ~= "" then map[line] = true end
|
if line ~= "" then
|
||||||
|
map[line] = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return map
|
return map
|
||||||
end
|
end
|
||||||
@@ -19,7 +21,9 @@ local function StringToArray(str, deliminer)
|
|||||||
local array = { strsplit(deliminer, str) }
|
local array = { strsplit(deliminer, str) }
|
||||||
for i, line in ipairs(array) do
|
for i, line in ipairs(array) do
|
||||||
line = strtrim(line)
|
line = strtrim(line)
|
||||||
if line ~= "" then ret[i] = line end
|
if line ~= "" then
|
||||||
|
ret[i] = line
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
@@ -35,7 +39,7 @@ local config = {
|
|||||||
stinky = aura_env.config.spotter.stinky,
|
stinky = aura_env.config.spotter.stinky,
|
||||||
notifyChannel = aura_env.config.spotter.notifyChannel,
|
notifyChannel = aura_env.config.spotter.notifyChannel,
|
||||||
zoneOverride = aura_env.config.spotter.zoneOverride,
|
zoneOverride = aura_env.config.spotter.zoneOverride,
|
||||||
throttleTime = aura_env.config.spotter.throttleTime,
|
throttleTime = aura_env.config.spotter.throttleTime
|
||||||
},
|
},
|
||||||
who = {
|
who = {
|
||||||
enabled = aura_env.config.who.enabled,
|
enabled = aura_env.config.who.enabled,
|
||||||
|
2
_L.lua
2
_L.lua
@@ -90,7 +90,6 @@ shared._Locale = {
|
|||||||
updateInterval = "Update Interval",
|
updateInterval = "Update Interval",
|
||||||
networkMessenger = "Network Messenger",
|
networkMessenger = "Network Messenger",
|
||||||
queries = "Who queries",
|
queries = "Who queries",
|
||||||
chatSniffer = "Chat Sniffer",
|
|
||||||
},
|
},
|
||||||
ru = {
|
ru = {
|
||||||
bonkDetected = "%s ударил %s (%s)",
|
bonkDetected = "%s ударил %s (%s)",
|
||||||
@@ -176,7 +175,6 @@ shared._Locale = {
|
|||||||
updateInterval = "Интервал Обновления",
|
updateInterval = "Интервал Обновления",
|
||||||
networkMessenger = "Сетевой Мессенджер",
|
networkMessenger = "Сетевой Мессенджер",
|
||||||
queries = "Запросы Who",
|
queries = "Запросы Who",
|
||||||
chatSniffer = "Сниффер Чата",
|
|
||||||
["Orgrimmar"] = "Оргриммар",
|
["Orgrimmar"] = "Оргриммар",
|
||||||
["Valley of Strength"] = "Долина Силы",
|
["Valley of Strength"] = "Долина Силы",
|
||||||
["Valley of Trials"] = "Долина Испытаний",
|
["Valley of Trials"] = "Долина Испытаний",
|
||||||
|
90
release.sh
90
release.sh
@@ -1,61 +1,43 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
echo "Figuring out the tag..."
|
# Default version increment
|
||||||
TAG=$(git describe --tags --exact-match 2>/dev/null || echo "")
|
DEFAULT_INCREMENT="0.0.1"
|
||||||
if [ -z "$TAG" ]; then
|
|
||||||
# Get the latest tag
|
|
||||||
LATEST_TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
|
|
||||||
# Increment the patch version
|
|
||||||
IFS='.' read -r -a VERSION_PARTS <<< "$LATEST_TAG"
|
|
||||||
VERSION_PARTS[2]=$((VERSION_PARTS[2]+1))
|
|
||||||
TAG="${VERSION_PARTS[0]}.${VERSION_PARTS[1]}.${VERSION_PARTS[2]}"
|
|
||||||
# Create a new tag
|
|
||||||
git tag $TAG
|
|
||||||
fi
|
|
||||||
echo "Tag: $TAG"
|
|
||||||
|
|
||||||
echo "Building the thing..."
|
# Get the increment parameter or use the default
|
||||||
sed -i "s/## Version: .*/## Version: $TAG/" Heimdall.toc
|
INCREMENT=${1:-$DEFAULT_INCREMENT}
|
||||||
sed -i "s/local VERSION = .*/local VERSION = \"$TAG\"/" Heimdall.lua
|
|
||||||
git add Heimdall.toc Heimdall.lua
|
|
||||||
git commit -m "Release $TAG"
|
|
||||||
git tag -f $TAG
|
|
||||||
git push origin $TAG
|
|
||||||
|
|
||||||
rm Heimdall-${TAG}.zip
|
# Function to increment the version
|
||||||
mkdir Heimdall
|
increment_version() {
|
||||||
cp *.lua *.toc Heimdall
|
local version=$1
|
||||||
cp -r Modules Heimdall
|
local increment=$2
|
||||||
cp -r Sounds Heimdall
|
|
||||||
cp -r Texture Heimdall
|
|
||||||
7z a Heimdall-${TAG}.zip Heimdall
|
|
||||||
rm -rf Heimdall
|
|
||||||
|
|
||||||
echo "Creating a release..."
|
IFS='.' read -r -a version_parts <<< "$version"
|
||||||
TOKEN="$GITEA_API_KEY"
|
IFS='.' read -r -a increment_parts <<< "$increment"
|
||||||
GITEA="https://git.site.quack-lab.dev"
|
|
||||||
REPO="dave/wow-heimdall"
|
|
||||||
# Create a release
|
|
||||||
RELEASE_RESPONSE=$(curl -s -X POST \
|
|
||||||
-H "Authorization: token $TOKEN" \
|
|
||||||
-H "Accept: application/json" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"tag_name": "'"$TAG"'",
|
|
||||||
"name": "'"$TAG"'",
|
|
||||||
"draft": false,
|
|
||||||
"prerelease": false
|
|
||||||
}' \
|
|
||||||
$GITEA/api/v1/repos/$REPO/releases)
|
|
||||||
|
|
||||||
# Extract the release ID
|
# Increment major, minor, and patch
|
||||||
echo $RELEASE_RESPONSE
|
version_parts[0]=$((version_parts[0] + increment_parts[0]))
|
||||||
RELEASE_ID=$(echo $RELEASE_RESPONSE | awk -F'"id":' '{print $2+0; exit}')
|
version_parts[1]=$((version_parts[1] + increment_parts[1]))
|
||||||
echo "Release ID: $RELEASE_ID"
|
version_parts[2]=$((version_parts[2] + increment_parts[2]))
|
||||||
|
|
||||||
echo "Uploading the things..."
|
# Reset minor and patch if major is incremented
|
||||||
curl -X POST \
|
if [ "${increment_parts[0]}" -gt 0 ]; then
|
||||||
-H "Authorization: token $TOKEN" \
|
version_parts[1]=0
|
||||||
-F "attachment=@Heimdall-${TAG}.zip" \
|
version_parts[2]=0
|
||||||
"$GITEA/api/v1/repos/$REPO/releases/${RELEASE_ID}/assets?name=Heimdall-${TAG}.zip"
|
elif [ "${increment_parts[1]}" -gt 0 ]; then
|
||||||
rm Heimdall-${TAG}.zip
|
version_parts[2]=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${version_parts[0]}.${version_parts[1]}.${version_parts[2]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
CURRENT_VERSION=$(grep -oP '## Version: \K[0-9]+\.[0-9]+\.[0-9]+' Heimdall.toc)
|
||||||
|
NEW_VERSION=$(increment_version "$CURRENT_VERSION" "$INCREMENT")
|
||||||
|
sed -i "s/## Version: $CURRENT_VERSION/## Version: $NEW_VERSION/" Heimdall.toc
|
||||||
|
sed -i "s/local VERSION = \"$CURRENT_VERSION\"/local VERSION = \"$NEW_VERSION\"/" Heimdall.lua
|
||||||
|
|
||||||
|
# Git operations
|
||||||
|
git add Heimdall.lua Heimdall.toc
|
||||||
|
git commit -m "Release $NEW_VERSION"
|
||||||
|
git tag "$NEW_VERSION"
|
||||||
|
|
||||||
|
echo "Deployment complete. New version: $NEW_VERSION"
|
12
stylua.toml
12
stylua.toml
@@ -1,12 +0,0 @@
|
|||||||
syntax = "All" # Specify a disambiguation for the style of Lua syntax being formatted. Possible options: All (default), Lua51, Lua52, Lua53, Lua54, LuaJIT, Luau, CfxLua
|
|
||||||
column_width = 120 # Approximate line length for printing. Used as a guide for line wrapping - this is not a hard requirement: lines may fall under or over the limit.
|
|
||||||
line_endings = "Windows" # Line endings type. Possible options: Unix (LF) or Windows (CRLF)
|
|
||||||
indent_type = "Tabs" # Indent type. Possible options: Tabs or Spaces
|
|
||||||
indent_width = 4 # Character size of single indentation. If indent_type is set to Tabs, this option is used as a heuristic to determine column width only.
|
|
||||||
quote_style = "AutoPreferDouble" # Quote style for string literals. Possible options: AutoPreferDouble, AutoPreferSingle, ForceDouble, ForceSingle. AutoPrefer styles will prefer the specified quote style, but fall back to the alternative if it has fewer string escapes. Force styles always use the specified style regardless of escapes.
|
|
||||||
call_parentheses = "Always" # Whether parentheses should be applied on function calls with a single string/table argument. Possible options: Always, NoSingleString, NoSingleTable, None, Input. Always applies parentheses in all cases. NoSingleString omits parentheses on calls with a single string argument. Similarly, NoSingleTable omits parentheses on calls with a single table argument. None omits parentheses in both cases. Note: parentheses are still kept in situations where removal can lead to obscurity (e.g. foo "bar".setup -> foo("bar").setup, since the index is on the call result, not the string). Input removes all automation and preserves parentheses only if they were present in input code: consistency is not enforced.
|
|
||||||
space_after_function_names = "Never" # Specify whether to add a space between the function name and parentheses. Possible options: Never, Definitions, Calls, or Always
|
|
||||||
collapse_simple_statement = "Always" # Specify whether to collapse simple statements. Possible options: Never, FunctionOnly, ConditionalOnly, or Always
|
|
||||||
|
|
||||||
[sort_requires]
|
|
||||||
enabled = false
|
|
Reference in New Issue
Block a user