Skip to content

Commit

Permalink
Allow _some_ use of DarkRPVars in the EntityRemoved hook
Browse files Browse the repository at this point in the history
  • Loading branch information
FPtje committed Dec 16, 2024
1 parent 59ab5d7 commit d9ac533
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
25 changes: 24 additions & 1 deletion gamemode/modules/base/cl_entityvars.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,31 @@ timer.Simple(0, fp{RunConsoleCommand, "_sendDarkRPvars"})

net.Receive("DarkRP_DarkRPVarDisconnect", function(len)
local userID = net.ReadUInt(16)
timer.Simple(5, function()
local ply = Player(userID)

-- If the player is already gone, then immediately clear the data and move on.
if not IsValid(ply) then
DarkRP.ClientsideDarkRPVars[userID] = nil
return
end
-- Otherwise, we need to wait until the player is actually removed
-- clientside. The net message may come in _much_ earlier than the message
-- that the player disconnected and should therefore be removed.
local hook_name = "darkrp_remove_darkrp_var_" .. userID

hook.Add("EntityRemoved", hook_name, function(ent)
-- NOTE: ent:UserID() will return -1 in this hook, so there is no use to
-- compare UserIDs. That also means that getting DarkRPVars in the
-- EntityRemoved hook is futile, as the lookup of -1 in
-- DarkRP.ClientsideDarkRPVars wil fail.
if ent ~= ply then return end
hook.Remove("EntityRemoved", hook_name)

-- Placing this in a timer allows for the rest of the hook runners to
-- still use the DarkRPVars until the entity is _really_ gone.
timer.Simple(0, function()
DarkRP.ClientsideDarkRPVars[userID] = nil
end)
end)
end)

Expand Down
25 changes: 12 additions & 13 deletions gamemode/modules/base/sv_entityvars.lua
Original file line number Diff line number Diff line change
Expand Up @@ -269,19 +269,18 @@ function meta:customEntityCount(entTable)
return entities
end

hook.Add("PlayerDisconnected", "DarkRP_VarRemoval", function(ply)
maxEntities[ply] = nil
-- We use EntityRemoved to clear players of tables, because it is always called
-- after the PlayerDisconnected hook. This is called _after_ the GAMEMODE
-- function, to make sure that all regular hooks can still use DarkRPVars until
-- the very end. See https://github.com/FPtje/DarkRP/pull/3270
(GAMEMODE or GM).DarkRPPostEntityRemoved = function(_gm, ent)
if not ent:IsPlayer() then return end

maxEntities[ent] = nil
DarkRP.ServerDarkRPVars[ent] = nil
DarkRP.ServerPrivateDarkRPVars[ent] = nil

net.Start("DarkRP_DarkRPVarDisconnect")
net.WriteUInt(ply:UserID(), 16)
net.WriteUInt(ent:UserID(), 16)
net.Broadcast()
end)

hook.Add("EntityRemoved", "DarkRP_VarRemoval", function(ent) -- We use EntityRemoved to clear players of tables, because it is always called after the PlayerDisconnected hook
if ent:IsPlayer() then
timer.Simple(0, function()
DarkRP.ServerDarkRPVars[ent] = nil
DarkRP.ServerPrivateDarkRPVars[ent] = nil
end)
end
end)
end
6 changes: 6 additions & 0 deletions gamemode/modules/base/sv_gamemode_functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ function GM:EntityRemoved(ent)
local owner = ent.Getowning_ent and ent:Getowning_ent() or Player(ent.SID or 0)
if ent.DarkRPItem and IsValid(owner) and not ent.IsPocketing then owner:removeCustomEntity(ent.DarkRPItem) end
if ent.isKeysOwnable and ent:isKeysOwnable() then ent:removeDoorData() end

-- Quick workaround for the fact that we don't have a hook ordering system
-- built into gmod.
if self.DarkRPPostEntityRemoved then
self.DarkRPPostEntityRemoved(self, ent)
end
end

function GM:ShowSpare1(ply)
Expand Down

0 comments on commit d9ac533

Please sign in to comment.