Compare commits

...

7 Commits

Author SHA1 Message Date
b43608b724 Fix importing actionbars 2025-05-06 23:04:20 +02:00
f5b9b973e3 Fix import and export 2025-05-06 23:00:44 +02:00
0638896bc3 Rename all functions to reduce duplication 2025-05-06 22:52:46 +02:00
7df8ecb582 Update meta 2025-05-06 22:43:32 +02:00
3bd12c8ca8 Thoroughly refuck everything 2025-05-06 22:42:57 +02:00
38b5dbccb1 Clean up the code in general a bit 2025-05-06 22:15:08 +02:00
24e56078bd Rename from Reloaded to Daved
Because now it's in my hands!
2025-05-06 22:09:52 +02:00
10 changed files with 343 additions and 347 deletions

12
ActionBarSaverDaved.toc Normal file
View File

@@ -0,0 +1,12 @@
## Interface: 70300
## Title: ActionBarSaver: Daved
## Version: 1.0.0
## Notes: Manage, save, restore, import and export action bar and keybind profiles
## Author: Phat phuck dave
## SavedVariables: ActionBarSaverDaved, KeybindSaverDaved
B64.lua
Constants.lua
Main.lua
Actions.lua
KeybindSaver.lua

View File

@@ -1,12 +0,0 @@
## Interface: 40400
## Title: ActionBarSaver: Reloaded
## Version: 1.0.7
## Notes: Manage, save, and restore action bar profiles
## Author: Voodoomoose
## SavedVariables: ActionBarSaverReloaded, KeybindSaverReloaded
B64.lua
Constants.lua
Main.lua
Actions.lua
KeybindSaver.lua

View File

@@ -1,5 +1,3 @@
local ADDON_LOADED, shared = ...
local typeMap = { local typeMap = {
spell = "S", spell = "S",
item = "I", item = "I",
@@ -17,6 +15,8 @@ local inverseTypeMap = {
U = "summonmount", U = "summonmount",
} }
---@param setName string
---@return nil
local function PickupEquipmentSet(setName) local function PickupEquipmentSet(setName)
local setIndex = 0 local setIndex = 0
@@ -38,7 +38,10 @@ local pickupActionButton = {
summonmount = C_MountJournal.Pickup, summonmount = C_MountJournal.Pickup,
} }
local function RestoreActionButton(self, index, actionButton) ---@param index number
---@param actionButton {type: string, id: number|string}
---@return boolean, number?
local function RestoreActionButton(index, actionButton)
if GetActionInfo(index) then if GetActionInfo(index) then
PickupAction(index) PickupAction(index)
ClearCursor() ClearCursor()
@@ -46,7 +49,7 @@ local function RestoreActionButton(self, index, actionButton)
if not actionButton then return true, nil end if not actionButton then return true, nil end
local aliases = ActionBarSaverReloaded.spellAliases[actionButton.id] or {} local aliases = ActionBarSaverDaved.spellAliases[actionButton.id] or {}
table.insert(aliases, actionButton.id) table.insert(aliases, actionButton.id)
for _, id in ipairs(aliases) do for _, id in ipairs(aliases) do
@@ -63,8 +66,20 @@ local function RestoreActionButton(self, index, actionButton)
return false return false
end end
---@param index number
---@return boolean
local function ClearActionButton(index)
if not index then return false end
PickupAction(index)
ClearCursor()
return true
end
---@param actionButton {type: string, id: number|string}
---@return boolean
local function IsMacro(actionButton) return actionButton and actionButton.type == "macro" end local function IsMacro(actionButton) return actionButton and actionButton.type == "macro" end
---@return table<string, number>
local function GetMacroDuplicates() local function GetMacroDuplicates()
local t = {} local t = {}
local duplicates = {} local duplicates = {}
@@ -85,6 +100,10 @@ local function GetMacroDuplicates()
return duplicates return duplicates
end end
---@param warnings table<string, number>
---@param macroName string
---@param usages number
---@return nil
local function AddWarning(warnings, macroName, usages) local function AddWarning(warnings, macroName, usages)
table.insert( table.insert(
warnings, warnings,
@@ -92,14 +111,18 @@ local function AddWarning(warnings, macroName, usages)
) )
end end
function SaveSet(setName) ---@param setName string
---@return nil
function SaveActionbarSet(setName)
if not setName or setName == "" then if not setName or setName == "" then
print("Set name cannot be empty") print("Set name cannot be empty")
return return
end end
local duplicates = GetMacroDuplicates() local duplicates = GetMacroDuplicates()
---@type table<number, {type: string, id: number|string}>
local set = {} local set = {}
---@type string[]
local warnings = {} local warnings = {}
for i = 1, MAX_ACTION_BUTTONS do for i = 1, MAX_ACTION_BUTTONS do
@@ -117,20 +140,22 @@ function SaveSet(setName)
} end } end
end end
ActionBarSaverReloaded.sets[setName] = set ActionBarSaverDaved.sets[setName] = set
print(string.format("Saved set '%s'!", setName)) print(string.format("Saved set '%s'!", setName))
for _, warning in ipairs(warnings) do for _, warning in ipairs(warnings) do
print(warning) print(warning)
end end
end end
function RestoreSet(setName) ---@param setName string
---@return nil
function RestoreActionbarSet(setName)
if not setName or setName == "" then if not setName or setName == "" then
print("Set name cannot be empty") print("Set name cannot be empty")
return return
end end
local set = ActionBarSaverReloaded.sets[setName] local set = ActionBarSaverDaved.sets[setName]
if not set then if not set then
print(string.format("No set with the name '%s' exists", setName)) print(string.format("No set with the name '%s' exists", setName))
@@ -149,32 +174,36 @@ function RestoreSet(setName)
for i = 1, MAX_ACTION_BUTTONS do for i = 1, MAX_ACTION_BUTTONS do
local actionButton = set[i] local actionButton = set[i]
if actionButton then
if IsMacro(actionButton) and duplicates[actionButton.id] then
---@cast actionButton {type: string, id: string}
AddWarning(messages, actionButton.id, duplicates[actionButton.id])
end
if IsMacro(actionButton) and duplicates[actionButton.id] then local succeeded, restoredID = RestoreActionButton(i, actionButton)
AddWarning(messages, actionButton.id, duplicates[actionButton.id]) if not succeeded or not restoredID then
end table.insert(
messages,
local succeeded, restoredID = RestoreActionButton(self, i, actionButton) string.format(
if not succeeded then "Error: Unable to restore %s with id [%s] to slot %d",
table.insert( actionButton.type,
messages, actionButton.id or "",
string.format( i
"Error: Unable to restore %s with id [%s] to slot %d", )
actionButton.type,
actionButton.id or "",
i
) )
) elseif actionButton and restoredID ~= actionButton.id then
elseif actionButton and restoredID ~= actionButton.id then table.insert(
table.insert( messages,
messages, string.format(
string.format( "Info: Restored spell %d (%s) in place of spell %d",
"Info: Restored spell %d (%s) in place of spell %d", restoredID,
restoredID, GetSpellInfo(restoredID),
GetSpellInfo(restoredID), actionButton.id
actionButton.id )
) )
) end
else
ClearActionButton(i)
end end
end end
@@ -184,25 +213,28 @@ function RestoreSet(setName)
end end
end end
function DeleteSet(setName) ---@param setName string
---@return nil
function DeleteActionbarSet(setName)
if not setName or setName == "" then if not setName or setName == "" then
print("Set name cannot be empty") print("Set name cannot be empty")
return return
end end
if not ActionBarSaverReloaded.sets[setName] then if not ActionBarSaverDaved.sets[setName] then
print(string.format("No set with the name '%s' exists", setName)) print(string.format("No set with the name '%s' exists", setName))
return return
end end
ActionBarSaverReloaded.sets[setName] = nil ActionBarSaverDaved.sets[setName] = nil
print(string.format("Deleted set '%s'", setName)) print(string.format("Deleted set '%s'", setName))
end end
function ListSets() ---@return nil
function ListActionbarSets()
local sets = {} local sets = {}
for setName, foo in pairs(ActionBarSaverReloaded.sets) do for setName, foo in pairs(ActionBarSaverDaved.sets) do
sets[#sets + 1] = setName sets[#sets + 1] = setName
end end
table.sort(sets) table.sort(sets)
@@ -211,93 +243,64 @@ function ListSets()
print(not (not setsStr or setsStr == "") and setsStr or "No sets found") print(not (not setsStr or setsStr == "") and setsStr or "No sets found")
end end
function AliasSpell(args) ---@param of string
if not args or args == "" then ---@param to string
---@return nil
function AliasSpell(of, to)
if not of or not to then
print("Must provide args in the format 'spellID aliasID'") print("Must provide args in the format 'spellID aliasID'")
return return
end end
local spellID, aliasID = string.match(args, "(%d+)%s+(%d+)") local ofId = tonumber(of)
local toId = tonumber(to)
spellID = tonumber(spellID) if not (ofId and toId) then
aliasID = tonumber(aliasID) print(string.format("Could not parse %s and/or %s to numbers", of, to))
if not (spellID and aliasID) then
print(string.format("Could not parse spellID and aliasID from '%s'", args))
return return
end end
local aliases = ActionBarSaverReloaded.spellAliases[spellID] or {} local aliases = ActionBarSaverDaved.spellAliases[ofId] or {}
for _, id in ipairs(aliases) do for _, id in ipairs(aliases) do
if id == aliasID then if id == toId then
print(string.format("Spell %d is already aliased by %d", spellID, aliasID)) print(string.format("Spell %d is already aliased by %d", ofId, toId))
return return
end end
end end
table.insert(ActionBarSaverReloaded.spellAliases[spellID], aliasID) table.insert(ActionBarSaverDaved.spellAliases[ofId], toId)
print(string.format("Added %d as an alias for %d", aliasID, spellID)) print(string.format("Added %d as an alias for %d", toId, ofId))
end end
function DeleteSpellAliases(spellID) ---@param of string
if not spellID or spellID == "" then ---@return nil
function DeleteSpellAliases(of)
if not of then
print("Must provide a valid spellID") print("Must provide a valid spellID")
return return
end end
spellID = tonumber(spellID) local ofId = tonumber(of)
if not ActionBarSaverReloaded.spellAliases[spellID] then if not ofId then
print(string.format("No aliases to remove for spell with ID %d", spellID)) print(string.format("Could not parse spellID from '%s'", of))
return return
end end
ActionBarSaverReloaded.spellAliases[spellID] = nil if not ActionBarSaverDaved.spellAliases[ofId] then
print(string.format("No aliases to remove for spell with ID %d", ofId))
return
end
print(string.format("Removed all aliases for spell with ID %d", spellID)) ActionBarSaverDaved.spellAliases[ofId] = nil
print(string.format("Removed all aliases for spell with ID %d", ofId))
end end
---@return nil
function ListAliases() function ListAliases()
local aliases = ActionBarSaverReloaded.spellAliases for spellID, spellAliases in pairs(ActionBarSaverDaved.spellAliases) do
print(string.format("Spell %d is aliased by: %s", spellID, table.concat(spellAliases, ", ")))
if Dict.isEmpty(aliases) then
print("No aliases found")
return
end end
Dict.iter(
ActionBarSaverReloaded.spellAliases,
function(spellID, aliases)
print(string.format("Spell %d is aliased by: %s", spellID, table.concat(aliases, ", ")))
end
)
end
---@param text string
---@param size number
---@param deliminer string
---@return string[]
local function Partition(text, size, deliminer)
local words = {}
for word in text:gmatch("[^" .. deliminer .. "]+") do
words[#words + 1] = word
end
local ret = {}
local currentChunk = ""
for _, word in ipairs(words) do
if #currentChunk + #word + 1 <= size then
currentChunk = currentChunk .. deliminer .. 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 end
local importingSet = nil local importingSet = nil
@@ -347,14 +350,16 @@ importExportFrameTextBox:SetScript("OnEscapePressed", function(self)
local lines = { strsplit("\n", self:GetText()) } local lines = { strsplit("\n", self:GetText()) }
for _, line in ipairs(lines) do for _, line in ipairs(lines) do
line = strtrim(line) line = strtrim(line)
if line ~= "" then ImportSet(importingSet, line) end if line ~= "" then ImportActionbarSet(importingSet, line) end
end end
importingSet = nil importingSet = nil
end end
end) end)
function ExportSet(setName) ---@param setName string
local set = ActionBarSaverReloaded.sets[setName] ---@return nil
function ExportActionbarSet(setName)
local set = ActionBarSaverDaved.sets[setName]
if not set then if not set then
print(string.format("No set with the name '%s' exists", setName)) print(string.format("No set with the name '%s' exists", setName))
return return
@@ -387,39 +392,53 @@ function ExportSet(setName)
importExportFrameTextBox:SetFocus() importExportFrameTextBox:SetFocus()
end end
---@param action {slot: number, id: number|string, type: string}
---@return string
function FormatAction(action) return string.format("slot: %d, id: %s, type: %s", action.slot, action.id, action.type) end
---@param action string
---@return {slot: number, id: number|string, type: string}
function ParseAction(action) function ParseAction(action)
if not action or action == "" then return nil end local ret = {
slot = 0,
id = 0,
type = "",
}
if not action or action == "" then return ret end
action = strtrim(action) action = strtrim(action)
---@type string, string, string
local slot, id, typeChar = string.match(action, "([^\\]+)\\([^\\]+)\\([^\\]+)") local slot, id, typeChar = string.match(action, "([^\\]+)\\([^\\]+)\\([^\\]+)")
if not typeChar then if not typeChar then
print(string.format("Unknown action type '%s' in set '%s'", tostring(typeChar), tostring(setName))) print(string.format("Unknown action type '%s' for action '%s'", tostring(typeChar), FormatAction(ret)))
return return ret
end end
local type = inverseTypeMap[typeChar] local type = inverseTypeMap[typeChar]
if not type then if not type then
print(string.format("Unknown action type '%s' in set '%s'", tostring(typeChar), tostring(setName))) print(string.format("Unknown action type '%s' for action '%s'", tostring(typeChar), FormatAction(ret)))
return return ret
end end
slot = tonumber(slot) local slotNum = tonumber(slot)
if not slotNum then
if not slot then print(string.format("Unknown slot '%s' for action '%s'", tostring(slot), FormatAction(ret)))
print(string.format("Unknown slot '%s' in set '%s'", tostring(slot), tostring(setName))) return ret
return
end end
if not id then if not id then
print(string.format("Unknown id '%s' in set '%s'", tostring(id), tostring(setName))) print(string.format("Unknown id '%s' for action '%s'", tostring(id), FormatAction(ret)))
return return ret
end end
return { return {
slot = slot, slot = slotNum,
id = id, id = id,
type = type, type = type,
} }
end end
---@param importString string
---@return nil
function ImportMacro(importString) function ImportMacro(importString)
if not importString or importString == "" then if not importString or importString == "" then
print("Must provide a valid macro string") print("Must provide a valid macro string")
@@ -437,15 +456,17 @@ function ImportMacro(importString)
local reconstructed = B64.Decode(content) local reconstructed = B64.Decode(content)
local macroIdx = GetMacroIndexByName(name) local macroIdx = GetMacroIndexByName(name)
if macroIdx == 0 then if macroIdx == 0 then
macroIdx = CreateMacro(name, "Inv_misc_questionmark", "") CreateMacro(name, "Inv_misc_questionmark", "")
macroIdx = GetMacroIndexByName(name) macroIdx = GetMacroIndexByName(name)
end end
EditMacro(macroIdx, name, nil, reconstructed) EditMacro(macroIdx, name, nil, reconstructed)
print(string.format("Imported macro '%s' with index %d and content '%s'", name, macroIdx, reconstructed)) print(string.format("Imported macro '%s' with index %d and content '%s'", name, macroIdx, reconstructed))
return
end end
function ImportSet(setName, str) ---@param setName string
---@param str string
---@return nil
function ImportActionbarSet(setName, str)
if not setName or setName == "" then if not setName or setName == "" then
print("Must provide a valid set name") print("Must provide a valid set name")
return return
@@ -455,7 +476,7 @@ function ImportSet(setName, str)
ImportMacro(str) ImportMacro(str)
return return
end end
local set = ActionBarSaverReloaded.sets[setName] or {} local set = ActionBarSaverDaved.sets[setName] or {}
-- if set then -- if set then
-- print(string.format("Set '%s' already exists", setName)) -- print(string.format("Set '%s' already exists", setName))
-- return -- return
@@ -471,13 +492,13 @@ function ImportSet(setName, str)
} end } end
end end
-- /dump ActionBarSaverReloaded.sets["havoc"] ActionBarSaverDaved.sets[setName] = set
-- /dump ActionBarSaverReloaded.sets["havoc2"]
ActionBarSaverReloaded.sets[setName] = set
print(string.format("Imported set '%s'", setName)) print(string.format("Imported set '%s'", setName))
end end
function ImportSetDialogue(setName) ---@param setName string
---@return nil
function ImportActionbarSetDialogue(setName)
if not setName or setName == "" then if not setName or setName == "" then
print("Must provide a valid set name") print("Must provide a valid set name")
return return
@@ -488,7 +509,8 @@ function ImportSetDialogue(setName)
importExportFrameTextBox:SetFocus() importExportFrameTextBox:SetFocus()
end end
function PrintUsage() ---@return nil
function PrintActionbarUsage()
print("ABS Slash commands") print("ABS Slash commands")
print("/abs save <set> - Saves your current action bar setup under the given <set>") print("/abs save <set> - Saves your current action bar setup under the given <set>")
print("/abs restore <set> - Restores the saved <set>") print("/abs restore <set> - Restores the saved <set>")
@@ -505,16 +527,16 @@ SlashCmdList["ABS"] = function(argv)
local args = { strsplit(" ", argv) } local args = { strsplit(" ", argv) }
local cmd = args[1] local cmd = args[1]
if cmd == "save" then SaveSet(args[2]) end if cmd == "save" then SaveActionbarSet(args[2]) end
if cmd == "restore" then RestoreSet(args[2]) end if cmd == "restore" then RestoreActionbarSet(args[2]) end
if cmd == "delete" then DeleteSet(args[2]) end if cmd == "delete" then DeleteActionbarSet(args[2]) end
if cmd == "list" then ListSets() end if cmd == "list" then ListActionbarSets() end
if cmd == "alias" then AliasSpell(args[2], args[3]) end if cmd == "alias" then AliasSpell(args[2], args[3]) end
if cmd == "unalias" then DeleteSpellAliases(args[2]) end if cmd == "unalias" then DeleteSpellAliases(args[2]) end
if cmd == "aliases" then ListAliases() end if cmd == "aliases" then ListAliases() end
if cmd == "export" then ExportSet(args[2]) end if cmd == "export" then ExportActionbarSet(args[2]) end
if cmd == "import" then ImportSetDialogue(args[2]) end if cmd == "import" then ImportActionbarSetDialogue(args[2]) end
if cmd == "" or not cmd then PrintUsage() end if cmd == "" or not cmd then PrintActionbarUsage() end
end end
SLASH_ABS1 = "/abs" SLASH_ABS1 = "/abs"

View File

@@ -1,4 +1,4 @@
local ADDON_NAME, shared = ... local ADDON_NAME = ...
-- Initialize saved variables -- Initialize saved variables
local frame = CreateFrame("Frame") local frame = CreateFrame("Frame")
@@ -6,10 +6,123 @@ frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function(self, event, addon) frame:SetScript("OnEvent", function(self, event, addon)
if addon ~= ADDON_NAME then return end if addon ~= ADDON_NAME then return end
KeybindSaverReloaded = KeybindSaverReloaded or {} KeybindSaverDaved = KeybindSaverDaved or {}
KeybindSaverReloaded.sets = KeybindSaverReloaded.sets or {} KeybindSaverDaved.sets = KeybindSaverDaved.sets or {}
end) end)
---@param setName string
---@return nil
local function SaveKeybindSet(setName)
if not setName or setName == "" then
print("Set name cannot be empty")
return
end
---@type table<string, {key1: string, key2: string?}>
local set = {}
local numBindings = GetNumBindings()
for i = 1, numBindings do
local command, _, key1, key2 = GetBinding(i)
if key1 or key2 then set[command] = {
key1 = key1,
key2 = key2,
} end
end
KeybindSaverDaved.sets[setName] = set
print(string.format("Saved keybind set '%s'!", setName))
end
---@param setName string
---@return nil
local function RestoreKeybindSet(setName)
if not setName or setName == "" then
print("Set name cannot be empty")
return
end
local set = KeybindSaverDaved.sets[setName]
if not set then
print(string.format("No set with the name '%s' exists", setName))
return
end
-- Clear all current bindings first
ClearOverrideBindings(frame)
-- Restore saved bindings
for command, keys in pairs(set) do
if keys.key1 then SetBinding(keys.key1, command) end
if keys.key2 then SetBinding(keys.key2, command) end
end
-- Save the changes
SaveBindings(GetCurrentBindingSet())
print(string.format("Restored keybind set '%s'", setName))
end
---@param setName string
---@return nil
local function DeleteKeybindSet(setName)
if not setName or setName == "" then
print("Set name cannot be empty")
return
end
if not KeybindSaverDaved.sets[setName] then
print(string.format("No set with the name '%s' exists", setName))
return
end
KeybindSaverDaved.sets[setName] = nil
print(string.format("Deleted keybind set '%s'", setName))
end
---@return nil
local function ListKeybindSets()
local sets = {}
for setName in pairs(KeybindSaverDaved.sets) do
table.insert(sets, setName)
end
table.sort(sets)
if #sets == 0 then
print("No keybind sets found")
else
print("Saved keybind sets:")
print(table.concat(sets, ", "))
end
end
---@param setName string
---@param importStr string
---@return nil
local function ImportKeybindSet(setName, importStr)
if not setName or setName == "" then
print("Set name cannot be empty")
return
end
local set = {}
local lines = { strsplit("\n", importStr) }
for _, line in ipairs(lines) do
local command, key = strsplit(":", line)
if command and key then
if not set[command] then set[command] = {} end
if not set[command].key1 then
set[command].key1 = key
else
set[command].key2 = key
end
end
end
KeybindSaverDaved.sets[setName] = set
print(string.format("Imported keybind set '%s'", setName))
end
-- Create the import/export frame -- Create the import/export frame
local importExportFrame = CreateFrame("Frame", "KBSImportExportFrame", UIParent) local importExportFrame = CreateFrame("Frame", "KBSImportExportFrame", UIParent)
importExportFrame:SetSize(512, 512) importExportFrame:SetSize(512, 512)
@@ -56,90 +169,15 @@ importExportFrameTextBox:SetScript("OnEscapePressed", function(self)
importExportFrame:Hide() importExportFrame:Hide()
if importingSet then if importingSet then
local text = self:GetText() local text = self:GetText()
if text and text ~= "" then ImportSet(importingSet, text) end if text and text ~= "" then ImportKeybindSet(importingSet, text) end
importingSet = nil importingSet = nil
end end
end) end)
local function SaveSet(setName) ---@param setName string
if not setName or setName == "" then ---@return nil
print("Set name cannot be empty") local function ExportKeybindSet(setName)
return local set = KeybindSaverDaved.sets[setName]
end
local set = {}
local numBindings = GetNumBindings()
for i = 1, numBindings do
local command, category, key1, key2 = GetBinding(i)
if key1 or key2 then set[command] = {
key1 = key1,
key2 = key2,
} end
end
KeybindSaverReloaded.sets[setName] = set
print(string.format("Saved keybind set '%s'!", setName))
end
local function RestoreSet(setName)
if not setName or setName == "" then
print("Set name cannot be empty")
return
end
local set = KeybindSaverReloaded.sets[setName]
if not set then
print(string.format("No set with the name '%s' exists", setName))
return
end
-- Clear all current bindings first
ClearOverrideBindings(frame)
-- Restore saved bindings
for command, keys in pairs(set) do
if keys.key1 then SetBinding(keys.key1, command) end
if keys.key2 then SetBinding(keys.key2, command) end
end
-- Save the changes
SaveBindings(GetCurrentBindingSet())
print(string.format("Restored keybind set '%s'", setName))
end
local function DeleteSet(setName)
if not setName or setName == "" then
print("Set name cannot be empty")
return
end
if not KeybindSaverReloaded.sets[setName] then
print(string.format("No set with the name '%s' exists", setName))
return
end
KeybindSaverReloaded.sets[setName] = nil
print(string.format("Deleted keybind set '%s'", setName))
end
local function ListSets()
local sets = {}
for setName in pairs(KeybindSaverReloaded.sets) do
table.insert(sets, setName)
end
table.sort(sets)
if #sets == 0 then
print("No keybind sets found")
else
print("Saved keybind sets:")
print(table.concat(sets, ", "))
end
end
local function ExportSet(setName)
local set = KeybindSaverReloaded.sets[setName]
if not set then if not set then
print(string.format("No set with the name '%s' exists", setName)) print(string.format("No set with the name '%s' exists", setName))
return return
@@ -157,32 +195,9 @@ local function ExportSet(setName)
importExportFrameTextBox:SetFocus() importExportFrameTextBox:SetFocus()
end end
local function ImportSet(setName, importStr) ---@param setName string
if not setName or setName == "" then ---@return nil
print("Set name cannot be empty") local function ImportKeybindSetDialogue(setName)
return
end
local set = {}
local lines = { strsplit("\n", importStr) }
for _, line in ipairs(lines) do
local command, key = strsplit(":", line)
if command and key then
if not set[command] then set[command] = {} end
if not set[command].key1 then
set[command].key1 = key
else
set[command].key2 = key
end
end
end
KeybindSaverReloaded.sets[setName] = set
print(string.format("Imported keybind set '%s'", setName))
end
local function ImportSetDialogue(setName)
if not setName or setName == "" then if not setName or setName == "" then
print("Set name cannot be empty") print("Set name cannot be empty")
return return
@@ -193,7 +208,8 @@ local function ImportSetDialogue(setName)
importExportFrameTextBox:SetFocus() importExportFrameTextBox:SetFocus()
end end
local function PrintUsage() ---@return nil
local function PrintKeybindUsage()
print("Keybind Saver Slash Commands:") print("Keybind Saver Slash Commands:")
print("/kbs save <set> - Saves your current keybinds under the given <set>") print("/kbs save <set> - Saves your current keybinds under the given <set>")
print("/kbs restore <set> - Restores the saved <set>") print("/kbs restore <set> - Restores the saved <set>")
@@ -203,25 +219,17 @@ local function PrintUsage()
print("/kbs import <set> - Opens a window to import a keybind set") print("/kbs import <set> - Opens a window to import a keybind set")
end end
-- Register slash commands
SLASH_KBS1 = "/kbs" SLASH_KBS1 = "/kbs"
SlashCmdList["KBS"] = function(argv) SlashCmdList["KBS"] = function(argv)
local args = { strsplit(" ", argv) } local args = { strsplit(" ", argv) }
local cmd = args[1] local cmd = args[1]
if cmd == "save" then if cmd == "save" then SaveKeybindSet(args[2]) end
SaveSet(args[2]) if cmd == "restore" then RestoreKeybindSet(args[2]) end
elseif cmd == "restore" then if cmd == "delete" then DeleteKeybindSet(args[2]) end
RestoreSet(args[2]) if cmd == "list" then ListKeybindSets() end
elseif cmd == "delete" then if cmd == "export" then ExportKeybindSet(args[2]) end
DeleteSet(args[2]) if cmd == "import" then ImportKeybindSetDialogue(args[2]) end
elseif cmd == "list" then
ListSets() if cmd == "" or not cmd then PrintKeybindUsage() end
elseif cmd == "export" then
ExportSet(args[2])
elseif cmd == "import" then
ImportSetDialogue(args[2])
else
PrintUsage()
end
end end

View File

@@ -1,30 +1,21 @@
local ADDON_NAME, shared = ... local ADDON_NAME = ...
local frame = CreateFrame("Frame") local frame = CreateFrame("Frame")
frame:RegisterEvent("ADDON_LOADED") frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function(self, event, addon) frame:SetScript("OnEvent", function(self, event, addon)
if addon ~= ADDON_NAME then return end if addon ~= ADDON_NAME then return end
ActionBarSaverReloaded = ActionBarSaverReloaded or {} ---@class ActionBarSaverDaved
ActionBarSaverReloaded.spellAliases = ActionBarSaverReloaded.spellAliases or {} ---@field spellAliases table<number, number[]>
ActionBarSaverReloaded.sets = ActionBarSaverReloaded.sets or {} ---@field sets table<string, table<number, {type: string, id: number|string}>>
ActionBarSaverDaved = ActionBarSaverDaved or {}
ActionBarSaverDaved.spellAliases = ActionBarSaverDaved.spellAliases or {}
ActionBarSaverDaved.sets = ActionBarSaverDaved.sets or {}
---@class KeybindSaverDaved
---@field sets table<string, table<string, {key1: string, key2: string?}>>
KeybindSaverDaved = KeybindSaverDaved or {}
KeybindSaverDaved.sets = KeybindSaverDaved.sets or {}
end) end)
-- function ABS:OnInitialize() -- TODO: Fix equipment sets (saving reloading exporting importing...)
-- self.commands = {
-- save = self.actions.SaveSet,
-- restore = self.actions.RestoreSet,
-- delete = self.actions.DeleteSet,
-- list = self.actions.ListSets,
-- alias = self.actions.AliasSpell,
-- unalias = self.actions.DeleteSpellAliases,
-- aliases = self.actions.ListAliases,
-- }
-- end
--
-- function ABS:HandleCommands(input)
-- local cmd, args = Str.split(input, " ", 2)
-- local fn = self.commands[Str.toLower(cmd)]
--
-- if fn then fn(self, args) else self.actions.PrintUsage(self) end
-- end

2
Meta

Submodule Meta updated: 90f71c5c56...51a48175fa

View File

@@ -1,16 +1,12 @@
# ActionBarSaver:Reloaded # ActionBarSaver:Daved
## Overview ## Overview
ActionBarSaver:Reloaded is an addon for saving and restoring action bar profiles. It is based on the original ActionBarSaver addon but is a full re-write. ActionBarSaver:Daved is an addon for saving and restoring action bar profiles and keybindings. It is based on the original ActionBarSaver addon but is a full re-write.
All sets are saved by class rather than by character. Additionally, when you list profiles, you will only see profiles that pertain to your class. All sets are saved by class rather than by character. Additionally, when you list profiles, you will only see profiles that pertain to your class.
Features such as rename have been deleted for simplicity. To perform a rename, simply save the set with a new name and delete the old set. Additionally, restoring a set will no longer try to re-create macros that do not exist. It will simply notify you of the missing macro and restore nothing for that slot. ABS:R will not work properly if you have multiple macros with the same name, and will warn you of potential issues if you restore a set that has a macro with a shared name. ## Action Bar Saver Usage
A new feature has been added for setting up aliases for spells. A common use case for this would be restoring a single set for two characters that share a class but have a different race. For example, you could create a set on a troll shaman that contains `Berserking` and then add an alias for `War Stomp` using `/abs alias 20554 20549`. If you do this, when you restore a set it will first try to restore the proper spell but will also try each alias that you set up. A spell can have as many aliases as you want.
## Usage
`/abs save <set>` - Saves your current action bar setup under the given <set>\ `/abs save <set>` - Saves your current action bar setup under the given <set>\
`/abs restore <set>` - Restores the saved <set>\ `/abs restore <set>` - Restores the saved <set>\
@@ -18,7 +14,20 @@ A new feature has been added for setting up aliases for spells. A common use cas
`/abs list` - Lists all saved sets\ `/abs list` - Lists all saved sets\
`/abs alias <spellID> <aliasID>` - Adds an alias with <aliasID> to <spellID>\ `/abs alias <spellID> <aliasID>` - Adds an alias with <aliasID> to <spellID>\
`/abs unalias <spellID>` - Removes all aliases associated with <spellID>\ `/abs unalias <spellID>` - Removes all aliases associated with <spellID>\
`/abs aliases` - List all spell aliases `/abs aliases` - List all spell aliases\
`/abs export <set>` - Opens a window to export the given <set>\
`/abs import <set>` - Opens a window to import an action bar set
## Keybind Saver Usage
The addon also includes a keybind saver that allows you to save and restore your keybindings. This is useful for maintaining different keybind setups for different specs or situations.
`/kbs save <set>` - Saves your current keybinds under the given <set>\
`/kbs restore <set>` - Restores the saved <set>\
`/kbs delete <set>` - Deletes the saved <set>\
`/kbs list` - Lists all saved sets\
`/kbs export <set>` - Opens a window to export the given <set>\
`/kbs import <set>` - Opens a window to import a keybind set
## Known Issues ## Known Issues

View File

@@ -1,31 +0,0 @@
## 1.0.7 (2024-06-30)
- Updated for Cata classic
## 1.0.6 (2023-08-29)
- TOC bump for ICC patch
## 1.0.5 (2023-06-20)
- TOC bump for ToGC patch
## 1.0.4 (2023-01-18)
- TOC bump for WOTLK patch
## 1.0.3 (2022-11-09)
- Fixed bug with equipment sets not being restored properly
## 1.0.2 (2022-10-27)
- Fixed bug where totem sets were not being saved or restored
## 1.0.1 (2022-09-26)
- Fixed bug related to restoring sets containing companions and mounts
## 1.0.0 (2022-07-15)
- Initial re-write of the addon

View File

@@ -1,5 +1,5 @@
mkdir ActionBarSaverReloaded mkdir ABS
cp -r *.lua ActionBarSaverReloaded cp -r *.lua ABS
cp -r *.toc ActionBarSaverReloaded cp -r *.toc ABS
7z a ActionBarSaverReloaded.zip ActionBarSaverReloaded 7z a ABS.zip ABS
rm -rf ActionBarSaverReloaded rm -rf ABS

View File

@@ -15,26 +15,23 @@ fi
echo "Tag: $TAG" echo "Tag: $TAG"
echo "Building the thing..." echo "Building the thing..."
sed -i "s/## Version: .*/## Version: $TAG/" Heimdall.toc sed -i "s/## Version: .*/## Version: $TAG/" ActionBarSaverDaved.toc
sed -i "s/local VERSION = .*/local VERSION = \"$TAG\"/" Heimdall.lua sed -i "s/local VERSION = .*/local VERSION = \"$TAG\"/" ActionBarSaverDaved.lua
git add Heimdall.toc Heimdall.lua git add ActionBarSaverDaved.toc ActionBarSaverDaved.lua
git commit -m "Release $TAG" git commit -m "Release $TAG"
git tag -f $TAG git tag -f $TAG
git push origin $TAG git push origin $TAG
rm Heimdall-${TAG}.zip rm ActionBarSaverDaved-${TAG}.zip
mkdir Heimdall mkdir ActionBarSaverDaved
cp *.lua *.toc Heimdall cp *.lua *.toc ActionBarSaverDaved
cp -r Modules Heimdall 7z a ActionBarSaverDaved-${TAG}.zip ActionBarSaverDaved
cp -r Sounds Heimdall rm -rf ActionBarSaverDaved
cp -r Texture Heimdall
7z a Heimdall-${TAG}.zip Heimdall
rm -rf Heimdall
echo "Creating a release..." echo "Creating a release..."
TOKEN="$GITEA_API_KEY" TOKEN="$GITEA_API_KEY"
GITEA="https://git.site.quack-lab.dev" GITEA="https://git.site.quack-lab.dev"
REPO="dave/wow-ABS" REPO="dave/wow_ABS"
# Create a release # Create a release
RELEASE_RESPONSE=$(curl -s -X POST \ RELEASE_RESPONSE=$(curl -s -X POST \
-H "Authorization: token $TOKEN" \ -H "Authorization: token $TOKEN" \
@@ -56,6 +53,6 @@ echo "Release ID: $RELEASE_ID"
echo "Uploading the things..." echo "Uploading the things..."
curl -X POST \ curl -X POST \
-H "Authorization: token $TOKEN" \ -H "Authorization: token $TOKEN" \
-F "attachment=@Heimdall-${TAG}.zip" \ -F "attachment=@ActionBarSaverDaved-${TAG}.zip" \
"$GITEA/api/v1/repos/$REPO/releases/${RELEASE_ID}/assets?name=Heimdall-${TAG}.zip" "$GITEA/api/v1/repos/$REPO/releases/${RELEASE_ID}/assets?name=ActionBarSaverDaved-${TAG}.zip"
rm Heimdall-${TAG}.zip rm ActionBarSaverDaved-${TAG}.zip