yellowfive@57: local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot") yellowfive@57: local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true) yellowfive@57: local AceGUI = LibStub("AceGUI-3.0") yellowfive@57: yellowfive@57: local _txtImport yellowfive@57: local _lblError yellowfive@69: local _panelCover yellowfive@57: yellowfive@57: local function onImportOkClick(widget) yellowfive@57: local txt = _txtImport:GetText() yellowfive@57: local msg = Amr:ImportCharacter(txt) yellowfive@57: if msg then yellowfive@57: _lblError:SetText(msg) yellowfive@57: _txtImport:SetFocus(true) yellowfive@57: else yellowfive@57: Amr:HideCover() yellowfive@57: Amr:RefreshGearTab() yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local function onImportCancelClick(widget) yellowfive@57: Amr:HideCover() yellowfive@57: end yellowfive@57: yellowfive@69: local function onTextEnterPressed(widget) yellowfive@69: -- hide the overwolf cover when import data is received yellowfive@69: if _panelCover then yellowfive@69: _panelCover:SetVisible(false) yellowfive@69: end yellowfive@69: yellowfive@69: -- do an import if the data starts and ends with a dollar sign yellowfive@69: local txt = _txtImport:GetText() yellowfive@69: local txtLen = string.len(txt) yellowfive@69: if txtLen > 2 and string.sub(txt, 1, 1) == '$' then yellowfive@69: onImportOkClick() yellowfive@69: end yellowfive@69: yellowfive@69: end yellowfive@69: yellowfive@69: local function renderImportWindow(container, fromOverwolf) yellowfive@57: yellowfive@57: local panelImport = Amr:RenderCoverChrome(container, 700, 450) yellowfive@57: yellowfive@57: local lbl = AceGUI:Create("AmrUiLabel") yellowfive@124: panelImport:AddChild(lbl) yellowfive@57: lbl:SetWidth(600) yellowfive@57: lbl:SetText(L.ImportHeader) yellowfive@57: lbl:SetPoint("TOP", panelImport.content, "TOP", 0, -10) yellowfive@57: yellowfive@57: _txtImport = AceGUI:Create("AmrUiTextarea") yellowfive@57: _txtImport:SetWidth(600) yellowfive@57: _txtImport:SetHeight(300) yellowfive@57: _txtImport:SetFont(Amr.CreateFont("Regular", 12, Amr.Colors.Text)) yellowfive@69: _txtImport:SetCallback("OnEnterPressed", onTextEnterPressed) yellowfive@57: panelImport:AddChild(_txtImport) yellowfive@124: _txtImport:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -10) yellowfive@57: yellowfive@57: local btnImportOk = AceGUI:Create("AmrUiButton") yellowfive@57: btnImportOk:SetText(L.ImportButtonOk) yellowfive@57: btnImportOk:SetBackgroundColor(Amr.Colors.Green) yellowfive@57: btnImportOk:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White)) yellowfive@57: btnImportOk:SetWidth(120) yellowfive@57: btnImportOk:SetHeight(28) yellowfive@57: btnImportOk:SetCallback("OnClick", onImportOkClick) yellowfive@57: panelImport:AddChild(btnImportOk) yellowfive@124: btnImportOk:SetPoint("TOPLEFT", _txtImport.frame, "BOTTOMLEFT", 0, -10) yellowfive@57: yellowfive@57: local btnImportCancel = AceGUI:Create("AmrUiButton") yellowfive@57: btnImportCancel:SetText(L.ImportButtonCancel) yellowfive@57: btnImportCancel:SetBackgroundColor(Amr.Colors.Green) yellowfive@57: btnImportCancel:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White)) yellowfive@57: btnImportCancel:SetWidth(120) yellowfive@57: btnImportCancel:SetHeight(28) yellowfive@57: btnImportCancel:SetCallback("OnClick", onImportCancelClick) yellowfive@57: panelImport:AddChild(btnImportCancel) yellowfive@124: btnImportCancel:SetPoint("LEFT", btnImportOk.frame, "RIGHT", 20, 0) yellowfive@57: yellowfive@57: _lblError = AceGUI:Create("AmrUiLabel") yellowfive@124: panelImport:AddChild(_lblError) yellowfive@57: _lblError:SetWidth(600) yellowfive@57: _lblError:SetFont(Amr.CreateFont("Bold", 14, Amr.Colors.Red)) yellowfive@57: _lblError:SetText("") yellowfive@57: _lblError:SetPoint("TOPLEFT", btnImportOk.frame, "BOTTOMLEFT", 0, -20) yellowfive@57: yellowfive@69: if fromOverwolf then yellowfive@69: -- show a cover preventing interaction until we receive data from overwolf yellowfive@69: _panelCover = AceGUI:Create("AmrUiPanel") yellowfive@69: _panelCover:SetLayout("None") yellowfive@69: _panelCover:EnableMouse(true) yellowfive@69: _panelCover:SetBackgroundColor(Amr.Colors.Black, 0.75) yellowfive@124: panelImport:AddChild(_panelCover) yellowfive@69: _panelCover:SetPoint("TOPLEFT", panelImport.frame, "TOPLEFT") yellowfive@69: _panelCover:SetPoint("BOTTOMRIGHT", panelImport.frame, "BOTTOMRIGHT") yellowfive@69: yellowfive@69: local coverMsg = AceGUI:Create("AmrUiLabel") yellowfive@124: _panelCover:AddChild(coverMsg) yellowfive@69: coverMsg:SetWidth(500) yellowfive@69: coverMsg:SetFont(Amr.CreateFont("Regular", 16, Amr.Colors.TextTan)) yellowfive@69: coverMsg:SetJustifyH("MIDDLE") yellowfive@69: coverMsg:SetJustifyV("MIDDLE") yellowfive@69: coverMsg:SetText(L.ImportOverwolfWait) yellowfive@69: coverMsg:SetPoint("CENTER", _panelCover.frame, "CENTER", 0, 20) yellowfive@69: yellowfive@69: -- after adding, set cover to sit on top of everything yellowfive@69: _panelCover:SetStrata("FULLSCREEN_DIALOG") yellowfive@69: _panelCover:SetLevel(Amr.FrameLevels.Highest) yellowfive@69: end yellowfive@57: end yellowfive@57: yellowfive@69: function Amr:ShowImportWindow(fromOverwolf) yellowfive@57: -- this is shown as a modal dialog yellowfive@69: Amr:ShowCover(function(container) yellowfive@69: renderImportWindow(container, fromOverwolf) yellowfive@69: end) yellowfive@57: yellowfive@57: _txtImport:SetText("") yellowfive@57: _txtImport:SetFocus(true) yellowfive@57: end yellowfive@57: yellowfive@57: ---------------------------------------------------------------------------- yellowfive@57: -- Import Parsing yellowfive@57: ---------------------------------------------------------------------------- yellowfive@57: yellowfive@57: -- yellowfive@57: -- Import a character, returning nil on success, otherwise an error message, import result stored in the db. yellowfive@57: -- yellowfive@57: function Amr:ImportCharacter(data, isTest) yellowfive@57: yellowfive@57: -- make sure all data is up to date before importing and get a local copy of player's current state yellowfive@57: local currentPlayerData = self:ExportCharacter() yellowfive@57: yellowfive@57: if data == nil or string.len(data) == 0 then yellowfive@57: return L.ImportErrorEmpty yellowfive@57: end yellowfive@57: yellowfive@57: -- if multiple specs are included in the data, parse each individually, then quit yellowfive@57: local specParts = { strsplit("\n", data) } yellowfive@57: if #specParts > 1 then yellowfive@57: for i = 1, #specParts do yellowfive@57: local err = self:ImportCharacter(specParts[i], isTest) yellowfive@57: if err ~= nil then yellowfive@57: return err yellowfive@57: end yellowfive@57: end yellowfive@57: return yellowfive@57: end yellowfive@57: yellowfive@57: local data1 = { strsplit("$", data) } yellowfive@57: if #data1 ~= 3 then yellowfive@57: return L.ImportErrorFormat yellowfive@57: end yellowfive@57: yellowfive@57: local parts = { strsplit(";", data1[2]) } yellowfive@57: yellowfive@57: -- require a minimum version yellowfive@57: local ver = tonumber(parts[1]) yellowfive@57: if ver < Amr.MIN_IMPORT_VERSION then yellowfive@57: return L.ImportErrorVersion yellowfive@57: end yellowfive@57: yellowfive@57: -- require name match (don't match realm due to language issues for now) yellowfive@57: if not isTest then yellowfive@57: local region = parts[2] yellowfive@57: local realm = parts[3] yellowfive@57: local name = parts[4] yellowfive@57: if name ~= currentPlayerData.Name then yellowfive@57: local importPlayerName = name .. " (" .. realm .. ")" yellowfive@57: local you = currentPlayerData.Name .. " (" .. currentPlayerData.Realm .. ")" yellowfive@57: return L.ImportErrorChar(importPlayerName, you) yellowfive@57: end yellowfive@57: yellowfive@57: -- require race match yellowfive@57: local race = tonumber(parts[6]) yellowfive@57: if race ~= Amr.RaceIds[currentPlayerData.Race] then yellowfive@57: return L.ImportErrorRace yellowfive@57: end yellowfive@57: yellowfive@57: -- require faction match yellowfive@57: local faction = tonumber(parts[7]) yellowfive@57: if faction ~= Amr.FactionIds[currentPlayerData.Faction] then yellowfive@57: return L.ImportErrorFaction yellowfive@57: end yellowfive@57: yellowfive@57: -- require level match yellowfive@57: local level = tonumber(parts[8]) yellowfive@57: if level ~= currentPlayerData.Level then yellowfive@57: return L.ImportErrorLevel yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- if we make it this far, the data is valid, so read item information yellowfive@124: local specSlot = tonumber(parts[11]) yellowfive@57: yellowfive@57: local importData = {} yellowfive@57: local enchantInfo = {} yellowfive@57: yellowfive@57: local prevItemId = 0 yellowfive@57: local prevGemId = 0 yellowfive@57: local prevEnchantId = 0 yellowfive@57: local prevUpgradeId = 0 yellowfive@57: local prevBonusId = 0 yellowfive@124: local prevLevel = 0 yellowfive@124: local prevAzeriteId = 0 yellowfive@57: local digits = { yellowfive@57: ["-"] = true, yellowfive@57: ["0"] = true, yellowfive@57: ["1"] = true, yellowfive@57: ["2"] = true, yellowfive@57: ["3"] = true, yellowfive@57: ["4"] = true, yellowfive@57: ["5"] = true, yellowfive@57: ["6"] = true, yellowfive@57: ["7"] = true, yellowfive@57: ["8"] = true, yellowfive@57: ["9"] = true, yellowfive@57: } yellowfive@124: for i = 16, #parts do yellowfive@57: local itemString = parts[i] yellowfive@57: if itemString ~= "" and itemString ~= "_" then yellowfive@57: local tokens = {} yellowfive@57: local bonusIds = {} yellowfive@124: local azerite = {} yellowfive@57: local hasBonuses = false yellowfive@124: local hasAzerites = false yellowfive@57: local token = "" yellowfive@57: local prop = "i" yellowfive@57: local tokenComplete = false yellowfive@57: for j = 1, string.len(itemString) do yellowfive@57: local c = string.sub(itemString, j, j) yellowfive@57: if digits[c] == nil then yellowfive@57: tokenComplete = true yellowfive@57: else yellowfive@57: token = token .. c yellowfive@57: end yellowfive@57: yellowfive@57: if tokenComplete or j == string.len(itemString) then yellowfive@57: local val = tonumber(token) yellowfive@57: if prop == "i" then yellowfive@57: val = val + prevItemId yellowfive@57: prevItemId = val yellowfive@57: elseif prop == "u" then yellowfive@57: val = val + prevUpgradeId yellowfive@57: prevUpgradeId = val yellowfive@81: elseif prop == "v" then yellowfive@81: val = val + prevLevel yellowfive@81: prevLevel = val yellowfive@57: elseif prop == "b" then yellowfive@57: val = val + prevBonusId yellowfive@57: prevBonusId = val yellowfive@57: elseif prop == "x" or prop == "y" or prop == "z" then yellowfive@57: val = val + prevGemId yellowfive@57: prevGemId = val yellowfive@57: elseif prop == "e" then yellowfive@57: val = val + prevEnchantId yellowfive@57: prevEnchantId = val yellowfive@124: elseif prop == "a" then yellowfive@124: val = val + prevAzeriteId yellowfive@124: prevAzeriteId = val yellowfive@57: end yellowfive@57: yellowfive@57: if prop == "b" then yellowfive@57: table.insert(bonusIds, val) yellowfive@57: hasBonuses = true yellowfive@124: elseif prop == "a" then yellowfive@124: table.insert(azerite, val) yellowfive@124: hasAzerites = true yellowfive@57: else yellowfive@57: tokens[prop] = val yellowfive@57: end yellowfive@57: yellowfive@57: token = "" yellowfive@57: tokenComplete = false yellowfive@57: yellowfive@57: -- we have moved on to the next token yellowfive@57: prop = c yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local obj = {} yellowfive@57: importData[tonumber(tokens["s"])] = obj yellowfive@57: yellowfive@57: obj.id = tokens["i"] yellowfive@57: obj.suffixId = tokens["f"] or 0 yellowfive@57: obj.upgradeId = tokens["u"] or 0 yellowfive@81: obj.level = tokens["v"] or 0 yellowfive@57: obj.enchantId = tokens["e"] or 0 yellowfive@89: obj.inventoryId = tokens["t"] or 0 yellowfive@57: yellowfive@57: obj.gemIds = {} yellowfive@57: table.insert(obj.gemIds, tokens["x"] or 0) yellowfive@57: table.insert(obj.gemIds, tokens["y"] or 0) yellowfive@57: table.insert(obj.gemIds, tokens["z"] or 0) yellowfive@57: table.insert(obj.gemIds, 0) yellowfive@57: yellowfive@57: if hasBonuses then yellowfive@57: obj.bonusIds = bonusIds yellowfive@57: end yellowfive@57: yellowfive@124: if hasAzerites then yellowfive@124: obj.azerite = azerite yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- now read any extra display information yellowfive@57: parts = { strsplit("@", data1[3]) } yellowfive@57: for i = 1, #parts do yellowfive@57: local infoParts = { strsplit("\\", parts[i]) } yellowfive@57: yellowfive@124: if infoParts[1] == "e" then yellowfive@57: yellowfive@57: local enchObj = {} yellowfive@57: enchObj.id = tonumber(infoParts[2]) yellowfive@57: enchObj.itemId = tonumber(infoParts[3]) yellowfive@57: enchObj.spellId = tonumber(infoParts[4]) yellowfive@57: enchObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.StatsShort[s] end) yellowfive@57: yellowfive@57: local mats = infoParts[6] yellowfive@57: if string.len(mats) > 0 then yellowfive@57: enchObj.materials = {} yellowfive@57: mats = { strsplit(",", mats) } yellowfive@57: for j = 1, #mats do yellowfive@57: local kv = { strsplit("=", mats[j]) } yellowfive@57: enchObj.materials[tonumber(kv[1])] = tonumber(kv[2]) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@124: enchantInfo[enchObj.id] = enchObj yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: if isTest then yellowfive@57: print("spec " .. specSlot) yellowfive@57: -- print result for debugging yellowfive@57: for k,v in pairs(importData) do yellowfive@57: local blah = Amr.CreateItemLink(v) yellowfive@57: --print(blah) yellowfive@57: local name, link = GetItemInfo(blah) yellowfive@57: print(link) yellowfive@57: if link == nil then yellowfive@57: print(blah) yellowfive@57: print("bad item: " .. v.id) yellowfive@57: end yellowfive@133: end yellowfive@57: else yellowfive@57: -- we have succeeded, record the result yellowfive@57: Amr.db.char.GearSets[specSlot] = importData yellowfive@124: yellowfive@124: for k,v in pairs(enchantInfo) do yellowfive@124: Amr.db.char.ExtraEnchantData[k] = v yellowfive@124: end yellowfive@57: yellowfive@57: -- also update shopping list after import yellowfive@57: Amr:UpdateShoppingData(currentPlayerData) yellowfive@57: end yellowfive@57: end