annotate AskMrRobot-Serializer/AskMrRobot-Serializer.lua @ 110:5021d5125484 v51

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