diff --git a/WeakAuras/GenericTrigger.lua b/WeakAuras/GenericTrigger.lua index 14fc0e2..7570369 100644 --- a/WeakAuras/GenericTrigger.lua +++ b/WeakAuras/GenericTrigger.lua @@ -2937,14 +2937,18 @@ function WeakAuras.WatchUnitChange(unit) eventsToSend["UNIT_CHANGED_" .. unitA] = unitA if watchUnitChange.GUIDToUnitIds[oldGUID] then for unitB in pairs(watchUnitChange.GUIDToUnitIds[oldGUID]) do - eventsToSend["UNIT_IS_UNIT_CHANGED_" .. unitA .. "_" .. unitB] = unitA - eventsToSend["UNIT_IS_UNIT_CHANGED_" .. unitB .. "_" .. unitA] = unitB + if unitA ~= unitB then + eventsToSend["UNIT_IS_UNIT_CHANGED_" .. unitA .. "_" .. unitB] = unitA + eventsToSend["UNIT_IS_UNIT_CHANGED_" .. unitB .. "_" .. unitA] = unitB + end end end if watchUnitChange.GUIDToUnitIds[newGUID] then for unitB in pairs(watchUnitChange.GUIDToUnitIds[newGUID]) do - eventsToSend["UNIT_IS_UNIT_CHANGED_" .. unitA .. "_" .. unitB] = unitA - eventsToSend["UNIT_IS_UNIT_CHANGED_" .. unitB .. "_" .. unitA] = unitB + if unitA ~= unitB then + eventsToSend["UNIT_IS_UNIT_CHANGED_" .. unitA .. "_" .. unitB] = unitA + eventsToSend["UNIT_IS_UNIT_CHANGED_" .. unitB .. "_" .. unitA] = unitB + end end end end @@ -3005,64 +3009,44 @@ function WeakAuras.WatchUnitChange(unit) end end + local function handleUnit(unit, eventsToSend, ...) + if watchUnitChange.trackedUnits[unit] then + local fn + for i = 1, select("#", ...) do + fn = select(i, ...) + fn(unit, eventsToSend) + end + end + end + watchUnitChange:SetScript("OnEvent", function(self, event, unit) Private.StartProfileSystem("generictrigger unit change"); local eventsToSend = {} if event == "PLAYER_ENTERING_WORLD" then for unit in pairs(watchUnitChange.unitIdToGUID) do - unitUpdate(unit, eventsToSend) - markerUpdate(unit, eventsToSend) - reactionUpdate(unit, eventsToSend) + handleUnit(unit, eventsToSend, unitUpdate, markerUpdate, reactionUpdate) end elseif event == "NAME_PLATE_UNIT_ADDED" then - if not watchUnitChange.trackedUnits[unit] then - Private.StopProfileSystem("generictrigger unit change"); - return - end - unitUpdate(unit, eventsToSend) - markerInit(unit) - reactionInit(unit) + handleUnit(unit, eventsToSend, unitUpdate, markerInit, reactionInit) elseif event == "NAME_PLATE_UNIT_REMOVED" then - if not watchUnitChange.trackedUnits[unit] then - Private.StopProfileSystem("generictrigger unit change"); - return - end - unitUpdate(unit, eventsToSend) - markerClear(unit) - reactionClear(unit) + handleUnit(unit, eventsToSend, unitUpdate, markerClear, reactionClear) elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then for i = 1, 5 do - local unit = "boss" .. i - if watchUnitChange.trackedUnits[unit] then - unitUpdate(unit, eventsToSend) - markerInit(unit) - reactionInit(unit) - end + handleUnit("boss" .. i, eventsToSend, unitUpdate, markerInit, reactionInit) + handleUnit("boss" .. i .. "target", eventsToSend, unitUpdate, markerInit, reactionInit) end elseif event == "PLAYER_TARGET_CHANGED" then - if not watchUnitChange.trackedUnits["target"] then - Private.StopProfileSystem("generictrigger unit change"); - return - end - unitUpdate("target", eventsToSend) - markerInit("target") - reactionInit("target") + handleUnit("target", eventsToSend, unitUpdate, markerInit, reactionInit) + handleUnit("targettarget", eventsToSend, unitUpdate, markerInit, reactionInit) elseif event == "PLAYER_FOCUS_CHANGED" then - if not watchUnitChange.trackedUnits["focus"] then - Private.StopProfileSystem("generictrigger unit change"); - return - end - unitUpdate("focus", eventsToSend) - markerInit("focus") - reactionInit("focus") + handleUnit("focus", eventsToSend, unitUpdate, markerInit, reactionInit) + handleUnit("focustarget", eventsToSend, unitUpdate, markerInit, reactionInit) elseif event == "RAID_TARGET_UPDATE" then for unit in pairs(watchUnitChange.raidmark) do - markerUpdate(unit, eventsToSend) + handleUnit(unit, eventsToSend, markerUpdate) end elseif event == "UNIT_FACTION" then - if watchUnitChange.trackedUnits[unit] then - reactionUpdate(unit, eventsToSend) - end + handleUnit(unit, eventsToSend, reactionUpdate) elseif event == "UNIT_PET" then local pet = WeakAuras.unitToPetUnit[unit] if pet and watchUnitChange.trackedUnits[pet] then @@ -3070,26 +3054,13 @@ function WeakAuras.WatchUnitChange(unit) end elseif event == "PLAYER_ROLES_ASSIGNED" then for unit in pairs(Private.multiUnitUnits.group) do - if watchUnitChange.trackedUnits[unit] then - roleUpdate(unit, eventsToSend) - end + handleUnit(unit, eventsToSend, roleUpdate) end elseif event == "UNIT_TARGET" then - local unitTarget = unit .. "target" - if not watchUnitChange.trackedUnits[unitTarget] then - Private.StopProfileSystem("generictrigger unit change"); - return - end - unitUpdate(unitTarget, eventsToSend) - markerInit(unitTarget) - reactionInit(unitTarget) + handleUnit(unit .. "target", eventsToSend, unitUpdate, markerInit, reactionInit) elseif event == "PARTY_MEMBERS_CHANGED" or event == "RAID_ROSTER_UPDATE" then for unit in pairs(Private.multiUnitUnits.group) do - if watchUnitChange.trackedUnits[unit] then - unitUpdate(unit, eventsToSend) - markerInit(unit, eventsToSend) - reactionInit(unit, eventsToSend) - end + handleUnit(unit, eventsToSend, unitUpdate, markerInit, reactionInit) end local inRaid = IsInRaid() local inRaidChanged = inRaid ~= watchUnitChange.inRaid diff --git a/WeakAuras/Modernize.lua b/WeakAuras/Modernize.lua index dfb0f50..40e13e1 100644 --- a/WeakAuras/Modernize.lua +++ b/WeakAuras/Modernize.lua @@ -3,7 +3,7 @@ local AddonName, Private = ... local L = WeakAuras.L -- Takes as input a table of display data and attempts to update it to be compatible with the current version -function Private.Modernize(data) +function Private.Modernize(data, oldSnapshot) if not data.internalVersion or data.internalVersion < 2 then WeakAuras.prettyPrint(string.format("Data for '%s' is too old, can't modernize.", data.id)) data.internalVersion = 2 @@ -1504,5 +1504,45 @@ function Private.Modernize(data) end end + if data.internalVersion < 75 then + -- this commit from nov 2019 https://github.com/WeakAuras/WeakAuras2/commit/6d8f11c17422aeffdb82a0aa05181edfdd137896 + -- changed adjustedMin & adjustedMax type from number to string (range => input) + -- but didn't include a migration + if type(data.adjustedMin) == "number" then + data.adjustedMin = tostring(data.adjustedMin) + end + if type(data.adjustedMax) == "number" then + data.adjustedMax = tostring(data.adjustedMax) + end + -- this commit https://github.com/WeakAuras/WeakAuras2/commit/dbcb70b1e4df262af82f63620b3b0d80741e6df2 + -- set a default for adjustedMin & adjustedMax with an empty string + -- in Private.validate if type of value is different from type of default, value is set to default + -- which had effect to lose data if aura was made before nov 2019 ~ 2020 + -- try detect data loss and restore from Archivist + if data.internalVersion == 74 and oldSnapshot then + local restoreMin = data.useAdjustededMin and data.adjustedMin == "" + local restoreMax = data.useAdjustededMax and data.adjustedMax == "" + if restoreMin or restoreMax then + if restoreMin and type(oldSnapshot.adjustedMin) == "number" then + data.adjustedMin = tostring(oldSnapshot.adjustedMin) + end + if restoreMax and type(oldSnapshot.adjustedMax) == "number" then + data.adjustedMax = tostring(oldSnapshot.adjustedMax) + end + end + end + end + data.internalVersion = max(data.internalVersion or 0, WeakAuras.InternalVersion()) end + +--- Returns true if Modernize will use data from last snapshot before a new one is done +function Private.ModernizeNeedsOldSnapshot(data) + if data.internalVersion == 74 then + local restoreMin = data.useAdjustededMin and data.adjustedMin == "" + local restoreMax = data.useAdjustededMax and data.adjustedMax == "" + if restoreMin or restoreMax then + return true + end + end +end diff --git a/WeakAuras/Prototypes.lua b/WeakAuras/Prototypes.lua index 01f7868..db4ec37 100644 --- a/WeakAuras/Prototypes.lua +++ b/WeakAuras/Prototypes.lua @@ -4067,9 +4067,11 @@ Private.event_prototypes = { ["Cooldown Ready (Equipment Slot)"] = { type = "item", events = {}, - internal_events = { - "ITEM_SLOT_COOLDOWN_READY" - }, + internal_events = function(trigger) + return { + "ITEM_SLOT_COOLDOWN_READY:" .. (trigger.itemSlot or 0) + } + end, name = L["Cooldown Ready Event (Slot)"], loadFunc = function(trigger) WeakAuras.WatchItemSlotCooldown(trigger.itemSlot); diff --git a/WeakAuras/SubRegionTypes/Glow.lua b/WeakAuras/SubRegionTypes/Glow.lua index 7baee07..5c21662 100644 --- a/WeakAuras/SubRegionTypes/Glow.lua +++ b/WeakAuras/SubRegionTypes/Glow.lua @@ -359,7 +359,7 @@ function Private.getDefaultGlow(regionType) glowYOffset = 0, glow_anchor = "bar" } - elseif regionType == "icon" then + else return { ["type"] = "subglow", glow = false, @@ -378,9 +378,14 @@ function Private.getDefaultGlow(regionType) end end +local supportedRegion = { + icon = true, + aurabar = true, + texture = true, + progresstexture = true +} local function supports(regionType) - return regionType == "icon" - or regionType == "aurabar" + return supportedRegion[regionType] end local function addDefaultsForNewAura(data) diff --git a/WeakAuras/Transmission.lua b/WeakAuras/Transmission.lua index 53b6176..13ae159 100644 --- a/WeakAuras/Transmission.lua +++ b/WeakAuras/Transmission.lua @@ -377,8 +377,60 @@ function Private.DisplayToString(id, forChat) end end -local function recurseStringify(data, level, lines) - for k, v in pairs(data) do +local orderedPairs +do + local function __genOrderedIndex(t) + local orderedIndex = {} + for key in pairs(t) do + if key ~= "__orderedIndex" then + table.insert(orderedIndex, key) + end + end + table.sort(orderedIndex, function(a, b) + local typeA, typeB = type(a), type(b) + if typeA ~= typeB then + return typeA < typeB + else + return a < b + end + end) + return orderedIndex + end + + local function orderedNext(t, state) + -- Equivalent of the next function, but returns the keys in the alphabetic + -- order. We use a temporary ordered key table that is stored in the + -- table being iterated. + local key = nil + if state == nil then + -- the first time, generate the index + t.__orderedIndex = __genOrderedIndex(t) + key = t.__orderedIndex[1] + else + -- fetch the next value + for i = 1, table.getn(t.__orderedIndex) do + if t.__orderedIndex[i] == state then + key = t.__orderedIndex[i+1] + end + end + end + + if key then + return key, t[key] + end + + -- no more value to return, cleanup + t.__orderedIndex = nil + end + + function orderedPairs(t) + return orderedNext, t, nil + end +end + +local function recurseStringify(data, level, lines, sorted) + local pairsFn = sorted and orderedPairs or pairs + for k, v in pairsFn(data) do local lineFormat = strrep(" ", level) .. "[%s] = %s" local form1, form2, value local kType, vType = type(k), type(v) @@ -401,7 +453,7 @@ local function recurseStringify(data, level, lines) lineFormat = lineFormat:format(form1, form2) if vType == "table" then tinsert(lines, lineFormat:format(k, "{")) - recurseStringify(v, level + 1, lines) + recurseStringify(v, level + 1, lines, sorted) tinsert(lines, strrep(" ", level) .. "},") else tinsert(lines, lineFormat:format(k, v) .. ",") @@ -409,16 +461,16 @@ local function recurseStringify(data, level, lines) end end -function Private.DataToString(id) +function Private.DataToString(id, sorted) local data = WeakAuras.GetData(id) if data then - return Private.SerializeTable(data):gsub("|", "||") + return Private.SerializeTable(data, sorted):gsub("|", "||") end end -function Private.SerializeTable(data) +function Private.SerializeTable(data, sorted) local lines = {"{"} - recurseStringify(data, 1, lines) + recurseStringify(data, 1, lines, sorted) tinsert(lines, "}") return table.concat(lines, "\n") end diff --git a/WeakAuras/Types.lua b/WeakAuras/Types.lua index 79918a1..f726790 100644 --- a/WeakAuras/Types.lua +++ b/WeakAuras/Types.lua @@ -2349,9 +2349,24 @@ LSM.RegisterCallback(WeakAuras, "LibSharedMedia_Registered", function(_, mediaty Private.sound_types[path] = key Private.sound_file_types[path] = key end + elseif mediatype == "statusbar" then + local path = LSM:Fetch(mediatype, key) + if path then + Private.texture_types["LibSharedMedia Textures"][path] = key + end end end) +Private.texture_types["LibSharedMedia Textures"] = {} +for _, mediaType in ipairs{"statusbar"} do + local mediaTable = LSM:HashTable(mediaType) + if mediaTable then + for name, path in pairs(mediaTable) do + Private.texture_types["LibSharedMedia Textures"][path] = name + end + end +end + -- register options font LSM:Register("font", "Fira Mono Medium", "Interface\\Addons\\WeakAuras\\Media\\Fonts\\FiraMono-Medium.ttf", LSM.LOCALE_BIT_western + LSM.LOCALE_BIT_ruRU) -- Other Fira fonts diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index 83ad10d..7b60518 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -1,6 +1,6 @@ local AddonName, Private = ... -local internalVersion = 73 +local internalVersion = 75 -- Lua APIs local insert = table.insert @@ -2192,8 +2192,12 @@ function Private.AddMany(tbl, takeSnapshots) local order = loadOrder(tbl, idtable) coroutine.yield() + local oldSnapshots = {} if takeSnapshots then for _, data in ipairs(order) do + if Private.ModernizeNeedsOldSnapshot(data) then + oldSnapshots[data.uid] = Private.GetMigrationSnapshot(data.uid) + end Private.SetMigrationSnapshot(data.uid, data) coroutine.yield() end @@ -2205,7 +2209,8 @@ function Private.AddMany(tbl, takeSnapshots) if data.parent and bads[data.parent] then bads[data.id] = true else - local ok = pcall(WeakAuras.PreAdd, data) + local oldSnapshot = oldSnapshots[data.uid] or nil + local ok = pcall(WeakAuras.PreAdd, data, oldSnapshot) if not ok then Private.GetErrorHandlerUid(data.uid, "PreAdd") prettyPrint(L["Unable to modernize aura '%s'. This is probably due to corrupt data or a bad migration, please report this to the WeakAuras team."]:format(data.id)) @@ -2576,7 +2581,7 @@ function Private.ClearSounds(uid) WeakAuras.FillOptions() end -function WeakAuras.PreAdd(data) +function WeakAuras.PreAdd(data, snapshot) if not data then return end -- Readd what Compress removed before version 8 if (not data.internalVersion or data.internalVersion < 7) then @@ -2585,7 +2590,7 @@ function WeakAuras.PreAdd(data) Private.validate(data, oldDataStub2) end - local ok = pcall(Private.Modernize, data) + local ok = pcall(Private.Modernize, data, snapshot) if not ok then Private.GetErrorHandlerId(data.id, L["Modernize"]) end @@ -2787,14 +2792,18 @@ function pAdd(data, simpleChange) end function WeakAuras.Add(data, simpleChange) + local oldSnapshot + if Private.ModernizeNeedsOldSnapshot(data) then + oldSnapshot = Private.GetMigrationSnapshot(data.uid) + end if (data.internalVersion or 0) < internalVersion then Private.SetMigrationSnapshot(data.uid, data) end - local ok, ret = pcall(WeakAuras.PreAdd, data) - if not ok then - Private.GetErrorHandlerUid(data.uid, "PreAdd") - elseif ok then + local ok, ret = pcall(WeakAuras.PreAdd, data, oldSnapshot) + if ok then pAdd(data, simpleChange) + else + Private.GetErrorHandlerUid(data.uid, "PreAdd") end end diff --git a/WeakAurasOptions/OptionsFrames/ImportExport.lua b/WeakAurasOptions/OptionsFrames/ImportExport.lua index ecc4075..5d19960 100644 --- a/WeakAurasOptions/OptionsFrames/ImportExport.lua +++ b/WeakAurasOptions/OptionsFrames/ImportExport.lua @@ -50,7 +50,7 @@ local function ConstructImportExport(frame) if(mode == "export") then displayStr = OptionsPrivate.Private.DisplayToString(id, true); elseif(mode == "table") then - displayStr = OptionsPrivate.Private.DataToString(id); + displayStr = OptionsPrivate.Private.DataToString(id, true); end input.editBox:SetMaxBytes(nil); input.editBox:SetScript("OnEscapePressed", function() group:Close(); end);