yellowfive@57
|
1 local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot")
|
yellowfive@57
|
2 local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true)
|
yellowfive@57
|
3 local AceGUI = LibStub("AceGUI-3.0")
|
yellowfive@57
|
4
|
yellowfive@57
|
5 local _txtImport
|
yellowfive@57
|
6 local _lblError
|
yellowfive@57
|
7
|
yellowfive@57
|
8 local function onImportOkClick(widget)
|
yellowfive@57
|
9 local txt = _txtImport:GetText()
|
yellowfive@57
|
10 local msg = Amr:ImportCharacter(txt)
|
yellowfive@57
|
11 if msg then
|
yellowfive@57
|
12 _lblError:SetText(msg)
|
yellowfive@57
|
13 _txtImport:SetFocus(true)
|
yellowfive@57
|
14 else
|
yellowfive@57
|
15 Amr:HideCover()
|
yellowfive@57
|
16 Amr:RefreshGearTab()
|
yellowfive@57
|
17 end
|
yellowfive@57
|
18 end
|
yellowfive@57
|
19
|
yellowfive@57
|
20 local function onImportCancelClick(widget)
|
yellowfive@57
|
21 Amr:HideCover()
|
yellowfive@57
|
22 end
|
yellowfive@57
|
23
|
yellowfive@57
|
24 local function renderImportWindow(container)
|
yellowfive@57
|
25
|
yellowfive@57
|
26 local panelImport = Amr:RenderCoverChrome(container, 700, 450)
|
yellowfive@57
|
27
|
yellowfive@57
|
28 local lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
29 lbl:SetWidth(600)
|
yellowfive@57
|
30 lbl:SetText(L.ImportHeader)
|
yellowfive@57
|
31 lbl:SetPoint("TOP", panelImport.content, "TOP", 0, -10)
|
yellowfive@57
|
32 panelImport:AddChild(lbl)
|
yellowfive@57
|
33
|
yellowfive@57
|
34 _txtImport = AceGUI:Create("AmrUiTextarea")
|
yellowfive@57
|
35 _txtImport:SetWidth(600)
|
yellowfive@57
|
36 _txtImport:SetHeight(300)
|
yellowfive@57
|
37 _txtImport:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -10)
|
yellowfive@57
|
38 _txtImport:SetFont(Amr.CreateFont("Regular", 12, Amr.Colors.Text))
|
yellowfive@57
|
39 panelImport:AddChild(_txtImport)
|
yellowfive@57
|
40
|
yellowfive@57
|
41 local btnImportOk = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
42 btnImportOk:SetText(L.ImportButtonOk)
|
yellowfive@57
|
43 btnImportOk:SetBackgroundColor(Amr.Colors.Green)
|
yellowfive@57
|
44 btnImportOk:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
45 btnImportOk:SetWidth(120)
|
yellowfive@57
|
46 btnImportOk:SetHeight(28)
|
yellowfive@57
|
47 btnImportOk:SetPoint("TOPLEFT", _txtImport.frame, "BOTTOMLEFT", 0, -10)
|
yellowfive@57
|
48 btnImportOk:SetCallback("OnClick", onImportOkClick)
|
yellowfive@57
|
49 panelImport:AddChild(btnImportOk)
|
yellowfive@57
|
50
|
yellowfive@57
|
51 local btnImportCancel = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
52 btnImportCancel:SetText(L.ImportButtonCancel)
|
yellowfive@57
|
53 btnImportCancel:SetBackgroundColor(Amr.Colors.Green)
|
yellowfive@57
|
54 btnImportCancel:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
55 btnImportCancel:SetWidth(120)
|
yellowfive@57
|
56 btnImportCancel:SetHeight(28)
|
yellowfive@57
|
57 btnImportCancel:SetPoint("LEFT", btnImportOk.frame, "RIGHT", 20, 0)
|
yellowfive@57
|
58 btnImportCancel:SetCallback("OnClick", onImportCancelClick)
|
yellowfive@57
|
59 panelImport:AddChild(btnImportCancel)
|
yellowfive@57
|
60
|
yellowfive@57
|
61 _lblError = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
62 _lblError:SetWidth(600)
|
yellowfive@57
|
63 _lblError:SetFont(Amr.CreateFont("Bold", 14, Amr.Colors.Red))
|
yellowfive@57
|
64 _lblError:SetText("")
|
yellowfive@57
|
65 _lblError:SetPoint("TOPLEFT", btnImportOk.frame, "BOTTOMLEFT", 0, -20)
|
yellowfive@57
|
66 panelImport:AddChild(_lblError)
|
yellowfive@57
|
67
|
yellowfive@57
|
68 end
|
yellowfive@57
|
69
|
yellowfive@57
|
70 function Amr:ShowImportWindow()
|
yellowfive@57
|
71 -- this is shown as a modal dialog
|
yellowfive@57
|
72 Amr:ShowCover(renderImportWindow)
|
yellowfive@57
|
73
|
yellowfive@57
|
74 _txtImport:SetText("")
|
yellowfive@57
|
75 _txtImport:SetFocus(true)
|
yellowfive@57
|
76 end
|
yellowfive@57
|
77
|
yellowfive@57
|
78 ----------------------------------------------------------------------------
|
yellowfive@57
|
79 -- Import Parsing
|
yellowfive@57
|
80 ----------------------------------------------------------------------------
|
yellowfive@57
|
81
|
yellowfive@57
|
82 --
|
yellowfive@57
|
83 -- Import a character, returning nil on success, otherwise an error message, import result stored in the db.
|
yellowfive@57
|
84 --
|
yellowfive@57
|
85 function Amr:ImportCharacter(data, isTest)
|
yellowfive@57
|
86
|
yellowfive@57
|
87 -- make sure all data is up to date before importing and get a local copy of player's current state
|
yellowfive@57
|
88 local currentPlayerData = self:ExportCharacter()
|
yellowfive@57
|
89
|
yellowfive@57
|
90 if data == nil or string.len(data) == 0 then
|
yellowfive@57
|
91 return L.ImportErrorEmpty
|
yellowfive@57
|
92 end
|
yellowfive@57
|
93
|
yellowfive@57
|
94 -- if multiple specs are included in the data, parse each individually, then quit
|
yellowfive@57
|
95 local specParts = { strsplit("\n", data) }
|
yellowfive@57
|
96 if #specParts > 1 then
|
yellowfive@57
|
97 for i = 1, #specParts do
|
yellowfive@57
|
98 local err = self:ImportCharacter(specParts[i], isTest)
|
yellowfive@57
|
99 if err ~= nil then
|
yellowfive@57
|
100 return err
|
yellowfive@57
|
101 end
|
yellowfive@57
|
102 end
|
yellowfive@57
|
103 return
|
yellowfive@57
|
104 end
|
yellowfive@57
|
105
|
yellowfive@57
|
106 local data1 = { strsplit("$", data) }
|
yellowfive@57
|
107 if #data1 ~= 3 then
|
yellowfive@57
|
108 return L.ImportErrorFormat
|
yellowfive@57
|
109 end
|
yellowfive@57
|
110
|
yellowfive@57
|
111 local parts = { strsplit(";", data1[2]) }
|
yellowfive@57
|
112
|
yellowfive@57
|
113 -- require a minimum version
|
yellowfive@57
|
114 local ver = tonumber(parts[1])
|
yellowfive@57
|
115 if ver < Amr.MIN_IMPORT_VERSION then
|
yellowfive@57
|
116 return L.ImportErrorVersion
|
yellowfive@57
|
117 end
|
yellowfive@57
|
118
|
yellowfive@57
|
119 -- require name match (don't match realm due to language issues for now)
|
yellowfive@57
|
120 if not isTest then
|
yellowfive@57
|
121 local region = parts[2]
|
yellowfive@57
|
122 local realm = parts[3]
|
yellowfive@57
|
123 local name = parts[4]
|
yellowfive@57
|
124 if name ~= currentPlayerData.Name then
|
yellowfive@57
|
125 local importPlayerName = name .. " (" .. realm .. ")"
|
yellowfive@57
|
126 local you = currentPlayerData.Name .. " (" .. currentPlayerData.Realm .. ")"
|
yellowfive@57
|
127 return L.ImportErrorChar(importPlayerName, you)
|
yellowfive@57
|
128 end
|
yellowfive@57
|
129
|
yellowfive@57
|
130 -- require race match
|
yellowfive@57
|
131 local race = tonumber(parts[6])
|
yellowfive@57
|
132 if race ~= Amr.RaceIds[currentPlayerData.Race] then
|
yellowfive@57
|
133 return L.ImportErrorRace
|
yellowfive@57
|
134 end
|
yellowfive@57
|
135
|
yellowfive@57
|
136 -- require faction match
|
yellowfive@57
|
137 local faction = tonumber(parts[7])
|
yellowfive@57
|
138 if faction ~= Amr.FactionIds[currentPlayerData.Faction] then
|
yellowfive@57
|
139 return L.ImportErrorFaction
|
yellowfive@57
|
140 end
|
yellowfive@57
|
141
|
yellowfive@57
|
142 -- require level match
|
yellowfive@57
|
143 local level = tonumber(parts[8])
|
yellowfive@57
|
144 if level ~= currentPlayerData.Level then
|
yellowfive@57
|
145 return L.ImportErrorLevel
|
yellowfive@57
|
146 end
|
yellowfive@57
|
147 end
|
yellowfive@57
|
148
|
yellowfive@57
|
149 -- if we make it this far, the data is valid, so read item information
|
yellowfive@57
|
150 local specSlot = tonumber(parts[10])
|
yellowfive@57
|
151
|
yellowfive@57
|
152 local importData = {}
|
yellowfive@57
|
153
|
yellowfive@57
|
154 local itemInfo = {}
|
yellowfive@57
|
155 local gemInfo = {}
|
yellowfive@57
|
156 local enchantInfo = {}
|
yellowfive@57
|
157
|
yellowfive@57
|
158 local prevItemId = 0
|
yellowfive@57
|
159 local prevGemId = 0
|
yellowfive@57
|
160 local prevEnchantId = 0
|
yellowfive@57
|
161 local prevUpgradeId = 0
|
yellowfive@57
|
162 local prevBonusId = 0
|
yellowfive@57
|
163 local digits = {
|
yellowfive@57
|
164 ["-"] = true,
|
yellowfive@57
|
165 ["0"] = true,
|
yellowfive@57
|
166 ["1"] = true,
|
yellowfive@57
|
167 ["2"] = true,
|
yellowfive@57
|
168 ["3"] = true,
|
yellowfive@57
|
169 ["4"] = true,
|
yellowfive@57
|
170 ["5"] = true,
|
yellowfive@57
|
171 ["6"] = true,
|
yellowfive@57
|
172 ["7"] = true,
|
yellowfive@57
|
173 ["8"] = true,
|
yellowfive@57
|
174 ["9"] = true,
|
yellowfive@57
|
175 }
|
yellowfive@57
|
176 for i = 16, #parts do
|
yellowfive@57
|
177 local itemString = parts[i]
|
yellowfive@57
|
178 if itemString ~= "" and itemString ~= "_" then
|
yellowfive@57
|
179 local tokens = {}
|
yellowfive@57
|
180 local bonusIds = {}
|
yellowfive@57
|
181 local hasBonuses = false
|
yellowfive@57
|
182 local token = ""
|
yellowfive@57
|
183 local prop = "i"
|
yellowfive@57
|
184 local tokenComplete = false
|
yellowfive@57
|
185 for j = 1, string.len(itemString) do
|
yellowfive@57
|
186 local c = string.sub(itemString, j, j)
|
yellowfive@57
|
187 if digits[c] == nil then
|
yellowfive@57
|
188 tokenComplete = true
|
yellowfive@57
|
189 else
|
yellowfive@57
|
190 token = token .. c
|
yellowfive@57
|
191 end
|
yellowfive@57
|
192
|
yellowfive@57
|
193 if tokenComplete or j == string.len(itemString) then
|
yellowfive@57
|
194 local val = tonumber(token)
|
yellowfive@57
|
195 if prop == "i" then
|
yellowfive@57
|
196 val = val + prevItemId
|
yellowfive@57
|
197 prevItemId = val
|
yellowfive@57
|
198 elseif prop == "u" then
|
yellowfive@57
|
199 val = val + prevUpgradeId
|
yellowfive@57
|
200 prevUpgradeId = val
|
yellowfive@57
|
201 elseif prop == "b" then
|
yellowfive@57
|
202 val = val + prevBonusId
|
yellowfive@57
|
203 prevBonusId = val
|
yellowfive@57
|
204 elseif prop == "x" or prop == "y" or prop == "z" then
|
yellowfive@57
|
205 val = val + prevGemId
|
yellowfive@57
|
206 prevGemId = val
|
yellowfive@57
|
207 elseif prop == "e" then
|
yellowfive@57
|
208 val = val + prevEnchantId
|
yellowfive@57
|
209 prevEnchantId = val
|
yellowfive@57
|
210 end
|
yellowfive@57
|
211
|
yellowfive@57
|
212 if prop == "b" then
|
yellowfive@57
|
213 table.insert(bonusIds, val)
|
yellowfive@57
|
214 hasBonuses = true
|
yellowfive@57
|
215 else
|
yellowfive@57
|
216 tokens[prop] = val
|
yellowfive@57
|
217 end
|
yellowfive@57
|
218
|
yellowfive@57
|
219 token = ""
|
yellowfive@57
|
220 tokenComplete = false
|
yellowfive@57
|
221
|
yellowfive@57
|
222 -- we have moved on to the next token
|
yellowfive@57
|
223 prop = c
|
yellowfive@57
|
224 end
|
yellowfive@57
|
225 end
|
yellowfive@57
|
226
|
yellowfive@57
|
227 local obj = {}
|
yellowfive@57
|
228 importData[tonumber(tokens["s"])] = obj
|
yellowfive@57
|
229
|
yellowfive@57
|
230 obj.id = tokens["i"]
|
yellowfive@57
|
231 obj.suffixId = tokens["f"] or 0
|
yellowfive@57
|
232 obj.upgradeId = tokens["u"] or 0
|
yellowfive@57
|
233 obj.enchantId = tokens["e"] or 0
|
yellowfive@57
|
234
|
yellowfive@57
|
235 obj.gemIds = {}
|
yellowfive@57
|
236 table.insert(obj.gemIds, tokens["x"] or 0)
|
yellowfive@57
|
237 table.insert(obj.gemIds, tokens["y"] or 0)
|
yellowfive@57
|
238 table.insert(obj.gemIds, tokens["z"] or 0)
|
yellowfive@57
|
239 table.insert(obj.gemIds, 0)
|
yellowfive@57
|
240
|
yellowfive@57
|
241 if hasBonuses then
|
yellowfive@57
|
242 obj.bonusIds = bonusIds
|
yellowfive@57
|
243 end
|
yellowfive@57
|
244
|
yellowfive@57
|
245 local itemObj = {}
|
yellowfive@57
|
246 itemObj.id = obj.id
|
yellowfive@57
|
247 itemInfo[obj.id] = itemObj
|
yellowfive@57
|
248
|
yellowfive@57
|
249 -- look for any socket color information, add to our extra data
|
yellowfive@57
|
250 if tokens["c"] then
|
yellowfive@57
|
251 itemObj.socketColors = {}
|
yellowfive@57
|
252 for j = 1, string.len(tokens["c"]) do
|
yellowfive@57
|
253 table.insert(itemObj.socketColors, tonumber(string.sub(tokens["c"], j, j)))
|
yellowfive@57
|
254 end
|
yellowfive@57
|
255 end
|
yellowfive@57
|
256
|
yellowfive@57
|
257 -- look for item ID duplicate info, deals with old SoO items
|
yellowfive@57
|
258 if tokens["d"] then
|
yellowfive@57
|
259 itemObj.duplicateId = tonumber(tokens["d"])
|
yellowfive@57
|
260 itemInfo[itemObj.duplicateId] = itemObj
|
yellowfive@57
|
261 end
|
yellowfive@57
|
262
|
yellowfive@57
|
263 end
|
yellowfive@57
|
264 end
|
yellowfive@57
|
265
|
yellowfive@57
|
266 -- now read any extra display information
|
yellowfive@57
|
267 parts = { strsplit("@", data1[3]) }
|
yellowfive@57
|
268 for i = 1, #parts do
|
yellowfive@57
|
269 local infoParts = { strsplit("\\", parts[i]) }
|
yellowfive@57
|
270
|
yellowfive@57
|
271 if infoParts[1] == "g" then
|
yellowfive@57
|
272
|
yellowfive@57
|
273 local gemObj = {}
|
yellowfive@57
|
274 gemObj.enchantId = tonumber(infoParts[2])
|
yellowfive@57
|
275 gemObj.id = tonumber(infoParts[3])
|
yellowfive@57
|
276
|
yellowfive@57
|
277 local identicalGems = infoParts[4]
|
yellowfive@57
|
278 if string.len(identicalGems) > 0 then
|
yellowfive@57
|
279 gemObj.identicalGroup = {}
|
yellowfive@57
|
280 identicalGems = { strsplit(",", identicalGems) }
|
yellowfive@57
|
281 for j = 1, #identicalGems do
|
yellowfive@57
|
282 gemObj.identicalGroup[tonumber(identicalGems[j])] = true
|
yellowfive@57
|
283 end
|
yellowfive@57
|
284 end
|
yellowfive@57
|
285
|
yellowfive@57
|
286 gemObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.StatsShort[s] end)
|
yellowfive@57
|
287 if infoParts[6] == nil or string.len(infoParts[6]) == 0 then
|
yellowfive@57
|
288 gemObj.identicalItemGroup = {[gemObj.id]=true}
|
yellowfive@57
|
289 else
|
yellowfive@57
|
290 local identicalIds = { strsplit(',', infoParts[6]) }
|
yellowfive@57
|
291 gemObj.identicalItemGroup = {}
|
yellowfive@57
|
292 for j = 1, #identicalIds do
|
yellowfive@57
|
293 gemObj.identicalItemGroup[tonumber(identicalIds[j])] = true
|
yellowfive@57
|
294 end
|
yellowfive@57
|
295 end
|
yellowfive@57
|
296
|
yellowfive@57
|
297 gemInfo[gemObj.enchantId] = gemObj
|
yellowfive@57
|
298
|
yellowfive@57
|
299 elseif infoParts[1] == "e" then
|
yellowfive@57
|
300
|
yellowfive@57
|
301 local enchObj = {}
|
yellowfive@57
|
302 enchObj.id = tonumber(infoParts[2])
|
yellowfive@57
|
303 enchObj.itemId = tonumber(infoParts[3])
|
yellowfive@57
|
304 enchObj.spellId = tonumber(infoParts[4])
|
yellowfive@57
|
305 enchObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.StatsShort[s] end)
|
yellowfive@57
|
306
|
yellowfive@57
|
307 local mats = infoParts[6]
|
yellowfive@57
|
308 if string.len(mats) > 0 then
|
yellowfive@57
|
309 enchObj.materials = {}
|
yellowfive@57
|
310 mats = { strsplit(",", mats) }
|
yellowfive@57
|
311 for j = 1, #mats do
|
yellowfive@57
|
312 local kv = { strsplit("=", mats[j]) }
|
yellowfive@57
|
313 enchObj.materials[tonumber(kv[1])] = tonumber(kv[2])
|
yellowfive@57
|
314 end
|
yellowfive@57
|
315 end
|
yellowfive@57
|
316
|
yellowfive@57
|
317 enchantInfo[enchObj.id] = enchObj
|
yellowfive@57
|
318
|
yellowfive@57
|
319 end
|
yellowfive@57
|
320 end
|
yellowfive@57
|
321
|
yellowfive@57
|
322 if isTest then
|
yellowfive@57
|
323 print("spec " .. specSlot)
|
yellowfive@57
|
324 -- print result for debugging
|
yellowfive@57
|
325 for k,v in pairs(importData) do
|
yellowfive@57
|
326 local blah = Amr.CreateItemLink(v)
|
yellowfive@57
|
327 --print(blah)
|
yellowfive@57
|
328 local name, link = GetItemInfo(blah)
|
yellowfive@57
|
329 print(link)
|
yellowfive@57
|
330 if link == nil then
|
yellowfive@57
|
331 print(blah)
|
yellowfive@57
|
332 print("bad item: " .. v.id)
|
yellowfive@57
|
333 end
|
yellowfive@57
|
334 end
|
yellowfive@57
|
335
|
yellowfive@57
|
336
|
yellowfive@57
|
337 else
|
yellowfive@57
|
338 -- we have succeeded, record the result
|
yellowfive@57
|
339 Amr.db.char.GearSets[specSlot] = importData
|
yellowfive@57
|
340 Amr.db.char.ExtraItemData[specSlot] = itemInfo
|
yellowfive@57
|
341 Amr.db.char.ExtraGemData[specSlot] = gemInfo
|
yellowfive@57
|
342 Amr.db.char.ExtraEnchantData[specSlot] = enchantInfo
|
yellowfive@57
|
343
|
yellowfive@57
|
344 -- also update shopping list after import
|
yellowfive@57
|
345 Amr:UpdateShoppingData(currentPlayerData)
|
yellowfive@57
|
346 end
|
yellowfive@57
|
347 end
|