yellowfive@57
|
1 -- AskMrRobot-Serializer will serialize and communicate character data between users.
|
yellowfive@57
|
2
|
yellowfive@131
|
3 local MAJOR, MINOR = "AskMrRobot-Serializer", 61
|
yellowfive@57
|
4 local Amr, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
yellowfive@57
|
5
|
yellowfive@57
|
6 if not Amr then return end -- already loaded by something else
|
yellowfive@57
|
7
|
yellowfive@57
|
8 -- event and comm used for player snapshotting on entering combat
|
yellowfive@57
|
9 LibStub("AceEvent-3.0"):Embed(Amr)
|
yellowfive@57
|
10 LibStub("AceComm-3.0"):Embed(Amr)
|
yellowfive@57
|
11
|
yellowfive@57
|
12 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
13 -- Constants
|
yellowfive@57
|
14 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
15
|
yellowfive@57
|
16 -- prefix used for communicating gear snapshots created by the AMR serializer
|
yellowfive@57
|
17 Amr.ChatPrefix = "_AMRS"
|
yellowfive@57
|
18
|
yellowfive@57
|
19 -- map of region ids to AMR region names
|
yellowfive@57
|
20 Amr.RegionNames = {
|
yellowfive@57
|
21 [1] = "US",
|
yellowfive@57
|
22 [2] = "KR",
|
yellowfive@57
|
23 [3] = "EU",
|
yellowfive@57
|
24 [4] = "TW",
|
yellowfive@57
|
25 [5] = "CN"
|
yellowfive@57
|
26 }
|
yellowfive@57
|
27
|
yellowfive@57
|
28 -- map of the skillLine returned by profession API to the AMR profession name
|
yellowfive@57
|
29 Amr.ProfessionSkillLineToName = {
|
yellowfive@57
|
30 [794] = "Archaeology",
|
yellowfive@57
|
31 [171] = "Alchemy",
|
yellowfive@57
|
32 [164] = "Blacksmithing",
|
yellowfive@57
|
33 [185] = "Cooking",
|
yellowfive@57
|
34 [333] = "Enchanting",
|
yellowfive@57
|
35 [202] = "Engineering",
|
yellowfive@57
|
36 [129] = "First Aid",
|
yellowfive@57
|
37 [356] = "Fishing",
|
yellowfive@57
|
38 [182] = "Herbalism",
|
yellowfive@57
|
39 [773] = "Inscription",
|
yellowfive@57
|
40 [755] = "Jewelcrafting",
|
yellowfive@57
|
41 [165] = "Leatherworking",
|
yellowfive@57
|
42 [186] = "Mining",
|
yellowfive@57
|
43 [393] = "Skinning",
|
yellowfive@57
|
44 [197] = "Tailoring"
|
yellowfive@57
|
45 }
|
yellowfive@57
|
46
|
yellowfive@57
|
47 -- all slot IDs that we care about, ordered in AMR standard display order
|
yellowfive@57
|
48 Amr.SlotIds = { 16, 17, 1, 2, 3, 15, 5, 9, 10, 6, 7, 8, 11, 12, 13, 14 }
|
yellowfive@57
|
49
|
yellowfive@57
|
50 Amr.SpecIds = {
|
yellowfive@57
|
51 [250] = 1, -- DeathKnightBlood
|
yellowfive@57
|
52 [251] = 2, -- DeathKnightFrost
|
yellowfive@57
|
53 [252] = 3, -- DeathKnightUnholy
|
yellowfive@81
|
54 [577] = 4, -- DemonHunterHavoc
|
yellowfive@81
|
55 [581] = 5, -- DemonHunterVengeance
|
yellowfive@81
|
56 [102] = 6, -- DruidBalance
|
yellowfive@81
|
57 [103] = 7, -- DruidFeral
|
yellowfive@81
|
58 [104] = 8, -- DruidGuardian
|
yellowfive@81
|
59 [105] = 9, -- DruidRestoration
|
yellowfive@81
|
60 [253] = 10, -- HunterBeastMastery
|
yellowfive@81
|
61 [254] = 11, -- HunterMarksmanship
|
yellowfive@81
|
62 [255] = 12, -- HunterSurvival
|
yellowfive@81
|
63 [62] = 13, -- MageArcane
|
yellowfive@81
|
64 [63] = 14, -- MageFire
|
yellowfive@81
|
65 [64] = 15, -- MageFrost
|
yellowfive@81
|
66 [268] = 16, -- MonkBrewmaster
|
yellowfive@81
|
67 [270] = 17, -- MonkMistweaver
|
yellowfive@81
|
68 [269] = 18, -- MonkWindwalker
|
yellowfive@81
|
69 [65] = 19, -- PaladinHoly
|
yellowfive@81
|
70 [66] = 20, -- PaladinProtection
|
yellowfive@81
|
71 [70] = 21, -- PaladinRetribution
|
yellowfive@81
|
72 [256] = 22, -- PriestDiscipline
|
yellowfive@81
|
73 [257] = 23, -- PriestHoly
|
yellowfive@81
|
74 [258] = 24, -- PriestShadow
|
yellowfive@81
|
75 [259] = 25, -- RogueAssassination
|
yellowfive@81
|
76 [260] = 26, -- RogueOutlaw
|
yellowfive@81
|
77 [261] = 27, -- RogueSubtlety
|
yellowfive@81
|
78 [262] = 28, -- ShamanElemental
|
yellowfive@81
|
79 [263] = 29, -- ShamanEnhancement
|
yellowfive@81
|
80 [264] = 30, -- ShamanRestoration
|
yellowfive@81
|
81 [265] = 31, -- WarlockAffliction
|
yellowfive@81
|
82 [266] = 32, -- WarlockDemonology
|
yellowfive@81
|
83 [267] = 33, -- WarlockDestruction
|
yellowfive@81
|
84 [71] = 34, -- WarriorArms
|
yellowfive@81
|
85 [72] = 35, -- WarriorFury
|
yellowfive@81
|
86 [73] = 36 -- WarriorProtection
|
yellowfive@57
|
87 }
|
yellowfive@57
|
88
|
yellowfive@57
|
89 Amr.ClassIds = {
|
yellowfive@57
|
90 ["NONE"] = 0,
|
yellowfive@57
|
91 ["DEATHKNIGHT"] = 1,
|
yellowfive@81
|
92 ["DEMONHUNTER"] = 2,
|
yellowfive@81
|
93 ["DRUID"] = 3,
|
yellowfive@81
|
94 ["HUNTER"] = 4,
|
yellowfive@81
|
95 ["MAGE"] = 5,
|
yellowfive@81
|
96 ["MONK"] = 6,
|
yellowfive@81
|
97 ["PALADIN"] = 7,
|
yellowfive@81
|
98 ["PRIEST"] = 8,
|
yellowfive@81
|
99 ["ROGUE"] = 9,
|
yellowfive@81
|
100 ["SHAMAN"] = 10,
|
yellowfive@81
|
101 ["WARLOCK"] = 11,
|
yellowfive@81
|
102 ["WARRIOR"] = 12,
|
yellowfive@57
|
103 }
|
yellowfive@57
|
104
|
yellowfive@57
|
105 Amr.ProfessionIds = {
|
yellowfive@57
|
106 ["None"] = 0,
|
yellowfive@57
|
107 ["Mining"] = 1,
|
yellowfive@57
|
108 ["Skinning"] = 2,
|
yellowfive@57
|
109 ["Herbalism"] = 3,
|
yellowfive@57
|
110 ["Enchanting"] = 4,
|
yellowfive@57
|
111 ["Jewelcrafting"] = 5,
|
yellowfive@57
|
112 ["Engineering"] = 6,
|
yellowfive@57
|
113 ["Blacksmithing"] = 7,
|
yellowfive@57
|
114 ["Leatherworking"] = 8,
|
yellowfive@57
|
115 ["Inscription"] = 9,
|
yellowfive@57
|
116 ["Tailoring"] = 10,
|
yellowfive@57
|
117 ["Alchemy"] = 11,
|
yellowfive@57
|
118 ["Fishing"] = 12,
|
yellowfive@57
|
119 ["Cooking"] = 13,
|
yellowfive@57
|
120 ["First Aid"] = 14,
|
yellowfive@57
|
121 ["Archaeology"] = 15
|
yellowfive@57
|
122 }
|
yellowfive@57
|
123
|
yellowfive@57
|
124 Amr.RaceIds = {
|
yellowfive@57
|
125 ["None"] = 0,
|
yellowfive@57
|
126 ["BloodElf"] = 1,
|
yellowfive@57
|
127 ["Draenei"] = 2,
|
yellowfive@57
|
128 ["Dwarf"] = 3,
|
yellowfive@57
|
129 ["Gnome"] = 4,
|
yellowfive@57
|
130 ["Human"] = 5,
|
yellowfive@57
|
131 ["NightElf"] = 6,
|
yellowfive@57
|
132 ["Orc"] = 7,
|
yellowfive@57
|
133 ["Tauren"] = 8,
|
yellowfive@57
|
134 ["Troll"] = 9,
|
yellowfive@57
|
135 ["Scourge"] = 10,
|
yellowfive@57
|
136 ["Undead"] = 10,
|
yellowfive@57
|
137 ["Goblin"] = 11,
|
yellowfive@57
|
138 ["Worgen"] = 12,
|
yellowfive@120
|
139 ["Pandaren"] = 13,
|
yellowfive@120
|
140 ["Nightborne"] = 14,
|
yellowfive@120
|
141 ["HighmountainTauren"] = 15,
|
yellowfive@120
|
142 ["VoidElf"] = 16,
|
yellowfive@120
|
143 ["LightforgedDraenei"] = 17
|
yellowfive@57
|
144 }
|
yellowfive@57
|
145
|
yellowfive@57
|
146 Amr.FactionIds = {
|
yellowfive@57
|
147 ["None"] = 0,
|
yellowfive@57
|
148 ["Alliance"] = 1,
|
yellowfive@57
|
149 ["Horde"] = 2
|
yellowfive@57
|
150 }
|
yellowfive@57
|
151
|
yellowfive@57
|
152 Amr.InstanceIds = {
|
yellowfive@93
|
153 EmeraldNightmare = 1520,
|
yellowfive@104
|
154 Nighthold = 1530,
|
yellowfive@110
|
155 TrialOfValor = 1648,
|
yellowfive@118
|
156 TombOfSargeras = 1676,
|
yellowfive@118
|
157 Antorus = 1712
|
yellowfive@57
|
158 }
|
yellowfive@57
|
159
|
yellowfive@57
|
160 -- instances that AskMrRobot currently supports logging for
|
yellowfive@57
|
161 Amr.SupportedInstanceIds = {
|
yellowfive@93
|
162 [1520] = true,
|
yellowfive@104
|
163 [1530] = true,
|
yellowfive@110
|
164 [1648] = true,
|
yellowfive@118
|
165 [1676] = true,
|
yellowfive@118
|
166 [1712] = true
|
yellowfive@57
|
167 }
|
yellowfive@57
|
168
|
yellowfive@57
|
169
|
yellowfive@57
|
170 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
171 -- Public Utility Methods
|
yellowfive@57
|
172 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
173
|
yellowfive@81
|
174 local function readBonusIdList(parts, first, last)
|
yellowfive@124
|
175 local ret = {}
|
yellowfive@81
|
176 for i = first, last do
|
yellowfive@81
|
177 table.insert(ret, tonumber(parts[i]))
|
yellowfive@81
|
178 end
|
yellowfive@81
|
179 table.sort(ret)
|
yellowfive@81
|
180 return ret
|
yellowfive@81
|
181 end
|
yellowfive@81
|
182
|
yellowfive@124
|
183 -- 1 2 3 4 5 6 7 8 9 10 11 12
|
yellowfive@124
|
184 -- itemId:ench:gem1 :gem2 :gem3 :gem4:suf:uid:lvl:spec:flags :instdiffid:numbonusIDs:bonusIDs1...n :varies:?:relic bonus ids
|
yellowfive@124
|
185 --|cffe6cc80|Hitem:128866: :152046:147100:152025: : : :110:66 :16777472:9 :4 :736:1494:1490:1495:709 :1:3:3610:1472:3528:3:3562:1483:3528:3:3610:1477:3336|h[Truthguard]|h|r
|
yellowfive@124
|
186 --
|
yellowfive@57
|
187 -- get an object with all of the parts of the item link format that we care about
|
yellowfive@57
|
188 function Amr.ParseItemLink(itemLink)
|
yellowfive@57
|
189 if not itemLink then return nil end
|
yellowfive@57
|
190
|
yellowfive@57
|
191 local str = string.match(itemLink, "|Hitem:([\-%d:]+)|")
|
yellowfive@57
|
192 if not str then return nil end
|
yellowfive@57
|
193
|
yellowfive@57
|
194 local parts = { strsplit(":", str) }
|
yellowfive@57
|
195
|
yellowfive@124
|
196 local item = {}
|
yellowfive@124
|
197 item.link = itemLink
|
yellowfive@81
|
198 item.id = tonumber(parts[1]) or 0
|
yellowfive@81
|
199 item.enchantId = tonumber(parts[2]) or 0
|
yellowfive@81
|
200 item.gemIds = { tonumber(parts[3]) or 0, tonumber(parts[4]) or 0, tonumber(parts[5]) or 0, tonumber(parts[6]) or 0 }
|
yellowfive@81
|
201 item.suffixId = math.abs(tonumber(parts[7]) or 0) -- convert suffix to positive number, that's what we use in our code
|
yellowfive@81
|
202 -- part 8 is some unique ID... we never really used it
|
yellowfive@81
|
203 -- part 9 is current player level
|
yellowfive@81
|
204 -- part 10 is player spec
|
yellowfive@81
|
205 local upgradeIdType = tonumber(parts[11]) or 0 -- part 11 indicates what kind of upgrade ID is just after the bonus IDs
|
yellowfive@81
|
206 -- part 12 is instance difficulty id
|
yellowfive@57
|
207
|
yellowfive@81
|
208 local numBonuses = tonumber(parts[13]) or 0
|
yellowfive@81
|
209 local offset = numBonuses
|
yellowfive@81
|
210 if numBonuses > 0 then
|
yellowfive@81
|
211 item.bonusIds = readBonusIdList(parts, 14, 13 + numBonuses)
|
yellowfive@57
|
212 end
|
yellowfive@69
|
213
|
yellowfive@81
|
214 item.upgradeId = 0
|
yellowfive@81
|
215 item.level = 0
|
yellowfive@81
|
216
|
yellowfive@124
|
217 -- the next part after bonus IDs depends on the upgrade id type
|
yellowfive@81
|
218 if upgradeIdType == 4 then
|
yellowfive@81
|
219 item.upgradeId = tonumber(parts[14 + offset]) or 0
|
yellowfive@81
|
220 elseif upgradeIdType == 512 then
|
yellowfive@81
|
221 item.level = tonumber(parts[14 + offset]) or 0
|
yellowfive@124
|
222 elseif #parts > 16 + offset then
|
yellowfive@124
|
223 -- check for relic info
|
yellowfive@124
|
224 item.relicBonusIds = { nil, nil, nil }
|
yellowfive@124
|
225 numBonuses = tonumber(parts[16 + offset])
|
yellowfive@124
|
226 if numBonuses then
|
yellowfive@124
|
227 if numBonuses > 0 then
|
yellowfive@124
|
228 item.relicBonusIds[1] = readBonusIdList(parts, 17 + offset, 16 + offset + numBonuses)
|
yellowfive@124
|
229 end
|
yellowfive@124
|
230
|
yellowfive@129
|
231 offset = offset + numBonuses
|
yellowfive@124
|
232 if #parts > 17 + offset then
|
yellowfive@124
|
233 numBonuses = tonumber(parts[17 + offset])
|
yellowfive@129
|
234 if numBonuses then
|
yellowfive@129
|
235 if numBonuses > 0 then
|
yellowfive@129
|
236 item.relicBonusIds[2] = readBonusIdList(parts, 18 + offset, 17 + offset + numBonuses)
|
yellowfive@129
|
237 end
|
yellowfive@129
|
238
|
yellowfive@129
|
239 offset= offset + numBonuses
|
yellowfive@129
|
240 if #parts > 18 + offset then
|
yellowfive@129
|
241 numBonuses = tonumber(parts[18 + offset])
|
yellowfive@129
|
242 if numBonuses then
|
yellowfive@129
|
243 if numBonuses > 0 then
|
yellowfive@129
|
244 item.relicBonusIds[3] = readBonusIdList(parts, 19 + offset, 18 + offset + numBonuses)
|
yellowfive@129
|
245 end
|
yellowfive@129
|
246 end
|
yellowfive@129
|
247 end
|
yellowfive@124
|
248 end
|
yellowfive@124
|
249 end
|
yellowfive@124
|
250 end
|
yellowfive@69
|
251 end
|
yellowfive@81
|
252
|
yellowfive@57
|
253 return item
|
yellowfive@57
|
254 end
|
yellowfive@57
|
255
|
yellowfive@81
|
256 function Amr.GetItemUniqueId(item, noUpgrade)
|
yellowfive@81
|
257 if not item then return "" end
|
yellowfive@81
|
258 local ret = item.id .. ""
|
yellowfive@81
|
259 if item.bonusIds then
|
yellowfive@81
|
260 for i = 1, #item.bonusIds do
|
yellowfive@81
|
261 ret = ret .. "b" .. item.bonusIds[i]
|
yellowfive@81
|
262 end
|
yellowfive@81
|
263 end
|
yellowfive@81
|
264 if item.suffixId ~= 0 then
|
yellowfive@81
|
265 ret = ret .. "s" .. item.suffixId
|
yellowfive@81
|
266 end
|
yellowfive@81
|
267 if not noUpgrade and item.upgradeId ~= 0 then
|
yellowfive@81
|
268 ret = ret .. "u" .. item.upgradeId
|
yellowfive@81
|
269 end
|
yellowfive@81
|
270 if item.level ~= 0 then
|
yellowfive@81
|
271 ret = ret .. "v" .. item.level
|
yellowfive@81
|
272 end
|
yellowfive@81
|
273 return ret
|
yellowfive@81
|
274 end
|
yellowfive@81
|
275
|
yellowfive@57
|
276 -- returns true if this is an instance that AskMrRobot supports for logging
|
yellowfive@57
|
277 function Amr.IsSupportedInstanceId(instanceMapID)
|
yellowfive@57
|
278 if Amr.SupportedInstanceIds[tonumber(instanceMapID)] then
|
yellowfive@57
|
279 return true
|
yellowfive@57
|
280 else
|
yellowfive@57
|
281 return false
|
yellowfive@57
|
282 end
|
yellowfive@57
|
283 end
|
yellowfive@57
|
284
|
yellowfive@57
|
285 -- returns true if currently in a supported instance for logging
|
yellowfive@57
|
286 function Amr.IsSupportedInstance()
|
yellowfive@57
|
287 local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo()
|
yellowfive@57
|
288 return Amr.IsSupportedInstanceId(instanceMapID)
|
yellowfive@57
|
289 end
|
yellowfive@57
|
290
|
yellowfive@81
|
291 -- helper to iterate over a table in order by its keys
|
yellowfive@81
|
292 local function spairs(t, order)
|
yellowfive@81
|
293 -- collect the keys
|
yellowfive@81
|
294 local keys = {}
|
yellowfive@81
|
295 for k in pairs(t) do keys[#keys+1] = k end
|
yellowfive@81
|
296
|
yellowfive@81
|
297 -- if order function given, sort by it by passing the table and keys a, b,
|
yellowfive@81
|
298 -- otherwise just sort the keys
|
yellowfive@81
|
299 if order then
|
yellowfive@81
|
300 table.sort(keys, function(a,b) return order(t, a, b) end)
|
yellowfive@81
|
301 else
|
yellowfive@81
|
302 table.sort(keys)
|
yellowfive@81
|
303 end
|
yellowfive@81
|
304
|
yellowfive@81
|
305 -- return the iterator function
|
yellowfive@81
|
306 local i = 0
|
yellowfive@81
|
307 return function()
|
yellowfive@81
|
308 i = i + 1
|
yellowfive@81
|
309 if keys[i] then
|
yellowfive@81
|
310 return keys[i], t[keys[i]]
|
yellowfive@81
|
311 end
|
yellowfive@81
|
312 end
|
yellowfive@81
|
313 end
|
yellowfive@81
|
314
|
yellowfive@81
|
315 -- scanning tooltip b/c for some odd reason the api has no way to get basic item properties...
|
yellowfive@81
|
316 -- so you have to generate a fake item tooltip and search for pre-defined strings in the display text
|
yellowfive@81
|
317 local _scanTt
|
yellowfive@81
|
318 function Amr.GetScanningTooltip()
|
yellowfive@81
|
319 if not _scanTt then
|
yellowfive@81
|
320 _scanTt = CreateFrame("GameTooltip", "AmrUiScanTooltip", nil, "GameTooltipTemplate")
|
yellowfive@81
|
321 _scanTt:SetOwner(UIParent, "ANCHOR_NONE")
|
yellowfive@81
|
322 end
|
yellowfive@81
|
323 return _scanTt
|
yellowfive@81
|
324 end
|
yellowfive@81
|
325
|
yellowfive@81
|
326 -- 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
|
327 function Amr.GetItemTooltip(bagId, slotId, link)
|
yellowfive@81
|
328 local tt = Amr.GetScanningTooltip()
|
yellowfive@81
|
329 tt:ClearLines()
|
yellowfive@81
|
330 if bagId then
|
yellowfive@81
|
331 tt:SetBagItem(bagId, slotId)
|
yellowfive@81
|
332 elseif slotId then
|
yellowfive@81
|
333 tt:SetInventoryItem("player", slotId)
|
yellowfive@81
|
334 else
|
yellowfive@81
|
335 tt:SetHyperlink(link)
|
yellowfive@81
|
336 end
|
yellowfive@81
|
337 return tt
|
yellowfive@81
|
338 end
|
yellowfive@81
|
339
|
yellowfive@124
|
340 function Amr.GetItemLevel(bagId, slotId, link)
|
yellowfive@81
|
341 local itemLevelPattern = _G["ITEM_LEVEL"]:gsub("%%d", "(%%d+)")
|
yellowfive@81
|
342 local tt = Amr.GetItemTooltip(bagId, slotId, link)
|
yellowfive@81
|
343
|
yellowfive@81
|
344 local regions = { tt:GetRegions() }
|
yellowfive@81
|
345 for i, region in ipairs(regions) do
|
yellowfive@81
|
346 if region and region:GetObjectType() == "FontString" then
|
yellowfive@81
|
347 local text = region:GetText()
|
yellowfive@81
|
348 if text then
|
yellowfive@81
|
349 ilvl = tonumber(text:match(itemLevelPattern))
|
yellowfive@81
|
350 if ilvl then
|
yellowfive@81
|
351 return ilvl
|
yellowfive@81
|
352 end
|
yellowfive@81
|
353 end
|
yellowfive@81
|
354 end
|
yellowfive@81
|
355 end
|
yellowfive@81
|
356
|
yellowfive@81
|
357 -- 0 means we couldn't find it for whatever reason
|
yellowfive@81
|
358 return 0
|
yellowfive@81
|
359 end
|
yellowfive@81
|
360
|
yellowfive@57
|
361
|
yellowfive@57
|
362 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
363 -- Character Reading
|
yellowfive@57
|
364 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
365
|
yellowfive@57
|
366 local function readProfessionInfo(prof, ret)
|
yellowfive@57
|
367 if prof then
|
yellowfive@57
|
368 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof);
|
yellowfive@57
|
369 if Amr.ProfessionSkillLineToName[skillLine] ~= nil then
|
yellowfive@57
|
370 ret.Professions[Amr.ProfessionSkillLineToName[skillLine]] = skillLevel;
|
yellowfive@57
|
371 end
|
yellowfive@57
|
372 end
|
yellowfive@57
|
373 end
|
yellowfive@57
|
374
|
yellowfive@124
|
375 -- get specs
|
yellowfive@81
|
376 local function readSpecs(ret)
|
yellowfive@57
|
377
|
yellowfive@81
|
378 for pos = 1, 4 do
|
yellowfive@57
|
379 -- spec, convert game spec id to one of our spec ids
|
yellowfive@81
|
380 local specId = GetSpecializationInfo(pos)
|
yellowfive@57
|
381 if specId then
|
yellowfive@81
|
382 ret.Specs[pos] = Amr.SpecIds[specId]
|
yellowfive@57
|
383 end
|
yellowfive@57
|
384 end
|
yellowfive@57
|
385 end
|
yellowfive@57
|
386
|
yellowfive@124
|
387 local function dump(o)
|
yellowfive@124
|
388 if type(o) == 'table' then
|
yellowfive@124
|
389 local s = '{ '
|
yellowfive@124
|
390 for k,v in pairs(o) do
|
yellowfive@124
|
391 if type(k) ~= 'number' then k = '"'..k..'"' end
|
yellowfive@124
|
392 s = s .. '['..k..'] = ' .. dump(v) .. ','
|
yellowfive@124
|
393 end
|
yellowfive@124
|
394 return s .. '} '
|
yellowfive@124
|
395 else
|
yellowfive@124
|
396 return tostring(o)
|
yellowfive@124
|
397 end
|
yellowfive@124
|
398 end
|
yellowfive@124
|
399
|
yellowfive@124
|
400 -- read azerite powers on the item in loc and put it on itemData
|
yellowfive@124
|
401 function Amr.ReadAzeritePowers(loc)
|
yellowfive@124
|
402 local ret = {}
|
yellowfive@124
|
403 local hasSome = false
|
yellowfive@124
|
404
|
yellowfive@124
|
405 local tiers = C_AzeriteEmpoweredItem.GetAllTierInfo(loc)
|
yellowfive@124
|
406 for tier, tierInfo in ipairs(tiers) do
|
yellowfive@124
|
407 for _, power in ipairs(tierInfo.azeritePowerIDs) do
|
yellowfive@124
|
408 if C_AzeriteEmpoweredItem.IsPowerSelected(loc, power) then
|
yellowfive@124
|
409 local powerInfo = C_AzeriteEmpoweredItem.GetPowerInfo(power)
|
yellowfive@124
|
410 table.insert(ret, powerInfo.spellID)
|
yellowfive@124
|
411 hasSome = true
|
yellowfive@124
|
412 end
|
yellowfive@124
|
413 end
|
yellowfive@124
|
414 end
|
yellowfive@124
|
415
|
yellowfive@124
|
416 if hasSome then
|
yellowfive@124
|
417 return ret
|
yellowfive@124
|
418 else
|
yellowfive@124
|
419 return nil
|
yellowfive@124
|
420 end
|
yellowfive@124
|
421 end
|
yellowfive@124
|
422
|
yellowfive@57
|
423 -- get currently equipped items, store with currently active spec
|
yellowfive@57
|
424 local function readEquippedItems(ret)
|
yellowfive@124
|
425 local equippedItems = {};
|
yellowfive@124
|
426 local loc = ItemLocation.CreateEmpty()
|
yellowfive@57
|
427 for slotNum = 1, #Amr.SlotIds do
|
yellowfive@57
|
428 local slotId = Amr.SlotIds[slotNum]
|
yellowfive@57
|
429 local itemLink = GetInventoryItemLink("player", slotId)
|
yellowfive@57
|
430 if itemLink then
|
yellowfive@124
|
431 local itemData = Amr.ParseItemLink(itemLink)
|
yellowfive@124
|
432 if itemData then
|
yellowfive@124
|
433 -- see if this is an azerite item and read azerite power ids
|
yellowfive@124
|
434 loc:SetEquipmentSlot(slotId)
|
yellowfive@124
|
435 if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then
|
yellowfive@124
|
436 local powers = Amr.ReadAzeritePowers(loc)
|
yellowfive@124
|
437 if powers then
|
yellowfive@124
|
438 itemData.azerite = powers
|
yellowfive@124
|
439 end
|
yellowfive@124
|
440 end
|
yellowfive@124
|
441
|
yellowfive@124
|
442 equippedItems[slotId] = itemData
|
yellowfive@124
|
443 end
|
yellowfive@57
|
444 end
|
yellowfive@57
|
445 end
|
yellowfive@57
|
446
|
yellowfive@57
|
447 -- store last-seen equipped gear for each spec
|
yellowfive@81
|
448 ret.Equipped[GetSpecialization()] = equippedItems
|
yellowfive@57
|
449 end
|
yellowfive@57
|
450
|
yellowfive@124
|
451 local function readHeartOfAzerothLevel(ret)
|
yellowfive@124
|
452 local azeriteItemLocation = C_AzeriteItem.FindActiveAzeriteItem();
|
yellowfive@124
|
453 if azeriteItemLocation then
|
yellowfive@124
|
454 local azeriteItem = Item:CreateFromItemLocation(azeriteItemLocation);
|
yellowfive@124
|
455 ret.HeartOfAzerothLevel = C_AzeriteItem.GetPowerLevel(azeriteItemLocation)
|
yellowfive@124
|
456 else
|
yellowfive@124
|
457 ret.HeartOfAzerothLevel = 0
|
yellowfive@124
|
458 end
|
yellowfive@124
|
459 end
|
yellowfive@124
|
460
|
yellowfive@124
|
461 -- Get just the player's currently equipped gear
|
yellowfive@124
|
462 function Amr:GetEquipped()
|
yellowfive@124
|
463 local ret= {}
|
yellowfive@124
|
464 ret.Equipped = {}
|
yellowfive@124
|
465 readEquippedItems(ret)
|
yellowfive@124
|
466 return ret
|
yellowfive@124
|
467 end
|
yellowfive@124
|
468
|
yellowfive@57
|
469 -- Get all data about the player as an object, includes:
|
yellowfive@57
|
470 -- serializer version
|
yellowfive@57
|
471 -- region/realm/name
|
yellowfive@57
|
472 -- guild
|
yellowfive@57
|
473 -- race
|
yellowfive@57
|
474 -- faction
|
yellowfive@57
|
475 -- level
|
yellowfive@57
|
476 -- professions
|
yellowfive@81
|
477 -- spec/talent for all specs
|
yellowfive@57
|
478 -- equipped gear for the current spec
|
yellowfive@57
|
479 --
|
yellowfive@81
|
480 function Amr:GetPlayerData()
|
yellowfive@57
|
481
|
yellowfive@57
|
482 local ret = {}
|
yellowfive@57
|
483
|
yellowfive@57
|
484 ret.Region = Amr.RegionNames[GetCurrentRegion()]
|
yellowfive@57
|
485 ret.Realm = GetRealmName()
|
yellowfive@57
|
486 ret.Name = UnitName("player")
|
yellowfive@57
|
487 ret.Guild = GetGuildInfo("player")
|
yellowfive@81
|
488 ret.ActiveSpec = GetSpecialization()
|
yellowfive@57
|
489 ret.Level = UnitLevel("player");
|
yellowfive@124
|
490 readHeartOfAzerothLevel(ret)
|
yellowfive@124
|
491
|
yellowfive@57
|
492 local cls, clsEn = UnitClass("player")
|
yellowfive@57
|
493 ret.Class = clsEn;
|
yellowfive@57
|
494
|
yellowfive@57
|
495 local race, raceEn = UnitRace("player")
|
yellowfive@57
|
496 ret.Race = raceEn;
|
yellowfive@57
|
497 ret.Faction = UnitFactionGroup("player")
|
yellowfive@57
|
498
|
yellowfive@57
|
499 ret.Professions = {};
|
yellowfive@57
|
500 local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions();
|
yellowfive@57
|
501 readProfessionInfo(prof1, ret)
|
yellowfive@57
|
502 readProfessionInfo(prof2, ret)
|
yellowfive@57
|
503 readProfessionInfo(archaeology, ret)
|
yellowfive@57
|
504 readProfessionInfo(fishing, ret)
|
yellowfive@57
|
505 readProfessionInfo(cooking, ret)
|
yellowfive@57
|
506 readProfessionInfo(firstAid, ret)
|
yellowfive@57
|
507
|
yellowfive@57
|
508 ret.Specs = {}
|
yellowfive@57
|
509 ret.Talents = {}
|
yellowfive@81
|
510 readSpecs(ret)
|
yellowfive@81
|
511
|
yellowfive@124
|
512 ret.Equipped = {}
|
yellowfive@57
|
513 readEquippedItems(ret)
|
yellowfive@57
|
514
|
yellowfive@57
|
515 return ret
|
yellowfive@57
|
516 end
|
yellowfive@57
|
517
|
yellowfive@57
|
518
|
yellowfive@57
|
519 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
520 -- Serialization
|
yellowfive@57
|
521 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
522
|
yellowfive@57
|
523 local function toCompressedNumberList(list)
|
yellowfive@57
|
524 -- ensure the values are numbers, sorted from lowest to highest
|
yellowfive@57
|
525 local nums = {}
|
yellowfive@57
|
526 for i, v in ipairs(list) do
|
yellowfive@57
|
527 table.insert(nums, tonumber(v))
|
yellowfive@57
|
528 end
|
yellowfive@57
|
529 table.sort(nums)
|
yellowfive@57
|
530
|
yellowfive@57
|
531 local ret = {}
|
yellowfive@57
|
532 local prev = 0
|
yellowfive@57
|
533 for i, v in ipairs(nums) do
|
yellowfive@57
|
534 local diff = v - prev
|
yellowfive@57
|
535 table.insert(ret, diff)
|
yellowfive@57
|
536 prev = v
|
yellowfive@57
|
537 end
|
yellowfive@57
|
538
|
yellowfive@57
|
539 return table.concat(ret, ",")
|
yellowfive@57
|
540 end
|
yellowfive@57
|
541
|
yellowfive@57
|
542 -- make this utility publicly available
|
yellowfive@57
|
543 function Amr:ToCompressedNumberList(list)
|
yellowfive@57
|
544 return toCompressedNumberList(list)
|
yellowfive@57
|
545 end
|
yellowfive@57
|
546
|
yellowfive@57
|
547 -- appends a list of items to the export
|
yellowfive@57
|
548 local function appendItemsToExport(fields, itemObjects)
|
yellowfive@57
|
549
|
yellowfive@57
|
550 -- sort by item id so we can compress it more easily
|
yellowfive@57
|
551 table.sort(itemObjects, function(a, b) return a.id < b.id end)
|
yellowfive@57
|
552
|
yellowfive@57
|
553 -- append to the export string
|
yellowfive@57
|
554 local prevItemId = 0
|
yellowfive@57
|
555 local prevGemId = 0
|
yellowfive@57
|
556 local prevEnchantId = 0
|
yellowfive@57
|
557 local prevUpgradeId = 0
|
yellowfive@57
|
558 local prevBonusId = 0
|
yellowfive@81
|
559 local prevLevel = 0
|
yellowfive@124
|
560 local prevAzeriteId = 0
|
yellowfive@124
|
561 local prevRelicBonusId = 0
|
yellowfive@57
|
562 for i, itemData in ipairs(itemObjects) do
|
yellowfive@57
|
563 local itemParts = {}
|
yellowfive@57
|
564
|
yellowfive@57
|
565 table.insert(itemParts, itemData.id - prevItemId)
|
yellowfive@57
|
566 prevItemId = itemData.id
|
yellowfive@57
|
567
|
yellowfive@57
|
568 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end
|
yellowfive@124
|
569 --if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end
|
yellowfive@57
|
570 if itemData.upgradeId ~= 0 then
|
yellowfive@57
|
571 table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId))
|
yellowfive@57
|
572 prevUpgradeId = itemData.upgradeId
|
yellowfive@57
|
573 end
|
yellowfive@81
|
574 if itemData.level ~= 0 then
|
yellowfive@81
|
575 table.insert(itemParts, "v" .. (itemData.level - prevLevel))
|
yellowfive@81
|
576 prevLevel = itemData.level
|
yellowfive@81
|
577 end
|
yellowfive@57
|
578 if itemData.bonusIds then
|
yellowfive@57
|
579 for bIndex, bValue in ipairs(itemData.bonusIds) do
|
yellowfive@57
|
580 table.insert(itemParts, "b" .. (bValue - prevBonusId))
|
yellowfive@57
|
581 prevBonusId = bValue
|
yellowfive@57
|
582 end
|
yellowfive@124
|
583 end
|
yellowfive@124
|
584
|
yellowfive@124
|
585 if itemData.azerite then
|
yellowfive@124
|
586 for aIndex, aValue in ipairs(itemData.azerite) do
|
yellowfive@124
|
587 table.insert(itemParts, "a" .. (aValue - prevAzeriteId))
|
yellowfive@124
|
588 prevAzeriteId = aValue
|
yellowfive@124
|
589 end
|
yellowfive@124
|
590 end
|
yellowfive@81
|
591
|
yellowfive@81
|
592 if itemData.gemIds[1] ~= 0 then
|
yellowfive@81
|
593 table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId))
|
yellowfive@81
|
594 prevGemId = itemData.gemIds[1]
|
yellowfive@81
|
595 end
|
yellowfive@81
|
596 if itemData.gemIds[2] ~= 0 then
|
yellowfive@81
|
597 table.insert(itemParts, "y" .. (itemData.gemIds[2] - prevGemId))
|
yellowfive@81
|
598 prevGemId = itemData.gemIds[2]
|
yellowfive@81
|
599 end
|
yellowfive@81
|
600 if itemData.gemIds[3] ~= 0 then
|
yellowfive@81
|
601 table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId))
|
yellowfive@81
|
602 prevGemId = itemData.gemIds[3]
|
yellowfive@124
|
603 end
|
yellowfive@81
|
604
|
yellowfive@57
|
605 if itemData.enchantId ~= 0 then
|
yellowfive@57
|
606 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId))
|
yellowfive@57
|
607 prevEnchantId = itemData.enchantId
|
yellowfive@57
|
608 end
|
yellowfive@124
|
609
|
yellowfive@124
|
610 if itemData.relicBonusIds and itemData.relicBonusIds[1] ~= nil then
|
yellowfive@124
|
611 for bIndex, bValue in ipairs(itemData.relicBonusIds[1]) do
|
yellowfive@124
|
612 table.insert(itemParts, "p" .. (bValue - prevRelicBonusId))
|
yellowfive@124
|
613 prevRelicBonusId = bValue
|
yellowfive@124
|
614 end
|
yellowfive@124
|
615 end
|
yellowfive@124
|
616
|
yellowfive@124
|
617 if itemData.relicBonusIds and itemData.relicBonusIds[2] ~= nil then
|
yellowfive@124
|
618 for bIndex, bValue in ipairs(itemData.relicBonusIds[2]) do
|
yellowfive@124
|
619 table.insert(itemParts, "q" .. (bValue - prevRelicBonusId))
|
yellowfive@124
|
620 prevRelicBonusId = bValue
|
yellowfive@124
|
621 end
|
yellowfive@124
|
622 end
|
yellowfive@124
|
623
|
yellowfive@124
|
624 if itemData.relicBonusIds and itemData.relicBonusIds[3] ~= nil then
|
yellowfive@124
|
625 for bIndex, bValue in ipairs(itemData.relicBonusIds[3]) do
|
yellowfive@124
|
626 table.insert(itemParts, "r" .. (bValue - prevRelicBonusId))
|
yellowfive@124
|
627 prevRelicBonusId = bValue
|
yellowfive@124
|
628 end
|
yellowfive@124
|
629 end
|
yellowfive@124
|
630
|
yellowfive@57
|
631 table.insert(fields, table.concat(itemParts, ""))
|
yellowfive@57
|
632 end
|
yellowfive@57
|
633 end
|
yellowfive@57
|
634
|
yellowfive@57
|
635 -- Serialize just the identity portion of a player (region/realm/name) in the same format used by the full serialization
|
yellowfive@57
|
636 function Amr:SerializePlayerIdentity(data)
|
yellowfive@57
|
637 local fields = {}
|
yellowfive@57
|
638 table.insert(fields, MINOR)
|
yellowfive@57
|
639 table.insert(fields, data.Region)
|
yellowfive@57
|
640 table.insert(fields, data.Realm)
|
yellowfive@57
|
641 table.insert(fields, data.Name)
|
yellowfive@57
|
642 return "$" .. table.concat(fields, ";") .. "$"
|
yellowfive@57
|
643 end
|
yellowfive@57
|
644
|
yellowfive@57
|
645 -- Serialize player data gathered by GetPlayerData. This can be augmented with extra data if desired (augmenting used mainly by AskMrRobot addon).
|
yellowfive@57
|
646 -- Pass complete = true to do a complete export of this extra information, otherwise it is ignored.
|
yellowfive@57
|
647 -- Extra data can include:
|
yellowfive@57
|
648 -- equipped gear for the player's inactive spec, slot id to item link dictionary
|
yellowfive@57
|
649 -- Reputations
|
yellowfive@57
|
650 -- BagItems, BankItems, VoidItems, lists of item links
|
yellowfive@57
|
651 --
|
yellowfive@57
|
652 function Amr:SerializePlayerData(data, complete)
|
yellowfive@57
|
653
|
yellowfive@57
|
654 local fields = {}
|
yellowfive@57
|
655
|
yellowfive@57
|
656 -- compressed string uses a fixed order rather than inserting identifiers
|
yellowfive@57
|
657 table.insert(fields, MINOR)
|
yellowfive@57
|
658 table.insert(fields, data.Region)
|
yellowfive@57
|
659 table.insert(fields, data.Realm)
|
yellowfive@57
|
660 table.insert(fields, data.Name)
|
yellowfive@57
|
661
|
yellowfive@57
|
662 -- guild name
|
yellowfive@57
|
663 if data.Guild == nil then
|
yellowfive@57
|
664 table.insert(fields, "")
|
yellowfive@57
|
665 else
|
yellowfive@57
|
666 table.insert(fields, data.Guild)
|
yellowfive@57
|
667 end
|
yellowfive@57
|
668
|
yellowfive@57
|
669 -- race, default to pandaren if we can't read it for some reason
|
yellowfive@57
|
670 local raceval = Amr.RaceIds[data.Race]
|
yellowfive@57
|
671 if raceval == nil then raceval = 13 end
|
yellowfive@57
|
672 table.insert(fields, raceval)
|
yellowfive@57
|
673
|
yellowfive@57
|
674 -- faction, default to alliance if we can't read it for some reason
|
yellowfive@57
|
675 raceval = Amr.FactionIds[data.Faction]
|
yellowfive@57
|
676 if raceval == nil then raceval = 1 end
|
yellowfive@57
|
677 table.insert(fields, raceval)
|
yellowfive@57
|
678
|
yellowfive@124
|
679 table.insert(fields, data.Level)
|
yellowfive@124
|
680 table.insert(fields, data.HeartOfAzerothLevel)
|
yellowfive@57
|
681
|
yellowfive@57
|
682 local profs = {}
|
yellowfive@57
|
683 local noprofs = true
|
yellowfive@57
|
684 if data.Professions then
|
yellowfive@57
|
685 for k, v in pairs(data.Professions) do
|
yellowfive@57
|
686 local profval = Amr.ProfessionIds[k]
|
yellowfive@57
|
687 if profval ~= nil then
|
yellowfive@57
|
688 noprofs = false
|
yellowfive@57
|
689 table.insert(profs, profval .. ":" .. v)
|
yellowfive@57
|
690 end
|
yellowfive@57
|
691 end
|
yellowfive@57
|
692 end
|
yellowfive@57
|
693
|
yellowfive@57
|
694 if noprofs then
|
yellowfive@57
|
695 table.insert(profs, "0:0")
|
yellowfive@57
|
696 end
|
yellowfive@57
|
697
|
yellowfive@57
|
698 table.insert(fields, table.concat(profs, ","))
|
yellowfive@57
|
699
|
yellowfive@57
|
700 -- export specs
|
yellowfive@57
|
701 table.insert(fields, data.ActiveSpec)
|
yellowfive@81
|
702 for spec = 1, 4 do
|
yellowfive@57
|
703 if data.Specs[spec] and (complete or spec == data.ActiveSpec) then
|
yellowfive@57
|
704 table.insert(fields, ".s" .. spec) -- indicates the start of a spec block
|
yellowfive@81
|
705 table.insert(fields, data.Specs[spec])
|
yellowfive@124
|
706 table.insert(fields, data.Talents[spec] or "")
|
yellowfive@57
|
707 end
|
yellowfive@57
|
708 end
|
yellowfive@57
|
709
|
yellowfive@57
|
710 -- export equipped gear
|
yellowfive@57
|
711 if data.Equipped then
|
yellowfive@81
|
712 for spec = 1, 4 do
|
yellowfive@57
|
713 if data.Equipped[spec] and (complete or spec == data.ActiveSpec) then
|
yellowfive@57
|
714 table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block
|
yellowfive@57
|
715
|
yellowfive@57
|
716 local itemObjects = {}
|
yellowfive@124
|
717 for k, itemData in pairs(data.Equipped[spec]) do
|
yellowfive@57
|
718 itemData.slot = k
|
yellowfive@57
|
719 table.insert(itemObjects, itemData)
|
yellowfive@57
|
720 end
|
yellowfive@57
|
721
|
yellowfive@57
|
722 appendItemsToExport(fields, itemObjects)
|
yellowfive@57
|
723 end
|
yellowfive@57
|
724 end
|
yellowfive@57
|
725 end
|
yellowfive@57
|
726
|
yellowfive@124
|
727 -- if doing a complete export, include bank/bag items too
|
yellowfive@124
|
728 if complete then
|
yellowfive@124
|
729
|
yellowfive@57
|
730 local itemObjects = {}
|
yellowfive@57
|
731 if data.BagItems then
|
yellowfive@124
|
732 for i, itemData in ipairs(data.BagItems) do
|
yellowfive@124
|
733 if itemData then
|
yellowfive@57
|
734 table.insert(itemObjects, itemData)
|
yellowfive@57
|
735 end
|
yellowfive@57
|
736 end
|
yellowfive@57
|
737 end
|
yellowfive@127
|
738 if data.BankItems then
|
yellowfive@124
|
739 for i, itemData in ipairs(data.BankItems) do
|
yellowfive@127
|
740 if itemData then
|
yellowfive@57
|
741 table.insert(itemObjects, itemData)
|
yellowfive@57
|
742 end
|
yellowfive@57
|
743 end
|
yellowfive@124
|
744 end
|
yellowfive@124
|
745
|
yellowfive@57
|
746 table.insert(fields, ".inv")
|
yellowfive@57
|
747 appendItemsToExport(fields, itemObjects)
|
yellowfive@57
|
748 end
|
yellowfive@57
|
749
|
yellowfive@57
|
750 return "$" .. table.concat(fields, ";") .. "$"
|
yellowfive@57
|
751
|
yellowfive@57
|
752 end
|
yellowfive@57
|
753
|
yellowfive@57
|
754 -- Shortcut for the common use case: serialize the player's currently active setup with no extras.
|
yellowfive@57
|
755 function Amr:SerializePlayer()
|
yellowfive@57
|
756 local data = self:GetPlayerData()
|
yellowfive@57
|
757 return self:SerializePlayerData(data)
|
yellowfive@57
|
758 end
|
yellowfive@57
|
759
|
yellowfive@81
|
760 --[[
|
yellowfive@57
|
761 ----------------------------------------------------------------------------------------------------------------------
|
yellowfive@57
|
762 -- Character Snapshots
|
yellowfive@81
|
763 -- This feature snapshots a player's gear/talents/artifact when entering combat. It is enabled by default. Consumers
|
yellowfive@57
|
764 -- of this library can create a setting to enable/disable it as desired per a user setting.
|
yellowfive@57
|
765 --
|
yellowfive@57
|
766 -- You should register for the AMR_SNAPSHOT_STATE_CHANGED message (sent via AceEvent-3.0 messaging) to ensure that
|
yellowfive@57
|
767 -- your addon settings stay in sync with any other addon that may also be trying to control the enabled state.
|
yellowfive@57
|
768 --
|
yellowfive@57
|
769 -- Note that if a user has the main AMR addon installed, it will always enable snapshotting, and override any attempt
|
yellowfive@57
|
770 -- to disable it by immediately re-enabling it and thus re-triggering AMR_SNAPSHOT_STATE_CHANGED.
|
yellowfive@57
|
771 ----------------------------------------------------------------------------------------------------------------------
|
yellowfive@57
|
772 Amr._snapshotEnabled = true
|
yellowfive@57
|
773
|
yellowfive@57
|
774 -- Enable snapshotting of character data when entering combat. Sends this player's character data to anyone logging with the AskMrRobot addon.
|
yellowfive@57
|
775 function Amr:EnableSnapshots()
|
yellowfive@57
|
776 self._snapshotEnabled = true
|
yellowfive@57
|
777 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
|
yellowfive@57
|
778 end
|
yellowfive@57
|
779
|
yellowfive@57
|
780 -- Disable snapshotting of character data when entering combat.
|
yellowfive@57
|
781 function Amr:DisableSnapshots()
|
yellowfive@57
|
782 self._snapshotEnabled = false
|
yellowfive@57
|
783 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
|
yellowfive@57
|
784 end
|
yellowfive@57
|
785
|
yellowfive@57
|
786 function Amr:IsSnapshotEnabled()
|
yellowfive@57
|
787 return self._snapshotEnabled
|
yellowfive@57
|
788 end
|
yellowfive@57
|
789
|
yellowfive@57
|
790
|
yellowfive@57
|
791 function Amr:PLAYER_REGEN_DISABLED()
|
yellowfive@57
|
792 --function Amr:GARRISON_MISSION_NPC_OPENED()
|
yellowfive@57
|
793
|
yellowfive@57
|
794 -- send data about this character when a player enters combat in a supported zone
|
yellowfive@57
|
795 if self._snapshotEnabled and Amr.IsSupportedInstance() then
|
yellowfive@57
|
796 local t = time()
|
yellowfive@57
|
797 local player = self:GetPlayerData()
|
yellowfive@57
|
798 local msg = self:SerializePlayerData(player)
|
yellowfive@57
|
799 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
|
800
|
yellowfive@57
|
801 self:SendCommMessage(Amr.ChatPrefix, msg, "RAID")
|
yellowfive@57
|
802 end
|
yellowfive@57
|
803 end
|
yellowfive@57
|
804
|
yellowfive@57
|
805 Amr:RegisterEvent("PLAYER_REGEN_DISABLED")
|
yellowfive@81
|
806 --Amr:RegisterEvent("GARRISON_MISSION_NPC_OPENED") -- for debugging, fire this event when open mission table
|
yellowfive@122
|
807 ]]
|