comparison lib/AceConsole-2.0/AceConsole-2.0.lua @ 22:1b9323256a1b

Merging in 1.0 dev tree
author Flick <flickerstreak@gmail.com>
date Fri, 07 Mar 2008 22:10:55 +0000
parents libs/AceConsole-2.0/AceConsole-2.0.lua@c11ca1d8ed91
children
comparison
equal deleted inserted replaced
21:90bf38d48efd 22:1b9323256a1b
1 --[[
2 Name: AceConsole-2.0
3 Revision: $Rev: 48940 $
4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
5 Inspired By: Ace 1.x by Turan (turan@gryphon.com)
6 Website: http://www.wowace.com/
7 Documentation: http://www.wowace.com/index.php/AceConsole-2.0
8 SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceConsole-2.0
9 Description: Mixin to allow for input/output capabilities. This uses the
10 AceOptions data table format to determine input.
11 http://www.wowace.com/index.php/AceOptions_data_table
12 Dependencies: AceLibrary, AceOO-2.0
13 License: LGPL v2.1
14 ]]
15
16 local MAJOR_VERSION = "AceConsole-2.0"
17 local MINOR_VERSION = "$Revision: 48940 $"
18
19 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
20 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
21
22 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0.") end
23
24 -- #AUTODOC_NAMESPACE AceConsole
25
26 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
27 if GetLocale() == "deDE" then
28 MAP_ONOFF = { [false] = "|cffff0000Aus|r", [true] = "|cff00ff00An|r" }
29 USAGE = "Benutzung"
30 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r steht momentan auf |cffffff7f[|r%s|cffffff7f]|r"
31 IS_NOW_SET_TO = "|cffffff7f%s|r ist nun auf |cffffff7f[|r%s|cffffff7f]|r gesetzt"
32 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] ist keine g\195\188ltige Option f\195\188r |cffffff7f%s|r"
33 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] ist kein g\195\188ltiger Wert f\195\188r |cffffff7f%s|r"
34 NO_OPTIONS_AVAILABLE = "Keine Optionen verfügbar"
35 OPTION_HANDLER_NOT_FOUND = "Optionen handler |cffffff7f%q|r nicht gefunden."
36 OPTION_HANDLER_NOT_VALID = "Optionen handler nicht g\195\188ltig."
37 OPTION_IS_DISABLED = "Option |cffffff7f%s|r deaktiviert."
38 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix
39 DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?" -- fix
40 elseif GetLocale() == "frFR" then
41 MAP_ONOFF = { [false] = "|cffff0000Inactif|r", [true] = "|cff00ff00Actif|r" }
42 USAGE = "Utilisation"
43 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r est actuellement positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r"
44 IS_NOW_SET_TO = "|cffffff7f%s|r est maintenant positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r"
45 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] n'est pas une option valide pour |cffffff7f%s|r"
46 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] n'est pas une valeur valide pour |cffffff7f%s|r"
47 NO_OPTIONS_AVAILABLE = "Pas d'options disponibles"
48 OPTION_HANDLER_NOT_FOUND = "Le gestionnaire d'option |cffffff7f%q|r n'a pas \195\169t\195\169 trouv\195\169."
49 OPTION_HANDLER_NOT_VALID = "Le gestionnaire d'option n'est pas valide."
50 OPTION_IS_DISABLED = "L'option |cffffff7f%s|r est d\195\169sactiv\195\169e."
51 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix
52 DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?" -- fix
53 elseif GetLocale() == "koKR" then
54 MAP_ONOFF = { [false] = "|cffff0000끔|r", [true] = "|cff00ff00켬|r" }
55 USAGE = "사용법"
56 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r|1은;는; 현재 상태는 |cffffff7f[|r%s|cffffff7f]|r|1으로;로; 설정되어 있습니다."
57 IS_NOW_SET_TO = "|cffffff7f%s|r|1을;를; |cffffff7f[|r%s|cffffff7f]|r 상태로 변경합니다."
58 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r]|1은;는; |cffffff7f%s|r에서 사용 불가능한 설정입니다."
59 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r]|1은;는; |cffffff7f%s|r에서 사용 불가능한 설정 값입니다."
60 NO_OPTIONS_AVAILABLE = "가능한 설정이 없습니다."
61 OPTION_HANDLER_NOT_FOUND = "설정 조정 값인 |cffffff7f%q|r|1을;를; 찾지 못했습니다."
62 OPTION_HANDLER_NOT_VALID = "설정 조정 값이 올바르지 않습니다."
63 OPTION_IS_DISABLED = "|cffffff7f%s|r 설정은 사용할 수 없습니다."
64 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>"
65 DEFAULT_CONFIRM_MESSAGE = "정말 당신은 `%s'|1을;를; 하시겠습니까?"
66 elseif GetLocale() == "zhCN" then
67 MAP_ONOFF = { [false] = "|cffff0000\229\133\179\233\151\173|r", [true] = "|cff00ff00\229\188\128\229\144\175|r" }
68 USAGE = "\231\148\168\230\179\149"
69 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"
70 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"
71 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"
72 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"
73 NO_OPTIONS_AVAILABLE = "\230\178\161\230\156\137\233\128\137\233\161\185\229\143\175\231\148\168"
74 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."
75 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."
76 OPTION_IS_DISABLED = "\233\128\137\233\161\185 |cffffff7f%s|r \228\184\141\229\174\140\230\149\180."
77 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix
78 DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?" -- fix
79 elseif GetLocale() == "zhTW" then
80 MAP_ONOFF = { [false] = "|cffff0000關閉|r", [true] = "|cff00ff00開啟|r" }
81 USAGE = "用法"
82 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r目前的設定為|cffffff7f[|r%s|cffffff7f]|r"
83 IS_NOW_SET_TO = "|cffffff7f%s|r現在被設定為|cffffff7f[|r%s|cffffff7f]|r"
84 IS_NOT_A_VALID_OPTION_FOR = "對於|cffffff7f%2$s|r,[|cffffff7f%1$s|r]是一個不符合規定的選項"
85 IS_NOT_A_VALID_VALUE_FOR = "對於|cffffff7f%2$s|r,[|cffffff7f%1$s|r]是一個不符合規定的數值"
86 NO_OPTIONS_AVAILABLE = "沒有可用的選項"
87 OPTION_HANDLER_NOT_FOUND = "找不到|cffffff7f%q|r選項處理器。"
88 OPTION_HANDLER_NOT_VALID = "選項處理器不符合規定。"
89 OPTION_IS_DISABLED = "|cffffff7f%s|r已被停用。"
90 KEYBINDING_USAGE = "<Alt-Ctrl-Shift-鍵>"
91 DEFAULT_CONFIRM_MESSAGE = "是否執行「%s」?"
92 elseif GetLocale() == "esES" then
93 MAP_ONOFF = { [false] = "|cffff0000Desactivado|r", [true] = "|cff00ff00Activado|r" }
94 USAGE = "Uso"
95 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r est\195\161 establecido actualmente a |cffffff7f[|r%s|cffffff7f]|r"
96 IS_NOW_SET_TO = "|cffffff7f%s|r se ha establecido a |cffffff7f[|r%s|cffffff7f]|r"
97 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] no es una opci\195\179n valida para |cffffff7f%s|r"
98 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] no es un valor v\195\161lido para |cffffff7f%s|r"
99 NO_OPTIONS_AVAILABLE = "No hay opciones disponibles"
100 OPTION_HANDLER_NOT_FOUND = "Gestor de opciones |cffffff7f%q|r no encontrado."
101 OPTION_HANDLER_NOT_VALID = "Gestor de opciones no v\195\161lido."
102 OPTION_IS_DISABLED = "La opci\195\179n |cffffff7f%s|r est\195\161 desactivada."
103 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>"
104 DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?" -- fix
105 else -- enUS
106 MAP_ONOFF = { [false] = "|cffff0000Off|r", [true] = "|cff00ff00On|r" }
107 USAGE = "Usage"
108 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r is currently set to |cffffff7f[|r%s|cffffff7f]|r"
109 IS_NOW_SET_TO = "|cffffff7f%s|r is now set to |cffffff7f[|r%s|cffffff7f]|r"
110 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] is not a valid option for |cffffff7f%s|r"
111 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] is not a valid value for |cffffff7f%s|r"
112 NO_OPTIONS_AVAILABLE = "No options available"
113 OPTION_HANDLER_NOT_FOUND = "Option handler |cffffff7f%q|r not found."
114 OPTION_HANDLER_NOT_VALID = "Option handler not valid."
115 OPTION_IS_DISABLED = "Option |cffffff7f%s|r is disabled."
116 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>"
117 DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?"
118 end
119
120 local NONE = NONE or "None"
121
122 local AceOO = AceLibrary("AceOO-2.0")
123 local AceEvent
124
125 local AceConsole = AceOO.Mixin { "Print", "PrintComma", "PrintLiteral", "CustomPrint", "RegisterChatCommand" }
126 local Dewdrop
127
128 local _G = getfenv(0)
129
130 local function print(text, name, r, g, b, frame, delay)
131 if not text or text:len() == 0 then
132 text = " "
133 end
134 if not name or name == AceConsole then
135 else
136 text = "|cffffff78" .. tostring(name) .. ":|r " .. text
137 end
138 local last_color
139 for t in text:gmatch("[^\n]+") do
140 (frame or DEFAULT_CHAT_FRAME):AddMessage(last_color and "|cff" .. last_color .. t or t, r, g, b, nil, delay or 5)
141 if not last_color or t:find("|r") or t:find("|c") then
142 last_color = t:match(".*|c[fF][fF](%x%x%x%x%x%x)[^|]-$")
143 end
144 end
145 return text
146 end
147
148 local real_tostring = tostring
149
150 local function tostring(t)
151 if type(t) == "table" then
152 if type(rawget(t, 0)) == "userdata" and type(t.GetObjectType) == "function" then
153 return ("<%s:%s>"):format(t:GetObjectType(), t:GetName() or "(anon)")
154 end
155 end
156 return real_tostring(t)
157 end
158
159 local getkeystring
160
161 local function isList(t)
162 local n = #t
163 for k,v in pairs(t) do
164 if type(k) ~= "number" then
165 return false
166 elseif k < 1 or k > n then
167 return false
168 end
169 end
170 return true
171 end
172
173 local findGlobal = setmetatable({}, {__index=function(self, t)
174 for k,v in pairs(_G) do
175 if v == t then
176 k = tostring(k)
177 self[v] = k
178 return k
179 end
180 end
181 self[t] = false
182 return false
183 end})
184
185 local recurse = {}
186 local timeToEnd
187 local GetTime = GetTime
188 local type = type
189
190 local new, del
191 do
192 local cache = setmetatable({},{__mode='k'})
193 function new()
194 local t = next(cache)
195 if t then
196 cache[t] = nil
197 return t
198 else
199 return {}
200 end
201 end
202
203 function del(t)
204 for k in pairs(t) do
205 t[k] = nil
206 end
207 cache[t] = true
208 return nil
209 end
210 end
211
212 local function ignoreCaseSort(alpha, bravo)
213 if not alpha or not bravo then
214 return false
215 end
216 return tostring(alpha):lower() < tostring(bravo):lower()
217 end
218
219 local function specialSort(alpha, bravo)
220 if alpha == nil or bravo == nil then
221 return false
222 end
223 local type_alpha, type_bravo = type(alpha), type(bravo)
224 if type_alpha ~= type_bravo then
225 return type_alpha < type_bravo
226 end
227 if type_alpha == "string" then
228 return alpha:lower() < bravo:lower()
229 elseif type_alpha == "number" then
230 return alpha < bravo
231 elseif type_alpha == "table" then
232 return #alpha < #bravo
233 elseif type_alpha == "boolean" then
234 return not alpha
235 else
236 return false
237 end
238 end
239
240 local function escapeChar(c)
241 return ("\\%03d"):format(c:byte())
242 end
243
244 local function literal_tostring_prime(t, depth)
245 if type(t) == "string" then
246 return ("|cff00ff00%q|r"):format((t:gsub("|", "||"))):gsub("[\001-\012\014-\031\128-\255]", escapeChar)
247 elseif type(t) == "table" then
248 if t == _G then
249 return "|cffffea00_G|r"
250 end
251 if type(rawget(t, 0)) == "userdata" and type(t.GetObjectType) == "function" then
252 return ("|cffffea00<%s:%s>|r"):format(t:GetObjectType(), t:GetName() or "(anon)")
253 end
254 if next(t) == nil then
255 local mt = getmetatable(t)
256 if type(mt) == "table" and type(mt.__raw) == "table" then
257 t = mt.__raw
258 end
259 end
260 if recurse[t] then
261 local g = findGlobal[t]
262 if g then
263 return ("|cff9f9f9f<Recursion _G[%q]>|r"):format(g)
264 else
265 return ("|cff9f9f9f<Recursion %s>|r"):format(real_tostring(t):gsub("|", "||"))
266 end
267 elseif GetTime() > timeToEnd then
268 local g = findGlobal[t]
269 if g then
270 return ("|cff9f9f9f<Timeout _G[%q]>|r"):format(g)
271 else
272 return ("|cff9f9f9f<Timeout %s>|r"):format(real_tostring(t):gsub("|", "||"))
273 end
274 elseif depth >= 2 then
275 local g = findGlobal[t]
276 if g then
277 return ("|cff9f9f9f<_G[%q]>|r"):format(g)
278 else
279 return ("|cff9f9f9f<%s>|r"):format(real_tostring(t):gsub("|", "||"))
280 end
281 end
282 recurse[t] = true
283 if next(t) == nil then
284 return "{}"
285 elseif next(t, (next(t))) == nil then
286 local k, v = next(t)
287 if k == 1 then
288 return "{ " .. literal_tostring_prime(v, depth+1) .. " }"
289 else
290 return "{ " .. getkeystring(k, depth+1) .. " = " .. literal_tostring_prime(v, depth+1) .. " }"
291 end
292 end
293 local s
294 local g = findGlobal[t]
295 if g then
296 s = ("{ |cff9f9f9f-- _G[%q]|r\n"):format(g)
297 else
298 s = "{ |cff9f9f9f-- " .. real_tostring(t):gsub("|", "||") .. "|r\n"
299 end
300 if isList(t) then
301 for i = 1, #t do
302 s = s .. (" "):rep(depth+1) .. literal_tostring_prime(t[i], depth+1) .. (i == #t and "\n" or ",\n")
303 end
304 else
305 local tmp = new()
306 for k in pairs(t) do
307 tmp[#tmp+1] = k
308 end
309 table.sort(tmp, specialSort)
310 for i,k in ipairs(tmp) do
311 tmp[i] = nil
312 local v = t[k]
313 s = s .. (" "):rep(depth+1) .. getkeystring(k, depth+1) .. " = " .. literal_tostring_prime(v, depth+1) .. (tmp[i+1] == nil and "\n" or ",\n")
314 end
315 tmp = del(tmp)
316 end
317 if g then
318 s = s .. (" "):rep(depth) .. string.format("} |cff9f9f9f-- _G[%q]|r", g)
319 else
320 s = s .. (" "):rep(depth) .. "} |cff9f9f9f-- " .. real_tostring(t):gsub("|", "||")
321 end
322 return s
323 end
324 if type(t) == "number" then
325 return "|cffff7fff" .. real_tostring(t) .. "|r"
326 elseif type(t) == "boolean" then
327 return "|cffff9100" .. real_tostring(t) .. "|r"
328 elseif t == nil then
329 return "|cffff7f7f" .. real_tostring(t) .. "|r"
330 else
331 return "|cffffea00" .. real_tostring(t) .. "|r"
332 end
333 end
334
335 function getkeystring(t, depth)
336 if type(t) == "string" then
337 if t:find("^[%a_][%a%d_]*$") then
338 return "|cff7fd5ff" .. t .. "|r"
339 end
340 end
341 return "[" .. literal_tostring_prime(t, depth) .. "]"
342 end
343
344 local get_stringed_args
345 do
346 local function g(value, ...)
347 if select('#', ...) == 0 then
348 return literal_tostring_prime(value, 1)
349 end
350 return literal_tostring_prime(value, 1) .. ", " .. g(...)
351 end
352
353 local function f(success, ...)
354 if not success then
355 return
356 end
357 return g(...)
358 end
359
360 function get_stringed_args(func, ...)
361 return f(pcall(func, ...))
362 end
363 end
364
365 local function literal_tostring_frame(t)
366 local s = ("|cffffea00<%s:%s|r\n"):format(t:GetObjectType(), t:GetName() or "(anon)")
367 local __index = getmetatable(t).__index
368 local tmp, tmp2, tmp3 = new(), new(), new()
369 for k in pairs(t) do
370 if k ~= 0 then
371 tmp3[k] = true
372 tmp2[k] = true
373 end
374 end
375 for k in pairs(__index) do
376 tmp2[k] = true
377 end
378 for k in pairs(tmp2) do
379 tmp[#tmp+1] = k
380 tmp2[k] = nil
381 end
382 table.sort(tmp, ignoreCaseSort)
383 local first = true
384 for i,k in ipairs(tmp) do
385 local v = t[k]
386 local good = true
387 if k == "GetPoint" then
388 for i = 1, t:GetNumPoints() do
389 if not first then
390 s = s .. ",\n"
391 else
392 first = false
393 end
394 s = s .. " " .. getkeystring(k, 1) .. "(" .. literal_tostring_prime(i, 1) .. ") => " .. get_stringed_args(v, t, i)
395 end
396 elseif type(v) == "function" and type(k) == "string" and (k:find("^Is") or k:find("^Get") or k:find("^Can")) then
397 local q = get_stringed_args(v, t)
398 if q then
399 if not first then
400 s = s .. ",\n"
401 else
402 first = false
403 end
404 s = s .. " " .. getkeystring(k, 1) .. "() => " .. q
405 end
406 elseif type(v) ~= "function" or (type(v) == "function" and type(k) == "string" and tmp3[k]) then
407 if not first then
408 s = s .. ",\n"
409 else
410 first = false
411 end
412 s = s .. " " .. getkeystring(k, 1) .. " = " .. literal_tostring_prime(v, 1)
413 else
414 good = false
415 end
416 end
417 tmp, tmp2, tmp3 = del(tmp), del(tmp2), del(tmp3)
418 s = s .. "\n|cffffea00>|r"
419 return s
420 end
421
422 local function literal_tostring(t, only)
423 timeToEnd = GetTime() + 0.2
424 local s
425 if only and type(t) == "table" and type(rawget(t, 0)) == "userdata" and type(t.GetObjectType) == "function" then
426 s = literal_tostring_frame(t)
427 else
428 s = literal_tostring_prime(t, 0)
429 end
430 for k,v in pairs(recurse) do
431 recurse[k] = nil
432 end
433 for k,v in pairs(findGlobal) do
434 findGlobal[k] = nil
435 end
436 return s
437 end
438
439 local function tostring_args(a1, ...)
440 if select('#', ...) < 1 then
441 return tostring(a1)
442 end
443 return tostring(a1), tostring_args(...)
444 end
445
446 local function literal_tostring_args(a1, ...)
447 if select('#', ...) < 1 then
448 return literal_tostring(a1)
449 end
450 return literal_tostring(a1), literal_tostring_args(...)
451 end
452
453 function AceConsole:CustomPrint(r, g, b, frame, delay, connector, a1, ...)
454 if connector == true then
455 local s
456 if select('#', ...) == 0 then
457 s = literal_tostring(a1, true)
458 else
459 s = (", "):join(literal_tostring_args(a1, ...))
460 end
461 return print(s, self, r, g, b, frame or self.printFrame, delay)
462 elseif tostring(a1):find("%%") and select('#', ...) >= 1 then
463 local success, text = pcall(string.format, tostring_args(a1, ...))
464 if success then
465 return print(text, self, r, g, b, frame or self.printFrame, delay)
466 end
467 end
468 return print((connector or " "):join(tostring_args(a1, ...)), self, r, g, b, frame or self.printFrame, delay)
469 end
470
471 function AceConsole:Print(...)
472 return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, " ", ...)
473 end
474
475 function AceConsole:PrintComma(...)
476 return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, ", ", ...)
477 end
478
479 function AceConsole:PrintLiteral(...)
480 return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, true, ...)
481 end
482
483 local work
484 local argwork
485
486 local function findTableLevel(self, options, chat, text, index, passTable)
487 if not index then
488 index = 1
489 if work then
490 for k,v in pairs(work) do
491 work[k] = nil
492 end
493 for k,v in pairs(argwork) do
494 argwork[k] = nil
495 end
496 else
497 work = {}
498 argwork = {}
499 end
500 local len = text:len()
501 local count
502 repeat
503 text, count = text:gsub("(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[[^%]]-) (.-%]|h|r)", "%1\001%2")
504 until count == 0
505 text = text:gsub("(%]|h|r)(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[)", "%1 %2")
506 for token in text:gmatch("([^%s]+)") do
507 local token = token
508 local num = tonumber(token)
509 if num then
510 token = num
511 else
512 token = token:gsub("\001", " ")
513 end
514 table.insert(work, token)
515 end
516 end
517
518 local path = chat
519 for i = 1, index - 1 do
520 path = path .. " " .. tostring(work[i])
521 end
522
523 local passValue = options.passValue or (passTable and work[index-1])
524 passTable = passTable or options
525
526 if type(options.args) == "table" then
527 local disabled, hidden = options.disabled, options.cmdHidden or options.hidden
528 if hidden then
529 if type(hidden) == "function" then
530 hidden = hidden(passValue)
531 elseif type(hidden) == "string" then
532 local handler = options.handler or self
533 local f = hidden
534 local neg = f:match("^~(.-)$")
535 if neg then
536 f = neg
537 end
538 if type(handler[f]) ~= "function" then
539 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
540 end
541 hidden = handler[f](handler, passValue)
542 if neg then
543 hidden = not hidden
544 end
545 end
546 end
547 if hidden then
548 disabled = true
549 elseif disabled then
550 if type(disabled) == "function" then
551 disabled = disabled(passValue)
552 elseif type(disabled) == "string" then
553 local handler = options.handler or self
554 local f = disabled
555 local neg = f:match("^~(.-)$")
556 if neg then
557 f = neg
558 end
559 if type(handler[f]) ~= "function" then
560 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
561 end
562 disabled = handler[f](handler, passValue)
563 if neg then
564 disabled = not disabled
565 end
566 end
567 end
568 if not disabled then
569 local next = work[index] and tostring(work[index]):lower()
570 local next_num = tonumber(next)
571 if next then
572 for k,v in pairs(options.args) do
573 local good = false
574 if tostring(k):gsub("%s", "-"):lower() == next then
575 good = true
576 elseif k == next_num then
577 good = true
578 elseif type(v.aliases) == "table" then
579 for _,alias in ipairs(v.aliases) do
580 if alias:gsub("%s", "-"):lower() == next then
581 good = true
582 break
583 end
584 end
585 elseif type(v.aliases) == "string" and v.aliases:gsub("%s", "-"):lower() == next then
586 good = true
587 end
588 if good then
589 work[index] = k -- revert it back to its original form as supplied in args
590 if options.pass then
591 passTable = passTable or options
592 if options.get and options.set then
593 passTable = options
594 end
595 else
596 passTable = nil
597 end
598 return findTableLevel(options.handler or self, v, chat, text, index + 1, passTable)
599 end
600 end
601 end
602 end
603 end
604 for i = index, #work do
605 table.insert(argwork, work[i])
606 end
607 return options, path, argwork, options.handler or self, passTable, passValue
608 end
609
610 local function validateOptionsMethods(self, options, position)
611 if type(options) ~= "table" then
612 return "Options must be a table.", position
613 end
614 self = options.handler or self
615 if options.type == "execute" then
616 if options.func and type(options.func) ~= "string" and type(options.func) ~= "function" then
617 return "func must be a string or function", position
618 end
619 if options.func and type(options.func) == "string" and type(self[options.func]) ~= "function" then
620 return ("%q is not a proper function"):format(tostring(options.func)), position
621 end
622 else
623 if options.get then
624 if type(options.get) ~= "string" and type(options.get) ~= "function" then
625 return "get must be a string or function", position
626 end
627 if type(options.get) == "string" then
628 local f = options.get
629 if options.type == "toggle" then
630 f = f:match("^~(.-)$") or f
631 end
632 if type(self[f]) ~= "function" then
633 return ("%q is not a proper function"):format(tostring(f)), position
634 end
635 end
636 end
637 if options.set then
638 if type(options.set) ~= "string" and type(options.set) ~= "function" then
639 return "set must be a string or function", position
640 end
641 if type(options.set) == "string" and type(self[options.set]) ~= "function" then
642 return ("%q is not a proper function"):format(tostring(options.set)), position
643 end
644 end
645 if options.validate and type(options.validate) ~= "table" and options.validate ~= "keybinding" then
646 if type(options.validate) ~= "string" and type(options.validate) ~= "function" then
647 return "validate must be a string or function", position
648 end
649 if type(options.validate) == "string" and type(self[options.validate]) ~= "function" then
650 return ("%q is not a proper function"):format(tostring(options.validate)), position
651 end
652 end
653 end
654 if options.disabled and type(options.disabled) == "string" then
655 local f = options.disabled
656 f = f:match("^~(.-)$") or f
657 if type(self[f]) ~= "function" then
658 return ("%q is not a proper function"):format(tostring(f)), position
659 end
660 end
661 if options.cmdHidden and type(options.cmdHidden) == "string" then
662 local f = options.cmdHidden
663 f = f:match("^~(.-)$") or f
664 if type(self[f]) ~= "function" then
665 return ("%q is not a proper function"):format(tostring(f)), position
666 end
667 end
668 if options.guiHidden and type(options.guiHidden) == "string" then
669 local f = options.guiHidden
670 f = f:match("^~(.-)$") or f
671 if type(self[f]) ~= "function" then
672 return ("%q is not a proper function"):format(tostring(f)), position
673 end
674 end
675 if options.hidden and type(options.hidden) == "string" then
676 local f = options.hidden
677 f = f:match("^~(.-)$") or f
678 if type(self[f]) ~= "function" then
679 return ("%q is not a proper function"):format(tostring(f)), position
680 end
681 end
682 if options.type == "group" and type(options.args) == "table" then
683 for k,v in pairs(options.args) do
684 if type(v) == "table" then
685 local newposition
686 if position then
687 newposition = position .. ".args." .. k
688 else
689 newposition = "args." .. k
690 end
691 local err, pos = validateOptionsMethods(self, v, newposition)
692 if err then
693 return err, pos
694 end
695 end
696 end
697 end
698 end
699
700 local function validateOptions(options, position, baseOptions, fromPass)
701 if not baseOptions then
702 baseOptions = options
703 end
704 if type(options) ~= "table" then
705 return "Options must be a table.", position
706 end
707 local kind = options.type
708 if type(kind) ~= "string" then
709 return '"type" must be a string.', position
710 elseif kind ~= "group" and kind ~= "range" and kind ~= "text" and kind ~= "execute" and kind ~= "toggle" and kind ~= "color" and kind ~= "header" then
711 return '"type" must either be "range", "text", "group", "toggle", "execute", "color", or "header".', position
712 end
713 if options.aliases then
714 if type(options.aliases) ~= "table" and type(options.aliases) ~= "string" then
715 return '"alias" must be a table or string', position
716 end
717 end
718 if not fromPass then
719 if kind == "execute" then
720 if type(options.func) ~= "string" and type(options.func) ~= "function" then
721 return '"func" must be a string or function', position
722 end
723 elseif kind == "range" or kind == "text" or kind == "toggle" then
724 if type(options.set) ~= "string" and type(options.set) ~= "function" then
725 return '"set" must be a string or function', position
726 end
727 if kind == "text" and options.get == false then
728 elseif type(options.get) ~= "string" and type(options.get) ~= "function" then
729 return '"get" must be a string or function', position
730 end
731 elseif kind == "group" and options.pass then
732 if options.pass ~= true then
733 return '"pass" must be either nil, true, or false', position
734 end
735 if not options.func then
736 if type(options.set) ~= "string" and type(options.set) ~= "function" then
737 return '"set" must be a string or function', position
738 end
739 if type(options.get) ~= "string" and type(options.get) ~= "function" then
740 return '"get" must be a string or function', position
741 end
742 elseif type(options.func) ~= "string" and type(options.func) ~= "function" then
743 return '"func" must be a string or function', position
744 end
745 end
746 end
747 if options ~= baseOptions then
748 if kind == "header" then
749 elseif type(options.desc) ~= "string" then
750 return '"desc" must be a string', position
751 elseif options.desc:len() == 0 then
752 return '"desc" cannot be a 0-length string', position
753 end
754 end
755
756 if options ~= baseOptions or kind == "range" or kind == "text" or kind == "toggle" or kind == "color" then
757 if options.type == "header" and not options.cmdName and not options.name then
758 elseif options.cmdName then
759 if type(options.cmdName) ~= "string" then
760 return '"cmdName" must be a string or nil', position
761 elseif options.cmdName:len() == 0 then
762 return '"cmdName" cannot be a 0-length string', position
763 end
764 if type(options.guiName) ~= "string" then
765 if not options.guiNameIsMap then
766 return '"guiName" must be a string or nil', position
767 end
768 elseif options.guiName:len() == 0 then
769 return '"guiName" cannot be a 0-length string', position
770 end
771 else
772 if type(options.name) ~= "string" then
773 return '"name" must be a string', position
774 elseif options.name:len() == 0 then
775 return '"name" cannot be a 0-length string', position
776 end
777 end
778 end
779 if options.guiNameIsMap then
780 if type(options.guiNameIsMap) ~= "boolean" then
781 return '"guiNameIsMap" must be a boolean or nil', position
782 elseif options.type ~= "toggle" then
783 return 'if "guiNameIsMap" is true, then "type" must be set to \'toggle\'', position
784 elseif type(options.map) ~= "table" then
785 return '"map" must be a table', position
786 end
787 end
788 if options.message and type(options.message) ~= "string" then
789 return '"message" must be a string or nil', position
790 end
791 if options.error and type(options.error) ~= "string" then
792 return '"error" must be a string or nil', position
793 end
794 if options.current and type(options.current) ~= "string" then
795 return '"current" must be a string or nil', position
796 end
797 if options.order then
798 if type(options.order) ~= "number" or (-1 < options.order and options.order < 0.999) then
799 return '"order" must be a non-zero number or nil', position
800 end
801 end
802 if options.disabled then
803 if type(options.disabled) ~= "function" and type(options.disabled) ~= "string" and options.disabled ~= true then
804 return '"disabled" must be a function, string, or boolean', position
805 end
806 end
807 if options.cmdHidden then
808 if type(options.cmdHidden) ~= "function" and type(options.cmdHidden) ~= "string" and options.cmdHidden ~= true then
809 return '"cmdHidden" must be a function, string, or boolean', position
810 end
811 end
812 if options.guiHidden then
813 if type(options.guiHidden) ~= "function" and type(options.guiHidden) ~= "string" and options.guiHidden ~= true then
814 return '"guiHidden" must be a function, string, or boolean', position
815 end
816 end
817 if options.hidden then
818 if type(options.hidden) ~= "function" and type(options.hidden) ~= "string" and options.hidden ~= true then
819 return '"hidden" must be a function, string, or boolean', position
820 end
821 end
822 if kind == "text" then
823 if type(options.validate) == "table" then
824 local t = options.validate
825 local iTable = nil
826 for k,v in pairs(t) do
827 if type(k) == "number" then
828 if iTable == nil then
829 iTable = true
830 elseif not iTable then
831 return '"validate" must either have all keys be indexed numbers or strings', position
832 elseif k < 1 or k > #t then
833 return '"validate" numeric keys must be indexed properly. >= 1 and <= #validate', position
834 end
835 else
836 if iTable == nil then
837 iTable = false
838 elseif iTable then
839 return '"validate" must either have all keys be indexed numbers or strings', position
840 end
841 end
842 if type(v) ~= "string" then
843 return '"validate" values must all be strings', position
844 end
845 end
846 if options.multiToggle and options.multiToggle ~= true then
847 return '"multiToggle" must be a boolean or nil if "validate" is a table', position
848 end
849 elseif options.validate == "keybinding" then
850
851 else
852 if type(options.usage) ~= "string" then
853 return '"usage" must be a string', position
854 elseif options.validate and type(options.validate) ~= "string" and type(options.validate) ~= "function" then
855 return '"validate" must be a string, function, or table', position
856 end
857 end
858 if options.multiToggle and type(options.validate) ~= "table" then
859 return '"validate" must be a table if "multiToggle" is true', position
860 end
861 elseif kind == "range" then
862 if options.min or options.max then
863 if type(options.min) ~= "number" then
864 return '"min" must be a number', position
865 elseif type(options.max) ~= "number" then
866 return '"max" must be a number', position
867 elseif options.min >= options.max then
868 return '"min" must be less than "max"', position
869 end
870 end
871 if options.step then
872 if type(options.step) ~= "number" then
873 return '"step" must be a number', position
874 elseif options.step < 0 then
875 return '"step" must be nonnegative', position
876 end
877 end
878 if options.isPercent and options.isPercent ~= true then
879 return '"isPercent" must either be nil, true, or false', position
880 end
881 elseif kind == "toggle" then
882 if options.map then
883 if type(options.map) ~= "table" then
884 return '"map" must be a table', position
885 elseif type(options.map[true]) ~= "string" then
886 return '"map[true]" must be a string', position
887 elseif type(options.map[false]) ~= "string" then
888 return '"map[false]" must be a string', position
889 end
890 end
891 elseif kind == "color" then
892 if options.hasAlpha and options.hasAlpha ~= true then
893 return '"hasAlpha" must be nil, true, or false', position
894 end
895 elseif kind == "group" then
896 if options.pass and options.pass ~= true then
897 return '"pass" must be nil, true, or false', position
898 end
899 if type(options.args) ~= "table" then
900 return '"args" must be a table', position
901 end
902 for k,v in pairs(options.args) do
903 if type(k) ~= "number" then
904 if type(k) ~= "string" then
905 return '"args" keys must be strings or numbers', position
906 elseif k:len() == 0 then
907 return '"args" keys must not be 0-length strings.', position
908 end
909 end
910 if type(v) ~= "table" then
911 if type(k) == "number" then
912 return '"args" values must be tables', position and position .. "[" .. k .. "]" or "[" .. k .. "]"
913 else
914 return '"args" values must be tables', position and position .. "." .. k or k
915 end
916 end
917 local newposition
918 if type(k) == "number" then
919 newposition = position and position .. ".args[" .. k .. "]" or "args[" .. k .. "]"
920 else
921 newposition = position and position .. ".args." .. k or "args." .. k
922 end
923 local err, pos = validateOptions(v, newposition, baseOptions, options.pass)
924 if err then
925 return err, pos
926 end
927 end
928 elseif kind == "execute" then
929 if type(options.confirm) ~= "string" and type(options.confirm) ~= "boolean" and type(options.confirm) ~= "nil" then
930 return '"confirm" must be a string, boolean, or nil', position
931 end
932 end
933 end
934
935 local colorTable
936 local colorFunc
937 local colorCancelFunc
938
939 local function keybindingValidateFunc(text)
940 if text == nil or text == "NONE" then
941 return nil
942 end
943 text = text:upper()
944 local shift, ctrl, alt
945 local modifier
946 while true do
947 if text == "-" then
948 break
949 end
950 modifier, text = strsplit('-', text, 2)
951 if text then
952 if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then
953 return false
954 end
955 if modifier == "SHIFT" then
956 if shift then
957 return false
958 end
959 shift = true
960 end
961 if modifier == "CTRL" then
962 if ctrl then
963 return false
964 end
965 ctrl = true
966 end
967 if modifier == "ALT" then
968 if alt then
969 return false
970 end
971 alt = true
972 end
973 else
974 text = modifier
975 break
976 end
977 end
978 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
979 return false
980 end
981 local s = text
982 if shift then
983 s = "SHIFT-" .. s
984 end
985 if ctrl then
986 s = "CTRL-" .. s
987 end
988 if alt then
989 s = "ALT-" .. s
990 end
991 return s
992 end
993 AceConsole.keybindingValidateFunc = keybindingValidateFunc
994
995 local order
996
997 local mysort_args
998 local mysort
999
1000 local function icaseSort(alpha, bravo)
1001 if type(alpha) == "number" and type(bravo) == "number" then
1002 return alpha < bravo
1003 end
1004 return tostring(alpha):lower() < tostring(bravo):lower()
1005 end
1006
1007 local tmp = {}
1008 local function printUsage(self, handler, realOptions, options, path, args, passValue, quiet, filter)
1009 if filter then
1010 filter = "^" .. filter:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
1011 end
1012 local hidden, disabled = options.cmdHidden or options.hidden, options.disabled
1013 if hidden then
1014 if type(hidden) == "function" then
1015 hidden = hidden(options.passValue)
1016 elseif type(hidden) == "string" then
1017 local f = hidden
1018 local neg = f:match("^~(.-)$")
1019 if neg then
1020 f = neg
1021 end
1022 if type(handler[f]) ~= "function" then
1023 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
1024 end
1025 hidden = handler[f](handler, options.passValue)
1026 if neg then
1027 hidden = not hidden
1028 end
1029 end
1030 end
1031 if hidden then
1032 disabled = true
1033 elseif disabled then
1034 if type(disabled) == "function" then
1035 disabled = disabled(options.passValue)
1036 elseif type(disabled) == "string" then
1037 local f = disabled
1038 local neg = f:match("^~(.-)$")
1039 if neg then
1040 f = neg
1041 end
1042 if type(handler[f]) ~= "function" then
1043 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
1044 end
1045 disabled = handler[f](handler, options.passValue)
1046 if neg then
1047 disabled = not disabled
1048 end
1049 end
1050 end
1051 local kind = (options.type or "group"):lower()
1052 if disabled then
1053 print(OPTION_IS_DISABLED:format(path), realOptions.cmdName or realOptions.name or self)
1054 elseif kind == "text" then
1055 local var
1056 local multiToggle
1057 for k in pairs(tmp) do
1058 tmp[k] = nil
1059 end
1060 if passTable then
1061 multiToggle = passTable.multiToggle
1062 if not passTable.get then
1063 elseif type(passTable.get) == "function" then
1064 if not multiToggle then
1065 var = passTable.get(passValue)
1066 else
1067 var = tmp
1068 for k,v in pairs(options.validate) do
1069 local val = type(k) ~= "number" and k or v
1070 if passValue == nil then
1071 var[val] = passTable.get(val) or nil
1072 else
1073 var[val] = passTable.get(passValue, val) or nil
1074 end
1075 end
1076 end
1077 else
1078 local handler = passTable.handler or handler
1079 if type(handler[passTable.get]) ~= "function" then
1080 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(passTable.get)))
1081 end
1082 var = handler[passTable.get](handler, passValue)
1083 if not multiToggle then
1084 var = handler[passTable.get](handler, passValue)
1085 else
1086 var = tmp
1087 for k,v in pairs(options.validate) do
1088 local val = type(k) ~= "number" and k or v
1089 if passValue == nil then
1090 var[val] = handler[passTable.get](handler, val) or nil
1091 else
1092 var[val] = handler[passTable.get](handler, passValue, val) or nil
1093 end
1094 end
1095 end
1096 end
1097 else
1098 multiToggle = options.multiToggle
1099 if not options.get then
1100 elseif type(options.get) == "function" then
1101 if not multiToggle then
1102 var = options.get(passValue)
1103 else
1104 var = tmp
1105 for k,v in pairs(options.validate) do
1106 local val = type(k) ~= "number" and k or v
1107 if passValue == nil then
1108 var[val] = options.get(val) or nil
1109 else
1110 var[val] = options.get(passValue, val) or nil
1111 end
1112 end
1113 end
1114 else
1115 local handler = options.handler or handler
1116 if type(handler[options.get]) ~= "function" then
1117 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options.get)))
1118 end
1119 if not multiToggle then
1120 var = handler[options.get](handler, passValue)
1121 else
1122 var = tmp
1123 for k,v in pairs(options.validate) do
1124 local val = type(k) ~= "number" and k or v
1125 if passValue == nil then
1126 var[val] = handler[options.get](handler, val) or nil
1127 else
1128 var[val] = handler[options.get](handler, passValue, val) or nil
1129 end
1130 end
1131 end
1132 end
1133 end
1134
1135 local usage
1136 if type(options.validate) == "table" then
1137 if filter then
1138 if not order then
1139 order = {}
1140 end
1141 for k,v in pairs(options.validate) do
1142 if v:find(filter) then
1143 table.insert(order, v)
1144 end
1145 end
1146 table.sort(order, icaseSort)
1147 usage = "{" .. table.concat(order, " || ") .. "}"
1148 for k in pairs(order) do
1149 order[k] = nil
1150 end
1151 else
1152 if not order then
1153 order = {}
1154 end
1155 for k,v in pairs(options.validate) do
1156 table.insert(order, v)
1157 end
1158 table.sort(order, icaseSort)
1159 usage = "{" .. table.concat(order, " || ") .. "}"
1160 for k in pairs(order) do
1161 order[k] = nil
1162 end
1163 end
1164 if multiToggle then
1165 if not next(var) then
1166 var = NONE
1167 else
1168 if not order then
1169 order = {}
1170 end
1171 for k in pairs(var) do
1172 if options.validate[k] then
1173 order[#order+1] = options.validate[k]
1174 else
1175 for _,v in pairs(options.validate) do
1176 if v == k or (type(v) == "string" and type(k) == "string" and v:lower() == k:lower()) then
1177 order[#order+1] = v
1178 break
1179 end
1180 end
1181 end
1182 end
1183 table.sort(order, icaseSort)
1184 var = table.concat(order, ", ")
1185 for k in pairs(order) do
1186 order[k] = nil
1187 end
1188 end
1189 else
1190 var = options.validate[var] or var
1191 end
1192 elseif options.validate == "keybinding" then
1193 usage = KEYBINDING_USAGE
1194 else
1195 usage = options.usage or "<value>"
1196 end
1197 if not quiet then
1198 print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, usage), realOptions.cmdName or realOptions.name or self)
1199 end
1200 if (passTable and passTable.get) or options.get then
1201 print((options.current or IS_CURRENTLY_SET_TO):format(tostring(options.cmdName or options.name), tostring(var or NONE)))
1202 end
1203 elseif kind == "range" then
1204 local var
1205 if passTable then
1206 if type(passTable.get) == "function" then
1207 var = passTable.get(passValue)
1208 else
1209 local handler = passTable.handler or handler
1210 if type(handler[passTable.get]) ~= "function" then
1211 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(passTable.get)))
1212 end
1213 var = handler[passTable.get](handler, passValue)
1214 end
1215 else
1216 if type(options.get) == "function" then
1217 var = options.get(passValue)
1218 else
1219 local handler = options.handler or handler
1220 if type(handler[options.get]) ~= "function" then
1221 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options.get)))
1222 end
1223 var = handler[options.get](handler, passValue)
1224 end
1225 end
1226
1227 local usage
1228 local min = options.min or 0
1229 local max = options.max or 1
1230 if options.isPercent then
1231 min, max = min * 100, max * 100
1232 var = tostring(var * 100) .. "%"
1233 end
1234 local bit = "-"
1235 if min < 0 or max < 0 then
1236 bit = " - "
1237 end
1238 usage = ("(%s%s%s)"):format(min, bit, max)
1239 if not quiet then
1240 print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, usage), realOptions.cmdName or realOptions.name or self)
1241 end
1242 print((options.current or IS_CURRENTLY_SET_TO):format(tostring(options.cmdName or options.name), tostring(var or NONE)))
1243 elseif kind == "group" then
1244 local usage
1245 if next(options.args) then
1246 if not order then
1247 order = {}
1248 end
1249 for k,v in pairs(options.args) do
1250 if v.type ~= "header" then
1251 local hidden = v.cmdHidden or v.hidden
1252 if hidden then
1253 if type(hidden) == "function" then
1254 hidden = hidden()
1255 elseif type(hidden) == "string" then
1256 local f = hidden
1257 local neg = f:match("^~(.-)$")
1258 if neg then
1259 f = neg
1260 end
1261 if type(handler[f]) ~= "function" then
1262 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
1263 end
1264 hidden = handler[f](handler)
1265 if neg then
1266 hidden = not hidden
1267 end
1268 end
1269 end
1270 if not hidden then
1271 if filter then
1272 if k:find(filter) then
1273 table.insert(order, k)
1274 elseif type(v.aliases) == "table" then
1275 for _,bit in ipairs(v.aliases) do
1276 if bit:find(filter) then
1277 table.insert(order, k)
1278 break
1279 end
1280 end
1281 elseif type(v.aliases) == "string" then
1282 if v.aliases:find(filter) then
1283 table.insert(order, k)
1284 end
1285 end
1286 else
1287 table.insert(order, k)
1288 end
1289 end
1290 end
1291 end
1292 if not mysort then
1293 mysort = function(a, b)
1294 local alpha, bravo = mysort_args[a], mysort_args[b]
1295 local alpha_order = alpha and alpha.order or 100
1296 local bravo_order = bravo and bravo.order or 100
1297 if alpha_order == bravo_order then
1298 return tostring(a):lower() < tostring(b):lower()
1299 else
1300 if alpha_order < 0 then
1301 if bravo_order > 0 then
1302 return false
1303 end
1304 else
1305 if bravo_order < 0 then
1306 return true
1307 end
1308 end
1309 if alpha_order > 0 and bravo_order > 0 then
1310 return tostring(a):lower() < tostring(b):lower()
1311 end
1312 return alpha_order < bravo_order
1313 end
1314 end
1315 end
1316 mysort_args = options.args
1317 table.sort(order, mysort)
1318 mysort_args = nil
1319 if not quiet then
1320 if options == realOptions then
1321 if options.desc then
1322 print(tostring(options.desc), realOptions.cmdName or realOptions.name or self)
1323 print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}"))
1324 elseif self.description or self.notes then
1325 print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self)
1326 print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}"))
1327 else
1328 print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self)
1329 end
1330 else
1331 if options.desc then
1332 print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self)
1333 print(tostring(options.desc))
1334 else
1335 print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self)
1336 end
1337 end
1338 end
1339 local passTable = options.pass and options or nil
1340 for _,k in ipairs(order) do
1341 local passValue = passTable and k or nil
1342 local real_k = k
1343 local v = options.args[k]
1344 if v then
1345 local v_p = passTable or v
1346 if v.get and v.set then
1347 v_p = v
1348 passValue = nil
1349 end
1350 if v.passValue then
1351 passValue = v.passValue
1352 end
1353 local k = tostring(k):gsub("%s", "-")
1354 local disabled = v.disabled
1355 if disabled then
1356 if type(disabled) == "function" then
1357 disabled = disabled(passValue)
1358 elseif type(disabled) == "string" then
1359 local f = disabled
1360 local neg = f:match("^~(.-)$")
1361 if neg then
1362 f = neg
1363 end
1364 if type(handler[f]) ~= "function" then
1365 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
1366 end
1367 disabled = handler[f](handler, passValue)
1368 if neg then
1369 disabled = not disabled
1370 end
1371 end
1372 end
1373 if type(v.aliases) == "table" then
1374 for _,s in ipairs(v.aliases) do
1375 k = k .. " || " .. s:gsub("%s", "-")
1376 end
1377 elseif type(v.aliases) == "string" then
1378 k = k .. " || " .. v.aliases:gsub("%s", "-")
1379 end
1380 if v_p.get then
1381 local a1,a2,a3,a4
1382 local multiToggle = v_p.type == "text" and v_p.multiToggle
1383 for k in pairs(tmp) do
1384 tmp[k] = nil
1385 end
1386 if type(v_p.get) == "function" then
1387 if multiToggle then
1388 a1 = tmp
1389 for k,v in pairs(v.validate) do
1390 local val = type(k) ~= "number" and k or v
1391 if passValue == nil then
1392 a1[val] = v_p.get(val) or nil
1393 else
1394 a1[val] = v_p.get(passValue, val) or nil
1395 end
1396 end
1397 else
1398 a1,a2,a3,a4 = v_p.get(passValue)
1399 end
1400 else
1401 local handler = v_p.handler or handler
1402 local f = v_p.get
1403 local neg
1404 if v.type == "toggle" then
1405 neg = f:match("^~(.-)$")
1406 if neg then
1407 f = neg
1408 end
1409 end
1410 if type(handler[f]) ~= "function" then
1411 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
1412 end
1413 if multiToggle then
1414 a1 = tmp
1415 for k,v in pairs(v.validate) do
1416 local val = type(k) ~= "number" and k or v
1417 if passValue == nil then
1418 a1[val] = handler[f](handler, val) or nil
1419 else
1420 a1[val] = handler[f](handler, passValue, val) or nil
1421 end
1422 end
1423 else
1424 a1,a2,a3,a4 = handler[f](handler, passValue)
1425 end
1426 if neg then
1427 a1 = not a1
1428 end
1429 end
1430 local s
1431 if v.type == "color" then
1432 if v.hasAlpha then
1433 if not a1 or not a2 or not a3 or not a4 then
1434 s = NONE
1435 else
1436 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)
1437 end
1438 else
1439 if not a1 or not a2 or not a3 then
1440 s = NONE
1441 else
1442 s = ("|cff%02x%02x%02x%02x%02x%02x|r"):format(a1*255, a2*255, a3*255, a1*255, a2*255, a3*255)
1443 end
1444 end
1445 elseif v.type == "toggle" then
1446 if v.map then
1447 s = tostring(v.map[a1 and true or false] or NONE)
1448 else
1449 s = tostring(MAP_ONOFF[a1 and true or false] or NONE)
1450 end
1451 elseif v.type == "range" then
1452 if v.isPercent then
1453 s = tostring(a1 * 100) .. "%"
1454 else
1455 s = tostring(a1)
1456 end
1457 elseif v.type == "text" and type(v.validate) == "table" then
1458 if multiToggle then
1459 if not next(a1) then
1460 s = NONE
1461 else
1462 s = ''
1463 for k in pairs(a1) do
1464 if v.validate[k] then
1465 if s == '' then
1466 s = v.validate[k]
1467 else
1468 s = s .. ', ' .. v.validate[k]
1469 end
1470 else
1471 for _,u in pairs(v.validate) do
1472 if u == k or (type(v) == "string" and type(k) == "string" and v:lower() == k:lower()) then
1473 if s == '' then
1474 s = u
1475 else
1476 s = s .. ', ' .. u
1477 end
1478 break
1479 end
1480 end
1481 end
1482 end
1483 end
1484 else
1485 s = tostring(v.validate[a1] or a1 or NONE)
1486 end
1487 else
1488 s = tostring(a1 or NONE)
1489 end
1490 if disabled then
1491 local s = s:gsub("|cff%x%x%x%x%x%x(.-)|r", "%1")
1492 local desc = (v.desc or NONE):gsub("|cff%x%x%x%x%x%x(.-)|r", "%1")
1493 print(("|cffcfcfcf - %s: [%s] %s|r"):format(k, s, desc))
1494 else
1495 print((" - |cffffff7f%s: [|r%s|cffffff7f]|r %s"):format(k, s, v.desc or NONE))
1496 end
1497 else
1498 if disabled then
1499 local desc = (v.desc or NONE):gsub("|cff%x%x%x%x%x%x(.-)|r", "%1")
1500 print(("|cffcfcfcf - %s: %s"):format(k, desc))
1501 else
1502 print((" - |cffffff7f%s:|r %s"):format(k, v.desc or NONE))
1503 end
1504 end
1505 end
1506 end
1507 for k in pairs(order) do
1508 order[k] = nil
1509 end
1510 else
1511 if options.desc then
1512 print(("|cffffff7f%s:|r %s"):format(USAGE, path), realOptions.cmdName or realOptions.name or self)
1513 print(tostring(options.desc))
1514 elseif options == realOptions and (self.description or self.notes) then
1515 print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self)
1516 print(("|cffffff7f%s:|r %s"):format(USAGE, path))
1517 else
1518 print(("|cffffff7f%s:|r %s"):format(USAGE, path), realOptions.cmdName or realOptions.name or self)
1519 end
1520 print(NO_OPTIONS_AVAILABLE)
1521 end
1522 end
1523 end
1524
1525 local function confirmPopup(message, func, ...)
1526 if not StaticPopupDialogs["ACECONSOLE20_CONFIRM_DIALOG"] then
1527 StaticPopupDialogs["ACECONSOLE20_CONFIRM_DIALOG"] = {}
1528 end
1529 local t = StaticPopupDialogs["ACECONSOLE20_CONFIRM_DIALOG"]
1530 for k in pairs(t) do
1531 t[k] = nil
1532 end
1533 t.text = message
1534 t.button1 = ACCEPT or "Accept"
1535 t.button2 = CANCEL or "Cancel"
1536 t.OnAccept = function()
1537 func(unpack(t))
1538 end
1539 for i = 1, select('#', ...) do
1540 t[i] = select(i, ...)
1541 end
1542 t.timeout = 0
1543 t.whileDead = 1
1544 t.hideOnEscape = 1
1545
1546 StaticPopup_Show("ACECONSOLE20_CONFIRM_DIALOG")
1547 end
1548
1549 local function handlerFunc(self, chat, msg, options)
1550 if not msg then
1551 msg = ""
1552 else
1553 msg = msg:gsub("^%s*(.-)%s*$", "%1")
1554 msg = msg:gsub("%s+", " ")
1555 end
1556
1557 local realOptions = options
1558 local options, path, args, handler, passTable, passValue = findTableLevel(self, options, chat, msg)
1559 if options.type == "execute" then
1560 if options.func then
1561 passTable = nil
1562 end
1563 else
1564 if options.get and options.set then
1565 passTable = nil
1566 end
1567 end
1568 passValue = options.passValue or passTable and passValue
1569
1570 local hidden, disabled = options.cmdHidden or options.hidden, options.disabled
1571 if hidden then
1572 if type(hidden) == "function" then
1573 hidden = hidden(passValue)
1574 elseif type(hidden) == "string" then
1575 local f = hidden
1576 local neg = f:match("^~(.-)$")
1577 if neg then
1578 f = neg
1579 end
1580 if type(handler[f]) ~= "function" then
1581 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
1582 end
1583 hidden = handler[f](handler, passValue)
1584 if neg then
1585 hidden = not hidden
1586 end
1587 end
1588 end
1589 if hidden then
1590 disabled = true
1591 elseif disabled then
1592 if type(disabled) == "function" then
1593 disabled = disabled(passValue)
1594 elseif type(disabled) == "string" then
1595 local f = disabled
1596 local neg = f:match("^~(.-)$")
1597 if neg then
1598 f = neg
1599 end
1600 if type(handler[f]) ~= "function" then
1601 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
1602 end
1603 disabled = handler[f](handler, passValue)
1604 if neg then
1605 disabled = not disabled
1606 end
1607 end
1608 end
1609 local _G_this = this
1610 local kind = (options.type or "group"):lower()
1611 local options_p = passTable or options
1612 if disabled then
1613 print(OPTION_IS_DISABLED:format(path), realOptions.cmdName or realOptions.name or self)
1614 elseif kind == "text" then
1615 if #args > 0 then
1616 if (type(options.validate) == "table" and #args > 1) or (type(options.validate) ~= "table" and not options.input) then
1617 local arg = table.concat(args, " ")
1618 for k,v in pairs(args) do
1619 args[k] = nil
1620 end
1621 args[1] = arg
1622 end
1623 if options.validate then
1624 local good
1625 if type(options.validate) == "function" then
1626 good = options.validate(unpack(args))
1627 elseif type(options.validate) == "table" then
1628 local arg = args[1]
1629 arg = tostring(arg):lower()
1630 for k,v in pairs(options.validate) do
1631 if v:lower() == arg then
1632 args[1] = type(k) == "string" and k or v
1633 good = true
1634 break
1635 end
1636 end
1637 if not good and type((next(options.validate))) == "string" then
1638 for k,v in pairs(options.validate) do
1639 if type(k) == "string" and k:lower() == arg then
1640 args[1] = k
1641 good = true
1642 break
1643 end
1644 end
1645 end
1646 elseif options.validate == "keybinding" then
1647 good = keybindingValidateFunc(unpack(args))
1648 if good ~= false then
1649 args[1] = good
1650 end
1651 else
1652 if type(handler[options.validate]) ~= "function" then
1653 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options.validate)))
1654 end
1655 good = handler[options.validate](handler, unpack(args))
1656 end
1657 if not good then
1658 local usage
1659 if type(options.validate) == "table" then
1660 if not order then
1661 order = {}
1662 end
1663 for k,v in pairs(options.validate) do
1664 table.insert(order, v)
1665 end
1666 usage = "{" .. table.concat(order, " || ") .. "}"
1667 for k in pairs(order) do
1668 order[k] = nil
1669 end
1670 elseif options.validate == "keybinding" then
1671 usage = KEYBINDING_USAGE
1672 else
1673 usage = options.usage or "<value>"
1674 end
1675 print((options.error or IS_NOT_A_VALID_OPTION_FOR):format(tostring(table.concat(args, " ")), path), realOptions.cmdName or realOptions.name or self)
1676 print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, usage))
1677 return
1678 end
1679 end
1680
1681 local var
1682 local multiToggle
1683 for k in pairs(tmp) do
1684 tmp[k] = nil
1685 end
1686 multiToggle = options_p.multiToggle
1687 if not options_p.get then
1688 elseif type(options_p.get) == "function" then
1689 if multiToggle then
1690 var = tmp
1691 for k,v in pairs(options.validate) do
1692 local val = type(k) ~= "number" and k or v
1693 if passValue then
1694 var[val] = options_p.get(passValue, val) or nil
1695 else
1696 var[val] = options_p.get(val) or nil
1697 end
1698 end
1699 else
1700 var = options_p.get(passValue)
1701 end
1702 else
1703 if type(handler[options_p.get]) ~= "function" then
1704 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get)))
1705 end
1706 if multiToggle then
1707 var = tmp
1708 for k,v in pairs(options.validate) do
1709 local val = type(k) ~= "number" and k or v
1710 if passValue then
1711 var[val] = handler[options_p.get](handler, passValue, val) or nil
1712 else
1713 var[val] = handler[options_p.get](handler, val) or nil
1714 end
1715 end
1716 else
1717 var = handler[options_p.get](handler, passValue)
1718 end
1719 end
1720
1721 if multiToggle or var ~= args[1] then
1722 if multiToggle then
1723 local current = var[args[1]]
1724 if current == nil and type(args[1]) == "string" then
1725 for k in pairs(var) do
1726 if type(k) == "string" and k:lower() == args[1]:lower() then
1727 current = true
1728 break
1729 end
1730 end
1731 end
1732 args[2] = not current
1733 end
1734 if type(options_p.set) == "function" then
1735 if passValue then
1736 options_p.set(passValue, unpack(args))
1737 else
1738 options_p.set(unpack(args))
1739 end
1740 else
1741 if type(handler[options_p.set]) ~= "function" then
1742 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.set)))
1743 end
1744 if passValue then
1745 handler[options_p.set](handler, passValue, unpack(args))
1746 else
1747 handler[options_p.set](handler, unpack(args))
1748 end
1749 end
1750 end
1751 end
1752
1753 if #args > 0 then
1754 local var
1755 local multiToggle
1756 for k in pairs(tmp) do
1757 tmp[k] = nil
1758 end
1759 multiToggle = options_p.multiToggle
1760 if not options_p.get then
1761 elseif type(options_p.get) == "function" then
1762 if multiToggle then
1763 var = tmp
1764 for k,v in pairs(options_p.validate) do
1765 local val = type(k) ~= "number" and k or v
1766 if passValue then
1767 var[val] = options_p.get(passValue, val) or nil
1768 else
1769 var[val] = options_p.get(val) or nil
1770 end
1771 end
1772 else
1773 var = options_p.get(passValue)
1774 end
1775 else
1776 if type(handler[options_p.get]) ~= "function" then
1777 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get)))
1778 end
1779 if multiToggle then
1780 var = tmp
1781 for k,v in pairs(options.validate) do
1782 local val = type(k) ~= "number" and k or v
1783 if passValue then
1784 var[val] = handler[options_p.get](handler, passValue, val) or nil
1785 else
1786 var[val] = handler[options_p.get](handler, val) or nil
1787 end
1788 end
1789 else
1790 var = handler[options_p.get](handler, passValue)
1791 end
1792 end
1793 if multiToggle then
1794 if not next(var) then
1795 var = NONE
1796 else
1797 if not order then
1798 order = {}
1799 end
1800 for k in pairs(var) do
1801 if options.validate[k] then
1802 order[#order+1] = options.validate[k]
1803 else
1804 for _,v in pairs(options.validate) do
1805 if v == k or (type(v) == "string" and type(k) == "string" and v:lower() == k:lower()) then
1806 order[#order+1] = v
1807 break
1808 end
1809 end
1810 end
1811 end
1812 table.sort(order, icaseSort)
1813 var = table.concat(order, ", ")
1814 for k in pairs(order) do
1815 order[k] = nil
1816 end
1817 end
1818 elseif type(options.validate) == "table" then
1819 var = options.validate[var] or var
1820 end
1821 if options_p.get then
1822 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)
1823 end
1824 if var == args[1] then
1825 return
1826 end
1827 else
1828 printUsage(self, handler, realOptions, options, path, args, passValue)
1829 return
1830 end
1831 elseif kind == "execute" then
1832 local confirm = options.confirm
1833 if confirm == true then
1834 confirm = DEFAULT_CONFIRM_MESSAGE:format(options.desc or options.name or UNKNOWN or "Unknown")
1835 end
1836 if type(options_p.func) == "function" then
1837 if confirm then
1838 confirmPopup(confirm, options_p.func, passValue)
1839 else
1840 options_p.func(passValue)
1841 end
1842 else
1843 if type(handler[options_p.func]) ~= "function" then
1844 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.func)))
1845 end
1846 if confirm then
1847 confirmPopup(confirm, handler[options_p.func], handler, passValue)
1848 else
1849 handler[options_p.func](handler, passValue)
1850 end
1851 end
1852 elseif kind == "toggle" then
1853 local var
1854 if type(options_p.get) == "function" then
1855 var = options_p.get(passValue)
1856 else
1857 local f = options_p.get
1858 local neg = f:match("^~(.-)$")
1859 if neg then
1860 f = neg
1861 end
1862 if type(handler[f]) ~= "function" then
1863 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
1864 end
1865 var = handler[f](handler, passValue)
1866 if neg then
1867 var = not var
1868 end
1869 end
1870 if type(options_p.set) == "function" then
1871 if passValue then
1872 options_p.set(passValue, not var)
1873 else
1874 options_p.set(not var)
1875 end
1876 else
1877 if type(handler[options_p.set]) ~= "function" then
1878 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.set)))
1879 end
1880 if passValue then
1881 handler[options_p.set](handler, passValue, not var)
1882 else
1883 handler[options_p.set](handler, not var)
1884 end
1885 end
1886 if type(options_p.get) == "function" then
1887 var = options_p.get(passValue)
1888 else
1889 local f = options_p.get
1890 local neg = f:match("^~(.-)$")
1891 if neg then
1892 f = neg
1893 end
1894 var = handler[f](handler, passValue)
1895 if neg then
1896 var = not var
1897 end
1898 end
1899
1900 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)
1901 elseif kind == "range" then
1902 local arg
1903 if #args <= 1 then
1904 arg = args[1]
1905 else
1906 arg = table.concat(args, " ")
1907 end
1908
1909 if arg then
1910 local min = options.min or 0
1911 local max = options.max or 1
1912 local good = false
1913 if type(arg) == "number" then
1914 if options.isPercent then
1915 arg = arg / 100
1916 end
1917
1918 if arg >= min and arg <= max then
1919 good = true
1920 end
1921
1922 if good and type(options.step) == "number" and options.step > 0 then
1923 local step = options.step
1924 arg = math.floor((arg - min) / step + 0.5) * step + min
1925 if arg > max then
1926 arg = max
1927 elseif arg < min then
1928 arg = min
1929 end
1930 end
1931 end
1932 if not good then
1933 local usage
1934 local min = options.min or 0
1935 local max = options.max or 1
1936 if options.isPercent then
1937 min, max = min * 100, max * 100
1938 end
1939 local bit = "-"
1940 if min < 0 or max < 0 then
1941 bit = " - "
1942 end
1943 usage = ("(%s%s%s)"):format(min, bit, max)
1944 print((options.error or IS_NOT_A_VALID_VALUE_FOR):format(tostring(arg), path), realOptions.cmdName or realOptions.name or self)
1945 print(("|cffffff7f%s:|r %s %s"):format(USAGE, path, usage))
1946 return
1947 end
1948
1949 local var
1950 if type(options_p.get) == "function" then
1951 var = options_p.get(passValue)
1952 else
1953 if type(handler[options_p.get]) ~= "function" then
1954 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get)))
1955 end
1956 var = handler[options_p.get](handler, passValue)
1957 end
1958
1959 if var ~= arg then
1960 if type(options_p.set) == "function" then
1961 if passValue then
1962 options_p.set(passValue, arg)
1963 else
1964 options_p.set(arg)
1965 end
1966 else
1967 if type(handler[options_p.set]) ~= "function" then
1968 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.set)))
1969 end
1970 if passValue then
1971 handler[options_p.set](handler, passValue, arg)
1972 else
1973 handler[options_p.set](handler, arg)
1974 end
1975 end
1976 end
1977 end
1978
1979 if arg then
1980 local var
1981 if type(options_p.get) == "function" then
1982 var = options_p.get(passValue)
1983 else
1984 if type(handler[options_p.get]) ~= "function" then
1985 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get)))
1986 end
1987 var = handler[options_p.get](handler, passValue)
1988 end
1989
1990 if var and options.isPercent then
1991 var = tostring(var * 100) .. "%"
1992 end
1993 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)
1994 if var == arg then
1995 return
1996 end
1997 else
1998 printUsage(self, handler, realOptions, options, path, args, passValue)
1999 return
2000 end
2001 elseif kind == "color" then
2002 if #args > 0 then
2003 local r,g,b,a
2004 if #args == 1 then
2005 local arg = tostring(args[1])
2006 if options.hasAlpha then
2007 if arg:len() == 8 and arg:find("^%x*$") then
2008 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
2009 end
2010 else
2011 if arg:len() == 6 and arg:find("^%x*$") then
2012 r,g,b = tonumber(arg:sub(1, 2), 16) / 255, tonumber(arg:sub(3, 4), 16) / 255, tonumber(arg:sub(5, 6), 16) / 255
2013 end
2014 end
2015 elseif #args == 4 and options.hasAlpha then
2016 local a1,a2,a3,a4 = args[1], args[2], args[3], args[4]
2017 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
2018 r,g,b,a = a1,a2,a3,a4
2019 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
2020 r,g,b,a = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255, tonumber(a4, 16) / 255
2021 end
2022 elseif #args == 3 and not options.hasAlpha then
2023 local a1,a2,a3 = args[1], args[2], args[3]
2024 if type(a1) == "number" and type(a2) == "number" and type(a3) == "number" and a1 <= 1 and a2 <= 1 and a3 <= 1 then
2025 r,g,b = a1,a2,a3
2026 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
2027 r,g,b = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255
2028 end
2029 end
2030 if not r then
2031 print((options.error or IS_NOT_A_VALID_OPTION_FOR):format(table.concat(args, ' '), path), realOptions.cmdName or realOptions.name or self)
2032 print(("|cffffff7f%s:|r %s {0-1} {0-1} {0-1}%s"):format(USAGE, path, options.hasAlpha and " {0-1}" or ""))
2033 return
2034 end
2035
2036 if type(options_p.set) == "function" then
2037 if passValue then
2038 options_p.set(passValue, r,g,b,a)
2039 else
2040 options_p.set(r,g,b,a)
2041 end
2042 else
2043 if type(handler[options_p.set]) ~= "function" then
2044 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.set)))
2045 end
2046 if passValue then
2047 handler[options_p.set](handler, passValue, r,g,b,a)
2048 else
2049 handler[options_p.set](handler, r,g,b,a)
2050 end
2051 end
2052
2053 local r,g,b,a
2054 if type(options_p.get) == "function" then
2055 r,g,b,a = options_p.get(passValue)
2056 else
2057 if type(handler[options_p.get]) ~= "function" then
2058 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get)))
2059 end
2060 r,g,b,a = handler[options_p.get](handler, passValue)
2061 end
2062
2063 local s
2064 if type(r) == "number" and type(g) == "number" and type(b) == "number" then
2065 if options.hasAlpha and type(a) == "number" then
2066 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)
2067 else
2068 s = ("|cff%02x%02x%02x%02x%02x%02x|r"):format(r*255, g*255, b*255, r*255, g*255, b*255)
2069 end
2070 else
2071 s = NONE
2072 end
2073 print((options.message or IS_NOW_SET_TO):format(tostring(options.cmdName or options.name), s), realOptions.cmdName or realOptions.name or self)
2074 else
2075 local r,g,b,a
2076 if type(options_p.get) == "function" then
2077 r,g,b,a = options_p.get(passValue)
2078 else
2079 if type(handler[options_p.get]) ~= "function" then
2080 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(options_p.get)))
2081 end
2082 r,g,b,a = handler[options_p.get](handler, passValue)
2083 end
2084
2085 if not colorTable then
2086 colorTable = {}
2087 local t = colorTable
2088
2089 if ColorPickerOkayButton then
2090 local ColorPickerOkayButton_OnClick = ColorPickerOkayButton:GetScript("OnClick")
2091 ColorPickerOkayButton:SetScript("OnClick", function()
2092 if ColorPickerOkayButton_OnClick then
2093 ColorPickerOkayButton_OnClick()
2094 end
2095 if t.active then
2096 ColorPickerFrame.cancelFunc = nil
2097 ColorPickerFrame.func = nil
2098 ColorPickerFrame.opacityFunc = nil
2099 local r,g,b,a
2100 if t.passValue then
2101 if type(t.get) == "function" then
2102 r,g,b,a = t.get(t.passValue)
2103 else
2104 if type(t.handler[t.get]) ~= "function" then
2105 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.get)))
2106 end
2107 r,g,b,a = t.handler[t.get](t.handler, t.passValue)
2108 end
2109 else
2110 if type(t.get) == "function" then
2111 r,g,b,a = t.get()
2112 else
2113 if type(t.handler[t.get]) ~= "function" then
2114 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.get)))
2115 end
2116 r,g,b,a = t.handler[t.get](t.handler)
2117 end
2118 end
2119 if r ~= t.r or g ~= t.g or b ~= t.b or (t.hasAlpha and a ~= t.a) then
2120 local s
2121 if type(r) == "number" and type(g) == "number" and type(b) == "number" then
2122 if t.hasAlpha and type(a) == "number" then
2123 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)
2124 else
2125 s = ("|cff%02x%02x%02x%02x%02x%02x|r"):format(r*255, g*255, b*255, r*255, g*255, b*255)
2126 end
2127 else
2128 s = NONE
2129 end
2130 print(t.message:format(tostring(t.name), s), t.realOptions.cmdName or t.realOptions.name or self)
2131 end
2132 for k,v in pairs(t) do
2133 t[k] = nil
2134 end
2135 end
2136 end)
2137 end
2138 else
2139 for k,v in pairs(colorTable) do
2140 colorTable[k] = nil
2141 end
2142 end
2143
2144 if type(r) ~= "number" or type(g) ~= "number" or type(b) ~= "number" then
2145 r,g,b = 1, 1, 1
2146 end
2147 if type(a) ~= "number" then
2148 a = 1
2149 end
2150 local t = colorTable
2151 t.r = r
2152 t.g = g
2153 t.b = b
2154 if hasAlpha then
2155 t.a = a
2156 end
2157 t.realOptions = realOptions
2158 t.hasAlpha = options.hasAlpha
2159 t.handler = handler
2160 t.set = options_p.set
2161 t.get = options_p.get
2162 t.name = options.cmdName or options.name
2163 t.message = options.message or IS_NOW_SET_TO
2164 t.passValue = passValue
2165 t.active = true
2166
2167 if not colorFunc then
2168 colorFunc = function()
2169 local r,g,b = ColorPickerFrame:GetColorRGB()
2170 if t.hasAlpha then
2171 local a = 1 - OpacitySliderFrame:GetValue()
2172 if type(t.set) == "function" then
2173 if t.passValue then
2174 t.set(t.passValue, r,g,b,a)
2175 else
2176 t.set(r,g,b,a)
2177 end
2178 else
2179 if type(t.handler[t.set]) ~= "function" then
2180 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.set)))
2181 end
2182 if t.passValue then
2183 t.handler[t.set](t.handler, t.passValue, r,g,b,a)
2184 else
2185 t.handler[t.set](t.handler, r,g,b,a)
2186 end
2187 end
2188 else
2189 if type(t.set) == "function" then
2190 if t.passValue then
2191 t.set(t.passValue, r,g,b)
2192 else
2193 t.set(r,g,b)
2194 end
2195 else
2196 if type(t.handler[t.set]) ~= "function" then
2197 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.set)))
2198 end
2199 if t.passValue then
2200 t.handler[t.set](t.handler, t.passValue, r,g,b)
2201 else
2202 t.handler[t.set](t.handler, r,g,b)
2203 end
2204 end
2205 end
2206 end
2207 end
2208
2209 ColorPickerFrame.func = colorFunc
2210 ColorPickerFrame.hasOpacity = options.hasAlpha
2211 if options.hasAlpha then
2212 ColorPickerFrame.opacityFunc = ColorPickerFrame.func
2213 ColorPickerFrame.opacity = 1 - a
2214 end
2215 ColorPickerFrame:SetColorRGB(r,g,b)
2216
2217 if not colorCancelFunc then
2218 colorCancelFunc = function()
2219 if t.hasAlpha then
2220 if type(t.set) == "function" then
2221 if t.passValue then
2222 t.set(t.passValue, t.r,t.g,t.b,t.a)
2223 else
2224 t.set(t.r,t.g,t.b,t.a)
2225 end
2226 else
2227 if type(t.handler[t.get]) ~= "function" then
2228 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.get)))
2229 end
2230 if t.passValue then
2231 t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b,t.a)
2232 else
2233 t.handler[t.set](t.handler, t.r,t.g,t.b,t.a)
2234 end
2235 end
2236 else
2237 if type(t.set) == "function" then
2238 if t.passValue then
2239 t.set(t.passValue, t.r,t.g,t.b)
2240 else
2241 t.set(t.r,t.g,t.b)
2242 end
2243 else
2244 if type(t.handler[t.set]) ~= "function" then
2245 AceConsole:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(t.set)))
2246 end
2247 if t.passValue then
2248 t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b)
2249 else
2250 t.handler[t.set](t.handler, t.r,t.g,t.b)
2251 end
2252 end
2253 end
2254 for k,v in pairs(t) do
2255 t[k] = nil
2256 end
2257 ColorPickerFrame.cancelFunc = nil
2258 ColorPickerFrame.func = nil
2259 ColorPickerFrame.opacityFunc = nil
2260 end
2261 end
2262
2263 ColorPickerFrame.cancelFunc = colorCancelFunc
2264
2265 ShowUIPanel(ColorPickerFrame)
2266 end
2267 return
2268 elseif kind == "group" then
2269 if #args == 0 then
2270 printUsage(self, handler, realOptions, options, path, args, passValue)
2271 else
2272 -- invalid argument
2273 print((options.error or IS_NOT_A_VALID_OPTION_FOR):format(args[1], path), realOptions.cmdName or realOptions.name or self)
2274 end
2275 return
2276 end
2277 this = _G_this
2278 if Dewdrop then
2279 Dewdrop:Refresh()
2280 end
2281 end
2282
2283 local external
2284 local tmp
2285 function AceConsole:RegisterChatCommand(...) -- slashCommands, options, name
2286 local slashCommands, options, name
2287 if type((...)) == "string" then
2288 if not tmp then
2289 tmp = {}
2290 else
2291 for i in ipairs(tmp) do
2292 tmp[i] = nil
2293 end
2294 end
2295 for i = 1, select('#', ...)+1 do
2296 local v = select(i, ...)
2297 if type(v) == "string" then
2298 tmp[#tmp+1] = v
2299 else
2300 slashCommands = tmp
2301 options = v
2302 name = select(i+1, ...)
2303 break
2304 end
2305 end
2306 else
2307 slashCommands, options, name = ...
2308 end
2309 if type(slashCommands) ~= "table" and slashCommands ~= false then
2310 AceConsole:error("Bad argument #2 to `RegisterChatCommand' (expected table, got %s)", type(slashCommands))
2311 end
2312 if not slashCommands and type(name) ~= "string" then
2313 AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string, got %s)", type(name))
2314 end
2315 if type(options) ~= "table" and type(options) ~= "function" and options ~= nil then
2316 AceConsole:error("Bad argument #3 to `RegisterChatCommand' (expected table, function, or nil, got %s)", type(options))
2317 end
2318 if name then
2319 if type(name) ~= "string" then
2320 AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string or nil, got %s)", type(name))
2321 elseif not name:find("^%w+$") or name:upper() ~= name or name:len() == 0 then
2322 AceConsole:error("Argument #4 must be an uppercase, letters-only string with at least 1 character")
2323 end
2324 end
2325 if slashCommands then
2326 if #slashCommands == 0 then
2327 AceConsole:error("Argument #2 to `RegisterChatCommand' must include at least one string")
2328 end
2329
2330 for k,v in pairs(slashCommands) do
2331 if type(k) ~= "number" then
2332 AceConsole:error("All keys in argument #2 to `RegisterChatCommand' must be numbers")
2333 end
2334 if type(v) ~= "string" then
2335 AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be strings")
2336 elseif not v:find("^/[A-Za-z][A-Za-z0-9_]*$") then
2337 AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be in the form of \"/word\"")
2338 end
2339 end
2340 end
2341
2342 if not options then
2343 options = {
2344 type = 'group',
2345 args = {},
2346 handler = self
2347 }
2348 end
2349
2350 if type(options) == "table" then
2351 local err, position = validateOptions(options)
2352 if err then
2353 if position then
2354 AceConsole:error(position .. ": " .. err)
2355 else
2356 AceConsole:error(err)
2357 end
2358 end
2359
2360 if not options.handler then
2361 options.handler = self
2362 end
2363
2364 if options.handler == self and options.type:lower() == "group" and self.class then
2365 AceConsole:InjectAceOptionsTable(self, options)
2366 end
2367 end
2368
2369 local chat
2370 if slashCommands then
2371 chat = slashCommands[1]
2372 else
2373 chat = _G["SLASH_"..name..1]
2374 end
2375
2376 local handler
2377 if type(options) == "function" then
2378 handler = options
2379 for k,v in pairs(_G) do
2380 if handler == v then
2381 local k = k
2382 handler = function(msg)
2383 return _G[k](msg)
2384 end
2385 end
2386 end
2387 else
2388 function handler(msg)
2389 handlerFunc(self, chat, msg, options)
2390 end
2391 end
2392
2393 if not _G.SlashCmdList then
2394 _G.SlashCmdList = {}
2395 end
2396
2397 if not name and type(slashCommands) == "table" and type(slashCommands[1]) == "string" then
2398 name = slashCommands[1]:gsub("%A", ""):upper()
2399 end
2400
2401 if not name then
2402 local A = ('A'):byte()
2403 repeat
2404 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)
2405 until not _G.SlashCmdList[name]
2406 end
2407
2408 if slashCommands then
2409 if _G.SlashCmdList[name] then
2410 local i = 0
2411 while true do
2412 i = i + 1
2413 if _G["SLASH_"..name..i] then
2414 _G["SLASH_"..name..i] = nil
2415 else
2416 break
2417 end
2418 end
2419 end
2420
2421 local i = 0
2422 for _,command in ipairs(slashCommands) do
2423 i = i + 1
2424 _G["SLASH_"..name..i] = command
2425 if command:lower() ~= command then
2426 i = i + 1
2427 _G["SLASH_"..name..i] = command:lower()
2428 end
2429 end
2430 end
2431 _G.SlashCmdList[name] = handler
2432 if self ~= AceConsole and self.slashCommand == nil then
2433 self.slashCommand = chat
2434 end
2435
2436 if not AceEvent and AceLibrary:HasInstance("AceEvent-2.0") then
2437 external(AceConsole, "AceEvent-2.0", AceLibrary("AceEvent-2.0"))
2438 end
2439 if AceEvent then
2440 if not AceConsole.nextAddon then
2441 AceConsole.nextAddon = {}
2442 end
2443 if type(options) == "table" then
2444 AceConsole.nextAddon[self] = options
2445 if not self.playerLogin then
2446 AceConsole:RegisterEvent("PLAYER_LOGIN", "PLAYER_LOGIN", true)
2447 end
2448 end
2449 end
2450
2451 AceConsole.registry[name] = options
2452
2453 if slashCommands == tmp then
2454 for i in ipairs(tmp) do
2455 tmp[i] = nil
2456 end
2457 end
2458 end
2459
2460 function AceConsole:InjectAceOptionsTable(handler, options)
2461 self:argCheck(handler, 2, "table")
2462 self:argCheck(options, 3, "table")
2463 if options.type:lower() ~= "group" then
2464 self:error('Cannot inject into options table argument #3 if its type is not "group"')
2465 end
2466 if options.handler ~= nil and options.handler ~= handler then
2467 self:error("Cannot inject into options table argument #3 if it has a different handler than argument #2")
2468 end
2469 options.handler = handler
2470 local class = handler.class
2471 if not AceLibrary:HasInstance("AceOO-2.0") or not class then
2472 if Rock then
2473 -- possible Rock object
2474 for mixin in Rock:IterateObjectMixins(handler) do
2475 if type(mixin.GetAceOptionsDataTable) == "function" then
2476 local t = mixin:GetAceOptionsDataTable(handler)
2477 for k,v in pairs(t) do
2478 if type(options.args) ~= "table" then
2479 options.args = {}
2480 end
2481 if options.args[k] == nil then
2482 options.args[k] = v
2483 end
2484 end
2485 end
2486 end
2487 end
2488 else
2489 -- Ace2 object
2490 while class and class ~= AceLibrary("AceOO-2.0").Class do
2491 if type(class.GetAceOptionsDataTable) == "function" then
2492 local t = class:GetAceOptionsDataTable(handler)
2493 for k,v in pairs(t) do
2494 if type(options.args) ~= "table" then
2495 options.args = {}
2496 end
2497 if options.args[k] == nil then
2498 options.args[k] = v
2499 end
2500 end
2501 end
2502 local mixins = class.mixins
2503 if mixins then
2504 for mixin in pairs(mixins) do
2505 if type(mixin.GetAceOptionsDataTable) == "function" then
2506 local t = mixin:GetAceOptionsDataTable(handler)
2507 for k,v in pairs(t) do
2508 if type(options.args) ~= "table" then
2509 options.args = {}
2510 end
2511 if options.args[k] == nil then
2512 options.args[k] = v
2513 end
2514 end
2515 end
2516 end
2517 end
2518 class = class.super
2519 end
2520 end
2521
2522 return options
2523 end
2524
2525 function AceConsole:PLAYER_LOGIN()
2526 self.playerLogin = true
2527 for addon, options in pairs(self.nextAddon) do
2528 local err, position = validateOptionsMethods(addon, options)
2529 if err then
2530 if position then
2531 geterrorhandler()(tostring(addon) .. ": AceConsole: " .. position .. ": " .. err)
2532 else
2533 geterrorhandler()(tostring(addon) .. ": AceConsole: " .. err)
2534 end
2535 end
2536 self.nextAddon[addon] = nil
2537 end
2538 end
2539
2540 function AceConsole:TabCompleteInfo(cmdpath)
2541 local cmd = cmdpath:match("(/%S+)")
2542 if not cmd then
2543 return
2544 end
2545 local path = cmdpath:sub(cmd:len() + 2)
2546 for name in pairs(SlashCmdList) do --global
2547 if AceConsole.registry[name] then
2548 local i = 0
2549 while true do
2550 i = i + 1
2551 local scmd = _G["SLASH_"..name..i]
2552 if not scmd then break end
2553 if cmd == scmd then
2554 return name, cmd, path
2555 end
2556 end
2557 end
2558 end
2559 end
2560
2561 function external(self, major, instance)
2562 if major == "AceEvent-2.0" then
2563 if not AceEvent then
2564 AceEvent = instance
2565
2566 AceEvent:embed(self)
2567 end
2568 elseif major == "AceTab-2.0" then
2569 instance:RegisterTabCompletion("AceConsole", "%/.*", function(t, cmdpath, pos)
2570 local name, cmd, path = self:TabCompleteInfo(cmdpath:sub(1, pos))
2571
2572 if not self.registry[name] then
2573 return false
2574 else
2575 local validArgs, _, _, handler = findTableLevel(self, self.registry[name], cmd, path or "")
2576 if validArgs.args then
2577 for arg, v in pairs(validArgs.args) do
2578 local hidden = v.hidden
2579 local handler = v.handler or handler
2580 if hidden then
2581 if type(hidden) == "function" then
2582 hidden = hidden(v.passValue)
2583 elseif type(hidden) == "string" then
2584 local f = hidden
2585 local neg = f:match("^~(.-)$")
2586 if neg then
2587 f = neg
2588 end
2589 if type(handler[f]) ~= "function" then
2590 self:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
2591 end
2592 hidden = handler[f](handler, v.passValue)
2593 if neg then
2594 hidden = not hidden
2595 end
2596 end
2597 end
2598 local disabled = hidden or v.disabled
2599 if disabled then
2600 if type(disabled) == "function" then
2601 disabled = disabled(v.passValue)
2602 elseif type(disabled) == "string" then
2603 local f = disabled
2604 local neg = f:match("^~(.-)$")
2605 if neg then
2606 f = neg
2607 end
2608 if type(handler[f]) ~= "function" then
2609 self:error("%s: %s", handler, OPTION_HANDLER_NOT_FOUND:format(tostring(f)))
2610 end
2611 disabled = handler[f](handler, v.passValue)
2612 if neg then
2613 disabled = not disabled
2614 end
2615 end
2616 end
2617 if not hidden and not disabled and v.type ~= "header" then
2618 table.insert(t, (tostring(arg):gsub("%s", "-")))
2619 end
2620 end
2621 end
2622 end
2623 end, function(u, matches, gcs, cmdpath)
2624 local name, cmd, path = self:TabCompleteInfo(cmdpath)
2625 if self.registry[name] then
2626 local validArgs, path2, argwork, handler = findTableLevel(self, self.registry[name], cmd, path)
2627 printUsage(self, validArgs.handler or handler, self.registry[name], validArgs, path2, argwork, argwork[#argwork], not gcs or gcs ~= "", gcs)
2628 end
2629 end)
2630 elseif major == "Dewdrop-2.0" then
2631 Dewdrop = instance
2632 end
2633 end
2634
2635 local function activate(self, oldLib, oldDeactivate)
2636 AceConsole = self
2637
2638 if oldLib then
2639 self.registry = oldLib.registry
2640 self.nextAddon = oldLib.nextAddon
2641 end
2642
2643 if not self.registry then
2644 self.registry = {}
2645 else
2646 for name,options in pairs(self.registry) do
2647 self:RegisterChatCommand(false, options, name)
2648 end
2649 end
2650
2651 self:RegisterChatCommand("/reload", "/rl", "/reloadui", ReloadUI, "RELOAD")
2652 self:RegisterChatCommand("/gm", ToggleHelpFrame, "GM")
2653 local t = { "/print", "/echo" }
2654 local _,_,_,enabled,loadable = GetAddOnInfo("DevTools")
2655 if not enabled and not loadable then
2656 table.insert(t, "/dump")
2657 end
2658 self:RegisterChatCommand(t, function(text)
2659 text = text:trim():match("^(.-);*$")
2660 local f, err = loadstring("AceLibrary('AceConsole-2.0'):PrintLiteral(" .. text .. ")")
2661 if not f then
2662 self:Print("|cffff0000Error:|r", err)
2663 else
2664 f()
2665 end
2666 end, "PRINT")
2667
2668 self:activate(oldLib, oldDeactivate)
2669
2670 if oldDeactivate then
2671 oldDeactivate(oldLib)
2672 end
2673 end
2674
2675 AceLibrary:Register(AceConsole, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)