annotate AskMrRobot-Serializer/AskMrRobot-Serializer.lua @ 118:5cb881417bbf v55

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