Nenue@6: -- KrakTool Nenue@6: -- Import.lua Nenue@6: -- Created: 7/10/2016 6:20 AM Nenue@6: -- %file-revision% Nenue@6: -- Tools for first-time setup and migration from other addons. Nenue@6: Nenue@6: local kb = LibStub("LibKraken").register(KeyBinder) Nenue@6: local print = DEVIAN_WORKSPACE and function(...) print('kbi', ...) end or function() end Nenue@6: Nenue@6: Nenue@6: local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544 Nenue@6: local SUMMON_RANDOM_FAVORITE_MOUNT_SPELLNAME = "Summon Random Favorite Mount" Nenue@6: local results = {} Nenue@6: local importSet = setmetatable({}, {__tostring = function() return 'Global Bindings' end}) Nenue@6: kb.importTypes = {} Nenue@6: Nenue@6: local lineNumber = 0 Nenue@6: local usedBinds, usedKeys = {}, {} Nenue@6: local profileName = '' Nenue@6: local specProfile Nenue@6: local msg = function(...) return KeyBinderImportLog:AddMessage(...) end Nenue@6: Nenue@6: --- Core interfaces Nenue@6: kb.ImportScan = function() Nenue@6: -- hang onto this Nenue@6: SUMMON_RANDOM_FAVORITE_MOUNT_SPELLNAME = GetSpellInfo(SUMMON_RANDOM_FAVORITE_MOUNT_SPELL) Nenue@6: Nenue@6: local hasAnyData = false Nenue@6: for addon, module in pairs(kb.importTypes) do Nenue@6: if IsAddOnLoaded(addon) then Nenue@6: local hasData = module.GetChanges(importSet) Nenue@6: if hasData then Nenue@6: kb:print("|cFFFFFF00"..addon.." is currently enabled.") Nenue@6: end Nenue@6: Nenue@6: hasAnyData = (hasData or hasAnyData) Nenue@6: end Nenue@6: end Nenue@6: if hasAnyData then Nenue@6: kb:print("You can use /skb import |cFF00FF00|r to attempt to copy settings related to this character. This will also disable that AddOn.") Nenue@6: end Nenue@6: Nenue@6: Nenue@6: kb.ui() Nenue@6: --KeyBinderImportLog:Show() Nenue@6: Nenue@6: return importSet Nenue@6: end Nenue@6: Nenue@6: kb.ImportCommmit = function(self, text) Nenue@6: kb.db.buttons = importSet.buttons Nenue@6: kb.db.bound = importSet.bound Nenue@6: kb.db.commands = importSet.commands Nenue@6: kb.db.bindings = importSet.bindings Nenue@6: kb.db.macros = importSet.macros Nenue@6: kb.db[profileName] = importSet[profileName] Nenue@6: kb.profile(profileName) Nenue@6: Nenue@6: Nenue@6: kb:ApplyAllBindings() Nenue@6: kb.ui() Nenue@6: kb:print('Imported settings applied! Note that you will need to change active specializations and run the command again to create their respective Char+Spec profiles.') Nenue@6: end Nenue@6: Nenue@6: --- Key Scan Nenue@6: kb.importTypes.KeyBinder = {} Nenue@6: kb.importTypes.BindPad = {} Nenue@6: local kbi = kb.importTypes.KeyBinder Nenue@6: local bp = kb.importTypes.BindPad Nenue@6: Nenue@6: --- BindPad import process Nenue@6: -- because bindpad doesn't store class info, it is not possible to discern the identity of primary/secondary Nenue@6: Nenue@6: local GetBindPadSlot = function(profile, slot, data) Nenue@6: local actionType = data.type:lower() Nenue@6: local command = data.action:gsub('CLICK BindPadKey:%s*', '') Nenue@6: local clickAction = command:match('BindPadMacro:%s*(.+)%s*$') Nenue@6: local macroName, macroText Nenue@6: if clickAction then Nenue@6: local clickType = 'spell' Nenue@6: if clickAction == SUMMON_RANDOM_FAVORITE_MOUNT_SPELLNAME then Nenue@6: clickType = 'mount' Nenue@6: clickAction = 0 Nenue@6: else Nenue@6: clickType = 'spell' Nenue@6: end Nenue@6: Nenue@6: macroName, macroText, command = kb.RegisterAction(nil, clickType, clickAction) Nenue@6: profile.macros[macroName] = {macroText, command} Nenue@6: end Nenue@6: print('[|cFF00FF00'.. data.type .. '|r] |cFFFF00FF' .. data.action .. '|r :: "' .. tostring(clickAction) .. '"') Nenue@6: Nenue@6: results[actionType] = (results[actionType] or 0) + 1 Nenue@6: profile.buttons[slot] = { Nenue@6: command, Nenue@6: command:gsub(data.type, ''), Nenue@6: data.texture Nenue@6: } Nenue@6: profile.commands[command] = slot Nenue@6: Nenue@6: if usedBinds[data.action] then Nenue@6: local key1, key2 = unpack(usedBinds[data.action]) Nenue@6: print('adding keybind |cFF00FFFF' .. command .. ' |cFF00FF00' .. (key1) .. ' |cFF00FF00' .. (key2 or '')) Nenue@6: profile.bindings[key1] = command Nenue@6: Nenue@6: if key2 then Nenue@6: profile.bindings[key2] = command Nenue@6: end Nenue@6: Nenue@6: usedBinds[data.action] = nil Nenue@6: Nenue@6: msg('|cFF00FFFF'..tostring(profile)..'|r '..slot..': ' .. '|cFF00FFFF' .. command .. '|r |cFF00FF00' .. (key1 or '') .. (key2 and ('|r, |cFF00FF00key2') or '') ) Nenue@6: else Nenue@6: print('|cFFFF4400no binding|r ' .. command) Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: local GetBindPadProfile = function(profile, bp) Nenue@6: local bpnames = {'CharacterSpecificTab1', 'CharacterSpecificTab2', 'CharacterSpecificTab3'} -- won't need this ever again, let it fall into gc Nenue@6: Nenue@6: -- resolve spec ID Nenue@6: local specID = GetSpecialization() Nenue@6: local globalID = GetSpecializationInfo(GetSpecialization()) Nenue@6: local activeProfile Nenue@6: Nenue@6: -- setup string coercions for debugging Nenue@6: setmetatable(profile,{__tostring = function(t) return 'Character' end}) Nenue@6: if GetNumSpecGroups() > 1 then Nenue@6: local activeGroup = GetActiveSpecGroup() Nenue@6: activeProfile = bp.profileForTalentGroup[activeGroup] Nenue@6: profile[specID] = kb.InitProfile(profile[specID] or {}) Nenue@6: specProfile = profile[specID] Nenue@6: setmetatable(specProfile,{__tostring = function(t) return 'Spec #'..specID end}) Nenue@6: end Nenue@6: Nenue@6: print('-') Nenue@6: Nenue@6: results.spell = 0 Nenue@6: results.macro = 0 Nenue@6: results.click = 0 Nenue@6: results.item = 0 Nenue@6: Nenue@6: table.wipe(usedBinds) -- [action] = {key1, key2} Nenue@6: table.wipe(usedKeys) -- [key] = "action" Nenue@6: for id, bpProfile in ipairs(bp) do Nenue@6: Nenue@6: local slots = 0 Nenue@6: Nenue@6: if bpProfile.AllKeyBindings then Nenue@6: for binding, command in pairs(bpProfile.AllKeyBindings) do Nenue@6: -- each binding value Nenue@6: if not usedKeys[binding] then Nenue@6: usedKeys[binding] = command Nenue@6: end Nenue@6: Nenue@6: usedBinds[command] = usedBinds[command] or {} Nenue@6: tinsert(usedBinds[command], binding) Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: Nenue@6: Nenue@6: for i, name in ipairs(bpnames) do Nenue@6: -- each tab Nenue@6: if bpProfile[name] then Nenue@6: for slot, data in pairs(bpProfile[name]) do Nenue@6: if type(data) == 'table' then Nenue@6: slots = slots + 1 Nenue@6: Nenue@6: Nenue@6: local profile = (id == activeProfile) and specProfile or profile Nenue@6: lineNumber = lineNumber + 1 Nenue@6: GetBindPadSlot(profile, slot, data) Nenue@6: Nenue@6: else Nenue@6: --print(type(data), slot, data) Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: Nenue@6: bp.GetChanges = function(importSet) Nenue@6: -- ensure that subtables are there Nenue@6: kb.InitProfile(importSet) Nenue@6: if BindPadVars then Nenue@6: local globalSlots = 0 Nenue@6: for k,v in pairs(BindPadVars) do Nenue@6: --print(k, type(k)) Nenue@6: if type(k) == 'string' then Nenue@6: local realm, name = k:match("^PROFILE_([%S]+)_(%S+)$") Nenue@6: if realm == kb.playerRealm and name == kb.playerName then Nenue@6: profileName = realm .. '_' .. name Nenue@6: msg('Found character profile: |cFFFFFF00'.. tostring(realm) .. '|r-|cFF00FFFF'..tostring(name)..'|r') Nenue@6: importSet[profileName] = kb.InitProfile({}) Nenue@6: importSet[profileName].imported = true Nenue@6: GetBindPadProfile(importSet[profileName], v) Nenue@6: end Nenue@6: elseif type(k) == 'number' and type(v) == 'table' then Nenue@6: globalSlots = globalSlots + 1 Nenue@6: GetBindPadSlot(importSet, globalSlots, v) Nenue@6: end Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: return results Nenue@6: end