Nenue@0: -- User: Krakyn Nenue@0: -- Created: 11/30/2015 7:46 AM Nenue@0: if not LibStub then Nenue@0: print('Something has happened...') Nenue@0: end Nenue@0: Devian = LibStub("AceAddon-3.0"):NewAddon("Devian", "AceConsole-3.0", "AceEvent-3.0") Nenue@13: local MAJOR, MINOR = 'Devian-1.3', 'r@project-revision@' Nenue@0: local D = _G.Devian Nenue@0: local STATE_LOW, STATE_HIGH = 1, 2 Nenue@0: local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName() Nenue@13: local DEVIAN_FRAME = 'DevianConsole' Nenue@7: local print = function(...) Nenue@13: _G.print('Dvn', ...) Nenue@7: end Nenue@9: local db Nenue@13: local defaults = { Nenue@13: ['global'] = {[STATE_LOW] = {}, [STATE_HIGH] = {}}, Nenue@13: ['tags'] = {}, Nenue@13: ['channels'] = {[1] = {signature = 'Dvn', name = 'Main', header = "%n [%t]", x = 100, y = 800, height = 500, width = 600, enabled = true}}, Nenue@13: current_channel = 1, Nenue@13: console = true, Nenue@13: dnd_status = true, Nenue@13: dnd_message = "Debugging. Your messages may get eaten.", Nenue@13: font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]], Nenue@13: fontsize = 13, Nenue@13: fontoutline = 'NONE', Nenue@13: } Nenue@9: Nenue@4: Nenue@13: local function ScanAddOnList(cmd, ...) Nenue@0: local list_state Nenue@0: Nenue@13: local mode = tonumber(cmd:match("%d")) Nenue@0: Nenue@13: Nenue@13: print('Starting Addons scan. arg=', mode) Nenue@0: if mode == nil then Nenue@0: list_state = db.enabled and STATE_LOW or STATE_HIGH Nenue@0: db.enabled = (db.enabled == false) and true or false Nenue@0: print(list_state, db.enabled) Nenue@0: Nenue@0: if list_state == STATE_LOW then Nenue@0: end Nenue@0: Nenue@0: else Nenue@0: if mode > 2 then Nenue@13: print('Something has happened.') Nenue@0: return Nenue@0: end Nenue@0: list_state = mode == STATE_LOW and STATE_LOW or STATE_HIGH Nenue@0: Nenue@0: Nenue@0: end Nenue@0: local char_list, global_list = db[PLAYER_REALM][list_state], db.global[list_state] Nenue@0: Nenue@0: local playername = UnitName("player") Nenue@0: Nenue@0: for i = 1, GetNumAddOns() do Nenue@0: local name = GetAddOnInfo(i) Nenue@0: local enableState, globalState = GetAddOnEnableState(playername, i), GetAddOnEnableState(nil, i) Nenue@0: Nenue@0: if mode == STATE_LOW or mode == STATE_HIGH then Nenue@0: char_list[name] = enableState Nenue@0: global_list[name] = globalState Nenue@0: else Nenue@13: if char_list[name] or global_list[name] then Nenue@0: Nenue@0: if char_list[name] ~= 0 and global_list[name] ~= 0 then Nenue@0: local value = false Nenue@0: if char_list[name] == 2 and global_list[name] == 1 then Nenue@0: value = UnitName("player") Nenue@0: elseif global_list[name] == 2 then Nenue@0: value = true Nenue@0: end Nenue@0: print('EnableAddOn(', i, ',', value,')') Nenue@0: EnableAddOn(i, value) Nenue@0: else Nenue@0: local value = true Nenue@0: if char_list[name] == 2 and global_list[name] == 1 then Nenue@0: value = UnitName("player") Nenue@0: end Nenue@0: print('DisableAddOn(', i, ',', value,')') Nenue@0: DisableAddOn(i,value) Nenue@0: end Nenue@13: end Nenue@0: Nenue@0: end Nenue@0: end Nenue@0: Nenue@0: if mode == nil then Nenue@0: ReloadUI() Nenue@0: end Nenue@0: if mode == STATE_LOW then Nenue@0: D:Print('Developement AddOn list saved.') Nenue@0: else Nenue@0: D:Print('Standard AddOn list saved.') Nenue@0: end Nenue@0: end Nenue@0: Nenue@0: Nenue@13: local function Console_MinMax(self) Nenue@13: if self.minimized then Nenue@7: self:Maximize() Nenue@7: else Nenue@7: self:Minimize() Nenue@7: end Nenue@7: end Nenue@13: Nenue@13: local function Console_Minimize(self) Nenue@13: self:SetHeight(20) Nenue@13: self:SetMaxResize(GetScreenWidth(),20) Nenue@13: self.minimized = true Nenue@13: return self.out:Hide() Nenue@7: end Nenue@0: Nenue@13: local function Console_Maximize(self) Nenue@13: local db = db.channels[self.index] Nenue@13: self:SetHeight(db.height) Nenue@13: self:SetMaxResize(GetScreenWidth(),GetScreenHeight()) Nenue@13: self.minimized = nil Nenue@13: self.grip:SetTexture(0.5,0.5,0.5) Nenue@13: return self.out:Show() Nenue@13: end Nenue@13: Nenue@13: Nenue@13: local function Console_Save(self) Nenue@13: local db = db.channels[self.index] Nenue@13: db.y = (self:GetTop() - GetScreenHeight()) Nenue@13: db.x = self:GetLeft() Nenue@13: db.width = self:GetWidth() Nenue@13: if not self.minimized then Nenue@13: db.height = self:GetHeight() Nenue@13: db.minimized = nil Nenue@13: else Nenue@13: db.minimized = true Nenue@13: end Nenue@13: if self:IsVisible() then Nenue@13: db.enabled = true Nenue@13: else Nenue@13: db.enabled = nil Nenue@13: end Nenue@13: self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y) Nenue@13: end Nenue@13: Nenue@13: Nenue@13: local function Console_Toggle(input) Nenue@13: local key = input:gmatch("[%a%d]") Nenue@13: local search Nenue@13: if key and D.sig[key] then Nenue@13: search = {D.sig[key]} Nenue@13: elseif D.console[key] then Nenue@13: search = {D.console[key]} Nenue@13: else Nenue@13: search = D.console Nenue@13: end Nenue@13: Nenue@13: for _, c in ipairs(search) do Nenue@13: if c:IsVisible() then Nenue@13: c:Hide() Nenue@13: else Nenue@13: c:Show() Nenue@13: c:Maximize() Nenue@13: end Nenue@13: c:Save() Nenue@13: end Nenue@13: end Nenue@13: Nenue@13: -- Nenue@13: -- Nenue@13: -- Construct a console frame Nenue@13: local function CreateConsole(i, vars) Nenue@13: local f = CreateFrame('Frame', 'DevianChannelFrame' .. tostring(i), UIParent, DEVIAN_FRAME) Nenue@13: f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.channels[i].x, db.channels[i].y) Nenue@13: f:SetSize(vars.width, vars.height) Nenue@13: f:Lower() Nenue@13: f.out:SetFont(db.font, db.fontsize, db.fontoutline) Nenue@13: f.Save = Console_Save Nenue@13: f.Minimize = Console_Minimize Nenue@13: f.Maximize = Console_Maximize Nenue@13: f.MinMax = Console_MinMax Nenue@13: f.Toggle = D.Console_Toggle Nenue@13: f.name = vars.name Nenue@13: f.index = i Nenue@13: Nenue@13: if db.channels[i].enabled then Nenue@13: f:Show() Nenue@13: end Nenue@13: if db.channels[i].minimized then Nenue@13: f:Minimize() Nenue@13: end Nenue@13: Nenue@13: return f Nenue@13: end Nenue@13: Nenue@13: -- Nenue@13: -- Nenue@13: -- Send a message somewhere Nenue@0: local function Message(prefix, ...) Nenue@1: if prefix == nil then Nenue@13: prefix = 1 Nenue@1: end Nenue@9: Nenue@13: local channel Nenue@13: local byName = true Nenue@13: if D.sig[prefix] then Nenue@13: channel = D.sig[prefix] Nenue@13: elseif D.console[prefix] then Nenue@13: channel = D.console[prefix] Nenue@13: byName = nil Nenue@13: else Nenue@13: channel = D.console[1] Nenue@13: end Nenue@13: Nenue@13: Nenue@13: Nenue@9: -- color me timbers Nenue@9: local pcolor Nenue@13: if D.tags[prefix] then Nenue@9: pcolor = db.tags[prefix] Nenue@13: elseif byName then Nenue@0: local c = {0, 0, 0 } Nenue@0: local max = string.len(prefix) Nenue@0: for i = 1, max, 3 do Nenue@0: for k, v in ipairs(c) do Nenue@0: local j = i + (k - 1) Nenue@0: c[k] = c[k] + (j <= max and string.byte(prefix,j) or 0) Nenue@0: end Nenue@0: end Nenue@0: for k,v in ipairs(c) do Nenue@0: c[k] = c[k] % 255 Nenue@0: if c[k] < 64 then Nenue@0: c[k] = 0 Nenue@0: elseif c[k] > 127 then Nenue@0: c[k] = 255 Nenue@0: end Nenue@0: end Nenue@13: D.tags[prefix] = string.format('%02X%02X%02X', unpack(c)) Nenue@0: end Nenue@0: Nenue@13: local buffer = {'|cFF'.. D.tags[prefix]..prefix ..'|r'} Nenue@0: for i = 1, select('#',...) do Nenue@0: local var = select(i, ...) Nenue@0: Nenue@0: if type(var) == 'table' then Nenue@0: var = '' Nenue@0: elseif type(var) == 'boolean' then Nenue@0: var = var and 'true' or 'false' Nenue@0: elseif type(var) == 'function' then Nenue@0: var = '' Nenue@0: elseif type(var) == 'nil' then Nenue@0: var = 'nil' Nenue@0: end Nenue@0: Nenue@0: table.insert(buffer, var) Nenue@0: end Nenue@13: channel.out:AddMessage(table.concat(buffer, ' ')) Nenue@0: table.wipe(buffer) Nenue@0: end Nenue@0: Nenue@0: function D:OnEnable() Nenue@13: -- commands Nenue@13: local cmdlist = { Nenue@13: ['dvn'] = ScanAddOnList, Nenue@13: ['devian'] = ScanAddOnList, Nenue@13: ['dvc'] = Console_Toggle, Nenue@13: } Nenue@13: for cmd, func in pairs(cmdlist) do Nenue@13: self:RegisterChatCommand(cmd, func, true) Nenue@13: end Nenue@13: Nenue@11: if db.enabled == true then Nenue@0: D:Print('Standard AddOn list active. Type /dvn to switch to development mode.') Nenue@0: else Nenue@0: D:Print('Development AddOn list active. Type /dvn to revert to regular operation.') Nenue@0: end Nenue@13: Nenue@0: end Nenue@0: Nenue@5: Nenue@0: function D:OnInitialize() Nenue@13: -- emergency button Nenue@13: self:RegisterChatCommand("cleandvn", function(args) Nenue@13: DevianDB = nil Nenue@13: ReloadUI() Nenue@13: end) Nenue@13: Nenue@13: -- savedvars Nenue@13: local cherry = false Nenue@9: if not _G.DevianDB then Nenue@13: _G.DevianDB = defaults Nenue@13: cherry = "Type /dvnsave to snapshot your current UI" Nenue@9: end Nenue@9: db = _G.DevianDB Nenue@0: Nenue@0: if not db[PLAYER_REALM] then Nenue@9: db[PLAYER_REALM] = {[STATE_LOW] = {}, [STATE_HIGH] = {}} Nenue@0: if not cherry then Nenue@0: cherry = "This character didn't have an AddOn table." Nenue@0: end Nenue@0: end Nenue@0: Nenue@13: -- copy tags Nenue@13: self.tags = {} Nenue@13: for n, c in pairs(db.tags) do Nenue@13: self.tags[n] = c Nenue@13: end Nenue@0: if cherry then Nenue@0: D:Print(cherry) Nenue@0: end Nenue@0: D.oldprint = getprinthandler() Nenue@0: if not _G.oldprint then Nenue@0: _G.oldprint = D.oldprint Nenue@0: end Nenue@13: Nenue@13: self.console = {} Nenue@13: self.sig = {} Nenue@13: for i, cinfo in ipairs(db.channels) do Nenue@13: self.console[i] = CreateConsole(i, cinfo) Nenue@13: self.sig[cinfo.signature] = self.console[i] Nenue@13: end Nenue@0: setprinthandler(Message) Nenue@13: print(MAJOR, MINOR) Nenue@0: end