adam@0
|
1 local _, AskMrRobot = ...
|
adam@0
|
2
|
adam@0
|
3 AskMrRobot.eventListener = CreateFrame("FRAME"); -- Need a frame to respond to events
|
adam@0
|
4 AskMrRobot.eventListener:RegisterEvent("ADDON_LOADED"); -- Fired when saved variables are loaded
|
adam@0
|
5 AskMrRobot.eventListener:RegisterEvent("ITEM_PUSH");
|
adam@0
|
6 AskMrRobot.eventListener:RegisterEvent("DELETE_ITEM_CONFIRM");
|
adam@0
|
7 AskMrRobot.eventListener:RegisterEvent("UNIT_INVENTORY_CHANGED");
|
adam@0
|
8 AskMrRobot.eventListener:RegisterEvent("BANKFRAME_OPENED");
|
adam@0
|
9 AskMrRobot.eventListener:RegisterEvent("BANKFRAME_CLOSED");
|
adam@0
|
10 AskMrRobot.eventListener:RegisterEvent("PLAYERBANKSLOTS_CHANGED");
|
adam@0
|
11 AskMrRobot.eventListener:RegisterEvent("CHARACTER_POINTS_CHANGED");
|
adam@0
|
12 AskMrRobot.eventListener:RegisterEvent("CONFIRM_TALENT_WIPE");
|
adam@0
|
13 AskMrRobot.eventListener:RegisterEvent("PLAYER_TALENT_UPDATE");
|
adam@0
|
14 AskMrRobot.eventListener:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED");
|
adam@0
|
15 AskMrRobot.eventListener:RegisterEvent("PLAYER_LOGOUT"); -- Fired when about to log out
|
adam@0
|
16 AskMrRobot.eventListener:RegisterEvent("PLAYER_LEVEL_UP");
|
adam@0
|
17 --AskMrRobot.eventListener:RegisterEvent("GET_ITEM_INFO_RECEIVED")
|
adam@0
|
18 AskMrRobot.eventListener:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED")
|
adam@0
|
19 AskMrRobot.eventListener:RegisterEvent("SOCKET_INFO_UPDATE")
|
adam@0
|
20 AskMrRobot.eventListener:RegisterEvent("SOCKET_INFO_CLOSE")
|
adam@0
|
21 AskMrRobot.eventListener:RegisterEvent("BAG_UPDATE")
|
adam@0
|
22 AskMrRobot.eventListener:RegisterEvent("ITEM_UNLOCKED")
|
adam@0
|
23 --AskMrRobot.eventListener:RegisterEvent("PLAYER_REGEN_DISABLED")
|
adam@0
|
24 AskMrRobot.eventListener:RegisterEvent("ENCOUNTER_START")
|
adam@0
|
25 AskMrRobot.eventListener:RegisterEvent("CHAT_MSG_ADDON")
|
adam@0
|
26 AskMrRobot.eventListener:RegisterEvent("UPDATE_INSTANCE_INFO")
|
adam@0
|
27 AskMrRobot.eventListener:RegisterEvent("PLAYER_DIFFICULTY_CHANGED")
|
adam@0
|
28
|
adam@0
|
29 AskMrRobot.AddonName = ...
|
adam@0
|
30 AskMrRobot.ChatPrefix = "_AMR"
|
adam@0
|
31
|
adam@0
|
32 local amrLDB
|
adam@0
|
33 local icon
|
adam@0
|
34 local reforgequeue
|
adam@0
|
35 local reforgeFrame = nil
|
adam@0
|
36 local LoggingCombat = _G.LoggingCombat
|
adam@0
|
37
|
adam@0
|
38 AskMrRobot.itemDiffs = {
|
adam@0
|
39 items = {}, -- slotNum -> nil (no change) or current <item id>, optimized <item id>
|
adam@0
|
40 enchants = {}, -- slotNum -> nil (no change) or current <enchant id>, optimized <enchant id>
|
adam@0
|
41 gems = {}, -- slotNum -> nil (no change) or ?
|
adam@0
|
42 reforges = {} -- slotNum -> nil (no change) or current <reforge id>, optimized <reforge id>
|
adam@0
|
43 }
|
adam@0
|
44
|
adam@0
|
45 AskMrRobot.instanceIds = {
|
adam@0
|
46 HeartOfFear = 1009,
|
adam@0
|
47 MogushanVaults = 1008,
|
adam@0
|
48 SiegeOfOrgrimmar = 1136,
|
adam@0
|
49 TerraceOfEndlessSpring = 996,
|
adam@0
|
50 ThroneOfThunder = 1098
|
adam@0
|
51 }
|
adam@0
|
52
|
adam@0
|
53 -- upgrade id -> upgrade level
|
adam@0
|
54 local upgradeTable = {
|
adam@0
|
55 [0] = 0,
|
adam@0
|
56 [1] = 1, -- 1/1 -> 8
|
adam@0
|
57 [373] = 1, -- 1/2 -> 4
|
adam@0
|
58 [374] = 2, -- 2/2 -> 8
|
adam@0
|
59 [375] = 1, -- 1/3 -> 4
|
adam@0
|
60 [376] = 2, -- 2/3 -> 4
|
adam@0
|
61 [377] = 3, -- 3/3 -> 4
|
adam@0
|
62 [378] = 1, -- 1/1 -> 7
|
adam@0
|
63 [379] = 1, -- 1/2 -> 4
|
adam@0
|
64 [380] = 2, -- 2/2 -> 4
|
adam@0
|
65 [445] = 0, -- 0/2 -> 0
|
adam@0
|
66 [446] = 1, -- 1/2 -> 4
|
adam@0
|
67 [447] = 2, -- 2/2 -> 8
|
adam@0
|
68 [451] = 0, -- 0/1 -> 0
|
adam@0
|
69 [452] = 1, -- 1/1 -> 8
|
adam@0
|
70 [453] = 0, -- 0/2 -> 0
|
adam@0
|
71 [454] = 1, -- 1/2 -> 4
|
adam@0
|
72 [455] = 2, -- 2/2 -> 8
|
adam@0
|
73 [456] = 0, -- 0/1 -> 0
|
adam@0
|
74 [457] = 1, -- 1/1 -> 8
|
adam@0
|
75 [458] = 0, -- 0/4 -> 0
|
adam@0
|
76 [459] = 1, -- 1/4 -> 4
|
adam@0
|
77 [460] = 2, -- 2/4 -> 8
|
adam@0
|
78 [461] = 3, -- 3/4 -> 12
|
adam@0
|
79 [462] = 4, -- 4/4 -> 16
|
adam@0
|
80 [465] = 0, -- 0/2 -> 0
|
adam@0
|
81 [466] = 1, -- 1/2 -> 4
|
adam@0
|
82 [467] = 2, -- 2/2 -> 8
|
adam@0
|
83 [468] = 0, -- 0/4 -> 0
|
adam@0
|
84 [469] = 1, -- 1/4 -> 4
|
adam@0
|
85 [470] = 2, -- 2/4 -> 8
|
adam@0
|
86 [471] = 3, -- 3/4 -> 12
|
adam@0
|
87 [472] = 4, -- 4/4 -> 16
|
adam@0
|
88 [476] = 0, -- ? -> 0
|
adam@0
|
89 [479] = 0, -- ? -> 0
|
adam@0
|
90 [491] = 0, -- ? -> 0
|
adam@0
|
91 [492] = 1, -- ? -> 0
|
adam@0
|
92 [493] = 2, -- ? -> 0
|
adam@0
|
93 [494] = 0,
|
adam@0
|
94 [495] = 1,
|
adam@0
|
95 [496] = 2,
|
adam@0
|
96 [497] = 3,
|
adam@0
|
97 [498] = 4,
|
adam@0
|
98 [504] = 3,
|
adam@0
|
99 [505] = 4
|
adam@0
|
100 }
|
adam@0
|
101
|
adam@0
|
102 local professionIds = {
|
adam@0
|
103 ["None"] = 0,
|
adam@0
|
104 ["Mining"] = 1,
|
adam@0
|
105 ["Skinning"] = 2,
|
adam@0
|
106 ["Herbalism"] = 3,
|
adam@0
|
107 ["Enchanting"] = 4,
|
adam@0
|
108 ["Jewelcrafting"] = 5,
|
adam@0
|
109 ["Engineering"] = 6,
|
adam@0
|
110 ["Blacksmithing"] = 7,
|
adam@0
|
111 ["Leatherworking"] = 8,
|
adam@0
|
112 ["Inscription"] = 9,
|
adam@0
|
113 ["Tailoring"] = 10,
|
adam@0
|
114 ["Alchemy"] = 11,
|
adam@0
|
115 ["Fishing"] = 12,
|
adam@0
|
116 ["Cooking"] = 13,
|
adam@0
|
117 ["First Aid"] = 14,
|
adam@0
|
118 ["Archaeology"] = 15
|
adam@0
|
119 }
|
adam@0
|
120
|
adam@0
|
121 local raceIds = {
|
adam@0
|
122 ["None"] = 0,
|
adam@0
|
123 ["BloodElf"] = 1,
|
adam@0
|
124 ["Draenei"] = 2,
|
adam@0
|
125 ["Dwarf"] = 3,
|
adam@0
|
126 ["Gnome"] = 4,
|
adam@0
|
127 ["Human"] = 5,
|
adam@0
|
128 ["NightElf"] = 6,
|
adam@0
|
129 ["Orc"] = 7,
|
adam@0
|
130 ["Tauren"] = 8,
|
adam@0
|
131 ["Troll"] = 9,
|
adam@0
|
132 ["Scourge"] = 10,
|
adam@0
|
133 ["Undead"] = 10,
|
adam@0
|
134 ["Goblin"] = 11,
|
adam@0
|
135 ["Worgen"] = 12,
|
adam@0
|
136 ["Pandaren"] = 13
|
adam@0
|
137 }
|
adam@0
|
138
|
adam@0
|
139 local factionIds = {
|
adam@0
|
140 ["None"] = 0,
|
adam@0
|
141 ["Alliance"] = 1,
|
adam@0
|
142 ["Horde"] = 2
|
adam@0
|
143 }
|
adam@0
|
144
|
adam@0
|
145 local function OnExport()
|
adam@0
|
146 if (AmrOptions.exportToClient) then
|
adam@0
|
147 AskMrRobot.SaveAll()
|
adam@0
|
148 ReloadUI()
|
adam@0
|
149 else
|
adam@0
|
150 AskMrRobot_ReforgeFrame:Show()
|
adam@0
|
151 AskMrRobot_ReforgeFrame:ShowTab("export")
|
adam@0
|
152 end
|
adam@0
|
153 end
|
adam@0
|
154
|
adam@0
|
155 function AskMrRobot.eventListener:OnEvent(event, ...)
|
adam@0
|
156 if event == "ADDON_LOADED" then
|
adam@0
|
157 local addon = select(1, ...)
|
adam@0
|
158 if (addon == "AskMrRobot") then
|
adam@0
|
159 print("Loaded Ask Mr. Robot " .. GetAddOnMetadata(AskMrRobot.AddonName, "Version"))
|
adam@0
|
160
|
adam@0
|
161 -- listen for messages from other AMR addons
|
adam@0
|
162 RegisterAddonMessagePrefix(AskMrRobot.ChatPrefix)
|
adam@0
|
163
|
adam@0
|
164 AmrRealmName = GetRealmName()
|
adam@0
|
165 AmrCharacterName = UnitName("player")
|
adam@0
|
166
|
adam@0
|
167 if not AmrLogData then AmrLogData = {} end
|
adam@0
|
168 if not AmrLogData._autoLog then AmrLogData._autoLog = {} end
|
adam@0
|
169 if not AmrLogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] then
|
adam@0
|
170 AmrLogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] = "disabled"
|
adam@0
|
171 end
|
adam@0
|
172
|
adam@0
|
173 if not AmrIconInfo then AmrIconInfo = {} end
|
adam@0
|
174 if not AmrBankItems then AmrBankItems = {} end
|
adam@0
|
175 if not AmrCurrencies then AmrCurrencies = {} end
|
adam@0
|
176 if not AmrSpecializations then AmrSpecializations = {} end
|
adam@0
|
177 if not AmrOptions then AmrOptions = {} end
|
adam@0
|
178 if not AmrGlyphs then AmrGlyphs = {} end
|
adam@0
|
179 if not AmrTalents then AmrTalents = {} end
|
adam@0
|
180 if not AmrBankItemsAndCounts then AmrBankItemsAndCounts = {} end
|
adam@0
|
181 if not AmrImportString then AmrImportString = "" end
|
adam@0
|
182 if not AmrImportDate then AmrImportDate = "" end
|
adam@0
|
183 if not AmrSendSettings then
|
adam@0
|
184 AmrSendSettings = {
|
adam@0
|
185 SendGems = true,
|
adam@0
|
186 SendEnchants = true,
|
adam@0
|
187 SendEnchantMaterials = true,
|
adam@0
|
188 SendToType = "a friend",
|
adam@0
|
189 SendTo = ""
|
adam@0
|
190 }
|
adam@0
|
191 end
|
adam@0
|
192
|
adam@0
|
193 amrLDB = LibStub("LibDataBroker-1.1"):NewDataObject("AskMrRobot", {
|
adam@0
|
194 type = "launcher",
|
adam@0
|
195 text = "Ask Mr. Robot",
|
adam@0
|
196 icon = "Interface\\AddOns\\AskMrRobot\\Media\\icon",
|
adam@0
|
197 OnClick = function()
|
adam@0
|
198
|
adam@0
|
199 if IsModifiedClick("CHATLINK") then
|
adam@0
|
200 OnExport()
|
adam@0
|
201 else
|
adam@0
|
202 AskMrRobot_ReforgeFrame:Toggle()
|
adam@0
|
203 end
|
adam@0
|
204 end,
|
adam@0
|
205 OnTooltipShow = function(tt)
|
adam@0
|
206 tt:AddLine("Ask Mr. Robot", 1, 1, 1);
|
adam@0
|
207 tt:AddLine(" ");
|
adam@0
|
208 tt:AddLine("Left Click to open the Ask Mr. Robot window.\n\nShift + Left Click to export your bag and bank data.")
|
adam@0
|
209 end
|
adam@0
|
210 });
|
adam@0
|
211
|
adam@0
|
212
|
adam@0
|
213 AskMrRobot.AmrUpdateMinimap()
|
adam@0
|
214
|
adam@0
|
215 AskMrRobot_ReforgeFrame = AskMrRobot.AmrUI:new()
|
adam@0
|
216
|
adam@0
|
217 -- remember the import settings between sessions
|
adam@0
|
218 AskMrRobot_ReforgeFrame.summaryTab.importDate = AmrImportDate or ""
|
adam@0
|
219 AskMrRobot_ReforgeFrame.buttons[2]:Click()
|
adam@0
|
220
|
adam@0
|
221 -- the previous import string is loaded when the UI is first shown, otherwise the game spams events and it lags
|
adam@0
|
222 end
|
adam@0
|
223
|
adam@0
|
224 elseif event == "ITEM_PUSH" or event == "DELETE_ITEM_CONFIRM" or event == "UNIT_INVENTORY_CHANGED" or event == "SOCKET_INFO_CLOSE" or event == "PLAYER_SPECIALIZATION_CHANGED" or event == "BAG_UPDATE" then
|
adam@0
|
225 if AskMrRobot_ReforgeFrame then
|
adam@0
|
226 AskMrRobot_ReforgeFrame:OnUpdate()
|
adam@0
|
227 end
|
adam@0
|
228 --AskMrRobot.SaveBags();
|
adam@0
|
229 --AskMrRobot.SaveEquiped();
|
adam@0
|
230 --AskMrRonot.GetCurrencies();
|
adam@0
|
231 --AskMrRobot.GetGold();
|
adam@0
|
232 elseif event == "BANKFRAME_OPENED" or event == "PLAYERBANKSLOTS_CHANGED" then
|
adam@0
|
233 --print("Scanning Bank: " .. event);
|
adam@0
|
234 AskMrRobot.ScanBank();
|
adam@0
|
235 elseif event == "BANKFRAME_CLOSED" then
|
adam@0
|
236 --print("Stop Scanning Bank");
|
adam@0
|
237 --inBank = false;
|
adam@0
|
238 elseif event == "CHARACTER_POINTS_CHANGED" or event == "CONFIRM_TALENT_WIPE" or event == "PLAYER_TALENT_UPDATE" or event == "ACTIVE_TALENT_GROUP_CHANGED" then
|
adam@0
|
239 --AskMrRobot.GetAmrSpecializations();
|
adam@0
|
240 if AskMrRobot_ReforgeFrame then
|
adam@0
|
241 AskMrRobot_ReforgeFrame:OnUpdate()
|
adam@0
|
242 end
|
adam@0
|
243 elseif event == "PLAYER_LEVEL_UP" then
|
adam@0
|
244 --GetLevel();
|
adam@0
|
245 elseif event == "ITEM_UNLOCKED" then
|
adam@0
|
246 AskMrRobot.On_ITEM_UNLOCKED()
|
adam@0
|
247 elseif event == "PLAYER_LOGOUT" then
|
adam@0
|
248 -- doing nothing right now, but leaving this in case we need something here
|
adam@0
|
249 elseif event == "ENCOUNTER_START" then
|
adam@0
|
250 -- send data about this character when a boss fight starts
|
adam@0
|
251 AskMrRobot.SaveAll()
|
adam@0
|
252 AskMrRobot.ExportToAddonChat(time())
|
adam@0
|
253 elseif event == "CHAT_MSG_ADDON" then
|
adam@0
|
254 local chatPrefix, message = select(1, ...)
|
adam@0
|
255 local isLogging = AskMrRobot_ReforgeFrame.combatLogTab:IsLogging()
|
adam@0
|
256 if (isLogging and chatPrefix == AskMrRobot.ChatPrefix) then
|
adam@0
|
257 AskMrRobot_ReforgeFrame.combatLogTab:ReadAddonMessage(message)
|
adam@0
|
258 end
|
adam@0
|
259 elseif event == "UPDATE_INSTANCE_INFO" or event == "PLAYER_DIFFICULTY_CHANGED" then
|
adam@0
|
260 AskMrRobot_ReforgeFrame.combatLogTab:UpdateAutoLogging()
|
adam@0
|
261 end
|
adam@0
|
262
|
adam@0
|
263 end
|
adam@0
|
264
|
adam@0
|
265 AskMrRobot.eventListener:SetScript("OnEvent", AskMrRobot.eventListener.OnEvent);
|
adam@0
|
266
|
adam@0
|
267 local function parseItemLink(input)
|
adam@0
|
268 local itemId, enchantId, gemEnchantId1, gemEnchantId2, gemEnchantId3, gemEnchantId4, suffixId, _, _, reforgeId, upgradeId = string.match(input, "^|.-|Hitem:(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(-?%d+):(-?%d+):(-?%d+):(%d+):(%d+)|");
|
adam@0
|
269 local item = {}
|
adam@0
|
270 item.itemId = tonumber(itemId)
|
adam@0
|
271 item.suffixId = tonumber(suffixId)
|
adam@0
|
272 item.enchantId = tonumber(enchantId)
|
adam@0
|
273 item.reforgeId = tonumber(reforgeId)
|
adam@0
|
274 item.upgradeId = tonumber(upgradeId)
|
adam@0
|
275 item.gemEnchantIds = { tonumber(gemEnchantId1), tonumber(gemEnchantId2), tonumber(gemEnchantId3), tonumber(gemEnchantId4) }
|
adam@0
|
276 return item
|
adam@0
|
277 end
|
adam@0
|
278
|
adam@0
|
279 SLASH_AMR1 = "/amr";
|
adam@0
|
280 function SlashCmdList.AMR(msg)
|
adam@0
|
281
|
adam@0
|
282 if msg == 'toggle' then
|
adam@0
|
283 AskMrRobot_ReforgeFrame:Toggle()
|
adam@0
|
284 elseif msg == 'show' then
|
adam@0
|
285 AskMrRobot_ReforgeFrame:Show()
|
adam@0
|
286 elseif msg == 'hide' then
|
adam@0
|
287 AskMrRobot_ReforgeFrame:Hide()
|
adam@0
|
288 elseif msg == 'export' then
|
adam@0
|
289 OnExport()
|
adam@0
|
290 else
|
adam@0
|
291 print('Available AskMrRobot slash commands:\n' ..
|
adam@0
|
292 ' /amr show -- show the main window\n' ..
|
adam@0
|
293 ' /amr hide -- hide the main window\n' ..
|
adam@0
|
294 ' /amr toggle -- toggle the main window\n' ..
|
adam@0
|
295 ' /amr export -- export bag and bank data (uses your last selected method and either opens the copy/paste window, or saves and reloads ui)')
|
adam@0
|
296 end
|
adam@0
|
297 end
|
adam@0
|
298
|
adam@0
|
299 function AskMrRobot.SaveAll()
|
adam@0
|
300 AskMrRobot.ScanBank()
|
adam@0
|
301 AskMrRobot.SaveBags()
|
adam@0
|
302 AskMrRobot.SaveEquiped()
|
adam@0
|
303 AskMrRobot.GetCurrencies()
|
adam@0
|
304 AskMrRobot.GetGold()
|
adam@0
|
305 AskMrRobot.GetAmrSpecializations()
|
adam@0
|
306 AskMrRobot.GetAmrProfessions()
|
adam@0
|
307 AskMrRobot.GetRace()
|
adam@0
|
308 AskMrRobot.GetLevel()
|
adam@0
|
309 AskMrRobot.GetAmrGlyphs()
|
adam@0
|
310 AskMrRobot.GetAmrTalents()
|
adam@0
|
311 --ReloadUI()
|
adam@0
|
312 end
|
adam@0
|
313
|
adam@0
|
314 local function InitIcon()
|
adam@0
|
315 icon = LibStub("LibDBIcon-1.0");
|
adam@0
|
316 icon:Register("AskMrRobot", amrLDB, AmrIconInfo);
|
adam@0
|
317 end
|
adam@0
|
318
|
adam@0
|
319 function AskMrRobot.AmrUpdateMinimap()
|
adam@0
|
320 if (AmrOptions.hideMapIcon) then
|
adam@0
|
321 if (icon) then
|
adam@0
|
322 icon:Hide("AskMrRobot");
|
adam@0
|
323 end
|
adam@0
|
324 else
|
adam@0
|
325 if (not icon) then
|
adam@0
|
326 InitIcon()
|
adam@0
|
327 end
|
adam@0
|
328 icon:Show("AskMrRobot");
|
adam@0
|
329 end
|
adam@0
|
330 end
|
adam@0
|
331
|
adam@0
|
332 local function getToolTipText(tip)
|
adam@0
|
333 return EnumerateTooltipLines_helper(tip:GetRegions())
|
adam@0
|
334 end
|
adam@0
|
335
|
adam@0
|
336 local bagItems = {}
|
adam@0
|
337 local bagItemsWithCount = {}
|
adam@0
|
338
|
adam@0
|
339 function AskMrRobot.ScanBag(bagId)
|
adam@0
|
340 local numSlots = GetContainerNumSlots(bagId);
|
adam@0
|
341 for slotId = 1, numSlots do
|
adam@0
|
342 local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId);
|
adam@0
|
343 if itemLink ~= nil then
|
adam@0
|
344 local itemData = parseItemLink(itemLink)
|
adam@0
|
345 if itemData.itemId ~= nil then
|
adam@0
|
346 tinsert(bagItems, itemLink);
|
adam@0
|
347 tinsert(bagItemsWithCount, {link = itemLink, count = itemCount})
|
adam@0
|
348 end
|
adam@0
|
349 end
|
adam@0
|
350 end
|
adam@0
|
351 end
|
adam@0
|
352
|
adam@0
|
353 local BACKPACK_CONTAINER = 0;
|
adam@0
|
354 local BANK_CONTAINER = -1;
|
adam@0
|
355
|
adam@0
|
356 function AskMrRobot.ScanEquiped()
|
adam@0
|
357 local equipedItems = {};
|
adam@0
|
358 for slotNum = 1, #AskMrRobot.slotIds do
|
adam@0
|
359 local slotId = AskMrRobot.slotIds[slotNum];
|
adam@0
|
360 local itemLink = GetInventoryItemLink("player", slotId);
|
adam@0
|
361 if (itemLink ~= nil) then
|
adam@0
|
362 equipedItems[slotId .. ""] = itemLink;
|
adam@0
|
363 end
|
adam@0
|
364 end
|
adam@0
|
365 return equipedItems
|
adam@0
|
366 end
|
adam@0
|
367
|
adam@0
|
368 function AskMrRobot.SaveEquiped()
|
adam@0
|
369 AmrEquipedItems = AskMrRobot.ScanEquiped();
|
adam@0
|
370 end
|
adam@0
|
371
|
adam@0
|
372 function AskMrRobot.ScanBags()
|
adam@0
|
373 bagItems = {}
|
adam@0
|
374 bagItemsWithCount = {}
|
adam@0
|
375
|
adam@0
|
376 AskMrRobot.ScanBag(BACKPACK_CONTAINER); -- backpack
|
adam@0
|
377
|
adam@0
|
378 for bagId = 1, NUM_BAG_SLOTS do
|
adam@0
|
379 AskMrRobot.ScanBag(bagId);
|
adam@0
|
380 end
|
adam@0
|
381
|
adam@0
|
382
|
adam@0
|
383 return bagItems, bagItemsWithCount
|
adam@0
|
384 end
|
adam@0
|
385
|
adam@0
|
386 function AskMrRobot.SaveBags()
|
adam@0
|
387 AmrBagItems, _ = AskMrRobot.ScanBags()
|
adam@0
|
388 end
|
adam@0
|
389
|
adam@0
|
390 function AskMrRobot.GetGold()
|
adam@0
|
391 AmrGold = GetMoney();
|
adam@0
|
392 end
|
adam@0
|
393
|
adam@0
|
394 local lastBankBagId = nil;
|
adam@0
|
395 local lastBankSlotId = nil;
|
adam@0
|
396 local bankItems = {};
|
adam@0
|
397 local bankItemsAndCount = {};
|
adam@0
|
398 AmrBankItemsAndCounts = {};
|
adam@0
|
399
|
adam@0
|
400 local function ScanBankBag(bagId)
|
adam@0
|
401 local numSlots = GetContainerNumSlots(bagId);
|
adam@0
|
402 for slotId = 1, numSlots do
|
adam@0
|
403 local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId);
|
adam@0
|
404 if itemLink ~= nil then
|
adam@0
|
405 local itemData = parseItemLink(itemLink)
|
adam@0
|
406 if itemData.itemId ~= nil then
|
adam@0
|
407 lastBankBagId = bagId;
|
adam@0
|
408 lastBankSlotId = slotId;
|
adam@0
|
409 tinsert(bankItems, itemLink);
|
adam@0
|
410 tinsert(bankItemsAndCount, {link = itemLink, count = itemCount})
|
adam@0
|
411 end
|
adam@0
|
412 end
|
adam@0
|
413 end
|
adam@0
|
414 end
|
adam@0
|
415
|
adam@0
|
416 function AskMrRobot.ScanBank()
|
adam@0
|
417
|
adam@0
|
418 bankItems = {};
|
adam@0
|
419 bankItemsAndCount = {}
|
adam@0
|
420
|
adam@0
|
421 ScanBankBag(BANK_CONTAINER);
|
adam@0
|
422 for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do
|
adam@0
|
423 ScanBankBag(bagId);
|
adam@0
|
424 end
|
adam@0
|
425
|
adam@0
|
426 -- see if the scan completed before the window closed
|
adam@0
|
427 if lastBankBagId ~= nil then
|
adam@0
|
428 local itemLink = GetContainerItemLink(lastBankBagId, lastBankSlotId);
|
adam@0
|
429 if itemLink ~= nil then --still open
|
adam@0
|
430 AmrBankItems = bankItems;
|
adam@0
|
431 AmrBankItemsAndCounts = bankItemsAndCount
|
adam@0
|
432 end
|
adam@0
|
433 end
|
adam@0
|
434 end
|
adam@0
|
435
|
adam@0
|
436 local function GetCurrencyAmount(index)
|
adam@0
|
437 local localized_label, amount, icon_file_name = GetCurrencyInfo(index);
|
adam@0
|
438 return amount;
|
adam@0
|
439 end
|
adam@0
|
440
|
adam@0
|
441 function AskMrRobot.GetCurrencies()
|
adam@0
|
442 local currencies = {};
|
adam@0
|
443 local currencyList = {61, 81, 241, 361, 384, 394, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 416, 515, 614, 615, 676, 679};
|
adam@0
|
444
|
adam@0
|
445 for i, currency in pairs(currencyList) do
|
adam@0
|
446 local amount = GetCurrencyAmount(currency);
|
adam@0
|
447 if amount ~= 0 then
|
adam@0
|
448 currencies[currencyList[i]] = amount;
|
adam@0
|
449 end
|
adam@0
|
450 end
|
adam@0
|
451 AmrCurrencies = currencies;
|
adam@0
|
452 end
|
adam@0
|
453
|
adam@0
|
454 local function GetAmrSpecialization(specGroup)
|
adam@0
|
455 local spec = GetSpecialization(false, false, specGroup);
|
adam@0
|
456 return spec and GetSpecializationInfo(spec);
|
adam@0
|
457 end
|
adam@0
|
458
|
adam@0
|
459 function AskMrRobot.GetAmrSpecializations()
|
adam@0
|
460
|
adam@0
|
461 AmrSpecializations = {};
|
adam@0
|
462
|
adam@0
|
463 AmrActiveSpec = GetActiveSpecGroup();
|
adam@0
|
464
|
adam@0
|
465 for group = 1, 2 do
|
adam@0
|
466 AmrSpecializations[group .. ""] = GetAmrSpecialization(group)
|
adam@0
|
467 end
|
adam@0
|
468
|
adam@0
|
469 -- Death Knight
|
adam@0
|
470 -- 250 - Blood
|
adam@0
|
471 -- 251 - Frost
|
adam@0
|
472 -- 252 - Unholy
|
adam@0
|
473 -- Druid
|
adam@0
|
474 -- 102 - Balance
|
adam@0
|
475 -- 103 - Feral Combat
|
adam@0
|
476 -- 104 - Guardian
|
adam@0
|
477 -- 105 - Restoration
|
adam@0
|
478 -- Hunter
|
adam@0
|
479 -- 253 - Beast Mastery
|
adam@0
|
480 -- 254 - Marksmanship
|
adam@0
|
481 -- 255 - Survival
|
adam@0
|
482 -- Mage
|
adam@0
|
483 -- 62 - Arcane
|
adam@0
|
484 -- 63 - Fire
|
adam@0
|
485 -- 64 - Frost
|
adam@0
|
486 -- Monk
|
adam@0
|
487 -- 268 - Brewmaster
|
adam@0
|
488 -- 269 - Windwalker
|
adam@0
|
489 -- 270 - Mistweaver
|
adam@0
|
490 -- Paladin
|
adam@0
|
491 -- 65 - Holy
|
adam@0
|
492 -- 66 - Protection
|
adam@0
|
493 -- 70 - Retribution
|
adam@0
|
494 -- Priest
|
adam@0
|
495 -- 256 Discipline
|
adam@0
|
496 -- 257 Holy
|
adam@0
|
497 -- 258 Shadow
|
adam@0
|
498 -- Rogue
|
adam@0
|
499 -- 259 - Assassination
|
adam@0
|
500 -- 260 - Combat
|
adam@0
|
501 -- 261 - Subtlety
|
adam@0
|
502 -- Shaman
|
adam@0
|
503 -- 262 - Elemental
|
adam@0
|
504 -- 263 - Enhancement
|
adam@0
|
505 -- 264 - Restoration
|
adam@0
|
506 -- Warlock
|
adam@0
|
507 -- 265 - Affliction
|
adam@0
|
508 -- 266 - Demonology
|
adam@0
|
509 -- 267 - Destruction
|
adam@0
|
510 -- Warrior
|
adam@0
|
511 -- 71 - Arms
|
adam@0
|
512 -- 72 - Fury
|
adam@0
|
513 -- 73 - Protection
|
adam@0
|
514 end
|
adam@0
|
515
|
adam@0
|
516 function AskMrRobot.GetAmrProfessions()
|
adam@0
|
517
|
adam@0
|
518 local profMap = {
|
adam@0
|
519 [794] = "Archaeology",
|
adam@0
|
520 [171] = "Alchemy",
|
adam@0
|
521 [164] = "Blacksmithing",
|
adam@0
|
522 [185] = "Cooking",
|
adam@0
|
523 [333] = "Enchanting",
|
adam@0
|
524 [202] = "Engineering",
|
adam@0
|
525 [129] = "First Aid",
|
adam@0
|
526 [356] = "Fishing",
|
adam@0
|
527 [182] = "Herbalism",
|
adam@0
|
528 [773] = "Inscription",
|
adam@0
|
529 [755] = "Jewelcrafting",
|
adam@0
|
530 [165] = "Leatherworking",
|
adam@0
|
531 [186] = "Mining",
|
adam@0
|
532 [393] = "Skinning",
|
adam@0
|
533 [197] = "Tailoring"
|
adam@0
|
534 }
|
adam@0
|
535
|
adam@0
|
536 local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions();
|
adam@0
|
537 AmrProfessions = {};
|
adam@0
|
538 if prof1 then
|
adam@0
|
539 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof1);
|
adam@0
|
540 if profMap[skillLine] ~= nil then
|
adam@0
|
541 AmrProfessions[profMap[skillLine]] = skillLevel;
|
adam@0
|
542 end
|
adam@0
|
543 end
|
adam@0
|
544 if prof2 then
|
adam@0
|
545 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof2);
|
adam@0
|
546 if profMap[skillLine] ~= nil then
|
adam@0
|
547 AmrProfessions[profMap[skillLine]] = skillLevel;
|
adam@0
|
548 end
|
adam@0
|
549 end
|
adam@0
|
550 if archaeology then
|
adam@0
|
551 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(archaeology);
|
adam@0
|
552 if profMap[skillLine] ~= nil then
|
adam@0
|
553 AmrProfessions[profMap[skillLine]] = skillLevel;
|
adam@0
|
554 end
|
adam@0
|
555 end
|
adam@0
|
556 if fishing then
|
adam@0
|
557 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(fishing);
|
adam@0
|
558 if profMap[skillLine] ~= nil then
|
adam@0
|
559 AmrProfessions[profMap[skillLine]] = skillLevel;
|
adam@0
|
560 end
|
adam@0
|
561 end
|
adam@0
|
562 if cooking then
|
adam@0
|
563 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(cooking);
|
adam@0
|
564 if profMap[skillLine] ~= nil then
|
adam@0
|
565 AmrProfessions[profMap[skillLine]] = skillLevel;
|
adam@0
|
566 end
|
adam@0
|
567 end
|
adam@0
|
568 if firstAid then
|
adam@0
|
569 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(firstAid);
|
adam@0
|
570 if profMap[skillLine] ~= nil then
|
adam@0
|
571 AmrProfessions[profMap[skillLine]] = skillLevel;
|
adam@0
|
572 end
|
adam@0
|
573 end
|
adam@0
|
574 end
|
adam@0
|
575
|
adam@0
|
576 function AskMrRobot.GetRace()
|
adam@0
|
577 local race, raceEn = UnitRace("player");
|
adam@0
|
578 AmrRace = raceEn;
|
adam@0
|
579 AmrFaction = UnitFactionGroup("player");
|
adam@0
|
580 end
|
adam@0
|
581
|
adam@0
|
582 function AskMrRobot.GetLevel()
|
adam@0
|
583 AmrLevel = UnitLevel("player");
|
adam@0
|
584 end
|
adam@0
|
585
|
adam@0
|
586 local SlotNames = {
|
adam@0
|
587 "HeadSlot",
|
adam@0
|
588 "NeckSlot",
|
adam@0
|
589 "ShoulderSlot",
|
adam@0
|
590 "ShirtSlot",
|
adam@0
|
591 "ChestSlot",
|
adam@0
|
592 "WaistSlot",
|
adam@0
|
593 "LegsSlot",
|
adam@0
|
594 "FeetSlot",
|
adam@0
|
595 "WristSlot",
|
adam@0
|
596 "HandsSlot",
|
adam@0
|
597 "Finger0Slot",
|
adam@0
|
598 "Finger1Slot",
|
adam@0
|
599 "Trinket0Slot",
|
adam@0
|
600 "Trinket1Slot",
|
adam@0
|
601 "BackSlot",
|
adam@0
|
602 "MainHandSlot",
|
adam@0
|
603 "SecondaryHandSlot",
|
adam@0
|
604 -- "RangedSlot",
|
adam@0
|
605 "TabardSlot",
|
adam@0
|
606 }
|
adam@0
|
607
|
adam@0
|
608 local function GetAmrTalentsForSpec(spec)
|
adam@0
|
609 local talentInfo = {}
|
adam@0
|
610 local maxTiers = 6
|
adam@0
|
611 for talent = 1, GetNumTalents() do
|
adam@0
|
612 local name, texture, tier, column, selected, available = GetTalentInfo(talent, false, spec)
|
adam@0
|
613 if tier > maxTiers then
|
adam@0
|
614 maxTiers = tier
|
adam@0
|
615 end
|
adam@0
|
616 if selected then
|
adam@0
|
617 talentInfo[tier] = column
|
adam@0
|
618 end
|
adam@0
|
619 end
|
adam@0
|
620
|
adam@0
|
621 local str = ""
|
adam@0
|
622 for i = 1, maxTiers do
|
adam@0
|
623 if talentInfo[i] then
|
adam@0
|
624 str = str .. talentInfo[i]
|
adam@0
|
625 else
|
adam@0
|
626 str = str .. '0'
|
adam@0
|
627 end
|
adam@0
|
628 end
|
adam@0
|
629
|
adam@0
|
630 return str
|
adam@0
|
631 end
|
adam@0
|
632
|
adam@0
|
633 function AskMrRobot.GetAmrTalents()
|
adam@0
|
634 AmrTalents = {}
|
adam@0
|
635 for spec = 1, GetNumSpecGroups() do
|
adam@0
|
636 AmrTalents[spec] = GetAmrTalentsForSpec(spec);
|
adam@0
|
637 end
|
adam@0
|
638 end
|
adam@0
|
639
|
adam@0
|
640 local function GetAmrGlyphsForSpec(spec)
|
adam@0
|
641 local glyphs = {}
|
adam@0
|
642 for i = 1, NUM_GLYPH_SLOTS do
|
adam@0
|
643 local _, _, _, glyphSpellID, _, glyphID = GetGlyphSocketInfo(i, spec)
|
adam@0
|
644 if (glyphID) then
|
adam@0
|
645 tinsert(glyphs, glyphSpellID)
|
adam@0
|
646 end
|
adam@0
|
647 end
|
adam@0
|
648 return glyphs;
|
adam@0
|
649 end
|
adam@0
|
650
|
adam@0
|
651 function AskMrRobot.GetAmrGlyphs()
|
adam@0
|
652 AmrGlyphs = {}
|
adam@0
|
653 for spec = 1, GetNumSpecGroups() do
|
adam@0
|
654 AmrGlyphs[spec] = GetAmrGlyphsForSpec(spec)
|
adam@0
|
655 end
|
adam@0
|
656 end
|
adam@0
|
657
|
adam@0
|
658 --[[
|
adam@0
|
659 local function ItemLinkToExportString(itemLink, slot)
|
adam@0
|
660 local itemData = parseItemLink(itemLink)
|
adam@0
|
661 local ret = {}
|
adam@0
|
662 table.insert(ret, slot)
|
adam@0
|
663 table.insert(ret, itemData.itemId)
|
adam@0
|
664 table.insert(ret, itemData.suffixId)
|
adam@0
|
665 table.insert(ret, itemData.upgradeId)
|
adam@0
|
666 table.insert(ret, itemData.gemEnchantIds[1])
|
adam@0
|
667 table.insert(ret, itemData.gemEnchantIds[2])
|
adam@0
|
668 table.insert(ret, itemData.gemEnchantIds[3])
|
adam@0
|
669 table.insert(ret, itemData.enchantId)
|
adam@0
|
670 table.insert(ret, itemData.reforgeId)
|
adam@0
|
671 return table.concat(ret, ":")
|
adam@0
|
672 end
|
adam@0
|
673 ]]
|
adam@0
|
674
|
adam@0
|
675 local function toCompressedNumberList(list)
|
adam@0
|
676 -- ensure the values are numbers, sorted from lowest to highest
|
adam@0
|
677 local nums = {}
|
adam@0
|
678 for i, v in ipairs(list) do
|
adam@0
|
679 table.insert(nums, tonumber(v))
|
adam@0
|
680 end
|
adam@0
|
681 table.sort(nums)
|
adam@0
|
682
|
adam@0
|
683 local ret = {}
|
adam@0
|
684 local prev = 0
|
adam@0
|
685 for i, v in ipairs(nums) do
|
adam@0
|
686 local diff = v - prev
|
adam@0
|
687 table.insert(ret, diff)
|
adam@0
|
688 prev = v
|
adam@0
|
689 end
|
adam@0
|
690
|
adam@0
|
691 return table.concat(ret, ",")
|
adam@0
|
692 end
|
adam@0
|
693
|
adam@0
|
694 -- create a more compact but less readable string
|
adam@0
|
695 function AskMrRobot.ExportToCompressedString(includeInventory)
|
adam@0
|
696 local fields = {}
|
adam@0
|
697
|
adam@0
|
698 -- compressed string uses a fixed order rather than inserting identifiers
|
adam@0
|
699 table.insert(fields, GetAddOnMetadata(AskMrRobot.AddonName, "Version"))
|
adam@0
|
700 table.insert(fields, AmrRealmName)
|
adam@0
|
701 table.insert(fields, AmrCharacterName)
|
adam@0
|
702
|
adam@0
|
703 -- guild name
|
adam@0
|
704 local guildName = GetGuildInfo("player")
|
adam@0
|
705 if guildName == nil then
|
adam@0
|
706 table.insert(fields, "")
|
adam@0
|
707 else
|
adam@0
|
708 table.insert(fields, guildName)
|
adam@0
|
709 end
|
adam@0
|
710
|
adam@0
|
711 -- race, default to pandaren if we can't read it for some reason
|
adam@0
|
712 local raceval = raceIds[AmrRace]
|
adam@0
|
713 if raceval == nil then raceval = 13 end
|
adam@0
|
714 table.insert(fields, raceval)
|
adam@0
|
715
|
adam@0
|
716 -- faction, default to alliance if we can't read it for some reason
|
adam@0
|
717 raceval = factionIds[AmrFaction]
|
adam@0
|
718 if raceval == nil then raceval = 1 end
|
adam@0
|
719 table.insert(fields, raceval)
|
adam@0
|
720
|
adam@0
|
721 table.insert(fields, AmrLevel)
|
adam@0
|
722
|
adam@0
|
723 local profs = {}
|
adam@0
|
724 local noprofs = true
|
adam@0
|
725 for k, v in pairs(AmrProfessions) do
|
adam@0
|
726 local profval = professionIds[k]
|
adam@0
|
727 if profval ~= nil then
|
adam@0
|
728 noprofs = false
|
adam@0
|
729 table.insert(profs, profval .. ":" .. v)
|
adam@0
|
730 end
|
adam@0
|
731 end
|
adam@0
|
732
|
adam@0
|
733 if noprofs then
|
adam@0
|
734 table.insert(profs, "0:0")
|
adam@0
|
735 end
|
adam@0
|
736
|
adam@0
|
737 table.insert(fields, table.concat(profs, ","))
|
adam@0
|
738
|
adam@0
|
739 if (AmrActiveSpec ~= nil) then
|
adam@0
|
740 table.insert(fields, AmrActiveSpec)
|
adam@0
|
741 table.insert(fields, AmrSpecializations[AmrActiveSpec .. ""])
|
adam@0
|
742 table.insert(fields, AmrTalents[AmrActiveSpec])
|
adam@0
|
743 table.insert(fields, toCompressedNumberList(AmrGlyphs[AmrActiveSpec]))
|
adam@0
|
744 else
|
adam@0
|
745 table.insert(fields, "_")
|
adam@0
|
746 table.insert(fields, "_")
|
adam@0
|
747 table.insert(fields, "_")
|
adam@0
|
748 table.insert(fields, "_")
|
adam@0
|
749 end
|
adam@0
|
750
|
adam@0
|
751 -- convert items to parsed objects, sorted by id
|
adam@0
|
752 local itemObjects = {}
|
adam@0
|
753 for k, v in pairs(AmrEquipedItems) do
|
adam@0
|
754 local itemData = parseItemLink(v)
|
adam@0
|
755 itemData.slot = k
|
adam@0
|
756 table.insert(itemObjects, itemData)
|
adam@0
|
757 end
|
adam@0
|
758
|
adam@0
|
759 -- if desired, include bank/bag items too
|
adam@0
|
760 if includeInventory then
|
adam@0
|
761 for i, v in ipairs(AmrBagItems) do
|
adam@0
|
762 local itemData = parseItemLink(v)
|
adam@0
|
763 if itemData.itemId ~= nil then
|
adam@0
|
764 table.insert(itemObjects, itemData)
|
adam@0
|
765 end
|
adam@0
|
766 end
|
adam@0
|
767 for i, v in ipairs(AmrBankItems) do
|
adam@0
|
768 local itemData = parseItemLink(v)
|
adam@0
|
769 if itemData.itemId ~= nil then
|
adam@0
|
770 table.insert(itemObjects, itemData)
|
adam@0
|
771 end
|
adam@0
|
772 end
|
adam@0
|
773 end
|
adam@0
|
774
|
adam@0
|
775 -- sort by item id so we can compress it more easily
|
adam@0
|
776 table.sort(itemObjects, function(a, b) return a.itemId < b.itemId end)
|
adam@0
|
777
|
adam@0
|
778 -- append to the export string
|
adam@0
|
779 local prevItemId = 0
|
adam@0
|
780 local prevGemId = 0
|
adam@0
|
781 local prevEnchantId = 0
|
adam@0
|
782 for i, itemData in ipairs(itemObjects) do
|
adam@0
|
783
|
adam@0
|
784 local itemParts = {}
|
adam@0
|
785
|
adam@0
|
786 table.insert(itemParts, itemData.itemId - prevItemId)
|
adam@0
|
787 prevItemId = itemData.itemId
|
adam@0
|
788
|
adam@0
|
789 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end
|
adam@0
|
790 if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end
|
adam@0
|
791 if upgradeTable[itemData.upgradeId] ~= 0 then table.insert(itemParts, "u" .. upgradeTable[itemData.upgradeId]) end
|
adam@0
|
792 if itemData.gemEnchantIds[1] ~= 0 then
|
adam@0
|
793 table.insert(itemParts, "a" .. (itemData.gemEnchantIds[1] - prevGemId))
|
adam@0
|
794 prevGemId = itemData.gemEnchantIds[1]
|
adam@0
|
795 end
|
adam@0
|
796 if itemData.gemEnchantIds[2] ~= 0 then
|
adam@0
|
797 table.insert(itemParts, "b" .. (itemData.gemEnchantIds[2] - prevGemId))
|
adam@0
|
798 prevGemId = itemData.gemEnchantIds[2]
|
adam@0
|
799 end
|
adam@0
|
800 if itemData.gemEnchantIds[3] ~= 0 then
|
adam@0
|
801 table.insert(itemParts, "c" .. (itemData.gemEnchantIds[3] - prevGemId))
|
adam@0
|
802 prevGemId = itemData.gemEnchantIds[3]
|
adam@0
|
803 end
|
adam@0
|
804 if itemData.enchantId ~= 0 then
|
adam@0
|
805 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId))
|
adam@0
|
806 prevEnchantId = itemData.enchantId
|
adam@0
|
807 end
|
adam@0
|
808 if itemData.reforgeId ~= 0 then table.insert(itemParts, "r" .. (itemData.reforgeId - 113)) end
|
adam@0
|
809
|
adam@0
|
810 table.insert(fields, table.concat(itemParts, ""))
|
adam@0
|
811 end
|
adam@0
|
812
|
adam@0
|
813 return "$" .. table.concat(fields, ";") .. "$"
|
adam@0
|
814 end
|
adam@0
|
815
|
adam@0
|
816 function AskMrRobot.ExportToAddonChat(timestamp)
|
adam@0
|
817 local data = AskMrRobot.ExportToCompressedString(false)
|
adam@0
|
818 local msgPrefix = timestamp .. "\n" .. AmrRealmName .. "\n" .. AmrCharacterName .. "\n"
|
adam@0
|
819
|
adam@0
|
820 -- break the data into 250 character chunks (to deal with the short limit on addon message size)
|
adam@0
|
821 local chunks = {}
|
adam@0
|
822 local i = 1
|
adam@0
|
823 local length = string.len(data)
|
adam@0
|
824 local chunkLen = 249 - string.len(msgPrefix)
|
adam@0
|
825 while (i <= length) do
|
adam@0
|
826 local endpos = math.min(i + chunkLen, length)
|
adam@0
|
827 table.insert(chunks, msgPrefix .. string.sub(data, i, endpos))
|
adam@0
|
828 i = endpos + 1
|
adam@0
|
829 end
|
adam@0
|
830
|
adam@0
|
831 for i, v in ipairs(chunks) do
|
adam@0
|
832 SendAddonMessage(AskMrRobot.ChatPrefix, v, "RAID")
|
adam@0
|
833 end
|
adam@0
|
834
|
adam@0
|
835 -- send a completion message
|
adam@0
|
836 SendAddonMessage(AskMrRobot.ChatPrefix, msgPrefix .. "done", "RAID")
|
adam@0
|
837 end
|
adam@0
|
838
|
adam@0
|
839 -- Create an export string that can be copied to the website
|
adam@0
|
840 function AskMrRobot.ExportToString()
|
adam@0
|
841
|
adam@0
|
842 --[[
|
adam@0
|
843 local fields = {}
|
adam@0
|
844
|
adam@0
|
845 fields["realm"] = AmrRealmName
|
adam@0
|
846 fields["name"] = AmrCharacterName
|
adam@0
|
847 fields["race"] = AmrRace
|
adam@0
|
848 fields["faction"] = AmrFaction
|
adam@0
|
849 fields["level"] = AmrLevel
|
adam@0
|
850
|
adam@0
|
851 local profs = {}
|
adam@0
|
852 for k, v in pairs(AmrProfessions) do
|
adam@0
|
853 table.insert(profs, k .. ":" .. v)
|
adam@0
|
854 end
|
adam@0
|
855 fields["professions"] = table.concat(profs, ",")
|
adam@0
|
856
|
adam@0
|
857 if (AmrActiveSpec ~= nil) then
|
adam@0
|
858 fields["activespec"] = AmrActiveSpec
|
adam@0
|
859 fields["spec"] = AmrSpecializations[AmrActiveSpec .. ""]
|
adam@0
|
860 fields["talents"] = AmrTalents[AmrActiveSpec]
|
adam@0
|
861 fields["glyphs"] = table.concat(AmrGlyphs[AmrActiveSpec], ",")
|
adam@0
|
862 end
|
adam@0
|
863
|
adam@0
|
864 local items = {}
|
adam@0
|
865 for k, v in pairs(AmrEquipedItems) do
|
adam@0
|
866 table.insert(items, ItemLinkToExportString(v, k))
|
adam@0
|
867 end
|
adam@0
|
868 for i, v in ipairs(AmrBagItems) do
|
adam@0
|
869 table.insert(items, ItemLinkToExportString(v, "-1"))
|
adam@0
|
870 end
|
adam@0
|
871 for i, v in ipairs(AmrBankItems) do
|
adam@0
|
872 table.insert(items, ItemLinkToExportString(v, "-1"))
|
adam@0
|
873 end
|
adam@0
|
874 fields["items"] = table.concat(items, "_")
|
adam@0
|
875
|
adam@0
|
876 local fieldList = {}
|
adam@0
|
877 for k, v in pairs(fields) do
|
adam@0
|
878 table.insert(fieldList, k .. "=" .. v)
|
adam@0
|
879 end
|
adam@0
|
880 ]]
|
adam@0
|
881
|
adam@0
|
882 --return table.concat(fieldList, ";")
|
adam@0
|
883
|
adam@0
|
884 return AskMrRobot.ExportToCompressedString(true)
|
adam@0
|
885 --return AskMrRobot.ExportToAddonChat(time())
|
adam@0
|
886 end
|
adam@0
|
887
|
adam@0
|
888 local function parseGlyphs(input)
|
adam@0
|
889 local glyphs = {}
|
adam@0
|
890 for glyph in string.gmatch(input, "([^,]+)") do
|
adam@0
|
891 tinsert(glyphs, glyph)
|
adam@0
|
892 end
|
adam@0
|
893 table.sort(glyphs)
|
adam@0
|
894 return glyphs
|
adam@0
|
895 end
|
adam@0
|
896
|
adam@0
|
897 local function parseProfessions(input)
|
adam@0
|
898 local professions = {}
|
adam@0
|
899 for prof, v in string.gmatch(input, "([^:,]+):([^,]+)") do
|
adam@0
|
900 professions[prof] = tonumber(v);
|
adam@0
|
901 end
|
adam@0
|
902 return professions;
|
adam@0
|
903 end
|
adam@0
|
904
|
adam@0
|
905 local gemColorMapping = {
|
adam@0
|
906 y = 'Yellow',
|
adam@0
|
907 b = 'Blue',
|
adam@0
|
908 r = 'Red',
|
adam@0
|
909 h = 'Hydraulic',
|
adam@0
|
910 p = 'Prismatic',
|
adam@0
|
911 m = 'Meta',
|
adam@0
|
912 c = 'Cogwheel'
|
adam@0
|
913 }
|
adam@0
|
914
|
adam@0
|
915 local function parseAmrItem(input)
|
adam@0
|
916 local slot, itemId, suffixList, upgradeId, gemColorString, gemEnchantIdString, gemIdString, enchantId, reforgeId = string.match(input, "^(%d+):(%d+):([^:]+):([^:]+):([^:]+):([^:]+):([^:]+):(%d+):(%d+)");
|
adam@0
|
917 -- parse the gem enchant ids out of their comma seperated list
|
adam@0
|
918 local gems = {}
|
adam@0
|
919 for gemEnchantId in string.gmatch(gemEnchantIdString, '(%d+)') do
|
adam@0
|
920 tinsert(gems, {enchantId = tonumber(gemEnchantId), id = 0})
|
adam@0
|
921 end
|
adam@0
|
922 -- make sure we have 4 gem ids
|
adam@0
|
923 for i = #gems + 1, 4 do
|
adam@0
|
924 tinsert(gems, {enchantId = 0, id = 0})
|
adam@0
|
925 end
|
adam@0
|
926 -- parse the gem ids out of their comma seperated list
|
adam@0
|
927 local gemIds = {}
|
adam@0
|
928 i = 1
|
adam@0
|
929 for gemId in string.gmatch(gemIdString, '(%d+)') do
|
adam@0
|
930 gems[i].id = tonumber(gemId)
|
adam@0
|
931 i = i + 1
|
adam@0
|
932 end
|
adam@0
|
933 i = 1
|
adam@0
|
934 for gemColor in string.gmatch(gemColorString, '([^,])') do
|
adam@0
|
935 gems[i].color = gemColorMapping[gemColor]
|
adam@0
|
936 i = i + 1
|
adam@0
|
937 end
|
adam@0
|
938
|
adam@0
|
939 -- parse the possible suffixes out of their comma seperated list and put them in a set (number -> bool)
|
adam@0
|
940 local suffixes = {}
|
adam@0
|
941 for suffixId in string.gmatch(suffixList, '(%-?%d+)') do
|
adam@0
|
942 suffixes[tonumber(suffixId)] = true
|
adam@0
|
943 end
|
adam@0
|
944
|
adam@0
|
945 local item = {
|
adam@0
|
946 itemId = tonumber(itemId),
|
adam@0
|
947 suffixes = suffixes,
|
adam@0
|
948 upgradeId = tonumber(upgradeId),
|
adam@0
|
949 gems = gems,
|
adam@0
|
950 enchantId = tonumber(enchantId),
|
adam@0
|
951 reforgeId = tonumber(reforgeId)
|
adam@0
|
952 }
|
adam@0
|
953 return slot, item
|
adam@0
|
954 end
|
adam@0
|
955
|
adam@0
|
956
|
adam@0
|
957 function AskMrRobot.parseAmr(input)
|
adam@0
|
958 local parsedInput = {}
|
adam@0
|
959 parsedInput.items = {}
|
adam@0
|
960 for k, v in string.gmatch(input, "([^=;]+)=([^;]*)") do
|
adam@0
|
961 if (k == 'item') then
|
adam@0
|
962 local slot, item = parseAmrItem(v);
|
adam@0
|
963 parsedInput.items[AskMrRobot.slotIdToSlotNum[tonumber(slot) + 1]] = item;
|
adam@0
|
964 elseif (k == 'glyphs') then
|
adam@0
|
965 parsedInput.glyphs = parseGlyphs(v)
|
adam@0
|
966 elseif (k == 'professions') then
|
adam@0
|
967 parsedInput.professions = parseProfessions(v)
|
adam@0
|
968 else
|
adam@0
|
969 parsedInput[k]=v
|
adam@0
|
970 end
|
adam@0
|
971 end
|
adam@0
|
972 return parsedInput
|
adam@0
|
973 end
|
adam@0
|
974
|
adam@0
|
975 function AskMrRobot.validateRealm(realm)
|
adam@0
|
976 return realm == GetRealmName();
|
adam@0
|
977 end
|
adam@0
|
978
|
adam@0
|
979 function AskMrRobot.validateCharacterName(characterName)
|
adam@0
|
980 return UnitName("player") == characterName
|
adam@0
|
981 end
|
adam@0
|
982
|
adam@0
|
983 function AskMrRobot.validateRace(race)
|
adam@0
|
984 local _, raceEn = UnitRace("player")
|
adam@0
|
985 return raceEn == race or (raceEn == "Scourge" and race == "Undead")
|
adam@0
|
986 end
|
adam@0
|
987
|
adam@0
|
988 function AskMrRobot.validateFaction(faction)
|
adam@0
|
989 return faction == UnitFactionGroup("player")
|
adam@0
|
990 end
|
adam@0
|
991
|
adam@0
|
992 function AskMrRobot.validateSpec(spec)
|
adam@0
|
993 if spec == 'nil' then
|
adam@0
|
994 spec = nil
|
adam@0
|
995 end
|
adam@0
|
996 local currentSpec = GetAmrSpecialization(GetActiveSpecGroup())
|
adam@0
|
997 return (not currentSpec and not spec) or tostring(currentSpec) == spec
|
adam@0
|
998 end
|
adam@0
|
999
|
adam@0
|
1000 function AskMrRobot.validateTalents(talents)
|
adam@0
|
1001 if talents == nil then
|
adam@0
|
1002 talents = ''
|
adam@0
|
1003 end
|
adam@0
|
1004 return talents == GetAmrTalentsForSpec(GetActiveSpecGroup())
|
adam@0
|
1005 end
|
adam@0
|
1006
|
adam@0
|
1007 function AskMrRobot.validateGlyphs(glyphs)
|
adam@0
|
1008 if (glyphs == nil) then
|
adam@0
|
1009 glyphs = {};
|
adam@0
|
1010 end
|
adam@0
|
1011 local currentGlyphs = GetAmrGlyphsForSpec(GetActiveSpecGroup())
|
adam@0
|
1012 table.sort(glyphs, function(a,b) return tostring(a) < tostring(b) end)
|
adam@0
|
1013 table.sort(currentGlyphs, function(a,b) return tostring(a) < tostring(b) end)
|
adam@0
|
1014
|
adam@0
|
1015 if #glyphs ~= #currentGlyphs then
|
adam@0
|
1016 return false
|
adam@0
|
1017 end
|
adam@0
|
1018 for i = 1, #glyphs do
|
adam@0
|
1019 if tostring(glyphs[i]) ~= tostring(currentGlyphs[i]) then
|
adam@0
|
1020 return false
|
adam@0
|
1021 end
|
adam@0
|
1022 end
|
adam@0
|
1023
|
adam@0
|
1024 return true
|
adam@0
|
1025 end
|
adam@0
|
1026
|
adam@0
|
1027 local function getPrimaryProfessions()
|
adam@0
|
1028 local profs = {}
|
adam@0
|
1029 local prof1, prof2 = GetProfessions()
|
adam@0
|
1030 local profMap = {
|
adam@0
|
1031 [794] = "Archaeology",
|
adam@0
|
1032 [171] = "Alchemy",
|
adam@0
|
1033 [164] = "Blacksmithing",
|
adam@0
|
1034 [185] = "Cooking",
|
adam@0
|
1035 [333] = "Enchanting",
|
adam@0
|
1036 [202] = "Engineering",
|
adam@0
|
1037 [129] = "First Aid",
|
adam@0
|
1038 [356] = "Fishing",
|
adam@0
|
1039 [182] = "Herbalism",
|
adam@0
|
1040 [773] = "Inscription",
|
adam@0
|
1041 [755] = "Jewelcrafting",
|
adam@0
|
1042 [165] = "Leatherworking",
|
adam@0
|
1043 [186] = "Mining",
|
adam@0
|
1044 [393] = "Skinning",
|
adam@0
|
1045 [197] = "Tailoring"
|
adam@0
|
1046 }
|
adam@0
|
1047
|
adam@0
|
1048 if prof1 then
|
adam@0
|
1049 local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof1);
|
adam@0
|
1050 if profMap[skillLine] ~= nil then
|
adam@0
|
1051 profs[profMap[skillLine]] = skillLevel
|
adam@0
|
1052 end
|
adam@0
|
1053 end
|
adam@0
|
1054 if prof2 then
|
adam@0
|
1055 local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof2);
|
adam@0
|
1056 if profMap[skillLine] ~= nil then
|
adam@0
|
1057 profs[profMap[skillLine]] = skillLevel
|
adam@0
|
1058 end
|
adam@0
|
1059 end
|
adam@0
|
1060 return profs;
|
adam@0
|
1061 end
|
adam@0
|
1062
|
adam@0
|
1063 local professionThresholds = {
|
adam@0
|
1064 Leatherworking = 575,
|
adam@0
|
1065 Inscription = 600,
|
adam@0
|
1066 Alchemy = 50,
|
adam@0
|
1067 Enchanting = 550,
|
adam@0
|
1068 Jewelcrafting = 550,
|
adam@0
|
1069 Blacksmithing = 550,
|
adam@0
|
1070 Tailoring = 550
|
adam@0
|
1071 }
|
adam@0
|
1072
|
adam@0
|
1073 function AskMrRobot.validateProfessions(professions)
|
adam@0
|
1074 local currentProfessions = getPrimaryProfessions()
|
adam@0
|
1075 if #currentProfessions ~= #professions then
|
adam@0
|
1076 return false
|
adam@0
|
1077 end
|
adam@0
|
1078 for k, v in pairs(professions) do
|
adam@0
|
1079 if currentProfessions[k] then
|
adam@0
|
1080 local threshold = professionThresholds[k]
|
adam@0
|
1081 if not threshold then
|
adam@0
|
1082 threshold = 1
|
adam@0
|
1083 end
|
adam@0
|
1084 -- compare the desired profession against the threshold
|
adam@0
|
1085 local desired = v >= threshold
|
adam@0
|
1086 -- compare the current profession against the threshold
|
adam@0
|
1087 local has = currentProfessions[k] and currentProfessions[k] >= threshold
|
adam@0
|
1088 -- if the current value is on the other side of the threshold
|
adam@0
|
1089 -- then we don't match
|
adam@0
|
1090 if desired ~= has then
|
adam@0
|
1091 return false
|
adam@0
|
1092 end
|
adam@0
|
1093 else
|
adam@0
|
1094 return false
|
adam@0
|
1095 end
|
adam@0
|
1096 end
|
adam@0
|
1097 return true
|
adam@0
|
1098 end
|
adam@0
|
1099
|
adam@0
|
1100 function AskMrRobot.populateItemDiffs(amrItem, itemLink, slotNum)
|
adam@0
|
1101 AskMrRobot.itemDiffs.items[slotNum] = nil
|
adam@0
|
1102 AskMrRobot.itemDiffs.gems[slotNum] = nil
|
adam@0
|
1103 AskMrRobot.itemDiffs.enchants[slotNum] = nil
|
adam@0
|
1104 AskMrRobot.itemDiffs.reforges[slotNum] = nil
|
adam@0
|
1105
|
adam@0
|
1106 local needsUpgrade = false
|
adam@0
|
1107 local aSuffix = 0
|
adam@0
|
1108 if amrItem then
|
adam@0
|
1109 for k,v in pairs(amrItem.suffixes) do
|
adam@0
|
1110 aSuffix = k
|
adam@0
|
1111 end
|
adam@0
|
1112 end
|
adam@0
|
1113
|
adam@0
|
1114 if itemLink == nil then
|
adam@0
|
1115 if amrItem ~= nil then
|
adam@0
|
1116 AskMrRobot.itemDiffs.items[slotNum] = {
|
adam@0
|
1117 current = nil,
|
adam@0
|
1118 optimized = { itemId = amrItem.itemId, upgradeId = amrItem.upgradeId, suffixId = aSuffix },
|
adam@0
|
1119 needsUpgrade = false
|
adam@0
|
1120 }
|
adam@0
|
1121 end
|
adam@0
|
1122 return
|
adam@0
|
1123 end
|
adam@0
|
1124 local item = parseItemLink(itemLink)
|
adam@0
|
1125 local isItemBad = false
|
adam@0
|
1126
|
adam@0
|
1127 if amrItem == nil or item.itemId ~= amrItem.itemId then
|
adam@0
|
1128 isItemBad = true
|
adam@0
|
1129 else
|
adam@0
|
1130 if item.suffixId == 0 then
|
adam@0
|
1131 if #amrItem.suffixes > 0 then
|
adam@0
|
1132 isItemBad = true
|
adam@0
|
1133 end
|
adam@0
|
1134 else
|
adam@0
|
1135 if not amrItem.suffixes[item.suffixId] then
|
adam@0
|
1136 isItemBad = true
|
adam@0
|
1137 end
|
adam@0
|
1138 end
|
adam@0
|
1139 if not isItemBad and upgradeTable[item.upgradeId] ~= upgradeTable[amrItem.upgradeId] then
|
adam@0
|
1140 isItemBad = true
|
adam@0
|
1141 needsUpgrade = true
|
adam@0
|
1142 end
|
adam@0
|
1143 end
|
adam@0
|
1144
|
adam@0
|
1145 if isItemBad then
|
adam@0
|
1146 AskMrRobot.itemDiffs.items[slotNum] = {
|
adam@0
|
1147 current = item.itemId,
|
adam@0
|
1148 optimized = { itemId = amrItem and amrItem.itemId or 0, upgradeId = amrItem and amrItem.upgradeId or 0, suffixId = aSuffix },
|
adam@0
|
1149 needsUpgrade = needsUpgrade
|
adam@0
|
1150 }
|
adam@0
|
1151 return
|
adam@0
|
1152 end
|
adam@0
|
1153
|
adam@0
|
1154 local badGemCount, gemInfo = AskMrRobot.MatchesGems(itemLink, item.gemEnchantIds, amrItem.gems)
|
adam@0
|
1155 if badGemCount > 0 then
|
adam@0
|
1156 AskMrRobot.itemDiffs.gems[slotNum] = gemInfo
|
adam@0
|
1157 end
|
adam@0
|
1158
|
adam@0
|
1159 if item.enchantId ~= amrItem.enchantId then
|
adam@0
|
1160 AskMrRobot.itemDiffs.enchants[slotNum] = {
|
adam@0
|
1161 current = item.enchantId,
|
adam@0
|
1162 optimized = amrItem.enchantId
|
adam@0
|
1163 }
|
adam@0
|
1164 end
|
adam@0
|
1165
|
adam@0
|
1166 if item.reforgeId ~= amrItem.reforgeId then
|
adam@0
|
1167 AskMrRobot.itemDiffs.reforges[slotNum] = {
|
adam@0
|
1168 current = item.reforgeId,
|
adam@0
|
1169 optimized = amrItem.reforgeId
|
adam@0
|
1170 }
|
adam@0
|
1171 end
|
adam@0
|
1172 end
|
adam@0
|
1173
|
adam@0
|
1174 --[[
|
adam@0
|
1175 function AskMrRobot.StartLogging()
|
adam@0
|
1176 if not LoggingCombat() then
|
adam@0
|
1177 LoggingCombat(1)
|
adam@0
|
1178 print("Started Combat Logging")
|
adam@0
|
1179 end
|
adam@0
|
1180 end
|
adam@0
|
1181
|
adam@0
|
1182 function AskMrRobot.FinishLogging()
|
adam@0
|
1183 if LoggingCombat() then
|
adam@0
|
1184 LoggingCombat(0)
|
adam@0
|
1185 print("Finished Combat Logging")
|
adam@0
|
1186 end
|
adam@0
|
1187 end
|
adam@0
|
1188
|
adam@0
|
1189 -- local difficultyLookup = {
|
adam@0
|
1190 -- DUNGEON_DIFFICULTY1,
|
adam@0
|
1191 -- DUNGEON_DIFFICULTY2,
|
adam@0
|
1192 -- RAID_DIFFICULTY_10PLAYER,
|
adam@0
|
1193 -- RAID_DIFFICULTY_25PLAYER,
|
adam@0
|
1194 -- RAID_DIFFICULTY_10PLAYER_HEROIC,
|
adam@0
|
1195 -- RAID_DIFFICULTY_25PLAYER_HEROIC,
|
adam@0
|
1196 -- RAID_FINDER,
|
adam@0
|
1197 -- CHALLENGE_MODE,
|
adam@0
|
1198 -- RAID_DIFFICULTY_40PLAYER,
|
adam@0
|
1199 -- nil,
|
adam@0
|
1200 -- nil, -- Norm scen
|
adam@0
|
1201 -- nil, -- heroic scen
|
adam@0
|
1202 -- nil,
|
adam@0
|
1203 -- PLAYER_DIFFICULTY4
|
adam@0
|
1204 -- }
|
adam@0
|
1205
|
adam@0
|
1206 --http://wowpedia.org/InstanceMapID
|
adam@0
|
1207 local instanceMaps = {
|
adam@0
|
1208 HeartOfFear = 1009,
|
adam@0
|
1209 MogushanVaults = 1008,
|
adam@0
|
1210 SiegeOfOrgrimmar = 1136,
|
adam@0
|
1211 TerraceOfEndlessSpring = 996,
|
adam@0
|
1212 ThroneOfThunder = 1098
|
adam@0
|
1213 }
|
adam@0
|
1214
|
adam@0
|
1215 function AskMrRobot.UpdateLogging()
|
adam@0
|
1216
|
adam@0
|
1217 -- get the info about the instance
|
adam@0
|
1218 --local zone, zonetype, difficultyIndex, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceMapID = GetInstanceInfo()
|
adam@0
|
1219 local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo()
|
adam@0
|
1220 --local difficulty = difficultyIndex
|
adam@0
|
1221 -- Unless Blizzard fixes scenarios to not return nil, let's hardcode this into returning "scenario" -Znuff
|
adam@0
|
1222 --if zonetype == nil and difficultyIndex == 1 then
|
adam@0
|
1223 --zonetype = "scenario"
|
adam@0
|
1224 --end
|
adam@0
|
1225
|
adam@0
|
1226 -- if nothing has changed, then bail
|
adam@0
|
1227 --if (not zone) and difficulty == 0 then return end
|
adam@0
|
1228 if zone == AskMrRobot.lastzone and difficultyIndex == AskMrRobot.lastdiff then
|
adam@0
|
1229 -- do nothing if the zone hasn't ACTUALLY changed
|
adam@0
|
1230 -- otherwise we may override the user's manual enable/disable
|
adam@0
|
1231 return
|
adam@0
|
1232 end
|
adam@0
|
1233
|
adam@0
|
1234 AskMrRobot.lastzone = zone
|
adam@0
|
1235 AskMrRobot.lastdiff = difficultyIndex
|
adam@0
|
1236
|
adam@0
|
1237 if AmrOptions.autoLog[tonumber(instanceMapID)] then
|
adam@0
|
1238 if instanceMapID == instanceMaps.SiegeOfOrgrimmar then
|
adam@0
|
1239 AskMrRobot.StartLogging()
|
adam@0
|
1240 else
|
adam@0
|
1241 AskMrRobot.FinishLogging()
|
adam@0
|
1242 end
|
adam@0
|
1243 end
|
adam@0
|
1244 end
|
adam@0
|
1245 ]]
|