Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lua/pac3/core/server/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,15 @@ function pac.GetRateLimitPlayerBuffer( ply, name )
return ply[ratelimitName] or 0
end


hook.Add("PlayerInitialSpawn", "pac_initial_spawn", function(ply)
local id = "pac_initial_spawn" .. ply:UniqueID()
hook.Add( "SetupMove", id, function(movingPly, _, cmd)
if not ply:IsValid() then
hook.Remove("SetupMove", id)
elseif movingPly == ply and not cmd:IsForced() then
hook.Run("pac_initial_spawn", ply)
hook.Remove("SetupMove", id)
end
end)
end)
13 changes: 2 additions & 11 deletions lua/pac3/core/shared/entity_mutator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -301,17 +301,8 @@ if SERVER then
end
end

hook.Add("PlayerInitialSpawn", "pac_entity_mutators_spawn", function(ply)
local id = "pac_entity_mutators_spawn" .. ply:UniqueID()
hook.Add( "SetupMove", id, function(movingPly, _, cmd)
if not ply:IsValid() then
hook.Remove("SetupMove", id)
elseif movingPly == ply and not cmd:IsForced() then
emut.ReplicateMutatorsForPlayer(ply)

hook.Remove("SetupMove", id)
end
end)
hook.Add("pac_initial_spawn", "pac_entity_mutators_spawn", function(ply)
emut.ReplicateMutatorsForPlayer(ply)
end)
end

Expand Down
1 change: 1 addition & 0 deletions lua/pac3/editor/client/wear.lua
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ do -- from server
function pace.WearPartFromServer(owner, part_data, data, doItNow)
pac.dprint("received outfit %q from %s with %i number of children to set on %s", part_data.self.Name or "", tostring(owner), table.Count(part_data.children), part_data.self.OwnerName or "")

if not IsValid(owner) or not owner:IsPlayer() or pac.IsEntityIgnored(owner) then return end
if pace.CallHook("WearPartFromServer", owner, part_data, data) == false then return end

local dupepart = pac.GetPartFromUniqueID(data.player_uid, part_data.self.UniqueID)
Expand Down
74 changes: 64 additions & 10 deletions lua/pac3/editor/client/wear_filter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ local function jsonid(ply)
return "_" .. pac.Hash(ply)
end

local function update_ignore()
local function update_ignore(shouldRequest)
for _, ply in ipairs(player.GetHumans()) do
pac.ToggleIgnoreEntity(ply, pace.ShouldIgnorePlayer(ply), "wear_filter")
end
end

hook.Add("PlayerSpawn", "pace_outfit_ignore_update", function()
update_ignore()
end)
if shouldRequest then
RunConsoleCommand("pac_request_outfits")
else
-- Transmit to server with a delay to coalesce rapid changes.
-- Don't need to transmit when requesting as that already makes the server prompt a filter update on everyone.
timer.Create( "pace_transmit_outfit_ignore", 4, 1, pace.TransmitOutfitFilter )
end
end

net.Receive("pac.TogglePartDrawing", function()
local ent = net.ReadEntity()
Expand Down Expand Up @@ -237,7 +241,7 @@ local function player_list_form(name, id, help)
store_config(id, tbl)

if id:StartWith("outfit") then
update_ignore()
update_ignore(id:EndsWith("whitelist")) -- auto-request if adding to whitelist (store_ is backwards???)
end
end,

Expand Down Expand Up @@ -268,7 +272,7 @@ local function player_list_form(name, id, help)
store_config(id, tbl)

if id:StartWith("outfit") then
update_ignore()
update_ignore(id:EndsWith("blacklist")) -- auto-request if removing from blacklist (store_ is backwards???)
end
end,
})
Expand All @@ -277,9 +281,9 @@ local function player_list_form(name, id, help)
end

do
net.Receive("pac_update_playerfilter", function()
net.Receive("pac_update_wearfilter", function()
local ids = pace.CreateWearFilter()
net.Start("pac_update_playerfilter")
net.Start("pac_update_wearfilter")
net.WriteUInt(#ids, 8)

for _, val in ipairs(ids) do
Expand All @@ -289,6 +293,34 @@ do
net.SendToServer()
end)

net.Receive("pac_update_wearfilter_singular_add",function()
local ids = pace.CreateWearFilter()
local id = net.ReadString()
if not table.HasValue(ids, id) then return end

net.Start("pac_update_wearfilter_singular_add")
net.WriteString(id)
net.SendToServer()
end)

net.Receive("pac_update_outfitfilter", pace.TransmitOutfitFilter )

net.Receive("pac_update_outfitfilter_singular_add",function()
local id = net.ReadString()
local ply = player.GetBySteamID(id)
if not IsValid(ply) then return end

if pace.ShouldIgnorePlayer(ply) then
pac.IgnoreEntity(ply, "wear_filter")

return
end

net.Start("pac_update_outfitfilter_singular_add")
net.WriteString(id)
net.SendToServer()
end)

function pace.PopulateWearMenu(menu)
for _, ply in ipairs(player.GetHumans()) do
if ply == pac.LocalPlayer then continue end
Expand All @@ -299,6 +331,28 @@ do
icon:SetImage(pace.MiscIcons.wear)
end
end

function pace.TransmitOutfitFilter()
local mode = GetConVar("pace_outfit_filter_mode"):GetString()
local ids = {} -- ids of ignored players

if mode ~= "disabled" then
for _, ply in ipairs(player.GetHumans()) do
if pace.ShouldIgnorePlayer(ply) then
table.insert(ids, ply:SteamID64())
end
end
end

net.Start("pac_update_outfitfilter")
net.WriteUInt(#ids, 8)

for _, val in ipairs(ids) do
net.WriteString(val)
end

net.SendToServer()
end
end

function pace.FillWearSettings(pnl)
Expand Down Expand Up @@ -385,7 +439,7 @@ function pace.FillWearSettings(pnl)

mode.form:SetParent(list)

update_ignore()
update_ignore(true)
end

local mode_str = GetConVar("pace_outfit_filter_mode"):GetString():gsub("_", " ")
Expand Down
10 changes: 10 additions & 0 deletions lua/pac3/editor/server/wear.lua
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ function pace.SubmitPartNow(data, filter)
local ply = players[key]
if not ply.pac_requested_outfits and ply ~= owner then
table.remove(players, key)
else
local ignoreLookup = ply.pac_outfit_ignore_lookup

if ignoreLookup and ignoreLookup[owner] then
table.remove(players, key)
end
end
end

Expand Down Expand Up @@ -443,3 +449,7 @@ function pace.RequestOutfits(ply)
end

concommand.Add("pac_request_outfits", pace.RequestOutfits)

hook.Add("pac_initial_spawn", "pac_update_wear_filter", function(ply)
pace.UpdateWearFiltersSingular(ply) -- Prevent wear filters from being skipped for a player who joins and doesn't manually request outfits
end)
156 changes: 138 additions & 18 deletions lua/pac3/editor/server/wear_filter.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

util.AddNetworkString('pac_submit_acknowledged')
util.AddNetworkString('pac_update_playerfilter')
util.AddNetworkString("pac_submit_acknowledged")
util.AddNetworkString("pac_update_wearfilter")
util.AddNetworkString("pac_update_wearfilter_singular_add")
util.AddNetworkString("pac_update_outfitfilter")
util.AddNetworkString("pac_update_outfitfilter_singular_add")

local function find_outfits(ply)
for id, outfits in pairs(pace.Parts) do
Expand All @@ -15,7 +18,56 @@ local function find_outfits(ply)
return {}
end

pace.PCallNetReceive(net.Receive, "pac_update_playerfilter", function(len, ply)
local function updateWearFilter(ply, ids)
ply.pac_wearfilter_ids = ids

for _, outfit in pairs(find_outfits(ply)) do
if outfit.wear_filter then
for _, id in ipairs(ids) do
if not table.HasValue(outfit.wear_filter, id) then
local p = pac.ReverseHash(id, "Player")
if p:IsValid() then
if p.pac_requested_outfits and not p.pac_gonna_receive_outfits then
pace.SubmitPart(outfit, p)
end
end
end
end
end

outfit.wear_filter = ids
end
end

local function checkCooldown(ply, cooldownID, cooldownDisplay)
local varNameCD = "pac_cooldown_" .. cooldownID
local varNameLogCD = "pac_log_cooldown_" .. cooldownID
local curCooldown = ply[varNameCD]

if curCooldown and curCooldown > CurTime() then
local logCooldown = ply[varNameLogCD]

if logCooldown and logCooldown < CurTime() then
pac.Message("Player ", ply, " tried to submit " .. cooldownDisplay .. " too quickly, dropping.")
ply[varNameLogCD] = CurTime() + 1
end

return false
end

ply[varNameCD] = CurTime() + 5

return true
end

local function clearCooldown(ply, cooldownID)
ply["pac_cooldown_" .. cooldownID] = nil
end


pace.PCallNetReceive(net.Receive, "pac_update_wearfilter", function(len, ply)
if not checkCooldown(ply, "wearfilter", "wear filters") then return end

local sizeof = net.ReadUInt(8)

if sizeof > game.MaxPlayers() then
Expand All @@ -29,26 +81,94 @@ pace.PCallNetReceive(net.Receive, "pac_update_playerfilter", function(len, ply)
table.insert(ids, net.ReadString())
end

for _, outfit in pairs(find_outfits(ply)) do
updateWearFilter(ply, ids)
end)

if outfit.wear_filter then
for _, id in ipairs(ids) do
if not table.HasValue(outfit.wear_filter, id) then
local ply = pac.ReverseHash(id, "Player")
if ply:IsValid() then
if ply.pac_requested_outfits and not ply.pac_gonna_receive_outfits then
pace.SubmitPart(outfit, ply)
end
end
end
end
end
pace.PCallNetReceive(net.Receive, "pac_update_wearfilter_singular_add", function(len, ply)
if not checkCooldown(ply, "wearfilter_singular", "singular wear filters") then return end

outfit.wear_filter = ids
local ids = ply.pac_wearfilter_ids or {}
local id = net.ReadString()
if table.HasValue(ids, id) then return end

table.insert(ids, id)
ply.pac_wearfilter_ids = ids -- In case it was nil
updateWearFilter(ply, ids)
end)

pace.PCallNetReceive(net.Receive, "pac_update_outfitfilter", function(len, ply)
if not checkCooldown(ply, "outfitfilter", "outfit filters") then return end

local sizeof = net.ReadUInt(8)

if sizeof > game.MaxPlayers() then
pac.Message("Player ", ply, " tried to submit extraordinary outfit filter size of ", sizeof, ", dropping.")
return
end

local filter = {}

for i = 1, sizeof do
local p = player.GetBySteamID64(net.ReadString())

if IsValid(p) then
filter[p] = true
end
end

ply.pac_outfit_ignore_lookup = filter
end)

pace.PCallNetReceive(net.Receive, "pac_update_outfitfilter_singular_add", function(len, ply)
if not checkCooldown(ply, "outfitfilter_singular", "singular outfit filters") then return end

local lookup = ply.pac_outfit_ignore_lookup or {}
local p = player.GetBySteamID64(net.ReadString())
if not IsValid(p) or lookup[p] then return end

lookup[p] = true
ply.pac_outfit_ignore_lookup = lookup -- In case it was nil
end)

function pace.UpdateWearFilters()
net.Start('pac_update_playerfilter')
for _, ply in player.Iterator() do
clearCooldown(ply, "outfitfilter")
clearCooldown(ply, "wearfilter")
end

net.Start("pac_update_outfitfilter")
net.Broadcast()

net.Start("pac_update_wearfilter")
net.Broadcast()
end

-- For when a player joins the server.
function pace.UpdateWearFiltersSingular(ply)
-- Technically could miss some messages due to cooldowns if 2+ players full load at the same time,
-- but gmod load time variance should make this a non-issue.
-- TODO: Needs thorough testing against map changes with high player count.
for _, p in player.Iterator() do
clearCooldown(p, "wearfilter_singular")
clearCooldown(p, "outfitfilter_singular")
clearCooldown(p, "outfitfilter")
clearCooldown(p, "wearfilter")
end

local plys = player.GetHumans()
table.RemoveByValue(plys, ply)

net.Start("pac_update_wearfilter_singular_add")
net.WriteString(pac.Hash(ply))
net.Send(plys)

net.Start("pac_update_outfitfilter_singular_add")
net.WriteString(ply:SteamID())
net.Send(plys)

net.Start("pac_update_outfitfilter")
net.Send(ply)

net.Start("pac_update_wearfilter")
net.Send(ply)
end
Loading