mirror of
https://github.com/Bluewhale1337/ElvUIModernized.git
synced 2026-07-27 08:24:44 +00:00
load Profile modules and settings (Import/Export) (NOT FINISHED)
@Bunny67 I need help finishing this.
This commit is contained in:
@@ -304,8 +304,8 @@ function E:PLAYER_ENTERING_WORLD()
|
||||
if(not self.MediaUpdated) then
|
||||
self:UpdateMedia()
|
||||
self.MediaUpdated = true
|
||||
else
|
||||
self:ScheduleTimer("CheckRole", 0.01)
|
||||
-- else
|
||||
-- self:ScheduleTimer("CheckRole", 0.01)
|
||||
end
|
||||
|
||||
local _, instanceType = IsInInstance()
|
||||
|
||||
@@ -0,0 +1,546 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local D = E:NewModule("Distributor", "AceEvent-3.0","AceTimer-3.0","AceComm-3.0","AceSerializer-3.0")
|
||||
local LibCompress = LibStub:GetLibrary("LibCompress");
|
||||
local LibBase64 = LibStub("LibBase64-1.0");
|
||||
|
||||
local tonumber, type, pcall, loadstring = tonumber, type, pcall, loadstring;
|
||||
local len, format, split, find = string.len, string.format, string.split, string.find;
|
||||
|
||||
local CreateFrame = CreateFrame;
|
||||
local GetNumRaidMembers, UnitInRaid = GetNumRaidMembers, UnitInRaid;
|
||||
local GetNumPartyMembers, UnitInParty = GetNumPartyMembers, UnitInParty;
|
||||
local ACCEPT, CANCEL, YES, NO = ACCEPT, CANCEL, YES, NO;
|
||||
|
||||
----------------------------------
|
||||
-- CONSTANTS
|
||||
----------------------------------
|
||||
|
||||
local REQUEST_PREFIX = "ELVUI_REQUEST"
|
||||
local REPLY_PREFIX = "ELVUI_REPLY"
|
||||
local TRANSFER_PREFIX = "ELVUI_TRANSFER"
|
||||
local TRANSFER_COMPLETE_PREFIX = "ELVUI_COMPLETE"
|
||||
|
||||
-- The active downloads
|
||||
local Downloads = {}
|
||||
local Uploads = {}
|
||||
|
||||
function D:Initialize()
|
||||
self:RegisterComm(REQUEST_PREFIX)
|
||||
self:RegisterEvent("CHAT_MSG_ADDON")
|
||||
|
||||
self.statusBar = CreateFrame("StatusBar", "ElvUI_Download", UIParent)
|
||||
E:RegisterStatusBar(self.statusBar);
|
||||
E:CreateBackdrop(self.statusBar, "Default")
|
||||
self.statusBar:SetStatusBarTexture(E.media.normTex)
|
||||
self.statusBar:SetStatusBarColor(0.95, 0.15, 0.15)
|
||||
self.statusBar:SetWidth(250)
|
||||
self.statusBar:SetWidth(18)
|
||||
self.statusBar.text = self.statusBar:CreateFontString(nil, "OVERLAY")
|
||||
E:FontTemplate(self.statusBar.text)
|
||||
self.statusBar.text:SetPoint("CENTER", 0, 0)
|
||||
self.statusBar:Hide()
|
||||
end
|
||||
|
||||
-- Used to start uploads
|
||||
function D:Distribute(target, otherServer, isGlobal)
|
||||
local profileKey, data;
|
||||
if not isGlobal then
|
||||
if ElvDB.profileKeys then
|
||||
profileKey = ElvDB.profileKeys[E.myname.." - "..E.myrealm]
|
||||
end
|
||||
|
||||
data = ElvDB.profiles[profileKey]
|
||||
else
|
||||
profileKey = "global"
|
||||
data = ElvDB.global
|
||||
end
|
||||
|
||||
if not data or not profileKey then return end
|
||||
|
||||
local serialData = self:Serialize(data)
|
||||
local length = len(serialData)
|
||||
local message = format("%s:%d:%s", profileKey, length, target)
|
||||
|
||||
Uploads[profileKey] = {
|
||||
serialData = serialData,
|
||||
target = target,
|
||||
}
|
||||
|
||||
if otherServer then
|
||||
local numParty, numRaid = GetNumPartyMembers(), GetNumRaidMembers();
|
||||
if(numRaid > 0 and UnitInRaid("target")) then
|
||||
self:SendCommMessage(REQUEST_PREFIX, message, "RAID");
|
||||
elseif(numParty > 0 and UnitInParty("target")) then
|
||||
self:SendCommMessage(REQUEST_PREFIX, message, "PARTY");
|
||||
else
|
||||
E:Print(L["Must be in group with the player if he isn't on the same server as you."])
|
||||
return
|
||||
end
|
||||
else
|
||||
self:SendCommMessage(REQUEST_PREFIX, message, "WHISPER", target)
|
||||
end
|
||||
self:RegisterComm(REPLY_PREFIX)
|
||||
E:StaticPopup_Show("DISTRIBUTOR_WAITING")
|
||||
end
|
||||
|
||||
function D:CHAT_MSG_ADDON(_, _, message, _, sender)
|
||||
if not Downloads[sender] then return end
|
||||
local cur = len(message)
|
||||
local max = Downloads[sender].length
|
||||
Downloads[sender].current = Downloads[sender].current + cur
|
||||
|
||||
if Downloads[sender].current > max then
|
||||
Downloads[sender].current = max
|
||||
end
|
||||
|
||||
self.statusBar:SetValue(Downloads[sender].current)
|
||||
end
|
||||
|
||||
function D:OnCommReceived(prefix, msg, dist, sender)
|
||||
if prefix == REQUEST_PREFIX then
|
||||
local profile, length, sendTo = split(":", msg)
|
||||
|
||||
if dist ~= "WHISPER" and sendTo ~= E.myname then
|
||||
return
|
||||
end
|
||||
|
||||
if self.statusBar:IsShown() then
|
||||
self:SendCommMessage(REPLY_PREFIX, profile..":NO", dist, sender)
|
||||
return
|
||||
end
|
||||
|
||||
local textString = format(L["%s is attempting to share the profile %s with you. Would you like to accept the request?"], sender, profile)
|
||||
if profile == "global" then
|
||||
textString = format(L["%s is attempting to share his filters with you. Would you like to accept the request?"], sender)
|
||||
end
|
||||
|
||||
E.PopupDialogs["DISTRIBUTOR_RESPONSE"] = {
|
||||
text = textString,
|
||||
OnAccept = function()
|
||||
self.statusBar:SetMinMaxValues(0, length)
|
||||
self.statusBar:SetValue(0)
|
||||
self.statusBar.text:SetFormattedText(L["Data From: %s"], sender)
|
||||
E:StaticPopupSpecial_Show(self.statusBar)
|
||||
self:SendCommMessage(REPLY_PREFIX, profile..":YES", dist, sender)
|
||||
end,
|
||||
OnCancel = function()
|
||||
self:SendCommMessage(REPLY_PREFIX, profile..":NO", dist, sender)
|
||||
end,
|
||||
button1 = ACCEPT,
|
||||
button2 = CANCEL,
|
||||
timeout = 32,
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1,
|
||||
}
|
||||
E:StaticPopup_Show("DISTRIBUTOR_RESPONSE")
|
||||
|
||||
Downloads[sender] = {
|
||||
current = 0,
|
||||
length = tonumber(length),
|
||||
profile = profile,
|
||||
}
|
||||
|
||||
self:RegisterComm(TRANSFER_PREFIX)
|
||||
elseif prefix == REPLY_PREFIX then
|
||||
self:UnregisterComm(REPLY_PREFIX)
|
||||
E:StaticPopup_Hide("DISTRIBUTOR_WAITING")
|
||||
|
||||
local profileKey, response = split(":", msg)
|
||||
if response == "YES" then
|
||||
self:RegisterComm(TRANSFER_COMPLETE_PREFIX)
|
||||
self:SendCommMessage(TRANSFER_PREFIX, Uploads[profileKey].serialData, dist, Uploads[profileKey].target)
|
||||
Uploads[profileKey] = nil
|
||||
else
|
||||
E:StaticPopup_Show("DISTRIBUTOR_REQUEST_DENIED")
|
||||
Uploads[profileKey] = nil
|
||||
end
|
||||
elseif prefix == TRANSFER_PREFIX then
|
||||
self:UnregisterComm(TRANSFER_PREFIX)
|
||||
E:StaticPopupSpecial_Hide(self.statusBar)
|
||||
|
||||
local profileKey = Downloads[sender].profile
|
||||
local success, data = self:Deserialize(msg)
|
||||
|
||||
if success then
|
||||
local textString = format(L["Profile download complete from %s, would you like to load the profile %s now?"], sender, profileKey)
|
||||
|
||||
if profileKey == "global" then
|
||||
textString = format(L["Filter download complete from %s, would you like to apply changes now?"], sender)
|
||||
else
|
||||
if not ElvDB.profiles[profileKey] then
|
||||
ElvDB.profiles[profileKey] = data
|
||||
else
|
||||
textString = format(L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."], sender, profileKey)
|
||||
E.PopupDialogs["DISTRIBUTOR_CONFIRM"] = {
|
||||
text = textString,
|
||||
button1 = ACCEPT,
|
||||
hasEditBox = 1,
|
||||
editBoxWidth = 350,
|
||||
maxLetters = 127,
|
||||
OnAccept = function(self)
|
||||
ElvDB.profiles[self.editBox:GetText()] = data
|
||||
LibStub("AceAddon-3.0"):GetAddon("ElvUI").data:SetProfile(self.editBox:GetText())
|
||||
E:UpdateAll(true)
|
||||
Downloads[sender] = nil
|
||||
end,
|
||||
OnShow = function(self) self.editBox:SetText(profileKey) self.editBox:SetFocus() end,
|
||||
timeout = 0,
|
||||
exclusive = 1,
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1,
|
||||
preferredIndex = 3
|
||||
}
|
||||
|
||||
E:StaticPopup_Show("DISTRIBUTOR_CONFIRM")
|
||||
self:SendCommMessage(TRANSFER_COMPLETE_PREFIX, "COMPLETE", dist, sender)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
E.PopupDialogs["DISTRIBUTOR_CONFIRM"] = {
|
||||
text = textString,
|
||||
OnAccept = function()
|
||||
if profileKey == "global" then
|
||||
E:CopyTable(ElvDB.global, data)
|
||||
E:UpdateAll(true)
|
||||
else
|
||||
LibStub("AceAddon-3.0"):GetAddon("ElvUI").data:SetProfile(profileKey)
|
||||
end
|
||||
Downloads[sender] = nil
|
||||
end,
|
||||
OnCancel = function()
|
||||
Downloads[sender] = nil
|
||||
end,
|
||||
button1 = YES,
|
||||
button2 = NO,
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1,
|
||||
}
|
||||
|
||||
E:StaticPopup_Show("DISTRIBUTOR_CONFIRM")
|
||||
self:SendCommMessage(TRANSFER_COMPLETE_PREFIX, "COMPLETE", dist, sender)
|
||||
else
|
||||
E:StaticPopup_Show("DISTRIBUTOR_FAILED")
|
||||
self:SendCommMessage(TRANSFER_COMPLETE_PREFIX, "FAILED", dist, sender)
|
||||
end
|
||||
elseif prefix == TRANSFER_COMPLETE_PREFIX then
|
||||
self:UnregisterComm(TRANSFER_COMPLETE_PREFIX)
|
||||
if msg == "COMPLETE" then
|
||||
E:StaticPopup_Show("DISTRIBUTOR_SUCCESS")
|
||||
else
|
||||
E:StaticPopup_Show("DISTRIBUTOR_FAILED")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function GetProfileData(profileType)
|
||||
if(not profileType or type(profileType) ~= "string") then
|
||||
E:Print("Bad argument #1 to 'GetProfileData' (string expected)");
|
||||
return;
|
||||
end
|
||||
|
||||
local profileKey;
|
||||
local profileData = {};
|
||||
|
||||
if(profileType == "profile") then
|
||||
if(ElvDB.profileKeys) then
|
||||
profileKey = ElvDB.profileKeys[E.myname.." - "..E.myrealm];
|
||||
end
|
||||
|
||||
profileData = E:CopyTable(profileData , ElvDB.profiles[profileKey])
|
||||
profileData = E:RemoveTableDuplicates(profileData, P);
|
||||
elseif(profileType == "private") then
|
||||
local privateProfileKey = E.myname.." - "..E.myrealm;
|
||||
profileKey = "private";
|
||||
|
||||
profileData = E:CopyTable(profileData, ElvPrivateDB.profiles[privateProfileKey]);
|
||||
profileData = E:RemoveTableDuplicates(profileData, V);
|
||||
elseif(profileType == "global") then
|
||||
profileKey = "global";
|
||||
|
||||
profileData = E:CopyTable(profileData, ElvDB.global);
|
||||
profileData = E:RemoveTableDuplicates(profileData, G);
|
||||
elseif(profileType == "filtersNP") then
|
||||
profileKey = "filtersNP";
|
||||
|
||||
profileData["nameplates"] = {};
|
||||
profileData["nameplates"]["filter"] = {};
|
||||
profileData["nameplates"]["filter"] = E:CopyTable(profileData["nameplates"]["filter"], ElvDB.global.nameplates.filter);
|
||||
profileData = E:RemoveTableDuplicates(profileData, G);
|
||||
elseif(profileType == "filtersUF") then
|
||||
profileKey = "filtersUF";
|
||||
|
||||
profileData["unitframe"] = {};
|
||||
profileData["unitframe"]["aurafilters"] = {};
|
||||
profileData["unitframe"]["aurafilters"] = E:CopyTable(profileData["unitframe"]["aurafilters"], ElvDB.global.unitframe.aurafilters);
|
||||
profileData["unitframe"]["buffwatch"] = {};
|
||||
profileData["unitframe"]["buffwatch"] = E:CopyTable(profileData["unitframe"]["buffwatch"], ElvDB.global.unitframe.buffwatch);
|
||||
profileData = E:RemoveTableDuplicates(profileData, G);
|
||||
elseif(profileType == "filtersAll") then
|
||||
profileKey = "filtersAll";
|
||||
|
||||
profileData["nameplates"] = {};
|
||||
profileData["nameplates"]["filter"] = {};
|
||||
profileData["nameplates"]["filter"] = E:CopyTable(profileData["nameplates"]["filter"], ElvDB.global.nameplates.filter);
|
||||
profileData["unitframe"] = {};
|
||||
profileData["unitframe"]["aurafilters"] = {};
|
||||
profileData["unitframe"]["aurafilters"] = E:CopyTable(profileData["unitframe"]["aurafilters"], ElvDB.global.unitframe.aurafilters);
|
||||
profileData["unitframe"]["buffwatch"] = {};
|
||||
profileData["unitframe"]["buffwatch"] = E:CopyTable(profileData["unitframe"]["buffwatch"], ElvDB.global.unitframe.buffwatch);
|
||||
profileData = E:RemoveTableDuplicates(profileData, G);
|
||||
end
|
||||
|
||||
return profileKey, profileData;
|
||||
end
|
||||
|
||||
local function GetProfileExport(profileType, exportFormat)
|
||||
local profileExport, exportString;
|
||||
local profileKey, profileData = GetProfileData(profileType);
|
||||
|
||||
if(not profileKey or not profileData or (profileData and type(profileData) ~= "table")) then
|
||||
E:Print("Error getting data from 'GetProfileData'");
|
||||
return;
|
||||
end
|
||||
|
||||
if(exportFormat == "text") then
|
||||
local serialData = D:Serialize(profileData);
|
||||
|
||||
exportString = D:CreateProfileExport(serialData, profileType, profileKey);
|
||||
|
||||
local compressedData = LibCompress:Compress(exportString);
|
||||
local encodedData = LibBase64:Encode(compressedData);
|
||||
profileExport = encodedData;
|
||||
elseif(exportFormat == "luaTable") then
|
||||
exportString = E:TableToLuaString(profileData);
|
||||
profileExport = D:CreateProfileExport(exportString, profileType, profileKey);
|
||||
elseif(exportFormat == "luaPlugin") then
|
||||
profileExport = E:ProfileTableToPluginFormat(profileData, profileType);
|
||||
end
|
||||
|
||||
return profileKey, profileExport;
|
||||
end
|
||||
|
||||
function D:CreateProfileExport(dataString, profileType, profileKey)
|
||||
local returnString;
|
||||
|
||||
if(profileType == "profile") then
|
||||
returnString = format("%s::%s::%s", dataString, profileType, profileKey);
|
||||
else
|
||||
returnString = format("%s::%s", dataString, profileType);
|
||||
end
|
||||
|
||||
return returnString;
|
||||
end
|
||||
|
||||
function D:GetImportStringType(dataString)
|
||||
local stringType = "";
|
||||
|
||||
if(LibBase64:IsBase64(dataString)) then
|
||||
stringType = "Base64";
|
||||
elseif(find(dataString, "{")) then
|
||||
stringType = "Table";
|
||||
end
|
||||
|
||||
return stringType;
|
||||
end
|
||||
|
||||
function D:Decode(dataString)
|
||||
local profileInfo, profileType, profileKey, profileData, message;
|
||||
local stringType = self:GetImportStringType(dataString);
|
||||
|
||||
if(stringType == "Base64") then
|
||||
local decodedData = LibBase64:Decode(dataString);
|
||||
local decompressedData, message = LibCompress:Decompress(decodedData);
|
||||
|
||||
if(not decompressedData) then
|
||||
E:Print("Error decompressing data:", message);
|
||||
return;
|
||||
end
|
||||
|
||||
local serializedData, success;
|
||||
serializedData, profileInfo = E:StringSplitMultiDelim(decompressedData, "^^::");
|
||||
|
||||
if not profileInfo then
|
||||
E:Print("Error importing profile. String is invalid or corrupted!")
|
||||
return
|
||||
end
|
||||
|
||||
serializedData = format("%s%s", serializedData, "^^");
|
||||
profileType, profileKey = E:StringSplitMultiDelim(profileInfo, "::");
|
||||
success, profileData = D:Deserialize(serializedData);
|
||||
|
||||
if(not success) then
|
||||
E:Print("Error deserializing:", profileData);
|
||||
return;
|
||||
end
|
||||
elseif(stringType == "Table") then
|
||||
local profileDataAsString;
|
||||
profileDataAsString, profileInfo = E:StringSplitMultiDelim(dataString, "}::");
|
||||
|
||||
if not profileInfo then
|
||||
E:Print("Error extracting profile info. Invalid import string!")
|
||||
return
|
||||
end
|
||||
|
||||
if(not profileDataAsString) then
|
||||
E:Print("Error extracting profile data. Invalid import string!");
|
||||
return;
|
||||
end
|
||||
|
||||
profileDataAsString = format("%s%s", profileDataAsString, "}");
|
||||
profileType, profileKey = E:StringSplitMultiDelim(profileInfo, "::");
|
||||
|
||||
local profileToTable = loadstring(format("%s %s", "return", profileDataAsString));
|
||||
if(profileToTable) then
|
||||
message, profileData = pcall(profileToTable);
|
||||
end
|
||||
|
||||
if(not profileData or type(profileData) ~= "table") then
|
||||
E:Print("Error converting lua string to table:", message);
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
return profileType, profileKey, profileData;
|
||||
end
|
||||
|
||||
local function SetImportedProfile(profileType, profileKey, profileData, force)
|
||||
D.profileType = nil;
|
||||
D.profileKey = nil;
|
||||
D.profileData = nil;
|
||||
|
||||
if(profileType == "profile") then
|
||||
if(not ElvDB.profiles[profileKey] or force) then
|
||||
if(force and E.data.keys.profile == profileKey) then
|
||||
local tempKey = profileKey.."_Temp";
|
||||
E.data.keys.profile = tempKey;
|
||||
end
|
||||
ElvDB.profiles[profileKey] = profileData;
|
||||
E.data:SetProfile(profileKey);
|
||||
else
|
||||
D.profileType = profileType;
|
||||
D.profileKey = profileKey;
|
||||
D.profileData = profileData;
|
||||
E:StaticPopup_Show("IMPORT_PROFILE_EXISTS");
|
||||
|
||||
return;
|
||||
end
|
||||
elseif(profileType == "private") then
|
||||
local profileKey = ElvPrivateDB.profileKeys[E.myname.." - "..E.myrealm];
|
||||
ElvPrivateDB.profiles[profileKey] = profileData;
|
||||
E:StaticPopup_Show("IMPORT_RL");
|
||||
|
||||
elseif(profileType == "global") then
|
||||
E:CopyTable(ElvDB.global, profileData);
|
||||
E:StaticPopup_Show("IMPORT_RL");
|
||||
elseif(profileType == "filtersNP") then
|
||||
E:CopyTable(ElvDB.global.nameplates, profileData.nameplates);
|
||||
elseif(profileType == "filtersUF") then
|
||||
E:CopyTable(ElvDB.global.unitframe, profileData.unitframe);
|
||||
elseif(profileType == "filtersAll") then
|
||||
E:CopyTable(ElvDB.global.nameplates, profileData.nameplates);
|
||||
E:CopyTable(ElvDB.global.unitframe, profileData.unitframe);
|
||||
end
|
||||
|
||||
E:UpdateAll(true);
|
||||
end
|
||||
|
||||
function D:ExportProfile(profileType, exportFormat)
|
||||
if(not profileType or not exportFormat) then
|
||||
E:Print("Bad argument to 'ExportProfile' (string expected)");
|
||||
return;
|
||||
end
|
||||
|
||||
local profileKey, profileExport = GetProfileExport(profileType, exportFormat);
|
||||
return profileKey, profileExport;
|
||||
end
|
||||
|
||||
function D:ImportProfile(dataString)
|
||||
local profileType, profileKey, profileData = self:Decode(dataString);
|
||||
|
||||
if(not profileData or type(profileData) ~= "table") then
|
||||
E:Print("Error: something went wrong when converting string to table!");
|
||||
return;
|
||||
end
|
||||
|
||||
if(profileType and ((profileType == "profile" and profileKey) or profileType ~= "profile")) then
|
||||
SetImportedProfile(profileType, profileKey, profileData);
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
E.PopupDialogs["DISTRIBUTOR_SUCCESS"] = {
|
||||
text = L["Your profile was successfully recieved by the player."],
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1,
|
||||
button1 = OKAY,
|
||||
}
|
||||
|
||||
E.PopupDialogs["DISTRIBUTOR_WAITING"] = {
|
||||
text = L["Profile request sent. Waiting for response from player."],
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1,
|
||||
timeout = 35,
|
||||
}
|
||||
|
||||
E.PopupDialogs["DISTRIBUTOR_REQUEST_DENIED"] = {
|
||||
text = L["Request was denied by user."],
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1,
|
||||
button1 = OKAY,
|
||||
}
|
||||
|
||||
E.PopupDialogs["DISTRIBUTOR_FAILED"] = {
|
||||
text = L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"],
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1,
|
||||
button1 = OKAY,
|
||||
}
|
||||
|
||||
E.PopupDialogs["DISTRIBUTOR_RESPONSE"] = {}
|
||||
E.PopupDialogs["DISTRIBUTOR_CONFIRM"] = {}
|
||||
|
||||
E.PopupDialogs["IMPORT_PROFILE_EXISTS"] = {
|
||||
text = L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."],
|
||||
button1 = ACCEPT,
|
||||
button2 = CANCEL,
|
||||
hasEditBox = 1,
|
||||
editBoxWidth = 350,
|
||||
maxLetters = 127,
|
||||
OnAccept = function(self)
|
||||
local profileType = D.profileType;
|
||||
local profileKey = self.editBox:GetText();
|
||||
local profileData = D.profileData;
|
||||
SetImportedProfile(profileType, profileKey, profileData, true);
|
||||
end,
|
||||
EditBoxOnTextChanged = function(self)
|
||||
if(self:GetText() == "") then
|
||||
self:GetParent().button1:Disable();
|
||||
else
|
||||
self:GetParent().button1:Enable();
|
||||
end
|
||||
end,
|
||||
OnShow = function(self) self.editBox:SetText(D.profileKey); self.editBox:SetFocus(); end,
|
||||
timeout = 0,
|
||||
whileDead = 1,
|
||||
hideOnEscape = true,
|
||||
preferredIndex = 3
|
||||
};
|
||||
|
||||
E.PopupDialogs["IMPORT_RL"] = {
|
||||
text = L["You have imported settings which may require a UI reload to take effect. Reload now?"],
|
||||
button1 = ACCEPT,
|
||||
button2 = CANCEL,
|
||||
OnAccept = ReloadUI,
|
||||
timeout = 0,
|
||||
whileDead = 1,
|
||||
hideOnEscape = false,
|
||||
preferredIndex = 3
|
||||
};
|
||||
|
||||
local function InitializeCallback()
|
||||
D:Initialize()
|
||||
end
|
||||
|
||||
E:RegisterModule(D:GetName(), InitializeCallback)
|
||||
@@ -6,34 +6,50 @@ Description: A library to encode and decode Base64 strings
|
||||
License: MIT
|
||||
]]
|
||||
|
||||
local LibBase64 = LibStub:NewLibrary("LibBase64-1.0-ElvUI", 1)
|
||||
local modf = math.modf
|
||||
local sub = string.sub
|
||||
local format = string.format
|
||||
local getn = table.getn
|
||||
local gsub = string.gsub
|
||||
local strlen = string.len
|
||||
local byte = string.byte
|
||||
|
||||
local LibBase64 = LibStub:NewLibrary("LibBase64-1.0", 1)
|
||||
|
||||
if not LibBase64 then
|
||||
return
|
||||
end
|
||||
|
||||
local _chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
local chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
local charTable = {}
|
||||
local byteToNum = {}
|
||||
local numToChar = {}
|
||||
for i = 1, #_chars do
|
||||
numToChar[i - 1] = _chars:sub(i, i)
|
||||
byteToNum[_chars:byte(i)] = i - 1
|
||||
|
||||
for i = 1, strlen(chars) do
|
||||
charTable[i] = sub(chars, i, i)
|
||||
end
|
||||
_chars = nil
|
||||
local A_byte = ("A"):byte()
|
||||
local Z_byte = ("Z"):byte()
|
||||
local a_byte = ("a"):byte()
|
||||
local z_byte = ("z"):byte()
|
||||
local zero_byte = ("0"):byte()
|
||||
local nine_byte = ("9"):byte()
|
||||
local plus_byte = ("+"):byte()
|
||||
local slash_byte = ("/"):byte()
|
||||
local equals_byte = ("="):byte()
|
||||
|
||||
for i = 1, getn(charTable) do
|
||||
numToChar[i - 1] = sub(chars, i, i)
|
||||
byteToNum[byte(chars, i)] = i - 1
|
||||
end
|
||||
|
||||
charTable = nil
|
||||
|
||||
local A_byte = byte("A")
|
||||
local Z_byte = byte("Z")
|
||||
local a_byte = byte("a")
|
||||
local z_byte = byte("z")
|
||||
local zero_byte = byte("0")
|
||||
local nine_byte = byte("9")
|
||||
local plus_byte = byte("+")
|
||||
local slash_byte = byte("/")
|
||||
local equals_byte = byte("=")
|
||||
local whitespace = {
|
||||
[(" "):byte()] = true,
|
||||
[("\t"):byte()] = true,
|
||||
[("\n"):byte()] = true,
|
||||
[("\r"):byte()] = true,
|
||||
[byte(" ")] = true,
|
||||
[byte("\t")] = true,
|
||||
[byte("\n")] = true,
|
||||
[byte("\r")] = true,
|
||||
}
|
||||
|
||||
local t = {}
|
||||
@@ -46,29 +62,29 @@ local t = {}
|
||||
-- @return a Base64-encoded string
|
||||
function LibBase64:Encode(text, maxLineLength, lineEnding)
|
||||
if type(text) ~= "string" then
|
||||
error(("Bad argument #1 to `Encode'. Expected %q, got %q"):format("string", type(text)), 2)
|
||||
error(format("Bad argument #1 to `Encode'. Expected %q, got %q", "string", type(text)), 2)
|
||||
end
|
||||
|
||||
if maxLineLength == nil then
|
||||
-- do nothing
|
||||
elseif type(maxLineLength) ~= "number" then
|
||||
error(("Bad argument #2 to `Encode'. Expected %q or %q, got %q"):format("number", "nil", type(maxLineLength)), 2)
|
||||
elseif (maxLineLength % 4) ~= 0 then
|
||||
error(("Bad argument #2 to `Encode'. Expected a multiple of 4, got %s"):format(maxLineLength), 2)
|
||||
error(format("Bad argument #2 to `Encode'. Expected %q or %q, got %q", "number", "nil", type(maxLineLength)), 2)
|
||||
elseif modf(maxLineLength, 4) ~= 0 then
|
||||
error(format("Bad argument #2 to `Encode'. Expected a multiple of 4, got %s", maxLineLength), 2)
|
||||
elseif maxLineLength <= 0 then
|
||||
error(("Bad argument #2 to `Encode'. Expected a number > 0, got %s"):format(maxLineLength), 2)
|
||||
error(format("Bad argument #2 to `Encode'. Expected a number > 0, got %s", maxLineLength), 2)
|
||||
end
|
||||
|
||||
if lineEnding == nil then
|
||||
lineEnding = "\r\n"
|
||||
elseif type(lineEnding) ~= "string" then
|
||||
error(("Bad argument #3 to `Encode'. Expected %q, got %q"):format("string", type(lineEnding)), 2)
|
||||
error(format("Bad argument #3 to `Encode'. Expected %q, got %q", "string", type(lineEnding)), 2)
|
||||
end
|
||||
|
||||
local currentLength = 0
|
||||
|
||||
for i = 1, #text, 3 do
|
||||
local a, b, c = text:byte(i, i+2)
|
||||
for i = 1, getn(text), 3 do
|
||||
local a, b, c = byte(text, i, i+2)
|
||||
local nilNum = 0
|
||||
if not b then
|
||||
nilNum = 2
|
||||
@@ -80,33 +96,33 @@ function LibBase64:Encode(text, maxLineLength, lineEnding)
|
||||
end
|
||||
local num = a * 2^16 + b * 2^8 + c
|
||||
|
||||
local d = num % 2^6
|
||||
local d = modf(num, 2^6)
|
||||
num = (num - d) / 2^6
|
||||
|
||||
local c = num % 2^6
|
||||
local c = modf(num, 2^6)
|
||||
num = (num - c) / 2^6
|
||||
|
||||
local b = num % 2^6
|
||||
local b = modf(num, 2^6)
|
||||
num = (num - b) / 2^6
|
||||
|
||||
local a = num % 2^6
|
||||
local a = modf(num, 2^6)
|
||||
|
||||
t[#t+1] = numToChar[a]
|
||||
t[getn(t+1)] = numToChar[a]
|
||||
|
||||
t[#t+1] = numToChar[b]
|
||||
t[getn(t+1)] = numToChar[b]
|
||||
|
||||
t[#t+1] = (nilNum >= 2) and "=" or numToChar[c]
|
||||
t[getn(t+1)] = (nilNum >= 2) and "=" or numToChar[c]
|
||||
|
||||
t[#t+1] = (nilNum >= 1) and "=" or numToChar[d]
|
||||
t[getn(t+1)] = (nilNum >= 1) and "=" or numToChar[d]
|
||||
|
||||
currentLength = currentLength + 4
|
||||
if maxLineLength and (currentLength % maxLineLength) == 0 then
|
||||
t[#t+1] = lineEnding
|
||||
if maxLineLength and modf(currentLength, maxLineLength) == 0 then
|
||||
t[getn(t+1)] = lineEnding
|
||||
end
|
||||
end
|
||||
|
||||
local s = table.concat(t)
|
||||
for i = 1, #t do
|
||||
for i = 1, getn(t) do
|
||||
t[i] = nil
|
||||
end
|
||||
return s
|
||||
@@ -122,27 +138,27 @@ local t2 = {}
|
||||
-- @return a bytestring
|
||||
function LibBase64:Decode(text)
|
||||
if type(text) ~= "string" then
|
||||
error(("Bad argument #1 to `Decode'. Expected %q, got %q"):format("string", type(text)), 2)
|
||||
error(format("Bad argument #1 to `Decode'. Expected %q, got %q", "string", type(text)), 2)
|
||||
end
|
||||
|
||||
for i = 1, #text do
|
||||
local byte = text:byte(i)
|
||||
for i = 1, getn(text) do
|
||||
local byte = byte(text, i)
|
||||
if whitespace[byte] or byte == equals_byte then
|
||||
-- do nothing
|
||||
else
|
||||
local num = byteToNum[byte]
|
||||
if not num then
|
||||
for i = 1, #t2 do
|
||||
for i = 1, getn(t2) do
|
||||
t2[k] = nil
|
||||
end
|
||||
|
||||
error(("Bad argument #1 to `Decode'. Received an invalid char: %q"):format(text:sub(i, i)), 2)
|
||||
error(format("Bad argument #1 to `Decode'. Received an invalid char: %q", sub(text, i, i)), 2)
|
||||
end
|
||||
t2[#t2+1] = num
|
||||
t2[getn(t2+1)] = num
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #t2, 4 do
|
||||
for i = 1, getn(t2), 4 do
|
||||
local a, b, c, d = t2[i], t2[i+1], t2[i+2], t2[i+3]
|
||||
|
||||
local nilNum = 0
|
||||
@@ -157,30 +173,30 @@ function LibBase64:Decode(text)
|
||||
|
||||
local num = a * 2^18 + b * 2^12 + c * 2^6 + d
|
||||
|
||||
local c = num % 2^8
|
||||
local c = modf(num, 2^8)
|
||||
num = (num - c) / 2^8
|
||||
|
||||
local b = num % 2^8
|
||||
local b = modf(num, 2^8)
|
||||
num = (num - b) / 2^8
|
||||
|
||||
local a = num % 2^8
|
||||
local a = modf(num, 2^8)
|
||||
|
||||
t[#t+1] = string.char(a)
|
||||
t[getn(t+1)] = string.char(a)
|
||||
if nilNum < 2 then
|
||||
t[#t+1] = string.char(b)
|
||||
t[getn(t+1)] = string.char(b)
|
||||
end
|
||||
if nilNum < 1 then
|
||||
t[#t+1] = string.char(c)
|
||||
t[getn(t+1)] = string.char(c)
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #t2 do
|
||||
for i = 1, getn(t2) do
|
||||
t2[i] = nil
|
||||
end
|
||||
|
||||
local s = table.concat(t)
|
||||
|
||||
for i = 1, #t do
|
||||
for i = 1, getn(t) do
|
||||
t[i] = nil
|
||||
end
|
||||
|
||||
@@ -189,15 +205,15 @@ end
|
||||
|
||||
function LibBase64:IsBase64(text)
|
||||
if type(text) ~= "string" then
|
||||
error(("Bad argument #1 to `IsBase64'. Expected %q, got %q"):format("string", type(text)), 2)
|
||||
error(format("Bad argument #1 to `IsBase64'. Expected %q, got %q", "string", type(text)), 2)
|
||||
end
|
||||
|
||||
if #text % 4 ~= 0 then
|
||||
if modf(strlen(text), 4 ~= 0) then
|
||||
return false
|
||||
end
|
||||
|
||||
for i = 1, #text do
|
||||
local byte = text:byte(i)
|
||||
for i = 1, getn(text) do
|
||||
local byte = byte(text, i)
|
||||
if whitespace[byte] or byte == equals_byte then
|
||||
-- do nothing
|
||||
else
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,11 +16,9 @@
|
||||
<Include file="LibDataBroker\LibDataBroker-1.1.xml"/>
|
||||
<Include file="LibElvUIPlugin-1.0\LibElvUIPlugin-1.0.xml"/>
|
||||
<Include file="oUF\oUF.xml"/>
|
||||
<!--
|
||||
<Include file="UTF8\UTF8.xml"/>
|
||||
<Include file="LibCompress\LibCompress.xml"/>
|
||||
<Include file="LibBase64-1.0\LibBase64-1.0.xml"/>
|
||||
-->
|
||||
<Include file="LibAnim\LibAnim.xml"/>
|
||||
<Include file="LibUIDropDownMenu\LibUIDropDownMenu.xml"/>
|
||||
</Ui>
|
||||
@@ -1,5 +1,5 @@
|
||||
local E, L, V, P, G = unpack(ElvUI);
|
||||
--local D = E:GetModule("Distributor");
|
||||
local D = E:GetModule("Distributor");
|
||||
local AceGUI = LibStub("AceGUI-3.0");
|
||||
|
||||
local pairs = pairs;
|
||||
@@ -161,5 +161,303 @@ for _, testerName in pairs(TESTERS) do
|
||||
TESTER_STRING = TESTER_STRING .. LINE_BREAK .. testerName;
|
||||
end
|
||||
|
||||
E.Options.args.credits = {
|
||||
type = "group",
|
||||
name = L["Credits"],
|
||||
order = -1,
|
||||
args = {
|
||||
text = {
|
||||
order = 1,
|
||||
type = "description",
|
||||
name = L["ELVUI_CREDITS"] .. "\n\n" .. L["Coding:"] .. DEVELOPER_STRING .. "\n\n" .. L["Testing:"] .. TESTER_STRING .. "\n\n" .. L["Donations:"] .. DONATOR_STRING
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local profileTypeItems = {
|
||||
["profile"] = L["Profile"],
|
||||
["private"] = L["Private (Character Settings)"],
|
||||
["global"] = L["Global (Account Settings)"],
|
||||
["filtersNP"] = L["Filters (NamePlates)"],
|
||||
["filtersUF"] = L["Filters (UnitFrames)"],
|
||||
["filtersAll"] = L["Filters (All)"]
|
||||
}
|
||||
|
||||
local profileTypeListOrder = {
|
||||
"profile",
|
||||
"private",
|
||||
"global",
|
||||
"filtersNP",
|
||||
"filtersUF",
|
||||
"filtersAll"
|
||||
}
|
||||
|
||||
local exportTypeItems = {
|
||||
["text"] = L["Text"],
|
||||
["luaTable"] = L["Table"],
|
||||
["luaPlugin"] = L["Plugin"]
|
||||
}
|
||||
|
||||
local exportTypeListOrder = {
|
||||
"text",
|
||||
"luaTable",
|
||||
"luaPlugin"
|
||||
}
|
||||
|
||||
local exportString = ""
|
||||
local function ExportImport_Open(mode)
|
||||
local frame = AceGUI:Create("Frame")
|
||||
frame:SetTitle("")
|
||||
frame:EnableResize(false)
|
||||
frame:SetWidth(800)
|
||||
frame:SetHeight(600)
|
||||
frame.frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
frame:SetLayout("flow")
|
||||
|
||||
local box = AceGUI:Create("MultiLineEditBox")
|
||||
box:SetNumLines(30)
|
||||
box:DisableButton(true)
|
||||
box:SetWidth(800)
|
||||
box:SetLabel("")
|
||||
frame:AddChild(box)
|
||||
box.editBox.OnTextChangedOrig = box.editBox:GetScript("OnTextChanged")
|
||||
box.editBox.OnCursorChangedOrig = box.editBox:GetScript("OnCursorChanged")
|
||||
box.editBox:SetScript("OnCursorChanged", nil)
|
||||
|
||||
local label1 = AceGUI:Create("Label")
|
||||
local font = GameFontHighlightSmall:GetFont()
|
||||
label1:SetFont(font, 14)
|
||||
label1:SetText(" ")
|
||||
label1:SetWidth(800)
|
||||
frame:AddChild(label1)
|
||||
|
||||
local label2 = AceGUI:Create("Label")
|
||||
local font = GameFontHighlightSmall:GetFont()
|
||||
label2:SetFont(font, 14)
|
||||
label2:SetText(" \n ")
|
||||
label2:SetWidth(800)
|
||||
frame:AddChild(label2)
|
||||
|
||||
if(mode == "export") then
|
||||
frame:SetTitle(L["Export Profile"])
|
||||
|
||||
local profileTypeDropdown = AceGUI:Create("Dropdown")
|
||||
profileTypeDropdown:SetMultiselect(false)
|
||||
profileTypeDropdown:SetLabel(L["Choose What To Export"])
|
||||
profileTypeDropdown:SetList(profileTypeItems, profileTypeListOrder)
|
||||
profileTypeDropdown:SetValue("profile")
|
||||
frame:AddChild(profileTypeDropdown)
|
||||
|
||||
local exportFormatDropdown = AceGUI:Create("Dropdown")
|
||||
exportFormatDropdown:SetMultiselect(false)
|
||||
exportFormatDropdown:SetLabel(L["Choose Export Format"])
|
||||
exportFormatDropdown:SetList(exportTypeItems, exportTypeListOrder)
|
||||
exportFormatDropdown:SetValue("text")
|
||||
exportFormatDropdown:SetWidth(150)
|
||||
frame:AddChild(exportFormatDropdown)
|
||||
|
||||
local exportButton = AceGUI:Create("Button")
|
||||
exportButton:SetText(L["Export Now"])
|
||||
exportButton:SetAutoWidth(true)
|
||||
local function OnClick(self)
|
||||
label1:SetText(" ")
|
||||
label2:SetText(" ")
|
||||
|
||||
local profileType, exportFormat = profileTypeDropdown:GetValue(), exportFormatDropdown:GetValue()
|
||||
local profileKey, profileExport = D:ExportProfile(profileType, exportFormat)
|
||||
if(not profileKey or not profileExport) then
|
||||
label1:SetText(L["Error exporting profile!"])
|
||||
else
|
||||
label1:SetText(format("%s: %s%s|r", L["Exported"], E.media.hexvaluecolor, profileTypeItems[profileType]))
|
||||
if(profileType == "profile") then
|
||||
label2:SetText(format("%s: %s%s|r", L["Profile Name"], E.media.hexvaluecolor, profileKey))
|
||||
end
|
||||
end
|
||||
box:SetText(profileExport)
|
||||
box.editBox:HighlightText()
|
||||
box:SetFocus()
|
||||
exportString = profileExport
|
||||
end
|
||||
exportButton:SetCallback("OnClick", OnClick)
|
||||
frame:AddChild(exportButton)
|
||||
|
||||
box.editBox:SetScript("OnChar", function() box:SetText(exportString) box.editBox:HighlightText() end)
|
||||
box.editBox:SetScript("OnTextChanged", function(self)
|
||||
box:SetText(exportString)
|
||||
box.editBox:HighlightText()
|
||||
end)
|
||||
elseif(mode == "import") then
|
||||
frame:SetTitle(L["Import Profile"])
|
||||
local importButton = AceGUI:Create("Button")
|
||||
importButton:SetDisabled(true)
|
||||
importButton:SetText(L["Import Now"])
|
||||
importButton:SetAutoWidth(true)
|
||||
importButton:SetCallback("OnClick", function()
|
||||
label1:SetText(" ")
|
||||
label2:SetText(" ")
|
||||
|
||||
local text
|
||||
local success = D:ImportProfile(box:GetText())
|
||||
if(success) then
|
||||
text = L["Profile imported successfully!"]
|
||||
else
|
||||
text = L["Error decoding data. Import string may be corrupted!"]
|
||||
end
|
||||
label1:SetText(text)
|
||||
end)
|
||||
frame:AddChild(importButton)
|
||||
|
||||
local decodeButton = AceGUI:Create("Button")
|
||||
decodeButton:SetDisabled(true)
|
||||
decodeButton:SetText(L["Decode Text"])
|
||||
decodeButton:SetAutoWidth(true)
|
||||
decodeButton:SetCallback("OnClick", function()
|
||||
label1:SetText(" ")
|
||||
label2:SetText(" ")
|
||||
local decodedText
|
||||
local profileType, profileKey, profileData = D:Decode(box:GetText())
|
||||
if(profileData) then
|
||||
decodedText = E:TableToLuaString(profileData)
|
||||
end
|
||||
local importText = D:CreateProfileExport(decodedText, profileType, profileKey)
|
||||
box:SetText(importText)
|
||||
end)
|
||||
frame:AddChild(decodeButton)
|
||||
|
||||
local oldText = ""
|
||||
local function OnTextChanged()
|
||||
local text = box:GetText()
|
||||
if(text == "") then
|
||||
label1:SetText(" ")
|
||||
label2:SetText(" ")
|
||||
importButton:SetDisabled(true)
|
||||
decodeButton:SetDisabled(true)
|
||||
elseif(oldText ~= text) then
|
||||
local stringType = D:GetImportStringType(text)
|
||||
if(stringType == "Base64") then
|
||||
decodeButton:SetDisabled(false)
|
||||
else
|
||||
decodeButton:SetDisabled(true)
|
||||
end
|
||||
|
||||
local profileType, profileKey = D:Decode(text)
|
||||
if not profileType or (profileType and profileType == "profile" and not profileKey) then
|
||||
label1:SetText(L["Error decoding data. Import string may be corrupted!"])
|
||||
label2:SetText(" ")
|
||||
importButton:SetDisabled(true)
|
||||
decodeButton:SetDisabled(true)
|
||||
else
|
||||
label1:SetText(format("%s: %s%s|r", L["Importing"], E.media.hexvaluecolor, profileTypeItems[profileType] or ""))
|
||||
if(profileType == "profile") then
|
||||
label2:SetText(format("%s: %s%s|r", L["Profile Name"], E.media.hexvaluecolor, profileKey))
|
||||
end
|
||||
importButton:SetDisabled(false)
|
||||
end
|
||||
|
||||
box.scrollFrame:UpdateScrollChildRect()
|
||||
box.scrollFrame:SetVerticalScroll(box.scrollFrame:GetVerticalScrollRange())
|
||||
box.scrollFrame:SetFrameLevel(box.scrollFrame:GetParent():GetFrameLevel() - 2)
|
||||
|
||||
oldText = text
|
||||
end
|
||||
end
|
||||
|
||||
box.editBox:SetFocus()
|
||||
box.editBox:SetScript("OnChar", nil)
|
||||
box.editBox:SetScript("OnTextChanged", OnTextChanged)
|
||||
end
|
||||
|
||||
frame:SetCallback("OnClose", function(widget)
|
||||
box.editBox:SetScript("OnChar", nil)
|
||||
box.editBox:SetScript("OnTextChanged", box.editBox.OnTextChangedOrig)
|
||||
box.editBox:SetScript("OnCursorChanged", box.editBox.OnCursorChangedOrig)
|
||||
box.editBox.OnTextChangedOrig = nil
|
||||
box.editBox.OnCursorChangedOrig = nil
|
||||
|
||||
exportString = ""
|
||||
|
||||
AceGUI:Release(widget)
|
||||
ACD:Open("ElvUI")
|
||||
end)
|
||||
|
||||
label1:SetText(" ")
|
||||
label2:SetText(" ")
|
||||
|
||||
ACD:Close("ElvUI")
|
||||
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
E.Options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(E.data)
|
||||
AC.RegisterOptionsTable(P, "ElvProfiles", E.Options.args.profiles)
|
||||
E.Options.args.profiles.order = -10
|
||||
|
||||
if(not E.Options.args.profiles.plugins) then
|
||||
E.Options.args.profiles.plugins = {}
|
||||
end
|
||||
|
||||
E.Options.args.profiles.plugins["ElvUI"] = {
|
||||
spacer = {
|
||||
order = 89,
|
||||
type = "description",
|
||||
name = "\n\n"
|
||||
},
|
||||
desc = {
|
||||
order = 90,
|
||||
type = "description",
|
||||
name = L["This feature will allow you to transfer settings to other characters."]
|
||||
},
|
||||
distributeProfile = {
|
||||
order = 91,
|
||||
name = L["Share Current Profile"],
|
||||
desc = L["Sends your current profile to your target."],
|
||||
type = "execute",
|
||||
func = function()
|
||||
if(not UnitExists("target") or not UnitIsPlayer("target") or not UnitIsFriend("player", "target") or UnitIsUnit("player", "target")) then
|
||||
E:Print(L["You must be targeting a player."])
|
||||
return
|
||||
end
|
||||
local name, server = UnitName("target")
|
||||
if(name and (not server or server == "")) then
|
||||
D:Distribute(name)
|
||||
elseif(server) then
|
||||
D:Distribute(name, true)
|
||||
end
|
||||
end
|
||||
},
|
||||
distributeGlobal = {
|
||||
order = 92,
|
||||
type = "execute",
|
||||
name = L["Share Filters"],
|
||||
desc = L["Sends your filter settings to your target."],
|
||||
func = function()
|
||||
if(not UnitExists("target") or not UnitIsPlayer("target") or not UnitIsFriend("player", "target") or UnitIsUnit("player", "target")) then
|
||||
E:Print(L["You must be targeting a player."])
|
||||
return
|
||||
end
|
||||
local name, server = UnitName("target")
|
||||
if(name and (not server or server == "")) then
|
||||
D:Distribute(name, false, true)
|
||||
elseif(server) then
|
||||
D:Distribute(name, true, true)
|
||||
end
|
||||
end,
|
||||
},
|
||||
spacer2 = {
|
||||
order = 93,
|
||||
type = "description",
|
||||
name = ""
|
||||
},
|
||||
exportProfile = {
|
||||
order = 94,
|
||||
type = "execute",
|
||||
name = L["Export Profile"],
|
||||
func = function() ExportImport_Open("export") end
|
||||
},
|
||||
importProfile = {
|
||||
order = 95,
|
||||
type = "execute",
|
||||
name = L["Import Profile"],
|
||||
func = function() ExportImport_Open("import") end
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,6 @@
|
||||
<Include file="AceConfigRegistry-3.0\AceConfigRegistry-3.0.xml"/>
|
||||
<Include file="AceConfigCmd-3.0\AceConfigCmd-3.0.xml"/>
|
||||
<Include file="AceConfigDialog-3.0\AceConfigDialog-3.0.xml"/>
|
||||
<!--<Include file="AceConfigDropdown-3.0\AceConfigDropdown-3.0.xml"/>-->
|
||||
<Include file="AceConfigDropdown-3.0\AceConfigDropdown-3.0.xml"/>
|
||||
<Script file="AceConfig-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -665,7 +665,7 @@ local function GetOptionsTable_Castbar(hasTicks, updateFunc, groupName, numUnits
|
||||
func = function()
|
||||
local frameName = E:StringTitle(groupName)
|
||||
frameName = "ElvUF_"..frameName
|
||||
frameName = frameName:gsub("t(arget)", "T%1")
|
||||
frameName = gsub(frameName, "t(arget)", "T%1")
|
||||
|
||||
if numUnits then
|
||||
for i=1, numUnits do
|
||||
@@ -835,7 +835,7 @@ local function GetOptionsTable_Castbar(hasTicks, updateFunc, groupName, numUnits
|
||||
tickColor = {
|
||||
order = 2,
|
||||
type = "color",
|
||||
name = "COLOR",
|
||||
name = COLOR,
|
||||
hasAlpha = true,
|
||||
get = function(info)
|
||||
local c = E.db.unitframe.units[groupName].castbar.tickColor
|
||||
@@ -1659,7 +1659,7 @@ local function GetOptionsTable_RaidDebuff(updateFunc, groupName)
|
||||
color = {
|
||||
order = 4,
|
||||
type = "color",
|
||||
name = "COLOR",
|
||||
name = COLOR,
|
||||
hasAlpha = true,
|
||||
get = function(info)
|
||||
local c = E.db.unitframe.units.raid.rdebuffs.duration.color
|
||||
@@ -1713,7 +1713,7 @@ local function GetOptionsTable_RaidDebuff(updateFunc, groupName)
|
||||
color = {
|
||||
order = 4,
|
||||
type = "color",
|
||||
name = "COLOR",
|
||||
name = COLOR,
|
||||
hasAlpha = true,
|
||||
get = function(info)
|
||||
local c = E.db.unitframe.units[groupName].rdebuffs.stack.color
|
||||
|
||||
Reference in New Issue
Block a user