annotate AskMrRobot-Serializer/AskMrRobot-Serializer.lua @ 113:406f56dd065b

Added tag v52 for changeset 57c6cac5143c
author yellowfive
date Mon, 28 Aug 2017 19:33:28 -0700
parents 57c6cac5143c
children 4cd98aa90d78
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@112 4 local MAJOR, MINOR = "AskMrRobot-Serializer", 52
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@57 886 -- get currently equipped items, store with currently active spec
yellowfive@57 887 local function readEquippedItems(ret)
yellowfive@57 888 local equippedItems = {};
yellowfive@57 889 for slotNum = 1, #Amr.SlotIds do
yellowfive@57 890 local slotId = Amr.SlotIds[slotNum]
yellowfive@57 891 local itemLink = GetInventoryItemLink("player", slotId)
yellowfive@57 892 if itemLink then
yellowfive@57 893 equippedItems[slotId] = itemLink
yellowfive@57 894 end
yellowfive@57 895 end
yellowfive@57 896
yellowfive@57 897 -- store last-seen equipped gear for each spec
yellowfive@81 898 ret.Equipped[GetSpecialization()] = equippedItems
yellowfive@57 899 end
yellowfive@57 900
yellowfive@57 901 -- Get all data about the player as an object, includes:
yellowfive@57 902 -- serializer version
yellowfive@57 903 -- region/realm/name
yellowfive@57 904 -- guild
yellowfive@57 905 -- race
yellowfive@57 906 -- faction
yellowfive@57 907 -- level
yellowfive@57 908 -- professions
yellowfive@81 909 -- spec/talent for all specs
yellowfive@81 910 -- artifact for current spec
yellowfive@57 911 -- equipped gear for the current spec
yellowfive@57 912 --
yellowfive@81 913 function Amr:GetPlayerData()
yellowfive@57 914
yellowfive@57 915 local ret = {}
yellowfive@57 916
yellowfive@57 917 ret.Region = Amr.RegionNames[GetCurrentRegion()]
yellowfive@57 918 ret.Realm = GetRealmName()
yellowfive@57 919 ret.Name = UnitName("player")
yellowfive@57 920 ret.Guild = GetGuildInfo("player")
yellowfive@81 921 ret.ActiveSpec = GetSpecialization()
yellowfive@57 922 ret.Level = UnitLevel("player");
yellowfive@57 923
yellowfive@57 924 local cls, clsEn = UnitClass("player")
yellowfive@57 925 ret.Class = clsEn;
yellowfive@57 926
yellowfive@57 927 local race, raceEn = UnitRace("player")
yellowfive@57 928 ret.Race = raceEn;
yellowfive@57 929 ret.Faction = UnitFactionGroup("player")
yellowfive@57 930
yellowfive@57 931 ret.Professions = {};
yellowfive@57 932 local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions();
yellowfive@57 933 readProfessionInfo(prof1, ret)
yellowfive@57 934 readProfessionInfo(prof2, ret)
yellowfive@57 935 readProfessionInfo(archaeology, ret)
yellowfive@57 936 readProfessionInfo(fishing, ret)
yellowfive@57 937 readProfessionInfo(cooking, ret)
yellowfive@57 938 readProfessionInfo(firstAid, ret)
yellowfive@57 939
yellowfive@57 940 ret.Specs = {}
yellowfive@57 941 ret.Talents = {}
yellowfive@81 942 readSpecs(ret)
yellowfive@81 943
yellowfive@112 944 ret.Artifacts = {}
yellowfive@57 945
yellowfive@57 946 ret.Equipped = {}
yellowfive@57 947 readEquippedItems(ret)
yellowfive@57 948
yellowfive@57 949 return ret
yellowfive@57 950 end
yellowfive@57 951
yellowfive@57 952
yellowfive@57 953 ----------------------------------------------------------------------------------------
yellowfive@57 954 -- Serialization
yellowfive@57 955 ----------------------------------------------------------------------------------------
yellowfive@57 956
yellowfive@57 957 local function toCompressedNumberList(list)
yellowfive@57 958 -- ensure the values are numbers, sorted from lowest to highest
yellowfive@57 959 local nums = {}
yellowfive@57 960 for i, v in ipairs(list) do
yellowfive@57 961 table.insert(nums, tonumber(v))
yellowfive@57 962 end
yellowfive@57 963 table.sort(nums)
yellowfive@57 964
yellowfive@57 965 local ret = {}
yellowfive@57 966 local prev = 0
yellowfive@57 967 for i, v in ipairs(nums) do
yellowfive@57 968 local diff = v - prev
yellowfive@57 969 table.insert(ret, diff)
yellowfive@57 970 prev = v
yellowfive@57 971 end
yellowfive@57 972
yellowfive@57 973 return table.concat(ret, ",")
yellowfive@57 974 end
yellowfive@57 975
yellowfive@57 976 -- make this utility publicly available
yellowfive@57 977 function Amr:ToCompressedNumberList(list)
yellowfive@57 978 return toCompressedNumberList(list)
yellowfive@57 979 end
yellowfive@57 980
yellowfive@57 981 -- appends a list of items to the export
yellowfive@57 982 local function appendItemsToExport(fields, itemObjects)
yellowfive@57 983
yellowfive@57 984 -- sort by item id so we can compress it more easily
yellowfive@57 985 table.sort(itemObjects, function(a, b) return a.id < b.id end)
yellowfive@57 986
yellowfive@57 987 -- append to the export string
yellowfive@57 988 local prevItemId = 0
yellowfive@57 989 local prevGemId = 0
yellowfive@57 990 local prevEnchantId = 0
yellowfive@57 991 local prevUpgradeId = 0
yellowfive@57 992 local prevBonusId = 0
yellowfive@81 993 local prevLevel = 0
yellowfive@57 994 for i, itemData in ipairs(itemObjects) do
yellowfive@57 995 local itemParts = {}
yellowfive@57 996
yellowfive@81 997 -- 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 998 --local _, _, quality = GetItemInfo(itemData.link)
yellowfive@81 999 --if quality == 6 then
yellowfive@81 1000 -- itemData.level = Amr.GetItemLevel(nil, nil, itemData.link)
yellowfive@81 1001 --end
yellowfive@81 1002
yellowfive@57 1003 table.insert(itemParts, itemData.id - prevItemId)
yellowfive@57 1004 prevItemId = itemData.id
yellowfive@57 1005
yellowfive@57 1006 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end
yellowfive@57 1007 if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end
yellowfive@57 1008 if itemData.upgradeId ~= 0 then
yellowfive@57 1009 table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId))
yellowfive@57 1010 prevUpgradeId = itemData.upgradeId
yellowfive@57 1011 end
yellowfive@81 1012 if itemData.level ~= 0 then
yellowfive@81 1013 table.insert(itemParts, "v" .. (itemData.level - prevLevel))
yellowfive@81 1014 prevLevel = itemData.level
yellowfive@81 1015 end
yellowfive@57 1016 if itemData.bonusIds then
yellowfive@57 1017 for bIndex, bValue in ipairs(itemData.bonusIds) do
yellowfive@57 1018 table.insert(itemParts, "b" .. (bValue - prevBonusId))
yellowfive@57 1019 prevBonusId = bValue
yellowfive@57 1020 end
yellowfive@57 1021 end
yellowfive@81 1022
yellowfive@81 1023 if itemData.gemIds[1] ~= 0 then
yellowfive@81 1024 table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId))
yellowfive@81 1025 prevGemId = itemData.gemIds[1]
yellowfive@81 1026 end
yellowfive@81 1027 if itemData.gemIds[2] ~= 0 then
yellowfive@81 1028 table.insert(itemParts, "y" .. (itemData.gemIds[2] - prevGemId))
yellowfive@81 1029 prevGemId = itemData.gemIds[2]
yellowfive@81 1030 end
yellowfive@81 1031 if itemData.gemIds[3] ~= 0 then
yellowfive@81 1032 table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId))
yellowfive@81 1033 prevGemId = itemData.gemIds[3]
yellowfive@81 1034 end
yellowfive@81 1035
yellowfive@57 1036 if itemData.enchantId ~= 0 then
yellowfive@57 1037 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId))
yellowfive@57 1038 prevEnchantId = itemData.enchantId
yellowfive@57 1039 end
yellowfive@57 1040
yellowfive@57 1041 table.insert(fields, table.concat(itemParts, ""))
yellowfive@57 1042 end
yellowfive@57 1043 end
yellowfive@57 1044
yellowfive@112 1045 local function serializeCrucibleInfo(fields, info, pos, prevPowerId)
yellowfive@112 1046
yellowfive@112 1047 if not info.Powers or not info.Active then
yellowfive@112 1048 return prevPowerId
yellowfive@112 1049 end
yellowfive@112 1050
yellowfive@112 1051 local parts = {}
yellowfive@112 1052
yellowfive@112 1053 if pos < 4 then
yellowfive@112 1054 table.insert(parts, pos)
yellowfive@112 1055 else
yellowfive@112 1056 local relic = Amr.ParseItemLink(info.ItemLink)
yellowfive@112 1057 table.insert(parts, Amr.GetItemUniqueId(relic) or "0")
yellowfive@112 1058 end
yellowfive@112 1059
yellowfive@112 1060 for i,powerId in ipairs(info.Powers) do
yellowfive@112 1061 table.insert(parts, (powerId - prevPowerId) .. "")
yellowfive@112 1062 prevPowerId = powerId
yellowfive@112 1063 end
yellowfive@112 1064
yellowfive@112 1065 for i,active in ipairs(info.Active) do
yellowfive@112 1066 table.insert(parts, active and "1" or "0")
yellowfive@112 1067 end
yellowfive@112 1068
yellowfive@112 1069 table.insert(fields, table.concat(parts, ","))
yellowfive@112 1070
yellowfive@112 1071 return prevPowerId
yellowfive@112 1072 end
yellowfive@112 1073
yellowfive@57 1074 -- Serialize just the identity portion of a player (region/realm/name) in the same format used by the full serialization
yellowfive@57 1075 function Amr:SerializePlayerIdentity(data)
yellowfive@57 1076 local fields = {}
yellowfive@57 1077 table.insert(fields, MINOR)
yellowfive@57 1078 table.insert(fields, data.Region)
yellowfive@57 1079 table.insert(fields, data.Realm)
yellowfive@57 1080 table.insert(fields, data.Name)
yellowfive@57 1081 return "$" .. table.concat(fields, ";") .. "$"
yellowfive@57 1082 end
yellowfive@57 1083
yellowfive@57 1084 -- Serialize player data gathered by GetPlayerData. This can be augmented with extra data if desired (augmenting used mainly by AskMrRobot addon).
yellowfive@57 1085 -- Pass complete = true to do a complete export of this extra information, otherwise it is ignored.
yellowfive@57 1086 -- Extra data can include:
yellowfive@57 1087 -- equipped gear for the player's inactive spec, slot id to item link dictionary
yellowfive@57 1088 -- Reputations
yellowfive@57 1089 -- BagItems, BankItems, VoidItems, lists of item links
yellowfive@57 1090 --
yellowfive@57 1091 function Amr:SerializePlayerData(data, complete)
yellowfive@57 1092
yellowfive@57 1093 local fields = {}
yellowfive@57 1094
yellowfive@57 1095 -- compressed string uses a fixed order rather than inserting identifiers
yellowfive@57 1096 table.insert(fields, MINOR)
yellowfive@57 1097 table.insert(fields, data.Region)
yellowfive@57 1098 table.insert(fields, data.Realm)
yellowfive@57 1099 table.insert(fields, data.Name)
yellowfive@57 1100
yellowfive@57 1101 -- guild name
yellowfive@57 1102 if data.Guild == nil then
yellowfive@57 1103 table.insert(fields, "")
yellowfive@57 1104 else
yellowfive@57 1105 table.insert(fields, data.Guild)
yellowfive@57 1106 end
yellowfive@57 1107
yellowfive@57 1108 -- race, default to pandaren if we can't read it for some reason
yellowfive@57 1109 local raceval = Amr.RaceIds[data.Race]
yellowfive@57 1110 if raceval == nil then raceval = 13 end
yellowfive@57 1111 table.insert(fields, raceval)
yellowfive@57 1112
yellowfive@57 1113 -- faction, default to alliance if we can't read it for some reason
yellowfive@57 1114 raceval = Amr.FactionIds[data.Faction]
yellowfive@57 1115 if raceval == nil then raceval = 1 end
yellowfive@57 1116 table.insert(fields, raceval)
yellowfive@57 1117
yellowfive@57 1118 table.insert(fields, data.Level)
yellowfive@57 1119
yellowfive@57 1120 local profs = {}
yellowfive@57 1121 local noprofs = true
yellowfive@57 1122 if data.Professions then
yellowfive@57 1123 for k, v in pairs(data.Professions) do
yellowfive@57 1124 local profval = Amr.ProfessionIds[k]
yellowfive@57 1125 if profval ~= nil then
yellowfive@57 1126 noprofs = false
yellowfive@57 1127 table.insert(profs, profval .. ":" .. v)
yellowfive@57 1128 end
yellowfive@57 1129 end
yellowfive@57 1130 end
yellowfive@57 1131
yellowfive@57 1132 if noprofs then
yellowfive@57 1133 table.insert(profs, "0:0")
yellowfive@57 1134 end
yellowfive@57 1135
yellowfive@57 1136 table.insert(fields, table.concat(profs, ","))
yellowfive@57 1137
yellowfive@57 1138 -- export specs
yellowfive@57 1139 table.insert(fields, data.ActiveSpec)
yellowfive@81 1140 for spec = 1, 4 do
yellowfive@57 1141 if data.Specs[spec] and (complete or spec == data.ActiveSpec) then
yellowfive@57 1142 table.insert(fields, ".s" .. spec) -- indicates the start of a spec block
yellowfive@81 1143 table.insert(fields, data.Specs[spec])
yellowfive@91 1144 table.insert(fields, data.Talents[spec] or "")
yellowfive@57 1145
yellowfive@81 1146 local powerids = {}
yellowfive@81 1147 local powerranks = {}
yellowfive@112 1148 local reliclinks = {}
yellowfive@112 1149 local crucibleinfos = {}
yellowfive@81 1150
yellowfive@81 1151 local artifactInfo = data.Artifacts and data.Artifacts[spec]
yellowfive@81 1152 if artifactInfo and artifactInfo.Powers then
yellowfive@81 1153 for k, v in spairs(artifactInfo.Powers) do
yellowfive@81 1154 table.insert(powerids, k)
yellowfive@81 1155 table.insert(powerranks, v)
yellowfive@81 1156 end
yellowfive@81 1157 end
yellowfive@81 1158 if artifactInfo and artifactInfo.Relics then
yellowfive@81 1159 for i, link in ipairs(artifactInfo.Relics) do
yellowfive@81 1160 local relic = Amr.ParseItemLink(link)
yellowfive@81 1161 table.insert(reliclinks, Amr.GetItemUniqueId(relic) or "")
yellowfive@81 1162 end
yellowfive@57 1163 end
yellowfive@112 1164 if artifactInfo and artifactInfo.Crucible then
yellowfive@112 1165 local prevPowerId = 0
yellowfive@112 1166 for i = 1,3 do
yellowfive@112 1167 local relicInfo = #artifactInfo.Crucible.Equipped >= i and artifactInfo.Crucible.Equipped[i]
yellowfive@112 1168 if relicInfo then
yellowfive@112 1169 prevPowerId = serializeCrucibleInfo(crucibleinfos, relicInfo, i, prevPowerId)
yellowfive@112 1170 end
yellowfive@112 1171 end
yellowfive@112 1172 for k,relicInfo in pairs(artifactInfo.Crucible.Inventory) do
yellowfive@112 1173 if relicInfo then
yellowfive@112 1174 prevPowerId = serializeCrucibleInfo(crucibleinfos, relicInfo, 4, prevPowerId)
yellowfive@112 1175 end
yellowfive@112 1176 end
yellowfive@112 1177 end
yellowfive@57 1178
yellowfive@81 1179 table.insert(fields, toCompressedNumberList(powerids))
yellowfive@81 1180 table.insert(fields, table.concat(powerranks, ","))
yellowfive@81 1181 table.insert(fields, table.concat(reliclinks, ","))
yellowfive@112 1182 table.insert(fields, table.concat(crucibleinfos, "/"))
yellowfive@81 1183
yellowfive@81 1184 --table.insert(fields, toCompressedNumberList(data.Glyphs[spec]))
yellowfive@57 1185 end
yellowfive@57 1186 end
yellowfive@57 1187
yellowfive@57 1188 -- export equipped gear
yellowfive@57 1189 if data.Equipped then
yellowfive@81 1190 for spec = 1, 4 do
yellowfive@57 1191 if data.Equipped[spec] and (complete or spec == data.ActiveSpec) then
yellowfive@57 1192 table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block
yellowfive@57 1193
yellowfive@57 1194 local itemObjects = {}
yellowfive@57 1195 for k, v in pairs(data.Equipped[spec]) do
yellowfive@57 1196 local itemData = Amr.ParseItemLink(v)
yellowfive@57 1197 itemData.slot = k
yellowfive@81 1198 itemData.link = v
yellowfive@57 1199 table.insert(itemObjects, itemData)
yellowfive@57 1200 end
yellowfive@57 1201
yellowfive@57 1202 appendItemsToExport(fields, itemObjects)
yellowfive@57 1203 end
yellowfive@57 1204 end
yellowfive@57 1205 end
yellowfive@57 1206
yellowfive@57 1207 -- if doing a complete export, include reputations and bank/bag items too
yellowfive@57 1208 if complete then
yellowfive@57 1209
yellowfive@57 1210 -- export reputations
yellowfive@57 1211 local reps = {}
yellowfive@91 1212 table.insert(reps, "_")
yellowfive@91 1213 --[[
yellowfive@57 1214 local noreps = true
yellowfive@57 1215 if data.Reputations then
yellowfive@57 1216 for k, v in pairs(data.Reputations) do
yellowfive@57 1217 noreps = false
yellowfive@57 1218 table.insert(reps, k .. ":" .. v)
yellowfive@57 1219 end
yellowfive@57 1220 end
yellowfive@57 1221 if noreps then
yellowfive@57 1222 table.insert(reps, "_")
yellowfive@57 1223 end
yellowfive@91 1224 ]]
yellowfive@91 1225
yellowfive@57 1226 table.insert(fields, ".r")
yellowfive@57 1227 table.insert(fields, table.concat(reps, ","))
yellowfive@57 1228
yellowfive@57 1229 -- export bag and bank
yellowfive@57 1230 local itemObjects = {}
yellowfive@57 1231 if data.BagItems then
yellowfive@57 1232 for i, v in ipairs(data.BagItems) do
yellowfive@57 1233 local itemData = Amr.ParseItemLink(v)
yellowfive@85 1234 if itemData ~= nil --[[and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id])]] then
yellowfive@81 1235 itemData.link = v
yellowfive@57 1236 table.insert(itemObjects, itemData)
yellowfive@57 1237 end
yellowfive@57 1238 end
yellowfive@57 1239 end
yellowfive@57 1240 if data.BankItems then
yellowfive@57 1241 for i, v in ipairs(data.BankItems) do
yellowfive@57 1242 local itemData = Amr.ParseItemLink(v)
yellowfive@85 1243 if itemData ~= nil --[[and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id])]] then
yellowfive@81 1244 itemData.link = v
yellowfive@57 1245 table.insert(itemObjects, itemData)
yellowfive@57 1246 end
yellowfive@57 1247 end
yellowfive@57 1248 end
yellowfive@57 1249 if data.VoidItems then
yellowfive@57 1250 for i, v in ipairs(data.VoidItems) do
yellowfive@57 1251 local itemData = Amr.ParseItemLink(v)
yellowfive@85 1252 if itemData ~= nil --[[and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id])]] then
yellowfive@81 1253 itemData.link = v
yellowfive@57 1254 table.insert(itemObjects, itemData)
yellowfive@57 1255 end
yellowfive@57 1256 end
yellowfive@57 1257 end
yellowfive@57 1258
yellowfive@57 1259 table.insert(fields, ".inv")
yellowfive@57 1260 appendItemsToExport(fields, itemObjects)
yellowfive@57 1261 end
yellowfive@57 1262
yellowfive@57 1263 return "$" .. table.concat(fields, ";") .. "$"
yellowfive@57 1264
yellowfive@57 1265 end
yellowfive@57 1266
yellowfive@57 1267 -- Shortcut for the common use case: serialize the player's currently active setup with no extras.
yellowfive@57 1268 function Amr:SerializePlayer()
yellowfive@57 1269 local data = self:GetPlayerData()
yellowfive@57 1270 return self:SerializePlayerData(data)
yellowfive@57 1271 end
yellowfive@57 1272
yellowfive@81 1273 --[[
yellowfive@57 1274 ----------------------------------------------------------------------------------------------------------------------
yellowfive@57 1275 -- Character Snapshots
yellowfive@81 1276 -- This feature snapshots a player's gear/talents/artifact when entering combat. It is enabled by default. Consumers
yellowfive@57 1277 -- of this library can create a setting to enable/disable it as desired per a user setting.
yellowfive@57 1278 --
yellowfive@57 1279 -- You should register for the AMR_SNAPSHOT_STATE_CHANGED message (sent via AceEvent-3.0 messaging) to ensure that
yellowfive@57 1280 -- your addon settings stay in sync with any other addon that may also be trying to control the enabled state.
yellowfive@57 1281 --
yellowfive@57 1282 -- Note that if a user has the main AMR addon installed, it will always enable snapshotting, and override any attempt
yellowfive@57 1283 -- to disable it by immediately re-enabling it and thus re-triggering AMR_SNAPSHOT_STATE_CHANGED.
yellowfive@57 1284 ----------------------------------------------------------------------------------------------------------------------
yellowfive@57 1285 Amr._snapshotEnabled = true
yellowfive@57 1286
yellowfive@57 1287 -- Enable snapshotting of character data when entering combat. Sends this player's character data to anyone logging with the AskMrRobot addon.
yellowfive@57 1288 function Amr:EnableSnapshots()
yellowfive@57 1289 self._snapshotEnabled = true
yellowfive@57 1290 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
yellowfive@57 1291 end
yellowfive@57 1292
yellowfive@57 1293 -- Disable snapshotting of character data when entering combat.
yellowfive@57 1294 function Amr:DisableSnapshots()
yellowfive@57 1295 self._snapshotEnabled = false
yellowfive@57 1296 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
yellowfive@57 1297 end
yellowfive@57 1298
yellowfive@57 1299 function Amr:IsSnapshotEnabled()
yellowfive@57 1300 return self._snapshotEnabled
yellowfive@57 1301 end
yellowfive@57 1302
yellowfive@57 1303
yellowfive@57 1304 function Amr:PLAYER_REGEN_DISABLED()
yellowfive@57 1305 --function Amr:GARRISON_MISSION_NPC_OPENED()
yellowfive@57 1306
yellowfive@57 1307 -- send data about this character when a player enters combat in a supported zone
yellowfive@57 1308 if self._snapshotEnabled and Amr.IsSupportedInstance() then
yellowfive@57 1309 local t = time()
yellowfive@57 1310 local player = self:GetPlayerData()
yellowfive@57 1311 local msg = self:SerializePlayerData(player)
yellowfive@57 1312 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 1313
yellowfive@57 1314 self:SendCommMessage(Amr.ChatPrefix, msg, "RAID")
yellowfive@57 1315 end
yellowfive@57 1316 end
yellowfive@57 1317
yellowfive@57 1318 Amr:RegisterEvent("PLAYER_REGEN_DISABLED")
yellowfive@81 1319 --Amr:RegisterEvent("GARRISON_MISSION_NPC_OPENED") -- for debugging, fire this event when open mission table
yellowfive@81 1320 ]]