yellowfive@57
|
1 -- AskMrRobot-Serializer will serialize and communicate character data between users.
|
yellowfive@57
|
2
|
yellowfive@187
|
3 local MAJOR, MINOR = "AskMrRobot-Serializer", 91
|
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@135
|
143 ["LightforgedDraenei"] = 17,
|
yellowfive@135
|
144 ["DarkIronDwarf"] = 18,
|
yellowfive@155
|
145 ["MagharOrc"] = 19,
|
yellowfive@155
|
146 ["ZandalariTroll"] = 20,
|
yellowfive@173
|
147 ["KulTiran"] = 21,
|
yellowfive@173
|
148 ["Vulpera"] = 22,
|
yellowfive@173
|
149 ["Mechagnome"] = 23
|
yellowfive@57
|
150 }
|
yellowfive@57
|
151
|
yellowfive@57
|
152 Amr.FactionIds = {
|
yellowfive@57
|
153 ["None"] = 0,
|
yellowfive@57
|
154 ["Alliance"] = 1,
|
yellowfive@57
|
155 ["Horde"] = 2
|
yellowfive@57
|
156 }
|
yellowfive@57
|
157
|
yellowfive@57
|
158 Amr.InstanceIds = {
|
yellowfive@185
|
159 Nathria = 2296
|
yellowfive@57
|
160 }
|
yellowfive@57
|
161
|
yellowfive@57
|
162 -- instances that AskMrRobot currently supports logging for
|
yellowfive@57
|
163 Amr.SupportedInstanceIds = {
|
yellowfive@185
|
164 [2296] = true
|
yellowfive@57
|
165 }
|
yellowfive@57
|
166
|
yellowfive@57
|
167
|
yellowfive@57
|
168 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
169 -- Public Utility Methods
|
yellowfive@57
|
170 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
171
|
yellowfive@81
|
172 local function readBonusIdList(parts, first, last)
|
yellowfive@124
|
173 local ret = {}
|
yellowfive@81
|
174 for i = first, last do
|
yellowfive@81
|
175 table.insert(ret, tonumber(parts[i]))
|
yellowfive@81
|
176 end
|
yellowfive@81
|
177 table.sort(ret)
|
yellowfive@81
|
178 return ret
|
yellowfive@81
|
179 end
|
yellowfive@81
|
180
|
yellowfive@124
|
181 -- 1 2 3 4 5 6 7 8 9 10 11 12
|
yellowfive@124
|
182 -- itemId:ench:gem1 :gem2 :gem3 :gem4:suf:uid:lvl:spec:flags :instdiffid:numbonusIDs:bonusIDs1...n :varies:?:relic bonus ids
|
yellowfive@124
|
183 --|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
|
184 --
|
yellowfive@57
|
185 -- get an object with all of the parts of the item link format that we care about
|
yellowfive@57
|
186 function Amr.ParseItemLink(itemLink)
|
yellowfive@57
|
187 if not itemLink then return nil end
|
yellowfive@57
|
188
|
yellowfive@57
|
189 local str = string.match(itemLink, "|Hitem:([\-%d:]+)|")
|
yellowfive@57
|
190 if not str then return nil end
|
yellowfive@57
|
191
|
yellowfive@57
|
192 local parts = { strsplit(":", str) }
|
yellowfive@57
|
193
|
yellowfive@124
|
194 local item = {}
|
yellowfive@124
|
195 item.link = itemLink
|
yellowfive@81
|
196 item.id = tonumber(parts[1]) or 0
|
yellowfive@81
|
197 item.enchantId = tonumber(parts[2]) or 0
|
yellowfive@81
|
198 item.gemIds = { tonumber(parts[3]) or 0, tonumber(parts[4]) or 0, tonumber(parts[5]) or 0, tonumber(parts[6]) or 0 }
|
yellowfive@81
|
199 item.suffixId = math.abs(tonumber(parts[7]) or 0) -- convert suffix to positive number, that's what we use in our code
|
yellowfive@81
|
200 -- part 8 is some unique ID... we never really used it
|
yellowfive@81
|
201 -- part 9 is current player level
|
yellowfive@81
|
202 -- part 10 is player spec
|
yellowfive@185
|
203 -- unsure what 11 is now --local upgradeIdType = tonumber(parts[11]) or 0 -- part 11 indicates what kind of upgrade ID is just after the bonus IDs
|
yellowfive@81
|
204 -- part 12 is instance difficulty id
|
yellowfive@185
|
205
|
yellowfive@185
|
206 -- 13 is num bonus IDs, followed by bonus IDs
|
yellowfive@81
|
207 local numBonuses = tonumber(parts[13]) or 0
|
yellowfive@81
|
208 local offset = numBonuses
|
yellowfive@81
|
209 if numBonuses > 0 then
|
yellowfive@81
|
210 item.bonusIds = readBonusIdList(parts, 14, 13 + numBonuses)
|
yellowfive@57
|
211 end
|
yellowfive@69
|
212
|
yellowfive@81
|
213 item.upgradeId = 0
|
yellowfive@81
|
214 item.level = 0
|
yellowfive@185
|
215
|
yellowfive@185
|
216 -- part 14 + numBonuses, unsure what this is... sometimes it is "2"
|
yellowfive@185
|
217 -- part 15 + numBonuses, unsure what this is... may indicate what part 16 will mean?
|
yellowfive@185
|
218 -- part 16 + numBonuses, is player level at drop when applicable
|
yellowfive@185
|
219 -- part 17 + numBonuses, unsure what this is...
|
yellowfive@185
|
220 -- part 18 + numBonuses, unsure what this is...
|
yellowfive@185
|
221 -- part 19 + numBonuses, relic info would be here for legion artifacts
|
yellowfive@185
|
222
|
yellowfive@185
|
223 local someNumber = tonumber(parts[15 + offset]) or 0
|
yellowfive@185
|
224 if someNumber ~= 0 then
|
yellowfive@185
|
225 local lvl = tonumber(parts[16 + offset]) or 0
|
yellowfive@185
|
226 if lvl <= 60 then
|
yellowfive@185
|
227 item.level = lvl
|
yellowfive@185
|
228 end
|
yellowfive@185
|
229 end
|
yellowfive@185
|
230
|
yellowfive@185
|
231 -- we don't need relic information anymore
|
yellowfive@185
|
232 --[[elseif #parts > 19 + offset then
|
yellowfive@124
|
233 -- check for relic info
|
yellowfive@124
|
234 item.relicBonusIds = { nil, nil, nil }
|
yellowfive@124
|
235 numBonuses = tonumber(parts[16 + offset])
|
yellowfive@124
|
236 if numBonuses then
|
yellowfive@124
|
237 if numBonuses > 0 then
|
yellowfive@124
|
238 item.relicBonusIds[1] = readBonusIdList(parts, 17 + offset, 16 + offset + numBonuses)
|
yellowfive@124
|
239 end
|
yellowfive@124
|
240
|
yellowfive@129
|
241 offset = offset + numBonuses
|
yellowfive@124
|
242 if #parts > 17 + offset then
|
yellowfive@124
|
243 numBonuses = tonumber(parts[17 + offset])
|
yellowfive@129
|
244 if numBonuses then
|
yellowfive@129
|
245 if numBonuses > 0 then
|
yellowfive@129
|
246 item.relicBonusIds[2] = readBonusIdList(parts, 18 + offset, 17 + offset + numBonuses)
|
yellowfive@129
|
247 end
|
yellowfive@129
|
248
|
yellowfive@129
|
249 offset= offset + numBonuses
|
yellowfive@129
|
250 if #parts > 18 + offset then
|
yellowfive@129
|
251 numBonuses = tonumber(parts[18 + offset])
|
yellowfive@129
|
252 if numBonuses then
|
yellowfive@129
|
253 if numBonuses > 0 then
|
yellowfive@129
|
254 item.relicBonusIds[3] = readBonusIdList(parts, 19 + offset, 18 + offset + numBonuses)
|
yellowfive@129
|
255 end
|
yellowfive@129
|
256 end
|
yellowfive@129
|
257 end
|
yellowfive@124
|
258 end
|
yellowfive@124
|
259 end
|
yellowfive@124
|
260 end
|
yellowfive@185
|
261 end]]
|
yellowfive@81
|
262
|
yellowfive@57
|
263 return item
|
yellowfive@57
|
264 end
|
yellowfive@57
|
265
|
yellowfive@135
|
266 local AZERITE_EMPOWERED_BONUS_ID = 4775
|
yellowfive@135
|
267
|
yellowfive@135
|
268 function Amr.GetItemUniqueId(item, noUpgrade, noAzeriteEmpoweredBonusId)
|
yellowfive@81
|
269 if not item then return "" end
|
yellowfive@81
|
270 local ret = item.id .. ""
|
yellowfive@81
|
271 if item.bonusIds then
|
yellowfive@135
|
272 for i = 1, #item.bonusIds do
|
yellowfive@135
|
273 if not noAzeriteEmpoweredBonusId or item.bonusIds[i] ~= AZERITE_EMPOWERED_BONUS_ID then
|
yellowfive@135
|
274 ret = ret .. "b" .. item.bonusIds[i]
|
yellowfive@135
|
275 end
|
yellowfive@81
|
276 end
|
yellowfive@81
|
277 end
|
yellowfive@81
|
278 if item.suffixId ~= 0 then
|
yellowfive@81
|
279 ret = ret .. "s" .. item.suffixId
|
yellowfive@81
|
280 end
|
yellowfive@81
|
281 if not noUpgrade and item.upgradeId ~= 0 then
|
yellowfive@81
|
282 ret = ret .. "u" .. item.upgradeId
|
yellowfive@81
|
283 end
|
yellowfive@81
|
284 if item.level ~= 0 then
|
yellowfive@81
|
285 ret = ret .. "v" .. item.level
|
yellowfive@81
|
286 end
|
yellowfive@81
|
287 return ret
|
yellowfive@81
|
288 end
|
yellowfive@81
|
289
|
yellowfive@57
|
290 -- returns true if this is an instance that AskMrRobot supports for logging
|
yellowfive@57
|
291 function Amr.IsSupportedInstanceId(instanceMapID)
|
yellowfive@57
|
292 if Amr.SupportedInstanceIds[tonumber(instanceMapID)] then
|
yellowfive@57
|
293 return true
|
yellowfive@57
|
294 else
|
yellowfive@57
|
295 return false
|
yellowfive@57
|
296 end
|
yellowfive@57
|
297 end
|
yellowfive@57
|
298
|
yellowfive@57
|
299 -- returns true if currently in a supported instance for logging
|
yellowfive@57
|
300 function Amr.IsSupportedInstance()
|
yellowfive@133
|
301 local _, _, _, _, _, _, _, instanceMapID = GetInstanceInfo()
|
yellowfive@57
|
302 return Amr.IsSupportedInstanceId(instanceMapID)
|
yellowfive@57
|
303 end
|
yellowfive@57
|
304
|
yellowfive@133
|
305 --[[
|
yellowfive@81
|
306 -- scanning tooltip b/c for some odd reason the api has no way to get basic item properties...
|
yellowfive@81
|
307 -- so you have to generate a fake item tooltip and search for pre-defined strings in the display text
|
yellowfive@81
|
308 local _scanTt
|
yellowfive@81
|
309 function Amr.GetScanningTooltip()
|
yellowfive@81
|
310 if not _scanTt then
|
yellowfive@81
|
311 _scanTt = CreateFrame("GameTooltip", "AmrUiScanTooltip", nil, "GameTooltipTemplate")
|
yellowfive@81
|
312 _scanTt:SetOwner(UIParent, "ANCHOR_NONE")
|
yellowfive@81
|
313 end
|
yellowfive@81
|
314 return _scanTt
|
yellowfive@81
|
315 end
|
yellowfive@81
|
316
|
yellowfive@81
|
317 -- 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
|
318 function Amr.GetItemTooltip(bagId, slotId, link)
|
yellowfive@81
|
319 local tt = Amr.GetScanningTooltip()
|
yellowfive@81
|
320 tt:ClearLines()
|
yellowfive@81
|
321 if bagId then
|
yellowfive@81
|
322 tt:SetBagItem(bagId, slotId)
|
yellowfive@81
|
323 elseif slotId then
|
yellowfive@81
|
324 tt:SetInventoryItem("player", slotId)
|
yellowfive@81
|
325 else
|
yellowfive@81
|
326 tt:SetHyperlink(link)
|
yellowfive@81
|
327 end
|
yellowfive@81
|
328 return tt
|
yellowfive@81
|
329 end
|
yellowfive@133
|
330 ]]
|
yellowfive@81
|
331
|
yellowfive@133
|
332 --[[
|
yellowfive@124
|
333 function Amr.GetItemLevel(bagId, slotId, link)
|
yellowfive@81
|
334 local itemLevelPattern = _G["ITEM_LEVEL"]:gsub("%%d", "(%%d+)")
|
yellowfive@81
|
335 local tt = Amr.GetItemTooltip(bagId, slotId, link)
|
yellowfive@81
|
336
|
yellowfive@81
|
337 local regions = { tt:GetRegions() }
|
yellowfive@81
|
338 for i, region in ipairs(regions) do
|
yellowfive@81
|
339 if region and region:GetObjectType() == "FontString" then
|
yellowfive@81
|
340 local text = region:GetText()
|
yellowfive@81
|
341 if text then
|
yellowfive@81
|
342 ilvl = tonumber(text:match(itemLevelPattern))
|
yellowfive@81
|
343 if ilvl then
|
yellowfive@81
|
344 return ilvl
|
yellowfive@81
|
345 end
|
yellowfive@81
|
346 end
|
yellowfive@81
|
347 end
|
yellowfive@81
|
348 end
|
yellowfive@81
|
349
|
yellowfive@81
|
350 -- 0 means we couldn't find it for whatever reason
|
yellowfive@81
|
351 return 0
|
yellowfive@81
|
352 end
|
yellowfive@133
|
353 ]]
|
yellowfive@81
|
354
|
yellowfive@57
|
355
|
yellowfive@57
|
356 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
357 -- Character Reading
|
yellowfive@57
|
358 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
359
|
yellowfive@57
|
360 local function readProfessionInfo(prof, ret)
|
yellowfive@57
|
361 if prof then
|
yellowfive@133
|
362 local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof);
|
yellowfive@57
|
363 if Amr.ProfessionSkillLineToName[skillLine] ~= nil then
|
yellowfive@57
|
364 ret.Professions[Amr.ProfessionSkillLineToName[skillLine]] = skillLevel;
|
yellowfive@57
|
365 end
|
yellowfive@57
|
366 end
|
yellowfive@57
|
367 end
|
yellowfive@57
|
368
|
yellowfive@124
|
369 -- get specs
|
yellowfive@81
|
370 local function readSpecs(ret)
|
yellowfive@57
|
371
|
yellowfive@81
|
372 for pos = 1, 4 do
|
yellowfive@57
|
373 -- spec, convert game spec id to one of our spec ids
|
yellowfive@81
|
374 local specId = GetSpecializationInfo(pos)
|
yellowfive@57
|
375 if specId then
|
yellowfive@81
|
376 ret.Specs[pos] = Amr.SpecIds[specId]
|
yellowfive@57
|
377 end
|
yellowfive@57
|
378 end
|
yellowfive@57
|
379 end
|
yellowfive@57
|
380
|
yellowfive@124
|
381 local function dump(o)
|
yellowfive@124
|
382 if type(o) == 'table' then
|
yellowfive@124
|
383 local s = '{ '
|
yellowfive@124
|
384 for k,v in pairs(o) do
|
yellowfive@124
|
385 if type(k) ~= 'number' then k = '"'..k..'"' end
|
yellowfive@124
|
386 s = s .. '['..k..'] = ' .. dump(v) .. ','
|
yellowfive@124
|
387 end
|
yellowfive@124
|
388 return s .. '} '
|
yellowfive@124
|
389 else
|
yellowfive@124
|
390 return tostring(o)
|
yellowfive@124
|
391 end
|
yellowfive@124
|
392 end
|
yellowfive@124
|
393
|
yellowfive@185
|
394 --[[
|
yellowfive@124
|
395 -- read azerite powers on the item in loc and put it on itemData
|
yellowfive@124
|
396 function Amr.ReadAzeritePowers(loc)
|
yellowfive@124
|
397 local ret = {}
|
yellowfive@124
|
398 local hasSome = false
|
yellowfive@124
|
399
|
yellowfive@124
|
400 local tiers = C_AzeriteEmpoweredItem.GetAllTierInfo(loc)
|
yellowfive@124
|
401 for tier, tierInfo in ipairs(tiers) do
|
yellowfive@124
|
402 for _, power in ipairs(tierInfo.azeritePowerIDs) do
|
yellowfive@124
|
403 if C_AzeriteEmpoweredItem.IsPowerSelected(loc, power) then
|
yellowfive@124
|
404 local powerInfo = C_AzeriteEmpoweredItem.GetPowerInfo(power)
|
yellowfive@124
|
405 table.insert(ret, powerInfo.spellID)
|
yellowfive@124
|
406 hasSome = true
|
yellowfive@124
|
407 end
|
yellowfive@124
|
408 end
|
yellowfive@124
|
409 end
|
yellowfive@124
|
410
|
yellowfive@124
|
411 if hasSome then
|
yellowfive@124
|
412 return ret
|
yellowfive@124
|
413 else
|
yellowfive@124
|
414 return nil
|
yellowfive@124
|
415 end
|
yellowfive@124
|
416 end
|
yellowfive@185
|
417 ]]
|
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@185
|
429 --[[
|
yellowfive@124
|
430 -- see if this is an azerite item and read azerite power ids
|
yellowfive@124
|
431 loc:SetEquipmentSlot(slotId)
|
yellowfive@124
|
432 if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then
|
yellowfive@124
|
433 local powers = Amr.ReadAzeritePowers(loc)
|
yellowfive@124
|
434 if powers then
|
yellowfive@124
|
435 itemData.azerite = powers
|
yellowfive@124
|
436 end
|
yellowfive@124
|
437 end
|
yellowfive@185
|
438 ]]
|
yellowfive@124
|
439
|
yellowfive@124
|
440 equippedItems[slotId] = itemData
|
yellowfive@124
|
441 end
|
yellowfive@57
|
442 end
|
yellowfive@57
|
443 end
|
yellowfive@57
|
444
|
yellowfive@57
|
445 -- store last-seen equipped gear for each spec
|
yellowfive@81
|
446 ret.Equipped[GetSpecialization()] = equippedItems
|
yellowfive@57
|
447 end
|
yellowfive@57
|
448
|
yellowfive@185
|
449 --[[
|
yellowfive@124
|
450 local function readHeartOfAzerothLevel(ret)
|
yellowfive@124
|
451 local azeriteItemLocation = C_AzeriteItem.FindActiveAzeriteItem();
|
yellowfive@124
|
452 if azeriteItemLocation then
|
yellowfive@124
|
453 local azeriteItem = Item:CreateFromItemLocation(azeriteItemLocation);
|
yellowfive@124
|
454 ret.HeartOfAzerothLevel = C_AzeriteItem.GetPowerLevel(azeriteItemLocation)
|
yellowfive@124
|
455 else
|
yellowfive@124
|
456 ret.HeartOfAzerothLevel = 0
|
yellowfive@124
|
457 end
|
yellowfive@124
|
458 end
|
yellowfive@185
|
459 ]]
|
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@185
|
490 --readHeartOfAzerothLevel(ret)
|
yellowfive@124
|
491
|
yellowfive@133
|
492 local _, clsEn = UnitClass("player")
|
yellowfive@57
|
493 ret.Class = clsEn;
|
yellowfive@57
|
494
|
yellowfive@133
|
495 local _, 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@165
|
511
|
yellowfive@165
|
512 -- these get updated later, since need to cache info for inactive specs
|
yellowfive@185
|
513 --ret.UnlockedEssences = {}
|
yellowfive@185
|
514 --ret.Essences = {}
|
yellowfive@81
|
515
|
yellowfive@124
|
516 ret.Equipped = {}
|
yellowfive@57
|
517 readEquippedItems(ret)
|
yellowfive@57
|
518
|
yellowfive@57
|
519 return ret
|
yellowfive@57
|
520 end
|
yellowfive@57
|
521
|
yellowfive@57
|
522
|
yellowfive@57
|
523 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
524 -- Serialization
|
yellowfive@57
|
525 ----------------------------------------------------------------------------------------
|
yellowfive@57
|
526
|
yellowfive@57
|
527 local function toCompressedNumberList(list)
|
yellowfive@57
|
528 -- ensure the values are numbers, sorted from lowest to highest
|
yellowfive@57
|
529 local nums = {}
|
yellowfive@57
|
530 for i, v in ipairs(list) do
|
yellowfive@57
|
531 table.insert(nums, tonumber(v))
|
yellowfive@57
|
532 end
|
yellowfive@57
|
533 table.sort(nums)
|
yellowfive@57
|
534
|
yellowfive@57
|
535 local ret = {}
|
yellowfive@57
|
536 local prev = 0
|
yellowfive@57
|
537 for i, v in ipairs(nums) do
|
yellowfive@57
|
538 local diff = v - prev
|
yellowfive@57
|
539 table.insert(ret, diff)
|
yellowfive@57
|
540 prev = v
|
yellowfive@57
|
541 end
|
yellowfive@57
|
542
|
yellowfive@57
|
543 return table.concat(ret, ",")
|
yellowfive@57
|
544 end
|
yellowfive@57
|
545
|
yellowfive@57
|
546 -- make this utility publicly available
|
yellowfive@57
|
547 function Amr:ToCompressedNumberList(list)
|
yellowfive@57
|
548 return toCompressedNumberList(list)
|
yellowfive@57
|
549 end
|
yellowfive@57
|
550
|
yellowfive@57
|
551 -- appends a list of items to the export
|
yellowfive@57
|
552 local function appendItemsToExport(fields, itemObjects)
|
yellowfive@57
|
553
|
yellowfive@57
|
554 -- sort by item id so we can compress it more easily
|
yellowfive@57
|
555 table.sort(itemObjects, function(a, b) return a.id < b.id end)
|
yellowfive@57
|
556
|
yellowfive@57
|
557 -- append to the export string
|
yellowfive@57
|
558 local prevItemId = 0
|
yellowfive@57
|
559 local prevGemId = 0
|
yellowfive@57
|
560 local prevEnchantId = 0
|
yellowfive@57
|
561 local prevUpgradeId = 0
|
yellowfive@57
|
562 local prevBonusId = 0
|
yellowfive@81
|
563 local prevLevel = 0
|
yellowfive@185
|
564 --local prevAzeriteId = 0
|
yellowfive@124
|
565 local prevRelicBonusId = 0
|
yellowfive@57
|
566 for i, itemData in ipairs(itemObjects) do
|
yellowfive@57
|
567 local itemParts = {}
|
yellowfive@57
|
568
|
yellowfive@57
|
569 table.insert(itemParts, itemData.id - prevItemId)
|
yellowfive@57
|
570 prevItemId = itemData.id
|
yellowfive@57
|
571
|
yellowfive@57
|
572 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end
|
yellowfive@124
|
573 --if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end
|
yellowfive@57
|
574 if itemData.upgradeId ~= 0 then
|
yellowfive@57
|
575 table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId))
|
yellowfive@57
|
576 prevUpgradeId = itemData.upgradeId
|
yellowfive@57
|
577 end
|
yellowfive@81
|
578 if itemData.level ~= 0 then
|
yellowfive@81
|
579 table.insert(itemParts, "v" .. (itemData.level - prevLevel))
|
yellowfive@81
|
580 prevLevel = itemData.level
|
yellowfive@81
|
581 end
|
yellowfive@57
|
582 if itemData.bonusIds then
|
yellowfive@57
|
583 for bIndex, bValue in ipairs(itemData.bonusIds) do
|
yellowfive@57
|
584 table.insert(itemParts, "b" .. (bValue - prevBonusId))
|
yellowfive@57
|
585 prevBonusId = bValue
|
yellowfive@57
|
586 end
|
yellowfive@124
|
587 end
|
yellowfive@124
|
588
|
yellowfive@185
|
589 --[[
|
yellowfive@124
|
590 if itemData.azerite then
|
yellowfive@124
|
591 for aIndex, aValue in ipairs(itemData.azerite) do
|
yellowfive@124
|
592 table.insert(itemParts, "a" .. (aValue - prevAzeriteId))
|
yellowfive@124
|
593 prevAzeriteId = aValue
|
yellowfive@124
|
594 end
|
yellowfive@124
|
595 end
|
yellowfive@185
|
596 ]]
|
yellowfive@185
|
597
|
yellowfive@81
|
598 if itemData.gemIds[1] ~= 0 then
|
yellowfive@81
|
599 table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId))
|
yellowfive@81
|
600 prevGemId = itemData.gemIds[1]
|
yellowfive@81
|
601 end
|
yellowfive@81
|
602 if itemData.gemIds[2] ~= 0 then
|
yellowfive@81
|
603 table.insert(itemParts, "y" .. (itemData.gemIds[2] - prevGemId))
|
yellowfive@81
|
604 prevGemId = itemData.gemIds[2]
|
yellowfive@81
|
605 end
|
yellowfive@81
|
606 if itemData.gemIds[3] ~= 0 then
|
yellowfive@81
|
607 table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId))
|
yellowfive@81
|
608 prevGemId = itemData.gemIds[3]
|
yellowfive@124
|
609 end
|
yellowfive@81
|
610
|
yellowfive@57
|
611 if itemData.enchantId ~= 0 then
|
yellowfive@57
|
612 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId))
|
yellowfive@57
|
613 prevEnchantId = itemData.enchantId
|
yellowfive@57
|
614 end
|
yellowfive@124
|
615
|
yellowfive@124
|
616 if itemData.relicBonusIds and itemData.relicBonusIds[1] ~= nil then
|
yellowfive@124
|
617 for bIndex, bValue in ipairs(itemData.relicBonusIds[1]) do
|
yellowfive@124
|
618 table.insert(itemParts, "p" .. (bValue - prevRelicBonusId))
|
yellowfive@124
|
619 prevRelicBonusId = bValue
|
yellowfive@124
|
620 end
|
yellowfive@124
|
621 end
|
yellowfive@124
|
622
|
yellowfive@124
|
623 if itemData.relicBonusIds and itemData.relicBonusIds[2] ~= nil then
|
yellowfive@124
|
624 for bIndex, bValue in ipairs(itemData.relicBonusIds[2]) do
|
yellowfive@124
|
625 table.insert(itemParts, "q" .. (bValue - prevRelicBonusId))
|
yellowfive@124
|
626 prevRelicBonusId = bValue
|
yellowfive@124
|
627 end
|
yellowfive@124
|
628 end
|
yellowfive@124
|
629
|
yellowfive@124
|
630 if itemData.relicBonusIds and itemData.relicBonusIds[3] ~= nil then
|
yellowfive@124
|
631 for bIndex, bValue in ipairs(itemData.relicBonusIds[3]) do
|
yellowfive@124
|
632 table.insert(itemParts, "r" .. (bValue - prevRelicBonusId))
|
yellowfive@124
|
633 prevRelicBonusId = bValue
|
yellowfive@124
|
634 end
|
yellowfive@124
|
635 end
|
yellowfive@124
|
636
|
yellowfive@57
|
637 table.insert(fields, table.concat(itemParts, ""))
|
yellowfive@57
|
638 end
|
yellowfive@57
|
639 end
|
yellowfive@57
|
640
|
yellowfive@57
|
641 -- Serialize just the identity portion of a player (region/realm/name) in the same format used by the full serialization
|
yellowfive@57
|
642 function Amr:SerializePlayerIdentity(data)
|
yellowfive@57
|
643 local fields = {}
|
yellowfive@57
|
644 table.insert(fields, MINOR)
|
yellowfive@57
|
645 table.insert(fields, data.Region)
|
yellowfive@57
|
646 table.insert(fields, data.Realm)
|
yellowfive@57
|
647 table.insert(fields, data.Name)
|
yellowfive@57
|
648 return "$" .. table.concat(fields, ";") .. "$"
|
yellowfive@57
|
649 end
|
yellowfive@57
|
650
|
yellowfive@57
|
651 -- Serialize player data gathered by GetPlayerData. This can be augmented with extra data if desired (augmenting used mainly by AskMrRobot addon).
|
yellowfive@57
|
652 -- Pass complete = true to do a complete export of this extra information, otherwise it is ignored.
|
yellowfive@57
|
653 -- Extra data can include:
|
yellowfive@57
|
654 -- equipped gear for the player's inactive spec, slot id to item link dictionary
|
yellowfive@57
|
655 -- Reputations
|
yellowfive@57
|
656 -- BagItems, BankItems, VoidItems, lists of item links
|
yellowfive@57
|
657 --
|
yellowfive@57
|
658 function Amr:SerializePlayerData(data, complete)
|
yellowfive@57
|
659
|
yellowfive@57
|
660 local fields = {}
|
yellowfive@57
|
661
|
yellowfive@57
|
662 -- compressed string uses a fixed order rather than inserting identifiers
|
yellowfive@57
|
663 table.insert(fields, MINOR)
|
yellowfive@57
|
664 table.insert(fields, data.Region)
|
yellowfive@57
|
665 table.insert(fields, data.Realm)
|
yellowfive@57
|
666 table.insert(fields, data.Name)
|
yellowfive@57
|
667
|
yellowfive@57
|
668 -- guild name
|
yellowfive@57
|
669 if data.Guild == nil then
|
yellowfive@57
|
670 table.insert(fields, "")
|
yellowfive@57
|
671 else
|
yellowfive@57
|
672 table.insert(fields, data.Guild)
|
yellowfive@57
|
673 end
|
yellowfive@57
|
674
|
yellowfive@57
|
675 -- race, default to pandaren if we can't read it for some reason
|
yellowfive@57
|
676 local raceval = Amr.RaceIds[data.Race]
|
yellowfive@57
|
677 if raceval == nil then raceval = 13 end
|
yellowfive@57
|
678 table.insert(fields, raceval)
|
yellowfive@57
|
679
|
yellowfive@57
|
680 -- faction, default to alliance if we can't read it for some reason
|
yellowfive@57
|
681 raceval = Amr.FactionIds[data.Faction]
|
yellowfive@57
|
682 if raceval == nil then raceval = 1 end
|
yellowfive@57
|
683 table.insert(fields, raceval)
|
yellowfive@57
|
684
|
yellowfive@124
|
685 table.insert(fields, data.Level)
|
yellowfive@185
|
686
|
yellowfive@57
|
687 local profs = {}
|
yellowfive@57
|
688 local noprofs = true
|
yellowfive@57
|
689 if data.Professions then
|
yellowfive@57
|
690 for k, v in pairs(data.Professions) do
|
yellowfive@57
|
691 local profval = Amr.ProfessionIds[k]
|
yellowfive@57
|
692 if profval ~= nil then
|
yellowfive@57
|
693 noprofs = false
|
yellowfive@57
|
694 table.insert(profs, profval .. ":" .. v)
|
yellowfive@57
|
695 end
|
yellowfive@57
|
696 end
|
yellowfive@57
|
697 end
|
yellowfive@57
|
698
|
yellowfive@57
|
699 if noprofs then
|
yellowfive@57
|
700 table.insert(profs, "0:0")
|
yellowfive@57
|
701 end
|
yellowfive@57
|
702
|
yellowfive@57
|
703 table.insert(fields, table.concat(profs, ","))
|
yellowfive@57
|
704
|
yellowfive@57
|
705 -- export specs
|
yellowfive@57
|
706 table.insert(fields, data.ActiveSpec)
|
yellowfive@81
|
707 for spec = 1, 4 do
|
yellowfive@57
|
708 if data.Specs[spec] and (complete or spec == data.ActiveSpec) then
|
yellowfive@57
|
709 table.insert(fields, ".s" .. spec) -- indicates the start of a spec block
|
yellowfive@81
|
710 table.insert(fields, data.Specs[spec])
|
yellowfive@165
|
711 table.insert(fields, data.Talents[spec] or "")
|
yellowfive@185
|
712 table.insert(fields, data.ActiveSoulbinds and data.ActiveSoulbinds[spec] or "0")
|
yellowfive@185
|
713
|
yellowfive@185
|
714 --[[
|
yellowfive@165
|
715 local essences = {}
|
yellowfive@165
|
716 if data.Essences and data.Essences[spec] then
|
yellowfive@165
|
717 for i, ess in ipairs(data.Essences[spec]) do
|
yellowfive@165
|
718 table.insert(essences, table.concat(ess, "."))
|
yellowfive@165
|
719 end
|
yellowfive@165
|
720 end
|
yellowfive@165
|
721 table.insert(fields, table.concat(essences, "_"))
|
yellowfive@185
|
722 ]]
|
yellowfive@57
|
723 end
|
yellowfive@57
|
724 end
|
yellowfive@57
|
725
|
yellowfive@57
|
726 -- export equipped gear
|
yellowfive@57
|
727 if data.Equipped then
|
yellowfive@81
|
728 for spec = 1, 4 do
|
yellowfive@57
|
729 if data.Equipped[spec] and (complete or spec == data.ActiveSpec) then
|
yellowfive@57
|
730 table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block
|
yellowfive@57
|
731
|
yellowfive@57
|
732 local itemObjects = {}
|
yellowfive@124
|
733 for k, itemData in pairs(data.Equipped[spec]) do
|
yellowfive@57
|
734 itemData.slot = k
|
yellowfive@57
|
735 table.insert(itemObjects, itemData)
|
yellowfive@57
|
736 end
|
yellowfive@57
|
737
|
yellowfive@57
|
738 appendItemsToExport(fields, itemObjects)
|
yellowfive@57
|
739 end
|
yellowfive@57
|
740 end
|
yellowfive@57
|
741 end
|
yellowfive@165
|
742
|
yellowfive@185
|
743 -- export soulbind tree info
|
yellowfive@185
|
744 if data.Soulbinds then
|
yellowfive@185
|
745 table.insert(fields, ".sol")
|
yellowfive@185
|
746 for soulbindId, soulbindData in pairs(data.Soulbinds) do
|
yellowfive@185
|
747 table.insert(fields, string.format("u.%s.%s", soulbindId, soulbindData.UnlockedTier))
|
yellowfive@185
|
748 for tier, node in pairs(soulbindData.Nodes) do
|
yellowfive@185
|
749 table.insert(fields, table.concat(node, "."))
|
yellowfive@185
|
750 end
|
yellowfive@185
|
751 end
|
yellowfive@185
|
752 end
|
yellowfive@185
|
753
|
yellowfive@185
|
754 -- export unlocked conduits
|
yellowfive@185
|
755 if data.UnlockedConduits then
|
yellowfive@185
|
756 table.insert(fields, ".con")
|
yellowfive@185
|
757 for i, conduit in ipairs(data.UnlockedConduits) do
|
yellowfive@185
|
758 table.insert(fields, table.concat(conduit, "."))
|
yellowfive@185
|
759 end
|
yellowfive@185
|
760 end
|
yellowfive@185
|
761
|
yellowfive@185
|
762 --[[
|
yellowfive@165
|
763 -- export unlocked essences
|
yellowfive@165
|
764 if data.UnlockedEssences then
|
yellowfive@165
|
765 table.insert(fields, ".ess")
|
yellowfive@165
|
766 for i, ess in ipairs(data.UnlockedEssences) do
|
yellowfive@165
|
767 table.insert(fields, table.concat(ess, "_"))
|
yellowfive@165
|
768 end
|
yellowfive@165
|
769 end
|
yellowfive@185
|
770 ]]
|
yellowfive@185
|
771
|
yellowfive@124
|
772 -- if doing a complete export, include bank/bag items too
|
yellowfive@124
|
773 if complete then
|
yellowfive@124
|
774
|
yellowfive@57
|
775 local itemObjects = {}
|
yellowfive@57
|
776 if data.BagItems then
|
yellowfive@124
|
777 for i, itemData in ipairs(data.BagItems) do
|
yellowfive@124
|
778 if itemData then
|
yellowfive@57
|
779 table.insert(itemObjects, itemData)
|
yellowfive@57
|
780 end
|
yellowfive@57
|
781 end
|
yellowfive@57
|
782 end
|
yellowfive@127
|
783 if data.BankItems then
|
yellowfive@124
|
784 for i, itemData in ipairs(data.BankItems) do
|
yellowfive@127
|
785 if itemData then
|
yellowfive@57
|
786 table.insert(itemObjects, itemData)
|
yellowfive@57
|
787 end
|
yellowfive@57
|
788 end
|
yellowfive@124
|
789 end
|
yellowfive@124
|
790
|
yellowfive@57
|
791 table.insert(fields, ".inv")
|
yellowfive@57
|
792 appendItemsToExport(fields, itemObjects)
|
yellowfive@57
|
793 end
|
yellowfive@57
|
794
|
yellowfive@57
|
795 return "$" .. table.concat(fields, ";") .. "$"
|
yellowfive@57
|
796
|
yellowfive@57
|
797 end
|
yellowfive@57
|
798
|
yellowfive@165
|
799 --[[
|
yellowfive@57
|
800 -- Shortcut for the common use case: serialize the player's currently active setup with no extras.
|
yellowfive@57
|
801 function Amr:SerializePlayer()
|
yellowfive@57
|
802 local data = self:GetPlayerData()
|
yellowfive@57
|
803 return self:SerializePlayerData(data)
|
yellowfive@57
|
804 end
|
yellowfive@165
|
805 ]]
|
yellowfive@57
|
806
|
yellowfive@81
|
807 --[[
|
yellowfive@57
|
808 ----------------------------------------------------------------------------------------------------------------------
|
yellowfive@57
|
809 -- Character Snapshots
|
yellowfive@81
|
810 -- This feature snapshots a player's gear/talents/artifact when entering combat. It is enabled by default. Consumers
|
yellowfive@57
|
811 -- of this library can create a setting to enable/disable it as desired per a user setting.
|
yellowfive@57
|
812 --
|
yellowfive@57
|
813 -- You should register for the AMR_SNAPSHOT_STATE_CHANGED message (sent via AceEvent-3.0 messaging) to ensure that
|
yellowfive@57
|
814 -- your addon settings stay in sync with any other addon that may also be trying to control the enabled state.
|
yellowfive@57
|
815 --
|
yellowfive@57
|
816 -- Note that if a user has the main AMR addon installed, it will always enable snapshotting, and override any attempt
|
yellowfive@57
|
817 -- to disable it by immediately re-enabling it and thus re-triggering AMR_SNAPSHOT_STATE_CHANGED.
|
yellowfive@57
|
818 ----------------------------------------------------------------------------------------------------------------------
|
yellowfive@57
|
819 Amr._snapshotEnabled = true
|
yellowfive@57
|
820
|
yellowfive@57
|
821 -- Enable snapshotting of character data when entering combat. Sends this player's character data to anyone logging with the AskMrRobot addon.
|
yellowfive@57
|
822 function Amr:EnableSnapshots()
|
yellowfive@57
|
823 self._snapshotEnabled = true
|
yellowfive@57
|
824 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
|
yellowfive@57
|
825 end
|
yellowfive@57
|
826
|
yellowfive@57
|
827 -- Disable snapshotting of character data when entering combat.
|
yellowfive@57
|
828 function Amr:DisableSnapshots()
|
yellowfive@57
|
829 self._snapshotEnabled = false
|
yellowfive@57
|
830 self:SendMessage("AMR_SNAPSHOT_STATE_CHANGED", self._snapshotEnabled)
|
yellowfive@57
|
831 end
|
yellowfive@57
|
832
|
yellowfive@57
|
833 function Amr:IsSnapshotEnabled()
|
yellowfive@57
|
834 return self._snapshotEnabled
|
yellowfive@57
|
835 end
|
yellowfive@57
|
836
|
yellowfive@57
|
837
|
yellowfive@57
|
838 function Amr:PLAYER_REGEN_DISABLED()
|
yellowfive@57
|
839 --function Amr:GARRISON_MISSION_NPC_OPENED()
|
yellowfive@57
|
840
|
yellowfive@57
|
841 -- send data about this character when a player enters combat in a supported zone
|
yellowfive@57
|
842 if self._snapshotEnabled and Amr.IsSupportedInstance() then
|
yellowfive@57
|
843 local t = time()
|
yellowfive@57
|
844 local player = self:GetPlayerData()
|
yellowfive@57
|
845 local msg = self:SerializePlayerData(player)
|
yellowfive@57
|
846 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
|
847
|
yellowfive@57
|
848 self:SendCommMessage(Amr.ChatPrefix, msg, "RAID")
|
yellowfive@57
|
849 end
|
yellowfive@57
|
850 end
|
yellowfive@57
|
851
|
yellowfive@57
|
852 Amr:RegisterEvent("PLAYER_REGEN_DISABLED")
|
yellowfive@81
|
853 --Amr:RegisterEvent("GARRISON_MISSION_NPC_OPENED") -- for debugging, fire this event when open mission table
|
yellowfive@122
|
854 ]]
|