Compare commits

..

10 Commits

Author SHA1 Message Date
1e014b2d5b Fix up importing macros 2025-01-05 15:19:37 +01:00
ac32b1fd75 Remove dump table 2025-01-05 15:19:23 +01:00
c7b843ca03 Create a frame for exporting and importing 2025-01-05 13:25:32 +01:00
8b310197fc Implement exporting macros 2025-01-04 23:18:50 +01:00
9520269857 Implement importing sets 2025-01-04 22:38:14 +01:00
29cd686eec Implement exporting sets 2025-01-04 19:13:47 +01:00
94408916e0 Cleanup 2025-01-04 19:05:46 +01:00
b7eb0b1cdf Add b64 encoder 2025-01-04 18:43:43 +01:00
6a4cc91413 Fix list command 2025-01-04 18:43:39 +01:00
a6d570c553 Fix some other bullshit, make work 2025-01-04 13:57:41 +01:00
3 changed files with 326 additions and 20 deletions

View File

@@ -5,6 +5,7 @@
## Author: Voodoomoose
## SavedVariables: ActionBarSaverReloaded
B64.lua
Constants.lua
Main.lua
Actions.lua

View File

@@ -1,5 +1,22 @@
local ADDON_LOADED, shared = ...
local typeMap = {
spell = "S",
item = "I",
macro = "M",
companion = "C",
equipmentset = "E",
summonmount = "U"
}
local inverseTypeMap = {
S = "spell",
I = "item",
M = "macro",
C = "companion",
E = "equipmentset",
U = "summonmount"
}
local function PickupEquipmentSet(setName)
local setIndex = 0
@@ -19,11 +36,11 @@ local pickupActionButton = {
spell = PickupSpell,
macro = PickupMacro,
companion = PickupSpell,
equipmentset = PickupEquipmentSet
equipmentset = PickupEquipmentSet,
summonmount = C_MountJournal.Pickup
}
local function RestoreActionButton(self, index, actionButton)
-- Clear the slot
if GetActionInfo(index) then
PickupAction(index)
ClearCursor()
@@ -34,9 +51,9 @@ local function RestoreActionButton(self, index, actionButton)
end
local aliases = ActionBarSaverReloaded.spellAliases[actionButton.id] or {}
local ids = Array.insert(aliases, actionButton.id, 1)
table.insert(aliases, actionButton.id)
for _, id in ipairs(ids) do
for _, id in ipairs(aliases) do
pickupActionButton[actionButton.type](id)
if GetCursorInfo() == actionButton.type then
@@ -80,7 +97,6 @@ local function AddWarning(warnings, macroName, usages)
end
function SaveSet(setName)
print("ABS SaveSet")
if not setName or setName == "" then
print("Set name cannot be empty")
return
@@ -111,9 +127,9 @@ function SaveSet(setName)
ActionBarSaverReloaded.sets[setName] = set
print(string.format("Saved set '%s'!", setName))
Array.iter(warnings, function(warning)
for _, warning in ipairs(warnings) do
print(warning)
end)
end
end
function RestoreSet(setName)
@@ -158,9 +174,9 @@ function RestoreSet(setName)
end
print(string.format("Restored set '%s'", setName))
Array.iter(messages, function(warning)
for _, warning in ipairs(messages) do
print(warning)
end)
end
end
function DeleteSet(setName)
@@ -180,11 +196,14 @@ function DeleteSet(setName)
end
function ListSets()
local sets = Dict.keysAsArray(ActionBarSaverReloaded.sets)
local sets = {}
for setName, foo in pairs(ActionBarSaverReloaded.sets) do
sets[#sets + 1] = setName
end
table.sort(sets)
local setsStr = table.concat(sets, ", ")
print(not Str.nullOrEmpty(setsStr) and setsStr or "No sets found")
print(not (not setsStr or setsStr == "") and setsStr or "No sets found")
end
function AliasSpell(args)
@@ -204,14 +223,14 @@ function AliasSpell(args)
local aliases = ActionBarSaverReloaded.spellAliases[spellID] or {}
if Array.contains(aliases, aliasID) then
print(string.format("Spell %d is already aliased by %d", spellID, aliasID))
return
for _, id in ipairs(aliases) do
if id == aliasID then
print(string.format("Spell %d is already aliased by %d", spellID, aliasID))
return
end
end
table.insert(aliases, aliasID)
ActionBarSaverReloaded.spellAliases[spellID] = aliases
table.insert(ActionBarSaverReloaded.spellAliases[spellID], aliasID)
print(string.format("Added %d as an alias for %d", aliasID, spellID))
end
@@ -246,6 +265,239 @@ function ListAliases()
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
local importingSet = nil
local importExportFrame = CreateFrame("Frame", "ABSImportExportFrame", UIParent)
importExportFrame:SetSize(512, 512)
importExportFrame:SetPoint("CENTER")
importExportFrame:SetFrameStrata("HIGH")
importExportFrame:EnableMouse(true)
importExportFrame:SetMovable(true)
importExportFrame:SetResizable(false)
importExportFrame:SetBackdrop({
bgFile = "Interface/Tooltips/UI-Tooltip-Background",
edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
tile = true,
tileSize = 4,
edgeSize = 4,
insets = {
left = 4,
right = 4,
top = 4,
bottom = 4
}
})
importExportFrame:SetBackdropColor(0, 0, 0, 0.8)
importExportFrame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
importExportFrame:SetMovable(true)
importExportFrame:EnableMouse(true)
importExportFrame:RegisterForDrag("LeftButton")
importExportFrame:SetScript("OnDragStart", function(self)
self:StartMoving()
end)
importExportFrame:SetScript("OnDragStop", function(self)
self:StopMovingOrSizing()
end)
importExportFrame:SetScript("OnShow", function(self)
self:SetScale(1)
end)
importExportFrame:Hide()
local importExportFrameTextBox = CreateFrame("EditBox", "ABSImportExportFrameTextBox", importExportFrame)
importExportFrameTextBox:SetSize(512, 512)
importExportFrameTextBox:SetPoint("TOPLEFT", importExportFrame, "TOPLEFT", 0, 0)
importExportFrameTextBox:SetFont("Fonts\\FRIZQT__.ttf", 12)
importExportFrameTextBox:SetTextColor(1, 1, 1, 1)
importExportFrameTextBox:SetTextInsets(20, 20, 20, 20)
importExportFrameTextBox:SetMultiLine(true)
importExportFrameTextBox:SetAutoFocus(true)
importExportFrameTextBox:SetMaxLetters(1000000)
importExportFrameTextBox:SetScript("OnEscapePressed", function(self)
importExportFrame:Hide()
if importingSet then
local lines = {strsplit("\n", self:GetText())}
for _, line in ipairs(lines) do
line = strtrim(line)
if line ~= "" then
ImportSet(importingSet, line)
end
end
importingSet = nil
end
end)
function ExportSet(setName)
local set = ActionBarSaverReloaded.sets[setName]
if not set then
print(string.format("No set with the name '%s' exists", setName))
return
end
local macros = {}
local stringified = {}
for slot, action in pairs(set) do
local typeChar = typeMap[action.type]
if not typeChar then
print(string.format("Unknown action type '%s' in set '%s'", action.type, setName))
return
end
stringified[#stringified + 1] = string.format("%s\\%s\\%s", tostring(slot), tostring(action.id),
tostring(typeChar))
if typeChar == "M" then
local _, _, macro = GetMacroInfo(action.id)
if macro then
macros[action.id] = macro
end
end
end
local export = {}
for name, macro in pairs(macros) do
local content = B64.Encode(macro)
export[#export + 1] = string.format("Mž%sž%s", name, content)
end
export[#export + 1] = table.concat(stringified, "ž")
local str = table.concat(export, "\n")
importExportFrame:Show()
importExportFrameTextBox:SetText(str)
importExportFrameTextBox:SetFocus()
end
function ParseAction(action)
if not action or action == "" then
return nil
end
action = strtrim(action)
local slot, id, typeChar = string.match(action, "([^\\]+)\\([^\\]+)\\([^\\]+)")
if not typeChar then
print(string.format("Unknown action type '%s' in set '%s'", tostring(typeChar), tostring(setName)))
return
end
local type = inverseTypeMap[typeChar]
if not type then
print(string.format("Unknown action type '%s' in set '%s'", tostring(typeChar), tostring(setName)))
return
end
slot = tonumber(slot)
if not slot then
print(string.format("Unknown slot '%s' in set '%s'", tostring(slot), tostring(setName)))
return
end
if not id then
print(string.format("Unknown id '%s' in set '%s'", tostring(id), tostring(setName)))
return
end
return {
slot = slot,
id = id,
type = type
}
end
function ImportMacro(importString)
if not importString or importString == "" then
print("Must provide a valid macro string")
return
end
importString = strtrim(importString)
local name, content = string.match(importString, "^Mž([^ž]+)ž([^ž]+)")
if not name or not content then
print("Error: Invalid macro part format")
return
end
content = strtrim(content)
name = strtrim(name)
local reconstructed = B64.Decode(content)
local macroIdx = GetMacroIndexByName(name)
if macroIdx == 0 then
macroIdx = CreateMacro(name, "Inv_misc_questionmark", "")
macroIdx = GetMacroIndexByName(name)
end
EditMacro(macroIdx, name, nil, reconstructed)
print(string.format("Imported macro '%s' with index %d and content '%s'", name, macroIdx, reconstructed))
return
end
function ImportSet(setName, str)
if not setName or setName == "" then
print("Must provide a valid set name")
return
end
if string.find(str, "^Mž") then
ImportMacro(str)
return
end
local set = ActionBarSaverReloaded.sets[setName] or {}
-- if set then
-- print(string.format("Set '%s' already exists", setName))
-- return
-- end
str = strtrim(str)
local data = {strsplit("ž", str)}
for _, action in ipairs(data) do
local paction = ParseAction(action)
if paction then
set[paction.slot] = {
type = paction.type,
id = paction.id
}
end
end
-- /dump ActionBarSaverReloaded.sets["havoc"]
-- /dump ActionBarSaverReloaded.sets["havoc2"]
ActionBarSaverReloaded.sets[setName] = set
print(string.format("Imported set '%s'", setName))
end
function ImportSetDialogue(setName)
if not setName or setName == "" then
print("Must provide a valid set name")
return
end
importingSet = setName
importExportFrameTextBox:SetText("")
importExportFrame:Show()
importExportFrameTextBox:SetFocus()
end
function PrintUsage()
print("ABS Slash commands")
print("/abs save <set> - Saves your current action bar setup under the given <set>")
@@ -255,13 +507,13 @@ function PrintUsage()
print("/abs alias <spellID> <aliasID> - Adds an alias with <aliasID> to <spellID>")
print("/abs unalias <spellID> - Removes all aliases associated with <spellID>")
print("/abs aliases - List all spell aliases")
print("/abs export <set> - Brings up a dialog to export the given <set>")
print("/abs import <set> - Brings up a dialog to import the given <set>")
end
SlashCmdList["ABS"] = function(argv)
print("ABS slash", tostring(argv))
local args = strsplit(" ", argv)
local args = {strsplit(" ", argv)}
local cmd = args[1]
print("ABS slash", tostring(cmd))
if cmd == "save" then
SaveSet(args[2])
@@ -284,6 +536,13 @@ SlashCmdList["ABS"] = function(argv)
if cmd == "aliases" then
ListAliases()
end
if cmd == "export" then
ExportSet(args[2])
end
if cmd == "import" then
ImportSetDialogue(args[2])
end
if cmd == "" or not cmd then
PrintUsage()
end

46
B64.lua Normal file
View File

@@ -0,0 +1,46 @@
if not B64 then
B64 = {}
end
local encode, decode = {}, {
[strbyte("=")] = false
}
for value = 0, 63 do
local char = strsub('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', value + 1, value + 1)
encode[value] = char
decode[strbyte(char)] = value
end
local t = {}
function B64.Encode(str)
local j = 1
for i = 1, strlen(str), 3 do
local a, b, c = strbyte(str, i, i + 2)
t[j] = encode[bit.rshift(a, 2)]
t[j + 1] = encode[bit.band(bit.lshift(a, 4) + bit.rshift(b or 0, 4), 0x3F)]
t[j + 2] = b and encode[bit.band(bit.lshift(b, 2) + bit.rshift(c or 0, 6), 0x3F)] or "="
t[j + 3] = c and encode[bit.band(c, 0x3F)] or "="
j = j + 4
end
return table.concat(t, "", 1, j - 1)
end
function B64.Decode(str)
local j = 1
if strlen(str) % 4 ~= 0 then
str = str .. string.rep("=", 4 - strlen(str) % 4)
end
assert(strlen(str) % 4 == 0, format("invalid data length: %d", strlen(str)))
for i = 1, strlen(str), 4 do
local ba, bb, bc, bd = strbyte(str, i, i + 3)
local a, b, c, d = decode[ba], decode[bb], decode[bc], decode[bd]
assert(a ~= nil, format("invalid data at position %d: '%s'", i, ba))
assert(b ~= nil, format("invalid data at position %d: '%s'", i + 1, bb))
assert(c ~= nil, format("invalid data at position %d: '%s'", i + 2, bc))
assert(d ~= nil, format("invalid data at position %d: '%s'", i + 3, bd))
t[j] = strchar(bit.lshift(a, 2) + bit.rshift(b, 4))
t[j + 1] = c and strchar(bit.band(bit.lshift(b, 4) + bit.rshift(c, 2), 0xFF)) or ""
t[j + 2] = d and strchar(bit.band(bit.lshift(c, 6) + d, 0xFF)) or ""
j = j + 3
end
return table.concat(t, "", 1, j - 1)
end