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
///