Mercurial > wow > askmrrobot
comparison Import.lua @ 161:35612aee8e15
Added junk list.
| author | yellowfive |
|---|---|
| date | Mon, 06 May 2019 14:08:03 -0700 |
| parents | cc82eeeec1c8 |
| children | f27a7c64b21f |
comparison
equal
deleted
inserted
replaced
| 160:d670336e8c89 | 161:35612aee8e15 |
|---|---|
| 25 local function onTextEnterPressed(widget) | 25 local function onTextEnterPressed(widget) |
| 26 -- hide the overwolf cover when import data is received | 26 -- hide the overwolf cover when import data is received |
| 27 if _panelCover then | 27 if _panelCover then |
| 28 _panelCover:SetVisible(false) | 28 _panelCover:SetVisible(false) |
| 29 end | 29 end |
| 30 | 30 |
| 31 -- do an import if the data starts and ends with a dollar sign | 31 -- do an import if the data starts with a dollar sign |
| 32 local txt = _txtImport:GetText() | 32 local txt = _txtImport:GetText() |
| 33 local txtLen = string.len(txt) | 33 local txtLen = string.len(txt) |
| 34 if txtLen > 2 and string.sub(txt, 1, 1) == '$' then | 34 if txtLen > 6 and (string.sub(txt, 1, 1) == '$' or string.sub(txt, 1, 5) == "_bib_" or string.sub(txt, 1, 6) == "_junk_") then |
| 35 onImportOkClick() | 35 onImportOkClick() |
| 36 end | 36 end |
| 37 | 37 |
| 38 end | 38 end |
| 39 | 39 |
| 120 ---------------------------------------------------------------------------- | 120 ---------------------------------------------------------------------------- |
| 121 -- Import Parsing | 121 -- Import Parsing |
| 122 ---------------------------------------------------------------------------- | 122 ---------------------------------------------------------------------------- |
| 123 | 123 |
| 124 -- | 124 -- |
| 125 -- Import a character, returning nil on success, otherwise an error message, import result stored in the db. | 125 -- Helper to parse a list of items in the standard item list format. |
| 126 -- | 126 -- |
| 127 function Amr:ImportCharacter(data, isTest, isChild) | 127 local function parseItemList(parts, startPos, endToken, hasSlot) |
| 128 | 128 |
| 129 -- make sure all data is up to date before importing and get a local copy of player's current state | |
| 130 local currentPlayerData = self:ExportCharacter() | |
| 131 | |
| 132 if data == nil or string.len(data) == 0 then | |
| 133 return L.ImportErrorEmpty | |
| 134 end | |
| 135 | |
| 136 -- if multiple setups are included in the data, parse each individually, then quit | |
| 137 local specParts = { strsplit("\n", data) } | |
| 138 if #specParts > 1 then | |
| 139 -- clear out any previously-imported BiB setups when importing new ones (non-BiB will always be imported one at a time) | |
| 140 for i = #Amr.db.char.GearSetups, 1, -1 do | |
| 141 if Amr.db.char.GearSetups[i].IsBib then | |
| 142 table.remove(Amr.db.char.GearSetups, i) | |
| 143 end | |
| 144 end | |
| 145 | |
| 146 for i = 1, #specParts do | |
| 147 if specParts[i] ~= "_bib_" then | |
| 148 local err = self:ImportCharacter(specParts[i], isTest, true) | |
| 149 if err ~= nil then | |
| 150 return err | |
| 151 end | |
| 152 end | |
| 153 end | |
| 154 | |
| 155 -- ensure that all BiB setups are sorted to the top | |
| 156 local nonBib = {} | |
| 157 for i = #Amr.db.char.GearSetups, 1, -1 do | |
| 158 if not Amr.db.char.GearSetups[i].IsBib then | |
| 159 table.insert(nonBib, Amr.db.char.GearSetups[i]) | |
| 160 table.remove(Amr.db.char.GearSetups, i) | |
| 161 end | |
| 162 end | |
| 163 for i, setup in ipairs(nonBib) do | |
| 164 table.insert(Amr.db.char.GearSetups, setup) | |
| 165 end | |
| 166 | |
| 167 return | |
| 168 end | |
| 169 | |
| 170 local data1 = { strsplit("$", data) } | |
| 171 if #data1 ~= 3 then | |
| 172 return L.ImportErrorFormat | |
| 173 end | |
| 174 | |
| 175 local parts = { strsplit(";", data1[2]) } | |
| 176 | |
| 177 -- require a minimum version | |
| 178 local ver = tonumber(parts[1]) | |
| 179 if ver < Amr.MIN_IMPORT_VERSION then | |
| 180 return L.ImportErrorVersion | |
| 181 end | |
| 182 | |
| 183 -- require name match (don't match realm due to language issues for now) | |
| 184 if not isTest then | |
| 185 local region = parts[2] | |
| 186 local realm = parts[3] | |
| 187 local name = parts[4] | |
| 188 if name ~= currentPlayerData.Name then | |
| 189 local importPlayerName = name .. " (" .. realm .. ")" | |
| 190 local you = currentPlayerData.Name .. " (" .. currentPlayerData.Realm .. ")" | |
| 191 return L.ImportErrorChar(importPlayerName, you) | |
| 192 end | |
| 193 | |
| 194 -- require race match | |
| 195 local race = tonumber(parts[6]) | |
| 196 if race ~= Amr.RaceIds[currentPlayerData.Race] then | |
| 197 return L.ImportErrorRace | |
| 198 end | |
| 199 | |
| 200 -- require faction match | |
| 201 local faction = tonumber(parts[7]) | |
| 202 if faction ~= Amr.FactionIds[currentPlayerData.Faction] then | |
| 203 return L.ImportErrorFaction | |
| 204 end | |
| 205 | |
| 206 -- require level match | |
| 207 local level = tonumber(parts[8]) | |
| 208 if level ~= currentPlayerData.Level then | |
| 209 return L.ImportErrorLevel | |
| 210 end | |
| 211 end | |
| 212 | |
| 213 -- if we make it this far, the data is valid, so read item information | |
| 214 local specSlot = tonumber(parts[11]) | |
| 215 | |
| 216 local importData = {} | 129 local importData = {} |
| 217 local enchantInfo = {} | 130 |
| 218 | |
| 219 local prevItemId = 0 | 131 local prevItemId = 0 |
| 220 local prevGemId = 0 | 132 local prevGemId = 0 |
| 221 local prevEnchantId = 0 | 133 local prevEnchantId = 0 |
| 222 local prevUpgradeId = 0 | 134 local prevUpgradeId = 0 |
| 223 local prevBonusId = 0 | 135 local prevBonusId = 0 |
| 234 ["6"] = true, | 146 ["6"] = true, |
| 235 ["7"] = true, | 147 ["7"] = true, |
| 236 ["8"] = true, | 148 ["8"] = true, |
| 237 ["9"] = true, | 149 ["9"] = true, |
| 238 } | 150 } |
| 239 for i = 16, #parts do | 151 for i = startPos, #parts do |
| 240 local itemString = parts[i] | 152 local itemString = parts[i] |
| 241 if itemString ~= "" and itemString ~= "_" then | 153 if itemString == endToken then |
| 154 break | |
| 155 elseif itemString ~= "" and itemString ~= "_" then | |
| 242 local tokens = {} | 156 local tokens = {} |
| 243 local bonusIds = {} | 157 local bonusIds = {} |
| 244 local azerite = {} | 158 local azerite = {} |
| 245 local hasBonuses = false | 159 local hasBonuses = false |
| 246 local hasAzerites = false | 160 local hasAzerites = false |
| 297 prop = c | 211 prop = c |
| 298 end | 212 end |
| 299 end | 213 end |
| 300 | 214 |
| 301 local obj = {} | 215 local obj = {} |
| 302 importData[tonumber(tokens["s"])] = obj | 216 |
| 303 | 217 if hasSlot then |
| 218 importData[tonumber(tokens["s"])] = obj | |
| 219 else | |
| 220 table.insert(importData, obj) | |
| 221 end | |
| 222 | |
| 304 obj.id = tokens["i"] | 223 obj.id = tokens["i"] |
| 305 obj.suffixId = tokens["f"] or 0 | 224 obj.suffixId = tokens["f"] or 0 |
| 306 obj.upgradeId = tokens["u"] or 0 | 225 obj.upgradeId = tokens["u"] or 0 |
| 307 obj.level = tokens["v"] or 0 | 226 obj.level = tokens["v"] or 0 |
| 308 obj.enchantId = tokens["e"] or 0 | 227 obj.enchantId = tokens["e"] or 0 |
| 321 if hasAzerites then | 240 if hasAzerites then |
| 322 obj.azerite = azerite | 241 obj.azerite = azerite |
| 323 end | 242 end |
| 324 end | 243 end |
| 325 end | 244 end |
| 245 | |
| 246 return importData | |
| 247 end | |
| 248 | |
| 249 -- | |
| 250 -- Import a character, returning nil on success, otherwise an error message, import result stored in the db. | |
| 251 -- | |
| 252 function Amr:ImportCharacter(data, isTest, isChild) | |
| 253 | |
| 254 -- make sure all data is up to date before importing and get a local copy of player's current state | |
| 255 local currentPlayerData = self:ExportCharacter() | |
| 256 | |
| 257 if data == nil or string.len(data) == 0 then | |
| 258 return L.ImportErrorEmpty | |
| 259 end | |
| 260 | |
| 261 -- if multiple setups are included in the data, parse each individually, then quit | |
| 262 local specParts = { strsplit("\n", data) } | |
| 263 | |
| 264 if #specParts > 1 and specParts[1] == "_junk_" then | |
| 265 -- if the string starts with "_junk_" then it is the junk list | |
| 266 Amr:ImportJunkList(specParts[2], currentPlayerData) | |
| 267 return | |
| 268 | |
| 269 elseif #specParts > 1 then | |
| 270 -- clear out any previously-imported BiB setups when importing new ones (non-BiB will always be imported one at a time) | |
| 271 for i = #Amr.db.char.GearSetups, 1, -1 do | |
| 272 if Amr.db.char.GearSetups[i].IsBib then | |
| 273 table.remove(Amr.db.char.GearSetups, i) | |
| 274 end | |
| 275 end | |
| 276 | |
| 277 for i = 1, #specParts do | |
| 278 if specParts[i] ~= "_bib_" then | |
| 279 local err = self:ImportCharacter(specParts[i], isTest, true) | |
| 280 if err ~= nil then | |
| 281 return err | |
| 282 end | |
| 283 end | |
| 284 end | |
| 285 | |
| 286 -- ensure that all BiB setups are sorted to the top | |
| 287 local nonBib = {} | |
| 288 for i = #Amr.db.char.GearSetups, 1, -1 do | |
| 289 if not Amr.db.char.GearSetups[i].IsBib then | |
| 290 table.insert(nonBib, Amr.db.char.GearSetups[i]) | |
| 291 table.remove(Amr.db.char.GearSetups, i) | |
| 292 end | |
| 293 end | |
| 294 for i, setup in ipairs(nonBib) do | |
| 295 table.insert(Amr.db.char.GearSetups, setup) | |
| 296 end | |
| 297 | |
| 298 return | |
| 299 end | |
| 300 | |
| 301 local data1 = { strsplit("$", data) } | |
| 302 if #data1 ~= 3 then | |
| 303 return L.ImportErrorFormat | |
| 304 end | |
| 305 | |
| 306 local parts = { strsplit(";", data1[2]) } | |
| 307 | |
| 308 -- require a minimum version | |
| 309 local ver = tonumber(parts[1]) | |
| 310 if ver < Amr.MIN_IMPORT_VERSION then | |
| 311 return L.ImportErrorVersion | |
| 312 end | |
| 313 | |
| 314 -- require name match (don't match realm due to language issues for now) | |
| 315 if not isTest then | |
| 316 local region = parts[2] | |
| 317 local realm = parts[3] | |
| 318 local name = parts[4] | |
| 319 if name ~= currentPlayerData.Name then | |
| 320 local importPlayerName = name .. " (" .. realm .. ")" | |
| 321 local you = currentPlayerData.Name .. " (" .. currentPlayerData.Realm .. ")" | |
| 322 return L.ImportErrorChar(importPlayerName, you) | |
| 323 end | |
| 324 | |
| 325 -- require race match | |
| 326 local race = tonumber(parts[6]) | |
| 327 if race ~= Amr.RaceIds[currentPlayerData.Race] then | |
| 328 return L.ImportErrorRace | |
| 329 end | |
| 330 | |
| 331 -- require faction match | |
| 332 local faction = tonumber(parts[7]) | |
| 333 if faction ~= Amr.FactionIds[currentPlayerData.Faction] then | |
| 334 return L.ImportErrorFaction | |
| 335 end | |
| 336 | |
| 337 -- require level match | |
| 338 local level = tonumber(parts[8]) | |
| 339 if level ~= currentPlayerData.Level then | |
| 340 return L.ImportErrorLevel | |
| 341 end | |
| 342 end | |
| 343 | |
| 344 -- if we make it this far, the data is valid, so read item information | |
| 345 local specSlot = tonumber(parts[11]) | |
| 346 | |
| 347 local importData = parseItemList(parts, 16, "n/a", true) | |
| 326 | 348 |
| 327 -- extra information contains setup id, display label, then extra enchant info | 349 -- extra information contains setup id, display label, then extra enchant info |
| 328 parts = { strsplit("@", data1[3]) } | 350 parts = { strsplit("@", data1[3]) } |
| 329 | 351 |
| 330 local setupId = parts[2] | 352 local setupId = parts[2] |
| 331 local setupName = parts[3] | 353 local setupName = parts[3] |
| 354 local enchantInfo = {} | |
| 332 | 355 |
| 333 for i = 4, #parts do | 356 for i = 4, #parts do |
| 334 local infoParts = { strsplit("\\", parts[i]) } | 357 local infoParts = { strsplit("\\", parts[i]) } |
| 335 | 358 |
| 336 if infoParts[1] == "e" then | 359 if infoParts[1] == "e" then |
| 408 | 431 |
| 409 -- also update shopping list after import | 432 -- also update shopping list after import |
| 410 Amr:UpdateShoppingData(currentPlayerData) | 433 Amr:UpdateShoppingData(currentPlayerData) |
| 411 end | 434 end |
| 412 end | 435 end |
| 436 | |
| 437 -- | |
| 438 -- Import a list of items that are junk. | |
| 439 -- | |
| 440 function Amr:ImportJunkList(data, currentPlayerData) | |
| 441 | |
| 442 local data1 = { strsplit("$", data) } | |
| 443 if #data1 ~= 3 then | |
| 444 return L.ImportErrorFormat | |
| 445 end | |
| 446 | |
| 447 local parts = { strsplit(";", data1[2]) } | |
| 448 | |
| 449 -- require a minimum version | |
| 450 local ver = tonumber(parts[1]) | |
| 451 if ver < Amr.MIN_IMPORT_VERSION then | |
| 452 return L.ImportErrorVersion | |
| 453 end | |
| 454 | |
| 455 -- require name match | |
| 456 local region = parts[2] | |
| 457 local realm = parts[3] | |
| 458 local name = parts[4] | |
| 459 if name ~= currentPlayerData.Name then | |
| 460 local importPlayerName = name .. " (" .. realm .. ")" | |
| 461 local you = currentPlayerData.Name .. " (" .. currentPlayerData.Realm .. ")" | |
| 462 return L.ImportErrorChar(importPlayerName, you) | |
| 463 end | |
| 464 | |
| 465 local keepStartPos = 0 | |
| 466 local junkStartPos = 0 | |
| 467 for i = 5, #parts do | |
| 468 local partString = parts[i] | |
| 469 if partString == ".k" then | |
| 470 keepStartPos = i + 1 | |
| 471 elseif partString == ".d" then | |
| 472 junkStartPos = i + 1 | |
| 473 end | |
| 474 end | |
| 475 | |
| 476 Amr.db.char.JunkData = {} | |
| 477 | |
| 478 -- Keep is a lookup by unique id | |
| 479 local keep = parseItemList(parts, keepStartPos, ".d", false) | |
| 480 Amr.db.char.JunkData.Keep = {} | |
| 481 for i = 1, #keep do | |
| 482 local uniqueId = Amr.GetItemUniqueId(keep[i]) | |
| 483 Amr.db.char.JunkData.Keep[uniqueId] = keep[i] | |
| 484 end | |
| 485 | |
| 486 -- Junk is a simple list of items to discard, in the desired display order | |
| 487 Amr.db.char.JunkData.Junk = parseItemList(parts, junkStartPos, "n/a", false) | |
| 488 | |
| 489 -- extra information contains extra enchant info | |
| 490 if #data1 >= 3 then | |
| 491 parts = { strsplit("@", data1[3]) } | |
| 492 | |
| 493 local enchantInfo = {} | |
| 494 | |
| 495 for i = 2, #parts do | |
| 496 local infoParts = { strsplit("\\", parts[i]) } | |
| 497 | |
| 498 if infoParts[1] == "e" then | |
| 499 | |
| 500 local enchObj = {} | |
| 501 enchObj.id = tonumber(infoParts[2]) | |
| 502 enchObj.itemId = tonumber(infoParts[3]) | |
| 503 enchObj.spellId = tonumber(infoParts[4]) | |
| 504 enchObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.StatsShort[s] end) | |
| 505 | |
| 506 local mats = infoParts[6] | |
| 507 if string.len(mats) > 0 then | |
| 508 enchObj.materials = {} | |
| 509 mats = { strsplit(",", mats) } | |
| 510 for j = 1, #mats do | |
| 511 local kv = { strsplit("=", mats[j]) } | |
| 512 enchObj.materials[tonumber(kv[1])] = tonumber(kv[2]) | |
| 513 end | |
| 514 end | |
| 515 | |
| 516 enchantInfo[enchObj.id] = enchObj | |
| 517 end | |
| 518 end | |
| 519 | |
| 520 for k,v in pairs(enchantInfo) do | |
| 521 Amr.db.char.ExtraEnchantData[k] = v | |
| 522 end | |
| 523 end | |
| 524 | |
| 525 -- show the junk window after a successful junk import | |
| 526 Amr:ShowJunkWindow() | |
| 527 end |
