diff --git a/Projects/UOContent/Engines/ConPVP/AcceptDuelGump.cs b/Projects/UOContent/Engines/ConPVP/AcceptDuelGump.cs
index c705587c1..00a2bf29e 100644
--- a/Projects/UOContent/Engines/ConPVP/AcceptDuelGump.cs
+++ b/Projects/UOContent/Engines/ConPVP/AcceptDuelGump.cs
@@ -244,7 +244,7 @@ namespace Server.Engines.ConPVP
m_Challenger.SendMessage($"{m_Challenged.Name} has accepted the request.");
m_Challenged.SendMessage($"You have accepted the request from {m_Challenger.Name}.");
- foreach (var g in m_Challenger.GetAllGumps())
+ foreach (var g in m_Challenger.GetGumps())
{
if (g is ParticipantGump pg && pg.Participant == m_Participant)
{
diff --git a/Projects/UOContent/Engines/ConPVP/DuelContext.cs b/Projects/UOContent/Engines/ConPVP/DuelContext.cs
index bbb8986d6..c44bb85c2 100644
--- a/Projects/UOContent/Engines/ConPVP/DuelContext.cs
+++ b/Projects/UOContent/Engines/ConPVP/DuelContext.cs
@@ -1541,7 +1541,7 @@ namespace Server.Engines.ConPVP
p.Nullify(pl);
pm.DuelPlayer = null;
- foreach (var g in init.GetAllGumps())
+ foreach (var g in init.GetGumps())
{
if (g is ParticipantGump pg && pg.Participant == p)
{
@@ -1576,7 +1576,7 @@ namespace Server.Engines.ConPVP
var send = true;
- foreach (var g in init.GetAllGumps())
+ foreach (var g in init.GetGumps())
{
if (g is ParticipantGump pg && pg.Participant == p)
{
@@ -1620,7 +1620,7 @@ namespace Server.Engines.ConPVP
var send = true;
- foreach (var g in init.GetAllGumps())
+ foreach (var g in init.GetGumps())
{
if (g is ParticipantGump pg && pg.Participant == p)
{
diff --git a/Projects/UOContent/Gumps/Base/GumpSystem.IncomingPackets.cs b/Projects/UOContent/Gumps/Base/GumpSystem.IncomingPackets.cs
index ca4f5e968..e1d6d033b 100644
--- a/Projects/UOContent/Gumps/Base/GumpSystem.IncomingPackets.cs
+++ b/Projects/UOContent/Gumps/Base/GumpSystem.IncomingPackets.cs
@@ -37,15 +37,18 @@ public static partial class GumpSystem
BaseGump baseGump = null;
- foreach (var g in GetAll(state))
+ if (_gumps.TryGetValue(state, out var gumps))
{
- if (g.Serial != serial || g.TypeID != typeId)
+ foreach (var g in gumps)
{
- continue;
- }
+ if (g.Serial != serial || g.TypeID != typeId)
+ {
+ continue;
+ }
- baseGump = g;
- break;
+ baseGump = g;
+ break;
+ }
}
if (baseGump != null)
diff --git a/Projects/UOContent/Gumps/Base/GumpSystem.cs b/Projects/UOContent/Gumps/Base/GumpSystem.cs
index fa96b627d..957f31852 100644
--- a/Projects/UOContent/Gumps/Base/GumpSystem.cs
+++ b/Projects/UOContent/Gumps/Base/GumpSystem.cs
@@ -13,8 +13,6 @@
* along with this program. If not, see . *
*************************************************************************/
-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> _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 GetAll(NetState ns) =>
- _gumps.TryGetValue(ns, out var gumps) ? CollectionsMarshal.AsSpan(gumps) : [];
-
- private static T Find(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(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(NetState ns) where T : BaseGump => ns != null ? Get(ns).Find() : null;
private static void Remove(NetState ns, BaseGump gump)
{
@@ -108,26 +60,6 @@ public static partial class GumpSystem
}
}
- private static bool Remove(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 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(NetState ns) where T : BaseGump
- {
- if (Remove(ns, out var gump))
- {
- ns.SendCloseGump(gump.TypeID, 0);
- gump.OnServerClose(ns);
- return true;
- }
-
- return false;
- }
-
- private static readonly List _emptyList = [];
+ private static bool Close(NetState ns) where T : BaseGump => ns != null && Get(ns).Close();
private static NetStateGumps Get(NetState ns)
{
if (ns == null)
{
- return new NetStateGumps(_emptyList, null);
+ return new NetStateGumps(null, null);
}
ref List 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 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([DisallowNull] this NetState ns) where T : BaseGump
{
ArgumentNullException.ThrowIfNull(ns);
- Send(ns, g, singleton);
+ return Find(ns);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -267,17 +146,10 @@ public static partial class GumpSystem
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan 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)]
diff --git a/Projects/UOContent/Gumps/Base/NetStateGumps.cs b/Projects/UOContent/Gumps/Base/NetStateGumps.cs
index 626ee7fcd..61f47b3a0 100644
--- a/Projects/UOContent/Gumps/Base/NetStateGumps.cs
+++ b/Projects/UOContent/Gumps/Base/NetStateGumps.cs
@@ -1,10 +1,31 @@
-using Server.Network;
-using System.Collections.Generic;
+/*************************************************************************
+ * ModernUO *
+ * Copyright 2019-2023 - ModernUO Development Team *
+ * Email: hi@modernuo.com *
+ * File: NetStateGumps.cs *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
+ *************************************************************************/
-namespace Server.Gumps.Base;
+using Server.Logging;
+using Server.Network;
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Server.Gumps;
public readonly ref struct NetStateGumps
{
+ private static readonly ILogger _logger = LogFactory.GetLogger(typeof(NetStateGumps));
+
private readonly List _gumps;
private readonly NetState _state;
@@ -16,7 +37,7 @@ public readonly ref struct NetStateGumps
public bool Close() where T : BaseGump
{
- if (_state == null || _gumps == null)
+ if (_state == null)
{
return false;
}
@@ -38,7 +59,7 @@ public readonly ref struct NetStateGumps
public T Find() where T : BaseGump
{
- if (_state == null || _gumps == null)
+ if (_state == null)
{
return null;
}
@@ -81,7 +102,18 @@ public readonly ref struct NetStateGumps
}
}
+ if (_gumps.Count >= GumpSystem.GumpCap)
+ {
+ _logger.Information("Exceeded gump cap, disconnecting...");
+ _state.Disconnect("Exceeded gump cap.");
+ return;
+ }
+
_gumps.Add(gump);
gump.SendTo(_state);
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public ReadOnlySpan.Enumerator GetEnumerator() =>
+ ((ReadOnlySpan)CollectionsMarshal.AsSpan(_gumps)).GetEnumerator();
}
diff --git a/Projects/UOContent/Gumps/PricedResurrectGump.cs b/Projects/UOContent/Gumps/PricedResurrectGump.cs
index 205e9a12a..3d173c38b 100644
--- a/Projects/UOContent/Gumps/PricedResurrectGump.cs
+++ b/Projects/UOContent/Gumps/PricedResurrectGump.cs
@@ -15,7 +15,6 @@ public class PricedResurrectGump : StaticGump
_healer = healer;
_price = price;
- // Close this gump when
TypeID = GetTypeId(typeof(ResurrectGump));
}
@@ -101,8 +100,8 @@ public class PricedResurrectGump : StaticGump
if (Banker.Withdraw(from, _price))
{
- // ~1_AMOUNT~ gold has been withdrawn from your bank box.
- from.SendLocalizedMessage(1060398, _price.ToString());
+ // ~1_AMOUNT~ gold has been withdrawn from your bank to cover the price of the healing.
+ from.SendLocalizedMessage(1060021, _price.ToString());
// You have ~1_AMOUNT~ gold in cash remaining in your bank box.
from.SendLocalizedMessage(1060022, Banker.GetBalance(from).ToString());
diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs
index dd015ee04..b88f3a9fb 100644
--- a/Projects/UOContent/Mobiles/PlayerMobile.cs
+++ b/Projects/UOContent/Mobiles/PlayerMobile.cs
@@ -1723,10 +1723,19 @@ namespace Server.Mobiles
public override bool Move(Direction d)
{
- if (NetState != null && Alive && !NetState.CloseGump())
+ if (NetState != null)
{
- SendLocalizedMessage(500111); // You are frozen and cannot move.
- return false;
+ var gumps = NetState.GetGumps();
+
+ if (Alive)
+ {
+ gumps.Close();
+ }
+ else if (gumps.Has())
+ {
+ SendLocalizedMessage(500111); // You are frozen and cannot move.
+ return false;
+ }
}
// var speed = ComputeMovementSpeed(d);