annotate AskMrRobot-Serializer/AskMrRobot-Serializer.lua @ 89:6bbe64d587b4 v42

Improved artifact/relic reading, gear display. Now creates equipment manager sets when you use button or command to equip a set.
author yellowfive
date Sun, 18 Sep 2016 21:24:08 -0700
parents fe0bc2f32851
children b8e9664d3229
rev   line source
yellowfive@57 1 -- AskMrRobot-Serializer will serialize and communicate character data between users.
yellowfive@57 2 -- This is used primarily to associate character information to logs uploaded to askmrrobot.com.
yellowfive@57 3
yellowfive@89 4 local MAJOR, MINOR = "AskMrRobot-Serializer", 42
yellowfive@57 5 local Amr, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
yellowfive@57 6
yellowfive@57 7 if not Amr then return end -- already loaded by something else
yellowfive@57 8
yellowfive@57 9 -- event and comm used for player snapshotting on entering combat
yellowfive@57 10 LibStub("AceEvent-3.0"):Embed(Amr)
yellowfive@57 11 LibStub("AceComm-3.0"):Embed(Amr)
yellowfive@57 12
yellowfive@57 13 ----------------------------------------------------------------------------------------
yellowfive@57 14 -- Constants
yellowfive@57 15 ----------------------------------------------------------------------------------------
yellowfive@57 16
yellowfive@57 17 -- prefix used for communicating gear snapshots created by the AMR serializer
yellowfive@57 18 Amr.ChatPrefix = "_AMRS"
yellowfive@57 19
yellowfive@57 20 -- map of region ids to AMR region names
yellowfive@57 21 Amr.RegionNames = {
yellowfive@57 22 [1] = "US",
yellowfive@57 23 [2] = "KR",
yellowfive@57 24 [3] = "EU",
yellowfive@57 25 [4] = "TW",
yellowfive@57 26 [5] = "CN"
yellowfive@57 27 }
yellowfive@57 28
yellowfive@57 29 -- map of the skillLine returned by profession API to the AMR profession name
yellowfive@57 30 Amr.ProfessionSkillLineToName = {
yellowfive@57 31 [794] = "Archaeology",
yellowfive@57 32 [171] = "Alchemy",
yellowfive@57 33 [164] = "Blacksmithing",
yellowfive@57 34 [185] = "Cooking",
yellowfive@57 35 [333] = "Enchanting",
yellowfive@57 36 [202] = "Engineering",
yellowfive@57 37 [129] = "First Aid",
yellowfive@57 38 [356] = "Fishing",
yellowfive@57 39 [182] = "Herbalism",
yellowfive@57 40 [773] = "Inscription",
yellowfive@57 41 [755] = "Jewelcrafting",
yellowfive@57 42 [165] = "Leatherworking",
yellowfive@57 43 [186] = "Mining",
yellowfive@57 44 [393] = "Skinning",
yellowfive@57 45 [197] = "Tailoring"
yellowfive@57 46 }
yellowfive@57 47
yellowfive@57 48 -- all slot IDs that we care about, ordered in AMR standard display order
yellowfive@57 49 Amr.SlotIds = { 16, 17, 1, 2, 3, 15, 5, 9, 10, 6, 7, 8, 11, 12, 13, 14 }
yellowfive@57 50
yellowfive@57 51 Amr.SpecIds = {
yellowfive@57 52 [250] = 1, -- DeathKnightBlood
yellowfive@57 53 [251] = 2, -- DeathKnightFrost
yellowfive@57 54 [252] = 3, -- DeathKnightUnholy
yellowfive@81 55 [577] = 4, -- DemonHunterHavoc
yellowfive@81 56 [581] = 5, -- DemonHunterVengeance
yellowfive@81 57 [102] = 6, -- DruidBalance
yellowfive@81 58 [103] = 7, -- DruidFeral
yellowfive@81 59 [104] = 8, -- DruidGuardian
yellowfive@81 60 [105] = 9, -- DruidRestoration
yellowfive@81 61 [253] = 10, -- HunterBeastMastery
yellowfive@81 62 [254] = 11, -- HunterMarksmanship
yellowfive@81 63 [255] = 12, -- HunterSurvival
yellowfive@81 64 [62] = 13, -- MageArcane
yellowfive@81 65 [63] = 14, -- MageFire
yellowfive@81 66 [64] = 15, -- MageFrost
yellowfive@81 67 [268] = 16, -- MonkBrewmaster
yellowfive@81 68 [270] = 17, -- MonkMistweaver
yellowfive@81 69 [269] = 18, -- MonkWindwalker
yellowfive@81 70 [65] = 19, -- PaladinHoly
yellowfive@81 71 [66] = 20, -- PaladinProtection
yellowfive@81 72 [70] = 21, -- PaladinRetribution
yellowfive@81 73 [256] = 22, -- PriestDiscipline
yellowfive@81 74 [257] = 23, -- PriestHoly
yellowfive@81 75 [258] = 24, -- PriestShadow
yellowfive@81 76 [259] = 25, -- RogueAssassination
yellowfive@81 77 [260] = 26, -- RogueOutlaw
yellowfive@81 78 [261] = 27, -- RogueSubtlety
yellowfive@81 79 [262] = 28, -- ShamanElemental
yellowfive@81 80 [263] = 29, -- ShamanEnhancement
yellowfive@81 81 [264] = 30, -- ShamanRestoration
yellowfive@81 82 [265] = 31, -- WarlockAffliction
yellowfive@81 83 [266] = 32, -- WarlockDemonology
yellowfive@81 84 [267] = 33, -- WarlockDestruction
yellowfive@81 85 [71] = 34, -- WarriorArms
yellowfive@81 86 [72] = 35, -- WarriorFury
yellowfive@81 87 [73] = 36 -- WarriorProtection
yellowfive@57 88 }
yellowfive@57 89
yellowfive@57 90 Amr.ClassIds = {
yellowfive@57 91 ["NONE"] = 0,
yellowfive@57 92 ["DEATHKNIGHT"] = 1,
yellowfive@81 93 ["DEMONHUNTER"] = 2,
yellowfive@81 94 ["DRUID"] = 3,
yellowfive@81 95 ["HUNTER"] = 4,
yellowfive@81 96 ["MAGE"] = 5,
yellowfive@81 97 ["MONK"] = 6,
yellowfive@81 98 ["PALADIN"] = 7,
yellowfive@81 99 ["PRIEST"] = 8,
yellowfive@81 100 ["ROGUE"] = 9,
yellowfive@81 101 ["SHAMAN"] = 10,
yellowfive@81 102 ["WARLOCK"] = 11,
yellowfive@81 103 ["WARRIOR"] = 12,
yellowfive@57 104 }
yellowfive@57 105
yellowfive@57 106 Amr.ProfessionIds = {
yellowfive@57 107 ["None"] = 0,
yellowfive@57 108 ["Mining"] = 1,
yellowfive@57 109 ["Skinning"] = 2,
yellowfive@57 110 ["Herbalism"] = 3,
yellowfive@57 111 ["Enchanting"] = 4,
yellowfive@57 112 ["Jewelcrafting"] = 5,
yellowfive@57 113 ["Engineering"] = 6,
yellowfive@57 114 ["Blacksmithing"] = 7,
yellowfive@57 115 ["Leatherworking"] = 8,
yellowfive@57 116 ["Inscription"] = 9,
yellowfive@57 117 ["Tailoring"] = 10,
yellowfive@57 118 ["Alchemy"] = 11,
yellowfive@57 119 ["Fishing"] = 12,
yellowfive@57 120 ["Cooking"] = 13,
yellowfive@57 121 ["First Aid"] = 14,
yellowfive@57 122 ["Archaeology"] = 15
yellowfive@57 123 }
yellowfive@57 124
yellowfive@57 125 Amr.RaceIds = {
yellowfive@57 126 ["None"] = 0,
yellowfive@57 127 ["BloodElf"] = 1,
yellowfive@57 128 ["Draenei"] = 2,
yellowfive@57 129 ["Dwarf"] = 3,
yellowfive@57 130 ["Gnome"] = 4,
yellowfive@57 131 ["Human"] = 5,
yellowfive@57 132 ["NightElf"] = 6,
yellowfive@57 133 ["Orc"] = 7,
yellowfive@57 134 ["Tauren"] = 8,
yellowfive@57 135 ["Troll"] = 9,
yellowfive@57 136 ["Scourge"] = 10,
yellowfive@57 137 ["Undead"] = 10,
yellowfive@57 138 ["Goblin"] = 11,
yellowfive@57 139 ["Worgen"] = 12,
yellowfive@57 140 ["Pandaren"] = 13
yellowfive@57 141 }
yellowfive@57 142
yellowfive@57 143 Amr.FactionIds = {
yellowfive@57 144 ["None"] = 0,
yellowfive@57 145 ["Alliance"] = 1,
yellowfive@57 146 ["Horde"] = 2
yellowfive@57 147 }
yellowfive@57 148
yellowfive@57 149 Amr.InstanceIds = {
yellowfive@57 150 Auchindoun = 1182,
yellowfive@57 151 BloodmaulSlagMines = 1175,
yellowfive@57 152 GrimrailDepot = 1208,
yellowfive@57 153 IronDocks = 1195,
yellowfive@57 154 ShadowmoonBurialGrounds = 1176,
yellowfive@57 155 Skyreach = 1209,
yellowfive@57 156 TheEverbloom = 1279,
yellowfive@57 157 UpperBlackrockSpire = 1358,
yellowfive@57 158 Highmaul = 1228,
yellowfive@61 159 BlackrockFoundry = 1205,
yellowfive@61 160 HellfireCitadel = 1448
yellowfive@57 161 }
yellowfive@57 162
yellowfive@57 163 -- instances that AskMrRobot currently supports logging for
yellowfive@57 164 Amr.SupportedInstanceIds = {
yellowfive@57 165 --[1182] = true,
yellowfive@57 166 --[1175] = true,
yellowfive@57 167 --[1208] = true,
yellowfive@57 168 --[1195] = true,
yellowfive@57 169 --[1176] = true,
yellowfive@57 170 --[1209] = true,
yellowfive@57 171 --[1279] = true,
yellowfive@57 172 --[1358] = true,
yellowfive@57 173 [1228] = true,
yellowfive@61 174 [1205] = true,
yellowfive@61 175 [1448] = true
yellowfive@57 176 }
yellowfive@57 177
yellowfive@89 178 -- just to make life easier, maps ID of each artifact weapon to the spec number (1-4)
yellowfive@89 179 Amr.ArtifactIdToSpecNumber = {
yellowfive@89 180 [128402] = 1, -- DK
yellowfive@89 181 [128292] = 2,
yellowfive@89 182 [128403] = 3,
yellowfive@89 183 [127829] = 1, -- DH
yellowfive@89 184 [128832] = 2,
yellowfive@89 185 [128858] = 1, -- Druid
yellowfive@89 186 [128860] = 2,
yellowfive@89 187 [128821] = 3,
yellowfive@89 188 [128306] = 4,
yellowfive@89 189 [128861] = 1, -- Hunter
yellowfive@89 190 [128826] = 2,
yellowfive@89 191 [128808] = 3,
yellowfive@89 192 [127857] = 1, -- Mage
yellowfive@89 193 [128820] = 2,
yellowfive@89 194 [128862] = 3,
yellowfive@89 195 [128938] = 1, -- Monk
yellowfive@89 196 [128937] = 2,
yellowfive@89 197 [128940] = 3,
yellowfive@89 198 [128823] = 1, -- Paladin
yellowfive@89 199 [128866] = 2,
yellowfive@89 200 [120978] = 3,
yellowfive@89 201 [128868] = 1, -- Priest
yellowfive@89 202 [128825] = 2,
yellowfive@89 203 [128827] = 3,
yellowfive@89 204 [128870] = 1, -- Rogue
yellowfive@89 205 [128872] = 2,
yellowfive@89 206 [128476] = 3,
yellowfive@89 207 [128935] = 1, -- Shaman
yellowfive@89 208 [128819] = 2,
yellowfive@89 209 [128911] = 3,
yellowfive@89 210 [128942] = 1, -- Warlock
yellowfive@89 211 [128943] = 2,
yellowfive@89 212 [128941] = 3,
yellowfive@89 213 [128910] = 1, -- Warrior
yellowfive@89 214 [128908] = 2,
yellowfive@89 215 [128289] = 3,
yellowfive@89 216
yellowfive@89 217 --[128293] = 2, -- Frost OH
yellowfive@89 218 --[127830] = 1, -- Havoc OH
yellowfive@89 219 --[128831] = 2, -- Vengeance OH
yellowfive@89 220 --[128859] = 2, -- Feral OH
yellowfive@89 221 --[128822] = 3, -- Guardian OH
yellowfive@89 222 --[133959] = 2, -- Fire OH
yellowfive@89 223 --[133948] = 3, -- Windwalker OH
yellowfive@89 224 --[128867] = 2, -- Prot MH
yellowfive@89 225 --[133958] = 3, -- Shadow OH
yellowfive@89 226 --[128869] = 1, -- Rogue OH's
yellowfive@89 227 --[134552] = 2,
yellowfive@89 228 --[128479] = 3,
yellowfive@89 229 --[128936] = 1, -- Shaman OH's
yellowfive@89 230 --[128873] = 2,
yellowfive@89 231 --[128934] = 3,
yellowfive@89 232 --[137246] = 2, -- Demo MH
yellowfive@89 233 --[134553] = 2, -- Fury OH
yellowfive@89 234 --[128288] = 3 -- Prot MH
yellowfive@89 235 }
yellowfive@89 236
yellowfive@57 237 -- IDs of set tokens that we would care about in a player's inventory
yellowfive@57 238 Amr.SetTokenIds = {
yellowfive@63 239 [127970] = true,
yellowfive@63 240 [127969] = true,
yellowfive@63 241 [127968] = true,
yellowfive@63 242 [127967] = true,
yellowfive@63 243 [127966] = true,
yellowfive@63 244 [127965] = true,
yellowfive@63 245 [127964] = true,
yellowfive@63 246 [127963] = true,
yellowfive@63 247 [127962] = true,
yellowfive@63 248 [127961] = true,
yellowfive@63 249 [127960] = true,
yellowfive@63 250 [127959] = true,
yellowfive@63 251 [127958] = true,
yellowfive@63 252 [127957] = true,
yellowfive@63 253 [127956] = true,
yellowfive@63 254 [127955] = true,
yellowfive@63 255 [127954] = true,
yellowfive@63 256 [127953] = true,
yellowfive@57 257 [120285] = true,
yellowfive@57 258 [120284] = true,
yellowfive@57 259 [120283] = true,
yellowfive@57 260 [120282] = true,
yellowfive@57 261 [120281] = true,
yellowfive@57 262 [120280] = true,
yellowfive@57 263 [120279] = true,
yellowfive@57 264 [120278] = true,
yellowfive@57 265 [120277] = true,
yellowfive@57 266 [120256] = true,
yellowfive@57 267 [120255] = true,
yellowfive@57 268 [120254] = true,
yellowfive@57 269 [120253] = true,
yellowfive@57 270 [120252] = true,
yellowfive@57 271 [120251] = true,
yellowfive@57 272 [120250] = true,
yellowfive@57 273 [120249] = true,
yellowfive@57 274 [120248] = true,
yellowfive@57 275 [120247] = true,
yellowfive@57 276 [120246] = true,
yellowfive@57 277 [120245] = true,
yellowfive@57 278 [120244] = true,
yellowfive@57 279 [120243] = true,
yellowfive@57 280 [120242] = true,
yellowfive@57 281 [120241] = true,
yellowfive@57 282 [120240] = true,
yellowfive@57 283 [120239] = true,
yellowfive@57 284 [120238] = true,
yellowfive@57 285 [120237] = true,
yellowfive@57 286 [120236] = true,
yellowfive@57 287 [120235] = true,
yellowfive@57 288 [120234] = true,
yellowfive@57 289 [120233] = true,
yellowfive@57 290 [120232] = true,
yellowfive@57 291 [120231] = true,
yellowfive@57 292 [120230] = true,
yellowfive@57 293 [120229] = true,
yellowfive@57 294 [120228] = true,
yellowfive@57 295 [120227] = true,
yellowfive@57 296 [120226] = true,
yellowfive@57 297 [120225] = true,
yellowfive@57 298 [120224] = true,
yellowfive@57 299 [120223] = true,
yellowfive@57 300 [120222] = true,
yellowfive@57 301 [120221] = true,
yellowfive@57 302 [120220] = true,
yellowfive@57 303 [120219] = true,
yellowfive@57 304 [120218] = true,
yellowfive@57 305 [120217] = true,
yellowfive@57 306 [120216] = true,
yellowfive@57 307 [120215] = true,
yellowfive@57 308 [120214] = true,
yellowfive@57 309 [120213] = true,
yellowfive@57 310 [120212] = true,
yellowfive@57 311 [120211] = true,
yellowfive@57 312 [120210] = true,
yellowfive@57 313 [120209] = true,
yellowfive@57 314 [120208] = true,
yellowfive@57 315 [120207] = true,
yellowfive@57 316 [120206] = true,
yellowfive@57 317 [119323] = true,
yellowfive@57 318 [119322] = true,
yellowfive@57 319 [119321] = true,
yellowfive@57 320 [119320] = true,
yellowfive@57 321 [119319] = true,
yellowfive@57 322 [119318] = true,
yellowfive@57 323 [119316] = true,
yellowfive@57 324 [119315] = true,
yellowfive@57 325 [119314] = true,
yellowfive@57 326 [119313] = true,
yellowfive@57 327 [119312] = true,
yellowfive@57 328 [119311] = true,
yellowfive@57 329 [119310] = true,
yellowfive@57 330 [119309] = true,
yellowfive@57 331 [119308] = true,
yellowfive@57 332 [119307] = true,
yellowfive@57 333 [119306] = true,
yellowfive@57 334 [119305] = true,
yellowfive@57 335 [105868] = true,
yellowfive@57 336 [105867] = true,
yellowfive@57 337 [105866] = true,
yellowfive@57 338 [105865] = true,
yellowfive@57 339 [105864] = true,
yellowfive@57 340 [105863] = true,
yellowfive@57 341 [105862] = true,
yellowfive@57 342 [105861] = true,
yellowfive@57 343 [105860] = true,
yellowfive@57 344 [105859] = true,
yellowfive@57 345 [105858] = true,
yellowfive@57 346 [105857] = true,
yellowfive@57 347 [99756] = true,
yellowfive@57 348 [99755] = true,
yellowfive@57 349 [99754] = true,
yellowfive@57 350 [99753] = true,
yellowfive@57 351 [99752] = true,
yellowfive@57 352 [99751] = true,
yellowfive@57 353 [99750] = true,
yellowfive@57 354 [99749] = true,
yellowfive@57 355 [99748] = true,
yellowfive@57 356 [99747] = true,
yellowfive@57 357 [99746] = true,
yellowfive@57 358 [99745] = true,
yellowfive@57 359 [99744] = true,
yellowfive@57 360 [99743] = true,
yellowfive@57 361 [99742] = true,
yellowfive@57 362 [99740] = true,
yellowfive@57 363 [99739] = true,
yellowfive@57 364 [99738] = true,
yellowfive@57 365 [99737] = true,
yellowfive@57 366 [99736] = true,
yellowfive@57 367 [99735] = true,
yellowfive@57 368 [99734] = true,
yellowfive@57 369 [99733] = true,
yellowfive@57 370 [99732] = true,
yellowfive@57 371 [99731] = true,
yellowfive@57 372 [99730] = true,
yellowfive@57 373 [99729] = true,
yellowfive@57 374 [99728] = true,
yellowfive@57 375 [99727] = true,
yellowfive@57 376 [99726] = true,
yellowfive@57 377 [99725] = true,
yellowfive@57 378 [99724] = true,
yellowfive@57 379 [99723] = true,
yellowfive@57 380 [99722] = true,
yellowfive@57 381 [99721] = true,
yellowfive@57 382 [99720] = true,
yellowfive@57 383 [99719] = true,
yellowfive@57 384 [99718] = true,
yellowfive@57 385 [99717] = true,
yellowfive@57 386 [99716] = true,
yellowfive@57 387 [99715] = true,
yellowfive@57 388 [99714] = true,
yellowfive@57 389 [99713] = true,
yellowfive@57 390 [99712] = true,
yellowfive@57 391 [99711] = true,
yellowfive@57 392 [99710] = true,
yellowfive@57 393 [99709] = true,
yellowfive@57 394 [99708] = true,
yellowfive@57 395 [99707] = true,
yellowfive@57 396 [99706] = true,
yellowfive@57 397 [99705] = true,
yellowfive@57 398 [99704] = true,
yellowfive@57 399 [99703] = true,
yellowfive@57 400 [99702] = true,
yellowfive@57 401 [99701] = true,
yellowfive@57 402 [99700] = true,
yellowfive@57 403 [99699] = true,
yellowfive@57 404 [99698] = true,
yellowfive@57 405 [99697] = true,
yellowfive@57 406 [99696] = true,
yellowfive@57 407 [99695] = true,
yellowfive@57 408 [99694] = true,
yellowfive@57 409 [99693] = true,
yellowfive@57 410 [99692] = true,
yellowfive@57 411 [99691] = true,
yellowfive@57 412 [99690] = true,
yellowfive@57 413 [99689] = true,
yellowfive@57 414 [99688] = true,
yellowfive@57 415 [99687] = true,
yellowfive@57 416 [99686] = true,
yellowfive@57 417 [99685] = true,
yellowfive@57 418 [99684] = true,
yellowfive@57 419 [99683] = true,
yellowfive@57 420 [99682] = true,
yellowfive@57 421 [99681] = true,
yellowfive@57 422 [99680] = true,
yellowfive@57 423 [99679] = true,
yellowfive@57 424 [99678] = true,
yellowfive@57 425 [99677] = true,
yellowfive@57 426 [99676] = true,
yellowfive@57 427 [99675] = true,
yellowfive@57 428 [99674] = true,
yellowfive@57 429 [99673] = true,
yellowfive@57 430 [99672] = true,
yellowfive@57 431 [99671] = true,
yellowfive@57 432 [99670] = true,
yellowfive@57 433 [99669] = true,
yellowfive@57 434 [99668] = true,
yellowfive@57 435 [99667] = true,
yellowfive@57 436 [96701] = true,
yellowfive@57 437 [96700] = true,
yellowfive@57 438 [96699] = true,
yellowfive@57 439 [96633] = true,
yellowfive@57 440 [96632] = true,
yellowfive@57 441 [96631] = true,
yellowfive@57 442 [96625] = true,
yellowfive@57 443 [96624] = true,
yellowfive@57 444 [96623] = true,
yellowfive@57 445 [96601] = true,
yellowfive@57 446 [96600] = true,
yellowfive@57 447 [96599] = true,
yellowfive@57 448 [96568] = true,
yellowfive@57 449 [96567] = true,
yellowfive@57 450 [96566] = true,
yellowfive@57 451 [95957] = true,
yellowfive@57 452 [95956] = true,
yellowfive@57 453 [95955] = true,
yellowfive@57 454 [95889] = true,
yellowfive@57 455 [95888] = true,
yellowfive@57 456 [95887] = true,
yellowfive@57 457 [95881] = true,
yellowfive@57 458 [95880] = true,
yellowfive@57 459 [95879] = true,
yellowfive@57 460 [95857] = true,
yellowfive@57 461 [95856] = true,
yellowfive@57 462 [95855] = true,
yellowfive@57 463 [95824] = true,
yellowfive@57 464 [95823] = true,
yellowfive@57 465 [95822] = true,
yellowfive@57 466 [95583] = true,
yellowfive@57 467 [95582] = true,
yellowfive@57 468 [95581] = true,
yellowfive@57 469 [95580] = true,
yellowfive@57 470 [95579] = true,
yellowfive@57 471 [95578] = true,
yellowfive@57 472 [95577] = true,
yellowfive@57 473 [95576] = true,
yellowfive@57 474 [95575] = true,
yellowfive@57 475 [95574] = true,
yellowfive@57 476 [95573] = true,
yellowfive@57 477 [95572] = true,
yellowfive@57 478 [95571] = true,
yellowfive@57 479 [95570] = true,
yellowfive@57 480 [95569] = true,
yellowfive@57 481 [89278] = true,
yellowfive@57 482 [89277] = true,
yellowfive@57 483 [89276] = true,
yellowfive@57 484 [89275] = true,
yellowfive@57 485 [89274] = true,
yellowfive@57 486 [89273] = true,
yellowfive@57 487 [89272] = true,
yellowfive@57 488 [89271] = true,
yellowfive@57 489 [89270] = true,
yellowfive@57 490 [89269] = true,
yellowfive@57 491 [89268] = true,
yellowfive@57 492 [89267] = true,
yellowfive@57 493 [89266] = true,
yellowfive@57 494 [89265] = true,
yellowfive@57 495 [89264] = true,
yellowfive@57 496 [89263] = true,
yellowfive@57 497 [89262] = true,
yellowfive@57 498 [89261] = true,
yellowfive@57 499 [89260] = true,
yellowfive@57 500 [89259] = true,
yellowfive@57 501 [89258] = true,
yellowfive@57 502 [89257] = true,
yellowfive@57 503 [89256] = true,
yellowfive@57 504 [89255] = true,
yellowfive@57 505 [89254] = true,
yellowfive@57 506 [89253] = true,
yellowfive@57 507 [89252] = true,
yellowfive@57 508 [89251] = true,
yellowfive@57 509 [89250] = true,
yellowfive@57 510 [89249] = true,
yellowfive@57 511 [89248] = true,
yellowfive@57 512 [89247] = true,
yellowfive@57 513 [89246] = true,
yellowfive@57 514 [89245] = true,
yellowfive@57 515 [89244] = true,
yellowfive@57 516 [89243] = true,
yellowfive@57 517 [89242] = true,
yellowfive@57 518 [89241] = true,
yellowfive@57 519 [89240] = true,
yellowfive@57 520 [89239] = true,
yellowfive@57 521 [89238] = true,
yellowfive@57 522 [89237] = true,
yellowfive@57 523 [89236] = true,
yellowfive@57 524 [89235] = true,
yellowfive@57 525 [89234] = true,
yellowfive@57 526 [78876] = true,
yellowfive@57 527 [78875] = true,
yellowfive@57 528 [78874] = true,
yellowfive@57 529 [78873] = true,
yellowfive@57 530 [78872] = true,
yellowfive@57 531 [78871] = true,
yellowfive@57 532 [78867] = true,
yellowfive@57 533 [78866] = true,
yellowfive@57 534 [78865] = true,
yellowfive@57 535 [78864] = true,
yellowfive@57 536 [78863] = true,
yellowfive@57 537 [78862] = true,
yellowfive@57 538 [78861] = true,
yellowfive@57 539 [78860] = true,
yellowfive@57 540 [78859] = true,
yellowfive@57 541 [78858] = true,
yellowfive@57 542 [78857] = true,
yellowfive@57 543 [78856] = true,
yellowfive@57 544 [78855] = true,
yellowfive@57 545 [78854] = true,
yellowfive@57 546 [78853] = true,
yellowfive@57 547 [78849] = true,
yellowfive@57 548 [78848] = true,
yellowfive@57 549 [78847] = true,
yellowfive@57 550 [78184] = true,
yellowfive@57 551 [78183] = true,
yellowfive@57 552 [78181] = true,
yellowfive@57 553 [78180] = true,
yellowfive@57 554 [78179] = true,
yellowfive@57 555 [78178] = true,
yellowfive@57 556 [78176] = true,
yellowfive@57 557 [78175] = true,
yellowfive@57 558 [78174] = true,
yellowfive@57 559 [78173] = true,
yellowfive@57 560 [78171] = true,
yellowfive@57 561 [78170] = true,
yellowfive@57 562 [71687] = true,
yellowfive@57 563 [71686] = true,
yellowfive@57 564 [71685] = true,
yellowfive@57 565 [71683] = true,
yellowfive@57 566 [71682] = true,
yellowfive@57 567 [71680] = true,
yellowfive@57 568 [71679] = true,
yellowfive@57 569 [71678] = true,
yellowfive@57 570 [71676] = true,
yellowfive@57 571 [71675] = true,
yellowfive@57 572 [71673] = true,
yellowfive@57 573 [71672] = true,
yellowfive@57 574 [71671] = true,
yellowfive@57 575 [71669] = true,
yellowfive@57 576 [71668] = true,
yellowfive@57 577 [67431] = true,
yellowfive@57 578 [67430] = true,
yellowfive@57 579 [67429] = true,
yellowfive@57 580 [67428] = true,
yellowfive@57 581 [67427] = true,
yellowfive@57 582 [67426] = true,
yellowfive@57 583 [67425] = true,
yellowfive@57 584 [67424] = true,
yellowfive@57 585 [67423] = true,
yellowfive@57 586 [66998] = true,
yellowfive@57 587 [65089] = true,
yellowfive@57 588 [65088] = true,
yellowfive@57 589 [65087] = true,
yellowfive@57 590 [63684] = true,
yellowfive@57 591 [63683] = true,
yellowfive@57 592 [63682] = true,
yellowfive@63 593 [51320] = true,
yellowfive@57 594 [45652] = true,
yellowfive@57 595 [45651] = true,
yellowfive@57 596 [45650] = true,
yellowfive@57 597 [45649] = true,
yellowfive@57 598 [45648] = true,
yellowfive@57 599 [45647] = true,
yellowfive@57 600 [45643] = true,
yellowfive@57 601 [45642] = true,
yellowfive@57 602 [45641] = true,
yellowfive@57 603 [40630] = true,
yellowfive@57 604 [40629] = true,
yellowfive@57 605 [40628] = true,
yellowfive@57 606 [40621] = true,
yellowfive@57 607 [40620] = true,
yellowfive@57 608 [40619] = true,
yellowfive@57 609 [40618] = true,
yellowfive@57 610 [40617] = true,
yellowfive@57 611 [40616] = true,
yellowfive@57 612 [34544] = true,
yellowfive@57 613 [31100] = true,
yellowfive@57 614 [31099] = true,
yellowfive@57 615 [31098] = true,
yellowfive@57 616 [31097] = true,
yellowfive@57 617 [31096] = true,
yellowfive@57 618 [31095] = true,
yellowfive@57 619 [30247] = true,
yellowfive@57 620 [30246] = true,
yellowfive@57 621 [30245] = true,
yellowfive@57 622 [30244] = true,
yellowfive@57 623 [30243] = true,
yellowfive@57 624 [30242] = true,
yellowfive@57 625 [29767] = true,
yellowfive@57 626 [29766] = true,
yellowfive@57 627 [29765] = true,
yellowfive@57 628 [29761] = true,
yellowfive@57 629 [29760] = true,
yellowfive@57 630 [29759] = true
yellowfive@57 631 }
yellowfive@57 632
yellowfive@57 633
yellowfive@57 634 ----------------------------------------------------------------------------------------
yellowfive@57 635 -- Public Utility Methods
yellowfive@57 636 ----------------------------------------------------------------------------------------
yellowfive@57 637
yellowfive@81 638 local function readBonusIdList(parts, first, last)
yellowfive@81 639 local ret = {}
yellowfive@81 640 for i = first, last do
yellowfive@81 641 table.insert(ret, tonumber(parts[i]))
yellowfive@81 642 end
yellowfive@81 643 table.sort(ret)
yellowfive@81 644 return ret
yellowfive@81 645 end
yellowfive@81 646
yellowfive@81 647 local function setRelicId(item, index, relicBonuses)
yellowfive@81 648 local relicId = item.gemIds[index] .. ""
yellowfive@81 649 for i = 1, #relicBonuses do
yellowfive@81 650 relicId = relicId .. "." .. relicBonuses[i]
yellowfive@81 651 end
yellowfive@81 652 local list = item.gemItemIds or {}
yellowfive@81 653 list[i] = relicId
yellowfive@81 654 end
yellowfive@81 655
yellowfive@81 656 --|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]
yellowfive@81 657 -- 133004 for relic on my warrior, gem2
yellowfive@81 658 -- 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
yellowfive@81 659
yellowfive@81 660 --|cffa335ee|Hitem:itemID:enchant:gem1:gem2:gem3:gem4:suffixID:uniqueID:level:unknown:unknown:instanceDifficultyID:numBonusIDs:bonusID1:bonusID2...|h[item name]|h|r
yellowfive@81 661
yellowfive@69 662 -- 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
yellowfive@57 663 -- get an object with all of the parts of the item link format that we care about
yellowfive@57 664 function Amr.ParseItemLink(itemLink)
yellowfive@57 665 if not itemLink then return nil end
yellowfive@57 666
yellowfive@57 667 local str = string.match(itemLink, "|Hitem:([\-%d:]+)|")
yellowfive@57 668 if not str then return nil end
yellowfive@57 669
yellowfive@57 670 local parts = { strsplit(":", str) }
yellowfive@57 671
yellowfive@57 672 local item = {}
yellowfive@81 673 item.id = tonumber(parts[1]) or 0
yellowfive@81 674 item.enchantId = tonumber(parts[2]) or 0
yellowfive@81 675 item.gemIds = { tonumber(parts[3]) or 0, tonumber(parts[4]) or 0, tonumber(parts[5]) or 0, tonumber(parts[6]) or 0 }
yellowfive@81 676 item.suffixId = math.abs(tonumber(parts[7]) or 0) -- convert suffix to positive number, that's what we use in our code
yellowfive@81 677 -- part 8 is some unique ID... we never really used it
yellowfive@81 678 -- part 9 is current player level
yellowfive@81 679 -- part 10 is player spec
yellowfive@81 680 local upgradeIdType = tonumber(parts[11]) or 0 -- part 11 indicates what kind of upgrade ID is just after the bonus IDs
yellowfive@81 681 -- part 12 is instance difficulty id
yellowfive@57 682
yellowfive@81 683 local numBonuses = tonumber(parts[13]) or 0
yellowfive@81 684 local offset = numBonuses
yellowfive@81 685 if numBonuses > 0 then
yellowfive@81 686 item.bonusIds = readBonusIdList(parts, 14, 13 + numBonuses)
yellowfive@57 687 end
yellowfive@69 688
yellowfive@81 689 item.upgradeId = 0
yellowfive@81 690 item.level = 0
yellowfive@81 691
yellowfive@81 692 -- 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
yellowfive@81 693 if upgradeIdType == 4 then
yellowfive@81 694 item.upgradeId = tonumber(parts[14 + offset]) or 0
yellowfive@81 695 elseif upgradeIdType == 512 then
yellowfive@81 696 item.level = tonumber(parts[14 + offset]) or 0
yellowfive@69 697 end
yellowfive@81 698
yellowfive@81 699 -- ignore relic stuff in the item link for now, we read the relic information directly and save it with artifact power info
yellowfive@81 700 --[[
yellowfive@81 701 -- the next part is the number of bonus IDs on the first relic slot of the artifact
yellowfive@81 702 numBonuses = tonumber(parts[15 + offset]) or 0
yellowfive@81 703 if numBonuses > 0 then
yellowfive@81 704 local relicBonuses = readBonusIdList(16 + offset, 15 + offset + numBonuses, parts)
yellowfive@81 705 setRelicId(item, 1, relicBonuses)
yellowfive@81 706 end
yellowfive@81 707
yellowfive@81 708 -- second relic slot bonus IDs
yellowfive@81 709 offset = offset + numBonuses
yellowfive@81 710 numBonuses = tonumber(parts[16 + offset]) or 0
yellowfive@81 711 if numBonuses > 0 then
yellowfive@81 712 local relicBonuses = readBonusIdList(17 + offset, 16 + offset + numBonuses, parts)
yellowfive@81 713 setRelicId(item, 2, relicBonuses)
yellowfive@81 714 end
yellowfive@81 715
yellowfive@81 716 -- third relic slot bonus IDs
yellowfive@81 717 offset = offset + numBonuses
yellowfive@81 718 numBonuses = tonumber(parts[17 + offset]) or 0
yellowfive@81 719 if numBonuses > 0 then
yellowfive@81 720 local relicBonuses = readBonusIdList(18 + offset, 17 + offset + numBonuses, parts)
yellowfive@81 721 setRelicId(item, 3, relicBonuses)
yellowfive@81 722 end
yellowfive@81 723 ]]
yellowfive@81 724
yellowfive@57 725 return item
yellowfive@57 726 end
yellowfive@57 727
yellowfive@81 728 function Amr.GetItemUniqueId(item, noUpgrade)
yellowfive@81 729 if not item then return "" end
yellowfive@81 730 local ret = item.id .. ""
yellowfive@81 731 if item.bonusIds then
yellowfive@81 732 for i = 1, #item.bonusIds do
yellowfive@81 733 ret = ret .. "b" .. item.bonusIds[i]
yellowfive@81 734 end
yellowfive@81 735 end
yellowfive@81 736 if item.suffixId ~= 0 then
yellowfive@81 737 ret = ret .. "s" .. item.suffixId
yellowfive@81 738 end
yellowfive@81 739 if not noUpgrade and item.upgradeId ~= 0 then
yellowfive@81 740 ret = ret .. "u" .. item.upgradeId
yellowfive@81 741 end
yellowfive@81 742 if item.level ~= 0 then
yellowfive@81 743 ret = ret .. "v" .. item.level
yellowfive@81 744 end
yellowfive@81 745 return ret
yellowfive@81 746 end
yellowfive@81 747
yellowfive@57 748 -- returns true if this is an instance that AskMrRobot supports for logging
yellowfive@57 749 function Amr.IsSupportedInstanceId(instanceMapID)
yellowfive@57 750 if Amr.SupportedInstanceIds[tonumber(instanceMapID)] then
yellowfive@57 751 return true
yellowfive@57 752 else
yellowfive@57 753 return false
yellowfive@57 754 end
yellowfive@57 755 end
yellowfive@57 756
yellowfive@57 757 -- returns true if currently in a supported instance for logging
yellowfive@57 758 function Amr.IsSupportedInstance()
yellowfive@57 759 local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo()
yellowfive@57 760 return Amr.IsSupportedInstanceId(instanceMapID)
yellowfive@57 761 end
yellowfive@57 762
yellowfive@81 763 -- helper to iterate over a table in order by its keys
yellowfive@81 764 local function spairs(t, order)
yellowfive@81 765 -- collect the keys
yellowfive@81 766 local keys = {}
yellowfive@81 767 for k in pairs(t) do keys[#keys+1] = k end
yellowfive@81 768
yellowfive@81 769 -- if order function given, sort by it by passing the table and keys a, b,
yellowfive@81 770 -- otherwise just sort the keys
yellowfive@81 771 if order then
yellowfive@81 772 table.sort(keys, function(a,b) return order(t, a, b) end)
yellowfive@81 773 else
yellowfive@81 774 table.sort(keys)
yellowfive@81 775 end
yellowfive@81 776
yellowfive@81 777 -- return the iterator function
yellowfive@81 778 local i = 0
yellowfive@81 779 return function()
yellowfive@81 780 i = i + 1
yellowfive@81 781 if keys[i] then
yellowfive@81 782 return keys[i], t[keys[i]]
yellowfive@81 783 end
yellowfive@81 784 end
yellowfive@81 785 end
yellowfive@81 786
yellowfive@81 787 -- scanning tooltip b/c for some odd reason the api has no way to get basic item properties...
yellowfive@81 788 -- so you have to generate a fake item tooltip and search for pre-defined strings in the display text
yellowfive@81 789 local _scanTt
yellowfive@81 790 function Amr.GetScanningTooltip()
yellowfive@81 791 if not _scanTt then
yellowfive@81 792 _scanTt = CreateFrame("GameTooltip", "AmrUiScanTooltip", nil, "GameTooltipTemplate")
yellowfive@81 793 _scanTt:SetOwner(UIParent, "ANCHOR_NONE")
yellowfive@81 794 end
yellowfive@81 795 return _scanTt
yellowfive@81 796 end
yellowfive@81 797
yellowfive@81 798 -- get the item tooltip for the specified item in one of your bags, or if bagId is nil, an equipped item, or if slotId is also nil, the specified item link
yellowfive@81 799 function Amr.GetItemTooltip(bagId, slotId, link)
yellowfive@81 800 local tt = Amr.GetScanningTooltip()
yellowfive@81 801 tt:ClearLines()
yellowfive@81 802 if bagId then
yellowfive@81 803 tt:SetBagItem(bagId, slotId)
yellowfive@81 804 elseif slotId then
yellowfive@81 805 tt:SetInventoryItem("player", slotId)
yellowfive@81 806 else
yellowfive@81 807 tt:SetHyperlink(link)
yellowfive@81 808 end
yellowfive@81 809 return tt
yellowfive@81 810 end
yellowfive@81 811
yellowfive@81 812 function Amr.GetItemLevel(bagId, slotId, link)
yellowfive@81 813 local itemLevelPattern = _G["ITEM_LEVEL"]:gsub("%%d", "(%%d+)")
yellowfive@81 814 local tt = Amr.GetItemTooltip(bagId, slotId, link)
yellowfive@81 815
yellowfive@81 816 local regions = { tt:GetRegions() }
yellowfive@81 817 for i, region in ipairs(regions) do
yellowfive@81 818 if region and region:GetObjectType() == "FontString" then
yellowfive@81 819 local text = region:GetText()
yellowfive@81 820 if text then
yellowfive@81 821 ilvl = tonumber(text:match(itemLevelPattern))
yellowfive@81 822 if ilvl then
yellowfive@81 823 return ilvl
yellowfive@81 824 end
yellowfive@81 825 end
yellowfive@81 826 end
yellowfive@81 827 end
yellowfive@81 828
yellowfive@81 829 -- 0 means we couldn't find it for whatever reason
yellowfive@81 830 return 0
yellowfive@81 831 end
yellowfive@81 832
yellowfive@57 833
yellowfive@57 834 ----------------------------------------------------------------------------------------
yellowfive@57 835 -- Character Reading
yellowfive@57 836 ----------------------------------------------------------------------------------------
yellowfive@57 837
yellowfive@57 838 local function readProfessionInfo(prof, ret)
yellowfive@57 839 if prof then
yellowfive@57 840 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof);
yellowfive@57 841 if Amr.ProfessionSkillLineToName[skillLine] ~= nil then
yellowfive@57 842 ret.Professions[Amr.ProfessionSkillLineToName[skillLine]] = skillLevel;
yellowfive@57 843 end
yellowfive@57 844 end
yellowfive@57 845 end
yellowfive@57 846
yellowfive@81 847 --[[
yellowfive@81 848 local function getTalents(specPos)
yellowfive@57 849 local talentInfo = {}
yellowfive@57 850 local maxTiers = 7
yellowfive@57 851 for tier = 1, maxTiers do
yellowfive@57 852 for col = 1, 3 do
yellowfive@81 853 local id, name, _, _, _, spellId, _, t, c, selected = GetTalentInfoBySpecialization(specPos, tier, col)
yellowfive@57 854 if selected then
yellowfive@57 855 talentInfo[tier] = col
yellowfive@57 856 end
yellowfive@57 857 end
yellowfive@57 858 end
yellowfive@57 859
yellowfive@57 860 local str = ""
yellowfive@57 861 for i = 1, maxTiers do
yellowfive@57 862 if talentInfo[i] then
yellowfive@57 863 str = str .. talentInfo[i]
yellowfive@57 864 else
yellowfive@57 865 str = str .. '0'
yellowfive@57 866 end
yellowfive@57 867 end
yellowfive@57 868
yellowfive@57 869 return str
yellowfive@57 870 end
yellowfive@81 871 ]]
yellowfive@57 872
yellowfive@81 873 --[[
yellowfive@57 874 local function getGlyphs(specGroup)
yellowfive@57 875 local glyphs = {}
yellowfive@57 876 for i = 1, NUM_GLYPH_SLOTS do
yellowfive@57 877 local _, _, _, glyphSpellID, _, glyphID = GetGlyphSocketInfo(i, specGroup)
yellowfive@57 878 if (glyphID) then
yellowfive@57 879 table.insert(glyphs, glyphSpellID)
yellowfive@57 880 end
yellowfive@57 881 end
yellowfive@57 882 return glyphs;
yellowfive@57 883 end
yellowfive@81 884 ]]
yellowfive@57 885
yellowfive@81 886 -- get specs and talents
yellowfive@81 887 local function readSpecs(ret)
yellowfive@57 888
yellowfive@81 889 for pos = 1, 4 do
yellowfive@57 890 -- spec, convert game spec id to one of our spec ids
yellowfive@81 891 local specId = GetSpecializationInfo(pos)
yellowfive@57 892 if specId then
yellowfive@81 893 ret.Specs[pos] = Amr.SpecIds[specId]
yellowfive@81 894 -- TODO: figure out how to read inactive spec talents if possible... used to be able to but they changed it
yellowfive@81 895 --ret.Talents[pos] = getTalents(pos)
yellowfive@57 896 end
yellowfive@57 897 end
yellowfive@57 898 end
yellowfive@57 899
yellowfive@81 900 -- TODO: hopefully we can read artifact here when there is an API to get info when the artifact UI is not open
yellowfive@81 901 -- get artifact info
yellowfive@81 902 local function readArtifact()
yellowfive@81 903
yellowfive@81 904 end
yellowfive@81 905
yellowfive@57 906 -- get currently equipped items, store with currently active spec
yellowfive@57 907 local function readEquippedItems(ret)
yellowfive@57 908 local equippedItems = {};
yellowfive@57 909 for slotNum = 1, #Amr.SlotIds do
yellowfive@57 910 local slotId = Amr.SlotIds[slotNum]
yellowfive@57 911 local itemLink = GetInventoryItemLink("player", slotId)
yellowfive@57 912 if itemLink then
yellowfive@57 913 equippedItems[slotId] = itemLink
yellowfive@57 914 end
yellowfive@57 915 end
yellowfive@57 916
yellowfive@57 917 -- store last-seen equipped gear for each spec
yellowfive@81 918 ret.Equipped[GetSpecialization()] = equippedItems
yellowfive@57 919 end
yellowfive@57 920
yellowfive@57 921 -- Get all data about the player as an object, includes:
yellowfive@57 922 -- serializer version
yellowfive@57 923 -- region/realm/name
yellowfive@57 924 -- guild
yellowfive@57 925 -- race
yellowfive@57 926 -- faction
yellowfive@57 927 -- level
yellowfive@57 928 -- professions
yellowfive@81 929 -- spec/talent for all specs
yellowfive@81 930 -- artifact for current spec
yellowfive@57 931 -- equipped gear for the current spec
yellowfive@57 932 --
yellowfive@81 933 function Amr:GetPlayerData()
yellowfive@57 934
yellowfive@57 935 local ret = {}
yellowfive@57 936
yellowfive@57 937 ret.Region = Amr.RegionNames[GetCurrentRegion()]
yellowfive@57 938 ret.Realm = GetRealmName()
yellowfive@57 939 ret.Name = UnitName("player")
yellowfive@57 940 ret.Guild = GetGuildInfo("player")
yellowfive@81 941 ret.ActiveSpec = GetSpecialization()
yellowfive@57 942 ret.Level = UnitLevel("player");
yellowfive@57 943
yellowfive@57 944 local cls, clsEn = UnitClass("player")
yellowfive@57 945 ret.Class = clsEn;
yellowfive@57 946
yellowfive@57 947 local race, raceEn = UnitRace("player")
yellowfive@57 948 ret.Race = raceEn;
yellowfive@57 949 ret.Faction = UnitFactionGroup("player")
yellowfive@57 950
yellowfive@57 951 ret.Professions = {};
yellowfive@57 952 local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions();
yellowfive@57 953 readProfessionInfo(prof1, ret)
yellowfive@57 954 readProfessionInfo(prof2, ret)
yellowfive@57 955 readProfessionInfo(archaeology, ret)
yellowfive@57 956 readProfessionInfo(fishing, ret)
yellowfive@57 957 readProfessionInfo(cooking, ret)
yellowfive@57 958 readProfessionInfo(firstAid, ret)
yellowfive@57 959
yellowfive@57 960 ret.Specs = {}
yellowfive@57 961 ret.Talents = {}
yellowfive@81 962 readSpecs(ret)
yellowfive@81 963
yellowfive@81 964 ret.Artifacts = {}
yellowfive@81 965 readArtifact()
yellowfive@57 966
yellowfive@57 967 ret.Equipped = {}
yellowfive@57 968 readEquippedItems(ret)
yellowfive@57 969
yellowfive@57 970 return ret
yellowfive@57 971 end
yellowfive@57 972
yellowfive@57 973
yellowfive@57 974 ----------------------------------------------------------------------------------------
yellowfive@57 975 -- Serialization
yellowfive@57 976 ----------------------------------------------------------------------------------------
yellowfive@57 977
yellowfive@57 978 local function toCompressedNumberList(list)
yellowfive@57 979 -- ensure the values are numbers, sorted from lowest to highest
yellowfive@57 980 local nums = {}
yellowfive@57 981 for i, v in ipairs(list) do
yellowfive@57 982 table.insert(nums, tonumber(v))
yellowfive@57 983 end
yellowfive@57 984 table.sort(nums)
yellowfive@57 985
yellowfive@57 986 local ret = {}
yellowfive@57 987 local prev = 0
yellowfive@57 988 for i, v in ipairs(nums) do
yellowfive@57 989 local diff = v - prev
yellowfive@57 990 table.insert(ret, diff)
yellowfive@57 991 prev = v
yellowfive@57 992 end
yellowfive@57 993
yellowfive@57 994 return table.concat(ret, ",")
yellowfive@57 995 end
yellowfive@57 996
yellowfive@57 997 -- make this utility publicly available
yellowfive@57 998 function Amr:ToCompressedNumberList(list)
yellowfive@57 999 return toCompressedNumberList(list)
yellowfive@57 1000 end
yellowfive@57 1001
yellowfive@57 1002 -- appends a list of items to the export
yellowfive@57 1003 local function appendItemsToExport(fields, itemObjects)
yellowfive@57 1004
yellowfive@57 1005 -- sort by item id so we can compress it more easily
yellowfive@57 1006 table.sort(itemObjects, function(a, b) return a.id < b.id end)
yellowfive@57 1007
yellowfive@57 1008 -- append to the export string
yellowfive@57 1009 local prevItemId = 0
yellowfive@57 1010 local prevGemId = 0
yellowfive@57 1011 local prevEnchantId = 0
yellowfive@57 1012 local prevUpgradeId = 0
yellowfive@57 1013 local prevBonusId = 0
yellowfive@81 1014 local prevLevel = 0
yellowfive@57 1015 for i, itemData in ipairs(itemObjects) do
yellowfive@57 1016 local itemParts = {}
yellowfive@57 1017
yellowfive@81 1018 -- 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
yellowfive@81 1019 --local _, _, quality = GetItemInfo(itemData.link)
yellowfive@81 1020 --if quality == 6 then
yellowfive@81 1021 -- itemData.level = Amr.GetItemLevel(nil, nil, itemData.link)
yellowfive@81 1022 --end
yellowfive@81 1023
yellowfive@57 1024 table.insert(itemParts, itemData.id - prevItemId)
yellowfive@57 1025 prevItemId = itemData.id
yellowfive@57 1026
yellowfive@57 1027 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end
yellowfive@57 1028 if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end
yellowfive@57 1029 if itemData.upgradeId ~= 0 then
yellowfive@57 1030 table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId))
yellowfive@57 1031 prevUpgradeId = itemData.upgradeId
yellowfive@57 1032 end
yellowfive@81 1033 if itemData.level ~= 0 then
yellowfive@81 1034 table.insert(itemParts, "v" .. (itemData.level - prevLevel))
yellowfive@81 1035 prevLevel = itemData.level
yellowfive@81 1036 end
yellowfive@57 1037 if itemData.bonusIds then
yellowfive@57 1038 for bIndex, bValue in ipairs(itemData.bonusIds) do
yellowfive@57 1039 table.insert(itemParts, "b" .. (bValue - prevBonusId))
yellowfive@57 1040 prevBonusId = bValue
yellowfive@57 1041 end
yellowfive@57 1042 end
yellowfive@81 1043
yellowfive@81 1044 if itemData.gemIds[1] ~= 0 then
yellowfive@81 1045 table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId))
yellowfive@81 1046 prevGemId = itemData.gemIds[1]
yellowfive@81 1047 end
yellowfive@81 1048 if itemData.gemIds[2] ~= 0 then
yellowfive@81 1049 table.insert(itemParts, "y" .. (itemData.gemIds[2] - prevGemId))
yellowfive@81 1050 prevGemId = itemData.gemIds[2]
yellowfive@81 1051 end
yellowfive@81 1052 if itemData.gemIds[3] ~= 0 then
yellowfive@81 1053 table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId))
yellowfive@81 1054 prevGemId = itemData.gemIds[3]
yellowfive@81 1055 end
yellowfive@81 1056
yellowfive@57 1057 if itemData.enchantId ~= 0 then
yellowfive@57 1058 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId))
yellowfive@57 1059 prevEnchantId = itemData.enchantId
yellowfive@57 1060 end
yellowfive@57 1061
yellowfive@57 1062 table.insert(fields, table.concat(itemParts, ""))
yellowfive@57 1063 end
yellowfive@57 1064 end
yellowfive@57 1065
yellowfive@57 1066 -- Serialize just the identity portion of a player (region/realm/name) in the same format used by the full serialization
yellowfive@57 1067 function Amr:SerializePlayerIdentity(data)
yellowfive@57 1068 local fields = {}
yellowfive@57 1069 table.insert(fields, MINOR)
yellowfive@57 1070 table.insert(fields, data.Region)
yellowfive@57 1071 table.insert(fields, data.Realm)
yellowfive@57 1072 table.insert(fields, data.Name)
yellowfive@57 1073 return "$" .. table.concat(fields, ";") .. "$"
yellowfive@57 1074 end
yellowfive@57 1075
yellowfive@57 1076 -- Serialize player data gathered by GetPlayerData. This can be augmented with extra data if desired (augmenting used mainly by AskMrRobot addon).
yellowfive@57 1077 -- Pass complete = true to do a complete export of this extra information, otherwise it is ignored.
yellowfive@57 1078 -- Extra data can include:
yellowfive@57 1079 -- equipped gear for the player's inactive spec, slot id to item link dictionary
yellowfive@57 1080 -- Reputations
yellowfive@57 1081 -- BagItems, BankItems, VoidItems, lists of item links
yellowfive@57 1082 --
yellowfive@57 1083 function Amr:SerializePlayerData(data, complete)
yellowfive@57 1084
yellowfive@57 1085 local fields = {}
yellowfive@57 1086
yellowfive@57 1087 -- compressed string uses a fixed order rather than inserting identifiers
yellowfive@57 1088 table.insert(fields, MINOR)
yellowfive@57 1089 table.insert(fields, data.Region)
yellowfive@57 1090 table.insert(fields, data.Realm)
yellowfive@57 1091 table.insert(fields, data.Name)
yellowfive@57 1092
yellowfive@57 1093 -- guild name
yellowfive@57 1094 if data.Guild == nil then
yellowfive@57 1095 table.insert(fields, "")
yellowfive@57 1096 else
yellowfive@57 1097 table.insert(fields, data.Guild)
yellowfive@57 1098 end
yellowfive@57 1099
yellowfive@57 1100 -- race, default to pandaren if we can't read it for some reason
yellowfive@57 1101 local raceval = Amr.RaceIds[data.Race]
yellowfive@57 1102 if raceval == nil then raceval = 13 end
yellowfive@57 1103 table.insert(fields, raceval)
yellowfive@57 1104
yellowfive@57 1105 -- faction, default to alliance if we can't read it for some reason
yellowfive@57 1106 raceval = Amr.FactionIds[data.Faction]
yellowfive@57 1107 if raceval == nil then raceval = 1 end
yellowfive@57 1108 table.insert(fields, raceval)
yellowfive@57 1109
yellowfive@57 1110 table.insert(fields, data.Level)
yellowfive@57 1111
yellowfive@57 1112 local profs = {}
yellowfive@57 1113 local noprofs = true
yellowfive@57 1114 if data.Professions then
yellowfive@57 1115 for k, v in pairs(data.Professions) do
yellowfive@57 1116 local profval = Amr.ProfessionIds[k]
yellowfive@57 1117 if profval ~= nil then
yellowfive@57 1118 noprofs = false
yellowfive@57 1119 table.insert(profs, profval .. ":" .. v)
yellowfive@57 1120 end
yellowfive@57 1121 end
yellowfive@57 1122 end
yellowfive@57 1123
yellowfive@57 1124 if noprofs then
yellowfive@57 1125 table.insert(profs, "0:0")
yellowfive@57 1126 end
yellowfive@57 1127
yellowfive@57 1128 table.insert(fields, table.concat(profs, ","))
yellowfive@57 1129
yellowfive@57 1130 -- export specs
yellowfive@57 1131 table.insert(fields, data.ActiveSpec)
yellowfive@81 1132 for spec = 1, 4 do
yellowfive@57 1133 if data.Specs[spec] and (complete or spec == data.ActiveSpec) then
yellowfive@57 1134 table.insert(fields, ".s" .. spec) -- indicates the start of a spec block
yellowfive@81 1135 table.insert(fields, data.Specs[spec])
yellowfive@81 1136 table.insert(fields, data.Talents[spec])
yellowfive@57 1137
yellowfive@81 1138 local powerids = {}
yellowfive@81 1139 local powerranks = {}
yellowfive@81 1140 local reliclinks = {}
yellowfive@81 1141
yellowfive@81 1142 local artifactInfo = data.Artifacts and data.Artifacts[spec]
yellowfive@81 1143 if artifactInfo and artifactInfo.Powers then
yellowfive@81 1144 for k, v in spairs(artifactInfo.Powers) do
yellowfive@81 1145 table.insert(powerids, k)
yellowfive@81 1146 table.insert(powerranks, v)
yellowfive@81 1147 end
yellowfive@81 1148 end
yellowfive@81 1149 if artifactInfo and artifactInfo.Relics then
yellowfive@81 1150 for i, link in ipairs(artifactInfo.Relics) do
yellowfive@81 1151 local relic = Amr.ParseItemLink(link)
yellowfive@81 1152 table.insert(reliclinks, Amr.GetItemUniqueId(relic) or "")
yellowfive@81 1153 end
yellowfive@57 1154 end
yellowfive@57 1155
yellowfive@81 1156 table.insert(fields, toCompressedNumberList(powerids))
yellowfive@81 1157 table.insert(fields, table.concat(powerranks, ","))
yellowfive@81 1158 table.insert(fields, table.concat(reliclinks, ","))
yellowfive@81 1159
yellowfive@81 1160 --table.insert(fields, toCompressedNumberList(data.Glyphs[spec]))
yellowfive@57 1161 end
yellowfive@57 1162 end
yellowfive@57 1163
yellowfive@57 1164 -- export equipped gear
yellowfive@57 1165 if data.Equipped then
yellowfive@81 1166 for spec = 1, 4 do
yellowfive@57 1167 if data.Equipped[spec] and (complete or spec == data.ActiveSpec) then
yellowfive@57 1168 table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block
yellowfive@57 1169
yellowfive@57 1170 local itemObjects = {}
yellowfive@57 1171 for k, v in pairs(data.Equipped[spec]) do
yellowfive@57 1172 local itemData = Amr.ParseItemLink(v)
yellowfive@57 1173 itemData.slot = k
yellowfive@81 1174 itemData.link = v
yellowfive@57 1175 table.insert(itemObjects, itemData)
yellowfive@57 1176 end
yellowfive@57 1177
yellowfive@57 1178 appendItemsToExport(fields, itemObjects)
yellowfive@57 1179 end
yellowfive@57 1180 end
yellowfive@57 1181 end
yellowfive@57 1182
yellowfive@57 1183 -- if doing a complete export, include reputations and bank/bag items too
yellowfive@57 1184 if complete then
yellowfive@57 1185
yellowfive@57 1186 -- export reputations
yellowfive@57 1187 local reps = {}
yellowfive@57 1188 local noreps = true
yellowfive@57 1189 if data.Reputations then
yellowfive@57 1190 for k, v in pairs(data.Reputations) do
yellowfive@57 1191 noreps = false
yellowfive@57 1192 table.insert(reps, k .. ":" .. v)
yellowfive@57 1193 end
yellowfive@57 1194 end
yellowfive@57 1195 if noreps then
yellowfive@57 1196 table.insert(reps, "_")
yellowfive@57 1197 end
yellowfive@57 1198
yellowfive@57 1199 table.insert(fields, ".r")
yellowfive@57 1200 table.insert(fields, table.concat(reps, ","))
yellowfive@57 1201
yellowfive@57 1202 -- export bag and bank
yellowfive@57 1203 local itemObjects = {}
yellowfive@57 1204 if data.BagItems then
yellowfive@57 1205 for i, v in ipairs(data.BagItems) do
yellowfive@57 1206 local itemData = Amr.ParseItemLink(v)
yellowfive@85 1207 if itemData ~= nil --[[and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id])]] then
yellowfive@81 1208 itemData.link = v
yellowfive@57 1209 table.insert(itemObjects, itemData)
yellowfive@57 1210 end
yellowfive@57 1211 end
yellowfive@57 1212 end
yellowfive@57 1213 if data.BankItems then
yellowfive@57 1214 for i, v in ipairs(data.BankItems) do
yellowfive@57 1215 local itemData = Amr.ParseItemLink(v)
yellowfive@85 1216 if itemData ~= nil --[[and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id])]] then
yellowfive@81 1217 itemData.link = v
yellowfive@57 1218 table.insert(itemObjects, itemData)
yellowfive@57 1219 end
yellowfive@57 1220 end
yellowfive@57 1221 end
yellowfive@57 1222 if data.VoidItems then
yellowfive@57 1223 for i, v in ipairs(data.VoidItems) do
yellowfive@57 1224 local itemData = Amr.ParseItemLink(v)
yellowfive@85 1225 if itemData ~= nil --[[and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id])]] then
yellowfive@81 1226 itemData.link = v
yellowfive@57 1227 table.insert(itemObjects, itemData)
yellowfive@57 1228 end
yellowfive@57 1229 end
yellowfive@57 1230 end
yellowfive@57 1231
yellowfive@57 1232 table.insert(fields, ".inv")
yellowfive@57 1233 appendItemsToExport(fields, itemObjects)
yellowfive@57 1234 end
yellowfive@57 1235
yellowfive@57 1236 return "$" .. table.concat(fields, ";") .. "$"
yellowfive@57 1237
yellowfive@57 1238 end
yellowfive@57 1239
yellowfive@57 1240 -- Shortcut for the common use case: serialize the player's currently active setup with no extras.
yellowfive@57 1241 function Amr:SerializePlayer()
yellowfive@57 1242 local data = self:GetPlayerData()
yellowfive@57 1243 return self:SerializePlayerData(data)
yellowfive@57 1244 end
yellowfive@57 1245
yellowfive@81 1246 --[[
yellowfive@57 1247 ----------------------------------------------------------------------------------------------------------------------
yellowfive@57 1248 -- Character Snapshots
yellowfive@81 1249 -- This feature snapshots a player's gear/talents/artifact when entering combat. It is enabled by default. Consumers
yellowfive@57 1250 -- of this library can create a setting to enable/disable it as desired per a user setting.
yellowfive@57 1251 --
yellowfive@57 1252 -- You should register for the AMR_SNAPSHOT_STATE_CHANGED message (sent via AceEvent-3.0 messaging) to ensure that
yellowfive@57 1253 -- your addon settings stay in sync with any other addon that may also be trying to control the enabled state.
yellowfive@57 1254 --
yellowfive@57 1255 -- Note that if a user has the main AMR addon installed, it will always enable snapshotting, and override any attempt
yellowfive@57 1256 -- to disable it by immediately re-enabling it and thus re-triggering AMR_SNAPSHOT_STATE_CHANGED.
yellowfive@57 1257 ----------------------------------------------------------------------------------------------------------------------
yellowfive@57 1258 Amr._snapshotEnabled = true
yellowfive@57 1259
yellowfive@57 1260 -- Enable snapshotting of character data when entering combat. Sends this player's character data to anyone logging with the AskMrRobot addon.
yellowfive@57 1261 function Amr:EnableSnapshots()
yellowfive@57 1262 self._snapshotEnabled = true
yellowfive@57 1263 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
yellowfive@57 1264 end
yellowfive@57 1265
yellowfive@57 1266 -- Disable snapshotting of character data when entering combat.
yellowfive@57 1267 function Amr:DisableSnapshots()
yellowfive@57 1268 self._snapshotEnabled = false
yellowfive@57 1269 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
yellowfive@57 1270 end
yellowfive@57 1271
yellowfive@57 1272 function Amr:IsSnapshotEnabled()
yellowfive@57 1273 return self._snapshotEnabled
yellowfive@57 1274 end
yellowfive@57 1275
yellowfive@57 1276
yellowfive@57 1277 function Amr:PLAYER_REGEN_DISABLED()
yellowfive@57 1278 --function Amr:GARRISON_MISSION_NPC_OPENED()
yellowfive@57 1279
yellowfive@57 1280 -- send data about this character when a player enters combat in a supported zone
yellowfive@57 1281 if self._snapshotEnabled and Amr.IsSupportedInstance() then
yellowfive@57 1282 local t = time()
yellowfive@57 1283 local player = self:GetPlayerData()
yellowfive@57 1284 local msg = self:SerializePlayerData(player)
yellowfive@57 1285 msg = string.format("%s\r%s\n%s\n%s\n%s\n%s", MINOR, t, player.Region, player.Realm, player.Name, msg)
yellowfive@57 1286
yellowfive@57 1287 self:SendCommMessage(Amr.ChatPrefix, msg, "RAID")
yellowfive@57 1288 end
yellowfive@57 1289 end
yellowfive@57 1290
yellowfive@57 1291 Amr:RegisterEvent("PLAYER_REGEN_DISABLED")
yellowfive@81 1292 --Amr:RegisterEvent("GARRISON_MISSION_NPC_OPENED") -- for debugging, fire this event when open mission table
yellowfive@81 1293 ]]