From 019672b02661f69792b612198fe7c9012cff9e02 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 2 Feb 2025 11:38:10 -0800 Subject: [PATCH 1/2] fix: Fixes cannot see that issue with Map LOS Refactor. (#2103) --- Projects/Server/Geometry/Point3DList.cs | 2 +- Projects/Server/Maps/Map.cs | 55 ++++++++++++------------- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/Projects/Server/Geometry/Point3DList.cs b/Projects/Server/Geometry/Point3DList.cs index 244a20defb..3de9410d20 100644 --- a/Projects/Server/Geometry/Point3DList.cs +++ b/Projects/Server/Geometry/Point3DList.cs @@ -9,7 +9,7 @@ public class Point3DList public Point3DList() { - m_List = new Point3D[8]; + m_List = new Point3D[16]; Count = 0; } diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index bef5ec52df..26ab156b88 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -973,25 +973,21 @@ public bool LineOfSight(Point3D origin, Point3D destination) return false; } - if (origin.X > destination.X || origin.X == destination.X && origin.Y > destination.Y || origin.X == destination.X && origin.Y == destination.Y && origin.Z > destination.Z) - { - (origin, destination) = (destination, origin); - } - - Point3D p; - var path = new Point3DList(); - TileFlag flags; - if (origin == destination) { return true; } - if (path.Count > 0) + var end = destination; + + if (origin.X > destination.X || origin.X == destination.X && origin.Y > destination.Y || origin.X == destination.X + && origin.Y == destination.Y && origin.Z > destination.Z) { - path.Clear(); + (origin, destination) = (destination, origin); } + var path = new Point3DList(); + var xd = destination.X - origin.X; var yd = destination.Y - origin.Y; var zd = destination.Z - origin.Z; @@ -1005,15 +1001,17 @@ public bool LineOfSight(Point3D origin, Point3D destination) double y = origin.Y; double z = origin.Z; double x = origin.X; - while (Utility.NumberBetween(x, destination.X, origin.X, 0.5) && Utility.NumberBetween(y, destination.Y, origin.Y, 0.5) && + while (Utility.NumberBetween(x, destination.X, origin.X, 0.5) && + Utility.NumberBetween(y, destination.Y, origin.Y, 0.5) && Utility.NumberBetween(z, destination.Z, origin.Z, 0.5)) { var ix = (int)Math.Round(x); var iy = (int)Math.Round(y); var iz = (int)Math.Round(z); + if (path.Count > 0) { - p = path.Last; + var p = path.Last; if (p.X != ix || p.Y != iy || p.Z != iz) { @@ -1035,18 +1033,13 @@ public bool LineOfSight(Point3D origin, Point3D destination) return true; // <--should never happen, but to be safe. } - p = path.Last; - - if (p != destination) + if (path.Last != destination) { path.Add(destination); } - Point3D pTop = origin, pBottom = destination; - Utility.FixPoints(ref pTop, ref pBottom); - var pathCount = path.Count; - var endTop = destination.Z + 1; + var endTop = end.Z + 1; for (var i = 0; i < pathCount; ++i) { @@ -1057,7 +1050,7 @@ public bool LineOfSight(Point3D origin, Point3D destination) GetAverageZ(point.X, point.Y, out var landZ, out _, out var landTop); if (landZ <= pointTop && landTop >= point.m_Z && - (point.X != destination.X || point.Y != destination.Y || landZ > endTop || landTop < destination.Z) && + (point.X != end.X || point.Y != end.Y || landZ > endTop || landTop < end.Z) && !landTile.Ignored) { return false; @@ -1085,14 +1078,14 @@ public bool LineOfSight(Point3D origin, Point3D destination) var id = TileData.ItemTable[t.ID & TileData.MaxItemValue]; - flags = id.Flags; + var flags = id.Flags; if ( t.Z <= pointTop && t.Z + id.CalcHeight >= point.Z && (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0 && - (point.X != destination.X || - point.Y != destination.Y || - t.Z > endTop || t.Z + id.CalcHeight < destination.Z) + (point.X != end.X || + point.Y != end.Y || + t.Z > endTop || t.Z + id.CalcHeight < end.Z) ) { return false; @@ -1117,6 +1110,10 @@ public bool LineOfSight(Point3D origin, Point3D destination) } } + var pTop = origin; + var pBottom = destination; + Utility.FixPoints(ref pTop, ref pBottom); + var rect = new Rectangle2D(pTop.X, pTop.Y, pBottom.X - pTop.X + 1, pBottom.Y - pTop.Y + 1); foreach (var item in GetItemsInBounds(rect)) @@ -1132,7 +1129,7 @@ public bool LineOfSight(Point3D origin, Point3D destination) } var id = item.ItemData; - flags = id.Flags; + var flags = id.Flags; if ((flags & (TileFlag.Window | TileFlag.NoShoot)) == 0) { @@ -1160,14 +1157,14 @@ public bool LineOfSight(Point3D origin, Point3D destination) itemLocation.X == destination.X && itemLocation.Y == destination.Y) && // Item is at some point along the path BEFORE the target - (itemLocation.X != destination.X || - itemLocation.Y != destination.Y || + (itemLocation.X != end.X || + itemLocation.Y != end.Y || // Item is diagonally looking DOWN at the target itemLocation.Z > endTop || // Item is diagonally looking UP at the target - itemLocation.Z + id.CalcHeight < destination.Z) + itemLocation.Z + id.CalcHeight < end.Z) ) { return false; From 717a1a062e99b7084f6ae7f1a66ffc0c1449e2f2 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 2 Feb 2025 12:05:40 -0800 Subject: [PATCH 2/2] fix: Fixes race condition with world save snapshot request (#2104) ### Summary * Fixes a race condition where the snapshot path isn't between the request snapshot being set on a background thread, and the main loop consuming that flag. Closes #2102 --- Projects/Server/Main.cs | 3 ++- Projects/Server/World/World.cs | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index 535327cbe8..44e84f0fc6 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -517,10 +517,11 @@ public static void RunEventLoop() DoKill(_restartOnKill); } + // This is generally called from background threads during Preserialize internal static void RequestSnapshot(string snapshotPath) { - _performSnapshot = true; _snapshotPath = snapshotPath; + _performSnapshot = true; // Set this after the path so race conditions do not occur } public static void VerifySerialization() diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs index 234c76d0b5..6a11c4f82d 100644 --- a/Projects/Server/World/World.cs +++ b/Projects/Server/World/World.cs @@ -324,6 +324,11 @@ internal static void Snapshot(string snapshotPath) { _serializationStart = Core.Now; + if (string.IsNullOrEmpty(snapshotPath)) + { + throw new ArgumentException("Snapshot path cannot be null or empty", nameof(snapshotPath)); + } + Persistence.SerializeAll(); PauseSerializationThreads(); EventSink.InvokeWorldSave();