From e4d6de3d1a01e6e21f4e0e49b565f70b9063fe68 Mon Sep 17 00:00:00 2001 From: Stimpy <95110502+StimpyDev@users.noreply.github.com> Date: Thu, 9 Jul 2026 17:33:15 +0200 Subject: [PATCH 1/2] Fix show mounted players to other clients and some cleanup --- src/Sanctuary.Game/Entities/Mount.cs | 7 +- src/Sanctuary.Game/Entities/Player.cs | 72 +++++++++---------- .../PacketDismountRequestHandler.cs | 24 +++++-- .../PacketMountSpawnHandler.cs | 28 ++++---- .../PacketClientFinishedLoadingHandler.cs | 34 ++++----- .../PacketWorldTeleportRequestHandler.cs | 2 +- .../PacketZoneSafeTeleportRequestHandler.cs | 2 +- .../PacketZoneTeleportRequestHandler.cs | 2 +- 8 files changed, 82 insertions(+), 89 deletions(-) diff --git a/src/Sanctuary.Game/Entities/Mount.cs b/src/Sanctuary.Game/Entities/Mount.cs index fd2a739..7f71f99 100644 --- a/src/Sanctuary.Game/Entities/Mount.cs +++ b/src/Sanctuary.Game/Entities/Mount.cs @@ -52,13 +52,8 @@ public override PlayerUpdatePacketAddNpc GetAddNpcPacket() { var packet = base.GetAddNpcPacket(); - packet.RiderGuid = Rider.Guid; + packet.RiderGuid = 0; return packet; } - - public override void Dispose() - { - base.Dispose(); - } } \ No newline at end of file diff --git a/src/Sanctuary.Game/Entities/Player.cs b/src/Sanctuary.Game/Entities/Player.cs index 1395f02..800dc72 100644 --- a/src/Sanctuary.Game/Entities/Player.cs +++ b/src/Sanctuary.Game/Entities/Player.cs @@ -263,12 +263,10 @@ public void OnAddVisibleNpcs(params IEnumerable npcs) { foreach (var npc in npcs) { - var playerUpdatePacketAddNpc = npc.GetAddNpcPacket(); - - if (npc is Mount mount && mount.Rider.Guid == Guid) - playerUpdatePacketAddNpc.RiderGuid = 0; + if (npc is Mount) + continue; - SendTunneled(playerUpdatePacketAddNpc); + SendTunneled(npc.GetAddNpcPacket()); } var playerUpdatePacketNpcRelevance = new PlayerUpdatePacketNpcRelevance(); @@ -310,9 +308,29 @@ public void OnAddVisiblePlayers(params IEnumerable players) { foreach (var player in players) { - var playerUpdatePacketAddPc = player.GetAddPcPacket(); - - SendTunneled(playerUpdatePacketAddPc); + if (player.Mount is not null) + { + var addPc = player.GetAddPcPacket(); + addPc.MountGuid = 0; + addPc.MountSeat = -1; + addPc.MountQueuePosition = -1; + addPc.NameVerticalOffset = 0; + + SendTunneled(addPc); + SendTunneled(player.Mount.GetAddNpcPacket()); + SendTunneled(new PacketMountResponse + { + RiderGuid = player.Guid, + MountGuid = player.Mount.Guid, + Seat = player.Mount.Seat, + QueuePosition = player.Mount.QueuePosition, + Unknown = 1, + CompositeEffectId = 46, + NameVerticalOffset = player.Mount.Definition.NameVerticalOffset + }); + } + else + SendTunneled(player.GetAddPcPacket()); } foreach (var player in players) @@ -323,28 +341,10 @@ public void OnRemoveVisibleNpcs(params IEnumerable npcs) { foreach (var npc in npcs) { - if (npc is Mount mount) - { - var playerUpdatePacketRemovePlayerGracefully = new PlayerUpdatePacketRemovePlayerGracefully(); - - playerUpdatePacketRemovePlayerGracefully.Guid = npc.Guid; - - playerUpdatePacketRemovePlayerGracefully.Animate = false; - playerUpdatePacketRemovePlayerGracefully.Delay = 0; - playerUpdatePacketRemovePlayerGracefully.EffectDelay = 0; - playerUpdatePacketRemovePlayerGracefully.CompositeEffectId = 46; - playerUpdatePacketRemovePlayerGracefully.Duration = 1000; - - SendTunneled(playerUpdatePacketRemovePlayerGracefully); - } - else - { - var playerUpdatePacketRemovePlayer = new PlayerUpdatePacketRemovePlayer(); - - playerUpdatePacketRemovePlayer.Guid = npc.Guid; + if (npc is Mount) + continue; - SendTunneled(playerUpdatePacketRemovePlayer); - } + SendTunneled(new PlayerUpdatePacketRemovePlayer { Guid = npc.Guid }); } foreach (var npc in npcs) @@ -355,11 +355,10 @@ public void OnRemoveVisiblePlayers(params IEnumerable players) { foreach (var player in players) { - var playerUpdatePacketRemovePlayer = new PlayerUpdatePacketRemovePlayer(); - - playerUpdatePacketRemovePlayer.Guid = player.Guid; + SendTunneled(new PlayerUpdatePacketRemovePlayer { Guid = player.Guid }); - SendTunneled(playerUpdatePacketRemovePlayer); + if (player.Mount is not null) + SendTunneled(new PlayerUpdatePacketRemovePlayer { Guid = player.Mount.Guid }); } foreach (var player in players) @@ -561,14 +560,13 @@ public override int GetHashCode() public void Dispose() { - Mount?.Dispose(); - Mount = null; - foreach (var visiblePlayer in VisiblePlayers) visiblePlayer.Value.OnRemoveVisiblePlayers([this]); - ZoneTile.Entities.Remove(Guid, out _); + Mount?.Dispose(); + Mount = null; + ZoneTile.Entities.Remove(Guid, out _); Zone.TryRemovePlayer(Guid); } } diff --git a/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketDismountRequestHandler.cs b/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketDismountRequestHandler.cs index f1f010a..41dc269 100644 --- a/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketDismountRequestHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketDismountRequestHandler.cs @@ -27,21 +27,31 @@ public static bool HandlePacket(GatewayConnection connection) if (connection.Player.Mount is null) return true; - var packetDismountResponse = new PacketDismountResponse(); - - packetDismountResponse.RiderGuid = connection.Player.Guid; - packetDismountResponse.CompositeEffectId = 0; // PFX_Teleport_Flash + var packetDismountResponse = new PacketDismountResponse + { + RiderGuid = connection.Player.Guid, + CompositeEffectId = 0, + }; connection.Player.SendTunneledToVisible(packetDismountResponse, true); - connection.Player.Mount.Dispose(); - connection.Player.Mount = null; - connection.Player.UpdateCharacterStats( CharacterStats.MaxMovementSpeed.Set(8f), CharacterStats.GlideEnabled.Set(0), CharacterStats.JumpHeight.Set(0f)); + connection.Player.SendTunneledToVisible(new PlayerUpdatePacketRemovePlayerGracefully + { + Guid = connection.Player.Mount.Guid, + Animate = false, + Delay = 0, + EffectDelay = 0, + CompositeEffectId = 0, + }, true); + + connection.Player.Mount.Dispose(); + connection.Player.Mount = null; + return true; } } \ No newline at end of file diff --git a/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketMountSpawnHandler.cs b/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketMountSpawnHandler.cs index 1ec886f..d6dbc85 100644 --- a/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketMountSpawnHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketMountSpawnHandler.cs @@ -76,22 +76,20 @@ public static void SpawnMount(GatewayConnection connection, PacketMountInfo moun mount.UpdatePosition(connection.Player.Position, connection.Player.Rotation); - var packetMountResponse = new PacketMountResponse(); + foreach (var visiblePlayer in connection.Player.VisiblePlayers) + visiblePlayer.Value.OnAddVisiblePlayers([connection.Player]); - packetMountResponse.RiderGuid = mount.Rider.Guid; - packetMountResponse.MountGuid = mount.Guid; - - packetMountResponse.Seat = mount.Seat; - - packetMountResponse.QueuePosition = mount.QueuePosition; - - packetMountResponse.Unknown = 1; - - packetMountResponse.CompositeEffectId = 46; // PFX_Teleport_Flash - - packetMountResponse.NameVerticalOffset = mountDefinition.NameVerticalOffset; - - connection.Player.SendTunneledToVisible(packetMountResponse, true); + connection.Player.SendTunneled(mount.GetAddNpcPacket()); + connection.Player.SendTunneled(new PacketMountResponse + { + RiderGuid = connection.Player.Guid, + MountGuid = mount.Guid, + Seat = mount.Seat, + QueuePosition = mount.QueuePosition, + Unknown = 1, + CompositeEffectId = 46, + NameVerticalOffset = mountDefinition.NameVerticalOffset + }); var mountStats = mountDefinition.Stats; diff --git a/src/Sanctuary.Gateway/Handlers/PacketClientFinishedLoadingHandler.cs b/src/Sanctuary.Gateway/Handlers/PacketClientFinishedLoadingHandler.cs index 61f0515..2c7c69e 100644 --- a/src/Sanctuary.Gateway/Handlers/PacketClientFinishedLoadingHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PacketClientFinishedLoadingHandler.cs @@ -24,33 +24,25 @@ public static bool HandlePacket(GatewayConnection connection) _logger.LogTrace("Received {name} packet.", nameof(PacketClientFinishedLoading)); connection.Player.Visible = true; - connection.Player.UpdatePosition(connection.Player.Position, connection.Player.Rotation); - var mount = connection.Player.Mount; - - if (mount is not null) + if (connection.Player.Mount is not null) { - mount.Visible = true; + var mount = connection.Player.Mount; + mount.Visible = true; mount.UpdatePosition(connection.Player.Position, connection.Player.Rotation); - var packetMountResponse = new PacketMountResponse(); - - packetMountResponse.RiderGuid = mount.Rider.Guid; - packetMountResponse.MountGuid = mount.Guid; - - packetMountResponse.Seat = mount.Seat; - - packetMountResponse.QueuePosition = mount.QueuePosition; - - packetMountResponse.Unknown = 1; - - packetMountResponse.CompositeEffectId = 46; // PFX_Teleport_Flash - - // packetMountResponse.NameVerticalOffset = mountDefinition.NameVerticalOffset; - - connection.Player.SendTunneled(packetMountResponse); + connection.Player.SendTunneled(new PacketMountResponse + { + RiderGuid = connection.Player.Guid, + MountGuid = mount.Guid, + Seat = mount.Seat, + QueuePosition = mount.QueuePosition, + Unknown = 1, + CompositeEffectId = 46, + NameVerticalOffset = mount.Definition.NameVerticalOffset + }); } connection.Player.Zone.OnClientFinishedLoading(connection.Player); diff --git a/src/Sanctuary.Gateway/Handlers/PacketWorldTeleportRequestHandler.cs b/src/Sanctuary.Gateway/Handlers/PacketWorldTeleportRequestHandler.cs index 16f0360..838f945 100644 --- a/src/Sanctuary.Gateway/Handlers/PacketWorldTeleportRequestHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PacketWorldTeleportRequestHandler.cs @@ -39,8 +39,8 @@ public static bool HandlePacket(GatewayConnection connection, Span data) var position = player.Position; var rotation = player.Rotation; - connection.Player.Mount?.UpdatePosition(position, rotation); connection.Player.UpdatePosition(position, rotation, updateZoneArea: false); + connection.Player.Mount?.UpdatePosition(position, rotation); var clientUpdatePacketUpdateLocation = new ClientUpdatePacketUpdateLocation { diff --git a/src/Sanctuary.Gateway/Handlers/PacketZoneSafeTeleportRequestHandler.cs b/src/Sanctuary.Gateway/Handlers/PacketZoneSafeTeleportRequestHandler.cs index 48bc43e..ca3274c 100644 --- a/src/Sanctuary.Gateway/Handlers/PacketZoneSafeTeleportRequestHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PacketZoneSafeTeleportRequestHandler.cs @@ -50,8 +50,8 @@ public static bool HandlePacket(GatewayConnection connection, Span data) var position = pointOfInterest.SpawnPosition; var rotation = new Quaternion(rotationZ, 0f, rotationX, 0f); - connection.Player.Mount?.UpdatePosition(position, rotation); connection.Player.UpdatePosition(position, rotation, updateZoneArea: false); + connection.Player.Mount?.UpdatePosition(position, rotation); var clientUpdatePacketUpdateLocation = new ClientUpdatePacketUpdateLocation { diff --git a/src/Sanctuary.Gateway/Handlers/PacketZoneTeleportRequestHandler.cs b/src/Sanctuary.Gateway/Handlers/PacketZoneTeleportRequestHandler.cs index 44d43ce..fd50b8d 100644 --- a/src/Sanctuary.Gateway/Handlers/PacketZoneTeleportRequestHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PacketZoneTeleportRequestHandler.cs @@ -46,8 +46,8 @@ public static bool HandlePacket(GatewayConnection connection, Span data) var position = pointOfInterest.SpawnPosition; var rotation = new Quaternion(rotationZ, 0f, rotationX, 0f); - connection.Player.Mount?.UpdatePosition(position, rotation); connection.Player.UpdatePosition(position, rotation, updateZoneArea: false); + connection.Player.Mount?.UpdatePosition(position, rotation); var clientUpdatePacketUpdateLocation = new ClientUpdatePacketUpdateLocation { From f0c178819a34a5fd309db264c4de8cc255715246 Mon Sep 17 00:00:00 2001 From: Stimpy <95110502+StimpyDev@users.noreply.github.com> Date: Fri, 10 Jul 2026 06:49:58 +0200 Subject: [PATCH 2/2] Address Feedback --- src/Sanctuary.Game/Entities/Mount.cs | 14 ++++++++++++++ src/Sanctuary.Game/Entities/Player.cs | 13 +++---------- .../MountBasePacket/PacketMountSpawnHandler.cs | 13 ++----------- .../PacketClientFinishedLoadingHandler.cs | 18 +++--------------- .../PacketWorldTeleportRequestHandler.cs | 1 - .../PacketZoneSafeTeleportRequestHandler.cs | 1 - .../PacketZoneTeleportRequestHandler.cs | 1 - .../Handlers/PlayerUpdatePacketJumpHandler.cs | 1 - .../PlayerUpdatePacketUpdatePositionHandler.cs | 1 - 9 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/Sanctuary.Game/Entities/Mount.cs b/src/Sanctuary.Game/Entities/Mount.cs index 7f71f99..97f2a9b 100644 --- a/src/Sanctuary.Game/Entities/Mount.cs +++ b/src/Sanctuary.Game/Entities/Mount.cs @@ -56,4 +56,18 @@ public override PlayerUpdatePacketAddNpc GetAddNpcPacket() return packet; } + + public PacketMountResponse GetMountResponsePacket() + { + return new PacketMountResponse + { + RiderGuid = Rider.Guid, + MountGuid = Guid, + Seat = Seat, + QueuePosition = QueuePosition, + Unknown = 1, + CompositeEffectId = 46, // PFX_Teleport_Flash + NameVerticalOffset = Definition.NameVerticalOffset + }; + } } \ No newline at end of file diff --git a/src/Sanctuary.Game/Entities/Player.cs b/src/Sanctuary.Game/Entities/Player.cs index 800dc72..2940192 100644 --- a/src/Sanctuary.Game/Entities/Player.cs +++ b/src/Sanctuary.Game/Entities/Player.cs @@ -133,6 +133,8 @@ public void UpdatePosition(Vector4 position, Quaternion rotation, bool updateZon Position = position; Rotation = rotation; + Mount?.UpdatePosition(position, rotation, updateZoneArea); + if (Visible) { UpdateZoneTile(); @@ -318,16 +320,7 @@ public void OnAddVisiblePlayers(params IEnumerable players) SendTunneled(addPc); SendTunneled(player.Mount.GetAddNpcPacket()); - SendTunneled(new PacketMountResponse - { - RiderGuid = player.Guid, - MountGuid = player.Mount.Guid, - Seat = player.Mount.Seat, - QueuePosition = player.Mount.QueuePosition, - Unknown = 1, - CompositeEffectId = 46, - NameVerticalOffset = player.Mount.Definition.NameVerticalOffset - }); + SendTunneled(player.Mount.GetMountResponsePacket()); } else SendTunneled(player.GetAddPcPacket()); diff --git a/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketMountSpawnHandler.cs b/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketMountSpawnHandler.cs index d6dbc85..258f489 100644 --- a/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketMountSpawnHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/MountBasePacket/PacketMountSpawnHandler.cs @@ -74,22 +74,13 @@ public static void SpawnMount(GatewayConnection connection, PacketMountInfo moun connection.Player.Mount = mount; - mount.UpdatePosition(connection.Player.Position, connection.Player.Rotation); + connection.Player.UpdatePosition(connection.Player.Position, connection.Player.Rotation); foreach (var visiblePlayer in connection.Player.VisiblePlayers) visiblePlayer.Value.OnAddVisiblePlayers([connection.Player]); connection.Player.SendTunneled(mount.GetAddNpcPacket()); - connection.Player.SendTunneled(new PacketMountResponse - { - RiderGuid = connection.Player.Guid, - MountGuid = mount.Guid, - Seat = mount.Seat, - QueuePosition = mount.QueuePosition, - Unknown = 1, - CompositeEffectId = 46, - NameVerticalOffset = mountDefinition.NameVerticalOffset - }); + connection.Player.SendTunneled(mount.GetMountResponsePacket()); var mountStats = mountDefinition.Stats; diff --git a/src/Sanctuary.Gateway/Handlers/PacketClientFinishedLoadingHandler.cs b/src/Sanctuary.Gateway/Handlers/PacketClientFinishedLoadingHandler.cs index 2c7c69e..b187c2e 100644 --- a/src/Sanctuary.Gateway/Handlers/PacketClientFinishedLoadingHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PacketClientFinishedLoadingHandler.cs @@ -28,21 +28,9 @@ public static bool HandlePacket(GatewayConnection connection) if (connection.Player.Mount is not null) { - var mount = connection.Player.Mount; - - mount.Visible = true; - mount.UpdatePosition(connection.Player.Position, connection.Player.Rotation); - - connection.Player.SendTunneled(new PacketMountResponse - { - RiderGuid = connection.Player.Guid, - MountGuid = mount.Guid, - Seat = mount.Seat, - QueuePosition = mount.QueuePosition, - Unknown = 1, - CompositeEffectId = 46, - NameVerticalOffset = mount.Definition.NameVerticalOffset - }); + connection.Player.Mount.Visible = true; + + connection.Player.SendTunneled(connection.Player.Mount.GetMountResponsePacket()); } connection.Player.Zone.OnClientFinishedLoading(connection.Player); diff --git a/src/Sanctuary.Gateway/Handlers/PacketWorldTeleportRequestHandler.cs b/src/Sanctuary.Gateway/Handlers/PacketWorldTeleportRequestHandler.cs index 838f945..c5afb92 100644 --- a/src/Sanctuary.Gateway/Handlers/PacketWorldTeleportRequestHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PacketWorldTeleportRequestHandler.cs @@ -40,7 +40,6 @@ public static bool HandlePacket(GatewayConnection connection, Span data) var rotation = player.Rotation; connection.Player.UpdatePosition(position, rotation, updateZoneArea: false); - connection.Player.Mount?.UpdatePosition(position, rotation); var clientUpdatePacketUpdateLocation = new ClientUpdatePacketUpdateLocation { diff --git a/src/Sanctuary.Gateway/Handlers/PacketZoneSafeTeleportRequestHandler.cs b/src/Sanctuary.Gateway/Handlers/PacketZoneSafeTeleportRequestHandler.cs index ca3274c..c0b41c8 100644 --- a/src/Sanctuary.Gateway/Handlers/PacketZoneSafeTeleportRequestHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PacketZoneSafeTeleportRequestHandler.cs @@ -51,7 +51,6 @@ public static bool HandlePacket(GatewayConnection connection, Span data) var rotation = new Quaternion(rotationZ, 0f, rotationX, 0f); connection.Player.UpdatePosition(position, rotation, updateZoneArea: false); - connection.Player.Mount?.UpdatePosition(position, rotation); var clientUpdatePacketUpdateLocation = new ClientUpdatePacketUpdateLocation { diff --git a/src/Sanctuary.Gateway/Handlers/PacketZoneTeleportRequestHandler.cs b/src/Sanctuary.Gateway/Handlers/PacketZoneTeleportRequestHandler.cs index fd50b8d..b92c8da 100644 --- a/src/Sanctuary.Gateway/Handlers/PacketZoneTeleportRequestHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PacketZoneTeleportRequestHandler.cs @@ -47,7 +47,6 @@ public static bool HandlePacket(GatewayConnection connection, Span data) var rotation = new Quaternion(rotationZ, 0f, rotationX, 0f); connection.Player.UpdatePosition(position, rotation, updateZoneArea: false); - connection.Player.Mount?.UpdatePosition(position, rotation); var clientUpdatePacketUpdateLocation = new ClientUpdatePacketUpdateLocation { diff --git a/src/Sanctuary.Gateway/Handlers/PlayerUpdatePacketJumpHandler.cs b/src/Sanctuary.Gateway/Handlers/PlayerUpdatePacketJumpHandler.cs index aa21488..edb548e 100644 --- a/src/Sanctuary.Gateway/Handlers/PlayerUpdatePacketJumpHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PlayerUpdatePacketJumpHandler.cs @@ -29,7 +29,6 @@ public static bool HandlePacket(GatewayConnection connection, Span data) // _logger.LogTrace("Received {name} packet. ( {packet} )", nameof(PlayerUpdatePacketJump), packet); - connection.Player.Mount?.UpdatePosition(packet.Position, packet.Rotation); connection.Player.UpdatePosition(packet.Position, packet.Rotation); connection.Player.SendTunneledToVisible(packet); diff --git a/src/Sanctuary.Gateway/Handlers/PlayerUpdatePacketUpdatePositionHandler.cs b/src/Sanctuary.Gateway/Handlers/PlayerUpdatePacketUpdatePositionHandler.cs index 66a74e5..5bdb9cd 100644 --- a/src/Sanctuary.Gateway/Handlers/PlayerUpdatePacketUpdatePositionHandler.cs +++ b/src/Sanctuary.Gateway/Handlers/PlayerUpdatePacketUpdatePositionHandler.cs @@ -29,7 +29,6 @@ public static bool HandlePacket(GatewayConnection connection, Span data) // _logger.LogTrace("Received {name} packet. ( {packet} )", nameof(PlayerUpdatePacketUpdatePosition), packet); - connection.Player.Mount?.UpdatePosition(packet.Position, packet.Rotation); connection.Player.UpdatePosition(packet.Position, packet.Rotation); connection.Player.SendTunneledToVisible(packet);