You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
559 lines
19 KiB
559 lines
19 KiB
|
3 years ago
|
--[[
|
||
|
|
]]
|
||
|
|
|
||
|
|
local ADDON_NAME, Internal = ...
|
||
|
|
local L = Internal.L
|
||
|
|
local External = _G[ADDON_NAME]
|
||
|
|
|
||
|
|
local format = string.format
|
||
|
|
local wipe = table.wipe
|
||
|
|
local concat = table.concat
|
||
|
|
|
||
|
|
local function StringToTable(text)
|
||
|
|
local stringType = text:sub(1,1)
|
||
|
|
if stringType == "{" then
|
||
|
|
local func, err = loadstring("return " .. text, "Import")
|
||
|
|
if not func then
|
||
|
|
return false, err
|
||
|
|
end
|
||
|
|
setfenv(func, {});
|
||
|
|
return pcall(func)
|
||
|
|
else
|
||
|
|
return false, L["Invalid string"]
|
||
|
|
end
|
||
|
|
end
|
||
|
|
local function TableToString(tbl)
|
||
|
|
local str = {}
|
||
|
|
for k,v in pairs(tbl) do
|
||
|
|
if type(k) == "number" then
|
||
|
|
k = "[" .. k .. "]"
|
||
|
|
elseif type(k) ~= "string" then
|
||
|
|
error(format(L["Invalid key type %s"], type(k)))
|
||
|
|
end
|
||
|
|
|
||
|
|
if type(v) == "table" then
|
||
|
|
v = TableToString(v)
|
||
|
|
elseif type(v) == "string" then
|
||
|
|
v = format("%q", v)
|
||
|
|
elseif type(v) ~= "number" and type(v) ~= "boolean" then
|
||
|
|
error(format(L["Invalid value type %s for key %s"], type(v), tostring(k)))
|
||
|
|
end
|
||
|
|
|
||
|
|
str[#str+1] = k .. "=" .. tostring(v)
|
||
|
|
end
|
||
|
|
return "{" .. concat(str, ",") .. "}"
|
||
|
|
end
|
||
|
|
|
||
|
|
local Base64Encode, Base64Decode
|
||
|
|
do
|
||
|
|
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||
|
|
function Base64Encode(data)
|
||
|
|
return ((data:gsub('.', function(x)
|
||
|
|
local r,b='',x:byte()
|
||
|
|
for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
|
||
|
|
return r;
|
||
|
|
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
|
||
|
|
if (#x < 6) then return '' end
|
||
|
|
local c=0
|
||
|
|
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
|
||
|
|
return b:sub(c+1,c+1)
|
||
|
|
end)..({ '', '==', '=' })[#data%3+1])
|
||
|
|
end
|
||
|
|
function Base64Decode(data)
|
||
|
|
data = string.gsub(data, '[^'..b..'=]', '')
|
||
|
|
return (data:gsub('.', function(x)
|
||
|
|
if (x == '=') then return '' end
|
||
|
|
local r,f='',(b:find(x)-1)
|
||
|
|
for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
|
||
|
|
return r;
|
||
|
|
end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
|
||
|
|
if (#x ~= 8) then return '' end
|
||
|
|
local c=0
|
||
|
|
for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
|
||
|
|
return string.char(c)
|
||
|
|
end))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function Encode(content, format)
|
||
|
|
if #format == 1 then
|
||
|
|
if format == "N" then
|
||
|
|
return "N" .. content
|
||
|
|
elseif format == "B" then
|
||
|
|
return "B" .. Base64Encode(content)
|
||
|
|
else
|
||
|
|
error("Unsupported format")
|
||
|
|
end
|
||
|
|
elseif #format > 1 then
|
||
|
|
local f, ormat = format:match("^([A-Z])([A-Z]*)$")
|
||
|
|
return Encode(Encode(content, ormat), f)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
local function Decode(content, err)
|
||
|
|
local format, content = content:match("^([A-Z])(.*)$")
|
||
|
|
|
||
|
|
if format == "N" then
|
||
|
|
return true, content
|
||
|
|
elseif format == "B" then
|
||
|
|
return Decode(Base64Decode(content))
|
||
|
|
else
|
||
|
|
return false, err or L["Unsupported format"]
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function VerifySource(source, sourceType, version, name, ...)
|
||
|
|
version = source.version or version
|
||
|
|
sourceType = source.type or sourceType
|
||
|
|
name = source.name or name
|
||
|
|
|
||
|
|
if not name then
|
||
|
|
return false, L["Missing name"]
|
||
|
|
elseif type(name) ~= "string" then
|
||
|
|
return false, L["Invalid name"]
|
||
|
|
end
|
||
|
|
|
||
|
|
if sourceType == "loadout" then
|
||
|
|
if version ~= 2 then -- Only supported version
|
||
|
|
return false, L["Invalid source version"]
|
||
|
|
end
|
||
|
|
|
||
|
|
local specID = source.specID or ...
|
||
|
|
if not specID or not GetSpecializationInfoByID(specID) then
|
||
|
|
return false, L["Invalid specialization"]
|
||
|
|
end
|
||
|
|
|
||
|
|
for _,segment in Internal.EnumerateLoadoutSegments() do
|
||
|
|
if source[segment.id] then
|
||
|
|
for _,set in ipairs(source[segment.id]) do
|
||
|
|
local result, err = VerifySource(set, segment.id, 1, name, specID)
|
||
|
|
if not result then
|
||
|
|
return result, err
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
local segment = Internal.GetLoadoutSegment(sourceType)
|
||
|
|
if not segment then
|
||
|
|
return false, L["Invalid import type"]
|
||
|
|
end
|
||
|
|
if not segment.verify then
|
||
|
|
return false, L["Missing verification function"]
|
||
|
|
end
|
||
|
|
|
||
|
|
return segment.verify(source, ...)
|
||
|
|
end
|
||
|
|
|
||
|
|
-- if sourceType == "loadout" then
|
||
|
|
-- if version ~= 2 then -- Only supported version
|
||
|
|
-- return false, L["Invalid source version"]
|
||
|
|
-- end
|
||
|
|
|
||
|
|
-- local specID = source.specID or ...
|
||
|
|
|
||
|
|
-- if not source.talents and not source.pvptalents and not source.essences then
|
||
|
|
-- return false, L["Missing value"]
|
||
|
|
-- end
|
||
|
|
-- if not specID or not GetSpecializationInfoByID(specID) then
|
||
|
|
-- return false, L["Invalid specialization"]
|
||
|
|
-- end
|
||
|
|
|
||
|
|
-- local function VerifyType(source, type, version, name, ...)
|
||
|
|
-- return VerifySource(source[type], type, version, name, ...)
|
||
|
|
-- end
|
||
|
|
|
||
|
|
-- for _,subtype in ipairs({"talents", "pvptalents", "essences"}) do
|
||
|
|
-- for _,set in ipairs(source[subtype]) do
|
||
|
|
-- local result, err = VerifySource(set, subtype, 1, name, specID)
|
||
|
|
-- if not result then
|
||
|
|
-- return result, err
|
||
|
|
-- end
|
||
|
|
-- end
|
||
|
|
-- end
|
||
|
|
-- -- if source.talents then
|
||
|
|
-- -- for _,set in ipairs(source.talents) do
|
||
|
|
-- -- end
|
||
|
|
-- -- local result, err = VerifySource(source.talents, "talents", 1, name, specID)
|
||
|
|
-- -- if not result then
|
||
|
|
-- -- return result, err
|
||
|
|
-- -- end
|
||
|
|
-- -- end
|
||
|
|
-- -- if source.pvptalents then
|
||
|
|
-- -- local result, err = VerifySource(source.pvptalents, "pvptalents", 1, name, specID)
|
||
|
|
-- -- if not result then
|
||
|
|
-- -- return result, err
|
||
|
|
-- -- end
|
||
|
|
-- -- end
|
||
|
|
-- -- if source.essences then
|
||
|
|
-- -- local result, err = VerifySource(source.essences, "essences", 1, name, GetSpecializationRoleByID(specID))
|
||
|
|
-- -- if not result then
|
||
|
|
-- -- return result, err
|
||
|
|
-- -- end
|
||
|
|
-- -- end
|
||
|
|
-- elseif sourceType == "talents" then
|
||
|
|
-- if version ~= 1 then -- Only supported version
|
||
|
|
-- return false, L["Invalid source version"]
|
||
|
|
-- end
|
||
|
|
|
||
|
|
-- local specID = source.specID or ...
|
||
|
|
-- if type(source.talents) ~= "table" then
|
||
|
|
-- return false, L["Missing talents"]
|
||
|
|
-- end
|
||
|
|
-- if not specID or not GetSpecializationInfoByID(specID) then
|
||
|
|
-- return false, L["Invalid specialization"]
|
||
|
|
-- end
|
||
|
|
-- elseif sourceType == "pvptalents" then
|
||
|
|
-- if version ~= 1 then -- Only supported version
|
||
|
|
-- return false, L["Invalid source version"]
|
||
|
|
-- end
|
||
|
|
|
||
|
|
-- local specID = source.specID or ...
|
||
|
|
-- if type(source.talents) ~= "table" then
|
||
|
|
-- return false, L["Missing pvp talents"]
|
||
|
|
-- end
|
||
|
|
-- if not specID or not GetSpecializationInfoByID(specID) then
|
||
|
|
-- return false, L["Invalid specialization"]
|
||
|
|
-- end
|
||
|
|
-- elseif sourceType == "essences" then
|
||
|
|
-- if version ~= 1 then -- Only supported version
|
||
|
|
-- return false, L["Invalid source version"]
|
||
|
|
-- end
|
||
|
|
|
||
|
|
-- local role = source.role or GetSpecializationRoleByID(...)
|
||
|
|
-- if type(source.essences) ~= "table" then
|
||
|
|
-- return false, L["Missing essences"]
|
||
|
|
-- end
|
||
|
|
-- if role ~= "DAMAGER" and role ~= "HEALER" and role ~= "TANK" then
|
||
|
|
-- return false, L["Invalid role"]
|
||
|
|
-- end
|
||
|
|
-- else
|
||
|
|
-- return false, L["Invalid import type"]
|
||
|
|
-- end
|
||
|
|
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
|
||
|
|
local DFTalentImportMixin = {
|
||
|
|
ImportLoadout = function (self, importText, loadoutName)
|
||
|
|
local importStream = ExportUtil.MakeImportDataStream(importText);
|
||
|
|
local headerValid, serializationVersion, specID, treeHash = self:ReadLoadoutHeader(importStream);
|
||
|
|
|
||
|
|
if not headerValid then
|
||
|
|
return false, LOADOUT_ERROR_BAD_STRING
|
||
|
|
end
|
||
|
|
|
||
|
|
if serializationVersion ~= 1 then
|
||
|
|
return false, LOADOUT_ERROR_SERIALIZATION_VERSION_MISMATCH
|
||
|
|
end
|
||
|
|
|
||
|
|
local classInfo = Internal.GetClassInfoBySpecID(specID);
|
||
|
|
|
||
|
|
local treeInfo = Internal.GetTreeInfoBySpecID(specID);
|
||
|
|
local treeNodes = Internal.GetTreeInfoBySpecID(specID);
|
||
|
|
|
||
|
|
if not self:IsHashEmpty(treeHash) then
|
||
|
|
-- allow third-party sites to generate loadout strings with an empty tree hash, which bypasses hash validation
|
||
|
|
if not self:HashEquals(treeHash, C_Traits.GetTreeHash(treeInfo.ID)) then
|
||
|
|
return false, LOADOUT_ERROR_TREE_CHANGED;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local loadoutContent = self:ReadLoadoutContent(importStream, treeInfo.ID);
|
||
|
|
local loadoutEntryInfo = self:ConvertToImportLoadoutEntryInfo(treeInfo.ID, loadoutContent);
|
||
|
|
|
||
|
|
local _, specName = GetSpecializationInfoByID(specID);
|
||
|
|
|
||
|
|
local result = {};
|
||
|
|
|
||
|
|
result.version = 1;
|
||
|
|
result.type = "dftalents";
|
||
|
|
result.name = format(loadoutName or L["New %s Set"], specName);
|
||
|
|
result.treeID = treeInfo.ID;
|
||
|
|
result.specID = specID;
|
||
|
|
result.classID = classInfo.classID;
|
||
|
|
|
||
|
|
result.nodes = loadoutEntryInfo;
|
||
|
|
|
||
|
|
return true, result
|
||
|
|
end,
|
||
|
|
ConvertToImportLoadoutEntryInfo = function (self, treeID, loadoutContent)
|
||
|
|
local results = {};
|
||
|
|
local treeNodes = C_Traits.GetTreeNodes(treeID);
|
||
|
|
local count = 1;
|
||
|
|
for i, treeNodeID in ipairs(treeNodes) do
|
||
|
|
local indexInfo = loadoutContent[i];
|
||
|
|
if indexInfo.isNodeSelected then
|
||
|
|
local treeNode = Internal.GetNodeInfo(treeNodeID);
|
||
|
|
if indexInfo.isChoiceNode then
|
||
|
|
results[treeNodeID] = indexInfo.choiceNodeSelection;
|
||
|
|
else
|
||
|
|
results[treeNodeID] = indexInfo.isPartiallyRanked and indexInfo.partialRanksPurchased or treeNode.maxRanks;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
return results;
|
||
|
|
end,
|
||
|
|
}
|
||
|
|
local DFTalentImport
|
||
|
|
DFTalentImport = {
|
||
|
|
ImportLoadout = function (...)
|
||
|
|
LoadAddOn("Blizzard_ClassTalentUI")
|
||
|
|
Mixin(DFTalentImport, ClassTalentImportExportMixin, DFTalentImportMixin);
|
||
|
|
return DFTalentImport.ImportLoadout(...)
|
||
|
|
end
|
||
|
|
}
|
||
|
|
|
||
|
|
-- Import Frame
|
||
|
|
do
|
||
|
|
local function GetUniqueName(setType, name)
|
||
|
|
if not Internal.GetSetByName(setType, name) then
|
||
|
|
return name
|
||
|
|
end
|
||
|
|
|
||
|
|
local index = 2
|
||
|
|
while Internal.GetSetByName(setType, format("%s (%d)", name, index)) do
|
||
|
|
index = index + 1
|
||
|
|
end
|
||
|
|
|
||
|
|
return format("%s (%d)", name, index)
|
||
|
|
end
|
||
|
|
local function AddSource(source, sourceType, version, name, ...)
|
||
|
|
sourceType = source.type or sourceType
|
||
|
|
version = source.version or version
|
||
|
|
name = source.name or name
|
||
|
|
|
||
|
|
if sourceType == "loadout" then
|
||
|
|
assert(version == 2, "Unsupported loadout version")
|
||
|
|
|
||
|
|
local name = GetUniqueName("profiles", name)
|
||
|
|
for _,segment in Internal.EnumerateLoadoutSegments() do
|
||
|
|
if segment.import and source[segment.id] then
|
||
|
|
for i=#source[segment.id],1,-1 do
|
||
|
|
if not source[segment.id][i] then
|
||
|
|
table.remove(source[segment.id], i)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
for index,set in ipairs(source[segment.id]) do
|
||
|
|
if type(set) == "table" then
|
||
|
|
set = AddSource(set, segment.id, 1, name)
|
||
|
|
source[segment.id][index] = set
|
||
|
|
end
|
||
|
|
|
||
|
|
set = segment.get(set)
|
||
|
|
set.useCount = (set.useCount or 0) + 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local set = Internal.ImportLoadout(source, version, name)
|
||
|
|
return set.setID
|
||
|
|
else
|
||
|
|
local segment = Internal.GetLoadoutSegment(sourceType)
|
||
|
|
if not segment then
|
||
|
|
return false, L["Unknown source type"]
|
||
|
|
end
|
||
|
|
|
||
|
|
local name = GetUniqueName(segment.id, name)
|
||
|
|
local set = segment.import(source, version, name, ...)
|
||
|
|
return set.setID
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local currentImport
|
||
|
|
BtWLoadoutsImportFrameMixin = {};
|
||
|
|
function BtWLoadoutsImportFrameMixin:OnLoad()
|
||
|
|
BackdropTemplateMixin.OnBackdropLoaded(self)
|
||
|
|
if self.TooltipBackdropOnLoad then
|
||
|
|
self:TooltipBackdropOnLoad()
|
||
|
|
end
|
||
|
|
|
||
|
|
tinsert(UISpecialFrames, self:GetName());
|
||
|
|
self:RegisterForDrag("LeftButton");
|
||
|
|
|
||
|
|
self.checkboxPool = CreateFramePool("CheckButton", self, "BtWLoadoutsImportCheckButtonTemplate")
|
||
|
|
end
|
||
|
|
function BtWLoadoutsImportFrameMixin:OnDragStart()
|
||
|
|
self:StartMoving();
|
||
|
|
end
|
||
|
|
function BtWLoadoutsImportFrameMixin:OnDragStop()
|
||
|
|
self:StopMovingOrSizing();
|
||
|
|
end
|
||
|
|
function BtWLoadoutsImportFrameMixin:OnShow()
|
||
|
|
local source = currentImport
|
||
|
|
if not source then
|
||
|
|
self:Hide();
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
self.checkboxPool:ReleaseAll()
|
||
|
|
|
||
|
|
local previousButton = self.Name
|
||
|
|
if source.type == "loadout" then
|
||
|
|
self.Name:SetText(format(L["Importing Loadout \"%s\""], source.name))
|
||
|
|
|
||
|
|
for _,segment in Internal.EnumerateLoadoutSegments() do
|
||
|
|
local sets = source[segment.id]
|
||
|
|
if sets then
|
||
|
|
for index,set in ipairs(sets) do
|
||
|
|
local button = self.checkboxPool:Acquire()
|
||
|
|
button:SetPoint("TOPLEFT", previousButton, "BOTTOMLEFT", 0, -5)
|
||
|
|
|
||
|
|
if type(set) == "number" then
|
||
|
|
local set = segment.get(set)
|
||
|
|
button.Text:SetText(format(L["Use existing %s set \"%s\""], segment.name, set.name))
|
||
|
|
else
|
||
|
|
button.Text:SetText(format(L["Include %s as \"%s\""], segment.name, set.name))
|
||
|
|
end
|
||
|
|
|
||
|
|
button.index = index
|
||
|
|
button.type = segment.id
|
||
|
|
button:SetChecked(true)
|
||
|
|
button:Show()
|
||
|
|
|
||
|
|
previousButton = button
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
local segment = Internal.GetLoadoutSegment(source.type)
|
||
|
|
if not segment then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
self.Name:SetText(format(L["Importing %s \"%s\""], segment.name, source.name))
|
||
|
|
end
|
||
|
|
|
||
|
|
self:SetHeight(self:GetTop() - previousButton:GetBottom() + 45)
|
||
|
|
end
|
||
|
|
function BtWLoadoutsImportFrameMixin:Accept()
|
||
|
|
local source = currentImport
|
||
|
|
|
||
|
|
-- Remove parts that the user disabled
|
||
|
|
if source.type == "loadout" then
|
||
|
|
for button in self.checkboxPool:EnumerateActive() do
|
||
|
|
if not button:GetChecked() then
|
||
|
|
source[button.type][button.index] = false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local setID = AddSource(source)
|
||
|
|
BtWLoadoutsFrame:SetSetByID(source.type, setID)
|
||
|
|
|
||
|
|
currentImport = nil
|
||
|
|
BtWLoadoutsImportFrame:Hide()
|
||
|
|
end
|
||
|
|
|
||
|
|
function Internal.UpdateImportFrame(source)
|
||
|
|
BtWLoadoutsImportFrame:Hide()
|
||
|
|
currentImport = source
|
||
|
|
BtWLoadoutsImportFrame:Show()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function External.Import(source)
|
||
|
|
local success, err
|
||
|
|
if type(source) == "string" then
|
||
|
|
success, err = DFTalentImport:ImportLoadout(source)
|
||
|
|
if success then -- Official DF Talents
|
||
|
|
source = err;
|
||
|
|
else
|
||
|
|
success, source = Decode(source, err)
|
||
|
|
if not success then
|
||
|
|
return false, source
|
||
|
|
end
|
||
|
|
|
||
|
|
success, source = StringToTable(source)
|
||
|
|
if not success then
|
||
|
|
return false, source
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if type(source) ~= "table" then
|
||
|
|
return false, L["Invalid source type"]
|
||
|
|
end
|
||
|
|
|
||
|
|
success, err = VerifySource(source)
|
||
|
|
if not success then
|
||
|
|
return false, err
|
||
|
|
end
|
||
|
|
|
||
|
|
if source.type == "loadout" then
|
||
|
|
-- Find existing sets with the same content
|
||
|
|
for _,segment in Internal.EnumerateLoadoutSegments() do
|
||
|
|
if source[segment.id] then
|
||
|
|
for index,set in ipairs(source[segment.id]) do
|
||
|
|
local target = segment.getByValue(set)
|
||
|
|
if target then
|
||
|
|
source[segment.id][index] = target.setID
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
Internal.UpdateImportFrame(source)
|
||
|
|
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
|
||
|
|
function Internal.Export(segmentType, id, format)
|
||
|
|
if segmentType == "loadout" then
|
||
|
|
local loadout = Internal.GetProfile(id)
|
||
|
|
local result = {}
|
||
|
|
|
||
|
|
assert(loadout.version == 2, "Unable to export loadouts that are not version 2")
|
||
|
|
|
||
|
|
result.version = 2
|
||
|
|
result.type = "loadout"
|
||
|
|
result.name = loadout.name
|
||
|
|
result.specID = loadout.specID
|
||
|
|
|
||
|
|
for _,segment in Internal.EnumerateLoadoutSegments() do
|
||
|
|
if segment.export and #loadout[segment.id] > 0 then
|
||
|
|
local sets = {}
|
||
|
|
for _,setID in ipairs(loadout[segment.id]) do
|
||
|
|
sets[#sets+1] = segment.export(segment.get(setID))
|
||
|
|
end
|
||
|
|
result[segment.id] = sets
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return Encode(TableToString(result), format or "BN")
|
||
|
|
else
|
||
|
|
local segment = Internal.GetLoadoutSegment(segmentType)
|
||
|
|
assert(segment ~= nil)
|
||
|
|
|
||
|
|
local set = segment.get(id)
|
||
|
|
local result = segment.export(set)
|
||
|
|
result.type = segment.id
|
||
|
|
|
||
|
|
return Encode(TableToString(result), format or "BN")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function External.Export(id, format)
|
||
|
|
return Internal.Export("loadout", id, format)
|
||
|
|
end
|
||
|
|
|
||
|
|
-- /run BtWLoadoutsFrame:SetExport(BtWLoadouts.Export(1))
|
||
|
|
BtWLoadoutsImportMixin = {}
|
||
|
|
function BtWLoadoutsImportMixin:Update()
|
||
|
|
self:GetParent():SetTitle(L["Import"]);
|
||
|
|
|
||
|
|
self:GetParent().Sidebar:Hide()
|
||
|
|
|
||
|
|
BtWLoadoutsFrame:SetNPEShown(false);
|
||
|
|
|
||
|
|
self.Scroll.EditBox.text = ""
|
||
|
|
self.Scroll.EditBox:SetText("")
|
||
|
|
|
||
|
|
self:GetParent().RefreshButton:Hide();
|
||
|
|
self:GetParent().ActivateButton:Hide();
|
||
|
|
self:GetParent().ExportButton:Hide();
|
||
|
|
self:GetParent().DeleteButton:Hide();
|
||
|
|
self:GetParent().AddButton:Hide();
|
||
|
|
end
|
||
|
|
function BtWLoadoutsImportMixin:OnShow()
|
||
|
|
self.Scroll.EditBox:SetFocus()
|
||
|
|
end
|