-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathviewer.lua
More file actions
303 lines (251 loc) · 8.3 KB
/
Copy pathviewer.lua
File metadata and controls
303 lines (251 loc) · 8.3 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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
--[[ Stash / viewer ------------------------------------------------------------
Turns the cached view on and off.
The window itself belongs to whichever backend is active (see backends.lua) -
Blizzard's BankFrame, Bagnon's Banknon, or anything else registered. This file
only decides what to show, asks the backend to open it, and makes sure leaving
the window leaves the cached view.
-----------------------------------------------------------------------------]]
Stash.modules.viewer = true
local pairs, ipairs = pairs, ipairs
local getn = table.getn
-- Other addons can register here to find out when the cached view opens or
-- closes, e.g. to repaint a frame that caches item data itself.
Stash.callbacks = {}
local function Fire(state)
for _, callback in ipairs(Stash.callbacks) do
callback(state, Stash.viewing)
end
end
-- --------------------------------------------------------------------------
-- helpers
-- --------------------------------------------------------------------------
-- Case insensitive so "/stash bank ana" finds "Ana".
local function ResolveName(name)
if not name or name == "" then
return UnitName("player")
end
for _, candidate in ipairs(Stash:GetCharNames()) do
if string.lower(candidate) == string.lower(name) then
return candidate
end
end
return nil
end
local function Ago(stamp)
if not stamp then
return "unknown"
end
local seconds = time() - stamp
if seconds < 120 then
return "just now"
elseif seconds < 7200 then
return math.floor(seconds / 60) .. " minutes ago"
elseif seconds < 172800 then
return math.floor(seconds / 3600) .. " hours ago"
end
return math.floor(seconds / 86400) .. " days ago"
end
-- --------------------------------------------------------------------------
-- repaint (Blizzard backend)
-- --------------------------------------------------------------------------
-- How many buttons the bank window actually has. Counting them beats trusting
-- a constant: this client draws 28 item buttons and 7 bag buttons where stock
-- 1.12 has 24 and 6.
local function CountButtons(prefix, fallback)
local found = 0
while getglobal(prefix .. (found + 1)) do
found = found + 1
if found > 64 then
break
end
end
return found > 0 and found or fallback
end
-- Paints one bank button from a texture and a stack size.
--
-- BankFrameItemButton_Update would normally do this, but it cannot be relied on
-- here: it does not exist on every 1.12 derived client, and a guarded call that
-- silently does nothing leaves whatever the buttons last had on them. That is
-- invisible right after a real bank visit, when the buttons are already painted,
-- and shows up as an empty window on a fresh login. So the icon and the count
-- are set directly, using the <name>IconTexture / <name>Count anatomy every
-- other bag addon on this client relies on.
local function PaintButton(name, texture, count)
local icon = getglobal(name .. "IconTexture")
if icon then
if texture then
icon:SetTexture(texture)
icon:Show()
else
icon:SetTexture(nil)
icon:Hide()
end
end
local text = getglobal(name .. "Count")
if text then
if count and count > 1 then
text:SetText(count)
text:Show()
else
text:SetText("")
text:Hide()
end
end
end
function Stash:RefreshBankFrame()
if not BankFrame or not BankFrame:IsShown() then
return
end
local slots = GetContainerNumSlots(Stash.BANK_CONTAINER) or 0
-- Both reads below go through the wrappers in shim.lua, so this paints the
-- cache while the cached view is up and the live bank the rest of the time.
for slot = 1, CountButtons("BankFrameItem", NUM_BANKGENERIC_SLOTS or 24) do
local name = "BankFrameItem" .. slot
local button = getglobal(name)
if button then
if BankFrameItemButton_Update then
pcall(BankFrameItemButton_Update, button)
end
local texture, count
if slot <= slots then
texture, count = GetContainerItemInfo(Stash.BANK_CONTAINER, slot)
end
PaintButton(name, texture, count)
end
end
for index = 1, CountButtons("BankFrameBag", NUM_BANKBAGSLOTS or 6) do
local name = "BankFrameBag" .. index
local button = getglobal(name)
if button then
if BankFrameItemButton_Update then
pcall(BankFrameItemButton_Update, button)
end
local bag = Stash.FIRST_BANK_BAG + index - 1
local inventory = ContainerIDToInventoryID and ContainerIDToInventoryID(bag)
PaintButton(name, inventory and GetInventoryItemTexture("player", inventory), nil)
end
end
if UpdateBagSlotStatus then
pcall(UpdateBagSlotStatus)
end
if BankFrame_UpdateCooldowns then
pcall(BankFrame_UpdateCooldowns)
end
-- Say whose bank this is, and that it is a copy rather than the real thing.
if BankFrameTitleText then
if Stash.viewing then
BankFrameTitleText:SetText(Stash.viewing .. " |cffffcc00(cached)|r")
else
BankFrameTitleText:SetText(UnitName("player"))
end
end
end
-- --------------------------------------------------------------------------
-- the cached view
-- --------------------------------------------------------------------------
-- backends.lua is a separate file, and vanilla only enumerates an addon's files
-- when the client starts: a newly added one is missing until a full restart,
-- even though /reload brings back the edited ones. Rather than blowing up on a
-- half loaded addon, fall back to Blizzard's frame and say what happened.
local warned
local function FallbackBackend()
if not warned then
Stash:Error("backends.lua is not loaded, falling back to the default bank window.")
Stash:Error("exit the game completely and start it again - /reload does not pick up newly added addon files.")
warned = true
end
if not BankFrame then
return nil
end
Stash:HookClose(BankFrame)
return {
name = "blizzard",
label = "Blizzard BankFrame",
isopen = function()
return BankFrame:IsShown() and true or nil
end,
open = function()
if ShowUIPanel then
ShowUIPanel(BankFrame)
else
BankFrame:Show()
end
end,
close = function()
if HideUIPanel then
HideUIPanel(BankFrame)
else
BankFrame:Hide()
end
end,
refresh = function()
Stash:RefreshBankFrame()
end,
}
end
function Stash:ShowBank(name)
if Stash:AtBank() then
Stash:Print("you are standing at your bank - that is the real thing.")
return
end
local backend
if Stash.GetBackend then
backend = Stash:GetBackend()
else
backend = FallbackBackend()
end
if not backend then
Stash:Error("no bank window available on this client.")
return
end
-- clicking again closes it
if Stash.viewing and backend.isopen() then
backend.close()
return
end
local target = ResolveName(name)
if not target then
Stash:Error("no character called '" .. name .. "'. Try |cffffcc00/stash list|r.")
return
end
local char = Stash:GetChar(target)
if not char or not char.containers or not char.containers[Stash.BANK_CONTAINER] then
Stash:Error("nothing cached for " .. target .. " yet - open a bank once on that character.")
return
end
Stash.viewing = target
Stash.backend = backend
-- A backend with its own cache shows that; diverting the API underneath it
-- would only give the screen two disagreeing sources.
Stash.offline = not backend.ownscache and true or nil
-- The frame may belong to an addon that was not loaded at PLAYER_LOGIN.
if backend.install then
backend.install()
end
backend.open()
if backend.refresh then
backend.refresh()
end
Fire("open")
if backend.ownscache then
Stash:Print(backend.label .. " keeps its own copy of the bank - showing that.")
else
local items = Stash:CountItems(target)
Stash:Print(target .. "'s bank: |cff33ff33" .. items .. "|r items, saved " .. Ago(char.updated) .. ".")
end
end
-- Leaves the cached view. Never closes the window itself - it is called from
-- the window's own OnHide, and from BANKFRAME_OPENED when a real bank arrives.
function Stash:EndOffline()
if not Stash.viewing then
return
end
local backend = Stash.backend
Stash.offline = nil
Stash.viewing = nil
Stash.backend = nil
if backend and backend.refresh then
backend.refresh()
end
Fire("close")
end