flickerstreak@22: --[[ flickerstreak@1: Name: AceConsole-2.0 flickerstreak@22: Revision: $Rev: 48940 $ flickerstreak@1: Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team) flickerstreak@1: Inspired By: Ace 1.x by Turan (turan@gryphon.com) flickerstreak@1: Website: http://www.wowace.com/ flickerstreak@1: Documentation: http://www.wowace.com/index.php/AceConsole-2.0 flickerstreak@22: SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceConsole-2.0 flickerstreak@1: Description: Mixin to allow for input/output capabilities. This uses the flickerstreak@1: AceOptions data table format to determine input. flickerstreak@22: http://www.wowace.com/index.php/AceOptions_data_table flickerstreak@1: Dependencies: AceLibrary, AceOO-2.0 flickerstreak@22: License: LGPL v2.1 flickerstreak@1: ]] flickerstreak@1: flickerstreak@1: local MAJOR_VERSION = "AceConsole-2.0" flickerstreak@22: local MINOR_VERSION = "$Revision: 48940 $" flickerstreak@1: flickerstreak@1: if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end flickerstreak@1: if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end flickerstreak@1: flickerstreak@1: if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0.") end flickerstreak@1: flickerstreak@22: -- #AUTODOC_NAMESPACE AceConsole flickerstreak@22: flickerstreak@22: local MAP_ONOFF, USAGE, IS_CURRENTLY_SET_TO, IS_NOW_SET_TO, IS_NOT_A_VALID_OPTION_FOR, IS_NOT_A_VALID_VALUE_FOR, NO_OPTIONS_AVAILABLE, OPTION_HANDLER_NOT_FOUND, OPTION_HANDLER_NOT_VALID, OPTION_IS_DISABLED, KEYBINDING_USAGE, DEFAULT_CONFIRM_MESSAGE flickerstreak@1: if GetLocale() == "deDE" then flickerstreak@1: MAP_ONOFF = { [false] = "|cffff0000Aus|r", [true] = "|cff00ff00An|r" } flickerstreak@1: USAGE = "Benutzung" flickerstreak@1: IS_CURRENTLY_SET_TO = "|cffffff7f%s|r steht momentan auf |cffffff7f[|r%s|cffffff7f]|r" flickerstreak@1: IS_NOW_SET_TO = "|cffffff7f%s|r ist nun auf |cffffff7f[|r%s|cffffff7f]|r gesetzt" flickerstreak@1: IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] ist keine g\195\188ltige Option f\195\188r |cffffff7f%s|r" flickerstreak@1: IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] ist kein g\195\188ltiger Wert f\195\188r |cffffff7f%s|r" flickerstreak@1: NO_OPTIONS_AVAILABLE = "Keine Optionen verfügbar" flickerstreak@1: OPTION_HANDLER_NOT_FOUND = "Optionen handler |cffffff7f%q|r nicht gefunden." flickerstreak@1: OPTION_HANDLER_NOT_VALID = "Optionen handler nicht g\195\188ltig." flickerstreak@1: OPTION_IS_DISABLED = "Option |cffffff7f%s|r deaktiviert." flickerstreak@1: KEYBINDING_USAGE = "" -- fix flickerstreak@22: DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?" -- fix flickerstreak@1: elseif GetLocale() == "frFR" then flickerstreak@1: MAP_ONOFF = { [false] = "|cffff0000Inactif|r", [true] = "|cff00ff00Actif|r" } flickerstreak@1: USAGE = "Utilisation" flickerstreak@1: IS_CURRENTLY_SET_TO = "|cffffff7f%s|r est actuellement positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r" flickerstreak@1: IS_NOW_SET_TO = "|cffffff7f%s|r est maintenant positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r" flickerstreak@1: IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] n'est pas une option valide pour |cffffff7f%s|r" flickerstreak@1: IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] n'est pas une valeur valide pour |cffffff7f%s|r" flickerstreak@1: NO_OPTIONS_AVAILABLE = "Pas d'options disponibles" flickerstreak@1: OPTION_HANDLER_NOT_FOUND = "Le gestionnaire d'option |cffffff7f%q|r n'a pas \195\169t\195\169 trouv\195\169." flickerstreak@1: OPTION_HANDLER_NOT_VALID = "Le gestionnaire d'option n'est pas valide." flickerstreak@1: OPTION_IS_DISABLED = "L'option |cffffff7f%s|r est d\195\169sactiv\195\169e." flickerstreak@1: KEYBINDING_USAGE = "" -- fix flickerstreak@22: DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?" -- fix flickerstreak@1: elseif GetLocale() == "koKR" then flickerstreak@1: MAP_ONOFF = { [false] = "|cffff0000끔|r", [true] = "|cff00ff00켬|r" } flickerstreak@1: USAGE = "사용법" flickerstreak@22: IS_CURRENTLY_SET_TO = "|cffffff7f%s|r|1은;는; 현재 상태는 |cffffff7f[|r%s|cffffff7f]|r|1으로;로; 설정되어 있습니다." flickerstreak@22: IS_NOW_SET_TO = "|cffffff7f%s|r|1을;를; |cffffff7f[|r%s|cffffff7f]|r 상태로 변경합니다." flickerstreak@22: IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r]|1은;는; |cffffff7f%s|r에서 사용 불가능한 설정입니다." flickerstreak@22: IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r]|1은;는; |cffffff7f%s|r에서 사용 불가능한 설정 값입니다." flickerstreak@22: NO_OPTIONS_AVAILABLE = "가능한 설정이 없습니다." flickerstreak@22: OPTION_HANDLER_NOT_FOUND = "설정 조정 값인 |cffffff7f%q|r|1을;를; 찾지 못했습니다." flickerstreak@22: OPTION_HANDLER_NOT_VALID = "설정 조정 값이 올바르지 않습니다." flickerstreak@1: OPTION_IS_DISABLED = "|cffffff7f%s|r 설정은 사용할 수 없습니다." flickerstreak@22: KEYBINDING_USAGE = "" flickerstreak@22: DEFAULT_CONFIRM_MESSAGE = "정말 당신은 `%s'|1을;를; 하시겠습니까?" flickerstreak@1: elseif GetLocale() == "zhCN" then flickerstreak@1: MAP_ONOFF = { [false] = "|cffff0000\229\133\179\233\151\173|r", [true] = "|cff00ff00\229\188\128\229\144\175|r" } flickerstreak@1: USAGE = "\231\148\168\230\179\149" flickerstreak@1: IS_CURRENTLY_SET_TO = "|cffffff7f%s|r \229\189\147\229\137\141\232\162\171\232\174\190\231\189\174 |cffffff7f[|r%s|cffffff7f]|r" flickerstreak@1: IS_NOW_SET_TO = "|cffffff7f%s|r \231\142\176\229\156\168\232\162\171\232\174\190\231\189\174\228\184\186 |cffffff7f[|r%s|cffffff7f]|r" flickerstreak@1: IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] \228\184\141\230\152\175\228\184\128\228\184\170\230\156\137\230\149\136\231\154\132\233\128\137\233\161\185 \228\184\186 |cffffff7f%s|r" flickerstreak@1: IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] \228\184\141\230\152\175\228\184\128\228\184\170\230\156\137\230\149\136\229\128\188 \228\184\186 |cffffff7f%s|r" flickerstreak@1: NO_OPTIONS_AVAILABLE = "\230\178\161\230\156\137\233\128\137\233\161\185\229\143\175\231\148\168" flickerstreak@1: OPTION_HANDLER_NOT_FOUND = "\233\128\137\233\161\185\229\164\132\231\144\134\231\168\139\229\186\143 |cffffff7f%q|r \230\178\161\230\159\165\230\137\190." flickerstreak@1: OPTION_HANDLER_NOT_VALID = "\233\128\137\233\161\185\229\164\132\231\144\134\231\168\139\229\186\143 \230\151\160\230\149\136." flickerstreak@1: OPTION_IS_DISABLED = "\233\128\137\233\161\185 |cffffff7f%s|r \228\184\141\229\174\140\230\149\180." flickerstreak@1: KEYBINDING_USAGE = "" -- fix flickerstreak@22: DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?" -- fix flickerstreak@1: elseif GetLocale() == "zhTW" then flickerstreak@1: MAP_ONOFF = { [false] = "|cffff0000關閉|r", [true] = "|cff00ff00開啟|r" } flickerstreak@1: USAGE = "用法" flickerstreak@22: IS_CURRENTLY_SET_TO = "|cffffff7f%s|r目前的設定為|cffffff7f[|r%s|cffffff7f]|r" flickerstreak@22: IS_NOW_SET_TO = "|cffffff7f%s|r現在被設定為|cffffff7f[|r%s|cffffff7f]|r" flickerstreak@22: IS_NOT_A_VALID_OPTION_FOR = "對於|cffffff7f%2$s|r,[|cffffff7f%1$s|r]是一個不符合規定的選項" flickerstreak@22: IS_NOT_A_VALID_VALUE_FOR = "對於|cffffff7f%2$s|r,[|cffffff7f%1$s|r]是一個不符合規定的數值" flickerstreak@22: NO_OPTIONS_AVAILABLE = "沒有可用的選項" flickerstreak@22: OPTION_HANDLER_NOT_FOUND = "找不到|cffffff7f%q|r選項處理器。" flickerstreak@1: OPTION_HANDLER_NOT_VALID = "選項處理器不符合規定。" flickerstreak@22: OPTION_IS_DISABLED = "|cffffff7f%s|r已被停用。" flickerstreak@22: KEYBINDING_USAGE = "" flickerstreak@22: DEFAULT_CONFIRM_MESSAGE = "是否執行「%s」?" flickerstreak@22: elseif GetLocale() == "esES" then flickerstreak@22: MAP_ONOFF = { [false] = "|cffff0000Desactivado|r", [true] = "|cff00ff00Activado|r" } flickerstreak@22: USAGE = "Uso" flickerstreak@22: IS_CURRENTLY_SET_TO = "|cffffff7f%s|r est\195\161 establecido actualmente a |cffffff7f[|r%s|cffffff7f]|r" flickerstreak@22: IS_NOW_SET_TO = "|cffffff7f%s|r se ha establecido a |cffffff7f[|r%s|cffffff7f]|r" flickerstreak@22: IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] no es una opci\195\179n valida para |cffffff7f%s|r" flickerstreak@22: IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] no es un valor v\195\161lido para |cffffff7f%s|r" flickerstreak@22: NO_OPTIONS_AVAILABLE = "No hay opciones disponibles" flickerstreak@22: OPTION_HANDLER_NOT_FOUND = "Gestor de opciones |cffffff7f%q|r no encontrado." flickerstreak@22: OPTION_HANDLER_NOT_VALID = "Gestor de opciones no v\195\161lido." flickerstreak@22: OPTION_IS_DISABLED = "La opci\195\179n |cffffff7f%s|r est\195\161 desactivada." flickerstreak@22: KEYBINDING_USAGE = "" flickerstreak@22: DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?" -- fix flickerstreak@1: else -- enUS flickerstreak@1: MAP_ONOFF = { [false] = "|cffff0000Off|r", [true] = "|cff00ff00On|r" } flickerstreak@1: USAGE = "Usage" flickerstreak@1: IS_CURRENTLY_SET_TO = "|cffffff7f%s|r is currently set to |cffffff7f[|r%s|cffffff7f]|r" flickerstreak@1: IS_NOW_SET_TO = "|cffffff7f%s|r is now set to |cffffff7f[|r%s|cffffff7f]|r" flickerstreak@1: IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] is not a valid option for |cffffff7f%s|r" flickerstreak@1: IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] is not a valid value for |cffffff7f%s|r" flickerstreak@1: NO_OPTIONS_AVAILABLE = "No options available" flickerstreak@1: OPTION_HANDLER_NOT_FOUND = "Option handler |cffffff7f%q|r not found." flickerstreak@1: OPTION_HANDLER_NOT_VALID = "Option handler not valid." flickerstreak@1: OPTION_IS_DISABLED = "Option |cffffff7f%s|r is disabled." flickerstreak@1: KEYBINDING_USAGE = "" flickerstreak@22: DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?" flickerstreak@1: end flickerstreak@1: flickerstreak@1: local NONE = NONE or "None" flickerstreak@1: flickerstreak@1: local AceOO = AceLibrary("AceOO-2.0") flickerstreak@1: local AceEvent flickerstreak@1: flickerstreak@22: local AceConsole = AceOO.Mixin { "Print", "PrintComma", "PrintLiteral", "CustomPrint", "RegisterChatCommand" } flickerstreak@1: local Dewdrop flickerstreak@1: flickerstreak@1: local _G = getfenv(0) flickerstreak@1: flickerstreak@1: local function print(text, name, r, g, b, frame, delay) flickerstreak@1: if not text or text:len() == 0 then flickerstreak@1: text = " " flickerstreak@1: end flickerstreak@1: if not name or name == AceConsole then flickerstreak@1: else flickerstreak@22: text = "|cffffff78" .. tostring(name) .. ":|r " .. text flickerstreak@1: end flickerstreak@22: local last_color flickerstreak@22: for t in text:gmatch("[^\n]+") do flickerstreak@22: (frame or DEFAULT_CHAT_FRAME):AddMessage(last_color and "|cff" .. last_color .. t or t, r, g, b, nil, delay or 5) flickerstreak@22: if not last_color or t:find("|r") or t:find("|c") then flickerstreak@22: last_color = t:match(".*|c[fF][fF](%x%x%x%x%x%x)[^|]-$") flickerstreak@22: end flickerstreak@22: end flickerstreak@22: return text flickerstreak@1: end flickerstreak@1: flickerstreak@1: local real_tostring = tostring flickerstreak@1: flickerstreak@1: local function tostring(t) flickerstreak@1: if type(t) == "table" then flickerstreak@1: if type(rawget(t, 0)) == "userdata" and type(t.GetObjectType) == "function" then flickerstreak@22: return ("<%s:%s>"):format(t:GetObjectType(), t:GetName() or "(anon)") flickerstreak@1: end flickerstreak@1: end flickerstreak@1: return real_tostring(t) flickerstreak@1: end flickerstreak@1: flickerstreak@22: local getkeystring flickerstreak@22: flickerstreak@22: local function isList(t) flickerstreak@22: local n = #t flickerstreak@22: for k,v in pairs(t) do flickerstreak@22: if type(k) ~= "number" then flickerstreak@22: return false flickerstreak@22: elseif k < 1 or k > n then flickerstreak@22: return false flickerstreak@22: end flickerstreak@1: end flickerstreak@22: return true flickerstreak@1: end flickerstreak@22: flickerstreak@22: local findGlobal = setmetatable({}, {__index=function(self, t) flickerstreak@22: for k,v in pairs(_G) do flickerstreak@22: if v == t then flickerstreak@22: k = tostring(k) flickerstreak@22: self[v] = k flickerstreak@22: return k flickerstreak@22: end flickerstreak@22: end flickerstreak@22: self[t] = false flickerstreak@22: return false flickerstreak@22: end}) flickerstreak@22: flickerstreak@22: local recurse = {} flickerstreak@22: local timeToEnd flickerstreak@22: local GetTime = GetTime flickerstreak@22: local type = type flickerstreak@22: flickerstreak@22: local new, del flickerstreak@22: do flickerstreak@22: local cache = setmetatable({},{__mode='k'}) flickerstreak@22: function new() flickerstreak@22: local t = next(cache) flickerstreak@22: if t then flickerstreak@22: cache[t] = nil flickerstreak@22: return t flickerstreak@22: else flickerstreak@22: return {} flickerstreak@22: end flickerstreak@22: end flickerstreak@22: flickerstreak@22: function del(t) flickerstreak@22: for k in pairs(t) do flickerstreak@22: t[k] = nil flickerstreak@22: end flickerstreak@22: cache[t] = true flickerstreak@22: return nil flickerstreak@22: end flickerstreak@22: end flickerstreak@22: flickerstreak@22: local function ignoreCaseSort(alpha, bravo) flickerstreak@22: if not alpha or not bravo then flickerstreak@22: return false flickerstreak@22: end flickerstreak@22: return tostring(alpha):lower() < tostring(bravo):lower() flickerstreak@22: end flickerstreak@22: flickerstreak@22: local function specialSort(alpha, bravo) flickerstreak@22: if alpha == nil or bravo == nil then flickerstreak@22: return false flickerstreak@22: end flickerstreak@22: local type_alpha, type_bravo = type(alpha), type(bravo) flickerstreak@22: if type_alpha ~= type_bravo then flickerstreak@22: return type_alpha < type_bravo flickerstreak@22: end flickerstreak@22: if type_alpha == "string" then flickerstreak@22: return alpha:lower() < bravo:lower() flickerstreak@22: elseif type_alpha == "number" then flickerstreak@22: return alpha < bravo flickerstreak@22: elseif type_alpha == "table" then flickerstreak@22: return #alpha < #bravo flickerstreak@22: elseif type_alpha == "boolean" then flickerstreak@22: return not alpha flickerstreak@22: else flickerstreak@22: return false flickerstreak@22: end flickerstreak@22: end flickerstreak@22: flickerstreak@22: local function escapeChar(c) flickerstreak@22: return ("\\%03d"):format(c:byte()) flickerstreak@22: end flickerstreak@22: flickerstreak@22: local function literal_tostring_prime(t, depth) flickerstreak@22: if type(t) == "string" then flickerstreak@22: return ("|cff00ff00%q|r"):format((t:gsub("|", "||"))):gsub("[\001-\012\014-\031\128-\255]", escapeChar) flickerstreak@22: elseif type(t) == "table" then flickerstreak@22: if t == _G then flickerstreak@22: return "|cffffea00_G|r" flickerstreak@22: end flickerstreak@22: if type(rawget(t, 0)) == "userdata" and type(t.GetObjectType) == "function" then flickerstreak@22: return ("|cffffea00<%s:%s>|r"):format(t:GetObjectType(), t:GetName() or "(anon)") flickerstreak@22: end flickerstreak@22: if next(t) == nil then flickerstreak@22: local mt = getmetatable(t) flickerstreak@22: if type(mt) == "table" and type(mt.__raw) == "table" then flickerstreak@22: t = mt.__raw flickerstreak@22: end flickerstreak@22: end flickerstreak@22: if recurse[t] then flickerstreak@22: local g = findGlobal[t] flickerstreak@22: if g then flickerstreak@22: return ("|cff9f9f9f|r"):format(g) flickerstreak@22: else flickerstreak@22: return ("|cff9f9f9f|r"):format(real_tostring(t):gsub("|", "||")) flickerstreak@22: end flickerstreak@22: elseif GetTime() > timeToEnd then flickerstreak@22: local g = findGlobal[t] flickerstreak@22: if g then flickerstreak@22: return ("|cff9f9f9f|r"):format(g) flickerstreak@22: else flickerstreak@22: return ("|cff9f9f9f|r"):format(real_tostring(t):gsub("|", "||")) flickerstreak@22: end flickerstreak@22: elseif depth >= 2 then flickerstreak@22: local g = findGlobal[t] flickerstreak@22: if g then flickerstreak@22: return ("|cff9f9f9f<_G[%q]>|r"):format(g) flickerstreak@22: else flickerstreak@22: return ("|cff9f9f9f<%s>|r"):format(real_tostring(t):gsub("|", "||")) flickerstreak@22: end flickerstreak@22: end flickerstreak@22: recurse[t] = true flickerstreak@22: if next(t) == nil then flickerstreak@22: return "{}" flickerstreak@22: elseif next(t, (next(t))) == nil then flickerstreak@22: local k, v = next(t) flickerstreak@22: if k == 1 then flickerstreak@22: return "{ " .. literal_tostring_prime(v, depth+1) .. " }" flickerstreak@22: else flickerstreak@22: return "{ " .. getkeystring(k, depth+1) .. " = " .. literal_tostring_prime(v, depth+1) .. " }" flickerstreak@22: end flickerstreak@22: end flickerstreak@22: local s flickerstreak@22: local g = findGlobal[t] flickerstreak@22: if g then flickerstreak@22: s = ("{ |cff9f9f9f-- _G[%q]|r\n"):format(g) flickerstreak@22: else flickerstreak@22: s = "{ |cff9f9f9f-- " .. real_tostring(t):gsub("|", "||") .. "|r\n" flickerstreak@22: end flickerstreak@22: if isList(t) then flickerstreak@22: for i = 1, #t do flickerstreak@22: s = s .. (" "):rep(depth+1) .. literal_tostring_prime(t[i], depth+1) .. (i == #t and "\n" or ",\n") flickerstreak@22: end flickerstreak@22: else flickerstreak@22: local tmp = new() flickerstreak@22: for k in pairs(t) do flickerstreak@22: tmp[#tmp+1] = k flickerstreak@22: end flickerstreak@22: table.sort(tmp, specialSort) flickerstreak@22: for i,k in ipairs(tmp) do flickerstreak@22: tmp[i] = nil flickerstreak@22: local v = t[k] flickerstreak@22: s = s .. (" "):rep(depth+1) .. getkeystring(k, depth+1) .. " = " .. literal_tostring_prime(v, depth+1) .. (tmp[i+1] == nil and "\n" or ",\n") flickerstreak@22: end flickerstreak@22: tmp = del(tmp) flickerstreak@22: end flickerstreak@22: if g then flickerstreak@22: s = s .. (" "):rep(depth) .. string.format("} |cff9f9f9f-- _G[%q]|r", g) flickerstreak@22: else flickerstreak@22: s = s .. (" "):rep(depth) .. "} |cff9f9f9f-- " .. real_tostring(t):gsub("|", "||") flickerstreak@22: end flickerstreak@22: return s flickerstreak@22: end flickerstreak@22: if type(t) == "number" then flickerstreak@22: return "|cffff7fff" .. real_tostring(t) .. "|r" flickerstreak@22: elseif type(t) == "boolean" then flickerstreak@22: return "|cffff9100" .. real_tostring(t) .. "|r" flickerstreak@22: elseif t == nil then flickerstreak@22: return "|cffff7f7f" .. real_tostring(t) .. "|r" flickerstreak@22: else flickerstreak@22: return "|cffffea00" .. real_tostring(t) .. "|r" flickerstreak@22: end flickerstreak@22: end flickerstreak@22: flickerstreak@22: function getkeystring(t, depth) flickerstreak@22: if type(t) == "string" then flickerstreak@22: if t:find("^[%a_][%a%d_]*$") then flickerstreak@22: return "|cff7fd5ff" .. t .. "|r" flickerstreak@22: end flickerstreak@22: end flickerstreak@22: return "[" .. literal_tostring_prime(t, depth) .. "]" flickerstreak@22: end flickerstreak@22: flickerstreak@22: local get_stringed_args flickerstreak@22: do flickerstreak@22: local function g(value, ...) flickerstreak@22: if select('#', ...) == 0 then flickerstreak@22: return literal_tostring_prime(value, 1) flickerstreak@22: end flickerstreak@22: return literal_tostring_prime(value, 1) .. ", " .. g(...) flickerstreak@22: end flickerstreak@22: flickerstreak@22: local function f(success, ...) flickerstreak@22: if not success then flickerstreak@1: return flickerstreak@1: end flickerstreak@22: return g(...) flickerstreak@1: end flickerstreak@22: flickerstreak@22: function get_stringed_args(func, ...) flickerstreak@22: return f(pcall(func, ...)) flickerstreak@22: end flickerstreak@22: end flickerstreak@22: flickerstreak@22: local function literal_tostring_frame(t) flickerstreak@22: local s = ("|cffffea00<%s:%s|r\n"):format(t:GetObjectType(), t:GetName() or "(anon)") flickerstreak@22: local __index = getmetatable(t).__index flickerstreak@22: local tmp, tmp2, tmp3 = new(), new(), new() flickerstreak@22: for k in pairs(t) do flickerstreak@22: if k ~= 0 then flickerstreak@22: tmp3[k] = true flickerstreak@22: tmp2[k] = true flickerstreak@22: end flickerstreak@22: end flickerstreak@22: for k in pairs(__index) do flickerstreak@22: tmp2[k] = true flickerstreak@22: end flickerstreak@22: for k in pairs(tmp2) do flickerstreak@22: tmp[#tmp+1] = k flickerstreak@22: tmp2[k] = nil flickerstreak@22: end flickerstreak@22: table.sort(tmp, ignoreCaseSort) flickerstreak@22: local first = true flickerstreak@22: for i,k in ipairs(tmp) do flickerstreak@22: local v = t[k] flickerstreak@22: local good = true flickerstreak@22: if k == "GetPoint" then flickerstreak@22: for i = 1, t:GetNumPoints() do flickerstreak@22: if not first then flickerstreak@22: s = s .. ",\n" flickerstreak@22: else flickerstreak@22: first = false flickerstreak@22: end flickerstreak@22: s = s .. " " .. getkeystring(k, 1) .. "(" .. literal_tostring_prime(i, 1) .. ") => " .. get_stringed_args(v, t, i) flickerstreak@22: end flickerstreak@22: elseif type(v) == "function" and type(k) == "string" and (k:find("^Is") or k:find("^Get") or k:find("^Can")) then flickerstreak@22: local q = get_stringed_args(v, t) flickerstreak@22: if q then flickerstreak@22: if not first then flickerstreak@22: s = s .. ",\n" flickerstreak@22: else flickerstreak@22: first = false flickerstreak@22: end flickerstreak@22: s = s .. " " .. getkeystring(k, 1) .. "() => " .. q flickerstreak@22: end flickerstreak@22: elseif type(v) ~= "function" or (type(v) == "function" and type(k) == "string" and tmp3[k]) then flickerstreak@22: if not first then flickerstreak@22: s = s .. ",\n" flickerstreak@22: else flickerstreak@22: first = false flickerstreak@22: end flickerstreak@22: s = s .. " " .. getkeystring(k, 1) .. " = " .. literal_tostring_prime(v, 1) flickerstreak@22: else flickerstreak@22: good = false flickerstreak@22: end flickerstreak@22: end flickerstreak@22: tmp, tmp2, tmp3 = del(tmp), del(tmp2), del(tmp3) flickerstreak@22: s = s .. "\n|cffffea00>|r" flickerstreak@22: return s flickerstreak@22: end flickerstreak@22: flickerstreak@22: local function literal_tostring(t, only) flickerstreak@22: timeToEnd = GetTime() + 0.2 flickerstreak@22: local s flickerstreak@22: if only and type(t) == "table" and type(rawget(t, 0)) == "userdata" and type(t.GetObjectType) == "function" then flickerstreak@22: s = literal_tostring_frame(t) flickerstreak@22: else flickerstreak@22: s = literal_tostring_prime(t, 0) flickerstreak@22: end flickerstreak@22: for k,v in pairs(recurse) do flickerstreak@22: recurse[k] = nil flickerstreak@22: end flickerstreak@22: for k,v in pairs(findGlobal) do flickerstreak@22: findGlobal[k] = nil flickerstreak@22: end flickerstreak@22: return s flickerstreak@22: end flickerstreak@22: flickerstreak@22: local function tostring_args(a1, ...) flickerstreak@22: if select('#', ...) < 1 then flickerstreak@22: return tostring(a1) flickerstreak@22: end flickerstreak@22: return tostring(a1), tostring_args(...) flickerstreak@22: end flickerstreak@22: flickerstreak@22: local function literal_tostring_args(a1, ...) flickerstreak@22: if select('#', ...) < 1 then flickerstreak@22: return literal_tostring(a1) flickerstreak@22: end flickerstreak@22: return literal_tostring(a1), literal_tostring_args(...) flickerstreak@22: end flickerstreak@22: flickerstreak@22: function AceConsole:CustomPrint(r, g, b, frame, delay, connector, a1, ...) flickerstreak@22: if connector == true then flickerstreak@22: local s flickerstreak@22: if select('#', ...) == 0 then flickerstreak@22: s = literal_tostring(a1, true) flickerstreak@22: else flickerstreak@22: s = (", "):join(literal_tostring_args(a1, ...)) flickerstreak@22: end flickerstreak@22: return print(s, self, r, g, b, frame or self.printFrame, delay) flickerstreak@22: elseif tostring(a1):find("%%") and select('#', ...) >= 1 then flickerstreak@22: local success, text = pcall(string.format, tostring_args(a1, ...)) flickerstreak@22: if success then flickerstreak@22: return print(text, self, r, g, b, frame or self.printFrame, delay) flickerstreak@22: end flickerstreak@22: end flickerstreak@22: return print((connector or " "):join(tostring_args(a1, ...)), self, r, g, b, frame or self.printFrame, delay) flickerstreak@1: end flickerstreak@1: flickerstreak@1: function AceConsole:Print(...) flickerstreak@1: return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, " ", ...) flickerstreak@1: end flickerstreak@1: flickerstreak@1: function AceConsole:PrintComma(...) flickerstreak@1: return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, ", ", ...) flickerstreak@1: end flickerstreak@1: flickerstreak@22: function AceConsole:PrintLiteral(...) flickerstreak@22: return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, true, ...) flickerstreak@22: end flickerstreak@22: flickerstreak@1: local work flickerstreak@1: local argwork flickerstreak@1: flickerstreak@1: local function findTableLevel(self, options, chat, text, index, passTable) flickerstreak@1: if not index then flickerstreak@1: index = 1 flickerstreak@1: if work then flickerstreak@1: for k,v in pairs(work) do flickerstreak@1: work[k] = nil flickerstreak@1: end flickerstreak@1: for k,v in pairs(argwork) do flickerstreak@1: argwork[k] = nil flickerstreak@1: end flickerstreak@1: else flickerstreak@1: work = {} flickerstreak@1: argwork = {} flickerstreak@1: end flickerstreak@1: local len = text:len() flickerstreak@1: local count flickerstreak@1: repeat flickerstreak@1: text, count = text:gsub("(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[[^%]]-) (.-%]|h|r)", "%1\001%2") flickerstreak@1: until count == 0 flickerstreak@1: text = text:gsub("(%]|h|r)(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[)", "%1 %2") flickerstreak@1: for token in text:gmatch("([^%s]+)") do flickerstreak@1: local token = token flickerstreak@1: local num = tonumber(token) flickerstreak@1: if num then flickerstreak@1: token = num flickerstreak@1: else flickerstreak@1: token = token:gsub("\001", " ") flickerstreak@1: end flickerstreak@1: table.insert(work, token) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: local path = chat flickerstreak@1: for i = 1, index - 1 do flickerstreak@1: path = path .. " " .. tostring(work[i]) flickerstreak@1: end flickerstreak@22: flickerstreak@22: local passValue = options.passValue or (passTable and work[index-1]) flickerstreak@22: passTable = passTable or options flickerstreak@22: flickerstreak@1: if type(options.args) == "table" then flickerstreak@1: local disabled, hidden = options.disabled, options.cmdHidden or options.hidden flickerstreak@1: if hidden then flickerstreak@1: if type(hidden) == "function" then flickerstreak@22: hidden = hidden(passValue) flickerstreak@1: elseif type(hidden) == "string" then flickerstreak@1: local handler = options.handler or self flickerstreak@1: local f = hidden flickerstreak@1: local neg = f:match("^~(.-)$") flickerstreak@1: if neg then flickerstreak@1: f = neg flickerstreak@1: end flickerstreak@1: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@1: end flickerstreak@22: hidden = handler[f](handler, passValue) flickerstreak@1: if neg then flickerstreak@1: hidden = not hidden flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if hidden then flickerstreak@1: disabled = true flickerstreak@1: elseif disabled then flickerstreak@1: if type(disabled) == "function" then flickerstreak@22: disabled = disabled(passValue) flickerstreak@1: elseif type(disabled) == "string" then flickerstreak@1: local handler = options.handler or self flickerstreak@1: local f = disabled flickerstreak@1: local neg = f:match("^~(.-)$") flickerstreak@1: if neg then flickerstreak@1: f = neg flickerstreak@1: end flickerstreak@1: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@1: end flickerstreak@22: disabled = handler[f](handler, passValue) flickerstreak@1: if neg then flickerstreak@1: disabled = not disabled flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if not disabled then flickerstreak@22: local next = work[index] and tostring(work[index]):lower() flickerstreak@22: local next_num = tonumber(next) flickerstreak@1: if next then flickerstreak@1: for k,v in pairs(options.args) do flickerstreak@1: local good = false flickerstreak@22: if tostring(k):gsub("%s", "-"):lower() == next then flickerstreak@22: good = true flickerstreak@22: elseif k == next_num then flickerstreak@1: good = true flickerstreak@1: elseif type(v.aliases) == "table" then flickerstreak@1: for _,alias in ipairs(v.aliases) do flickerstreak@22: if alias:gsub("%s", "-"):lower() == next then flickerstreak@1: good = true flickerstreak@1: break flickerstreak@1: end flickerstreak@1: end flickerstreak@22: elseif type(v.aliases) == "string" and v.aliases:gsub("%s", "-"):lower() == next then flickerstreak@1: good = true flickerstreak@1: end flickerstreak@1: if good then flickerstreak@22: work[index] = k -- revert it back to its original form as supplied in args flickerstreak@22: if options.pass then flickerstreak@22: passTable = passTable or options flickerstreak@22: if options.get and options.set then flickerstreak@22: passTable = options flickerstreak@22: end flickerstreak@22: else flickerstreak@22: passTable = nil flickerstreak@22: end flickerstreak@22: return findTableLevel(options.handler or self, v, chat, text, index + 1, passTable) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: for i = index, #work do flickerstreak@1: table.insert(argwork, work[i]) flickerstreak@1: end flickerstreak@22: return options, path, argwork, options.handler or self, passTable, passValue flickerstreak@1: end flickerstreak@1: flickerstreak@1: local function validateOptionsMethods(self, options, position) flickerstreak@1: if type(options) ~= "table" then flickerstreak@1: return "Options must be a table.", position flickerstreak@1: end flickerstreak@1: self = options.handler or self flickerstreak@1: if options.type == "execute" then flickerstreak@1: if options.func and type(options.func) ~= "string" and type(options.func) ~= "function" then flickerstreak@1: return "func must be a string or function", position flickerstreak@1: end flickerstreak@1: if options.func and type(options.func) == "string" and type(self[options.func]) ~= "function" then flickerstreak@22: return ("%q is not a proper function"):format(tostring(options.func)), position flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if options.get then flickerstreak@1: if type(options.get) ~= "string" and type(options.get) ~= "function" then flickerstreak@1: return "get must be a string or function", position flickerstreak@1: end flickerstreak@1: if type(options.get) == "string" then flickerstreak@1: local f = options.get flickerstreak@1: if options.type == "toggle" then flickerstreak@1: f = f:match("^~(.-)$") or f flickerstreak@1: end flickerstreak@1: if type(self[f]) ~= "function" then flickerstreak@22: return ("%q is not a proper function"):format(tostring(f)), position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.set then flickerstreak@1: if type(options.set) ~= "string" and type(options.set) ~= "function" then flickerstreak@1: return "set must be a string or function", position flickerstreak@1: end flickerstreak@1: if type(options.set) == "string" and type(self[options.set]) ~= "function" then flickerstreak@22: return ("%q is not a proper function"):format(tostring(options.set)), position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.validate and type(options.validate) ~= "table" and options.validate ~= "keybinding" then flickerstreak@1: if type(options.validate) ~= "string" and type(options.validate) ~= "function" then flickerstreak@1: return "validate must be a string or function", position flickerstreak@1: end flickerstreak@1: if type(options.validate) == "string" and type(self[options.validate]) ~= "function" then flickerstreak@22: return ("%q is not a proper function"):format(tostring(options.validate)), position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.disabled and type(options.disabled) == "string" then flickerstreak@1: local f = options.disabled flickerstreak@1: f = f:match("^~(.-)$") or f flickerstreak@1: if type(self[f]) ~= "function" then flickerstreak@22: return ("%q is not a proper function"):format(tostring(f)), position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.cmdHidden and type(options.cmdHidden) == "string" then flickerstreak@1: local f = options.cmdHidden flickerstreak@1: f = f:match("^~(.-)$") or f flickerstreak@1: if type(self[f]) ~= "function" then flickerstreak@22: return ("%q is not a proper function"):format(tostring(f)), position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.guiHidden and type(options.guiHidden) == "string" then flickerstreak@1: local f = options.guiHidden flickerstreak@1: f = f:match("^~(.-)$") or f flickerstreak@1: if type(self[f]) ~= "function" then flickerstreak@22: return ("%q is not a proper function"):format(tostring(f)), position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.hidden and type(options.hidden) == "string" then flickerstreak@1: local f = options.hidden flickerstreak@1: f = f:match("^~(.-)$") or f flickerstreak@1: if type(self[f]) ~= "function" then flickerstreak@22: return ("%q is not a proper function"):format(tostring(f)), position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.type == "group" and type(options.args) == "table" then flickerstreak@1: for k,v in pairs(options.args) do flickerstreak@1: if type(v) == "table" then flickerstreak@1: local newposition flickerstreak@1: if position then flickerstreak@1: newposition = position .. ".args." .. k flickerstreak@1: else flickerstreak@1: newposition = "args." .. k flickerstreak@1: end flickerstreak@1: local err, pos = validateOptionsMethods(self, v, newposition) flickerstreak@1: if err then flickerstreak@1: return err, pos flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: local function validateOptions(options, position, baseOptions, fromPass) flickerstreak@1: if not baseOptions then flickerstreak@1: baseOptions = options flickerstreak@1: end flickerstreak@1: if type(options) ~= "table" then flickerstreak@1: return "Options must be a table.", position flickerstreak@1: end flickerstreak@1: local kind = options.type flickerstreak@1: if type(kind) ~= "string" then flickerstreak@1: return '"type" must be a string.', position flickerstreak@1: elseif kind ~= "group" and kind ~= "range" and kind ~= "text" and kind ~= "execute" and kind ~= "toggle" and kind ~= "color" and kind ~= "header" then flickerstreak@1: return '"type" must either be "range", "text", "group", "toggle", "execute", "color", or "header".', position flickerstreak@1: end flickerstreak@1: if options.aliases then flickerstreak@1: if type(options.aliases) ~= "table" and type(options.aliases) ~= "string" then flickerstreak@1: return '"alias" must be a table or string', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if not fromPass then flickerstreak@1: if kind == "execute" then flickerstreak@1: if type(options.func) ~= "string" and type(options.func) ~= "function" then flickerstreak@1: return '"func" must be a string or function', position flickerstreak@1: end flickerstreak@1: elseif kind == "range" or kind == "text" or kind == "toggle" then flickerstreak@1: if type(options.set) ~= "string" and type(options.set) ~= "function" then flickerstreak@1: return '"set" must be a string or function', position flickerstreak@1: end flickerstreak@1: if kind == "text" and options.get == false then flickerstreak@1: elseif type(options.get) ~= "string" and type(options.get) ~= "function" then flickerstreak@1: return '"get" must be a string or function', position flickerstreak@1: end flickerstreak@1: elseif kind == "group" and options.pass then flickerstreak@1: if options.pass ~= true then flickerstreak@1: return '"pass" must be either nil, true, or false', position flickerstreak@1: end flickerstreak@1: if not options.func then flickerstreak@1: if type(options.set) ~= "string" and type(options.set) ~= "function" then flickerstreak@1: return '"set" must be a string or function', position flickerstreak@1: end flickerstreak@1: if type(options.get) ~= "string" and type(options.get) ~= "function" then flickerstreak@1: return '"get" must be a string or function', position flickerstreak@1: end flickerstreak@1: elseif type(options.func) ~= "string" and type(options.func) ~= "function" then flickerstreak@1: return '"func" must be a string or function', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options ~= baseOptions then flickerstreak@1: if kind == "header" then flickerstreak@1: elseif type(options.desc) ~= "string" then flickerstreak@1: return '"desc" must be a string', position flickerstreak@1: elseif options.desc:len() == 0 then flickerstreak@1: return '"desc" cannot be a 0-length string', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: if options ~= baseOptions or kind == "range" or kind == "text" or kind == "toggle" or kind == "color" then flickerstreak@1: if options.type == "header" and not options.cmdName and not options.name then flickerstreak@1: elseif options.cmdName then flickerstreak@1: if type(options.cmdName) ~= "string" then flickerstreak@1: return '"cmdName" must be a string or nil', position flickerstreak@1: elseif options.cmdName:len() == 0 then flickerstreak@1: return '"cmdName" cannot be a 0-length string', position flickerstreak@1: end flickerstreak@1: if type(options.guiName) ~= "string" then flickerstreak@1: if not options.guiNameIsMap then flickerstreak@1: return '"guiName" must be a string or nil', position flickerstreak@1: end flickerstreak@1: elseif options.guiName:len() == 0 then flickerstreak@1: return '"guiName" cannot be a 0-length string', position flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(options.name) ~= "string" then flickerstreak@1: return '"name" must be a string', position flickerstreak@1: elseif options.name:len() == 0 then flickerstreak@1: return '"name" cannot be a 0-length string', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.guiNameIsMap then flickerstreak@1: if type(options.guiNameIsMap) ~= "boolean" then flickerstreak@1: return '"guiNameIsMap" must be a boolean or nil', position flickerstreak@1: elseif options.type ~= "toggle" then flickerstreak@1: return 'if "guiNameIsMap" is true, then "type" must be set to \'toggle\'', position flickerstreak@1: elseif type(options.map) ~= "table" then flickerstreak@1: return '"map" must be a table', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.message and type(options.message) ~= "string" then flickerstreak@1: return '"message" must be a string or nil', position flickerstreak@1: end flickerstreak@1: if options.error and type(options.error) ~= "string" then flickerstreak@1: return '"error" must be a string or nil', position flickerstreak@1: end flickerstreak@1: if options.current and type(options.current) ~= "string" then flickerstreak@1: return '"current" must be a string or nil', position flickerstreak@1: end flickerstreak@1: if options.order then flickerstreak@1: if type(options.order) ~= "number" or (-1 < options.order and options.order < 0.999) then flickerstreak@1: return '"order" must be a non-zero number or nil', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.disabled then flickerstreak@1: if type(options.disabled) ~= "function" and type(options.disabled) ~= "string" and options.disabled ~= true then flickerstreak@1: return '"disabled" must be a function, string, or boolean', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.cmdHidden then flickerstreak@1: if type(options.cmdHidden) ~= "function" and type(options.cmdHidden) ~= "string" and options.cmdHidden ~= true then flickerstreak@1: return '"cmdHidden" must be a function, string, or boolean', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.guiHidden then flickerstreak@1: if type(options.guiHidden) ~= "function" and type(options.guiHidden) ~= "string" and options.guiHidden ~= true then flickerstreak@1: return '"guiHidden" must be a function, string, or boolean', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.hidden then flickerstreak@1: if type(options.hidden) ~= "function" and type(options.hidden) ~= "string" and options.hidden ~= true then flickerstreak@1: return '"hidden" must be a function, string, or boolean', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if kind == "text" then flickerstreak@1: if type(options.validate) == "table" then flickerstreak@1: local t = options.validate flickerstreak@1: local iTable = nil flickerstreak@1: for k,v in pairs(t) do flickerstreak@1: if type(k) == "number" then flickerstreak@1: if iTable == nil then flickerstreak@1: iTable = true flickerstreak@1: elseif not iTable then flickerstreak@1: return '"validate" must either have all keys be indexed numbers or strings', position flickerstreak@1: elseif k < 1 or k > #t then flickerstreak@1: return '"validate" numeric keys must be indexed properly. >= 1 and <= #validate', position flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if iTable == nil then flickerstreak@1: iTable = false flickerstreak@1: elseif iTable then flickerstreak@1: return '"validate" must either have all keys be indexed numbers or strings', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if type(v) ~= "string" then flickerstreak@1: return '"validate" values must all be strings', position flickerstreak@1: end flickerstreak@1: end flickerstreak@22: if options.multiToggle and options.multiToggle ~= true then flickerstreak@22: return '"multiToggle" must be a boolean or nil if "validate" is a table', position flickerstreak@22: end flickerstreak@1: elseif options.validate == "keybinding" then flickerstreak@22: flickerstreak@1: else flickerstreak@1: if type(options.usage) ~= "string" then flickerstreak@1: return '"usage" must be a string', position flickerstreak@1: elseif options.validate and type(options.validate) ~= "string" and type(options.validate) ~= "function" then flickerstreak@1: return '"validate" must be a string, function, or table', position flickerstreak@1: end flickerstreak@1: end flickerstreak@22: if options.multiToggle and type(options.validate) ~= "table" then flickerstreak@22: return '"validate" must be a table if "multiToggle" is true', position flickerstreak@22: end flickerstreak@1: elseif kind == "range" then flickerstreak@1: if options.min or options.max then flickerstreak@1: if type(options.min) ~= "number" then flickerstreak@1: return '"min" must be a number', position flickerstreak@1: elseif type(options.max) ~= "number" then flickerstreak@1: return '"max" must be a number', position flickerstreak@1: elseif options.min >= options.max then flickerstreak@1: return '"min" must be less than "max"', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.step then flickerstreak@1: if type(options.step) ~= "number" then flickerstreak@1: return '"step" must be a number', position flickerstreak@1: elseif options.step < 0 then flickerstreak@1: return '"step" must be nonnegative', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if options.isPercent and options.isPercent ~= true then flickerstreak@1: return '"isPercent" must either be nil, true, or false', position flickerstreak@1: end flickerstreak@1: elseif kind == "toggle" then flickerstreak@1: if options.map then flickerstreak@1: if type(options.map) ~= "table" then flickerstreak@1: return '"map" must be a table', position flickerstreak@1: elseif type(options.map[true]) ~= "string" then flickerstreak@1: return '"map[true]" must be a string', position flickerstreak@1: elseif type(options.map[false]) ~= "string" then flickerstreak@1: return '"map[false]" must be a string', position flickerstreak@1: end flickerstreak@1: end flickerstreak@1: elseif kind == "color" then flickerstreak@1: if options.hasAlpha and options.hasAlpha ~= true then flickerstreak@1: return '"hasAlpha" must be nil, true, or false', position flickerstreak@1: end flickerstreak@1: elseif kind == "group" then flickerstreak@1: if options.pass and options.pass ~= true then flickerstreak@1: return '"pass" must be nil, true, or false', position flickerstreak@1: end flickerstreak@1: if type(options.args) ~= "table" then flickerstreak@1: return '"args" must be a table', position flickerstreak@1: end flickerstreak@1: for k,v in pairs(options.args) do flickerstreak@22: if type(k) ~= "number" then flickerstreak@22: if type(k) ~= "string" then flickerstreak@22: return '"args" keys must be strings or numbers', position flickerstreak@22: elseif k:len() == 0 then flickerstreak@22: return '"args" keys must not be 0-length strings.', position flickerstreak@22: end flickerstreak@1: end flickerstreak@1: if type(v) ~= "table" then flickerstreak@22: if type(k) == "number" then flickerstreak@22: return '"args" values must be tables', position and position .. "[" .. k .. "]" or "[" .. k .. "]" flickerstreak@22: else flickerstreak@22: return '"args" values must be tables', position and position .. "." .. k or k flickerstreak@22: end flickerstreak@1: end flickerstreak@1: local newposition flickerstreak@22: if type(k) == "number" then flickerstreak@22: newposition = position and position .. ".args[" .. k .. "]" or "args[" .. k .. "]" flickerstreak@1: else flickerstreak@22: newposition = position and position .. ".args." .. k or "args." .. k flickerstreak@1: end flickerstreak@1: local err, pos = validateOptions(v, newposition, baseOptions, options.pass) flickerstreak@1: if err then flickerstreak@1: return err, pos flickerstreak@1: end flickerstreak@1: end flickerstreak@22: elseif kind == "execute" then flickerstreak@22: if type(options.confirm) ~= "string" and type(options.confirm) ~= "boolean" and type(options.confirm) ~= "nil" then flickerstreak@22: return '"confirm" must be a string, boolean, or nil', position flickerstreak@22: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: local colorTable flickerstreak@1: local colorFunc flickerstreak@1: local colorCancelFunc flickerstreak@1: flickerstreak@1: local function keybindingValidateFunc(text) flickerstreak@1: if text == nil or text == "NONE" then flickerstreak@1: return nil flickerstreak@1: end flickerstreak@1: text = text:upper() flickerstreak@1: local shift, ctrl, alt flickerstreak@1: local modifier flickerstreak@1: while true do flickerstreak@1: if text == "-" then flickerstreak@1: break flickerstreak@1: end flickerstreak@1: modifier, text = strsplit('-', text, 2) flickerstreak@1: if text then flickerstreak@1: if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then flickerstreak@1: return false flickerstreak@1: end flickerstreak@1: if modifier == "SHIFT" then flickerstreak@1: if shift then flickerstreak@1: return false flickerstreak@1: end flickerstreak@1: shift = true flickerstreak@1: end flickerstreak@1: if modifier == "CTRL" then flickerstreak@1: if ctrl then flickerstreak@1: return false flickerstreak@1: end flickerstreak@1: ctrl = true flickerstreak@1: end flickerstreak@1: if modifier == "ALT" then flickerstreak@1: if alt then flickerstreak@1: return false flickerstreak@1: end flickerstreak@1: alt = true flickerstreak@1: end flickerstreak@1: else flickerstreak@1: text = modifier flickerstreak@1: break flickerstreak@1: end flickerstreak@1: end flickerstreak@22: if not text:find("^F%d+$") and text ~= "CAPSLOCK" and text:len() ~= 1 and (text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] then flickerstreak@1: return false flickerstreak@1: end flickerstreak@1: local s = text flickerstreak@1: if shift then flickerstreak@1: s = "SHIFT-" .. s flickerstreak@1: end flickerstreak@1: if ctrl then flickerstreak@1: s = "CTRL-" .. s flickerstreak@1: end flickerstreak@1: if alt then flickerstreak@1: s = "ALT-" .. s flickerstreak@1: end flickerstreak@1: return s flickerstreak@1: end flickerstreak@1: AceConsole.keybindingValidateFunc = keybindingValidateFunc flickerstreak@1: flickerstreak@1: local order flickerstreak@1: flickerstreak@1: local mysort_args flickerstreak@1: local mysort flickerstreak@1: flickerstreak@22: local function icaseSort(alpha, bravo) flickerstreak@22: if type(alpha) == "number" and type(bravo) == "number" then flickerstreak@22: return alpha < bravo flickerstreak@22: end flickerstreak@22: return tostring(alpha):lower() < tostring(bravo):lower() flickerstreak@22: end flickerstreak@22: flickerstreak@22: local tmp = {} flickerstreak@22: local function printUsage(self, handler, realOptions, options, path, args, passValue, quiet, filter) flickerstreak@1: if filter then flickerstreak@1: filter = "^" .. filter:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1") flickerstreak@1: end flickerstreak@1: local hidden, disabled = options.cmdHidden or options.hidden, options.disabled flickerstreak@1: if hidden then flickerstreak@1: if type(hidden) == "function" then flickerstreak@22: hidden = hidden(options.passValue) flickerstreak@1: elseif type(hidden) == "string" then flickerstreak@1: local f = hidden flickerstreak@1: local neg = f:match("^~(.-)$") flickerstreak@1: if neg then flickerstreak@1: f = neg flickerstreak@1: end flickerstreak@1: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@1: end flickerstreak@22: hidden = handler[f](handler, options.passValue) flickerstreak@1: if neg then flickerstreak@1: hidden = not hidden flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if hidden then flickerstreak@1: disabled = true flickerstreak@1: elseif disabled then flickerstreak@1: if type(disabled) == "function" then flickerstreak@22: disabled = disabled(options.passValue) flickerstreak@1: elseif type(disabled) == "string" then flickerstreak@1: local f = disabled flickerstreak@1: local neg = f:match("^~(.-)$") flickerstreak@1: if neg then flickerstreak@1: f = neg flickerstreak@1: end flickerstreak@1: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@1: end flickerstreak@22: disabled = handler[f](handler, options.passValue) flickerstreak@1: if neg then flickerstreak@1: disabled = not disabled flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: local kind = (options.type or "group"):lower() flickerstreak@1: if disabled then flickerstreak@22: print(OPTION_IS_DISABLED:format(path), realOptions.cmdName or realOptions.name or self) flickerstreak@1: elseif kind == "text" then flickerstreak@1: local var flickerstreak@22: local multiToggle flickerstreak@22: for k in pairs(tmp) do flickerstreak@22: tmp[k] = nil flickerstreak@22: end flickerstreak@1: if passTable then flickerstreak@22: multiToggle = passTable.multiToggle flickerstreak@1: if not passTable.get then flickerstreak@1: elseif type(passTable.get) == "function" then flickerstreak@22: if not multiToggle then flickerstreak@22: var = passTable.get(passValue) flickerstreak@22: else flickerstreak@22: var = tmp flickerstreak@22: for k,v in pairs(options.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue == nil then flickerstreak@22: var[val] = passTable.get(val) or nil flickerstreak@22: else flickerstreak@22: var[val] = passTable.get(passValue, val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@1: else flickerstreak@1: local handler = passTable.handler or handler flickerstreak@1: if type(handler[passTable.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(passTable.get))) flickerstreak@1: end flickerstreak@1: var = handler[passTable.get](handler, passValue) flickerstreak@22: if not multiToggle then flickerstreak@22: var = handler[passTable.get](handler, passValue) flickerstreak@22: else flickerstreak@22: var = tmp flickerstreak@22: for k,v in pairs(options.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue == nil then flickerstreak@22: var[val] = handler[passTable.get](handler, val) or nil flickerstreak@22: else flickerstreak@22: var[val] = handler[passTable.get](handler, passValue, val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@1: end flickerstreak@1: else flickerstreak@22: multiToggle = options.multiToggle flickerstreak@1: if not options.get then flickerstreak@1: elseif type(options.get) == "function" then flickerstreak@22: if not multiToggle then flickerstreak@22: var = options.get(passValue) flickerstreak@22: else flickerstreak@22: var = tmp flickerstreak@22: for k,v in pairs(options.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue == nil then flickerstreak@22: var[val] = options.get(val) or nil flickerstreak@22: else flickerstreak@22: var[val] = options.get(passValue, val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@1: else flickerstreak@1: local handler = options.handler or handler flickerstreak@1: if type(handler[options.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options.get))) flickerstreak@1: end flickerstreak@22: if not multiToggle then flickerstreak@22: var = handler[options.get](handler, passValue) flickerstreak@22: else flickerstreak@22: var = tmp flickerstreak@22: for k,v in pairs(options.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue == nil then flickerstreak@22: var[val] = handler[options.get](handler, val) or nil flickerstreak@22: else flickerstreak@22: var[val] = handler[options.get](handler, passValue, val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: local usage flickerstreak@1: if type(options.validate) == "table" then flickerstreak@1: if filter then flickerstreak@1: if not order then flickerstreak@1: order = {} flickerstreak@1: end flickerstreak@1: for k,v in pairs(options.validate) do flickerstreak@1: if v:find(filter) then flickerstreak@1: table.insert(order, v) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: table.sort(order, icaseSort) flickerstreak@1: usage = "{" .. table.concat(order, " || ") .. "}" flickerstreak@1: for k in pairs(order) do flickerstreak@1: order[k] = nil flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if not order then flickerstreak@1: order = {} flickerstreak@1: end flickerstreak@1: for k,v in pairs(options.validate) do flickerstreak@1: table.insert(order, v) flickerstreak@1: end flickerstreak@22: table.sort(order, icaseSort) flickerstreak@1: usage = "{" .. table.concat(order, " || ") .. "}" flickerstreak@1: for k in pairs(order) do flickerstreak@1: order[k] = nil flickerstreak@1: end flickerstreak@1: end flickerstreak@22: if multiToggle then flickerstreak@22: if not next(var) then flickerstreak@22: var = NONE flickerstreak@22: else flickerstreak@22: if not order then flickerstreak@22: order = {} flickerstreak@22: end flickerstreak@22: for k in pairs(var) do flickerstreak@22: if options.validate[k] then flickerstreak@22: order[#order+1] = options.validate[k] flickerstreak@22: else flickerstreak@22: for _,v in pairs(options.validate) do flickerstreak@22: if v == k or (type(v) == "string" and type(k) == "string" and v:lower() == k:lower()) then flickerstreak@22: order[#order+1] = v flickerstreak@22: break flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: table.sort(order, icaseSort) flickerstreak@22: var = table.concat(order, ", ") flickerstreak@22: for k in pairs(order) do flickerstreak@22: order[k] = nil flickerstreak@22: end flickerstreak@22: end flickerstreak@22: else flickerstreak@22: var = options.validate[var] or var flickerstreak@22: end flickerstreak@1: elseif options.validate == "keybinding" then flickerstreak@1: usage = KEYBINDING_USAGE flickerstreak@1: else flickerstreak@1: usage = options.usage or "" flickerstreak@1: end flickerstreak@1: if not quiet then flickerstreak@22: print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, usage), realOptions.cmdName or realOptions.name or self) flickerstreak@1: end flickerstreak@1: if (passTable and passTable.get) or options.get then flickerstreak@22: print((options.current or IS_CURRENTLY_SET_TO):format(tostring(options.cmdName or options.name), tostring(var or NONE))) flickerstreak@1: end flickerstreak@1: elseif kind == "range" then flickerstreak@1: local var flickerstreak@1: if passTable then flickerstreak@1: if type(passTable.get) == "function" then flickerstreak@1: var = passTable.get(passValue) flickerstreak@1: else flickerstreak@1: local handler = passTable.handler or handler flickerstreak@1: if type(handler[passTable.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(passTable.get))) flickerstreak@1: end flickerstreak@1: var = handler[passTable.get](handler, passValue) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(options.get) == "function" then flickerstreak@22: var = options.get(passValue) flickerstreak@1: else flickerstreak@1: local handler = options.handler or handler flickerstreak@1: if type(handler[options.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options.get))) flickerstreak@1: end flickerstreak@22: var = handler[options.get](handler, passValue) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: local usage flickerstreak@1: local min = options.min or 0 flickerstreak@1: local max = options.max or 1 flickerstreak@1: if options.isPercent then flickerstreak@1: min, max = min * 100, max * 100 flickerstreak@1: var = tostring(var * 100) .. "%" flickerstreak@1: end flickerstreak@1: local bit = "-" flickerstreak@1: if min < 0 or max < 0 then flickerstreak@1: bit = " - " flickerstreak@1: end flickerstreak@22: usage = ("(%s%s%s)"):format(min, bit, max) flickerstreak@1: if not quiet then flickerstreak@22: print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, usage), realOptions.cmdName or realOptions.name or self) flickerstreak@1: end flickerstreak@22: print((options.current or IS_CURRENTLY_SET_TO):format(tostring(options.cmdName or options.name), tostring(var or NONE))) flickerstreak@1: elseif kind == "group" then flickerstreak@1: local usage flickerstreak@1: if next(options.args) then flickerstreak@1: if not order then flickerstreak@1: order = {} flickerstreak@1: end flickerstreak@1: for k,v in pairs(options.args) do flickerstreak@1: if v.type ~= "header" then flickerstreak@1: local hidden = v.cmdHidden or v.hidden flickerstreak@1: if hidden then flickerstreak@1: if type(hidden) == "function" then flickerstreak@1: hidden = hidden() flickerstreak@1: elseif type(hidden) == "string" then flickerstreak@1: local f = hidden flickerstreak@1: local neg = f:match("^~(.-)$") flickerstreak@1: if neg then flickerstreak@1: f = neg flickerstreak@1: end flickerstreak@1: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@1: end flickerstreak@1: hidden = handler[f](handler) flickerstreak@1: if neg then flickerstreak@1: hidden = not hidden flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if not hidden then flickerstreak@1: if filter then flickerstreak@1: if k:find(filter) then flickerstreak@1: table.insert(order, k) flickerstreak@1: elseif type(v.aliases) == "table" then flickerstreak@1: for _,bit in ipairs(v.aliases) do flickerstreak@1: if bit:find(filter) then flickerstreak@1: table.insert(order, k) flickerstreak@1: break flickerstreak@1: end flickerstreak@1: end flickerstreak@1: elseif type(v.aliases) == "string" then flickerstreak@1: if v.aliases:find(filter) then flickerstreak@1: table.insert(order, k) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: else flickerstreak@1: table.insert(order, k) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if not mysort then flickerstreak@1: mysort = function(a, b) flickerstreak@1: local alpha, bravo = mysort_args[a], mysort_args[b] flickerstreak@1: local alpha_order = alpha and alpha.order or 100 flickerstreak@1: local bravo_order = bravo and bravo.order or 100 flickerstreak@1: if alpha_order == bravo_order then flickerstreak@22: return tostring(a):lower() < tostring(b):lower() flickerstreak@1: else flickerstreak@1: if alpha_order < 0 then flickerstreak@1: if bravo_order > 0 then flickerstreak@1: return false flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if bravo_order < 0 then flickerstreak@1: return true flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if alpha_order > 0 and bravo_order > 0 then flickerstreak@22: return tostring(a):lower() < tostring(b):lower() flickerstreak@1: end flickerstreak@1: return alpha_order < bravo_order flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: mysort_args = options.args flickerstreak@1: table.sort(order, mysort) flickerstreak@1: mysort_args = nil flickerstreak@1: if not quiet then flickerstreak@1: if options == realOptions then flickerstreak@1: if options.desc then flickerstreak@1: print(tostring(options.desc), realOptions.cmdName or realOptions.name or self) flickerstreak@22: print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}")) flickerstreak@1: elseif self.description or self.notes then flickerstreak@1: print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self) flickerstreak@22: print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}")) flickerstreak@1: else flickerstreak@22: print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if options.desc then flickerstreak@22: print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self) flickerstreak@1: print(tostring(options.desc)) flickerstreak@1: else flickerstreak@22: print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@22: local passTable = options.pass and options or nil flickerstreak@1: for _,k in ipairs(order) do flickerstreak@22: local passValue = passTable and k or nil flickerstreak@22: local real_k = k flickerstreak@1: local v = options.args[k] flickerstreak@1: if v then flickerstreak@22: local v_p = passTable or v flickerstreak@22: if v.get and v.set then flickerstreak@22: v_p = v flickerstreak@22: passValue = nil flickerstreak@22: end flickerstreak@22: if v.passValue then flickerstreak@22: passValue = v.passValue flickerstreak@22: end flickerstreak@22: local k = tostring(k):gsub("%s", "-") flickerstreak@1: local disabled = v.disabled flickerstreak@1: if disabled then flickerstreak@1: if type(disabled) == "function" then flickerstreak@22: disabled = disabled(passValue) flickerstreak@1: elseif type(disabled) == "string" then flickerstreak@1: local f = disabled flickerstreak@1: local neg = f:match("^~(.-)$") flickerstreak@1: if neg then flickerstreak@1: f = neg flickerstreak@1: end flickerstreak@1: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@1: end flickerstreak@22: disabled = handler[f](handler, passValue) flickerstreak@1: if neg then flickerstreak@1: disabled = not disabled flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if type(v.aliases) == "table" then flickerstreak@22: for _,s in ipairs(v.aliases) do flickerstreak@22: k = k .. " || " .. s:gsub("%s", "-") flickerstreak@22: end flickerstreak@1: elseif type(v.aliases) == "string" then flickerstreak@22: k = k .. " || " .. v.aliases:gsub("%s", "-") flickerstreak@1: end flickerstreak@22: if v_p.get then flickerstreak@1: local a1,a2,a3,a4 flickerstreak@22: local multiToggle = v_p.type == "text" and v_p.multiToggle flickerstreak@22: for k in pairs(tmp) do flickerstreak@22: tmp[k] = nil flickerstreak@22: end flickerstreak@22: if type(v_p.get) == "function" then flickerstreak@22: if multiToggle then flickerstreak@22: a1 = tmp flickerstreak@22: for k,v in pairs(v.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue == nil then flickerstreak@22: a1[val] = v_p.get(val) or nil flickerstreak@22: else flickerstreak@22: a1[val] = v_p.get(passValue, val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@1: else flickerstreak@22: a1,a2,a3,a4 = v_p.get(passValue) flickerstreak@1: end flickerstreak@1: else flickerstreak@22: local handler = v_p.handler or handler flickerstreak@22: local f = v_p.get flickerstreak@1: local neg flickerstreak@1: if v.type == "toggle" then flickerstreak@1: neg = f:match("^~(.-)$") flickerstreak@1: if neg then flickerstreak@1: f = neg flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@1: end flickerstreak@22: if multiToggle then flickerstreak@22: a1 = tmp flickerstreak@22: for k,v in pairs(v.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue == nil then flickerstreak@22: a1[val] = handler[f](handler, val) or nil flickerstreak@22: else flickerstreak@22: a1[val] = handler[f](handler, passValue, val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@1: else flickerstreak@22: a1,a2,a3,a4 = handler[f](handler, passValue) flickerstreak@1: end flickerstreak@1: if neg then flickerstreak@1: a1 = not a1 flickerstreak@1: end flickerstreak@1: end flickerstreak@22: local s flickerstreak@1: if v.type == "color" then flickerstreak@1: if v.hasAlpha then flickerstreak@1: if not a1 or not a2 or not a3 or not a4 then flickerstreak@1: s = NONE flickerstreak@1: else flickerstreak@22: s = ("|c%02x%02x%02x%02x%02x%02x%02x%02x|r"):format(a4*255, a1*255, a2*255, a3*255, a4*255, a1*255, a2*255, a3*255) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if not a1 or not a2 or not a3 then flickerstreak@1: s = NONE flickerstreak@1: else flickerstreak@22: s = ("|cff%02x%02x%02x%02x%02x%02x|r"):format(a1*255, a2*255, a3*255, a1*255, a2*255, a3*255) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: elseif v.type == "toggle" then flickerstreak@1: if v.map then flickerstreak@1: s = tostring(v.map[a1 and true or false] or NONE) flickerstreak@1: else flickerstreak@1: s = tostring(MAP_ONOFF[a1 and true or false] or NONE) flickerstreak@1: end flickerstreak@1: elseif v.type == "range" then flickerstreak@1: if v.isPercent then flickerstreak@1: s = tostring(a1 * 100) .. "%" flickerstreak@1: else flickerstreak@1: s = tostring(a1) flickerstreak@1: end flickerstreak@1: elseif v.type == "text" and type(v.validate) == "table" then flickerstreak@22: if multiToggle then flickerstreak@22: if not next(a1) then flickerstreak@22: s = NONE flickerstreak@22: else flickerstreak@22: s = '' flickerstreak@22: for k in pairs(a1) do flickerstreak@22: if v.validate[k] then flickerstreak@22: if s == '' then flickerstreak@22: s = v.validate[k] flickerstreak@22: else flickerstreak@22: s = s .. ', ' .. v.validate[k] flickerstreak@22: end flickerstreak@22: else flickerstreak@22: for _,u in pairs(v.validate) do flickerstreak@22: if u == k or (type(v) == "string" and type(k) == "string" and v:lower() == k:lower()) then flickerstreak@22: if s == '' then flickerstreak@22: s = u flickerstreak@22: else flickerstreak@22: s = s .. ', ' .. u flickerstreak@22: end flickerstreak@22: break flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: else flickerstreak@22: s = tostring(v.validate[a1] or a1 or NONE) flickerstreak@22: end flickerstreak@1: else flickerstreak@1: s = tostring(a1 or NONE) flickerstreak@1: end flickerstreak@1: if disabled then flickerstreak@1: local s = s:gsub("|cff%x%x%x%x%x%x(.-)|r", "%1") flickerstreak@1: local desc = (v.desc or NONE):gsub("|cff%x%x%x%x%x%x(.-)|r", "%1") flickerstreak@22: print(("|cffcfcfcf - %s: [%s] %s|r"):format(k, s, desc)) flickerstreak@1: else flickerstreak@22: print((" - |cffffff7f%s: [|r%s|cffffff7f]|r %s"):format(k, s, v.desc or NONE)) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if disabled then flickerstreak@1: local desc = (v.desc or NONE):gsub("|cff%x%x%x%x%x%x(.-)|r", "%1") flickerstreak@22: print(("|cffcfcfcf - %s: %s"):format(k, desc)) flickerstreak@1: else flickerstreak@22: print((" - |cffffff7f%s:|r %s"):format(k, v.desc or NONE)) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: for k in pairs(order) do flickerstreak@1: order[k] = nil flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if options.desc then flickerstreak@22: print(("|cffffff7f%s:|r %s"):format(USAGE, path), realOptions.cmdName or realOptions.name or self) flickerstreak@1: print(tostring(options.desc)) flickerstreak@1: elseif options == realOptions and (self.description or self.notes) then flickerstreak@1: print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self) flickerstreak@22: print(("|cffffff7f%s:|r %s"):format(USAGE, path)) flickerstreak@1: else flickerstreak@22: print(("|cffffff7f%s:|r %s"):format(USAGE, path), realOptions.cmdName or realOptions.name or self) flickerstreak@1: end flickerstreak@1: print(NO_OPTIONS_AVAILABLE) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@22: local function confirmPopup(message, func, ...) flickerstreak@22: if not StaticPopupDialogs["ACECONSOLE20_CONFIRM_DIALOG"] then flickerstreak@22: StaticPopupDialogs["ACECONSOLE20_CONFIRM_DIALOG"] = {} flickerstreak@22: end flickerstreak@22: local t = StaticPopupDialogs["ACECONSOLE20_CONFIRM_DIALOG"] flickerstreak@22: for k in pairs(t) do flickerstreak@22: t[k] = nil flickerstreak@22: end flickerstreak@22: t.text = message flickerstreak@22: t.button1 = ACCEPT or "Accept" flickerstreak@22: t.button2 = CANCEL or "Cancel" flickerstreak@22: t.OnAccept = function() flickerstreak@22: func(unpack(t)) flickerstreak@22: end flickerstreak@22: for i = 1, select('#', ...) do flickerstreak@22: t[i] = select(i, ...) flickerstreak@22: end flickerstreak@22: t.timeout = 0 flickerstreak@22: t.whileDead = 1 flickerstreak@22: t.hideOnEscape = 1 flickerstreak@22: flickerstreak@22: StaticPopup_Show("ACECONSOLE20_CONFIRM_DIALOG") flickerstreak@22: end flickerstreak@22: flickerstreak@1: local function handlerFunc(self, chat, msg, options) flickerstreak@1: if not msg then flickerstreak@1: msg = "" flickerstreak@1: else flickerstreak@1: msg = msg:gsub("^%s*(.-)%s*$", "%1") flickerstreak@1: msg = msg:gsub("%s+", " ") flickerstreak@1: end flickerstreak@22: flickerstreak@1: local realOptions = options flickerstreak@1: local options, path, args, handler, passTable, passValue = findTableLevel(self, options, chat, msg) flickerstreak@22: if options.type == "execute" then flickerstreak@22: if options.func then flickerstreak@22: passTable = nil flickerstreak@22: end flickerstreak@22: else flickerstreak@22: if options.get and options.set then flickerstreak@22: passTable = nil flickerstreak@22: end flickerstreak@22: end flickerstreak@22: passValue = options.passValue or passTable and passValue flickerstreak@22: flickerstreak@1: local hidden, disabled = options.cmdHidden or options.hidden, options.disabled flickerstreak@1: if hidden then flickerstreak@1: if type(hidden) == "function" then flickerstreak@22: hidden = hidden(passValue) flickerstreak@1: elseif type(hidden) == "string" then flickerstreak@1: local f = hidden flickerstreak@1: local neg = f:match("^~(.-)$") flickerstreak@1: if neg then flickerstreak@1: f = neg flickerstreak@1: end flickerstreak@1: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@1: end flickerstreak@22: hidden = handler[f](handler, passValue) flickerstreak@1: if neg then flickerstreak@1: hidden = not hidden flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if hidden then flickerstreak@1: disabled = true flickerstreak@1: elseif disabled then flickerstreak@1: if type(disabled) == "function" then flickerstreak@22: disabled = disabled(passValue) flickerstreak@1: elseif type(disabled) == "string" then flickerstreak@1: local f = disabled flickerstreak@1: local neg = f:match("^~(.-)$") flickerstreak@1: if neg then flickerstreak@1: f = neg flickerstreak@1: end flickerstreak@1: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@1: end flickerstreak@22: disabled = handler[f](handler, passValue) flickerstreak@1: if neg then flickerstreak@1: disabled = not disabled flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: local _G_this = this flickerstreak@1: local kind = (options.type or "group"):lower() flickerstreak@22: local options_p = passTable or options flickerstreak@1: if disabled then flickerstreak@22: print(OPTION_IS_DISABLED:format(path), realOptions.cmdName or realOptions.name or self) flickerstreak@1: elseif kind == "text" then flickerstreak@1: if #args > 0 then flickerstreak@1: if (type(options.validate) == "table" and #args > 1) or (type(options.validate) ~= "table" and not options.input) then flickerstreak@1: local arg = table.concat(args, " ") flickerstreak@1: for k,v in pairs(args) do flickerstreak@1: args[k] = nil flickerstreak@1: end flickerstreak@1: args[1] = arg flickerstreak@1: end flickerstreak@1: if options.validate then flickerstreak@1: local good flickerstreak@1: if type(options.validate) == "function" then flickerstreak@1: good = options.validate(unpack(args)) flickerstreak@1: elseif type(options.validate) == "table" then flickerstreak@1: local arg = args[1] flickerstreak@1: arg = tostring(arg):lower() flickerstreak@1: for k,v in pairs(options.validate) do flickerstreak@1: if v:lower() == arg then flickerstreak@1: args[1] = type(k) == "string" and k or v flickerstreak@1: good = true flickerstreak@1: break flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if not good and type((next(options.validate))) == "string" then flickerstreak@1: for k,v in pairs(options.validate) do flickerstreak@1: if type(k) == "string" and k:lower() == arg then flickerstreak@1: args[1] = k flickerstreak@1: good = true flickerstreak@1: break flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: elseif options.validate == "keybinding" then flickerstreak@1: good = keybindingValidateFunc(unpack(args)) flickerstreak@1: if good ~= false then flickerstreak@1: args[1] = good flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(handler[options.validate]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options.validate))) flickerstreak@1: end flickerstreak@1: good = handler[options.validate](handler, unpack(args)) flickerstreak@1: end flickerstreak@1: if not good then flickerstreak@1: local usage flickerstreak@1: if type(options.validate) == "table" then flickerstreak@1: if not order then flickerstreak@1: order = {} flickerstreak@1: end flickerstreak@1: for k,v in pairs(options.validate) do flickerstreak@1: table.insert(order, v) flickerstreak@1: end flickerstreak@1: usage = "{" .. table.concat(order, " || ") .. "}" flickerstreak@1: for k in pairs(order) do flickerstreak@1: order[k] = nil flickerstreak@1: end flickerstreak@1: elseif options.validate == "keybinding" then flickerstreak@1: usage = KEYBINDING_USAGE flickerstreak@1: else flickerstreak@1: usage = options.usage or "" flickerstreak@1: end flickerstreak@22: print((options.error or IS_NOT_A_VALID_OPTION_FOR):format(tostring(table.concat(args, " ")), path), realOptions.cmdName or realOptions.name or self) flickerstreak@22: print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, usage)) flickerstreak@1: return flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: local var flickerstreak@22: local multiToggle flickerstreak@22: for k in pairs(tmp) do flickerstreak@22: tmp[k] = nil flickerstreak@22: end flickerstreak@22: multiToggle = options_p.multiToggle flickerstreak@22: if not options_p.get then flickerstreak@22: elseif type(options_p.get) == "function" then flickerstreak@22: if multiToggle then flickerstreak@22: var = tmp flickerstreak@22: for k,v in pairs(options.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue then flickerstreak@22: var[val] = options_p.get(passValue, val) or nil flickerstreak@22: else flickerstreak@22: var[val] = options_p.get(val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@1: else flickerstreak@22: var = options_p.get(passValue) flickerstreak@1: end flickerstreak@1: else flickerstreak@22: if type(handler[options_p.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get))) flickerstreak@22: end flickerstreak@22: if multiToggle then flickerstreak@22: var = tmp flickerstreak@22: for k,v in pairs(options.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue then flickerstreak@22: var[val] = handler[options_p.get](handler, passValue, val) or nil flickerstreak@22: else flickerstreak@22: var[val] = handler[options_p.get](handler, val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@1: else flickerstreak@22: var = handler[options_p.get](handler, passValue) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@22: if multiToggle or var ~= args[1] then flickerstreak@22: if multiToggle then flickerstreak@22: local current = var[args[1]] flickerstreak@22: if current == nil and type(args[1]) == "string" then flickerstreak@22: for k in pairs(var) do flickerstreak@22: if type(k) == "string" and k:lower() == args[1]:lower() then flickerstreak@22: current = true flickerstreak@22: break flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: args[2] = not current flickerstreak@22: end flickerstreak@22: if type(options_p.set) == "function" then flickerstreak@22: if passValue then flickerstreak@22: options_p.set(passValue, unpack(args)) flickerstreak@1: else flickerstreak@22: options_p.set(unpack(args)) flickerstreak@1: end flickerstreak@1: else flickerstreak@22: if type(handler[options_p.set]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.set))) flickerstreak@22: end flickerstreak@22: if passValue then flickerstreak@22: handler[options_p.set](handler, passValue, unpack(args)) flickerstreak@1: else flickerstreak@22: handler[options_p.set](handler, unpack(args)) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: if #args > 0 then flickerstreak@1: local var flickerstreak@22: local multiToggle flickerstreak@22: for k in pairs(tmp) do flickerstreak@22: tmp[k] = nil flickerstreak@22: end flickerstreak@22: multiToggle = options_p.multiToggle flickerstreak@22: if not options_p.get then flickerstreak@22: elseif type(options_p.get) == "function" then flickerstreak@22: if multiToggle then flickerstreak@22: var = tmp flickerstreak@22: for k,v in pairs(options_p.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue then flickerstreak@22: var[val] = options_p.get(passValue, val) or nil flickerstreak@22: else flickerstreak@22: var[val] = options_p.get(val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@1: else flickerstreak@22: var = options_p.get(passValue) flickerstreak@1: end flickerstreak@1: else flickerstreak@22: if type(handler[options_p.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get))) flickerstreak@22: end flickerstreak@22: if multiToggle then flickerstreak@22: var = tmp flickerstreak@22: for k,v in pairs(options.validate) do flickerstreak@22: local val = type(k) ~= "number" and k or v flickerstreak@22: if passValue then flickerstreak@22: var[val] = handler[options_p.get](handler, passValue, val) or nil flickerstreak@22: else flickerstreak@22: var[val] = handler[options_p.get](handler, val) or nil flickerstreak@22: end flickerstreak@22: end flickerstreak@1: else flickerstreak@22: var = handler[options_p.get](handler, passValue) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: if multiToggle then flickerstreak@22: if not next(var) then flickerstreak@22: var = NONE flickerstreak@22: else flickerstreak@22: if not order then flickerstreak@22: order = {} flickerstreak@22: end flickerstreak@22: for k in pairs(var) do flickerstreak@22: if options.validate[k] then flickerstreak@22: order[#order+1] = options.validate[k] flickerstreak@22: else flickerstreak@22: for _,v in pairs(options.validate) do flickerstreak@22: if v == k or (type(v) == "string" and type(k) == "string" and v:lower() == k:lower()) then flickerstreak@22: order[#order+1] = v flickerstreak@22: break flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: table.sort(order, icaseSort) flickerstreak@22: var = table.concat(order, ", ") flickerstreak@22: for k in pairs(order) do flickerstreak@22: order[k] = nil flickerstreak@22: end flickerstreak@22: end flickerstreak@22: elseif type(options.validate) == "table" then flickerstreak@1: var = options.validate[var] or var flickerstreak@1: end flickerstreak@22: if options_p.get then flickerstreak@22: print((options.message or IS_NOW_SET_TO):format(tostring(options.cmdName or options.name), tostring(var or NONE)), realOptions.cmdName or realOptions.name or self) flickerstreak@1: end flickerstreak@1: if var == args[1] then flickerstreak@1: return flickerstreak@1: end flickerstreak@1: else flickerstreak@22: printUsage(self, handler, realOptions, options, path, args, passValue) flickerstreak@1: return flickerstreak@1: end flickerstreak@1: elseif kind == "execute" then flickerstreak@22: local confirm = options.confirm flickerstreak@22: if confirm == true then flickerstreak@22: confirm = DEFAULT_CONFIRM_MESSAGE:format(options.desc or options.name or UNKNOWN or "Unknown") flickerstreak@22: end flickerstreak@22: if type(options_p.func) == "function" then flickerstreak@22: if confirm then flickerstreak@22: confirmPopup(confirm, options_p.func, passValue) flickerstreak@1: else flickerstreak@22: options_p.func(passValue) flickerstreak@1: end flickerstreak@1: else flickerstreak@22: if type(handler[options_p.func]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.func))) flickerstreak@22: end flickerstreak@22: if confirm then flickerstreak@22: confirmPopup(confirm, handler[options_p.func], handler, passValue) flickerstreak@1: else flickerstreak@22: handler[options_p.func](handler, passValue) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: elseif kind == "toggle" then flickerstreak@1: local var flickerstreak@22: if type(options_p.get) == "function" then flickerstreak@22: var = options_p.get(passValue) flickerstreak@22: else flickerstreak@22: local f = options_p.get flickerstreak@22: local neg = f:match("^~(.-)$") flickerstreak@22: if neg then flickerstreak@22: f = neg flickerstreak@22: end flickerstreak@22: if type(handler[f]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@22: end flickerstreak@22: var = handler[f](handler, passValue) flickerstreak@22: if neg then flickerstreak@22: var = not var flickerstreak@22: end flickerstreak@22: end flickerstreak@22: if type(options_p.set) == "function" then flickerstreak@22: if passValue then flickerstreak@22: options_p.set(passValue, not var) flickerstreak@1: else flickerstreak@22: options_p.set(not var) flickerstreak@1: end flickerstreak@1: else flickerstreak@22: if type(handler[options_p.set]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.set))) flickerstreak@22: end flickerstreak@22: if passValue then flickerstreak@22: handler[options_p.set](handler, passValue, not var) flickerstreak@1: else flickerstreak@22: handler[options_p.set](handler, not var) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: if type(options_p.get) == "function" then flickerstreak@22: var = options_p.get(passValue) flickerstreak@22: else flickerstreak@22: local f = options_p.get flickerstreak@22: local neg = f:match("^~(.-)$") flickerstreak@22: if neg then flickerstreak@22: f = neg flickerstreak@22: end flickerstreak@22: var = handler[f](handler, passValue) flickerstreak@22: if neg then flickerstreak@22: var = not var flickerstreak@22: end flickerstreak@22: end flickerstreak@22: flickerstreak@22: print((options.message or IS_NOW_SET_TO):format(tostring(options.cmdName or options.name), (options.map or MAP_ONOFF)[var and true or false] or NONE), realOptions.cmdName or realOptions.name or self) flickerstreak@1: elseif kind == "range" then flickerstreak@1: local arg flickerstreak@1: if #args <= 1 then flickerstreak@1: arg = args[1] flickerstreak@1: else flickerstreak@1: arg = table.concat(args, " ") flickerstreak@1: end flickerstreak@1: flickerstreak@1: if arg then flickerstreak@1: local min = options.min or 0 flickerstreak@1: local max = options.max or 1 flickerstreak@1: local good = false flickerstreak@1: if type(arg) == "number" then flickerstreak@1: if options.isPercent then flickerstreak@1: arg = arg / 100 flickerstreak@1: end flickerstreak@1: flickerstreak@1: if arg >= min and arg <= max then flickerstreak@1: good = true flickerstreak@1: end flickerstreak@22: flickerstreak@1: if good and type(options.step) == "number" and options.step > 0 then flickerstreak@1: local step = options.step flickerstreak@1: arg = math.floor((arg - min) / step + 0.5) * step + min flickerstreak@1: if arg > max then flickerstreak@1: arg = max flickerstreak@1: elseif arg < min then flickerstreak@1: arg = min flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if not good then flickerstreak@1: local usage flickerstreak@1: local min = options.min or 0 flickerstreak@1: local max = options.max or 1 flickerstreak@1: if options.isPercent then flickerstreak@1: min, max = min * 100, max * 100 flickerstreak@1: end flickerstreak@1: local bit = "-" flickerstreak@1: if min < 0 or max < 0 then flickerstreak@1: bit = " - " flickerstreak@1: end flickerstreak@22: usage = ("(%s%s%s)"):format(min, bit, max) flickerstreak@22: print((options.error or IS_NOT_A_VALID_VALUE_FOR):format(tostring(arg), path), realOptions.cmdName or realOptions.name or self) flickerstreak@22: print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, usage)) flickerstreak@1: return flickerstreak@1: end flickerstreak@22: flickerstreak@1: local var flickerstreak@22: if type(options_p.get) == "function" then flickerstreak@22: var = options_p.get(passValue) flickerstreak@22: else flickerstreak@22: if type(handler[options_p.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get))) flickerstreak@1: end flickerstreak@22: var = handler[options_p.get](handler, passValue) flickerstreak@1: end flickerstreak@22: flickerstreak@1: if var ~= arg then flickerstreak@22: if type(options_p.set) == "function" then flickerstreak@22: if passValue then flickerstreak@22: options_p.set(passValue, arg) flickerstreak@1: else flickerstreak@22: options_p.set(arg) flickerstreak@1: end flickerstreak@1: else flickerstreak@22: if type(handler[options_p.set]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.set))) flickerstreak@22: end flickerstreak@22: if passValue then flickerstreak@22: handler[options_p.set](handler, passValue, arg) flickerstreak@1: else flickerstreak@22: handler[options_p.set](handler, arg) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: if arg then flickerstreak@1: local var flickerstreak@22: if type(options_p.get) == "function" then flickerstreak@22: var = options_p.get(passValue) flickerstreak@22: else flickerstreak@22: if type(handler[options_p.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get))) flickerstreak@1: end flickerstreak@22: var = handler[options_p.get](handler, passValue) flickerstreak@1: end flickerstreak@22: flickerstreak@1: if var and options.isPercent then flickerstreak@1: var = tostring(var * 100) .. "%" flickerstreak@1: end flickerstreak@22: print((options.message or IS_NOW_SET_TO):format(tostring(options.cmdName or options.name), tostring(var or NONE)), realOptions.cmdName or realOptions.name or self) flickerstreak@1: if var == arg then flickerstreak@1: return flickerstreak@1: end flickerstreak@1: else flickerstreak@22: printUsage(self, handler, realOptions, options, path, args, passValue) flickerstreak@1: return flickerstreak@1: end flickerstreak@1: elseif kind == "color" then flickerstreak@1: if #args > 0 then flickerstreak@1: local r,g,b,a flickerstreak@1: if #args == 1 then flickerstreak@1: local arg = tostring(args[1]) flickerstreak@1: if options.hasAlpha then flickerstreak@1: if arg:len() == 8 and arg:find("^%x*$") then flickerstreak@1: r,g,b,a = tonumber(arg:sub(1, 2), 16) / 255, tonumber(arg:sub(3, 4), 16) / 255, tonumber(arg:sub(5, 6), 16) / 255, tonumber(arg:sub(7, 8), 16) / 255 flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if arg:len() == 6 and arg:find("^%x*$") then flickerstreak@1: r,g,b = tonumber(arg:sub(1, 2), 16) / 255, tonumber(arg:sub(3, 4), 16) / 255, tonumber(arg:sub(5, 6), 16) / 255 flickerstreak@1: end flickerstreak@1: end flickerstreak@1: elseif #args == 4 and options.hasAlpha then flickerstreak@1: local a1,a2,a3,a4 = args[1], args[2], args[3], args[4] flickerstreak@1: if type(a1) == "number" and type(a2) == "number" and type(a3) == "number" and type(a4) == "number" and a1 <= 1 and a2 <= 1 and a3 <= 1 and a4 <= 1 then flickerstreak@1: r,g,b,a = a1,a2,a3,a4 flickerstreak@1: elseif (type(a1) == "number" or a1:len() == 2) and a1:find("^%x*$") and (type(a2) == "number" or a2:len() == 2) and a2:find("^%x*$") and (type(a3) == "number" or a3:len() == 2) and a3:find("^%x*$") and (type(a4) == "number" or a4:len() == 2) and a4:find("^%x*$") then flickerstreak@1: r,g,b,a = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255, tonumber(a4, 16) / 255 flickerstreak@1: end flickerstreak@1: elseif #args == 3 and not options.hasAlpha then flickerstreak@1: local a1,a2,a3 = args[1], args[2], args[3] flickerstreak@1: if type(a1) == "number" and type(a2) == "number" and type(a3) == "number" and a1 <= 1 and a2 <= 1 and a3 <= 1 then flickerstreak@1: r,g,b = a1,a2,a3 flickerstreak@1: elseif (type(a1) == "number" or a1:len() == 2) and a1:find("^%x*$") and (type(a2) == "number" or a2:len() == 2) and a2:find("^%x*$") and (type(a3) == "number" or a3:len() == 2) and a3:find("^%x*$") then flickerstreak@1: r,g,b = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255 flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if not r then flickerstreak@22: print((options.error or IS_NOT_A_VALID_OPTION_FOR):format(table.concat(args, ' '), path), realOptions.cmdName or realOptions.name or self) flickerstreak@22: print(("|cffffff7f%s:|r %s {0-1} {0-1} {0-1}%s"):format(USAGE, path, options.hasAlpha and " {0-1}" or "")) flickerstreak@1: return flickerstreak@1: end flickerstreak@22: flickerstreak@22: if type(options_p.set) == "function" then flickerstreak@22: if passValue then flickerstreak@22: options_p.set(passValue, r,g,b,a) flickerstreak@1: else flickerstreak@22: options_p.set(r,g,b,a) flickerstreak@1: end flickerstreak@1: else flickerstreak@22: if type(handler[options_p.set]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.set))) flickerstreak@22: end flickerstreak@22: if passValue then flickerstreak@22: handler[options_p.set](handler, passValue, r,g,b,a) flickerstreak@1: else flickerstreak@22: handler[options_p.set](handler, r,g,b,a) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: local r,g,b,a flickerstreak@22: if type(options_p.get) == "function" then flickerstreak@22: r,g,b,a = options_p.get(passValue) flickerstreak@22: else flickerstreak@22: if type(handler[options_p.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get))) flickerstreak@1: end flickerstreak@22: r,g,b,a = handler[options_p.get](handler, passValue) flickerstreak@1: end flickerstreak@22: flickerstreak@1: local s flickerstreak@1: if type(r) == "number" and type(g) == "number" and type(b) == "number" then flickerstreak@1: if options.hasAlpha and type(a) == "number" then flickerstreak@22: s = ("|c%02x%02x%02x%02x%02x%02x%02x%02x|r"):format(a*255, r*255, g*255, b*255, r*255, g*255, b*255, a*255) flickerstreak@1: else flickerstreak@22: s = ("|cff%02x%02x%02x%02x%02x%02x|r"):format(r*255, g*255, b*255, r*255, g*255, b*255) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: s = NONE flickerstreak@1: end flickerstreak@22: print((options.message or IS_NOW_SET_TO):format(tostring(options.cmdName or options.name), s), realOptions.cmdName or realOptions.name or self) flickerstreak@1: else flickerstreak@1: local r,g,b,a flickerstreak@22: if type(options_p.get) == "function" then flickerstreak@22: r,g,b,a = options_p.get(passValue) flickerstreak@22: else flickerstreak@22: if type(handler[options_p.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get))) flickerstreak@1: end flickerstreak@22: r,g,b,a = handler[options_p.get](handler, passValue) flickerstreak@1: end flickerstreak@22: flickerstreak@1: if not colorTable then flickerstreak@1: colorTable = {} flickerstreak@1: local t = colorTable flickerstreak@22: flickerstreak@1: if ColorPickerOkayButton then flickerstreak@1: local ColorPickerOkayButton_OnClick = ColorPickerOkayButton:GetScript("OnClick") flickerstreak@1: ColorPickerOkayButton:SetScript("OnClick", function() flickerstreak@1: if ColorPickerOkayButton_OnClick then flickerstreak@1: ColorPickerOkayButton_OnClick() flickerstreak@1: end flickerstreak@1: if t.active then flickerstreak@1: ColorPickerFrame.cancelFunc = nil flickerstreak@1: ColorPickerFrame.func = nil flickerstreak@1: ColorPickerFrame.opacityFunc = nil flickerstreak@1: local r,g,b,a flickerstreak@1: if t.passValue then flickerstreak@1: if type(t.get) == "function" then flickerstreak@1: r,g,b,a = t.get(t.passValue) flickerstreak@1: else flickerstreak@1: if type(t.handler[t.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.get))) flickerstreak@1: end flickerstreak@1: r,g,b,a = t.handler[t.get](t.handler, t.passValue) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(t.get) == "function" then flickerstreak@1: r,g,b,a = t.get() flickerstreak@1: else flickerstreak@1: if type(t.handler[t.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.get))) flickerstreak@1: end flickerstreak@1: r,g,b,a = t.handler[t.get](t.handler) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if r ~= t.r or g ~= t.g or b ~= t.b or (t.hasAlpha and a ~= t.a) then flickerstreak@1: local s flickerstreak@1: if type(r) == "number" and type(g) == "number" and type(b) == "number" then flickerstreak@1: if t.hasAlpha and type(a) == "number" then flickerstreak@22: s = ("|c%02x%02x%02x%02x%02x%02x%02x%02x|r"):format(a*255, r*255, g*255, b*255, r*255, g*255, b*255, a*255) flickerstreak@1: else flickerstreak@22: s = ("|cff%02x%02x%02x%02x%02x%02x|r"):format(r*255, g*255, b*255, r*255, g*255, b*255) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: s = NONE flickerstreak@1: end flickerstreak@22: print(t.message:format(tostring(t.name), s), t.realOptions.cmdName or t.realOptions.name or self) flickerstreak@1: end flickerstreak@1: for k,v in pairs(t) do flickerstreak@1: t[k] = nil flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: for k,v in pairs(colorTable) do flickerstreak@1: colorTable[k] = nil flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: if type(r) ~= "number" or type(g) ~= "number" or type(b) ~= "number" then flickerstreak@1: r,g,b = 1, 1, 1 flickerstreak@1: end flickerstreak@1: if type(a) ~= "number" then flickerstreak@1: a = 1 flickerstreak@1: end flickerstreak@1: local t = colorTable flickerstreak@1: t.r = r flickerstreak@1: t.g = g flickerstreak@1: t.b = b flickerstreak@1: if hasAlpha then flickerstreak@1: t.a = a flickerstreak@1: end flickerstreak@1: t.realOptions = realOptions flickerstreak@1: t.hasAlpha = options.hasAlpha flickerstreak@1: t.handler = handler flickerstreak@22: t.set = options_p.set flickerstreak@22: t.get = options_p.get flickerstreak@1: t.name = options.cmdName or options.name flickerstreak@1: t.message = options.message or IS_NOW_SET_TO flickerstreak@1: t.passValue = passValue flickerstreak@1: t.active = true flickerstreak@22: flickerstreak@1: if not colorFunc then flickerstreak@1: colorFunc = function() flickerstreak@1: local r,g,b = ColorPickerFrame:GetColorRGB() flickerstreak@1: if t.hasAlpha then flickerstreak@1: local a = 1 - OpacitySliderFrame:GetValue() flickerstreak@1: if type(t.set) == "function" then flickerstreak@1: if t.passValue then flickerstreak@1: t.set(t.passValue, r,g,b,a) flickerstreak@1: else flickerstreak@1: t.set(r,g,b,a) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(t.handler[t.set]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.set))) flickerstreak@1: end flickerstreak@1: if t.passValue then flickerstreak@1: t.handler[t.set](t.handler, t.passValue, r,g,b,a) flickerstreak@1: else flickerstreak@1: t.handler[t.set](t.handler, r,g,b,a) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(t.set) == "function" then flickerstreak@1: if t.passValue then flickerstreak@1: t.set(t.passValue, r,g,b) flickerstreak@1: else flickerstreak@1: t.set(r,g,b) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(t.handler[t.set]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.set))) flickerstreak@1: end flickerstreak@1: if t.passValue then flickerstreak@1: t.handler[t.set](t.handler, t.passValue, r,g,b) flickerstreak@1: else flickerstreak@1: t.handler[t.set](t.handler, r,g,b) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: ColorPickerFrame.func = colorFunc flickerstreak@1: ColorPickerFrame.hasOpacity = options.hasAlpha flickerstreak@1: if options.hasAlpha then flickerstreak@1: ColorPickerFrame.opacityFunc = ColorPickerFrame.func flickerstreak@1: ColorPickerFrame.opacity = 1 - a flickerstreak@1: end flickerstreak@1: ColorPickerFrame:SetColorRGB(r,g,b) flickerstreak@22: flickerstreak@1: if not colorCancelFunc then flickerstreak@1: colorCancelFunc = function() flickerstreak@1: if t.hasAlpha then flickerstreak@1: if type(t.set) == "function" then flickerstreak@1: if t.passValue then flickerstreak@1: t.set(t.passValue, t.r,t.g,t.b,t.a) flickerstreak@1: else flickerstreak@1: t.set(t.r,t.g,t.b,t.a) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(t.handler[t.get]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.get))) flickerstreak@1: end flickerstreak@1: if t.passValue then flickerstreak@1: t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b,t.a) flickerstreak@1: else flickerstreak@1: t.handler[t.set](t.handler, t.r,t.g,t.b,t.a) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(t.set) == "function" then flickerstreak@1: if t.passValue then flickerstreak@1: t.set(t.passValue, t.r,t.g,t.b) flickerstreak@1: else flickerstreak@1: t.set(t.r,t.g,t.b) flickerstreak@1: end flickerstreak@1: else flickerstreak@1: if type(t.handler[t.set]) ~= "function" then flickerstreak@22: AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.set))) flickerstreak@1: end flickerstreak@1: if t.passValue then flickerstreak@1: t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b) flickerstreak@1: else flickerstreak@1: t.handler[t.set](t.handler, t.r,t.g,t.b) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: for k,v in pairs(t) do flickerstreak@1: t[k] = nil flickerstreak@1: end flickerstreak@1: ColorPickerFrame.cancelFunc = nil flickerstreak@1: ColorPickerFrame.func = nil flickerstreak@1: ColorPickerFrame.opacityFunc = nil flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: ColorPickerFrame.cancelFunc = colorCancelFunc flickerstreak@22: flickerstreak@1: ShowUIPanel(ColorPickerFrame) flickerstreak@1: end flickerstreak@1: return flickerstreak@1: elseif kind == "group" then flickerstreak@1: if #args == 0 then flickerstreak@22: printUsage(self, handler, realOptions, options, path, args, passValue) flickerstreak@1: else flickerstreak@1: -- invalid argument flickerstreak@22: print((options.error or IS_NOT_A_VALID_OPTION_FOR):format(args[1], path), realOptions.cmdName or realOptions.name or self) flickerstreak@1: end flickerstreak@1: return flickerstreak@1: end flickerstreak@1: this = _G_this flickerstreak@1: if Dewdrop then flickerstreak@22: Dewdrop:Refresh() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: local external flickerstreak@22: local tmp flickerstreak@22: function AceConsole:RegisterChatCommand(...) -- slashCommands, options, name flickerstreak@22: local slashCommands, options, name flickerstreak@22: if type((...)) == "string" then flickerstreak@22: if not tmp then flickerstreak@22: tmp = {} flickerstreak@22: else flickerstreak@22: for i in ipairs(tmp) do flickerstreak@22: tmp[i] = nil flickerstreak@22: end flickerstreak@22: end flickerstreak@22: for i = 1, select('#', ...)+1 do flickerstreak@22: local v = select(i, ...) flickerstreak@22: if type(v) == "string" then flickerstreak@22: tmp[#tmp+1] = v flickerstreak@22: else flickerstreak@22: slashCommands = tmp flickerstreak@22: options = v flickerstreak@22: name = select(i+1, ...) flickerstreak@22: break flickerstreak@22: end flickerstreak@22: end flickerstreak@22: else flickerstreak@22: slashCommands, options, name = ... flickerstreak@22: end flickerstreak@1: if type(slashCommands) ~= "table" and slashCommands ~= false then flickerstreak@1: AceConsole:error("Bad argument #2 to `RegisterChatCommand' (expected table, got %s)", type(slashCommands)) flickerstreak@1: end flickerstreak@1: if not slashCommands and type(name) ~= "string" then flickerstreak@1: AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string, got %s)", type(name)) flickerstreak@1: end flickerstreak@1: if type(options) ~= "table" and type(options) ~= "function" and options ~= nil then flickerstreak@1: AceConsole:error("Bad argument #3 to `RegisterChatCommand' (expected table, function, or nil, got %s)", type(options)) flickerstreak@1: end flickerstreak@1: if name then flickerstreak@1: if type(name) ~= "string" then flickerstreak@1: AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string or nil, got %s)", type(name)) flickerstreak@1: elseif not name:find("^%w+$") or name:upper() ~= name or name:len() == 0 then flickerstreak@1: AceConsole:error("Argument #4 must be an uppercase, letters-only string with at least 1 character") flickerstreak@1: end flickerstreak@1: end flickerstreak@1: if slashCommands then flickerstreak@1: if #slashCommands == 0 then flickerstreak@1: AceConsole:error("Argument #2 to `RegisterChatCommand' must include at least one string") flickerstreak@1: end flickerstreak@22: flickerstreak@1: for k,v in pairs(slashCommands) do flickerstreak@1: if type(k) ~= "number" then flickerstreak@1: AceConsole:error("All keys in argument #2 to `RegisterChatCommand' must be numbers") flickerstreak@1: end flickerstreak@1: if type(v) ~= "string" then flickerstreak@1: AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be strings") flickerstreak@1: elseif not v:find("^/[A-Za-z][A-Za-z0-9_]*$") then flickerstreak@1: AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be in the form of \"/word\"") flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: if not options then flickerstreak@1: options = { flickerstreak@1: type = 'group', flickerstreak@1: args = {}, flickerstreak@1: handler = self flickerstreak@1: } flickerstreak@1: end flickerstreak@22: flickerstreak@1: if type(options) == "table" then flickerstreak@1: local err, position = validateOptions(options) flickerstreak@1: if err then flickerstreak@1: if position then flickerstreak@1: AceConsole:error(position .. ": " .. err) flickerstreak@1: else flickerstreak@1: AceConsole:error(err) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: if not options.handler then flickerstreak@1: options.handler = self flickerstreak@1: end flickerstreak@22: flickerstreak@1: if options.handler == self and options.type:lower() == "group" and self.class then flickerstreak@1: AceConsole:InjectAceOptionsTable(self, options) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: local chat flickerstreak@1: if slashCommands then flickerstreak@1: chat = slashCommands[1] flickerstreak@1: else flickerstreak@1: chat = _G["SLASH_"..name..1] flickerstreak@1: end flickerstreak@22: flickerstreak@1: local handler flickerstreak@1: if type(options) == "function" then flickerstreak@1: handler = options flickerstreak@1: for k,v in pairs(_G) do flickerstreak@1: if handler == v then flickerstreak@1: local k = k flickerstreak@1: handler = function(msg) flickerstreak@1: return _G[k](msg) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: else flickerstreak@1: function handler(msg) flickerstreak@1: handlerFunc(self, chat, msg, options) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: if not _G.SlashCmdList then flickerstreak@1: _G.SlashCmdList = {} flickerstreak@1: end flickerstreak@22: flickerstreak@22: if not name and type(slashCommands) == "table" and type(slashCommands[1]) == "string" then flickerstreak@22: name = slashCommands[1]:gsub("%A", ""):upper() flickerstreak@22: end flickerstreak@22: flickerstreak@1: if not name then flickerstreak@1: local A = ('A'):byte() flickerstreak@1: repeat flickerstreak@1: name = string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) flickerstreak@1: until not _G.SlashCmdList[name] flickerstreak@1: end flickerstreak@22: flickerstreak@1: if slashCommands then flickerstreak@1: if _G.SlashCmdList[name] then flickerstreak@1: local i = 0 flickerstreak@1: while true do flickerstreak@1: i = i + 1 flickerstreak@1: if _G["SLASH_"..name..i] then flickerstreak@1: _G["SLASH_"..name..i] = nil flickerstreak@1: else flickerstreak@1: break flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: local i = 0 flickerstreak@1: for _,command in ipairs(slashCommands) do flickerstreak@1: i = i + 1 flickerstreak@1: _G["SLASH_"..name..i] = command flickerstreak@1: if command:lower() ~= command then flickerstreak@1: i = i + 1 flickerstreak@1: _G["SLASH_"..name..i] = command:lower() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: _G.SlashCmdList[name] = handler flickerstreak@1: if self ~= AceConsole and self.slashCommand == nil then flickerstreak@1: self.slashCommand = chat flickerstreak@1: end flickerstreak@22: flickerstreak@1: if not AceEvent and AceLibrary:HasInstance("AceEvent-2.0") then flickerstreak@1: external(AceConsole, "AceEvent-2.0", AceLibrary("AceEvent-2.0")) flickerstreak@1: end flickerstreak@1: if AceEvent then flickerstreak@1: if not AceConsole.nextAddon then flickerstreak@1: AceConsole.nextAddon = {} flickerstreak@1: end flickerstreak@1: if type(options) == "table" then flickerstreak@1: AceConsole.nextAddon[self] = options flickerstreak@1: if not self.playerLogin then flickerstreak@1: AceConsole:RegisterEvent("PLAYER_LOGIN", "PLAYER_LOGIN", true) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: AceConsole.registry[name] = options flickerstreak@22: flickerstreak@22: if slashCommands == tmp then flickerstreak@22: for i in ipairs(tmp) do flickerstreak@22: tmp[i] = nil flickerstreak@22: end flickerstreak@22: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function AceConsole:InjectAceOptionsTable(handler, options) flickerstreak@1: self:argCheck(handler, 2, "table") flickerstreak@1: self:argCheck(options, 3, "table") flickerstreak@1: if options.type:lower() ~= "group" then flickerstreak@1: self:error('Cannot inject into options table argument #3 if its type is not "group"') flickerstreak@1: end flickerstreak@1: if options.handler ~= nil and options.handler ~= handler then flickerstreak@1: self:error("Cannot inject into options table argument #3 if it has a different handler than argument #2") flickerstreak@1: end flickerstreak@1: options.handler = handler flickerstreak@1: local class = handler.class flickerstreak@22: if not AceLibrary:HasInstance("AceOO-2.0") or not class then flickerstreak@22: if Rock then flickerstreak@22: -- possible Rock object flickerstreak@22: for mixin in Rock:IterateObjectMixins(handler) do flickerstreak@1: if type(mixin.GetAceOptionsDataTable) == "function" then flickerstreak@1: local t = mixin:GetAceOptionsDataTable(handler) flickerstreak@1: for k,v in pairs(t) do flickerstreak@1: if type(options.args) ~= "table" then flickerstreak@1: options.args = {} flickerstreak@1: end flickerstreak@1: if options.args[k] == nil then flickerstreak@1: options.args[k] = v flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@22: else flickerstreak@22: -- Ace2 object flickerstreak@22: while class and class ~= AceLibrary("AceOO-2.0").Class do flickerstreak@22: if type(class.GetAceOptionsDataTable) == "function" then flickerstreak@22: local t = class:GetAceOptionsDataTable(handler) flickerstreak@22: for k,v in pairs(t) do flickerstreak@22: if type(options.args) ~= "table" then flickerstreak@22: options.args = {} flickerstreak@22: end flickerstreak@22: if options.args[k] == nil then flickerstreak@22: options.args[k] = v flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: local mixins = class.mixins flickerstreak@22: if mixins then flickerstreak@22: for mixin in pairs(mixins) do flickerstreak@22: if type(mixin.GetAceOptionsDataTable) == "function" then flickerstreak@22: local t = mixin:GetAceOptionsDataTable(handler) flickerstreak@22: for k,v in pairs(t) do flickerstreak@22: if type(options.args) ~= "table" then flickerstreak@22: options.args = {} flickerstreak@22: end flickerstreak@22: if options.args[k] == nil then flickerstreak@22: options.args[k] = v flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: class = class.super flickerstreak@22: end flickerstreak@1: end flickerstreak@22: flickerstreak@1: return options flickerstreak@1: end flickerstreak@1: flickerstreak@1: function AceConsole:PLAYER_LOGIN() flickerstreak@1: self.playerLogin = true flickerstreak@1: for addon, options in pairs(self.nextAddon) do flickerstreak@1: local err, position = validateOptionsMethods(addon, options) flickerstreak@1: if err then flickerstreak@1: if position then flickerstreak@1: geterrorhandler()(tostring(addon) .. ": AceConsole: " .. position .. ": " .. err) flickerstreak@1: else flickerstreak@1: geterrorhandler()(tostring(addon) .. ": AceConsole: " .. err) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: self.nextAddon[addon] = nil flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function AceConsole:TabCompleteInfo(cmdpath) flickerstreak@1: local cmd = cmdpath:match("(/%S+)") flickerstreak@1: if not cmd then flickerstreak@1: return flickerstreak@1: end flickerstreak@1: local path = cmdpath:sub(cmd:len() + 2) flickerstreak@1: for name in pairs(SlashCmdList) do --global flickerstreak@1: if AceConsole.registry[name] then flickerstreak@1: local i = 0 flickerstreak@1: while true do flickerstreak@1: i = i + 1 flickerstreak@1: local scmd = _G["SLASH_"..name..i] flickerstreak@1: if not scmd then break end flickerstreak@1: if cmd == scmd then flickerstreak@1: return name, cmd, path flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function external(self, major, instance) flickerstreak@1: if major == "AceEvent-2.0" then flickerstreak@1: if not AceEvent then flickerstreak@1: AceEvent = instance flickerstreak@22: flickerstreak@1: AceEvent:embed(self) flickerstreak@1: end flickerstreak@1: elseif major == "AceTab-2.0" then flickerstreak@1: instance:RegisterTabCompletion("AceConsole", "%/.*", function(t, cmdpath, pos) flickerstreak@22: local name, cmd, path = self:TabCompleteInfo(cmdpath:sub(1, pos)) flickerstreak@1: flickerstreak@22: if not self.registry[name] then flickerstreak@1: return false flickerstreak@1: else flickerstreak@22: local validArgs, _, _, handler = findTableLevel(self, self.registry[name], cmd, path or "") flickerstreak@1: if validArgs.args then flickerstreak@22: for arg, v in pairs(validArgs.args) do flickerstreak@22: local hidden = v.hidden flickerstreak@22: local handler = v.handler or handler flickerstreak@22: if hidden then flickerstreak@22: if type(hidden) == "function" then flickerstreak@22: hidden = hidden(v.passValue) flickerstreak@22: elseif type(hidden) == "string" then flickerstreak@22: local f = hidden flickerstreak@22: local neg = f:match("^~(.-)$") flickerstreak@22: if neg then flickerstreak@22: f = neg flickerstreak@22: end flickerstreak@22: if type(handler[f]) ~= "function" then flickerstreak@22: self:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@22: end flickerstreak@22: hidden = handler[f](handler, v.passValue) flickerstreak@22: if neg then flickerstreak@22: hidden = not hidden flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: local disabled = hidden or v.disabled flickerstreak@22: if disabled then flickerstreak@22: if type(disabled) == "function" then flickerstreak@22: disabled = disabled(v.passValue) flickerstreak@22: elseif type(disabled) == "string" then flickerstreak@22: local f = disabled flickerstreak@22: local neg = f:match("^~(.-)$") flickerstreak@22: if neg then flickerstreak@22: f = neg flickerstreak@22: end flickerstreak@22: if type(handler[f]) ~= "function" then flickerstreak@22: self:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f))) flickerstreak@22: end flickerstreak@22: disabled = handler[f](handler, v.passValue) flickerstreak@22: if neg then flickerstreak@22: disabled = not disabled flickerstreak@22: end flickerstreak@22: end flickerstreak@22: end flickerstreak@22: if not hidden and not disabled and v.type ~= "header" then flickerstreak@22: table.insert(t, (tostring(arg):gsub("%s", "-"))) flickerstreak@22: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end, function(u, matches, gcs, cmdpath) flickerstreak@22: local name, cmd, path = self:TabCompleteInfo(cmdpath) flickerstreak@22: if self.registry[name] then flickerstreak@22: local validArgs, path2, argwork, handler = findTableLevel(self, self.registry[name], cmd, path) flickerstreak@22: printUsage(self, validArgs.handler or handler, self.registry[name], validArgs, path2, argwork, argwork[#argwork], not gcs or gcs ~= "", gcs) flickerstreak@1: end flickerstreak@1: end) flickerstreak@1: elseif major == "Dewdrop-2.0" then flickerstreak@1: Dewdrop = instance flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: local function activate(self, oldLib, oldDeactivate) flickerstreak@1: AceConsole = self flickerstreak@22: flickerstreak@1: if oldLib then flickerstreak@1: self.registry = oldLib.registry flickerstreak@1: self.nextAddon = oldLib.nextAddon flickerstreak@1: end flickerstreak@22: flickerstreak@1: if not self.registry then flickerstreak@1: self.registry = {} flickerstreak@1: else flickerstreak@1: for name,options in pairs(self.registry) do flickerstreak@1: self:RegisterChatCommand(false, options, name) flickerstreak@1: end flickerstreak@1: end flickerstreak@22: flickerstreak@22: self:RegisterChatCommand("/reload", "/rl", "/reloadui", ReloadUI, "RELOAD") flickerstreak@22: self:RegisterChatCommand("/gm", ToggleHelpFrame, "GM") flickerstreak@22: local t = { "/print", "/echo" } flickerstreak@22: local _,_,_,enabled,loadable = GetAddOnInfo("DevTools") flickerstreak@22: if not enabled and not loadable then flickerstreak@22: table.insert(t, "/dump") flickerstreak@22: end flickerstreak@22: self:RegisterChatCommand(t, function(text) flickerstreak@22: text = text:trim():match("^(.-);*$") flickerstreak@22: local f, err = loadstring("AceLibrary('AceConsole-2.0'):PrintLiteral(" .. text .. ")") flickerstreak@1: if not f then flickerstreak@1: self:Print("|cffff0000Error:|r", err) flickerstreak@1: else flickerstreak@1: f() flickerstreak@1: end flickerstreak@1: end, "PRINT") flickerstreak@22: flickerstreak@1: self:activate(oldLib, oldDeactivate) flickerstreak@22: flickerstreak@1: if oldDeactivate then flickerstreak@1: oldDeactivate(oldLib) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: AceLibrary:Register(AceConsole, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)