fix: Fixes map iterators for Items (#1564)
### Summary Modifying a ValueLinkList using one of the methods will bump the "version". This field is used by iterators (foreach loops) to determine if the link list was modified while iterating. The sector.Items (and in the future other lists), will no longer be safe to modify while iterating. The server will _CRASH_ if the ValueLinkList is modified. Thanks to @stefanomerotta for help! ### Screenshots <img width="588" alt="image" src="https://github.com/modernuo/ModernUO/assets/3953314/83ee0b6e-ff4f-4768-9e29-84456e04b1ec">
This commit is contained in:
parent
658f564f34
commit
d919f71149
33 changed files with 706 additions and 468 deletions
|
|
@ -627,12 +627,6 @@ public sealed partial class Map : IComparable<Map>, ISpanFormattable, ISpanParsa
|
|||
|
||||
public void OnEnter(Item item)
|
||||
{
|
||||
if (IsIteratingItems)
|
||||
{
|
||||
_delayedItemActions.Add((MapAction.Enter, item.Location, item));
|
||||
return;
|
||||
}
|
||||
|
||||
OnEnter(item.Location, item);
|
||||
}
|
||||
|
||||
|
|
@ -669,12 +663,6 @@ public sealed partial class Map : IComparable<Map>, ISpanFormattable, ISpanParsa
|
|||
|
||||
public void OnLeave(Item item)
|
||||
{
|
||||
if (IsIteratingItems)
|
||||
{
|
||||
_delayedItemActions.Add((MapAction.Leave, item.Location, item));
|
||||
return;
|
||||
}
|
||||
|
||||
OnLeave(item.Location, item);
|
||||
}
|
||||
|
||||
|
|
@ -765,12 +753,6 @@ public sealed partial class Map : IComparable<Map>, ISpanFormattable, ISpanParsa
|
|||
|
||||
if (oldSector != newSector)
|
||||
{
|
||||
if (IsIteratingItems)
|
||||
{
|
||||
_delayedItemActions.Add((MapAction.Move, item.Location, item));
|
||||
return;
|
||||
}
|
||||
|
||||
oldSector.OnLeave(item);
|
||||
newSector.OnEnter(item);
|
||||
}
|
||||
|
|
@ -787,12 +769,6 @@ public sealed partial class Map : IComparable<Map>, ISpanFormattable, ISpanParsa
|
|||
|
||||
if (oldStart != start || oldEnd != end)
|
||||
{
|
||||
if (IsIteratingItems)
|
||||
{
|
||||
_delayedItemActions.Add((MapAction.Move, oldLocation, item));
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveMulti(m, oldStart, oldEnd);
|
||||
AddMulti(m, start, end);
|
||||
}
|
||||
|
|
@ -1038,8 +1014,6 @@ public sealed partial class Map : IComparable<Map>, ISpanFormattable, ISpanParsa
|
|||
|
||||
public Sector GetSector(Point2D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift);
|
||||
|
||||
// public Sector GetSector(IPoint2D p) => InternalGetSector(p.X >> SectorShift, p.Y >> SectorShift);
|
||||
|
||||
public Sector GetSector(int x, int y) => InternalGetSector(x >> SectorShift, y >> SectorShift);
|
||||
|
||||
public Sector GetRealSector(int x, int y) => InternalGetSector(x, y);
|
||||
|
|
@ -1459,14 +1433,6 @@ public sealed partial class Map : IComparable<Map>, ISpanFormattable, ISpanParsa
|
|||
return false;
|
||||
}
|
||||
|
||||
private enum MapAction
|
||||
{
|
||||
None,
|
||||
Enter,
|
||||
Leave,
|
||||
Move
|
||||
}
|
||||
|
||||
public class Sector
|
||||
{
|
||||
// TODO: Can we avoid this?
|
||||
|
|
@ -1495,7 +1461,7 @@ public sealed partial class Map : IComparable<Map>, ISpanFormattable, ISpanParsa
|
|||
|
||||
public List<Mobile> Mobiles => _mobiles ?? m_DefaultMobileList;
|
||||
|
||||
public ref ValueLinkList<Item> Items => ref _items;
|
||||
internal ref readonly ValueLinkList<Item> Items => ref _items;
|
||||
|
||||
public List<NetState> Clients => _clients ?? m_DefaultClientList;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue