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