-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShare.lua
More file actions
208 lines (174 loc) · 6.98 KB
/
Share.lua
File metadata and controls
208 lines (174 loc) · 6.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
local addon_name, addon = ...
local AceGUI = LibStub("AceGUI-3.0")
local AceSerializer = LibStub("AceSerializer-3.0")
local LibPetJournal = LibStub("LibPetJournal-2.0")
local C_PetJournal = C_PetJournal
local type, strfind, tinsert = type, strfind, tinsert
local EXPORT_PREFIX = "PetCall:1:"
-- ---------------------------------------------------------------------------
-- Serialization helpers
-- ---------------------------------------------------------------------------
-- Returns an export string for the named set, or nil + error.
-- The set name is intentionally excluded: the importer chooses their own name.
function addon:ExportSet(setName)
local setData = addon.db.profile.sets[setName]
if not setData then
return nil, "Set not found: " .. tostring(setName)
end
-- Convert pets from {petGUID → weight} to {speciesID → weight} so the
-- export string is portable across different accounts.
local exportPets = {}
for petGUID, weight in pairs(setData.pets) do
if type(weight) == "number" then
local speciesID = C_PetJournal.GetPetInfoByPetID(petGUID)
if speciesID and speciesID > 0 then
local cur = exportPets[speciesID]
if cur == nil or weight > cur then
exportPets[speciesID] = weight
end
end
end
end
local export = {
enabled = setData.enabled,
priority = setData.priority,
defaultValue = setData.defaultValue,
immediate = setData.immediate,
pets = exportPets,
filter = setData.filter,
trigger = setData.trigger,
}
local str = AceSerializer:Serialize(export)
if not str then return nil, "Serialization failed" end
return EXPORT_PREFIX .. str
end
-- Imports a set from an export string using the caller-supplied name.
-- Returns true + newName on success, or nil + error message on failure.
function addon:ImportSet(str, newName)
str = str and str:gsub("^%s+", ""):gsub("%s+$", "") or ""
if str:sub(1, #EXPORT_PREFIX) ~= EXPORT_PREFIX then
return nil, "Invalid import string (missing PetCall prefix)"
end
local ok, data = AceSerializer:Deserialize(str:sub(#EXPORT_PREFIX + 1))
if not ok then
return nil, "Corrupt import string: " .. tostring(data)
end
if type(data) ~= "table" then
return nil, "Invalid data format"
end
-- Validate the name supplied by the user.
newName = newName and newName:gsub("^%s+", ""):gsub("%s+$", "") or ""
if #newName == 0 then
return nil, "Please enter a name for the set"
end
-- Use rawget to bypass the AceDB $Default metatable: a plain table
-- lookup would return the wildcard default for any key, making every
-- name appear to already exist.
if rawget(addon.db.profile.sets, newName) then
return nil, "A set named \"" .. newName .. "\" already exists"
end
-- Convert pets from {speciesID → weight} to {petGUID → weight} using
-- the importer's own pet collection. Pets whose species aren't owned
-- are simply omitted.
local importedPets = type(data.pets) == "table" and data.pets or {}
local convertedPets = {}
for _, petGUID in LibPetJournal:IteratePetIDs() do
local speciesID = C_PetJournal.GetPetInfoByPetID(petGUID)
if speciesID and importedPets[speciesID] ~= nil then
convertedPets[petGUID] = importedPets[speciesID]
end
end
-- Write validated data to DB.
addon.db.profile.sets[newName] = {
name = newName,
enabled = data.enabled ~= false,
priority = type(data.priority) == "number" and data.priority or 1,
defaultValue = type(data.defaultValue) == "number" and data.defaultValue or 0,
immediate = data.immediate or false,
pets = convertedPets,
filter = type(data.filter) == "table" and data.filter or {},
trigger = type(data.trigger) == "table" and data.trigger or {},
}
addon:ReloadSets()
return true, newName
end
-- ---------------------------------------------------------------------------
-- Export dialog
-- ---------------------------------------------------------------------------
function addon:ShowExportDialog(setName)
local str, err = self:ExportSet(setName)
if not str then
self:Print("Export failed: " .. tostring(err))
return
end
local frame = AceGUI:Create("Frame")
frame:SetTitle("PetCall \226\128\148 Export: " .. setName)
frame:SetLayout("Flow")
frame:SetWidth(500)
frame:SetHeight(185)
frame:SetCallback("OnClose", function(widget) AceGUI:Release(widget) end)
local hint = AceGUI:Create("Label")
hint:SetText("All text is selected \226\128\148 press Ctrl+C to copy.")
hint:SetFullWidth(true)
frame:AddChild(hint)
local eb = AceGUI:Create("MultiLineEditBox")
eb:SetLabel("")
eb:SetText(str)
eb:SetFullWidth(true)
eb:SetHeight(80)
eb:DisableButton(true)
-- Hook before AddChild: the editBox becomes visible when the layout engine
-- shows it during AddChild, so OnShow fires at exactly the right moment.
eb.editBox:HookScript("OnShow", function(self)
self:SetFocus()
self:HighlightText()
end)
frame:AddChild(eb)
end
-- ---------------------------------------------------------------------------
-- Import dialog
-- ---------------------------------------------------------------------------
function addon:ShowImportDialog(onImported)
local frame = AceGUI:Create("Frame")
frame:SetTitle("PetCall \226\128\148 Import Set")
frame:SetLayout("Flow")
frame:SetWidth(500)
frame:SetHeight(265)
frame:SetCallback("OnClose", function(widget) AceGUI:Release(widget) end)
local hint = AceGUI:Create("Label")
hint:SetText("Paste a PetCall export string below:")
hint:SetFullWidth(true)
frame:AddChild(hint)
local eb = AceGUI:Create("MultiLineEditBox")
eb:SetLabel("")
eb:SetFullWidth(true)
eb:SetHeight(90)
eb:DisableButton(true)
eb.editBox:HookScript("OnShow", function(self)
self:SetFocus()
end)
frame:AddChild(eb)
local nameBox = AceGUI:Create("EditBox")
nameBox:SetLabel("Set name:")
nameBox:SetFullWidth(true)
nameBox:DisableButton(true)
frame:AddChild(nameBox)
local statusLabel = AceGUI:Create("Label")
statusLabel:SetFullWidth(true)
frame:AddChild(statusLabel)
local function doImport()
local ok, result = addon:ImportSet(eb:GetText(), nameBox:GetText())
if ok then
if onImported then onImported() end
AceGUI:Release(frame)
else
statusLabel:SetText("|cffffcc00" .. tostring(result) .. "|r")
end
end
nameBox:SetCallback("OnEnterPressed", doImport)
local importBtn = AceGUI:Create("Button")
importBtn:SetText("Import")
importBtn:SetFullWidth(true)
importBtn:SetCallback("OnClick", doImport)
frame:AddChild(importBtn)
end