-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVersion.lua
More file actions
93 lines (84 loc) · 3.31 KB
/
Copy pathVersion.lua
File metadata and controls
93 lines (84 loc) · 3.31 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
-- WickCore
-- Version.lua — suite-wide version broadcast.
--
-- Every registered product announces itself on the WICK prefix when the
-- player logs in, joins a group, or the guild roster changes. Seeing a newer
-- version of an installed product prints one notice per session. Addon chat
-- is blocked during encounters, keystones and PvP matches, so sends route
-- through the Dialect guard and simply skip when restricted.
local ADDON = ...
local Core = LibStub("WickCore-1.0", true)
if not Core or Core._sourceAddon ~= ADDON then return end
local Version = {}
Core.Version = Version
Version.PREFIX = "WICK"
Version.registered = Version.registered or {}
Version.newest = Version.newest or {}
Version.notified = Version.notified or {}
local D = Core.Dialect
local THROTTLE = 30
local lastSend = 0
function Version:Register(addon)
if not addon.version then return end
self.registered[addon.name] = addon
self.newest[addon.name] = self.newest[addon.name] or addon.version
self:_Schedule(5)
end
local function channels()
local out = {}
if IsInRaid and IsInRaid() then out[#out + 1] = "RAID"
elseif IsInGroup and IsInGroup() then out[#out + 1] = "PARTY" end
if IsInGuild and IsInGuild() then out[#out + 1] = "GUILD" end
return out
end
function Version:Broadcast(force)
local now = GetTime and GetTime() or 0
if not force and now - lastSend < THROTTLE then return end
lastSend = now
local chans = channels()
if #chans == 0 then return end
for name, addon in pairs(self.registered) do
local msg = "V\t" .. name .. "\t" .. tostring(addon.version)
for _, chan in ipairs(chans) do
D.SendAddonMessage(self.PREFIX, msg, chan)
end
end
end
function Version:_Schedule(delay)
if self.pending then return end
self.pending = true
local function go()
self.pending = false
self:Broadcast(true)
end
if rawget(_G, "C_Timer") and C_Timer.After then C_Timer.After(delay, go) else go() end
end
function Version:OnMessage(prefix, text, _, sender)
-- Chat payloads reach a tainted addon as secret strings while the
-- client's restrictions are up, and a secret cannot be compared or
-- matched. Addon messages have not been seen to arrive that way,
-- but the line below compares and the one after matches, so the
-- same guard costs nothing and removes the whole class.
local R = Core.Restrict
if R and (R:IsSecret(prefix) or R:IsSecret(text)) then return end
if prefix ~= self.PREFIX then return end
local kind, name, ver = text:match("^(%a)\t([^\t]+)\t(.+)$")
if kind ~= "V" or not name then return end
local mine = self.registered[name]
if not mine then return end
if Core.compareVersions(ver, self.newest[name]) > 0 then
self.newest[name] = ver
end
if Core.compareVersions(ver, mine.version) > 0 and not self.notified[name] then
self.notified[name] = true
mine:Print(string.format("a newer version is out: %s (you have %s)", ver, mine.version))
end
end
-- Wiring
D.RegisterAddonPrefix(Version.PREFIX)
local A = Core.self
A:On("CHAT_MSG_ADDON", function(prefix, text, channel, sender)
Version:OnMessage(prefix, text, channel, sender)
end)
A:On("GROUP_ROSTER_UPDATE", function() Version:Broadcast() end)
A:On("GUILD_ROSTER_UPDATE", function() Version:Broadcast() end)