Add per-session force send pvs override (#4781)

This commit is contained in:
Leon Friedrich
2023-12-30 13:26:56 -05:00
committed by GitHub
parent e39b249070
commit d6ce7e950b
3 changed files with 49 additions and 4 deletions

View File

@@ -18,6 +18,7 @@ public sealed class PvsOverrideSystem : EntitySystem
internal HashSet<EntityUid> GlobalOverride = new();
internal HashSet<EntityUid> ForceSend = new();
internal Dictionary<ICommonSession, HashSet<EntityUid>> SessionOverrides = new();
internal Dictionary<ICommonSession, HashSet<EntityUid>> SessionForceSend = new();
public override void Initialize()
{
@@ -35,6 +36,7 @@ public sealed class PvsOverrideSystem : EntitySystem
return;
SessionOverrides.Remove(ev.Session);
SessionForceSend.Remove(ev.Session);
}
public override void Shutdown()
@@ -61,6 +63,12 @@ public sealed class PvsOverrideSystem : EntitySystem
if (set.Remove(uid) && set.Count == 0)
SessionOverrides.Remove(session);
}
foreach (var (session, set) in SessionForceSend)
{
if (set.Remove(uid) && set.Count == 0)
SessionForceSend.Remove(session);
}
}
/// <summary>
@@ -88,7 +96,7 @@ public sealed class PvsOverrideSystem : EntitySystem
/// </summary>
/// <remarks>
/// This differs from <see cref="AddGlobalOverride"/> as it does not send children, and will ignore a players usual
/// PVS budget. You generally shouldn't use this.
/// PVS budget. You generally shouldn't use this unless an entity absolutely always needs to be sent to all clients.
/// </remarks>
public void AddForceSend(EntityUid uid)
{
@@ -103,6 +111,35 @@ public sealed class PvsOverrideSystem : EntitySystem
// might as well just do that when the entity gets deleted anyways.
}
/// <summary>
/// This causes an entity and all of its parents to always be sent to a player..
/// </summary>
/// <remarks>
/// This differs from <see cref="AddSessionOverride"/> as it does not send children, and will ignore a players usual
/// PVS budget. You generally shouldn't use this unless an entity absolutely always needs to be sent to a client.
/// </remarks>
public void AddForceSend(EntityUid uid, ICommonSession session)
{
if (SessionForceSend.GetOrNew(session).Add(uid))
_hasOverride.Add(uid);
}
/// <summary>
/// Removes an entity from a session's force send set.
/// </summary>
public void RemoveForceSend(EntityUid uid, ICommonSession session)
{
if (!SessionForceSend.TryGetValue(session, out var overrides))
return;
if (overrides.Remove(uid) && overrides.Count == 0)
SessionForceSend.Remove(session);
// Not bothering to clear _hasOverride, as we'd have to check all the other collections, and at that point we
// might as well just do that when the entity gets deleted anyways.
}
/// <summary>
/// Forces the entity, all of its parents, and all of its children to ignore normal PVS range limitations for a
/// specific session.

View File

@@ -52,6 +52,14 @@ internal sealed partial class PvsSystem
{
RecursivelyAddOverride(session, uid, fromTick, addChildren: false);
}
if (!_pvsOverride.SessionForceSend.TryGetValue(session.Session, out var sessionForce))
return;
foreach (var uid in sessionForce)
{
RecursivelyAddOverride(session, uid, fromTick, addChildren: false);
}
}
private void RaiseExpandEvent(PvsSession session, GameTick fromTick)

View File

@@ -326,12 +326,12 @@ internal sealed partial class PvsSystem : EntitySystem
session.Budget.EnterLimit = CVars.NetPVSEntityEnterBudget.DefaultValue;
}
// Process all entities in visible PVS chunks
AddPvsChunks(session);
// Process all PVS overrides.
AddAllOverrides(session);
// Process all entities in visible PVS chunks
AddPvsChunks(session);
VerifySessionData(session);
var toSend = session.ToSend!;