annotate AskMrRobot-Serializer/AskMrRobot-Serializer.lua @ 104:5bacf5c7c66d v48

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