fix: Fix NetStateGumps and other Gumps cleanup (#1919)

This commit is contained in:
Stefano Merotta 2024-08-10 18:57:28 +02:00 committed by GitHub
parent 8282b00ca2
commit 6fe01488ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 73 additions and 158 deletions

View file

@ -13,8 +13,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using Server.Gumps.Base;
using Server.Logging;
using Server.Network;
using System;
using System.Collections.Generic;
@ -26,11 +24,9 @@ namespace Server.Gumps;
public static partial class GumpSystem
{
private const int GumpCap = 512;
private const int InitialCapacity = 4;
public const int GumpCap = 512;
private static readonly Dictionary<NetState, List<BaseGump>> _gumps = [];
private static readonly ILogger _logger = LogFactory.GetLogger(typeof(GumpSystem));
public static unsafe void Configure()
{
@ -47,51 +43,7 @@ public static partial class GumpSystem
}
}
private static ReadOnlySpan<BaseGump> GetAll(NetState ns) =>
_gumps.TryGetValue(ns, out var gumps) ? CollectionsMarshal.AsSpan(gumps) : [];
private static T Find<T>(NetState ns) where T : BaseGump
{
if (ns == null || !_gumps.TryGetValue(ns, out var gumps))
{
return null;
}
var gumpsSpan = CollectionsMarshal.AsSpan(gumps);
for (int i = 0; i < gumpsSpan.Length; i++)
{
if (gumpsSpan[i] is T tGump)
{
return tGump;
}
}
return null;
}
private static void Add(NetState ns, BaseGump gump)
{
if (ns == null || gump == null)
{
return;
}
if (!_gumps.TryGetValue(ns, out var gumps))
{
gumps = new List<BaseGump>(InitialCapacity);
_gumps.Add(ns, gumps);
}
if (gumps.Count < GumpCap)
{
gumps.Add(gump);
}
else
{
_logger.Information("Exceeded gump cap, disconnecting...");
ns.Disconnect("Exceeded gump cap.");
}
}
private static T Find<T>(NetState ns) where T : BaseGump => ns != null ? Get(ns).Find<T>() : null;
private static void Remove(NetState ns, BaseGump gump)
{
@ -108,26 +60,6 @@ public static partial class GumpSystem
}
}
private static bool Remove<T>(NetState ns, out T gump) where T : BaseGump
{
if (ns != null && _gumps.TryGetValue(ns, out var gumps))
{
var gumpsSpan = CollectionsMarshal.AsSpan(gumps);
for (int i = 0; i < gumpsSpan.Length; i++)
{
if (gumpsSpan[i] is T tGump)
{
gumps.RemoveAt(i);
gump = tGump;
return true;
}
}
}
gump = null;
return false;
}
private static void Send(NetState ns, BaseGump gump, bool singleton)
{
if (ns.CannotSendPackets()) // Handles ns null check too
@ -135,62 +67,16 @@ public static partial class GumpSystem
return;
}
ref List<BaseGump> list = ref CollectionsMarshal.GetValueRefOrAddDefault(_gumps, ns, out bool exists);
if (exists)
{
bool replaced = false;
if (singleton || gump.Singleton)
{
for (int i = 0; i < list.Count; i++)
{
BaseGump old = list[i];
if (old.TypeID == gump.TypeID)
{
ns.SendCloseGump(old.TypeID, 0);
old.OnServerClose(ns);
list[i] = gump;
replaced = true;
break;
}
}
}
if (!replaced)
{
list.Add(gump);
}
}
else
{
list = [gump];
}
gump.SendTo(ns);
Get(ns).Send(gump, singleton);
}
private static bool Close<T>(NetState ns) where T : BaseGump
{
if (Remove<T>(ns, out var gump))
{
ns.SendCloseGump(gump.TypeID, 0);
gump.OnServerClose(ns);
return true;
}
return false;
}
private static readonly List<BaseGump> _emptyList = [];
private static bool Close<T>(NetState ns) where T : BaseGump => ns != null && Get(ns).Close<T>();
private static NetStateGumps Get(NetState ns)
{
if (ns == null)
{
return new NetStateGumps(_emptyList, null);
return new NetStateGumps(null, null);
}
ref List<BaseGump> list = ref CollectionsMarshal.GetValueRefOrAddDefault(_gumps, ns, out bool exists);
@ -231,13 +117,6 @@ public static partial class GumpSystem
Send(m.NetState, g, singleton);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan<BaseGump> GetAllGumps([DisallowNull] this Mobile m)
{
ArgumentNullException.ThrowIfNull(m);
return GetAll(m.NetState);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NetStateGumps GetGumps([DisallowNull] this Mobile m)
{
@ -253,10 +132,10 @@ public static partial class GumpSystem
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SendGump([DisallowNull] this NetState ns, BaseGump g, bool singleton = false)
public static T FindGump<T>([DisallowNull] this NetState ns) where T : BaseGump
{
ArgumentNullException.ThrowIfNull(ns);
Send(ns, g, singleton);
return Find<T>(ns);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -267,17 +146,10 @@ public static partial class GumpSystem
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan<BaseGump> GetAllGumps([DisallowNull] this NetState ns)
public static void SendGump([DisallowNull] this NetState ns, BaseGump g, bool singleton = false)
{
ArgumentNullException.ThrowIfNull(ns);
return GetAll(ns);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AddGump([DisallowNull] this NetState ns, BaseGump gump)
{
ArgumentNullException.ThrowIfNull(ns);
Add(ns, gump);
Send(ns, g, singleton);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]