From 5ea3e77b56b4062d84b4935a39b0725e7e3f4d21 Mon Sep 17 00:00:00 2001 From: Goodlyay Date: Thu, 15 Feb 2024 23:32:19 -0800 Subject: [PATCH] WIP on ignoring unwanted positions after TPing, spawning a player --- MCGalaxy/Network/ClassicProtocol.cs | 23 ++++++++++++++++++++++- MCGalaxy/Network/Utils/PingList.cs | 13 +++++++++++-- MCGalaxy/Player/Player.Fields.cs | 10 ++++++++++ MCGalaxy/Player/Player.Handlers.cs | 1 + 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/MCGalaxy/Network/ClassicProtocol.cs b/MCGalaxy/Network/ClassicProtocol.cs index bfede8db5..8174eff1f 100644 --- a/MCGalaxy/Network/ClassicProtocol.cs +++ b/MCGalaxy/Network/ClassicProtocol.cs @@ -259,10 +259,16 @@ namespace MCGalaxy.Network bool serverToClient = buffer[offset + 1] != 0; ushort data = NetUtils.ReadU16(buffer, offset + 2); + //player.Message("&bServerToClient? {0}, data {1}", serverToClient, data); + if (!serverToClient) { // Client-> server ping, immediately send reply. Send(Packet.TwoWayPing(false, data)); } else { + if (Ping.UnIgnorePosition(data)) { + player.IgnorePosition = false; + player.Message("Your position is no longer being ignored, received {0}", data); + } // Server -> client ping, set time received for reply. Ping.Update(data); } @@ -358,6 +364,7 @@ namespace MCGalaxy.Network if (id == Entities.SelfID) pos.Y -= 22; Send(Packet.Teleport(id, pos, rot, player.hasExtPositions)); + DoIgnorePositionPing(id); } public override bool SendTeleport(byte id, Position pos, Orientation rot, Packet.TeleportMoveMode moveMode, bool usePos = true, bool interpolateOri = false, bool useOri = true) { @@ -368,8 +375,16 @@ namespace MCGalaxy.Network { pos.Y -= 22; } Send(Packet.TeleportExt(id, usePos, moveMode, useOri, interpolateOri, pos, rot, player.hasExtPositions)); + DoIgnorePositionPing(id); return true; } + void DoIgnorePositionPing(byte id) { + if (!hasTwoWayPing || id != Entities.SelfID) { return; } + ushort data = Ping.NextTwoWayPingData(true); + SendTwoWayPing(data); + player.IgnorePosition = true; + player.Message("Now ignoring your position until {0}", data); + } public override void SendRemoveEntity(byte id) { Send(Packet.RemoveEntity(id)); @@ -521,11 +536,15 @@ namespace MCGalaxy.Network public override void SendPing() { if (hasTwoWayPing) { - Send(Packet.TwoWayPing(true, Ping.NextTwoWayPingData())); + SendTwoWayPing(Ping.NextTwoWayPingData()); } else { Send(Packet.Ping()); } } + void SendTwoWayPing(BlockID data) { + if (!hasTwoWayPing) { return; } + Send(Packet.TwoWayPing(true, data)); + } public override void SendSetSpawnpoint(Position pos, Orientation rot) { if (Supports(CpeExt.SetSpawnpoint)) { @@ -559,6 +578,8 @@ namespace MCGalaxy.Network } else { Send(Packet.AddEntity(id, name, pos, rot, player.hasCP437, player.hasExtPositions)); } + + DoIgnorePositionPing(id); } public override void SendLevel(Level prev, Level level) { diff --git a/MCGalaxy/Network/Utils/PingList.cs b/MCGalaxy/Network/Utils/PingList.cs index 95d94633c..19241951e 100644 --- a/MCGalaxy/Network/Utils/PingList.cs +++ b/MCGalaxy/Network/Utils/PingList.cs @@ -35,9 +35,17 @@ namespace MCGalaxy.Network // Pings are stored using a circular array public PingEntry[] Entries = new PingEntry[10]; int pingCounter, nextPingHead; + + long ignorePositionData = -1; + public bool UnIgnorePosition(ushort data) { + if (Interlocked.Read(ref ignorePositionData) == data) { + Interlocked.Exchange(ref ignorePositionData, -1); + return true; + } + return false; + } - - public ushort NextTwoWayPingData() { + public ushort NextTwoWayPingData(bool waitingForMovementAcknowledged = false) { int pingValue = Interlocked.Increment(ref pingCounter); int pingHead = (Interlocked.Increment(ref nextPingHead) - 1) % 10; @@ -45,6 +53,7 @@ namespace MCGalaxy.Network Entries[pingHead].TimeRecv = default(DateTime); Entries[pingHead].TimeSent = DateTime.UtcNow; + if (waitingForMovementAcknowledged) Interlocked.Exchange(ref ignorePositionData, pingValue); return (ushort)pingValue; } diff --git a/MCGalaxy/Player/Player.Fields.cs b/MCGalaxy/Player/Player.Fields.cs index 5856b8cba..594271ee8 100644 --- a/MCGalaxy/Player/Player.Fields.cs +++ b/MCGalaxy/Player/Player.Fields.cs @@ -15,6 +15,7 @@ permissions and limitations under the Licenses. using System; using System.Collections.Generic; using System.Net; +using System.Threading; using MCGalaxy.Drawing; using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Transforms; @@ -109,6 +110,15 @@ namespace MCGalaxy { public bool onTrain, trainInvincible; int mbRecursion; + private long _ignorePosition = 0; + internal bool IgnorePosition { + get { return Interlocked.Read(ref _ignorePosition) > 0; } + set { + if (value) Interlocked.Exchange(ref _ignorePosition, 1); + else Interlocked.Exchange(ref _ignorePosition, 0); + } + } + public bool frozen; public string following = ""; public string possess = ""; diff --git a/MCGalaxy/Player/Player.Handlers.cs b/MCGalaxy/Player/Player.Handlers.cs index 3c2818681..fb3c0dc83 100644 --- a/MCGalaxy/Player/Player.Handlers.cs +++ b/MCGalaxy/Player/Player.Handlers.cs @@ -224,6 +224,7 @@ namespace MCGalaxy public void ProcessMovement(int x, int y, int z, byte yaw, byte pitch, int held) { if (held >= 0) ClientHeldBlock = (BlockID)held; + if (IgnorePosition) { return; } if (trainGrab || following.Length > 0) { CheckBlocks(Pos, Pos); return; } Position next = new Position(x, y, z); CheckBlocks(Pos, next);