comparison libs/AceConsole-2.0/AceConsole-2.0.lua @ 1:c11ca1d8ed91

Version 0.1
author Flick <flickerstreak@gmail.com>
date Tue, 20 Mar 2007 21:03:57 +0000
parents
children
comparison
equal deleted inserted replaced
0:4e2ce2894c21 1:c11ca1d8ed91
1 --[[
2 Name: AceConsole-2.0
3 Revision: $Rev: 19865 $
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/root/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://wiki.wowace.com/index.php/AceOptions_data_table
12 Dependencies: AceLibrary, AceOO-2.0
13 ]]
14
15 local MAJOR_VERSION = "AceConsole-2.0"
16 local MINOR_VERSION = "$Revision: 19865 $"
17
18 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
19 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
20
21 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0.") end
22
23 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
24 if GetLocale() == "deDE" then
25 MAP_ONOFF = { [false] = "|cffff0000Aus|r", [true] = "|cff00ff00An|r" }
26 USAGE = "Benutzung"
27 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r steht momentan auf |cffffff7f[|r%s|cffffff7f]|r"
28 IS_NOW_SET_TO = "|cffffff7f%s|r ist nun auf |cffffff7f[|r%s|cffffff7f]|r gesetzt"
29 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] ist keine g\195\188ltige Option f\195\188r |cffffff7f%s|r"
30 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] ist kein g\195\188ltiger Wert f\195\188r |cffffff7f%s|r"
31 NO_OPTIONS_AVAILABLE = "Keine Optionen verfügbar"
32 OPTION_HANDLER_NOT_FOUND = "Optionen handler |cffffff7f%q|r nicht gefunden."
33 OPTION_HANDLER_NOT_VALID = "Optionen handler nicht g\195\188ltig."
34 OPTION_IS_DISABLED = "Option |cffffff7f%s|r deaktiviert."
35 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix
36 elseif GetLocale() == "frFR" then
37 MAP_ONOFF = { [false] = "|cffff0000Inactif|r", [true] = "|cff00ff00Actif|r" }
38 USAGE = "Utilisation"
39 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r est actuellement positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r"
40 IS_NOW_SET_TO = "|cffffff7f%s|r est maintenant positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r"
41 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] n'est pas une option valide pour |cffffff7f%s|r"
42 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] n'est pas une valeur valide pour |cffffff7f%s|r"
43 NO_OPTIONS_AVAILABLE = "Pas d'options disponibles"
44 OPTION_HANDLER_NOT_FOUND = "Le gestionnaire d'option |cffffff7f%q|r n'a pas \195\169t\195\169 trouv\195\169."
45 OPTION_HANDLER_NOT_VALID = "Le gestionnaire d'option n'est pas valide."
46 OPTION_IS_DISABLED = "L'option |cffffff7f%s|r est d\195\169sactiv\195\169e."
47 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix
48 elseif GetLocale() == "koKR" then
49 MAP_ONOFF = { [false] = "|cffff0000끔|r", [true] = "|cff00ff00켬|r" }
50 USAGE = "사용법"
51 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r|1은;는; 현재 상태는 |cffffff7f[|r%s|cffffff7f]|r|1으로;로; 설정되어 있습니다"
52 IS_NOW_SET_TO = "|cffffff7f%s|r|1을;를; |cffffff7f[|r%s|cffffff7f]|r 상태로 변경합니다"
53 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r]|1은;는; |cffffff7f%s|r에서 사용불가능한 설정입니다"
54 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r]|1은;는; |cffffff7f%s|r에서 사용불가능한 설정값입니다"
55 NO_OPTIONS_AVAILABLE = "가능한 설정이 없습니다"
56 OPTION_HANDLER_NOT_FOUND = "설정 조정값인 |cffffff7f%q|r|1을;를; 찾지 못했습니다."
57 OPTION_HANDLER_NOT_VALID = "설정 조정값이 올바르지 않습니다."
58 OPTION_IS_DISABLED = "|cffffff7f%s|r 설정은 사용할 수 없습니다."
59 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix
60 elseif GetLocale() == "zhCN" then
61 MAP_ONOFF = { [false] = "|cffff0000\229\133\179\233\151\173|r", [true] = "|cff00ff00\229\188\128\229\144\175|r" }
62 USAGE = "\231\148\168\230\179\149"
63 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"
64 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"
65 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"
66 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"
67 NO_OPTIONS_AVAILABLE = "\230\178\161\230\156\137\233\128\137\233\161\185\229\143\175\231\148\168"
68 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."
69 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."
70 OPTION_IS_DISABLED = "\233\128\137\233\161\185 |cffffff7f%s|r \228\184\141\229\174\140\230\149\180."
71 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix
72 elseif GetLocale() == "zhTW" then
73 MAP_ONOFF = { [false] = "|cffff0000關閉|r", [true] = "|cff00ff00開啟|r" }
74 USAGE = "用法"
75 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r 目前的設定為 |cffffff7f[|r%s|cffffff7f]|r"
76 IS_NOW_SET_TO = "|cffffff7f%s|r 現在被設定為 |cffffff7f[|r%s|cffffff7f]|r"
77 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] 是一個不符合規定的選項,對 |cffffff7f%s|r"
78 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] 是一個不符合規定的數值,對 |cffffff7f%s|r"
79 NO_OPTIONS_AVAILABLE = "沒有可用的選項處理器。"
80 OPTION_HANDLER_NOT_FOUND = "找不到 |cffffff7f%q|r 選項處理器。"
81 OPTION_HANDLER_NOT_VALID = "選項處理器不符合規定。"
82 OPTION_IS_DISABLED = "|cffffff7f%s|r 已被停用。"
83 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix
84 else -- enUS
85 MAP_ONOFF = { [false] = "|cffff0000Off|r", [true] = "|cff00ff00On|r" }
86 USAGE = "Usage"
87 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r is currently set to |cffffff7f[|r%s|cffffff7f]|r"
88 IS_NOW_SET_TO = "|cffffff7f%s|r is now set to |cffffff7f[|r%s|cffffff7f]|r"
89 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] is not a valid option for |cffffff7f%s|r"
90 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] is not a valid value for |cffffff7f%s|r"
91 NO_OPTIONS_AVAILABLE = "No options available"
92 OPTION_HANDLER_NOT_FOUND = "Option handler |cffffff7f%q|r not found."
93 OPTION_HANDLER_NOT_VALID = "Option handler not valid."
94 OPTION_IS_DISABLED = "Option |cffffff7f%s|r is disabled."
95 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>"
96 end
97
98 local NONE = NONE or "None"
99
100 local AceOO = AceLibrary("AceOO-2.0")
101 local AceEvent
102
103 local AceConsole = AceOO.Mixin { "Print", "PrintComma", "CustomPrint", "RegisterChatCommand" }
104 local Dewdrop
105
106 local _G = getfenv(0)
107
108 local function print(text, name, r, g, b, frame, delay)
109 if not text or text:len() == 0 then
110 text = " "
111 end
112 if not name or name == AceConsole then
113 (frame or DEFAULT_CHAT_FRAME):AddMessage(text, r, g, b, nil, delay or 5)
114 else
115 (frame or DEFAULT_CHAT_FRAME):AddMessage("|cffffff78" .. tostring(name) .. ":|r " .. text, r, g, b, nil, delay or 5)
116 end
117 end
118
119 local real_tostring = tostring
120
121 local function tostring(t)
122 if type(t) == "table" then
123 if type(rawget(t, 0)) == "userdata" and type(t.GetObjectType) == "function" then
124 return string.format("<%s:%s>", t:GetObjectType(), t:GetName() or "(anon)")
125 end
126 end
127 return real_tostring(t)
128 end
129
130 local function _tostring(...)
131 if select('#', ...) < 1 then
132 return
133 end
134 return tostring((...)), _tostring(select(2, ...))
135 end
136 function AceConsole:CustomPrint(r, g, b, frame, delay, connector, a1, ...)
137 if tostring(a1):find("%%") and select('#', ...) >= 1 then
138 local success, text = pcall(string.format, _tostring(a1, ...))
139 if success then
140 print(text, self, r, g, b, frame or self.printFrame, delay)
141 return
142 end
143 end
144 print((connector or " "):join(_tostring(a1, ...)), self, r, g, b, frame or self.printFrame, delay)
145 end
146
147 function AceConsole:Print(...)
148 return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, " ", ...)
149 end
150
151 function AceConsole:PrintComma(...)
152 return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, ", ", ...)
153 end
154
155 local work
156 local argwork
157
158 local function findTableLevel(self, options, chat, text, index, passTable)
159 if not index then
160 index = 1
161 if work then
162 for k,v in pairs(work) do
163 work[k] = nil
164 end
165 for k,v in pairs(argwork) do
166 argwork[k] = nil
167 end
168 else
169 work = {}
170 argwork = {}
171 end
172 local len = text:len()
173 local count
174 repeat
175 text, count = text:gsub("(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[[^%]]-) (.-%]|h|r)", "%1\001%2")
176 until count == 0
177 text = text:gsub("(%]|h|r)(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[)", "%1 %2")
178 for token in text:gmatch("([^%s]+)") do
179 local token = token
180 local num = tonumber(token)
181 if num then
182 token = num
183 else
184 token = token:gsub("\001", " ")
185 end
186 table.insert(work, token)
187 end
188 end
189
190 local path = chat
191 for i = 1, index - 1 do
192 path = path .. " " .. tostring(work[i])
193 end
194
195 if type(options.args) == "table" then
196 local disabled, hidden = options.disabled, options.cmdHidden or options.hidden
197 if hidden then
198 if type(hidden) == "function" then
199 hidden = hidden()
200 elseif type(hidden) == "string" then
201 local handler = options.handler or self
202 local f = hidden
203 local neg = f:match("^~(.-)$")
204 if neg then
205 f = neg
206 end
207 if type(handler[f]) ~= "function" then
208 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
209 end
210 hidden = handler[f](handler)
211 if neg then
212 hidden = not hidden
213 end
214 end
215 end
216 if hidden then
217 disabled = true
218 elseif disabled then
219 if type(disabled) == "function" then
220 disabled = disabled()
221 elseif type(disabled) == "string" then
222 local handler = options.handler or self
223 local f = disabled
224 local neg = f:match("^~(.-)$")
225 if neg then
226 f = neg
227 end
228 if type(handler[f]) ~= "function" then
229 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
230 end
231 disabled = handler[f](handler)
232 if neg then
233 disabled = not disabled
234 end
235 end
236 end
237 if not disabled then
238 local next = work[index] and work[index]:lower()
239 if next then
240 for k,v in pairs(options.args) do
241 local good = false
242 if k:lower() == next then
243 good = true
244 elseif type(v.aliases) == "table" then
245 for _,alias in ipairs(v.aliases) do
246 if alias:lower() == next then
247 good = true
248 break
249 end
250 end
251 elseif type(v.aliases) == "string" and v.aliases:lower() == next then
252 good = true
253 end
254 if good then
255 return findTableLevel(options.handler or self, v, chat, text, index + 1, options.pass and options or nil)
256 end
257 end
258 end
259 end
260 end
261 for i = index, #work do
262 table.insert(argwork, work[i])
263 end
264 return options, path, argwork, options.handler or self, passTable, passTable and work[index - 1]
265 end
266
267 local function validateOptionsMethods(self, options, position)
268 if type(options) ~= "table" then
269 return "Options must be a table.", position
270 end
271 self = options.handler or self
272 if options.type == "execute" then
273 if options.func and type(options.func) ~= "string" and type(options.func) ~= "function" then
274 return "func must be a string or function", position
275 end
276 if options.func and type(options.func) == "string" and type(self[options.func]) ~= "function" then
277 return string.format("%q is not a proper function", options.func), position
278 end
279 else
280 if options.get then
281 if type(options.get) ~= "string" and type(options.get) ~= "function" then
282 return "get must be a string or function", position
283 end
284 if type(options.get) == "string" then
285 local f = options.get
286 if options.type == "toggle" then
287 f = f:match("^~(.-)$") or f
288 end
289 if type(self[f]) ~= "function" then
290 return string.format("%q is not a proper function", f), position
291 end
292 end
293 end
294 if options.set then
295 if type(options.set) ~= "string" and type(options.set) ~= "function" then
296 return "set must be a string or function", position
297 end
298 if type(options.set) == "string" and type(self[options.set]) ~= "function" then
299 return string.format("%q is not a proper function", options.set), position
300 end
301 end
302 if options.validate and type(options.validate) ~= "table" and options.validate ~= "keybinding" then
303 if type(options.validate) ~= "string" and type(options.validate) ~= "function" then
304 return "validate must be a string or function", position
305 end
306 if type(options.validate) == "string" and type(self[options.validate]) ~= "function" then
307 return string.format("%q is not a proper function", options.validate), position
308 end
309 end
310 end
311 if options.disabled and type(options.disabled) == "string" then
312 local f = options.disabled
313 f = f:match("^~(.-)$") or f
314 if type(self[f]) ~= "function" then
315 return string.format("%q is not a proper function", f), position
316 end
317 end
318 if options.cmdHidden and type(options.cmdHidden) == "string" then
319 local f = options.cmdHidden
320 f = f:match("^~(.-)$") or f
321 if type(self[f]) ~= "function" then
322 return string.format("%q is not a proper function", f), position
323 end
324 end
325 if options.guiHidden and type(options.guiHidden) == "string" then
326 local f = options.guiHidden
327 f = f:match("^~(.-)$") or f
328 if type(self[f]) ~= "function" then
329 return string.format("%q is not a proper function", f), position
330 end
331 end
332 if options.hidden and type(options.hidden) == "string" then
333 local f = options.hidden
334 f = f:match("^~(.-)$") or f
335 if type(self[f]) ~= "function" then
336 return string.format("%q is not a proper function", f), position
337 end
338 end
339 if options.type == "group" and type(options.args) == "table" then
340 for k,v in pairs(options.args) do
341 if type(v) == "table" then
342 local newposition
343 if position then
344 newposition = position .. ".args." .. k
345 else
346 newposition = "args." .. k
347 end
348 local err, pos = validateOptionsMethods(self, v, newposition)
349 if err then
350 return err, pos
351 end
352 end
353 end
354 end
355 end
356
357 local function validateOptions(options, position, baseOptions, fromPass)
358 if not baseOptions then
359 baseOptions = options
360 end
361 if type(options) ~= "table" then
362 return "Options must be a table.", position
363 end
364 local kind = options.type
365 if type(kind) ~= "string" then
366 return '"type" must be a string.', position
367 elseif kind ~= "group" and kind ~= "range" and kind ~= "text" and kind ~= "execute" and kind ~= "toggle" and kind ~= "color" and kind ~= "header" then
368 return '"type" must either be "range", "text", "group", "toggle", "execute", "color", or "header".', position
369 end
370 if options.aliases then
371 if type(options.aliases) ~= "table" and type(options.aliases) ~= "string" then
372 return '"alias" must be a table or string', position
373 end
374 end
375 if not fromPass then
376 if kind == "execute" then
377 if type(options.func) ~= "string" and type(options.func) ~= "function" then
378 return '"func" must be a string or function', position
379 end
380 elseif kind == "range" or kind == "text" or kind == "toggle" then
381 if type(options.set) ~= "string" and type(options.set) ~= "function" then
382 return '"set" must be a string or function', position
383 end
384 if kind == "text" and options.get == false then
385 elseif type(options.get) ~= "string" and type(options.get) ~= "function" then
386 return '"get" must be a string or function', position
387 end
388 elseif kind == "group" and options.pass then
389 if options.pass ~= true then
390 return '"pass" must be either nil, true, or false', position
391 end
392 if not options.func then
393 if type(options.set) ~= "string" and type(options.set) ~= "function" then
394 return '"set" must be a string or function', position
395 end
396 if type(options.get) ~= "string" and type(options.get) ~= "function" then
397 return '"get" must be a string or function', position
398 end
399 elseif type(options.func) ~= "string" and type(options.func) ~= "function" then
400 return '"func" must be a string or function', position
401 end
402 end
403 else
404 if kind == "group" then
405 return 'cannot have "type" = "group" as a subgroup of a passing group', position
406 end
407 end
408 if options ~= baseOptions then
409 if kind == "header" then
410 elseif type(options.desc) ~= "string" then
411 return '"desc" must be a string', position
412 elseif options.desc:len() == 0 then
413 return '"desc" cannot be a 0-length string', position
414 end
415 end
416
417 if options ~= baseOptions or kind == "range" or kind == "text" or kind == "toggle" or kind == "color" then
418 if options.type == "header" and not options.cmdName and not options.name then
419 elseif options.cmdName then
420 if type(options.cmdName) ~= "string" then
421 return '"cmdName" must be a string or nil', position
422 elseif options.cmdName:len() == 0 then
423 return '"cmdName" cannot be a 0-length string', position
424 end
425 if type(options.guiName) ~= "string" then
426 if not options.guiNameIsMap then
427 return '"guiName" must be a string or nil', position
428 end
429 elseif options.guiName:len() == 0 then
430 return '"guiName" cannot be a 0-length string', position
431 end
432 else
433 if type(options.name) ~= "string" then
434 return '"name" must be a string', position
435 elseif options.name:len() == 0 then
436 return '"name" cannot be a 0-length string', position
437 end
438 end
439 end
440 if options.guiNameIsMap then
441 if type(options.guiNameIsMap) ~= "boolean" then
442 return '"guiNameIsMap" must be a boolean or nil', position
443 elseif options.type ~= "toggle" then
444 return 'if "guiNameIsMap" is true, then "type" must be set to \'toggle\'', position
445 elseif type(options.map) ~= "table" then
446 return '"map" must be a table', position
447 end
448 end
449 if options.message and type(options.message) ~= "string" then
450 return '"message" must be a string or nil', position
451 end
452 if options.error and type(options.error) ~= "string" then
453 return '"error" must be a string or nil', position
454 end
455 if options.current and type(options.current) ~= "string" then
456 return '"current" must be a string or nil', position
457 end
458 if options.order then
459 if type(options.order) ~= "number" or (-1 < options.order and options.order < 0.999) then
460 return '"order" must be a non-zero number or nil', position
461 end
462 end
463 if options.disabled then
464 if type(options.disabled) ~= "function" and type(options.disabled) ~= "string" and options.disabled ~= true then
465 return '"disabled" must be a function, string, or boolean', position
466 end
467 end
468 if options.cmdHidden then
469 if type(options.cmdHidden) ~= "function" and type(options.cmdHidden) ~= "string" and options.cmdHidden ~= true then
470 return '"cmdHidden" must be a function, string, or boolean', position
471 end
472 end
473 if options.guiHidden then
474 if type(options.guiHidden) ~= "function" and type(options.guiHidden) ~= "string" and options.guiHidden ~= true then
475 return '"guiHidden" must be a function, string, or boolean', position
476 end
477 end
478 if options.hidden then
479 if type(options.hidden) ~= "function" and type(options.hidden) ~= "string" and options.hidden ~= true then
480 return '"hidden" must be a function, string, or boolean', position
481 end
482 end
483 if kind == "text" then
484 if type(options.validate) == "table" then
485 local t = options.validate
486 local iTable = nil
487 for k,v in pairs(t) do
488 if type(k) == "number" then
489 if iTable == nil then
490 iTable = true
491 elseif not iTable then
492 return '"validate" must either have all keys be indexed numbers or strings', position
493 elseif k < 1 or k > #t then
494 return '"validate" numeric keys must be indexed properly. >= 1 and <= #validate', position
495 end
496 else
497 if iTable == nil then
498 iTable = false
499 elseif iTable then
500 return '"validate" must either have all keys be indexed numbers or strings', position
501 end
502 end
503 if type(v) ~= "string" then
504 return '"validate" values must all be strings', position
505 end
506 end
507 elseif options.validate == "keybinding" then
508
509 else
510 if type(options.usage) ~= "string" then
511 return '"usage" must be a string', position
512 elseif options.validate and type(options.validate) ~= "string" and type(options.validate) ~= "function" then
513 return '"validate" must be a string, function, or table', position
514 end
515 end
516 elseif kind == "range" then
517 if options.min or options.max then
518 if type(options.min) ~= "number" then
519 return '"min" must be a number', position
520 elseif type(options.max) ~= "number" then
521 return '"max" must be a number', position
522 elseif options.min >= options.max then
523 return '"min" must be less than "max"', position
524 end
525 end
526 if options.step then
527 if type(options.step) ~= "number" then
528 return '"step" must be a number', position
529 elseif options.step < 0 then
530 return '"step" must be nonnegative', position
531 end
532 end
533 if options.isPercent and options.isPercent ~= true then
534 return '"isPercent" must either be nil, true, or false', position
535 end
536 elseif kind == "toggle" then
537 if options.map then
538 if type(options.map) ~= "table" then
539 return '"map" must be a table', position
540 elseif type(options.map[true]) ~= "string" then
541 return '"map[true]" must be a string', position
542 elseif type(options.map[false]) ~= "string" then
543 return '"map[false]" must be a string', position
544 end
545 end
546 elseif kind == "color" then
547 if options.hasAlpha and options.hasAlpha ~= true then
548 return '"hasAlpha" must be nil, true, or false', position
549 end
550 elseif kind == "group" then
551 if options.pass and options.pass ~= true then
552 return '"pass" must be nil, true, or false', position
553 end
554 if type(options.args) ~= "table" then
555 return '"args" must be a table', position
556 end
557 for k,v in pairs(options.args) do
558 if type(k) ~= "string" then
559 return '"args" keys must be strings', position
560 elseif k:find("%s") then
561 return string.format('"args" keys must not include spaces. %q is not appropriate.', k), position
562 elseif k:len() == 0 then
563 return '"args" keys must not be 0-length strings.', position
564 end
565 if type(v) ~= "table" then
566 return '"args" values must be tables', position and position .. "." .. k or k
567 end
568 local newposition
569 if position then
570 newposition = position .. ".args." .. k
571 else
572 newposition = "args." .. k
573 end
574 local err, pos = validateOptions(v, newposition, baseOptions, options.pass)
575 if err then
576 return err, pos
577 end
578 end
579 end
580 end
581
582 local colorTable
583 local colorFunc
584 local colorCancelFunc
585
586 local function keybindingValidateFunc(text)
587 if text == nil or text == "NONE" then
588 return nil
589 end
590 text = text:upper()
591 local shift, ctrl, alt
592 local modifier
593 while true do
594 if text == "-" then
595 break
596 end
597 modifier, text = strsplit('-', text, 2)
598 if text then
599 if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then
600 return false
601 end
602 if modifier == "SHIFT" then
603 if shift then
604 return false
605 end
606 shift = true
607 end
608 if modifier == "CTRL" then
609 if ctrl then
610 return false
611 end
612 ctrl = true
613 end
614 if modifier == "ALT" then
615 if alt then
616 return false
617 end
618 alt = true
619 end
620 else
621 text = modifier
622 break
623 end
624 end
625 if not text:find("^F%d+$") and text:len() ~= 1 and (text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] then
626 return false
627 end
628 local s = text
629 if shift then
630 s = "SHIFT-" .. s
631 end
632 if ctrl then
633 s = "CTRL-" .. s
634 end
635 if alt then
636 s = "ALT-" .. s
637 end
638 return s
639 end
640 AceConsole.keybindingValidateFunc = keybindingValidateFunc
641
642 local order
643
644 local mysort_args
645 local mysort
646
647 local function printUsage(self, handler, realOptions, options, path, args, quiet, filter)
648 if filter then
649 filter = "^" .. filter:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
650 end
651 local hidden, disabled = options.cmdHidden or options.hidden, options.disabled
652 if hidden then
653 if type(hidden) == "function" then
654 hidden = hidden()
655 elseif type(hidden) == "string" then
656 local f = hidden
657 local neg = f:match("^~(.-)$")
658 if neg then
659 f = neg
660 end
661 if type(handler[f]) ~= "function" then
662 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
663 end
664 hidden = handler[f](handler)
665 if neg then
666 hidden = not hidden
667 end
668 end
669 end
670 if hidden then
671 disabled = true
672 elseif disabled then
673 if type(disabled) == "function" then
674 disabled = disabled()
675 elseif type(disabled) == "string" then
676 local f = disabled
677 local neg = f:match("^~(.-)$")
678 if neg then
679 f = neg
680 end
681 if type(handler[f]) ~= "function" then
682 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
683 end
684 disabled = handler[f](handler)
685 if neg then
686 disabled = not disabled
687 end
688 end
689 end
690 local kind = (options.type or "group"):lower()
691 if disabled then
692 print(string.format(OPTION_IS_DISABLED, path), realOptions.cmdName or realOptions.name or self)
693 elseif kind == "text" then
694 local var
695 if passTable then
696 if not passTable.get then
697 elseif type(passTable.get) == "function" then
698 var = passTable.get(passValue)
699 else
700 local handler = passTable.handler or handler
701 if type(handler[passTable.get]) ~= "function" then
702 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get))
703 end
704 var = handler[passTable.get](handler, passValue)
705 end
706 else
707 if not options.get then
708 elseif type(options.get) == "function" then
709 var = options.get()
710 else
711 local handler = options.handler or handler
712 if type(handler[options.get]) ~= "function" then
713 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get))
714 end
715 var = handler[options.get](handler)
716 end
717 end
718
719 local usage
720 if type(options.validate) == "table" then
721 if filter then
722 if not order then
723 order = {}
724 end
725 for k,v in pairs(options.validate) do
726 if v:find(filter) then
727 table.insert(order, v)
728 end
729 end
730 usage = "{" .. table.concat(order, " || ") .. "}"
731 for k in pairs(order) do
732 order[k] = nil
733 end
734 else
735 if not order then
736 order = {}
737 end
738 for k,v in pairs(options.validate) do
739 table.insert(order, v)
740 end
741 usage = "{" .. table.concat(order, " || ") .. "}"
742 for k in pairs(order) do
743 order[k] = nil
744 end
745 end
746 var = options.validate[var] or var
747 elseif options.validate == "keybinding" then
748 usage = KEYBINDING_USAGE
749 else
750 usage = options.usage or "<value>"
751 end
752 if not quiet then
753 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage), realOptions.cmdName or realOptions.name or self)
754 end
755 if (passTable and passTable.get) or options.get then
756 print(string.format(options.current or IS_CURRENTLY_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)))
757 end
758 elseif kind == "range" then
759 local var
760 if passTable then
761 if type(passTable.get) == "function" then
762 var = passTable.get(passValue)
763 else
764 local handler = passTable.handler or handler
765 if type(handler[passTable.get]) ~= "function" then
766 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get))
767 end
768 var = handler[passTable.get](handler, passValue)
769 end
770 else
771 if type(options.get) == "function" then
772 var = options.get()
773 else
774 local handler = options.handler or handler
775 if type(handler[options.get]) ~= "function" then
776 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get))
777 end
778 var = handler[options.get](handler)
779 end
780 end
781
782 local usage
783 local min = options.min or 0
784 local max = options.max or 1
785 if options.isPercent then
786 min, max = min * 100, max * 100
787 var = tostring(var * 100) .. "%"
788 end
789 local bit = "-"
790 if min < 0 or max < 0 then
791 bit = " - "
792 end
793 usage = string.format("(%s%s%s)", min, bit, max)
794 if not quiet then
795 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage), realOptions.cmdName or realOptions.name or self)
796 end
797 print(string.format(options.current or IS_CURRENTLY_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)))
798 elseif kind == "group" then
799 local usage
800 if next(options.args) then
801 if not order then
802 order = {}
803 end
804 for k,v in pairs(options.args) do
805 if v.type ~= "header" then
806 local hidden = v.cmdHidden or v.hidden
807 if hidden then
808 if type(hidden) == "function" then
809 hidden = hidden()
810 elseif type(hidden) == "string" then
811 local f = hidden
812 local neg = f:match("^~(.-)$")
813 if neg then
814 f = neg
815 end
816 if type(handler[f]) ~= "function" then
817 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
818 end
819 hidden = handler[f](handler)
820 if neg then
821 hidden = not hidden
822 end
823 end
824 end
825 if not hidden then
826 if filter then
827 if k:find(filter) then
828 table.insert(order, k)
829 elseif type(v.aliases) == "table" then
830 for _,bit in ipairs(v.aliases) do
831 if bit:find(filter) then
832 table.insert(order, k)
833 break
834 end
835 end
836 elseif type(v.aliases) == "string" then
837 if v.aliases:find(filter) then
838 table.insert(order, k)
839 end
840 end
841 else
842 table.insert(order, k)
843 end
844 end
845 end
846 end
847 if not mysort then
848 mysort = function(a, b)
849 local alpha, bravo = mysort_args[a], mysort_args[b]
850 local alpha_order = alpha and alpha.order or 100
851 local bravo_order = bravo and bravo.order or 100
852 if alpha_order == bravo_order then
853 return tostring(a) < tostring(b)
854 else
855 if alpha_order < 0 then
856 if bravo_order > 0 then
857 return false
858 end
859 else
860 if bravo_order < 0 then
861 return true
862 end
863 end
864 if alpha_order > 0 and bravo_order > 0 then
865 return tostring(a) < tostring(b)
866 end
867 return alpha_order < bravo_order
868 end
869 end
870 end
871 mysort_args = options.args
872 table.sort(order, mysort)
873 mysort_args = nil
874 if not quiet then
875 if options == realOptions then
876 if options.desc then
877 print(tostring(options.desc), realOptions.cmdName or realOptions.name or self)
878 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"))
879 elseif self.description or self.notes then
880 print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self)
881 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"))
882 else
883 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self)
884 end
885 else
886 if options.desc then
887 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self)
888 print(tostring(options.desc))
889 else
890 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self)
891 end
892 end
893 end
894 for _,k in ipairs(order) do
895 local v = options.args[k]
896 if v then
897 local disabled = v.disabled
898 if disabled then
899 if type(disabled) == "function" then
900 disabled = disabled()
901 elseif type(disabled) == "string" then
902 local f = disabled
903 local neg = f:match("^~(.-)$")
904 if neg then
905 f = neg
906 end
907 if type(handler[f]) ~= "function" then
908 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
909 end
910 disabled = handler[f](handler)
911 if neg then
912 disabled = not disabled
913 end
914 end
915 end
916 if type(v.aliases) == "table" then
917 k = k .. " || " .. table.concat(v.aliases, " || ")
918 elseif type(v.aliases) == "string" then
919 k = k .. " || " .. v.aliases
920 end
921 if v.get then
922 local a1,a2,a3,a4
923 if type(v.get) == "function" then
924 if options.pass then
925 a1,a2,a3,a4 = v.get(k)
926 else
927 a1,a2,a3,a4 = v.get()
928 end
929 else
930 local handler = v.handler or handler
931 local f = v.get
932 local neg
933 if v.type == "toggle" then
934 neg = f:match("^~(.-)$")
935 if neg then
936 f = neg
937 end
938 end
939 if type(handler[f]) ~= "function" then
940 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
941 end
942 if options.pass then
943 a1,a2,a3,a4 = handler[f](handler, k)
944 else
945 a1,a2,a3,a4 = handler[f](handler)
946 end
947 if neg then
948 a1 = not a1
949 end
950 end
951 if v.type == "color" then
952 if v.hasAlpha then
953 if not a1 or not a2 or not a3 or not a4 then
954 s = NONE
955 else
956 s = string.format("|c%02x%02x%02x%02x%02x%02x%02x%02x|r", a4*255, a1*255, a2*255, a3*255, a4*255, a1*255, a2*255, a3*255)
957 end
958 else
959 if not a1 or not a2 or not a3 then
960 s = NONE
961 else
962 s = string.format("|cff%02x%02x%02x%02x%02x%02x|r", a1*255, a2*255, a3*255, a1*255, a2*255, a3*255)
963 end
964 end
965 elseif v.type == "toggle" then
966 if v.map then
967 s = tostring(v.map[a1 and true or false] or NONE)
968 else
969 s = tostring(MAP_ONOFF[a1 and true or false] or NONE)
970 end
971 elseif v.type == "range" then
972 if v.isPercent then
973 s = tostring(a1 * 100) .. "%"
974 else
975 s = tostring(a1)
976 end
977 elseif v.type == "text" and type(v.validate) == "table" then
978 s = tostring(v.validate[a1] or a1 or NONE)
979 else
980 s = tostring(a1 or NONE)
981 end
982 if disabled then
983 local s = s:gsub("|cff%x%x%x%x%x%x(.-)|r", "%1")
984 local desc = (v.desc or NONE):gsub("|cff%x%x%x%x%x%x(.-)|r", "%1")
985 print(string.format("|cffcfcfcf - %s: [%s] %s|r", k, s, desc))
986 else
987 print(string.format(" - |cffffff7f%s: [|r%s|cffffff7f]|r %s", k, s, v.desc or NONE))
988 end
989 else
990 if disabled then
991 local desc = (v.desc or NONE):gsub("|cff%x%x%x%x%x%x(.-)|r", "%1")
992 print(string.format("|cffcfcfcf - %s: %s", k, desc))
993 else
994 print(string.format(" - |cffffff7f%s:|r %s", k, v.desc or NONE))
995 end
996 end
997 end
998 end
999 for k in pairs(order) do
1000 order[k] = nil
1001 end
1002 else
1003 if options.desc then
1004 desc = options.desc
1005 print(string.format("|cffffff7f%s:|r %s", USAGE, path), realOptions.cmdName or realOptions.name or self)
1006 print(tostring(options.desc))
1007 elseif options == realOptions and (self.description or self.notes) then
1008 print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self)
1009 print(string.format("|cffffff7f%s:|r %s", USAGE, path))
1010 else
1011 print(string.format("|cffffff7f%s:|r %s", USAGE, path), realOptions.cmdName or realOptions.name or self)
1012 end
1013 print(NO_OPTIONS_AVAILABLE)
1014 end
1015 end
1016 end
1017
1018 local function handlerFunc(self, chat, msg, options)
1019 if not msg then
1020 msg = ""
1021 else
1022 msg = msg:gsub("^%s*(.-)%s*$", "%1")
1023 msg = msg:gsub("%s+", " ")
1024 end
1025
1026 local realOptions = options
1027 local options, path, args, handler, passTable, passValue = findTableLevel(self, options, chat, msg)
1028
1029 local hidden, disabled = options.cmdHidden or options.hidden, options.disabled
1030 if hidden then
1031 if type(hidden) == "function" then
1032 hidden = hidden()
1033 elseif type(hidden) == "string" then
1034 local f = hidden
1035 local neg = f:match("^~(.-)$")
1036 if neg then
1037 f = neg
1038 end
1039 if type(handler[f]) ~= "function" then
1040 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
1041 end
1042 hidden = handler[f](handler)
1043 if neg then
1044 hidden = not hidden
1045 end
1046 end
1047 end
1048 if hidden then
1049 disabled = true
1050 elseif disabled then
1051 if type(disabled) == "function" then
1052 disabled = disabled()
1053 elseif type(disabled) == "string" then
1054 local f = disabled
1055 local neg = f:match("^~(.-)$")
1056 if neg then
1057 f = neg
1058 end
1059 if type(handler[f]) ~= "function" then
1060 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
1061 end
1062 disabled = handler[f](handler)
1063 if neg then
1064 disabled = not disabled
1065 end
1066 end
1067 end
1068 local _G_this = this
1069 local kind = (options.type or "group"):lower()
1070 if disabled then
1071 print(string.format(OPTION_IS_DISABLED, path), realOptions.cmdName or realOptions.name or self)
1072 elseif kind == "text" then
1073 if #args > 0 then
1074 if (type(options.validate) == "table" and #args > 1) or (type(options.validate) ~= "table" and not options.input) then
1075 local arg = table.concat(args, " ")
1076 for k,v in pairs(args) do
1077 args[k] = nil
1078 end
1079 args[1] = arg
1080 end
1081 if options.validate then
1082 local good
1083 if type(options.validate) == "function" then
1084 good = options.validate(unpack(args))
1085 elseif type(options.validate) == "table" then
1086 local arg = args[1]
1087 arg = tostring(arg):lower()
1088 for k,v in pairs(options.validate) do
1089 if v:lower() == arg then
1090 args[1] = type(k) == "string" and k or v
1091 good = true
1092 break
1093 end
1094 end
1095 if not good and type((next(options.validate))) == "string" then
1096 for k,v in pairs(options.validate) do
1097 if type(k) == "string" and k:lower() == arg then
1098 args[1] = k
1099 good = true
1100 break
1101 end
1102 end
1103 end
1104 elseif options.validate == "keybinding" then
1105 good = keybindingValidateFunc(unpack(args))
1106 if good ~= false then
1107 args[1] = good
1108 end
1109 else
1110 if type(handler[options.validate]) ~= "function" then
1111 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.validate))
1112 end
1113 good = handler[options.validate](handler, unpack(args))
1114 end
1115 if not good then
1116 local usage
1117 if type(options.validate) == "table" then
1118 if not order then
1119 order = {}
1120 end
1121 for k,v in pairs(options.validate) do
1122 table.insert(order, v)
1123 end
1124 usage = "{" .. table.concat(order, " || ") .. "}"
1125 for k in pairs(order) do
1126 order[k] = nil
1127 end
1128 elseif options.validate == "keybinding" then
1129 usage = KEYBINDING_USAGE
1130 else
1131 usage = options.usage or "<value>"
1132 end
1133 print(string.format(options.error or IS_NOT_A_VALID_OPTION_FOR, tostring(table.concat(args, " ")), path), realOptions.cmdName or realOptions.name or self)
1134 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage))
1135 return
1136 end
1137 end
1138
1139 local var
1140 if passTable then
1141 if not passTable.get then
1142 elseif type(passTable.get) == "function" then
1143 var = passTable.get(passValue)
1144 else
1145 if type(handler[passTable.get]) ~= "function" then
1146 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get))
1147 end
1148 var = handler[passTable.get](handler, passValue)
1149 end
1150 else
1151 if not options.get then
1152 elseif type(options.get) == "function" then
1153 var = options.get()
1154 else
1155 if type(handler[options.get]) ~= "function" then
1156 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get))
1157 end
1158 var = handler[options.get](handler)
1159 end
1160 end
1161
1162 if var ~= args[1] then
1163 if passTable then
1164 if type(passTable.set) == "function" then
1165 passTable.set(passValue, unpack(args))
1166 else
1167 if type(handler[passTable.set]) ~= "function" then
1168 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.set))
1169 end
1170 handler[passTable.set](handler, passTable.set, unpack(args))
1171 end
1172 else
1173 if type(options.set) == "function" then
1174 options.set(unpack(args))
1175 else
1176 if type(handler[options.set]) ~= "function" then
1177 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.set))
1178 end
1179 handler[options.set](handler, unpack(args))
1180 end
1181 end
1182 end
1183 end
1184
1185 if #args > 0 then
1186 local var
1187 if passTable then
1188 if not passTable.get then
1189 elseif type(passTable.get) == "function" then
1190 var = passTable.get(passValue)
1191 else
1192 if type(handler[passTable.get]) ~= "function" then
1193 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get))
1194 end
1195 var = handler[passTable.get](handler, passValue)
1196 end
1197 else
1198 if not options.get then
1199 elseif type(options.get) == "function" then
1200 var = options.get()
1201 else
1202 if type(handler[options.get]) ~= "function" then
1203 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get))
1204 end
1205 var = handler[options.get](handler)
1206 end
1207 end
1208 if type(options.validate) == "table" then
1209 var = options.validate[var] or var
1210 end
1211 if (passTable and passTable.get) or options.get then
1212 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)), realOptions.cmdName or realOptions.name or self)
1213 end
1214 if var == args[1] then
1215 return
1216 end
1217 else
1218 printUsage(self, handler, realOptions, options, path, args)
1219 return
1220 end
1221 elseif kind == "execute" then
1222 if passTable then
1223 if type(passFunc) == "function" then
1224 set(passValue)
1225 else
1226 if type(handler[passFunc]) ~= "function" then
1227 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passFunc))
1228 end
1229 handler[passFunc](handler, passValue)
1230 end
1231 else
1232 local ret, msg
1233 if type(options.func) == "function" then
1234 options.func()
1235 else
1236 local handler = options.handler or self
1237 if type(handler[options.func]) ~= "function" then
1238 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.func))
1239 end
1240 handler[options.func](handler)
1241 end
1242 end
1243 elseif kind == "toggle" then
1244 local var
1245 if passTable then
1246 if type(passTable.get) == "function" then
1247 var = passTable.get(passValue)
1248 else
1249 local f = passTable.get
1250 local neg = f:match("^~(.-)$")
1251 if neg then
1252 f = neg
1253 end
1254 if type(handler[f]) ~= "function" then
1255 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
1256 end
1257 var = handler[f](handler, passValue)
1258 if neg then
1259 var = not var
1260 end
1261 end
1262 if type(passTable.set) == "function" then
1263 passTable.set(passValue, not var)
1264 else
1265 if type(handler[passTable.set]) ~= "function" then
1266 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.set))
1267 end
1268 handler[passTable.set](handler, passValue, not var)
1269 end
1270 if type(passTable.get) == "function" then
1271 var = passTable.get(passValue)
1272 else
1273 local f = passTable.get
1274 local neg = f:match("^~(.-)$")
1275 if neg then
1276 f = neg
1277 end
1278 var = handler[f](handler, passValue)
1279 if neg then
1280 var = not var
1281 end
1282 end
1283 else
1284 local handler = options.handler or self
1285 if type(options.get) == "function" then
1286 var = options.get()
1287 else
1288 local f = options.get
1289 local neg = f:match("^~(.-)$")
1290 if neg then
1291 f = neg
1292 end
1293 if type(handler[f]) ~= "function" then
1294 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f))
1295 end
1296 var = handler[f](handler)
1297 if neg then
1298 var = not var
1299 end
1300 end
1301 if type(options.set) == "function" then
1302 options.set(not var)
1303 else
1304 if type(handler[options.set]) ~= "function" then
1305 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.set))
1306 end
1307 handler[options.set](handler, not var)
1308 end
1309 if type(options.get) == "function" then
1310 var = options.get()
1311 else
1312 local f = options.get
1313 local neg = f:match("^~(.-)$")
1314 if neg then
1315 f = neg
1316 end
1317 var = handler[f](handler)
1318 if neg then
1319 var = not var
1320 end
1321 end
1322 end
1323
1324 print(string.format(options.message or IS_NOW_SET_TO, 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)
1325 elseif kind == "range" then
1326 local arg
1327 if #args <= 1 then
1328 arg = args[1]
1329 else
1330 arg = table.concat(args, " ")
1331 end
1332
1333 if arg then
1334 local min = options.min or 0
1335 local max = options.max or 1
1336 local good = false
1337 if type(arg) == "number" then
1338 if options.isPercent then
1339 arg = arg / 100
1340 end
1341
1342 if arg >= min and arg <= max then
1343 good = true
1344 end
1345
1346 if good and type(options.step) == "number" and options.step > 0 then
1347 local step = options.step
1348 arg = math.floor((arg - min) / step + 0.5) * step + min
1349 if arg > max then
1350 arg = max
1351 elseif arg < min then
1352 arg = min
1353 end
1354 end
1355 end
1356 if not good then
1357 local usage
1358 local min = options.min or 0
1359 local max = options.max or 1
1360 if options.isPercent then
1361 min, max = min * 100, max * 100
1362 end
1363 local bit = "-"
1364 if min < 0 or max < 0 then
1365 bit = " - "
1366 end
1367 usage = string.format("(%s%s%s)", min, bit, max)
1368 print(string.format(options.error or IS_NOT_A_VALID_VALUE_FOR, tostring(arg), path), realOptions.cmdName or realOptions.name or self)
1369 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage))
1370 return
1371 end
1372
1373 local var
1374 if passTable then
1375 if type(passTable.get) == "function" then
1376 var = passTable.get(passValue)
1377 else
1378 if type(handler[passTable.get]) ~= "function" then
1379 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get))
1380 end
1381 var = handler[passTable.get](handler, passValue)
1382 end
1383 else
1384 if type(options.get) == "function" then
1385 var = options.get()
1386 else
1387 local handler = options.handler or self
1388 if type(handler[options.get]) ~= "function" then
1389 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get))
1390 end
1391 var = handler[options.get](handler)
1392 end
1393 end
1394
1395 if var ~= arg then
1396 if passTable then
1397 if type(passTable.set) == "function" then
1398 passTable.set(passValue, arg)
1399 else
1400 if type(handler[passTable.set]) ~= "function" then
1401 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.set))
1402 end
1403 handler[passTable.set](handler, passValue, arg)
1404 end
1405 else
1406 if type(options.set) == "function" then
1407 options.set(arg)
1408 else
1409 local handler = options.handler or self
1410 if type(handler[options.set]) ~= "function" then
1411 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.set))
1412 end
1413 handler[options.set](handler, arg)
1414 end
1415 end
1416 end
1417 end
1418
1419 if arg then
1420 local var
1421 if passTable then
1422 if type(passTable.get) == "function" then
1423 var = passTable.get(passValue)
1424 else
1425 if type(handler[passTable.get]) ~= "function" then
1426 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get))
1427 end
1428 var = handler[passTable.get](handler, passValue)
1429 end
1430 else
1431 if type(options.get) == "function" then
1432 var = options.get()
1433 else
1434 local handler = options.handler or self
1435 if type(handler[options.get]) ~= "function" then
1436 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get))
1437 end
1438 var = handler[options.get](handler)
1439 end
1440 end
1441
1442 if var and options.isPercent then
1443 var = tostring(var * 100) .. "%"
1444 end
1445 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)), realOptions.cmdName or realOptions.name or self)
1446 if var == arg then
1447 return
1448 end
1449 else
1450 printUsage(self, handler, realOptions, options, path, args)
1451 return
1452 end
1453 elseif kind == "color" then
1454 if #args > 0 then
1455 local r,g,b,a
1456 if #args == 1 then
1457 local arg = tostring(args[1])
1458 if options.hasAlpha then
1459 if arg:len() == 8 and arg:find("^%x*$") then
1460 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
1461 end
1462 else
1463 if arg:len() == 6 and arg:find("^%x*$") then
1464 r,g,b = tonumber(arg:sub(1, 2), 16) / 255, tonumber(arg:sub(3, 4), 16) / 255, tonumber(arg:sub(5, 6), 16) / 255
1465 end
1466 end
1467 elseif #args == 4 and options.hasAlpha then
1468 local a1,a2,a3,a4 = args[1], args[2], args[3], args[4]
1469 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
1470 r,g,b,a = a1,a2,a3,a4
1471 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
1472 r,g,b,a = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255, tonumber(a4, 16) / 255
1473 end
1474 elseif #args == 3 and not options.hasAlpha then
1475 local a1,a2,a3 = args[1], args[2], args[3]
1476 if type(a1) == "number" and type(a2) == "number" and type(a3) == "number" and a1 <= 1 and a2 <= 1 and a3 <= 1 then
1477 r,g,b = a1,a2,a3
1478 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
1479 r,g,b = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255
1480 end
1481 end
1482 if not r then
1483 print(string.format(options.error or IS_NOT_A_VALID_OPTION_FOR, table.concat(args, ' '), path), realOptions.cmdName or realOptions.name or self)
1484 print(string.format("|cffffff7f%s:|r %s {0-1} {0-1} {0-1}%s", USAGE, path, options.hasAlpha and " {0-1}" or ""))
1485 return
1486 end
1487 if passTable then
1488 if type(passTable.set) == "function" then
1489 passTable.set(passValue, r,g,b,a)
1490 else
1491 if type(handler[passTable.set]) ~= "function" then
1492 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.set))
1493 end
1494 handler[passTable.set](handler, passValue, r,g,b,a)
1495 end
1496 else
1497 if type(options.set) == "function" then
1498 options.set(r,g,b,a)
1499 else
1500 if type(handler[options.set]) ~= "function" then
1501 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.set))
1502 end
1503 handler[options.set](handler, r,g,b,a)
1504 end
1505 end
1506
1507 local r,g,b,a
1508 if passTable then
1509 if type(passTable.get) == "function" then
1510 r,g,b,a = passTable.get(passValue)
1511 else
1512 if type(handler[passTable.get]) ~= "function" then
1513 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get))
1514 end
1515 r,g,b,a = handler[passTable.get](handler, passValue)
1516 end
1517 else
1518 if type(options.get) == "function" then
1519 r,g,b,a = options.get()
1520 else
1521 if type(handler[options.get]) ~= "function" then
1522 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get))
1523 end
1524 r,g,b,a = handler[options.get](handler)
1525 end
1526 end
1527
1528 local s
1529 if type(r) == "number" and type(g) == "number" and type(b) == "number" then
1530 if options.hasAlpha and type(a) == "number" then
1531 s = string.format("|c%02x%02x%02x%02x%02x%02x%02x%02x|r", a*255, r*255, g*255, b*255, r*255, g*255, b*255, a*255)
1532 else
1533 s = string.format("|cff%02x%02x%02x%02x%02x%02x|r", r*255, g*255, b*255, r*255, g*255, b*255)
1534 end
1535 else
1536 s = NONE
1537 end
1538 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), s), realOptions.cmdName or realOptions.name or self)
1539 else
1540 local r,g,b,a
1541 if passTable then
1542 if type(passTable.get) == "function" then
1543 r,g,b,a = passTable.get(passValue)
1544 else
1545 if type(handler[passTable.get]) ~= "function" then
1546 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get))
1547 end
1548 r,g,b,a = handler[passTable.get](handler, passValue)
1549 end
1550 else
1551 if type(options.get) == "function" then
1552 r,g,b,a = options.get()
1553 else
1554 if type(handler[options.get]) ~= "function" then
1555 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get))
1556 end
1557 r,g,b,a = handler[options.get](handler)
1558 end
1559 end
1560
1561 if not colorTable then
1562 colorTable = {}
1563 local t = colorTable
1564
1565 if ColorPickerOkayButton then
1566 local ColorPickerOkayButton_OnClick = ColorPickerOkayButton:GetScript("OnClick")
1567 ColorPickerOkayButton:SetScript("OnClick", function()
1568 if ColorPickerOkayButton_OnClick then
1569 ColorPickerOkayButton_OnClick()
1570 end
1571 if t.active then
1572 ColorPickerFrame.cancelFunc = nil
1573 ColorPickerFrame.func = nil
1574 ColorPickerFrame.opacityFunc = nil
1575 local r,g,b,a
1576 if t.passValue then
1577 if type(t.get) == "function" then
1578 r,g,b,a = t.get(t.passValue)
1579 else
1580 if type(t.handler[t.get]) ~= "function" then
1581 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.get))
1582 end
1583 r,g,b,a = t.handler[t.get](t.handler, t.passValue)
1584 end
1585 else
1586 if type(t.get) == "function" then
1587 r,g,b,a = t.get()
1588 else
1589 if type(t.handler[t.get]) ~= "function" then
1590 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.get))
1591 end
1592 r,g,b,a = t.handler[t.get](t.handler)
1593 end
1594 end
1595 if r ~= t.r or g ~= t.g or b ~= t.b or (t.hasAlpha and a ~= t.a) then
1596 local s
1597 if type(r) == "number" and type(g) == "number" and type(b) == "number" then
1598 if t.hasAlpha and type(a) == "number" then
1599 s = string.format("|c%02x%02x%02x%02x%02x%02x%02x%02x|r", a*255, r*255, g*255, b*255, r*255, g*255, b*255, a*255)
1600 else
1601 s = string.format("|cff%02x%02x%02x%02x%02x%02x|r", r*255, g*255, b*255, r*255, g*255, b*255)
1602 end
1603 else
1604 s = NONE
1605 end
1606 print(string.format(t.message, tostring(t.name), s), t.realOptions.cmdName or t.realOptions.name or self)
1607 end
1608 for k,v in pairs(t) do
1609 t[k] = nil
1610 end
1611 end
1612 end)
1613 end
1614 else
1615 for k,v in pairs(colorTable) do
1616 colorTable[k] = nil
1617 end
1618 end
1619
1620 if type(r) ~= "number" or type(g) ~= "number" or type(b) ~= "number" then
1621 r,g,b = 1, 1, 1
1622 end
1623 if type(a) ~= "number" then
1624 a = 1
1625 end
1626 local t = colorTable
1627 t.r = r
1628 t.g = g
1629 t.b = b
1630 if hasAlpha then
1631 t.a = a
1632 end
1633 t.realOptions = realOptions
1634 t.hasAlpha = options.hasAlpha
1635 t.handler = handler
1636 t.set = passTable and passTable.set or options.set
1637 t.get = passTable and passTable.get or options.get
1638 t.name = options.cmdName or options.name
1639 t.message = options.message or IS_NOW_SET_TO
1640 t.passValue = passValue
1641 t.active = true
1642
1643 if not colorFunc then
1644 colorFunc = function()
1645 local r,g,b = ColorPickerFrame:GetColorRGB()
1646 if t.hasAlpha then
1647 local a = 1 - OpacitySliderFrame:GetValue()
1648 if type(t.set) == "function" then
1649 if t.passValue then
1650 t.set(t.passValue, r,g,b,a)
1651 else
1652 t.set(r,g,b,a)
1653 end
1654 else
1655 if type(t.handler[t.set]) ~= "function" then
1656 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.set))
1657 end
1658 if t.passValue then
1659 t.handler[t.set](t.handler, t.passValue, r,g,b,a)
1660 else
1661 t.handler[t.set](t.handler, r,g,b,a)
1662 end
1663 end
1664 else
1665 if type(t.set) == "function" then
1666 if t.passValue then
1667 t.set(t.passValue, r,g,b)
1668 else
1669 t.set(r,g,b)
1670 end
1671 else
1672 if type(t.handler[t.set]) ~= "function" then
1673 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.set))
1674 end
1675 if t.passValue then
1676 t.handler[t.set](t.handler, t.passValue, r,g,b)
1677 else
1678 t.handler[t.set](t.handler, r,g,b)
1679 end
1680 end
1681 end
1682 end
1683 end
1684
1685 ColorPickerFrame.func = colorFunc
1686 ColorPickerFrame.hasOpacity = options.hasAlpha
1687 if options.hasAlpha then
1688 ColorPickerFrame.opacityFunc = ColorPickerFrame.func
1689 ColorPickerFrame.opacity = 1 - a
1690 end
1691 ColorPickerFrame:SetColorRGB(r,g,b)
1692
1693 if not colorCancelFunc then
1694 colorCancelFunc = function()
1695 if t.hasAlpha then
1696 if type(t.set) == "function" then
1697 if t.passValue then
1698 t.set(t.passValue, t.r,t.g,t.b,t.a)
1699 else
1700 t.set(t.r,t.g,t.b,t.a)
1701 end
1702 else
1703 if type(t.handler[t.get]) ~= "function" then
1704 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.get))
1705 end
1706 if t.passValue then
1707 t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b,t.a)
1708 else
1709 t.handler[t.set](t.handler, t.r,t.g,t.b,t.a)
1710 end
1711 end
1712 else
1713 if type(t.set) == "function" then
1714 if t.passValue then
1715 t.set(t.passValue, t.r,t.g,t.b)
1716 else
1717 t.set(t.r,t.g,t.b)
1718 end
1719 else
1720 if type(t.handler[t.set]) ~= "function" then
1721 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.set))
1722 end
1723 if t.passValue then
1724 t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b)
1725 else
1726 t.handler[t.set](t.handler, t.r,t.g,t.b)
1727 end
1728 end
1729 end
1730 for k,v in pairs(t) do
1731 t[k] = nil
1732 end
1733 ColorPickerFrame.cancelFunc = nil
1734 ColorPickerFrame.func = nil
1735 ColorPickerFrame.opacityFunc = nil
1736 end
1737 end
1738
1739 ColorPickerFrame.cancelFunc = colorCancelFunc
1740
1741 ShowUIPanel(ColorPickerFrame)
1742 end
1743 return
1744 elseif kind == "group" then
1745 if #args == 0 then
1746 printUsage(self, handler, realOptions, options, path, args)
1747 else
1748 -- invalid argument
1749 print(string.format(options.error or IS_NOT_A_VALID_OPTION_FOR, args[1], path), realOptions.cmdName or realOptions.name or self)
1750 end
1751 return
1752 end
1753 this = _G_this
1754 if Dewdrop then
1755 Dewdrop:Refresh(1)
1756 Dewdrop:Refresh(2)
1757 Dewdrop:Refresh(3)
1758 Dewdrop:Refresh(4)
1759 Dewdrop:Refresh(5)
1760 end
1761 end
1762
1763 local external
1764 function AceConsole:RegisterChatCommand(slashCommands, options, name)
1765 if type(slashCommands) ~= "table" and slashCommands ~= false then
1766 AceConsole:error("Bad argument #2 to `RegisterChatCommand' (expected table, got %s)", type(slashCommands))
1767 end
1768 if not slashCommands and type(name) ~= "string" then
1769 AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string, got %s)", type(name))
1770 end
1771 if type(options) ~= "table" and type(options) ~= "function" and options ~= nil then
1772 AceConsole:error("Bad argument #3 to `RegisterChatCommand' (expected table, function, or nil, got %s)", type(options))
1773 end
1774 if name then
1775 if type(name) ~= "string" then
1776 AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string or nil, got %s)", type(name))
1777 elseif not name:find("^%w+$") or name:upper() ~= name or name:len() == 0 then
1778 AceConsole:error("Argument #4 must be an uppercase, letters-only string with at least 1 character")
1779 end
1780 end
1781 if slashCommands then
1782 if #slashCommands == 0 then
1783 AceConsole:error("Argument #2 to `RegisterChatCommand' must include at least one string")
1784 end
1785
1786 for k,v in pairs(slashCommands) do
1787 if type(k) ~= "number" then
1788 AceConsole:error("All keys in argument #2 to `RegisterChatCommand' must be numbers")
1789 end
1790 if type(v) ~= "string" then
1791 AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be strings")
1792 elseif not v:find("^/[A-Za-z][A-Za-z0-9_]*$") then
1793 AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be in the form of \"/word\"")
1794 end
1795 end
1796 end
1797
1798 if not options then
1799 options = {
1800 type = 'group',
1801 args = {},
1802 handler = self
1803 }
1804 end
1805
1806 if type(options) == "table" then
1807 local err, position = validateOptions(options)
1808 if err then
1809 if position then
1810 AceConsole:error(position .. ": " .. err)
1811 else
1812 AceConsole:error(err)
1813 end
1814 end
1815
1816 if not options.handler then
1817 options.handler = self
1818 end
1819
1820 if options.handler == self and options.type:lower() == "group" and self.class then
1821 AceConsole:InjectAceOptionsTable(self, options)
1822 end
1823 end
1824
1825 local chat
1826 if slashCommands then
1827 chat = slashCommands[1]
1828 else
1829 chat = _G["SLASH_"..name..1]
1830 end
1831
1832 local handler
1833 if type(options) == "function" then
1834 handler = options
1835 for k,v in pairs(_G) do
1836 if handler == v then
1837 local k = k
1838 handler = function(msg)
1839 return _G[k](msg)
1840 end
1841 end
1842 end
1843 else
1844 function handler(msg)
1845 handlerFunc(self, chat, msg, options)
1846 end
1847 end
1848
1849 if not _G.SlashCmdList then
1850 _G.SlashCmdList = {}
1851 end
1852
1853 if not name then
1854 local A = ('A'):byte()
1855 repeat
1856 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)
1857 until not _G.SlashCmdList[name]
1858 end
1859
1860 if slashCommands then
1861 if _G.SlashCmdList[name] then
1862 local i = 0
1863 while true do
1864 i = i + 1
1865 if _G["SLASH_"..name..i] then
1866 _G["SLASH_"..name..i] = nil
1867 else
1868 break
1869 end
1870 end
1871 end
1872
1873 local i = 0
1874 for _,command in ipairs(slashCommands) do
1875 i = i + 1
1876 _G["SLASH_"..name..i] = command
1877 if command:lower() ~= command then
1878 i = i + 1
1879 _G["SLASH_"..name..i] = command:lower()
1880 end
1881 end
1882 end
1883 _G.SlashCmdList[name] = handler
1884 if self ~= AceConsole and self.slashCommand == nil then
1885 self.slashCommand = chat
1886 end
1887
1888 if not AceEvent and AceLibrary:HasInstance("AceEvent-2.0") then
1889 external(AceConsole, "AceEvent-2.0", AceLibrary("AceEvent-2.0"))
1890 end
1891 if AceEvent then
1892 if not AceConsole.nextAddon then
1893 AceConsole.nextAddon = {}
1894 end
1895 if type(options) == "table" then
1896 AceConsole.nextAddon[self] = options
1897 if not self.playerLogin then
1898 AceConsole:RegisterEvent("PLAYER_LOGIN", "PLAYER_LOGIN", true)
1899 end
1900 end
1901 end
1902
1903 AceConsole.registry[name] = options
1904 end
1905
1906 function AceConsole:InjectAceOptionsTable(handler, options)
1907 self:argCheck(handler, 2, "table")
1908 self:argCheck(options, 3, "table")
1909 if options.type:lower() ~= "group" then
1910 self:error('Cannot inject into options table argument #3 if its type is not "group"')
1911 end
1912 if options.handler ~= nil and options.handler ~= handler then
1913 self:error("Cannot inject into options table argument #3 if it has a different handler than argument #2")
1914 end
1915 options.handler = handler
1916 local class = handler.class
1917 if not class then
1918 self:error("Cannot retrieve AceOptions tables from a non-object argument #2")
1919 end
1920 while class and class ~= AceOO.Class do
1921 if type(class.GetAceOptionsDataTable) == "function" then
1922 local t = class:GetAceOptionsDataTable(handler)
1923 for k,v in pairs(t) do
1924 if type(options.args) ~= "table" then
1925 options.args = {}
1926 end
1927 if options.args[k] == nil then
1928 options.args[k] = v
1929 end
1930 end
1931 end
1932 local mixins = class.mixins
1933 if mixins then
1934 for mixin in pairs(mixins) do
1935 if type(mixin.GetAceOptionsDataTable) == "function" then
1936 local t = mixin:GetAceOptionsDataTable(handler)
1937 for k,v in pairs(t) do
1938 if type(options.args) ~= "table" then
1939 options.args = {}
1940 end
1941 if options.args[k] == nil then
1942 options.args[k] = v
1943 end
1944 end
1945 end
1946 end
1947 end
1948 class = class.super
1949 end
1950 return options
1951 end
1952
1953 function AceConsole:PLAYER_LOGIN()
1954 self.playerLogin = true
1955 for addon, options in pairs(self.nextAddon) do
1956 local err, position = validateOptionsMethods(addon, options)
1957 if err then
1958 if position then
1959 geterrorhandler()(tostring(addon) .. ": AceConsole: " .. position .. ": " .. err)
1960 else
1961 geterrorhandler()(tostring(addon) .. ": AceConsole: " .. err)
1962 end
1963 end
1964 self.nextAddon[addon] = nil
1965 end
1966 end
1967
1968 function AceConsole:TabCompleteInfo(cmdpath)
1969 local cmd = cmdpath:match("(/%S+)")
1970 if not cmd then
1971 return
1972 end
1973 local path = cmdpath:sub(cmd:len() + 2)
1974 for name in pairs(SlashCmdList) do --global
1975 if AceConsole.registry[name] then
1976 local i = 0
1977 while true do
1978 i = i + 1
1979 local scmd = _G["SLASH_"..name..i]
1980 if not scmd then break end
1981 if cmd == scmd then
1982 return name, cmd, path
1983 end
1984 end
1985 end
1986 end
1987 end
1988
1989 function external(self, major, instance)
1990 if major == "AceEvent-2.0" then
1991 if not AceEvent then
1992 AceEvent = instance
1993
1994 AceEvent:embed(self)
1995 end
1996 elseif major == "AceTab-2.0" then
1997 instance:RegisterTabCompletion("AceConsole", "%/.*", function(t, cmdpath, pos)
1998 local ac = AceLibrary("AceConsole-2.0")
1999 local name, cmd, path = ac:TabCompleteInfo(cmdpath:sub(1, pos))
2000
2001 if not ac.registry[name] then
2002 return false
2003 else
2004 local validArgs = findTableLevel(ac, ac.registry[name], cmd, path or "")
2005 if validArgs.args then
2006 for arg in pairs(validArgs.args) do
2007 table.insert(t, arg)
2008 end
2009 end
2010 end
2011 end, function(u, matches, gcs, cmdpath)
2012 local ac = AceLibrary("AceConsole-2.0")
2013 local name, cmd, path = ac:TabCompleteInfo(cmdpath)
2014 if ac.registry[name] then
2015 local validArgs, path2, argwork = findTableLevel(ac, ac.registry[name], cmd, path)
2016 printUsage(ac, validArgs.handler, ac.registry[name], validArgs, path2, argwork, not gcs or gcs ~= "", gcs)
2017 end
2018 end)
2019 elseif major == "Dewdrop-2.0" then
2020 Dewdrop = instance
2021 end
2022 end
2023
2024 local function activate(self, oldLib, oldDeactivate)
2025 AceConsole = self
2026
2027 if oldLib then
2028 self.registry = oldLib.registry
2029 self.nextAddon = oldLib.nextAddon
2030 end
2031
2032 if not self.registry then
2033 self.registry = {}
2034 else
2035 for name,options in pairs(self.registry) do
2036 self:RegisterChatCommand(false, options, name)
2037 end
2038 end
2039
2040 self:RegisterChatCommand({ "/reload", "/rl", "/reloadui" }, ReloadUI, "RELOAD")
2041
2042 self:RegisterChatCommand({ "/print" }, function(text)
2043 local f, err = loadstring("AceLibrary('AceConsole-2.0'):PrintComma(" .. text .. ")")
2044 if not f then
2045 self:Print("|cffff0000Error:|r", err)
2046 else
2047 f()
2048 end
2049 end, "PRINT")
2050
2051 self:activate(oldLib, oldDeactivate)
2052
2053 if oldDeactivate then
2054 oldDeactivate(oldLib)
2055 end
2056 end
2057
2058 AceLibrary:Register(AceConsole, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)