yellowfive@57
|
1 -- AskMrRobot-Serializer will serialize and communicate character data between users.
|
yellowfive@57
|
2
|
yellowfive@127
|
3 local MAJOR, MINOR = "AskMrRobot-Serializer", 59
|
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@124
|
231 offset= offset + numBonuses
|
yellowfive@124
|
232 if #parts > 17 + offset then
|
yellowfive@124
|
233 numBonuses = tonumber(parts[17 + offset])
|
yellowfive@124
|
234 if numBonuses > 0 then
|
yellowfive@124
|
235 item.relicBonusIds[2] = readBonusIdList(parts, 18 + offset, 17 + offset + numBonuses)
|
yellowfive@124
|
236 end
|
yellowfive@124
|
237
|
yellowfive@124
|
238 offset= offset + numBonuses
|
yellowfive@124
|
239 if #parts > 18 + offset then
|
yellowfive@124
|
240 numBonuses = tonumber(parts[18 + offset])
|
yellowfive@124
|
241 if numBonuses > 0 then
|
yellowfive@124
|
242 item.relicBonusIds[3] = readBonusIdList(parts, 19 + offset, 18 + offset + numBonuses)
|
yellowfive@124
|
243 end
|
yellowfive@124
|
244 end
|
yellowfive@124
|
245 end
|
yellowfive@124
|
246 end
|
yellowfive@69
|
247 end
|
yellowfive@81
|
248
|
yellowfive@57
|
249 return item
|
yellowfive@57
|
250 end
|
yellowfive@57
|
251
|
yellowfive@81
|
252 function Amr.GetItemUniqueId(item, noUpgrade)
|
yellowfive@81
|
253 if not item then return "" end
|
yellowfive@81
|
254 local ret = item.id .. ""
|
yellowfive@81
|
255 if item.bonusIds then
|
yellowfive@81
|
256 for i = 1, #item.bonusIds do
|
yellowfive@81
|
257 ret = ret .. "b" .. item.bonusIds[i]
|
yellowfive@81
|
258 end
|
yellowfive@81
|
259 end
|
yellowfive@81
|
260 if item.suffixId ~= 0 then
|
yellowfive@81
|
261 ret = ret .. "s" .. item.suffixId
|
yellowfive@81
|
262 end
|
yellowfive@81
|
263 if not noUpgrade and item.upgradeId ~= 0 then
|
yellowfive@81
|
264 ret = ret .. "u" .. item.upgradeId
|
yellowfive@81
|
265 end
|
yellowfive@81
|
266 if item.level ~= 0 then
|
yellowfive@81
|
267 ret = ret .. "v" .. item.level
|
yellowfive@81
|
268 end
|
yellowfive@81
|
269 return ret
|
yellowfive@81
|
270 end
|
yellowfive@81
|
271
|
yellowfive@57
|
272 -- returns true if this is an instance that AskMrRobot supports for logging
|
yellowfive@57
|
273 function Amr.IsSupportedInstanceId(instanceMapID)
|
yellowfive@57
|
274 if Amr.SupportedInstanceIds[tonumber(instanceMapID)] then
|
yellowfive@57
|
275 return true
|
yellowfive@57
|
276 else
|
yellowfive@57
|
277 return false
|
yellowfive@57
|
278 end
|
yellowfive@57
|
279 end
|
yellowfive@57
|
280
|
yellowfive@57
|
281 -- returns true if currently in a supported instance for logging
|
yellowfive@57
|
282 function Amr.IsSupportedInstance()
|
yellowfive@57
|
283 local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo()
|
yellowfive@57
|
284 return Amr.IsSupportedInstanceId(instanceMapID)
|
yellowfive@57
|
285 end
|
yellowfive@57
|
286
|
yellowfive@81
|
287 -- helper to iterate over a table in order by its keys
|
yellowfive@81
|
288 local function spairs(t, order)
|
yellowfive@81
|
289 -- collect the keys
|
yellowfive@81
|
290 local keys = {}
|
yellowfive@81
|
291 for k in pairs(t) do keys[#keys+1] = k end
|
yellowfive@81
|
292
|
yellowfive@81
|
293 -- if order function given, sort by it by passing the table and keys a, b,
|
yellowfive@81
|
294 -- otherwise just sort the keys
|
yellowfive@81
|
295 if order then
|
yellowfive@81
|
296 table.sort(keys, function(a,b) return order(t, a, b) end)
|
yellowfive@81
|
297 else
|
yellowfive@81
|
298 table.sort(keys)
|
yellowfive@81
|
299 end
|
yellowfive@81
|
300
|
yellowfive@81
|
301 -- return the iterator function
|
yellowfive@81
|
302 local i = 0
|
yellowfive@81
|
303 return function()
|
yellowfive@81
|
304 i = i + 1
|
yellowfive@81
|
305 if keys[i] then
|
yellowfive@81
|
306 return keys[i], t[keys[i]]
|
yellowfive@81
|
307 end
|
yellowfive@81
|
308 end
|
yellowfive@81
|
309 end
|
yellowfive@81
|
310
|
yellowfive@81
|
311 -- scanning tooltip b/c for some odd reason the api has no way to get basic item properties...
|
yellowfive@81
|
312 -- so you have to generate a fake item tooltip and search for pre-defined strings in the display text
|
yellowfive@81
|
313 local _scanTt
|
yellowfive@81
|
314 function Amr.GetScanningTooltip()
|
yellowfive@81
|
315 if not _scanTt then
|
yellowfive@81
|
316 _scanTt = CreateFrame("GameTooltip", "AmrUiScanTooltip", nil, "GameTooltipTemplate")
|
yellowfive@81
|
317 _scanTt:SetOwner(UIParent, "ANCHOR_NONE")
|
yellowfive@81
|
318 end
|
yellowfive@81
|
319 return _scanTt
|
yellowfive@81
|
320 end
|
yellowfive@81
|
321
|
yellowfive@81
|
322 -- 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
|
323 function Amr.GetItemTooltip(bagId, slotId, link)
|
yellowfive@81
|
324 local tt = Amr.GetScanningTooltip()
|
yellowfive@81
|
325 tt:ClearLines()
|
yellowfive@81
|
326 if bagId then
|
yellowfive@81
|
327 tt:SetBagItem(bagId, slotId)
|
yellowfive@81
|
328 elseif slotId then
|
yellowfive@81
|
329 tt:SetInventoryItem("player", slotId)
|
yellowfive@81
|
330 else
|
yellowfive@81
|
331 tt:SetHyperlink(link)
|
yellowfive@81
|
332 end
|
yellowfive@81
|
333 return tt
|
yellowfive@81
|
334 end
|
yellowfive@81
|
335
|
yellowfive@124
|
336 function Amr.GetItemLevel(bagId, slotId, link)
|
yellowfive@81
|
337 local itemLevelPattern = _G["ITEM_LEVEL"]:gsub("%%d", "(%%d+)")
|
yellowfive@81
|
338 local tt = Amr.GetItemTooltip(bagId, slotId, link)
|
yellowfive@81
|
339
|
yellowfive@81
|
340 local regions = { tt:GetRegions() }
|
yellowfive@81
|
341 for i, region in ipairs(regions) do
|
yellowfive@81
|
342 if region and region:GetObjectType() == "FontString" then
|
yellowfive@81
|
343 local text = region:GetText()
|
yellowfive@81
|
344 if text then
|
yellowfive@81
|
345 ilvl = tonumber(text:match(itemLevelPattern))
|
yellowfive@81
|
346 if ilvl then
|
yellowfive@81
|
347 return ilvl
|
yellowfive@81
|
348 end
|
yellowfive@81
|
349 end
|
yellowfive@81
|
350 end
|
yellowfive@81
|
351 end
|
yellowfive@81
|
352
|
yellowfive@81
|
353 -- 0 means we couldn't find it for whatever reason
|
yellowfive@81
|
354 return 0
|
yellowfive@81
|
355 end
|
yellowfive@81
|
356
|
yellowfive@57
|
357
|
yellowfive@57
|
358 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
359 -- Character Reading
|
yellowfive@57
|
360 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
361
|
yellowfive@57
|
362 local function readProfessionInfo(prof, ret)
|
yellowfive@57
|
363 if prof then
|
yellowfive@57
|
364 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof);
|
yellowfive@57
|
365 if Amr.ProfessionSkillLineToName[skillLine] ~= nil then
|
yellowfive@57
|
366 ret.Professions[Amr.ProfessionSkillLineToName[skillLine]] = skillLevel;
|
yellowfive@57
|
367 end
|
yellowfive@57
|
368 end
|
yellowfive@57
|
369 end
|
yellowfive@57
|
370
|
yellowfive@124
|
371 -- get specs
|
yellowfive@81
|
372 local function readSpecs(ret)
|
yellowfive@57
|
373
|
yellowfive@81
|
374 for pos = 1, 4 do
|
yellowfive@57
|
375 -- spec, convert game spec id to one of our spec ids
|
yellowfive@81
|
376 local specId = GetSpecializationInfo(pos)
|
yellowfive@57
|
377 if specId then
|
yellowfive@81
|
378 ret.Specs[pos] = Amr.SpecIds[specId]
|
yellowfive@57
|
379 end
|
yellowfive@57
|
380 end
|
yellowfive@57
|
381 end
|
yellowfive@57
|
382
|
yellowfive@124
|
383 local function dump(o)
|
yellowfive@124
|
384 if type(o) == 'table' then
|
yellowfive@124
|
385 local s = '{ '
|
yellowfive@124
|
386 for k,v in pairs(o) do
|
yellowfive@124
|
387 if type(k) ~= 'number' then k = '"'..k..'"' end
|
yellowfive@124
|
388 s = s .. '['..k..'] = ' .. dump(v) .. ','
|
yellowfive@124
|
389 end
|
yellowfive@124
|
390 return s .. '} '
|
yellowfive@124
|
391 else
|
yellowfive@124
|
392 return tostring(o)
|
yellowfive@124
|
393 end
|
yellowfive@124
|
394 end
|
yellowfive@124
|
395
|
yellowfive@124
|
396 -- read azerite powers on the item in loc and put it on itemData
|
yellowfive@124
|
397 function Amr.ReadAzeritePowers(loc)
|
yellowfive@124
|
398 local ret = {}
|
yellowfive@124
|
399 local hasSome = false
|
yellowfive@124
|
400
|
yellowfive@124
|
401 local tiers = C_AzeriteEmpoweredItem.GetAllTierInfo(loc)
|
yellowfive@124
|
402 for tier, tierInfo in ipairs(tiers) do
|
yellowfive@124
|
403 for _, power in ipairs(tierInfo.azeritePowerIDs) do
|
yellowfive@124
|
404 if C_AzeriteEmpoweredItem.IsPowerSelected(loc, power) then
|
yellowfive@124
|
405 local powerInfo = C_AzeriteEmpoweredItem.GetPowerInfo(power)
|
yellowfive@124
|
406 table.insert(ret, powerInfo.spellID)
|
yellowfive@124
|
407 hasSome = true
|
yellowfive@124
|
408 end
|
yellowfive@124
|
409 end
|
yellowfive@124
|
410 end
|
yellowfive@124
|
411
|
yellowfive@124
|
412 if hasSome then
|
yellowfive@124
|
413 return ret
|
yellowfive@124
|
414 else
|
yellowfive@124
|
415 return nil
|
yellowfive@124
|
416 end
|
yellowfive@124
|
417 end
|
yellowfive@124
|
418
|
yellowfive@57
|
419 -- get currently equipped items, store with currently active spec
|
yellowfive@57
|
420 local function readEquippedItems(ret)
|
yellowfive@124
|
421 local equippedItems = {};
|
yellowfive@124
|
422 local loc = ItemLocation.CreateEmpty()
|
yellowfive@57
|
423 for slotNum = 1, #Amr.SlotIds do
|
yellowfive@57
|
424 local slotId = Amr.SlotIds[slotNum]
|
yellowfive@57
|
425 local itemLink = GetInventoryItemLink("player", slotId)
|
yellowfive@57
|
426 if itemLink then
|
yellowfive@124
|
427 local itemData = Amr.ParseItemLink(itemLink)
|
yellowfive@124
|
428 if itemData then
|
yellowfive@124
|
429 -- see if this is an azerite item and read azerite power ids
|
yellowfive@124
|
430 loc:SetEquipmentSlot(slotId)
|
yellowfive@124
|
431 if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then
|
yellowfive@124
|
432 local powers = Amr.ReadAzeritePowers(loc)
|
yellowfive@124
|
433 if powers then
|
yellowfive@124
|
434 itemData.azerite = powers
|
yellowfive@124
|
435 end
|
yellowfive@124
|
436 end
|
yellowfive@124
|
437
|
yellowfive@124
|
438 equippedItems[slotId] = itemData
|
yellowfive@124
|
439 end
|
yellowfive@57
|
440 end
|
yellowfive@57
|
441 end
|
yellowfive@57
|
442
|
yellowfive@57
|
443 -- store last-seen equipped gear for each spec
|
yellowfive@81
|
444 ret.Equipped[GetSpecialization()] = equippedItems
|
yellowfive@57
|
445 end
|
yellowfive@57
|
446
|
yellowfive@124
|
447 local function readHeartOfAzerothLevel(ret)
|
yellowfive@124
|
448 local azeriteItemLocation = C_AzeriteItem.FindActiveAzeriteItem();
|
yellowfive@124
|
449 if azeriteItemLocation then
|
yellowfive@124
|
450 local azeriteItem = Item:CreateFromItemLocation(azeriteItemLocation);
|
yellowfive@124
|
451 ret.HeartOfAzerothLevel = C_AzeriteItem.GetPowerLevel(azeriteItemLocation)
|
yellowfive@124
|
452 else
|
yellowfive@124
|
453 ret.HeartOfAzerothLevel = 0
|
yellowfive@124
|
454 end
|
yellowfive@124
|
455 end
|
yellowfive@124
|
456
|
yellowfive@124
|
457 -- Get just the player's currently equipped gear
|
yellowfive@124
|
458 function Amr:GetEquipped()
|
yellowfive@124
|
459 local ret= {}
|
yellowfive@124
|
460 ret.Equipped = {}
|
yellowfive@124
|
461 readEquippedItems(ret)
|
yellowfive@124
|
462 return ret
|
yellowfive@124
|
463 end
|
yellowfive@124
|
464
|
yellowfive@57
|
465 -- Get all data about the player as an object, includes:
|
yellowfive@57
|
466 -- serializer version
|
yellowfive@57
|
467 -- region/realm/name
|
yellowfive@57
|
468 -- guild
|
yellowfive@57
|
469 -- race
|
yellowfive@57
|
470 -- faction
|
yellowfive@57
|
471 -- level
|
yellowfive@57
|
472 -- professions
|
yellowfive@81
|
473 -- spec/talent for all specs
|
yellowfive@57
|
474 -- equipped gear for the current spec
|
yellowfive@57
|
475 --
|
yellowfive@81
|
476 function Amr:GetPlayerData()
|
yellowfive@57
|
477
|
yellowfive@57
|
478 local ret = {}
|
yellowfive@57
|
479
|
yellowfive@57
|
480 ret.Region = Amr.RegionNames[GetCurrentRegion()]
|
yellowfive@57
|
481 ret.Realm = GetRealmName()
|
yellowfive@57
|
482 ret.Name = UnitName("player")
|
yellowfive@57
|
483 ret.Guild = GetGuildInfo("player")
|
yellowfive@81
|
484 ret.ActiveSpec = GetSpecialization()
|
yellowfive@57
|
485 ret.Level = UnitLevel("player");
|
yellowfive@124
|
486 readHeartOfAzerothLevel(ret)
|
yellowfive@124
|
487
|
yellowfive@57
|
488 local cls, clsEn = UnitClass("player")
|
yellowfive@57
|
489 ret.Class = clsEn;
|
yellowfive@57
|
490
|
yellowfive@57
|
491 local race, raceEn = UnitRace("player")
|
yellowfive@57
|
492 ret.Race = raceEn;
|
yellowfive@57
|
493 ret.Faction = UnitFactionGroup("player")
|
yellowfive@57
|
494
|
yellowfive@57
|
495 ret.Professions = {};
|
yellowfive@57
|
496 local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions();
|
yellowfive@57
|
497 readProfessionInfo(prof1, ret)
|
yellowfive@57
|
498 readProfessionInfo(prof2, ret)
|
yellowfive@57
|
499 readProfessionInfo(archaeology, ret)
|
yellowfive@57
|
500 readProfessionInfo(fishing, ret)
|
yellowfive@57
|
501 readProfessionInfo(cooking, ret)
|
yellowfive@57
|
502 readProfessionInfo(firstAid, ret)
|
yellowfive@57
|
503
|
yellowfive@57
|
504 ret.Specs = {}
|
yellowfive@57
|
505 ret.Talents = {}
|
yellowfive@81
|
506 readSpecs(ret)
|
yellowfive@81
|
507
|
yellowfive@124
|
508 ret.Equipped = {}
|
yellowfive@57
|
509 readEquippedItems(ret)
|
yellowfive@57
|
510
|
yellowfive@57
|
511 return ret
|
yellowfive@57
|
512 end
|
yellowfive@57
|
513
|
yellowfive@57
|
514
|
yellowfive@57
|
515 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
516 -- Serialization
|
yellowfive@57
|
517 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
518
|
yellowfive@57
|
519 local function toCompressedNumberList(list)
|
yellowfive@57
|
520 -- ensure the values are numbers, sorted from lowest to highest
|
yellowfive@57
|
521 local nums = {}
|
yellowfive@57
|
522 for i, v in ipairs(list) do
|
yellowfive@57
|
523 table.insert(nums, tonumber(v))
|
yellowfive@57
|
524 end
|
yellowfive@57
|
525 table.sort(nums)
|
yellowfive@57
|
526
|
yellowfive@57
|
527 local ret = {}
|
yellowfive@57
|
528 local prev = 0
|
yellowfive@57
|
529 for i, v in ipairs(nums) do
|
yellowfive@57
|
530 local diff = v - prev
|
yellowfive@57
|
531 table.insert(ret, diff)
|
yellowfive@57
|
532 prev = v
|
yellowfive@57
|
533 end
|
yellowfive@57
|
534
|
yellowfive@57
|
535 return table.concat(ret, ",")
|
yellowfive@57
|
536 end
|
yellowfive@57
|
537
|
yellowfive@57
|
538 -- make this utility publicly available
|
yellowfive@57
|
539 function Amr:ToCompressedNumberList(list)
|
yellowfive@57
|
540 return toCompressedNumberList(list)
|
yellowfive@57
|
541 end
|
yellowfive@57
|
542
|
yellowfive@57
|
543 -- appends a list of items to the export
|
yellowfive@57
|
544 local function appendItemsToExport(fields, itemObjects)
|
yellowfive@57
|
545
|
yellowfive@57
|
546 -- sort by item id so we can compress it more easily
|
yellowfive@57
|
547 table.sort(itemObjects, function(a, b) return a.id < b.id end)
|
yellowfive@57
|
548
|
yellowfive@57
|
549 -- append to the export string
|
yellowfive@57
|
550 local prevItemId = 0
|
yellowfive@57
|
551 local prevGemId = 0
|
yellowfive@57
|
552 local prevEnchantId = 0
|
yellowfive@57
|
553 local prevUpgradeId = 0
|
yellowfive@57
|
554 local prevBonusId = 0
|
yellowfive@81
|
555 local prevLevel = 0
|
yellowfive@124
|
556 local prevAzeriteId = 0
|
yellowfive@124
|
557 local prevRelicBonusId = 0
|
yellowfive@57
|
558 for i, itemData in ipairs(itemObjects) do
|
yellowfive@57
|
559 local itemParts = {}
|
yellowfive@57
|
560
|
yellowfive@57
|
561 table.insert(itemParts, itemData.id - prevItemId)
|
yellowfive@57
|
562 prevItemId = itemData.id
|
yellowfive@57
|
563
|
yellowfive@57
|
564 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end
|
yellowfive@124
|
565 --if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end
|
yellowfive@57
|
566 if itemData.upgradeId ~= 0 then
|
yellowfive@57
|
567 table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId))
|
yellowfive@57
|
568 prevUpgradeId = itemData.upgradeId
|
yellowfive@57
|
569 end
|
yellowfive@81
|
570 if itemData.level ~= 0 then
|
yellowfive@81
|
571 table.insert(itemParts, "v" .. (itemData.level - prevLevel))
|
yellowfive@81
|
572 prevLevel = itemData.level
|
yellowfive@81
|
573 end
|
yellowfive@57
|
574 if itemData.bonusIds then
|
yellowfive@57
|
575 for bIndex, bValue in ipairs(itemData.bonusIds) do
|
yellowfive@57
|
576 table.insert(itemParts, "b" .. (bValue - prevBonusId))
|
yellowfive@57
|
577 prevBonusId = bValue
|
yellowfive@57
|
578 end
|
yellowfive@124
|
579 end
|
yellowfive@124
|
580
|
yellowfive@124
|
581 if itemData.azerite then
|
yellowfive@124
|
582 for aIndex, aValue in ipairs(itemData.azerite) do
|
yellowfive@124
|
583 table.insert(itemParts, "a" .. (aValue - prevAzeriteId))
|
yellowfive@124
|
584 prevAzeriteId = aValue
|
yellowfive@124
|
585 end
|
yellowfive@124
|
586 end
|
yellowfive@81
|
587
|
yellowfive@81
|
588 if itemData.gemIds[1] ~= 0 then
|
yellowfive@81
|
589 table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId))
|
yellowfive@81
|
590 prevGemId = itemData.gemIds[1]
|
yellowfive@81
|
591 end
|
yellowfive@81
|
592 if itemData.gemIds[2] ~= 0 then
|
yellowfive@81
|
593 table.insert(itemParts, "y" .. (itemData.gemIds[2] - prevGemId))
|
yellowfive@81
|
594 prevGemId = itemData.gemIds[2]
|
yellowfive@81
|
595 end
|
yellowfive@81
|
596 if itemData.gemIds[3] ~= 0 then
|
yellowfive@81
|
597 table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId))
|
yellowfive@81
|
598 prevGemId = itemData.gemIds[3]
|
yellowfive@124
|
599 end
|
yellowfive@81
|
600
|
yellowfive@57
|
601 if itemData.enchantId ~= 0 then
|
yellowfive@57
|
602 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId))
|
yellowfive@57
|
603 prevEnchantId = itemData.enchantId
|
yellowfive@57
|
604 end
|
yellowfive@124
|
605
|
yellowfive@124
|
606 if itemData.relicBonusIds and itemData.relicBonusIds[1] ~= nil then
|
yellowfive@124
|
607 for bIndex, bValue in ipairs(itemData.relicBonusIds[1]) do
|
yellowfive@124
|
608 table.insert(itemParts, "p" .. (bValue - prevRelicBonusId))
|
yellowfive@124
|
609 prevRelicBonusId = bValue
|
yellowfive@124
|
610 end
|
yellowfive@124
|
611 end
|
yellowfive@124
|
612
|
yellowfive@124
|
613 if itemData.relicBonusIds and itemData.relicBonusIds[2] ~= nil then
|
yellowfive@124
|
614 for bIndex, bValue in ipairs(itemData.relicBonusIds[2]) do
|
yellowfive@124
|
615 table.insert(itemParts, "q" .. (bValue - prevRelicBonusId))
|
yellowfive@124
|
616 prevRelicBonusId = bValue
|
yellowfive@124
|
617 end
|
yellowfive@124
|
618 end
|
yellowfive@124
|
619
|
yellowfive@124
|
620 if itemData.relicBonusIds and itemData.relicBonusIds[3] ~= nil then
|
yellowfive@124
|
621 for bIndex, bValue in ipairs(itemData.relicBonusIds[3]) do
|
yellowfive@124
|
622 table.insert(itemParts, "r" .. (bValue - prevRelicBonusId))
|
yellowfive@124
|
623 prevRelicBonusId = bValue
|
yellowfive@124
|
624 end
|
yellowfive@124
|
625 end
|
yellowfive@124
|
626
|
yellowfive@57
|
627 table.insert(fields, table.concat(itemParts, ""))
|
yellowfive@57
|
628 end
|
yellowfive@57
|
629 end
|
yellowfive@57
|
630
|
yellowfive@57
|
631 -- Serialize just the identity portion of a player (region/realm/name) in the same format used by the full serialization
|
yellowfive@57
|
632 function Amr:SerializePlayerIdentity(data)
|
yellowfive@57
|
633 local fields = {}
|
yellowfive@57
|
634 table.insert(fields, MINOR)
|
yellowfive@57
|
635 table.insert(fields, data.Region)
|
yellowfive@57
|
636 table.insert(fields, data.Realm)
|
yellowfive@57
|
637 table.insert(fields, data.Name)
|
yellowfive@57
|
638 return "$" .. table.concat(fields, ";") .. "$"
|
yellowfive@57
|
639 end
|
yellowfive@57
|
640
|
yellowfive@57
|
641 -- Serialize player data gathered by GetPlayerData. This can be augmented with extra data if desired (augmenting used mainly by AskMrRobot addon).
|
yellowfive@57
|
642 -- Pass complete = true to do a complete export of this extra information, otherwise it is ignored.
|
yellowfive@57
|
643 -- Extra data can include:
|
yellowfive@57
|
644 -- equipped gear for the player's inactive spec, slot id to item link dictionary
|
yellowfive@57
|
645 -- Reputations
|
yellowfive@57
|
646 -- BagItems, BankItems, VoidItems, lists of item links
|
yellowfive@57
|
647 --
|
yellowfive@57
|
648 function Amr:SerializePlayerData(data, complete)
|
yellowfive@57
|
649
|
yellowfive@57
|
650 local fields = {}
|
yellowfive@57
|
651
|
yellowfive@57
|
652 -- compressed string uses a fixed order rather than inserting identifiers
|
yellowfive@57
|
653 table.insert(fields, MINOR)
|
yellowfive@57
|
654 table.insert(fields, data.Region)
|
yellowfive@57
|
655 table.insert(fields, data.Realm)
|
yellowfive@57
|
656 table.insert(fields, data.Name)
|
yellowfive@57
|
657
|
yellowfive@57
|
658 -- guild name
|
yellowfive@57
|
659 if data.Guild == nil then
|
yellowfive@57
|
660 table.insert(fields, "")
|
yellowfive@57
|
661 else
|
yellowfive@57
|
662 table.insert(fields, data.Guild)
|
yellowfive@57
|
663 end
|
yellowfive@57
|
664
|
yellowfive@57
|
665 -- race, default to pandaren if we can't read it for some reason
|
yellowfive@57
|
666 local raceval = Amr.RaceIds[data.Race]
|
yellowfive@57
|
667 if raceval == nil then raceval = 13 end
|
yellowfive@57
|
668 table.insert(fields, raceval)
|
yellowfive@57
|
669
|
yellowfive@57
|
670 -- faction, default to alliance if we can't read it for some reason
|
yellowfive@57
|
671 raceval = Amr.FactionIds[data.Faction]
|
yellowfive@57
|
672 if raceval == nil then raceval = 1 end
|
yellowfive@57
|
673 table.insert(fields, raceval)
|
yellowfive@57
|
674
|
yellowfive@124
|
675 table.insert(fields, data.Level)
|
yellowfive@124
|
676 table.insert(fields, data.HeartOfAzerothLevel)
|
yellowfive@57
|
677
|
yellowfive@57
|
678 local profs = {}
|
yellowfive@57
|
679 local noprofs = true
|
yellowfive@57
|
680 if data.Professions then
|
yellowfive@57
|
681 for k, v in pairs(data.Professions) do
|
yellowfive@57
|
682 local profval = Amr.ProfessionIds[k]
|
yellowfive@57
|
683 if profval ~= nil then
|
yellowfive@57
|
684 noprofs = false
|
yellowfive@57
|
685 table.insert(profs, profval .. ":" .. v)
|
yellowfive@57
|
686 end
|
yellowfive@57
|
687 end
|
yellowfive@57
|
688 end
|
yellowfive@57
|
689
|
yellowfive@57
|
690 if noprofs then
|
yellowfive@57
|
691 table.insert(profs, "0:0")
|
yellowfive@57
|
692 end
|
yellowfive@57
|
693
|
yellowfive@57
|
694 table.insert(fields, table.concat(profs, ","))
|
yellowfive@57
|
695
|
yellowfive@57
|
696 -- export specs
|
yellowfive@57
|
697 table.insert(fields, data.ActiveSpec)
|
yellowfive@81
|
698 for spec = 1, 4 do
|
yellowfive@57
|
699 if data.Specs[spec] and (complete or spec == data.ActiveSpec) then
|
yellowfive@57
|
700 table.insert(fields, ".s" .. spec) -- indicates the start of a spec block
|
yellowfive@81
|
701 table.insert(fields, data.Specs[spec])
|
yellowfive@124
|
702 table.insert(fields, data.Talents[spec] or "")
|
yellowfive@57
|
703 end
|
yellowfive@57
|
704 end
|
yellowfive@57
|
705
|
yellowfive@57
|
706 -- export equipped gear
|
yellowfive@57
|
707 if data.Equipped then
|
yellowfive@81
|
708 for spec = 1, 4 do
|
yellowfive@57
|
709 if data.Equipped[spec] and (complete or spec == data.ActiveSpec) then
|
yellowfive@57
|
710 table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block
|
yellowfive@57
|
711
|
yellowfive@57
|
712 local itemObjects = {}
|
yellowfive@124
|
713 for k, itemData in pairs(data.Equipped[spec]) do
|
yellowfive@57
|
714 itemData.slot = k
|
yellowfive@57
|
715 table.insert(itemObjects, itemData)
|
yellowfive@57
|
716 end
|
yellowfive@57
|
717
|
yellowfive@57
|
718 appendItemsToExport(fields, itemObjects)
|
yellowfive@57
|
719 end
|
yellowfive@57
|
720 end
|
yellowfive@57
|
721 end
|
yellowfive@57
|
722
|
yellowfive@124
|
723 -- if doing a complete export, include bank/bag items too
|
yellowfive@124
|
724 if complete then
|
yellowfive@124
|
725
|
yellowfive@57
|
726 local itemObjects = {}
|
yellowfive@57
|
727 if data.BagItems then
|
yellowfive@124
|
728 for i, itemData in ipairs(data.BagItems) do
|
yellowfive@124
|
729 if itemData then
|
yellowfive@57
|
730 table.insert(itemObjects, itemData)
|
yellowfive@57
|
731 end
|
yellowfive@57
|
732 end
|
yellowfive@57
|
733 end
|
yellowfive@127
|
734 if data.BankItems then
|
yellowfive@124
|
735 for i, itemData in ipairs(data.BankItems) do
|
yellowfive@127
|
736 if itemData then
|
yellowfive@57
|
737 table.insert(itemObjects, itemData)
|
yellowfive@57
|
738 end
|
yellowfive@57
|
739 end
|
yellowfive@124
|
740 end
|
yellowfive@124
|
741
|
yellowfive@57
|
742 table.insert(fields, ".inv")
|
yellowfive@57
|
743 appendItemsToExport(fields, itemObjects)
|
yellowfive@57
|
744 end
|
yellowfive@57
|
745
|
yellowfive@57
|
746 return "$" .. table.concat(fields, ";") .. "$"
|
yellowfive@57
|
747
|
yellowfive@57
|
748 end
|
yellowfive@57
|
749
|
yellowfive@57
|
750 -- Shortcut for the common use case: serialize the player's currently active setup with no extras.
|
yellowfive@57
|
751 function Amr:SerializePlayer()
|
yellowfive@57
|
752 local data = self:GetPlayerData()
|
yellowfive@57
|
753 return self:SerializePlayerData(data)
|
yellowfive@57
|
754 end
|
yellowfive@57
|
755
|
yellowfive@81
|
756 --[[
|
yellowfive@57
|
757 ----------------------------------------------------------------------------------------------------------------------
|
yellowfive@57
|
758 -- Character Snapshots
|
yellowfive@81
|
759 -- This feature snapshots a player's gear/talents/artifact when entering combat. It is enabled by default. Consumers
|
yellowfive@57
|
760 -- of this library can create a setting to enable/disable it as desired per a user setting.
|
yellowfive@57
|
761 --
|
yellowfive@57
|
762 -- You should register for the AMR_SNAPSHOT_STATE_CHANGED message (sent via AceEvent-3.0 messaging) to ensure that
|
yellowfive@57
|
763 -- your addon settings stay in sync with any other addon that may also be trying to control the enabled state.
|
yellowfive@57
|
764 --
|
yellowfive@57
|
765 -- Note that if a user has the main AMR addon installed, it will always enable snapshotting, and override any attempt
|
yellowfive@57
|
766 -- to disable it by immediately re-enabling it and thus re-triggering AMR_SNAPSHOT_STATE_CHANGED.
|
yellowfive@57
|
767 ----------------------------------------------------------------------------------------------------------------------
|
yellowfive@57
|
768 Amr._snapshotEnabled = true
|
yellowfive@57
|
769
|
yellowfive@57
|
770 -- Enable snapshotting of character data when entering combat. Sends this player's character data to anyone logging with the AskMrRobot addon.
|
yellowfive@57
|
771 function Amr:EnableSnapshots()
|
yellowfive@57
|
772 self._snapshotEnabled = true
|
yellowfive@57
|
773 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
|
yellowfive@57
|
774 end
|
yellowfive@57
|
775
|
yellowfive@57
|
776 -- Disable snapshotting of character data when entering combat.
|
yellowfive@57
|
777 function Amr:DisableSnapshots()
|
yellowfive@57
|
778 self._snapshotEnabled = false
|
yellowfive@57
|
779 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
|
yellowfive@57
|
780 end
|
yellowfive@57
|
781
|
yellowfive@57
|
782 function Amr:IsSnapshotEnabled()
|
yellowfive@57
|
783 return self._snapshotEnabled
|
yellowfive@57
|
784 end
|
yellowfive@57
|
785
|
yellowfive@57
|
786
|
yellowfive@57
|
787 function Amr:PLAYER_REGEN_DISABLED()
|
yellowfive@57
|
788 --function Amr:GARRISON_MISSION_NPC_OPENED()
|
yellowfive@57
|
789
|
yellowfive@57
|
790 -- send data about this character when a player enters combat in a supported zone
|
yellowfive@57
|
791 if self._snapshotEnabled and Amr.IsSupportedInstance() then
|
yellowfive@57
|
792 local t = time()
|
yellowfive@57
|
793 local player = self:GetPlayerData()
|
yellowfive@57
|
794 local msg = self:SerializePlayerData(player)
|
yellowfive@57
|
795 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
|
796
|
yellowfive@57
|
797 self:SendCommMessage(Amr.ChatPrefix, msg, "RAID")
|
yellowfive@57
|
798 end
|
yellowfive@57
|
799 end
|
yellowfive@57
|
800
|
yellowfive@57
|
801 Amr:RegisterEvent("PLAYER_REGEN_DISABLED")
|
yellowfive@81
|
802 --Amr:RegisterEvent("GARRISON_MISSION_NPC_OPENED") -- for debugging, fire this event when open mission table
|
yellowfive@122
|
803 ]]
|