From a6e660c974f4df30665e5fbce67f2efde1e13f3b Mon Sep 17 00:00:00 2001 From: ORelio Date: Sun, 28 Apr 2019 21:32:03 +0200 Subject: [PATCH] Enable/Disable TerrainAndMovements while logged in Feature requested in #705 --- MinecraftClient/ChatBot.cs | 22 ++++++- MinecraftClient/Commands/Look.cs | 2 +- MinecraftClient/Commands/Move.cs | 25 +++++--- MinecraftClient/Mapping/World.cs | 8 +++ MinecraftClient/McTcpClient.cs | 60 ++++++++++++++++++- .../Protocol/Handlers/Protocol16.cs | 6 +- .../Protocol/Handlers/Protocol18.cs | 15 ++--- .../Protocol/IMinecraftComHandler.cs | 7 +++ 8 files changed, 126 insertions(+), 19 deletions(-) diff --git a/MinecraftClient/ChatBot.cs b/MinecraftClient/ChatBot.cs index d7ea7559..051eea01 100644 --- a/MinecraftClient/ChatBot.cs +++ b/MinecraftClient/ChatBot.cs @@ -579,13 +579,33 @@ namespace MinecraftClient Handler.BotLoad(new ChatBots.Script(filename, playername)); } + /// + /// Check whether Terrain and Movements is enabled. + /// + /// Enable status. + public bool GetTerrainEnabled() + { + return Handler.GetTerrainEnabled(); + } + + /// + /// Enable or disable Terrain and Movements. + /// Please note that Enabling will be deferred until next relog, respawn or world change. + /// + /// Enabled + /// TRUE if the setting was applied immediately, FALSE if delayed. + public bool SetTerrainEnabled(bool enabled) + { + return Handler.SetTerrainEnabled(enabled); + } + /// /// Get the current Minecraft World /// /// Minecraft world or null if associated setting is disabled protected Mapping.World GetWorld() { - if (Settings.TerrainAndMovements) + if (GetTerrainEnabled()) return Handler.GetWorld(); return null; } diff --git a/MinecraftClient/Commands/Look.cs b/MinecraftClient/Commands/Look.cs index 7845c77b..04be02f2 100644 --- a/MinecraftClient/Commands/Look.cs +++ b/MinecraftClient/Commands/Look.cs @@ -13,7 +13,7 @@ namespace MinecraftClient.Commands public override string Run(McTcpClient handler, string command) { - if (Settings.TerrainAndMovements) + if (handler.GetTerrainEnabled()) { string[] args = getArgs(command); if (args.Length == 1) diff --git a/MinecraftClient/Commands/Move.cs b/MinecraftClient/Commands/Move.cs index 68a4323c..a9cbcab6 100644 --- a/MinecraftClient/Commands/Move.cs +++ b/MinecraftClient/Commands/Move.cs @@ -9,18 +9,29 @@ namespace MinecraftClient.Commands public class Move : Command { public override string CMDName { get { return "move"; } } - public override string CMDDesc { get { return "move : walk or start walking."; } } + public override string CMDDesc { get { return "move : walk or start walking."; } } public override string Run(McTcpClient handler, string command) { - if (Settings.TerrainAndMovements) + string[] args = getArgs(command); + string argStr = getArg(command).Trim().ToLower(); + + if (argStr == "on") + { + handler.SetTerrainEnabled(true); + return "Enabling Terrain and Movements on next server login, respawn or world change."; + } + else if (argStr == "off") + { + handler.SetTerrainEnabled(false); + return "Disabling Terrain and Movements."; + } + else if (handler.GetTerrainEnabled()) { - string[] args = getArgs(command); if (args.Length == 1) { - string dirStr = getArg(command).Trim().ToLower(); Direction direction; - switch (dirStr) + switch (argStr) { case "up": direction = Direction.Up; break; case "down": direction = Direction.Down; break; @@ -29,12 +40,12 @@ namespace MinecraftClient.Commands case "north": direction = Direction.North; break; case "south": direction = Direction.South; break; case "get": return handler.GetCurrentLocation().ToString(); - default: return "Unknown direction '" + dirStr + "'."; + default: return "Unknown direction '" + argStr + "'."; } if (Movement.CanMove(handler.GetWorld(), handler.GetCurrentLocation(), direction)) { handler.MoveTo(Movement.Move(handler.GetCurrentLocation(), direction)); - return "Moving " + dirStr + '.'; + return "Moving " + argStr + '.'; } else return "Cannot move in that direction."; } diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index 7340cfd9..4f34a512 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -99,5 +99,13 @@ namespace MinecraftClient.Mapping chunk[location.ChunkBlockX, location.ChunkBlockY, location.ChunkBlockZ] = block; } } + + /// + /// Clear all terrain data from the world + /// + public void Clear() + { + chunks = new Dictionary>(); + } } } diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index 755619ab..e2fc4090 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -30,6 +30,8 @@ namespace MinecraftClient private readonly Dictionary> registeredBotPluginChannels = new Dictionary>(); private readonly List registeredServerPluginChannels = new List(); + private bool terrainAndMovementsEnabled; + private bool terrainAndMovementsRequested = false; private object locationLock = new object(); private bool locationReceived = false; private World world = new World(); @@ -100,6 +102,8 @@ namespace MinecraftClient /// The text or command to send. Will only be sent if singlecommand is set to true. private void StartClient(string user, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, ForgeInfo forgeInfo, bool singlecommand, string command) { + terrainAndMovementsEnabled = Settings.TerrainAndMovements; + bool retry = false; this.sessionid = sessionID; this.uuid = uuid; @@ -387,6 +391,58 @@ namespace MinecraftClient bot.AfterGameJoined(); } + /// + /// Called when the player respawns, which happens on login, respawn and world change. + /// + public void OnRespawn() + { + if (terrainAndMovementsRequested) + { + terrainAndMovementsEnabled = true; + terrainAndMovementsRequested = false; + ConsoleIO.WriteLogLine("Terrain and Movements is now enabled."); + } + + if (terrainAndMovementsEnabled) + { + world.Clear(); + } + } + + /// + /// Get Terrain and Movements status. + /// + public bool GetTerrainEnabled() + { + return terrainAndMovementsEnabled; + } + + /// + /// Enable or disable Terrain and Movements. + /// Please note that Enabling will be deferred until next relog, respawn or world change. + /// + /// Enabled + /// TRUE if the setting was applied immediately, FALSE if delayed. + public bool SetTerrainEnabled(bool enabled) + { + if (enabled) + { + if (!terrainAndMovementsEnabled) + { + terrainAndMovementsRequested = true; + return false; + } + } + else + { + terrainAndMovementsEnabled = false; + terrainAndMovementsRequested = false; + locationReceived = false; + world.Clear(); + } + return true; + } + /// /// Called when the server sends a new player location, /// or if a ChatBot whishes to update the player's location. @@ -538,6 +594,8 @@ namespace MinecraftClient /// public void OnConnectionLost(ChatBot.DisconnectReason reason, string message) { + world.Clear(); + bool will_restart = false; switch (reason) @@ -587,7 +645,7 @@ namespace MinecraftClient } } - if (Settings.TerrainAndMovements && locationReceived) + if (terrainAndMovementsEnabled && locationReceived) { lock (locationLock) { diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index 150ba7a3..391fa066 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -35,10 +35,12 @@ namespace MinecraftClient.Protocol.Handlers this.protocolversion = ProtocolVersion; this.handler = Handler; - if (Settings.TerrainAndMovements) + if (Handler.GetTerrainEnabled()) { ConsoleIO.WriteLineFormatted("ยง8Terrain & Movements currently not handled for that MC version."); - Settings.TerrainAndMovements = false; + // Re-enable terrain on next relog on a supported server version + Handler.SetTerrainEnabled(false); + Handler.SetTerrainEnabled(true); } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index cb638063..32306896 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -460,9 +460,10 @@ namespace MinecraftClient.Protocol.Handlers readNextByte(packetData); readNextByte(packetData); readNextString(packetData); + handler.OnRespawn(); break; case PacketIncomingType.PlayerPositionAndLook: - if (Settings.TerrainAndMovements) + if (handler.GetTerrainEnabled()) { double x = readNextDouble(packetData); double y = readNextDouble(packetData); @@ -490,7 +491,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketIncomingType.ChunkData: - if (Settings.TerrainAndMovements) + if (handler.GetTerrainEnabled()) { int chunkX = readNextInt(packetData); int chunkZ = readNextInt(packetData); @@ -514,7 +515,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketIncomingType.MultiBlockChange: - if (Settings.TerrainAndMovements) + if (handler.GetTerrainEnabled()) { int chunkX = readNextInt(packetData); int chunkZ = readNextInt(packetData); @@ -549,7 +550,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketIncomingType.BlockChange: - if (Settings.TerrainAndMovements) + if (handler.GetTerrainEnabled()) { if (protocolversion < MC18Version) { @@ -564,7 +565,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketIncomingType.MapChunkBulk: - if (protocolversion < MC19Version && Settings.TerrainAndMovements) + if (protocolversion < MC19Version && handler.GetTerrainEnabled()) { int chunkCount; bool hasSkyLight; @@ -607,7 +608,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketIncomingType.UnloadChunk: - if (protocolversion >= MC19Version && Settings.TerrainAndMovements) + if (protocolversion >= MC19Version && handler.GetTerrainEnabled()) { int chunkX = readNextInt(packetData); int chunkZ = readNextInt(packetData); @@ -1818,7 +1819,7 @@ namespace MinecraftClient.Protocol.Handlers /// True if the location update was successfully sent public bool SendLocationUpdate(Location location, bool onGround, float? yaw = null, float? pitch = null) { - if (Settings.TerrainAndMovements) + if (handler.GetTerrainEnabled()) { byte[] yawpitch = new byte[0]; PacketOutgoingType packetType = PacketOutgoingType.PlayerPosition; diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index a4949693..0f336ab8 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -26,6 +26,8 @@ namespace MinecraftClient.Protocol Dictionary GetOnlinePlayersWithUUID(); Location GetCurrentLocation(); World GetWorld(); + bool GetTerrainEnabled(); + bool SetTerrainEnabled(bool enabled); /// /// Called when a server was successfully joined @@ -39,6 +41,11 @@ namespace MinecraftClient.Protocol /// TRUE if the text is JSON-Encoded void OnTextReceived(string text, bool isJson); + /// + /// Called when the player respawns, which happens on login, respawn and world change. + /// + void OnRespawn(); + /// /// This method is called when a new player joins the game ///