annotate Import.lua @ 57:01b63b8ed811 v21

total rewrite to version 21
author yellowfive
date Fri, 05 Jun 2015 11:05:15 -0700
parents
children 69db1c3025ac
rev   line source
yellowfive@57 1 local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot")
yellowfive@57 2 local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true)
yellowfive@57 3 local AceGUI = LibStub("AceGUI-3.0")
yellowfive@57 4
yellowfive@57 5 local _txtImport
yellowfive@57 6 local _lblError
yellowfive@57 7
yellowfive@57 8 local function onImportOkClick(widget)
yellowfive@57 9 local txt = _txtImport:GetText()
yellowfive@57 10 local msg = Amr:ImportCharacter(txt)
yellowfive@57 11 if msg then
yellowfive@57 12 _lblError:SetText(msg)
yellowfive@57 13 _txtImport:SetFocus(true)
yellowfive@57 14 else
yellowfive@57 15 Amr:HideCover()
yellowfive@57 16 Amr:RefreshGearTab()
yellowfive@57 17 end
yellowfive@57 18 end
yellowfive@57 19
yellowfive@57 20 local function onImportCancelClick(widget)
yellowfive@57 21 Amr:HideCover()
yellowfive@57 22 end
yellowfive@57 23
yellowfive@57 24 local function renderImportWindow(container)
yellowfive@57 25
yellowfive@57 26 local panelImport = Amr:RenderCoverChrome(container, 700, 450)
yellowfive@57 27
yellowfive@57 28 local lbl = AceGUI:Create("AmrUiLabel")
yellowfive@57 29 lbl:SetWidth(600)
yellowfive@57 30 lbl:SetText(L.ImportHeader)
yellowfive@57 31 lbl:SetPoint("TOP", panelImport.content, "TOP", 0, -10)
yellowfive@57 32 panelImport:AddChild(lbl)
yellowfive@57 33
yellowfive@57 34 _txtImport = AceGUI:Create("AmrUiTextarea")
yellowfive@57 35 _txtImport:SetWidth(600)
yellowfive@57 36 _txtImport:SetHeight(300)
yellowfive@57 37 _txtImport:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -10)
yellowfive@57 38 _txtImport:SetFont(Amr.CreateFont("Regular", 12, Amr.Colors.Text))
yellowfive@57 39 panelImport:AddChild(_txtImport)
yellowfive@57 40
yellowfive@57 41 local btnImportOk = AceGUI:Create("AmrUiButton")
yellowfive@57 42 btnImportOk:SetText(L.ImportButtonOk)
yellowfive@57 43 btnImportOk:SetBackgroundColor(Amr.Colors.Green)
yellowfive@57 44 btnImportOk:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
yellowfive@57 45 btnImportOk:SetWidth(120)
yellowfive@57 46 btnImportOk:SetHeight(28)
yellowfive@57 47 btnImportOk:SetPoint("TOPLEFT", _txtImport.frame, "BOTTOMLEFT", 0, -10)
yellowfive@57 48 btnImportOk:SetCallback("OnClick", onImportOkClick)
yellowfive@57 49 panelImport:AddChild(btnImportOk)
yellowfive@57 50
yellowfive@57 51 local btnImportCancel = AceGUI:Create("AmrUiButton")
yellowfive@57 52 btnImportCancel:SetText(L.ImportButtonCancel)
yellowfive@57 53 btnImportCancel:SetBackgroundColor(Amr.Colors.Green)
yellowfive@57 54 btnImportCancel:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
yellowfive@57 55 btnImportCancel:SetWidth(120)
yellowfive@57 56 btnImportCancel:SetHeight(28)
yellowfive@57 57 btnImportCancel:SetPoint("LEFT", btnImportOk.frame, "RIGHT", 20, 0)
yellowfive@57 58 btnImportCancel:SetCallback("OnClick", onImportCancelClick)
yellowfive@57 59 panelImport:AddChild(btnImportCancel)
yellowfive@57 60
yellowfive@57 61 _lblError = AceGUI:Create("AmrUiLabel")
yellowfive@57 62 _lblError:SetWidth(600)
yellowfive@57 63 _lblError:SetFont(Amr.CreateFont("Bold", 14, Amr.Colors.Red))
yellowfive@57 64 _lblError:SetText("")
yellowfive@57 65 _lblError:SetPoint("TOPLEFT", btnImportOk.frame, "BOTTOMLEFT", 0, -20)
yellowfive@57 66 panelImport:AddChild(_lblError)
yellowfive@57 67
yellowfive@57 68 end
yellowfive@57 69
yellowfive@57 70 function Amr:ShowImportWindow()
yellowfive@57 71 -- this is shown as a modal dialog
yellowfive@57 72 Amr:ShowCover(renderImportWindow)
yellowfive@57 73
yellowfive@57 74 _txtImport:SetText("")
yellowfive@57 75 _txtImport:SetFocus(true)
yellowfive@57 76 end
yellowfive@57 77
yellowfive@57 78 ----------------------------------------------------------------------------
yellowfive@57 79 -- Import Parsing
yellowfive@57 80 ----------------------------------------------------------------------------
yellowfive@57 81
yellowfive@57 82 --
yellowfive@57 83 -- Import a character, returning nil on success, otherwise an error message, import result stored in the db.
yellowfive@57 84 --
yellowfive@57 85 function Amr:ImportCharacter(data, isTest)
yellowfive@57 86
yellowfive@57 87 -- make sure all data is up to date before importing and get a local copy of player's current state
yellowfive@57 88 local currentPlayerData = self:ExportCharacter()
yellowfive@57 89
yellowfive@57 90 if data == nil or string.len(data) == 0 then
yellowfive@57 91 return L.ImportErrorEmpty
yellowfive@57 92 end
yellowfive@57 93
yellowfive@57 94 -- if multiple specs are included in the data, parse each individually, then quit
yellowfive@57 95 local specParts = { strsplit("\n", data) }
yellowfive@57 96 if #specParts > 1 then
yellowfive@57 97 for i = 1, #specParts do
yellowfive@57 98 local err = self:ImportCharacter(specParts[i], isTest)
yellowfive@57 99 if err ~= nil then
yellowfive@57 100 return err
yellowfive@57 101 end
yellowfive@57 102 end
yellowfive@57 103 return
yellowfive@57 104 end
yellowfive@57 105
yellowfive@57 106 local data1 = { strsplit("$", data) }
yellowfive@57 107 if #data1 ~= 3 then
yellowfive@57 108 return L.ImportErrorFormat
yellowfive@57 109 end
yellowfive@57 110
yellowfive@57 111 local parts = { strsplit(";", data1[2]) }
yellowfive@57 112
yellowfive@57 113 -- require a minimum version
yellowfive@57 114 local ver = tonumber(parts[1])
yellowfive@57 115 if ver < Amr.MIN_IMPORT_VERSION then
yellowfive@57 116 return L.ImportErrorVersion
yellowfive@57 117 end
yellowfive@57 118
yellowfive@57 119 -- require name match (don't match realm due to language issues for now)
yellowfive@57 120 if not isTest then
yellowfive@57 121 local region = parts[2]
yellowfive@57 122 local realm = parts[3]
yellowfive@57 123 local name = parts[4]
yellowfive@57 124 if name ~= currentPlayerData.Name then
yellowfive@57 125 local importPlayerName = name .. " (" .. realm .. ")"
yellowfive@57 126 local you = currentPlayerData.Name .. " (" .. currentPlayerData.Realm .. ")"
yellowfive@57 127 return L.ImportErrorChar(importPlayerName, you)
yellowfive@57 128 end
yellowfive@57 129
yellowfive@57 130 -- require race match
yellowfive@57 131 local race = tonumber(parts[6])
yellowfive@57 132 if race ~= Amr.RaceIds[currentPlayerData.Race] then
yellowfive@57 133 return L.ImportErrorRace
yellowfive@57 134 end
yellowfive@57 135
yellowfive@57 136 -- require faction match
yellowfive@57 137 local faction = tonumber(parts[7])
yellowfive@57 138 if faction ~= Amr.FactionIds[currentPlayerData.Faction] then
yellowfive@57 139 return L.ImportErrorFaction
yellowfive@57 140 end
yellowfive@57 141
yellowfive@57 142 -- require level match
yellowfive@57 143 local level = tonumber(parts[8])
yellowfive@57 144 if level ~= currentPlayerData.Level then
yellowfive@57 145 return L.ImportErrorLevel
yellowfive@57 146 end
yellowfive@57 147 end
yellowfive@57 148
yellowfive@57 149 -- if we make it this far, the data is valid, so read item information
yellowfive@57 150 local specSlot = tonumber(parts[10])
yellowfive@57 151
yellowfive@57 152 local importData = {}
yellowfive@57 153
yellowfive@57 154 local itemInfo = {}
yellowfive@57 155 local gemInfo = {}
yellowfive@57 156 local enchantInfo = {}
yellowfive@57 157
yellowfive@57 158 local prevItemId = 0
yellowfive@57 159 local prevGemId = 0
yellowfive@57 160 local prevEnchantId = 0
yellowfive@57 161 local prevUpgradeId = 0
yellowfive@57 162 local prevBonusId = 0
yellowfive@57 163 local digits = {
yellowfive@57 164 ["-"] = true,
yellowfive@57 165 ["0"] = true,
yellowfive@57 166 ["1"] = true,
yellowfive@57 167 ["2"] = true,
yellowfive@57 168 ["3"] = true,
yellowfive@57 169 ["4"] = true,
yellowfive@57 170 ["5"] = true,
yellowfive@57 171 ["6"] = true,
yellowfive@57 172 ["7"] = true,
yellowfive@57 173 ["8"] = true,
yellowfive@57 174 ["9"] = true,
yellowfive@57 175 }
yellowfive@57 176 for i = 16, #parts do
yellowfive@57 177 local itemString = parts[i]
yellowfive@57 178 if itemString ~= "" and itemString ~= "_" then
yellowfive@57 179 local tokens = {}
yellowfive@57 180 local bonusIds = {}
yellowfive@57 181 local hasBonuses = false
yellowfive@57 182 local token = ""
yellowfive@57 183 local prop = "i"
yellowfive@57 184 local tokenComplete = false
yellowfive@57 185 for j = 1, string.len(itemString) do
yellowfive@57 186 local c = string.sub(itemString, j, j)
yellowfive@57 187 if digits[c] == nil then
yellowfive@57 188 tokenComplete = true
yellowfive@57 189 else
yellowfive@57 190 token = token .. c
yellowfive@57 191 end
yellowfive@57 192
yellowfive@57 193 if tokenComplete or j == string.len(itemString) then
yellowfive@57 194 local val = tonumber(token)
yellowfive@57 195 if prop == "i" then
yellowfive@57 196 val = val + prevItemId
yellowfive@57 197 prevItemId = val
yellowfive@57 198 elseif prop == "u" then
yellowfive@57 199 val = val + prevUpgradeId
yellowfive@57 200 prevUpgradeId = val
yellowfive@57 201 elseif prop == "b" then
yellowfive@57 202 val = val + prevBonusId
yellowfive@57 203 prevBonusId = val
yellowfive@57 204 elseif prop == "x" or prop == "y" or prop == "z" then
yellowfive@57 205 val = val + prevGemId
yellowfive@57 206 prevGemId = val
yellowfive@57 207 elseif prop == "e" then
yellowfive@57 208 val = val + prevEnchantId
yellowfive@57 209 prevEnchantId = val
yellowfive@57 210 end
yellowfive@57 211
yellowfive@57 212 if prop == "b" then
yellowfive@57 213 table.insert(bonusIds, val)
yellowfive@57 214 hasBonuses = true
yellowfive@57 215 else
yellowfive@57 216 tokens[prop] = val
yellowfive@57 217 end
yellowfive@57 218
yellowfive@57 219 token = ""
yellowfive@57 220 tokenComplete = false
yellowfive@57 221
yellowfive@57 222 -- we have moved on to the next token
yellowfive@57 223 prop = c
yellowfive@57 224 end
yellowfive@57 225 end
yellowfive@57 226
yellowfive@57 227 local obj = {}
yellowfive@57 228 importData[tonumber(tokens["s"])] = obj
yellowfive@57 229
yellowfive@57 230 obj.id = tokens["i"]
yellowfive@57 231 obj.suffixId = tokens["f"] or 0
yellowfive@57 232 obj.upgradeId = tokens["u"] or 0
yellowfive@57 233 obj.enchantId = tokens["e"] or 0
yellowfive@57 234
yellowfive@57 235 obj.gemIds = {}
yellowfive@57 236 table.insert(obj.gemIds, tokens["x"] or 0)
yellowfive@57 237 table.insert(obj.gemIds, tokens["y"] or 0)
yellowfive@57 238 table.insert(obj.gemIds, tokens["z"] or 0)
yellowfive@57 239 table.insert(obj.gemIds, 0)
yellowfive@57 240
yellowfive@57 241 if hasBonuses then
yellowfive@57 242 obj.bonusIds = bonusIds
yellowfive@57 243 end
yellowfive@57 244
yellowfive@57 245 local itemObj = {}
yellowfive@57 246 itemObj.id = obj.id
yellowfive@57 247 itemInfo[obj.id] = itemObj
yellowfive@57 248
yellowfive@57 249 -- look for any socket color information, add to our extra data
yellowfive@57 250 if tokens["c"] then
yellowfive@57 251 itemObj.socketColors = {}
yellowfive@57 252 for j = 1, string.len(tokens["c"]) do
yellowfive@57 253 table.insert(itemObj.socketColors, tonumber(string.sub(tokens["c"], j, j)))
yellowfive@57 254 end
yellowfive@57 255 end
yellowfive@57 256
yellowfive@57 257 -- look for item ID duplicate info, deals with old SoO items
yellowfive@57 258 if tokens["d"] then
yellowfive@57 259 itemObj.duplicateId = tonumber(tokens["d"])
yellowfive@57 260 itemInfo[itemObj.duplicateId] = itemObj
yellowfive@57 261 end
yellowfive@57 262
yellowfive@57 263 end
yellowfive@57 264 end
yellowfive@57 265
yellowfive@57 266 -- now read any extra display information
yellowfive@57 267 parts = { strsplit("@", data1[3]) }
yellowfive@57 268 for i = 1, #parts do
yellowfive@57 269 local infoParts = { strsplit("\\", parts[i]) }
yellowfive@57 270
yellowfive@57 271 if infoParts[1] == "g" then
yellowfive@57 272
yellowfive@57 273 local gemObj = {}
yellowfive@57 274 gemObj.enchantId = tonumber(infoParts[2])
yellowfive@57 275 gemObj.id = tonumber(infoParts[3])
yellowfive@57 276
yellowfive@57 277 local identicalGems = infoParts[4]
yellowfive@57 278 if string.len(identicalGems) > 0 then
yellowfive@57 279 gemObj.identicalGroup = {}
yellowfive@57 280 identicalGems = { strsplit(",", identicalGems) }
yellowfive@57 281 for j = 1, #identicalGems do
yellowfive@57 282 gemObj.identicalGroup[tonumber(identicalGems[j])] = true
yellowfive@57 283 end
yellowfive@57 284 end
yellowfive@57 285
yellowfive@57 286 gemObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.StatsShort[s] end)
yellowfive@57 287 if infoParts[6] == nil or string.len(infoParts[6]) == 0 then
yellowfive@57 288 gemObj.identicalItemGroup = {[gemObj.id]=true}
yellowfive@57 289 else
yellowfive@57 290 local identicalIds = { strsplit(',', infoParts[6]) }
yellowfive@57 291 gemObj.identicalItemGroup = {}
yellowfive@57 292 for j = 1, #identicalIds do
yellowfive@57 293 gemObj.identicalItemGroup[tonumber(identicalIds[j])] = true
yellowfive@57 294 end
yellowfive@57 295 end
yellowfive@57 296
yellowfive@57 297 gemInfo[gemObj.enchantId] = gemObj
yellowfive@57 298
yellowfive@57 299 elseif infoParts[1] == "e" then
yellowfive@57 300
yellowfive@57 301 local enchObj = {}
yellowfive@57 302 enchObj.id = tonumber(infoParts[2])
yellowfive@57 303 enchObj.itemId = tonumber(infoParts[3])
yellowfive@57 304 enchObj.spellId = tonumber(infoParts[4])
yellowfive@57 305 enchObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.StatsShort[s] end)
yellowfive@57 306
yellowfive@57 307 local mats = infoParts[6]
yellowfive@57 308 if string.len(mats) > 0 then
yellowfive@57 309 enchObj.materials = {}
yellowfive@57 310 mats = { strsplit(",", mats) }
yellowfive@57 311 for j = 1, #mats do
yellowfive@57 312 local kv = { strsplit("=", mats[j]) }
yellowfive@57 313 enchObj.materials[tonumber(kv[1])] = tonumber(kv[2])
yellowfive@57 314 end
yellowfive@57 315 end
yellowfive@57 316
yellowfive@57 317 enchantInfo[enchObj.id] = enchObj
yellowfive@57 318
yellowfive@57 319 end
yellowfive@57 320 end
yellowfive@57 321
yellowfive@57 322 if isTest then
yellowfive@57 323 print("spec " .. specSlot)
yellowfive@57 324 -- print result for debugging
yellowfive@57 325 for k,v in pairs(importData) do
yellowfive@57 326 local blah = Amr.CreateItemLink(v)
yellowfive@57 327 --print(blah)
yellowfive@57 328 local name, link = GetItemInfo(blah)
yellowfive@57 329 print(link)
yellowfive@57 330 if link == nil then
yellowfive@57 331 print(blah)
yellowfive@57 332 print("bad item: " .. v.id)
yellowfive@57 333 end
yellowfive@57 334 end
yellowfive@57 335
yellowfive@57 336
yellowfive@57 337 else
yellowfive@57 338 -- we have succeeded, record the result
yellowfive@57 339 Amr.db.char.GearSets[specSlot] = importData
yellowfive@57 340 Amr.db.char.ExtraItemData[specSlot] = itemInfo
yellowfive@57 341 Amr.db.char.ExtraGemData[specSlot] = gemInfo
yellowfive@57 342 Amr.db.char.ExtraEnchantData[specSlot] = enchantInfo
yellowfive@57 343
yellowfive@57 344 -- also update shopping list after import
yellowfive@57 345 Amr:UpdateShoppingData(currentPlayerData)
yellowfive@57 346 end
yellowfive@57 347 end