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