feat(announcement): add usergroup targeting and recipient filtering to broadcasts
Add support for targeting announcements to specific usergroups or individual players. - Add 'target' field to store a usergroup to filter recipients - Implement recipient filtering logic that prioritizes explicit player lists over usergroup lists over preset target - Update net.Broadcast() to net.Send() when specific recipients are selected - Parse scope parameter from client to determine targeting type (all/group/players) - Return early if no valid recipients are found after filtering
This commit is contained in:
@@ -45,6 +45,7 @@ function BladW.Announcement.Resolve(entry)
|
|||||||
text = (entry.text and entry.text ~= "" and entry.text ) or base.text or "",
|
text = (entry.text and entry.text ~= "" and entry.text ) or base.text or "",
|
||||||
style = entry.style or base.style or "",
|
style = entry.style or base.style or "",
|
||||||
duration = tonumber(entry.duration) or tonumber(base.duration) or 0,
|
duration = tonumber(entry.duration) or tonumber(base.duration) or 0,
|
||||||
|
target = entry.target or base.target, -- usergroup ciblé (nil = tout le monde)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -56,6 +57,30 @@ function BladW.Announcement.Broadcast(entry)
|
|||||||
local a = BladW.Announcement.Resolve(entry)
|
local a = BladW.Announcement.Resolve(entry)
|
||||||
if a.text == "" then return false end
|
if a.text == "" then return false end
|
||||||
|
|
||||||
|
-- destinataires (nil = tout le monde) :
|
||||||
|
-- liste de joueurs (menu) > liste de groupes (menu) + target unique (preset/schedule)
|
||||||
|
local recipients
|
||||||
|
if istable(entry.players) and #entry.players > 0 then
|
||||||
|
recipients = {}
|
||||||
|
for _, p in ipairs(entry.players) do
|
||||||
|
if IsValid(p) and p:IsPlayer() then recipients[#recipients + 1] = p end
|
||||||
|
end
|
||||||
|
elseif (istable(entry.groups) and #entry.groups > 0)
|
||||||
|
or (a.target and a.target ~= "" and a.target ~= "all") then
|
||||||
|
local set = {}
|
||||||
|
if istable(entry.groups) then
|
||||||
|
for _, g in ipairs(entry.groups) do set[g] = true end
|
||||||
|
end
|
||||||
|
if a.target and a.target ~= "" and a.target ~= "all" then set[a.target] = true end
|
||||||
|
|
||||||
|
recipients = {}
|
||||||
|
for _, p in ipairs(player.GetAll()) do
|
||||||
|
if set[p:GetUserGroup()] then recipients[#recipients + 1] = p end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if recipients and #recipients == 0 then return false end -- personne à qui envoyer
|
||||||
|
|
||||||
local Conf = BladW.Announcement.Conf or {}
|
local Conf = BladW.Announcement.Conf or {}
|
||||||
local maxLen = tonumber(Conf.announcement_max_length) or 120
|
local maxLen = tonumber(Conf.announcement_max_length) or 120
|
||||||
local dur = a.duration > 0 and a.duration or (tonumber(Conf.announcement_duration) or 10)
|
local dur = a.duration > 0 and a.duration or (tonumber(Conf.announcement_duration) or 10)
|
||||||
@@ -68,7 +93,7 @@ function BladW.Announcement.Broadcast(entry)
|
|||||||
net.WriteString(LimitChars(a.text, maxLen))
|
net.WriteString(LimitChars(a.text, maxLen))
|
||||||
net.WriteString(a.style or "")
|
net.WriteString(a.style or "")
|
||||||
net.WriteUInt(math.Clamp(a.duration, 0, 65535), 16)
|
net.WriteUInt(math.Clamp(a.duration, 0, 65535), 16)
|
||||||
net.Broadcast()
|
if recipients then net.Send(recipients) else net.Broadcast() end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@@ -81,10 +106,30 @@ net.Receive("bladWSendAnnouncement", function(len, ply)
|
|||||||
local title = net.ReadString()
|
local title = net.ReadString()
|
||||||
local text = net.ReadString()
|
local text = net.ReadString()
|
||||||
|
|
||||||
|
-- destinataires : "all" / "group" (liste de groupes) / "players" (liste de joueurs)
|
||||||
|
-- le choix du menu est explicite -> il prime sur le target du preset
|
||||||
|
local scope = net.ReadString()
|
||||||
|
local target, groups, players = "all", nil, nil
|
||||||
|
if scope == "group" then
|
||||||
|
target = "" -- vide = on ignore le target du preset, on prend la liste
|
||||||
|
groups = {}
|
||||||
|
for _ = 1, net.ReadUInt(8) do groups[#groups + 1] = net.ReadString() end
|
||||||
|
elseif scope == "players" then
|
||||||
|
target = ""
|
||||||
|
players = {}
|
||||||
|
for _ = 1, net.ReadUInt(8) do
|
||||||
|
local p = net.ReadEntity()
|
||||||
|
if IsValid(p) and p:IsPlayer() then players[#players + 1] = p end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local ok = BladW.Announcement.Broadcast({
|
local ok = BladW.Announcement.Broadcast({
|
||||||
preset = preset ~= "" and preset or nil,
|
preset = preset ~= "" and preset or nil,
|
||||||
title = title,
|
title = title,
|
||||||
text = text,
|
text = text,
|
||||||
|
target = target,
|
||||||
|
groups = groups,
|
||||||
|
players = players,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- je réponds à l'admin : publié -> il ferme le menu, refusé -> il garde son texte
|
-- je réponds à l'admin : publié -> il ferme le menu, refusé -> il garde son texte
|
||||||
|
|||||||
Reference in New Issue
Block a user