diff --git a/Projects/Server.Tests/Tests/PropertyList/ObjectPropertyListReentrancyTests.cs b/Projects/Server.Tests/Tests/PropertyList/ObjectPropertyListReentrancyTests.cs index b7816ae96..a30e9c9e3 100644 --- a/Projects/Server.Tests/Tests/PropertyList/ObjectPropertyListReentrancyTests.cs +++ b/Projects/Server.Tests/Tests/PropertyList/ObjectPropertyListReentrancyTests.cs @@ -8,8 +8,7 @@ namespace Server.Tests; /// hole is evaluated while it is live. A Reset()/Dispose() landing in that window used to leave the /// next Append* spanning a null array: ArgumentNullException, parameter "array". /// -// Sequential: building a list rents and returns through STArrayPool, whose bucket cache is a plain static -// with a check-then-act initialize. Two test classes doing this on different threads race it. +// Sequential: building a list rents from STArrayPool, which is not thread-safe. [Collection("Sequential Server Tests")] public class ObjectPropertyListReentrancyTests { @@ -55,7 +54,7 @@ public class ObjectPropertyListReentrancyTests /// The guard is per-list, so nested builds (a GetProperties override that reads another entity's /// PropertyList) cannot unguard the outer one the way a single shared slot would. /// -[Collection("Sequential Server Tests")] // same STArrayPool exposure as above +[Collection("Sequential Server Tests")] public class ObjectPropertyListNestedBuildTests { [Fact] diff --git a/Projects/Server/Network/Bans/BanChannel.cs b/Projects/Server/Network/Bans/BanChannel.cs index bd159a893..b682158d0 100644 --- a/Projects/Server/Network/Bans/BanChannel.cs +++ b/Projects/Server/Network/Bans/BanChannel.cs @@ -104,13 +104,11 @@ public static class BanChannel /// Fans a locally-decided ban out to every reporter. Non-blocking; never throws. /// - /// Optional content-supplied exemption. When it returns true the contribution is dropped before reaching - /// any reporter. + /// Optional content-supplied exemption; true drops the contribution before any reporter sees it. This + /// withholds escalation only — the gate that reached the verdict has already acted. /// /// - /// Suppresses escalation only — the gate that reached the verdict has already acted, so the shard stays - /// protected. The reason is passed so policy can refuse to exempt an operator's own decision; an - /// implementation that ignores it would silently swallow manual bans. See + /// An implementation that ignores reason would silently swallow manual bans. See /// . /// public static Func IsExempt { get; set; } diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index e76c4bfa8..7312603f7 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -696,14 +696,9 @@ public partial class NetState : IComparable, IValueLinkListNode. * *************************************************************************/ +using System; using System.Net; using Server.Network.Bans; namespace Server.Network; /// -/// The single answer to "should this ban contribution be dropped?", combining the operator's file allowlist -/// with the one addresses earn by logging in. Owns so neither source has to -/// know about the other. +/// Combines and into the one answer +/// asks for, so neither source has to know about the other. /// -/// -/// Suppresses escalation only. Whatever gate reached the verdict has already acted, so the shard is -/// protected either way; what is withheld is pushing the address to an external bouncer. -/// public static class BanExemptions { public static void Configure() @@ -41,7 +37,7 @@ public static class BanExemptions /// Split for testing. is stateful — calling it spends a strike — so it /// must not be invoked once the answer is already decided. /// - internal static bool IsExempt(IPAddress address, string reason, System.Func loginAllowlist) + internal static bool IsExempt(IPAddress address, string reason, Func loginAllowlist) { if (address == null) { diff --git a/Projects/UOContent/Network/LoginAllowlist/LoginAllowlist.cs b/Projects/UOContent/Network/LoginAllowlist/LoginAllowlist.cs index 5ff52882e..ed65b5ec6 100644 --- a/Projects/UOContent/Network/LoginAllowlist/LoginAllowlist.cs +++ b/Projects/UOContent/Network/LoginAllowlist/LoginAllowlist.cs @@ -33,9 +33,9 @@ namespace Server.Network; /// /// /// Consulted only after the blocklist has already matched, and again before a ban is contributed, so a -/// normal accept pays nothing for it. Suppresses escalation only. An entry is evidence rather than a -/// licence: enough strikes inside the window revokes it. It cannot bootstrap, so it hedges stable addresses -/// and does not replace . See dev-docs/ip-bans-and-allowlists.md. +/// normal accept pays nothing for it. An entry is evidence rather than a licence: enough strikes inside the +/// window revokes it. It cannot bootstrap, so it hedges stable addresses and does not replace +/// . See dev-docs/ip-bans-and-allowlists.md. /// /// /// Both dictionaries are game-loop state. Only the file write runs off-loop, over a snapshot taken on the