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