Mercurial > wow > askmrrobot
comparison AskMrRobot-Serializer/AskMrRobot-Serializer.lua @ 124:e31b02b24488
Updated for 8.0 pre-patch and BfA.
author | yellowfive |
---|---|
date | Tue, 17 Jul 2018 09:57:39 -0700 |
parents | f1da233629be |
children | 65c285394049 |
comparison
equal
deleted
inserted
replaced
123:7a6364917f86 | 124:e31b02b24488 |
---|---|
1 -- AskMrRobot-Serializer will serialize and communicate character data between users. | 1 -- AskMrRobot-Serializer will serialize and communicate character data between users. |
2 -- This is used primarily to associate character information to logs uploaded to askmrrobot.com. | 2 |
3 | 3 local MAJOR, MINOR = "AskMrRobot-Serializer", 58 |
4 local MAJOR, MINOR = "AskMrRobot-Serializer", 57 | |
5 local Amr, oldminor = LibStub:NewLibrary(MAJOR, MINOR) | 4 local Amr, oldminor = LibStub:NewLibrary(MAJOR, MINOR) |
6 | 5 |
7 if not Amr then return end -- already loaded by something else | 6 if not Amr then return end -- already loaded by something else |
8 | 7 |
9 -- event and comm used for player snapshotting on entering combat | 8 -- event and comm used for player snapshotting on entering combat |
165 [1648] = true, | 164 [1648] = true, |
166 [1676] = true, | 165 [1676] = true, |
167 [1712] = true | 166 [1712] = true |
168 } | 167 } |
169 | 168 |
170 -- just to make life easier, maps ID of each artifact weapon to the spec number (1-4) | |
171 Amr.ArtifactIdToSpecNumber = { | |
172 [128402] = 1, -- DK | |
173 [128292] = 2, | |
174 [128403] = 3, | |
175 [127829] = 1, -- DH | |
176 [128832] = 2, | |
177 [128858] = 1, -- Druid | |
178 [128860] = 2, | |
179 [128821] = 3, | |
180 [128306] = 4, | |
181 [128861] = 1, -- Hunter | |
182 [128826] = 2, | |
183 [128808] = 3, | |
184 [127857] = 1, -- Mage | |
185 [128820] = 2, | |
186 [128862] = 3, | |
187 [128938] = 1, -- Monk | |
188 [128937] = 2, | |
189 [128940] = 3, | |
190 [128823] = 1, -- Paladin | |
191 [128866] = 2, | |
192 [120978] = 3, | |
193 [128868] = 1, -- Priest | |
194 [128825] = 2, | |
195 [128827] = 3, | |
196 [128870] = 1, -- Rogue | |
197 [128872] = 2, | |
198 [128476] = 3, | |
199 [128935] = 1, -- Shaman | |
200 [128819] = 2, | |
201 [128911] = 3, | |
202 [128942] = 1, -- Warlock | |
203 [128943] = 2, | |
204 [128941] = 3, | |
205 [128910] = 1, -- Warrior | |
206 [128908] = 2, | |
207 [128289] = 3, | |
208 | |
209 --[128293] = 2, -- Frost OH | |
210 --[127830] = 1, -- Havoc OH | |
211 --[128831] = 2, -- Vengeance OH | |
212 --[128859] = 2, -- Feral OH | |
213 --[128822] = 3, -- Guardian OH | |
214 --[133959] = 2, -- Fire OH | |
215 --[133948] = 3, -- Windwalker OH | |
216 --[128867] = 2, -- Prot MH | |
217 --[133958] = 3, -- Shadow OH | |
218 --[128869] = 1, -- Rogue OH's | |
219 --[134552] = 2, | |
220 --[128479] = 3, | |
221 --[128936] = 1, -- Shaman OH's | |
222 --[128873] = 2, | |
223 --[128934] = 3, | |
224 --[137246] = 2, -- Demo MH | |
225 --[134553] = 2, -- Fury OH | |
226 --[128288] = 3 -- Prot MH | |
227 } | |
228 | |
229 -- IDs of set tokens that we would care about in a player's inventory | |
230 Amr.SetTokenIds = { | |
231 [127970] = true, | |
232 [127969] = true, | |
233 [127968] = true, | |
234 [127967] = true, | |
235 [127966] = true, | |
236 [127965] = true, | |
237 [127964] = true, | |
238 [127963] = true, | |
239 [127962] = true, | |
240 [127961] = true, | |
241 [127960] = true, | |
242 [127959] = true, | |
243 [127958] = true, | |
244 [127957] = true, | |
245 [127956] = true, | |
246 [127955] = true, | |
247 [127954] = true, | |
248 [127953] = true, | |
249 [120285] = true, | |
250 [120284] = true, | |
251 [120283] = true, | |
252 [120282] = true, | |
253 [120281] = true, | |
254 [120280] = true, | |
255 [120279] = true, | |
256 [120278] = true, | |
257 [120277] = true, | |
258 [120256] = true, | |
259 [120255] = true, | |
260 [120254] = true, | |
261 [120253] = true, | |
262 [120252] = true, | |
263 [120251] = true, | |
264 [120250] = true, | |
265 [120249] = true, | |
266 [120248] = true, | |
267 [120247] = true, | |
268 [120246] = true, | |
269 [120245] = true, | |
270 [120244] = true, | |
271 [120243] = true, | |
272 [120242] = true, | |
273 [120241] = true, | |
274 [120240] = true, | |
275 [120239] = true, | |
276 [120238] = true, | |
277 [120237] = true, | |
278 [120236] = true, | |
279 [120235] = true, | |
280 [120234] = true, | |
281 [120233] = true, | |
282 [120232] = true, | |
283 [120231] = true, | |
284 [120230] = true, | |
285 [120229] = true, | |
286 [120228] = true, | |
287 [120227] = true, | |
288 [120226] = true, | |
289 [120225] = true, | |
290 [120224] = true, | |
291 [120223] = true, | |
292 [120222] = true, | |
293 [120221] = true, | |
294 [120220] = true, | |
295 [120219] = true, | |
296 [120218] = true, | |
297 [120217] = true, | |
298 [120216] = true, | |
299 [120215] = true, | |
300 [120214] = true, | |
301 [120213] = true, | |
302 [120212] = true, | |
303 [120211] = true, | |
304 [120210] = true, | |
305 [120209] = true, | |
306 [120208] = true, | |
307 [120207] = true, | |
308 [120206] = true, | |
309 [119323] = true, | |
310 [119322] = true, | |
311 [119321] = true, | |
312 [119320] = true, | |
313 [119319] = true, | |
314 [119318] = true, | |
315 [119316] = true, | |
316 [119315] = true, | |
317 [119314] = true, | |
318 [119313] = true, | |
319 [119312] = true, | |
320 [119311] = true, | |
321 [119310] = true, | |
322 [119309] = true, | |
323 [119308] = true, | |
324 [119307] = true, | |
325 [119306] = true, | |
326 [119305] = true, | |
327 [105868] = true, | |
328 [105867] = true, | |
329 [105866] = true, | |
330 [105865] = true, | |
331 [105864] = true, | |
332 [105863] = true, | |
333 [105862] = true, | |
334 [105861] = true, | |
335 [105860] = true, | |
336 [105859] = true, | |
337 [105858] = true, | |
338 [105857] = true, | |
339 [99756] = true, | |
340 [99755] = true, | |
341 [99754] = true, | |
342 [99753] = true, | |
343 [99752] = true, | |
344 [99751] = true, | |
345 [99750] = true, | |
346 [99749] = true, | |
347 [99748] = true, | |
348 [99747] = true, | |
349 [99746] = true, | |
350 [99745] = true, | |
351 [99744] = true, | |
352 [99743] = true, | |
353 [99742] = true, | |
354 [99740] = true, | |
355 [99739] = true, | |
356 [99738] = true, | |
357 [99737] = true, | |
358 [99736] = true, | |
359 [99735] = true, | |
360 [99734] = true, | |
361 [99733] = true, | |
362 [99732] = true, | |
363 [99731] = true, | |
364 [99730] = true, | |
365 [99729] = true, | |
366 [99728] = true, | |
367 [99727] = true, | |
368 [99726] = true, | |
369 [99725] = true, | |
370 [99724] = true, | |
371 [99723] = true, | |
372 [99722] = true, | |
373 [99721] = true, | |
374 [99720] = true, | |
375 [99719] = true, | |
376 [99718] = true, | |
377 [99717] = true, | |
378 [99716] = true, | |
379 [99715] = true, | |
380 [99714] = true, | |
381 [99713] = true, | |
382 [99712] = true, | |
383 [99711] = true, | |
384 [99710] = true, | |
385 [99709] = true, | |
386 [99708] = true, | |
387 [99707] = true, | |
388 [99706] = true, | |
389 [99705] = true, | |
390 [99704] = true, | |
391 [99703] = true, | |
392 [99702] = true, | |
393 [99701] = true, | |
394 [99700] = true, | |
395 [99699] = true, | |
396 [99698] = true, | |
397 [99697] = true, | |
398 [99696] = true, | |
399 [99695] = true, | |
400 [99694] = true, | |
401 [99693] = true, | |
402 [99692] = true, | |
403 [99691] = true, | |
404 [99690] = true, | |
405 [99689] = true, | |
406 [99688] = true, | |
407 [99687] = true, | |
408 [99686] = true, | |
409 [99685] = true, | |
410 [99684] = true, | |
411 [99683] = true, | |
412 [99682] = true, | |
413 [99681] = true, | |
414 [99680] = true, | |
415 [99679] = true, | |
416 [99678] = true, | |
417 [99677] = true, | |
418 [99676] = true, | |
419 [99675] = true, | |
420 [99674] = true, | |
421 [99673] = true, | |
422 [99672] = true, | |
423 [99671] = true, | |
424 [99670] = true, | |
425 [99669] = true, | |
426 [99668] = true, | |
427 [99667] = true, | |
428 [96701] = true, | |
429 [96700] = true, | |
430 [96699] = true, | |
431 [96633] = true, | |
432 [96632] = true, | |
433 [96631] = true, | |
434 [96625] = true, | |
435 [96624] = true, | |
436 [96623] = true, | |
437 [96601] = true, | |
438 [96600] = true, | |
439 [96599] = true, | |
440 [96568] = true, | |
441 [96567] = true, | |
442 [96566] = true, | |
443 [95957] = true, | |
444 [95956] = true, | |
445 [95955] = true, | |
446 [95889] = true, | |
447 [95888] = true, | |
448 [95887] = true, | |
449 [95881] = true, | |
450 [95880] = true, | |
451 [95879] = true, | |
452 [95857] = true, | |
453 [95856] = true, | |
454 [95855] = true, | |
455 [95824] = true, | |
456 [95823] = true, | |
457 [95822] = true, | |
458 [95583] = true, | |
459 [95582] = true, | |
460 [95581] = true, | |
461 [95580] = true, | |
462 [95579] = true, | |
463 [95578] = true, | |
464 [95577] = true, | |
465 [95576] = true, | |
466 [95575] = true, | |
467 [95574] = true, | |
468 [95573] = true, | |
469 [95572] = true, | |
470 [95571] = true, | |
471 [95570] = true, | |
472 [95569] = true, | |
473 [89278] = true, | |
474 [89277] = true, | |
475 [89276] = true, | |
476 [89275] = true, | |
477 [89274] = true, | |
478 [89273] = true, | |
479 [89272] = true, | |
480 [89271] = true, | |
481 [89270] = true, | |
482 [89269] = true, | |
483 [89268] = true, | |
484 [89267] = true, | |
485 [89266] = true, | |
486 [89265] = true, | |
487 [89264] = true, | |
488 [89263] = true, | |
489 [89262] = true, | |
490 [89261] = true, | |
491 [89260] = true, | |
492 [89259] = true, | |
493 [89258] = true, | |
494 [89257] = true, | |
495 [89256] = true, | |
496 [89255] = true, | |
497 [89254] = true, | |
498 [89253] = true, | |
499 [89252] = true, | |
500 [89251] = true, | |
501 [89250] = true, | |
502 [89249] = true, | |
503 [89248] = true, | |
504 [89247] = true, | |
505 [89246] = true, | |
506 [89245] = true, | |
507 [89244] = true, | |
508 [89243] = true, | |
509 [89242] = true, | |
510 [89241] = true, | |
511 [89240] = true, | |
512 [89239] = true, | |
513 [89238] = true, | |
514 [89237] = true, | |
515 [89236] = true, | |
516 [89235] = true, | |
517 [89234] = true, | |
518 [78876] = true, | |
519 [78875] = true, | |
520 [78874] = true, | |
521 [78873] = true, | |
522 [78872] = true, | |
523 [78871] = true, | |
524 [78867] = true, | |
525 [78866] = true, | |
526 [78865] = true, | |
527 [78864] = true, | |
528 [78863] = true, | |
529 [78862] = true, | |
530 [78861] = true, | |
531 [78860] = true, | |
532 [78859] = true, | |
533 [78858] = true, | |
534 [78857] = true, | |
535 [78856] = true, | |
536 [78855] = true, | |
537 [78854] = true, | |
538 [78853] = true, | |
539 [78849] = true, | |
540 [78848] = true, | |
541 [78847] = true, | |
542 [78184] = true, | |
543 [78183] = true, | |
544 [78181] = true, | |
545 [78180] = true, | |
546 [78179] = true, | |
547 [78178] = true, | |
548 [78176] = true, | |
549 [78175] = true, | |
550 [78174] = true, | |
551 [78173] = true, | |
552 [78171] = true, | |
553 [78170] = true, | |
554 [71687] = true, | |
555 [71686] = true, | |
556 [71685] = true, | |
557 [71683] = true, | |
558 [71682] = true, | |
559 [71680] = true, | |
560 [71679] = true, | |
561 [71678] = true, | |
562 [71676] = true, | |
563 [71675] = true, | |
564 [71673] = true, | |
565 [71672] = true, | |
566 [71671] = true, | |
567 [71669] = true, | |
568 [71668] = true, | |
569 [67431] = true, | |
570 [67430] = true, | |
571 [67429] = true, | |
572 [67428] = true, | |
573 [67427] = true, | |
574 [67426] = true, | |
575 [67425] = true, | |
576 [67424] = true, | |
577 [67423] = true, | |
578 [66998] = true, | |
579 [65089] = true, | |
580 [65088] = true, | |
581 [65087] = true, | |
582 [63684] = true, | |
583 [63683] = true, | |
584 [63682] = true, | |
585 [51320] = true, | |
586 [45652] = true, | |
587 [45651] = true, | |
588 [45650] = true, | |
589 [45649] = true, | |
590 [45648] = true, | |
591 [45647] = true, | |
592 [45643] = true, | |
593 [45642] = true, | |
594 [45641] = true, | |
595 [40630] = true, | |
596 [40629] = true, | |
597 [40628] = true, | |
598 [40621] = true, | |
599 [40620] = true, | |
600 [40619] = true, | |
601 [40618] = true, | |
602 [40617] = true, | |
603 [40616] = true, | |
604 [34544] = true, | |
605 [31100] = true, | |
606 [31099] = true, | |
607 [31098] = true, | |
608 [31097] = true, | |
609 [31096] = true, | |
610 [31095] = true, | |
611 [30247] = true, | |
612 [30246] = true, | |
613 [30245] = true, | |
614 [30244] = true, | |
615 [30243] = true, | |
616 [30242] = true, | |
617 [29767] = true, | |
618 [29766] = true, | |
619 [29765] = true, | |
620 [29761] = true, | |
621 [29760] = true, | |
622 [29759] = true | |
623 } | |
624 | |
625 | 169 |
626 ---------------------------------------------------------------------------------------- | 170 ---------------------------------------------------------------------------------------- |
627 -- Public Utility Methods | 171 -- Public Utility Methods |
628 ---------------------------------------------------------------------------------------- | 172 ---------------------------------------------------------------------------------------- |
629 | 173 |
630 local function readBonusIdList(parts, first, last) | 174 local function readBonusIdList(parts, first, last) |
631 local ret = {} | 175 local ret = {} |
632 for i = first, last do | 176 for i = first, last do |
633 table.insert(ret, tonumber(parts[i])) | 177 table.insert(ret, tonumber(parts[i])) |
634 end | 178 end |
635 table.sort(ret) | 179 table.sort(ret) |
636 return ret | 180 return ret |
637 end | 181 end |
638 | 182 |
639 local function setRelicId(item, index, relicBonuses) | 183 -- 1 2 3 4 5 6 7 8 9 10 11 12 |
640 local relicId = item.gemIds[index] .. "" | 184 -- itemId:ench:gem1 :gem2 :gem3 :gem4:suf:uid:lvl:spec:flags :instdiffid:numbonusIDs:bonusIDs1...n :varies:?:relic bonus ids |
641 for i = 1, #relicBonuses do | 185 --|cffe6cc80|Hitem:128866: :152046:147100:152025: : : :110:66 :16777472:9 :4 :736:1494:1490:1495:709 :1:3:3610:1472:3528:3:3562:1483:3528:3:3610:1477:3336|h[Truthguard]|h|r |
642 relicId = relicId .. "." .. relicBonuses[i] | 186 -- |
643 end | |
644 local list = item.gemItemIds or {} | |
645 list[i] = relicId | |
646 end | |
647 | |
648 --|color|Hitem:135820:enchant:gem1:gem2:gem3:gem4:suffixID:uniqueID:playerlevel:spec?:flags:11:numBonusIDs:bonusID1:bonusID2...:playerlevelwhengotitem, 296 for warrior artifact:upgrade ID?:num artifact bonuses?:artifact bonus 1:artifact bonus 2:artifact bonus 3:[item name] | |
649 -- 133004 for relic on my warrior, gem2 | |
650 -- 296::3:767:1507:1809:[item name] this is for warrior artifact with the above relic in storm slot, for parts after the bonus IDs | |
651 | |
652 --|cffa335ee|Hitem:itemID:enchant:gem1:gem2:gem3:gem4:suffixID:uniqueID:level:unknown:unknown:instanceDifficultyID:numBonusIDs:bonusID1:bonusID2...|h[item name]|h|r | |
653 | |
654 -- item link format: |cffa335ee|Hitem:itemID:enchant:gem1:gem2:gem3:gem4:suffixID:uniqueID:level:unknown:unknown:instanceDifficultyID:numBonusIDs:bonusID1:bonusID2...|h[item name]|h|r | |
655 -- get an object with all of the parts of the item link format that we care about | 187 -- get an object with all of the parts of the item link format that we care about |
656 function Amr.ParseItemLink(itemLink) | 188 function Amr.ParseItemLink(itemLink) |
657 if not itemLink then return nil end | 189 if not itemLink then return nil end |
658 | 190 |
659 local str = string.match(itemLink, "|Hitem:([\-%d:]+)|") | 191 local str = string.match(itemLink, "|Hitem:([\-%d:]+)|") |
660 if not str then return nil end | 192 if not str then return nil end |
661 | 193 |
662 local parts = { strsplit(":", str) } | 194 local parts = { strsplit(":", str) } |
663 | 195 |
664 local item = {} | 196 local item = {} |
197 item.link = itemLink | |
665 item.id = tonumber(parts[1]) or 0 | 198 item.id = tonumber(parts[1]) or 0 |
666 item.enchantId = tonumber(parts[2]) or 0 | 199 item.enchantId = tonumber(parts[2]) or 0 |
667 item.gemIds = { tonumber(parts[3]) or 0, tonumber(parts[4]) or 0, tonumber(parts[5]) or 0, tonumber(parts[6]) or 0 } | 200 item.gemIds = { tonumber(parts[3]) or 0, tonumber(parts[4]) or 0, tonumber(parts[5]) or 0, tonumber(parts[6]) or 0 } |
668 item.suffixId = math.abs(tonumber(parts[7]) or 0) -- convert suffix to positive number, that's what we use in our code | 201 item.suffixId = math.abs(tonumber(parts[7]) or 0) -- convert suffix to positive number, that's what we use in our code |
669 -- part 8 is some unique ID... we never really used it | 202 -- part 8 is some unique ID... we never really used it |
679 end | 212 end |
680 | 213 |
681 item.upgradeId = 0 | 214 item.upgradeId = 0 |
682 item.level = 0 | 215 item.level = 0 |
683 | 216 |
684 -- the next part after bonus IDs depends on the upgrade id type; is either the "drop level" or upgrade ID, or not sure for artifacts | 217 -- the next part after bonus IDs depends on the upgrade id type |
685 if upgradeIdType == 4 then | 218 if upgradeIdType == 4 then |
686 item.upgradeId = tonumber(parts[14 + offset]) or 0 | 219 item.upgradeId = tonumber(parts[14 + offset]) or 0 |
687 elseif upgradeIdType == 512 then | 220 elseif upgradeIdType == 512 then |
688 item.level = tonumber(parts[14 + offset]) or 0 | 221 item.level = tonumber(parts[14 + offset]) or 0 |
689 end | 222 elseif #parts > 16 + offset then |
690 | 223 -- check for relic info |
691 -- ignore relic stuff in the item link for now, we read the relic information directly and save it with artifact power info | 224 item.relicBonusIds = { nil, nil, nil } |
692 --[[ | 225 numBonuses = tonumber(parts[16 + offset]) |
693 -- the next part is the number of bonus IDs on the first relic slot of the artifact | 226 if numBonuses then |
694 numBonuses = tonumber(parts[15 + offset]) or 0 | 227 if numBonuses > 0 then |
695 if numBonuses > 0 then | 228 item.relicBonusIds[1] = readBonusIdList(parts, 17 + offset, 16 + offset + numBonuses) |
696 local relicBonuses = readBonusIdList(16 + offset, 15 + offset + numBonuses, parts) | 229 end |
697 setRelicId(item, 1, relicBonuses) | 230 |
698 end | 231 offset= offset + numBonuses |
699 | 232 if #parts > 17 + offset then |
700 -- second relic slot bonus IDs | 233 numBonuses = tonumber(parts[17 + offset]) |
701 offset = offset + numBonuses | 234 if numBonuses > 0 then |
702 numBonuses = tonumber(parts[16 + offset]) or 0 | 235 item.relicBonusIds[2] = readBonusIdList(parts, 18 + offset, 17 + offset + numBonuses) |
703 if numBonuses > 0 then | 236 end |
704 local relicBonuses = readBonusIdList(17 + offset, 16 + offset + numBonuses, parts) | 237 |
705 setRelicId(item, 2, relicBonuses) | 238 offset= offset + numBonuses |
706 end | 239 if #parts > 18 + offset then |
707 | 240 numBonuses = tonumber(parts[18 + offset]) |
708 -- third relic slot bonus IDs | 241 if numBonuses > 0 then |
709 offset = offset + numBonuses | 242 item.relicBonusIds[3] = readBonusIdList(parts, 19 + offset, 18 + offset + numBonuses) |
710 numBonuses = tonumber(parts[17 + offset]) or 0 | 243 end |
711 if numBonuses > 0 then | 244 end |
712 local relicBonuses = readBonusIdList(18 + offset, 17 + offset + numBonuses, parts) | 245 end |
713 setRelicId(item, 3, relicBonuses) | 246 end |
714 end | 247 end |
715 ]] | |
716 | 248 |
717 return item | 249 return item |
718 end | 250 end |
719 | 251 |
720 function Amr.GetItemUniqueId(item, noUpgrade) | 252 function Amr.GetItemUniqueId(item, noUpgrade) |
799 tt:SetHyperlink(link) | 331 tt:SetHyperlink(link) |
800 end | 332 end |
801 return tt | 333 return tt |
802 end | 334 end |
803 | 335 |
804 function Amr.GetItemLevel(bagId, slotId, link) | 336 function Amr.GetItemLevel(bagId, slotId, link) |
805 local itemLevelPattern = _G["ITEM_LEVEL"]:gsub("%%d", "(%%d+)") | 337 local itemLevelPattern = _G["ITEM_LEVEL"]:gsub("%%d", "(%%d+)") |
806 local tt = Amr.GetItemTooltip(bagId, slotId, link) | 338 local tt = Amr.GetItemTooltip(bagId, slotId, link) |
807 | 339 |
808 local regions = { tt:GetRegions() } | 340 local regions = { tt:GetRegions() } |
809 for i, region in ipairs(regions) do | 341 for i, region in ipairs(regions) do |
834 ret.Professions[Amr.ProfessionSkillLineToName[skillLine]] = skillLevel; | 366 ret.Professions[Amr.ProfessionSkillLineToName[skillLine]] = skillLevel; |
835 end | 367 end |
836 end | 368 end |
837 end | 369 end |
838 | 370 |
839 --[[ | 371 -- get specs |
840 local function getTalents(specPos) | |
841 local talentInfo = {} | |
842 local maxTiers = 7 | |
843 for tier = 1, maxTiers do | |
844 for col = 1, 3 do | |
845 local id, name, _, _, _, spellId, _, t, c, selected = GetTalentInfoBySpecialization(specPos, tier, col) | |
846 if selected then | |
847 talentInfo[tier] = col | |
848 end | |
849 end | |
850 end | |
851 | |
852 local str = "" | |
853 for i = 1, maxTiers do | |
854 if talentInfo[i] then | |
855 str = str .. talentInfo[i] | |
856 else | |
857 str = str .. '0' | |
858 end | |
859 end | |
860 | |
861 return str | |
862 end | |
863 ]] | |
864 | |
865 --[[ | |
866 local function getGlyphs(specGroup) | |
867 local glyphs = {} | |
868 for i = 1, NUM_GLYPH_SLOTS do | |
869 local _, _, _, glyphSpellID, _, glyphID = GetGlyphSocketInfo(i, specGroup) | |
870 if (glyphID) then | |
871 table.insert(glyphs, glyphSpellID) | |
872 end | |
873 end | |
874 return glyphs; | |
875 end | |
876 ]] | |
877 | |
878 -- get specs and talents | |
879 local function readSpecs(ret) | 372 local function readSpecs(ret) |
880 | 373 |
881 for pos = 1, 4 do | 374 for pos = 1, 4 do |
882 -- spec, convert game spec id to one of our spec ids | 375 -- spec, convert game spec id to one of our spec ids |
883 local specId = GetSpecializationInfo(pos) | 376 local specId = GetSpecializationInfo(pos) |
884 if specId then | 377 if specId then |
885 ret.Specs[pos] = Amr.SpecIds[specId] | 378 ret.Specs[pos] = Amr.SpecIds[specId] |
886 -- TODO: figure out how to read inactive spec talents if possible... used to be able to but they changed it | |
887 --ret.Talents[pos] = getTalents(pos) | |
888 end | 379 end |
380 end | |
381 end | |
382 | |
383 local function dump(o) | |
384 if type(o) == 'table' then | |
385 local s = '{ ' | |
386 for k,v in pairs(o) do | |
387 if type(k) ~= 'number' then k = '"'..k..'"' end | |
388 s = s .. '['..k..'] = ' .. dump(v) .. ',' | |
389 end | |
390 return s .. '} ' | |
391 else | |
392 return tostring(o) | |
393 end | |
394 end | |
395 | |
396 -- read azerite powers on the item in loc and put it on itemData | |
397 function Amr.ReadAzeritePowers(loc) | |
398 local ret = {} | |
399 local hasSome = false | |
400 | |
401 local tiers = C_AzeriteEmpoweredItem.GetAllTierInfo(loc) | |
402 for tier, tierInfo in ipairs(tiers) do | |
403 for _, power in ipairs(tierInfo.azeritePowerIDs) do | |
404 if C_AzeriteEmpoweredItem.IsPowerSelected(loc, power) then | |
405 local powerInfo = C_AzeriteEmpoweredItem.GetPowerInfo(power) | |
406 table.insert(ret, powerInfo.spellID) | |
407 hasSome = true | |
408 end | |
409 end | |
410 end | |
411 | |
412 if hasSome then | |
413 return ret | |
414 else | |
415 return nil | |
889 end | 416 end |
890 end | 417 end |
891 | 418 |
892 -- get currently equipped items, store with currently active spec | 419 -- get currently equipped items, store with currently active spec |
893 local function readEquippedItems(ret) | 420 local function readEquippedItems(ret) |
894 local equippedItems = {}; | 421 local equippedItems = {}; |
422 local loc = ItemLocation.CreateEmpty() | |
895 for slotNum = 1, #Amr.SlotIds do | 423 for slotNum = 1, #Amr.SlotIds do |
896 local slotId = Amr.SlotIds[slotNum] | 424 local slotId = Amr.SlotIds[slotNum] |
897 local itemLink = GetInventoryItemLink("player", slotId) | 425 local itemLink = GetInventoryItemLink("player", slotId) |
898 if itemLink then | 426 if itemLink then |
899 equippedItems[slotId] = itemLink | 427 local itemData = Amr.ParseItemLink(itemLink) |
428 if itemData then | |
429 -- see if this is an azerite item and read azerite power ids | |
430 loc:SetEquipmentSlot(slotId) | |
431 if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then | |
432 local powers = Amr.ReadAzeritePowers(loc) | |
433 if powers then | |
434 itemData.azerite = powers | |
435 end | |
436 end | |
437 | |
438 equippedItems[slotId] = itemData | |
439 end | |
900 end | 440 end |
901 end | 441 end |
902 | 442 |
903 -- store last-seen equipped gear for each spec | 443 -- store last-seen equipped gear for each spec |
904 ret.Equipped[GetSpecialization()] = equippedItems | 444 ret.Equipped[GetSpecialization()] = equippedItems |
445 end | |
446 | |
447 local function readHeartOfAzerothLevel(ret) | |
448 local azeriteItemLocation = C_AzeriteItem.FindActiveAzeriteItem(); | |
449 if azeriteItemLocation then | |
450 local azeriteItem = Item:CreateFromItemLocation(azeriteItemLocation); | |
451 ret.HeartOfAzerothLevel = C_AzeriteItem.GetPowerLevel(azeriteItemLocation) | |
452 else | |
453 ret.HeartOfAzerothLevel = 0 | |
454 end | |
455 end | |
456 | |
457 -- Get just the player's currently equipped gear | |
458 function Amr:GetEquipped() | |
459 local ret= {} | |
460 ret.Equipped = {} | |
461 readEquippedItems(ret) | |
462 return ret | |
905 end | 463 end |
906 | 464 |
907 -- Get all data about the player as an object, includes: | 465 -- Get all data about the player as an object, includes: |
908 -- serializer version | 466 -- serializer version |
909 -- region/realm/name | 467 -- region/realm/name |
911 -- race | 469 -- race |
912 -- faction | 470 -- faction |
913 -- level | 471 -- level |
914 -- professions | 472 -- professions |
915 -- spec/talent for all specs | 473 -- spec/talent for all specs |
916 -- artifact for current spec | |
917 -- equipped gear for the current spec | 474 -- equipped gear for the current spec |
918 -- | 475 -- |
919 function Amr:GetPlayerData() | 476 function Amr:GetPlayerData() |
920 | 477 |
921 local ret = {} | 478 local ret = {} |
924 ret.Realm = GetRealmName() | 481 ret.Realm = GetRealmName() |
925 ret.Name = UnitName("player") | 482 ret.Name = UnitName("player") |
926 ret.Guild = GetGuildInfo("player") | 483 ret.Guild = GetGuildInfo("player") |
927 ret.ActiveSpec = GetSpecialization() | 484 ret.ActiveSpec = GetSpecialization() |
928 ret.Level = UnitLevel("player"); | 485 ret.Level = UnitLevel("player"); |
929 | 486 readHeartOfAzerothLevel(ret) |
487 | |
930 local cls, clsEn = UnitClass("player") | 488 local cls, clsEn = UnitClass("player") |
931 ret.Class = clsEn; | 489 ret.Class = clsEn; |
932 | 490 |
933 local race, raceEn = UnitRace("player") | 491 local race, raceEn = UnitRace("player") |
934 ret.Race = raceEn; | 492 ret.Race = raceEn; |
945 | 503 |
946 ret.Specs = {} | 504 ret.Specs = {} |
947 ret.Talents = {} | 505 ret.Talents = {} |
948 readSpecs(ret) | 506 readSpecs(ret) |
949 | 507 |
950 ret.Artifacts = {} | 508 ret.Equipped = {} |
951 | |
952 ret.Equipped = {} | |
953 readEquippedItems(ret) | 509 readEquippedItems(ret) |
954 | 510 |
955 return ret | 511 return ret |
956 end | 512 end |
957 | 513 |
995 local prevGemId = 0 | 551 local prevGemId = 0 |
996 local prevEnchantId = 0 | 552 local prevEnchantId = 0 |
997 local prevUpgradeId = 0 | 553 local prevUpgradeId = 0 |
998 local prevBonusId = 0 | 554 local prevBonusId = 0 |
999 local prevLevel = 0 | 555 local prevLevel = 0 |
556 local prevAzeriteId = 0 | |
557 local prevRelicBonusId = 0 | |
1000 for i, itemData in ipairs(itemObjects) do | 558 for i, itemData in ipairs(itemObjects) do |
1001 local itemParts = {} | 559 local itemParts = {} |
1002 | 560 |
1003 -- for now export the item level of artifacts as the "drop level" because it is a pain in the ass to figure it out from the bonus IDs | |
1004 --local _, _, quality = GetItemInfo(itemData.link) | |
1005 --if quality == 6 then | |
1006 -- itemData.level = Amr.GetItemLevel(nil, nil, itemData.link) | |
1007 --end | |
1008 | |
1009 table.insert(itemParts, itemData.id - prevItemId) | 561 table.insert(itemParts, itemData.id - prevItemId) |
1010 prevItemId = itemData.id | 562 prevItemId = itemData.id |
1011 | 563 |
1012 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end | 564 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end |
1013 if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end | 565 --if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end |
1014 if itemData.upgradeId ~= 0 then | 566 if itemData.upgradeId ~= 0 then |
1015 table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId)) | 567 table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId)) |
1016 prevUpgradeId = itemData.upgradeId | 568 prevUpgradeId = itemData.upgradeId |
1017 end | 569 end |
1018 if itemData.level ~= 0 then | 570 if itemData.level ~= 0 then |
1022 if itemData.bonusIds then | 574 if itemData.bonusIds then |
1023 for bIndex, bValue in ipairs(itemData.bonusIds) do | 575 for bIndex, bValue in ipairs(itemData.bonusIds) do |
1024 table.insert(itemParts, "b" .. (bValue - prevBonusId)) | 576 table.insert(itemParts, "b" .. (bValue - prevBonusId)) |
1025 prevBonusId = bValue | 577 prevBonusId = bValue |
1026 end | 578 end |
1027 end | 579 end |
580 | |
581 if itemData.azerite then | |
582 for aIndex, aValue in ipairs(itemData.azerite) do | |
583 table.insert(itemParts, "a" .. (aValue - prevAzeriteId)) | |
584 prevAzeriteId = aValue | |
585 end | |
586 end | |
1028 | 587 |
1029 if itemData.gemIds[1] ~= 0 then | 588 if itemData.gemIds[1] ~= 0 then |
1030 table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId)) | 589 table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId)) |
1031 prevGemId = itemData.gemIds[1] | 590 prevGemId = itemData.gemIds[1] |
1032 end | 591 end |
1035 prevGemId = itemData.gemIds[2] | 594 prevGemId = itemData.gemIds[2] |
1036 end | 595 end |
1037 if itemData.gemIds[3] ~= 0 then | 596 if itemData.gemIds[3] ~= 0 then |
1038 table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId)) | 597 table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId)) |
1039 prevGemId = itemData.gemIds[3] | 598 prevGemId = itemData.gemIds[3] |
1040 end | 599 end |
1041 | 600 |
1042 if itemData.enchantId ~= 0 then | 601 if itemData.enchantId ~= 0 then |
1043 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId)) | 602 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId)) |
1044 prevEnchantId = itemData.enchantId | 603 prevEnchantId = itemData.enchantId |
1045 end | 604 end |
1046 | 605 |
606 if itemData.relicBonusIds and itemData.relicBonusIds[1] ~= nil then | |
607 for bIndex, bValue in ipairs(itemData.relicBonusIds[1]) do | |
608 table.insert(itemParts, "p" .. (bValue - prevRelicBonusId)) | |
609 prevRelicBonusId = bValue | |
610 end | |
611 end | |
612 | |
613 if itemData.relicBonusIds and itemData.relicBonusIds[2] ~= nil then | |
614 for bIndex, bValue in ipairs(itemData.relicBonusIds[2]) do | |
615 table.insert(itemParts, "q" .. (bValue - prevRelicBonusId)) | |
616 prevRelicBonusId = bValue | |
617 end | |
618 end | |
619 | |
620 if itemData.relicBonusIds and itemData.relicBonusIds[3] ~= nil then | |
621 for bIndex, bValue in ipairs(itemData.relicBonusIds[3]) do | |
622 table.insert(itemParts, "r" .. (bValue - prevRelicBonusId)) | |
623 prevRelicBonusId = bValue | |
624 end | |
625 end | |
626 | |
1047 table.insert(fields, table.concat(itemParts, "")) | 627 table.insert(fields, table.concat(itemParts, "")) |
1048 end | 628 end |
1049 end | |
1050 | |
1051 local function serializeCrucibleInfo(fields, info, pos, prevPowerId) | |
1052 | |
1053 if not info.Powers or not info.Active then | |
1054 return prevPowerId | |
1055 end | |
1056 | |
1057 local parts = {} | |
1058 | |
1059 if pos < 4 then | |
1060 table.insert(parts, pos) | |
1061 else | |
1062 local relic = Amr.ParseItemLink(info.ItemLink) | |
1063 table.insert(parts, Amr.GetItemUniqueId(relic) or "0") | |
1064 end | |
1065 | |
1066 for i,powerId in ipairs(info.Powers) do | |
1067 table.insert(parts, (powerId - prevPowerId) .. "") | |
1068 prevPowerId = powerId | |
1069 end | |
1070 | |
1071 for i,active in ipairs(info.Active) do | |
1072 table.insert(parts, active and "1" or "0") | |
1073 end | |
1074 | |
1075 table.insert(fields, table.concat(parts, ",")) | |
1076 | |
1077 return prevPowerId | |
1078 end | 629 end |
1079 | 630 |
1080 -- Serialize just the identity portion of a player (region/realm/name) in the same format used by the full serialization | 631 -- Serialize just the identity portion of a player (region/realm/name) in the same format used by the full serialization |
1081 function Amr:SerializePlayerIdentity(data) | 632 function Amr:SerializePlayerIdentity(data) |
1082 local fields = {} | 633 local fields = {} |
1119 -- faction, default to alliance if we can't read it for some reason | 670 -- faction, default to alliance if we can't read it for some reason |
1120 raceval = Amr.FactionIds[data.Faction] | 671 raceval = Amr.FactionIds[data.Faction] |
1121 if raceval == nil then raceval = 1 end | 672 if raceval == nil then raceval = 1 end |
1122 table.insert(fields, raceval) | 673 table.insert(fields, raceval) |
1123 | 674 |
1124 table.insert(fields, data.Level) | 675 table.insert(fields, data.Level) |
676 table.insert(fields, data.HeartOfAzerothLevel) | |
1125 | 677 |
1126 local profs = {} | 678 local profs = {} |
1127 local noprofs = true | 679 local noprofs = true |
1128 if data.Professions then | 680 if data.Professions then |
1129 for k, v in pairs(data.Professions) do | 681 for k, v in pairs(data.Professions) do |
1145 table.insert(fields, data.ActiveSpec) | 697 table.insert(fields, data.ActiveSpec) |
1146 for spec = 1, 4 do | 698 for spec = 1, 4 do |
1147 if data.Specs[spec] and (complete or spec == data.ActiveSpec) then | 699 if data.Specs[spec] and (complete or spec == data.ActiveSpec) then |
1148 table.insert(fields, ".s" .. spec) -- indicates the start of a spec block | 700 table.insert(fields, ".s" .. spec) -- indicates the start of a spec block |
1149 table.insert(fields, data.Specs[spec]) | 701 table.insert(fields, data.Specs[spec]) |
1150 table.insert(fields, data.Talents[spec] or "") | 702 table.insert(fields, data.Talents[spec] or "") |
1151 | |
1152 local powerids = {} | |
1153 local powerranks = {} | |
1154 local reliclinks = {} | |
1155 local crucibleinfos = {} | |
1156 | |
1157 local artifactInfo = data.Artifacts and data.Artifacts[spec] | |
1158 if artifactInfo and artifactInfo.Powers then | |
1159 for k, v in spairs(artifactInfo.Powers) do | |
1160 table.insert(powerids, k) | |
1161 table.insert(powerranks, v) | |
1162 end | |
1163 end | |
1164 if artifactInfo and artifactInfo.Relics then | |
1165 for i, link in ipairs(artifactInfo.Relics) do | |
1166 local relic = Amr.ParseItemLink(link) | |
1167 table.insert(reliclinks, Amr.GetItemUniqueId(relic) or "") | |
1168 end | |
1169 end | |
1170 if artifactInfo and artifactInfo.Crucible then | |
1171 local prevPowerId = 0 | |
1172 for i = 1,3 do | |
1173 local relicInfo = #artifactInfo.Crucible.Equipped >= i and artifactInfo.Crucible.Equipped[i] | |
1174 if relicInfo then | |
1175 prevPowerId = serializeCrucibleInfo(crucibleinfos, relicInfo, i, prevPowerId) | |
1176 end | |
1177 end | |
1178 if artifactInfo.Crucible.Previewed then | |
1179 for k,relicInfo in pairs(artifactInfo.Crucible.Previewed) do | |
1180 if relicInfo then | |
1181 prevPowerId = serializeCrucibleInfo(crucibleinfos, relicInfo, 4, prevPowerId) | |
1182 end | |
1183 end | |
1184 end | |
1185 end | |
1186 | |
1187 table.insert(fields, toCompressedNumberList(powerids)) | |
1188 table.insert(fields, table.concat(powerranks, ",")) | |
1189 table.insert(fields, table.concat(reliclinks, ",")) | |
1190 table.insert(fields, table.concat(crucibleinfos, "/")) | |
1191 | |
1192 --table.insert(fields, toCompressedNumberList(data.Glyphs[spec])) | |
1193 end | 703 end |
1194 end | 704 end |
1195 | 705 |
1196 -- export equipped gear | 706 -- export equipped gear |
1197 if data.Equipped then | 707 if data.Equipped then |
1198 for spec = 1, 4 do | 708 for spec = 1, 4 do |
1199 if data.Equipped[spec] and (complete or spec == data.ActiveSpec) then | 709 if data.Equipped[spec] and (complete or spec == data.ActiveSpec) then |
1200 table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block | 710 table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block |
1201 | 711 |
1202 local itemObjects = {} | 712 local itemObjects = {} |
1203 for k, v in pairs(data.Equipped[spec]) do | 713 for k, itemData in pairs(data.Equipped[spec]) do |
1204 local itemData = Amr.ParseItemLink(v) | |
1205 itemData.slot = k | 714 itemData.slot = k |
1206 itemData.link = v | |
1207 table.insert(itemObjects, itemData) | 715 table.insert(itemObjects, itemData) |
1208 end | 716 end |
1209 | 717 |
1210 appendItemsToExport(fields, itemObjects) | 718 appendItemsToExport(fields, itemObjects) |
1211 end | 719 end |
1212 end | 720 end |
1213 end | 721 end |
1214 | 722 |
1215 -- if doing a complete export, include reputations and bank/bag items too | 723 -- if doing a complete export, include bank/bag items too |
1216 if complete then | 724 if complete then |
1217 | 725 |
1218 -- export reputations | |
1219 local reps = {} | |
1220 table.insert(reps, "_") | |
1221 --[[ | |
1222 local noreps = true | |
1223 if data.Reputations then | |
1224 for k, v in pairs(data.Reputations) do | |
1225 noreps = false | |
1226 table.insert(reps, k .. ":" .. v) | |
1227 end | |
1228 end | |
1229 if noreps then | |
1230 table.insert(reps, "_") | |
1231 end | |
1232 ]] | |
1233 | |
1234 table.insert(fields, ".r") | |
1235 table.insert(fields, table.concat(reps, ",")) | |
1236 | |
1237 -- export bag and bank | |
1238 local itemObjects = {} | 726 local itemObjects = {} |
1239 if data.BagItems then | 727 if data.BagItems then |
1240 for i, v in ipairs(data.BagItems) do | 728 for i, itemData in ipairs(data.BagItems) do |
1241 local itemData = Amr.ParseItemLink(v) | 729 if itemData then |
1242 if itemData ~= nil --[[and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id])]] then | |
1243 itemData.link = v | |
1244 table.insert(itemObjects, itemData) | 730 table.insert(itemObjects, itemData) |
1245 end | 731 end |
1246 end | 732 end |
1247 end | 733 end |
1248 if data.BankItems then | 734 if data.BankItems then |
1249 for i, v in ipairs(data.BankItems) do | 735 for i, itemData in ipairs(data.BankItems) do |
1250 local itemData = Amr.ParseItemLink(v) | 736 if itemData then |
1251 if itemData ~= nil --[[and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id])]] then | |
1252 itemData.link = v | |
1253 table.insert(itemObjects, itemData) | 737 table.insert(itemObjects, itemData) |
1254 end | 738 end |
1255 end | 739 end |
1256 end | 740 end |
1257 if data.VoidItems then | 741 |
1258 for i, v in ipairs(data.VoidItems) do | |
1259 local itemData = Amr.ParseItemLink(v) | |
1260 if itemData ~= nil --[[and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id])]] then | |
1261 itemData.link = v | |
1262 table.insert(itemObjects, itemData) | |
1263 end | |
1264 end | |
1265 end | |
1266 | |
1267 table.insert(fields, ".inv") | 742 table.insert(fields, ".inv") |
1268 appendItemsToExport(fields, itemObjects) | 743 appendItemsToExport(fields, itemObjects) |
1269 end | 744 end |
1270 | 745 |
1271 return "$" .. table.concat(fields, ";") .. "$" | 746 return "$" .. table.concat(fields, ";") .. "$" |