Enable/Disable TerrainAndMovements while logged in

Feature requested in #705
This commit is contained in:
ORelio 2019-04-28 21:32:03 +02:00
parent 41b3f98924
commit a6e660c974
8 changed files with 126 additions and 19 deletions

View file

@ -579,13 +579,33 @@ namespace MinecraftClient
Handler.BotLoad(new ChatBots.Script(filename, playername)); Handler.BotLoad(new ChatBots.Script(filename, playername));
} }
/// <summary>
/// Check whether Terrain and Movements is enabled.
/// </summary>
/// <returns>Enable status.</returns>
public bool GetTerrainEnabled()
{
return Handler.GetTerrainEnabled();
}
/// <summary>
/// Enable or disable Terrain and Movements.
/// Please note that Enabling will be deferred until next relog, respawn or world change.
/// </summary>
/// <param name="enabled">Enabled</param>
/// <returns>TRUE if the setting was applied immediately, FALSE if delayed.</returns>
public bool SetTerrainEnabled(bool enabled)
{
return Handler.SetTerrainEnabled(enabled);
}
/// <summary> /// <summary>
/// Get the current Minecraft World /// Get the current Minecraft World
/// </summary> /// </summary>
/// <returns>Minecraft world or null if associated setting is disabled</returns> /// <returns>Minecraft world or null if associated setting is disabled</returns>
protected Mapping.World GetWorld() protected Mapping.World GetWorld()
{ {
if (Settings.TerrainAndMovements) if (GetTerrainEnabled())
return Handler.GetWorld(); return Handler.GetWorld();
return null; return null;
} }

View file

@ -13,7 +13,7 @@ namespace MinecraftClient.Commands
public override string Run(McTcpClient handler, string command) public override string Run(McTcpClient handler, string command)
{ {
if (Settings.TerrainAndMovements) if (handler.GetTerrainEnabled())
{ {
string[] args = getArgs(command); string[] args = getArgs(command);
if (args.Length == 1) if (args.Length == 1)

View file

@ -9,18 +9,29 @@ namespace MinecraftClient.Commands
public class Move : Command public class Move : Command
{ {
public override string CMDName { get { return "move"; } } public override string CMDName { get { return "move"; } }
public override string CMDDesc { get { return "move <get|up|down|east|west|north|south|x y z>: walk or start walking."; } } public override string CMDDesc { get { return "move <on|off|get|up|down|east|west|north|south|x y z>: walk or start walking."; } }
public override string Run(McTcpClient handler, string command) public override string Run(McTcpClient handler, string command)
{
if (Settings.TerrainAndMovements)
{ {
string[] args = getArgs(command); 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())
{
if (args.Length == 1) if (args.Length == 1)
{ {
string dirStr = getArg(command).Trim().ToLower();
Direction direction; Direction direction;
switch (dirStr) switch (argStr)
{ {
case "up": direction = Direction.Up; break; case "up": direction = Direction.Up; break;
case "down": direction = Direction.Down; break; case "down": direction = Direction.Down; break;
@ -29,12 +40,12 @@ namespace MinecraftClient.Commands
case "north": direction = Direction.North; break; case "north": direction = Direction.North; break;
case "south": direction = Direction.South; break; case "south": direction = Direction.South; break;
case "get": return handler.GetCurrentLocation().ToString(); case "get": return handler.GetCurrentLocation().ToString();
default: return "Unknown direction '" + dirStr + "'."; default: return "Unknown direction '" + argStr + "'.";
} }
if (Movement.CanMove(handler.GetWorld(), handler.GetCurrentLocation(), direction)) if (Movement.CanMove(handler.GetWorld(), handler.GetCurrentLocation(), direction))
{ {
handler.MoveTo(Movement.Move(handler.GetCurrentLocation(), direction)); handler.MoveTo(Movement.Move(handler.GetCurrentLocation(), direction));
return "Moving " + dirStr + '.'; return "Moving " + argStr + '.';
} }
else return "Cannot move in that direction."; else return "Cannot move in that direction.";
} }

View file

@ -99,5 +99,13 @@ namespace MinecraftClient.Mapping
chunk[location.ChunkBlockX, location.ChunkBlockY, location.ChunkBlockZ] = block; chunk[location.ChunkBlockX, location.ChunkBlockY, location.ChunkBlockZ] = block;
} }
} }
/// <summary>
/// Clear all terrain data from the world
/// </summary>
public void Clear()
{
chunks = new Dictionary<int, Dictionary<int, ChunkColumn>>();
}
} }
} }

View file

@ -30,6 +30,8 @@ namespace MinecraftClient
private readonly Dictionary<string, List<ChatBot>> registeredBotPluginChannels = new Dictionary<string, List<ChatBot>>(); private readonly Dictionary<string, List<ChatBot>> registeredBotPluginChannels = new Dictionary<string, List<ChatBot>>();
private readonly List<string> registeredServerPluginChannels = new List<String>(); private readonly List<string> registeredServerPluginChannels = new List<String>();
private bool terrainAndMovementsEnabled;
private bool terrainAndMovementsRequested = false;
private object locationLock = new object(); private object locationLock = new object();
private bool locationReceived = false; private bool locationReceived = false;
private World world = new World(); private World world = new World();
@ -100,6 +102,8 @@ namespace MinecraftClient
/// <param name="command">The text or command to send. Will only be sent if singlecommand is set to true.</param> /// <param name="command">The text or command to send. Will only be sent if singlecommand is set to true.</param>
private void StartClient(string user, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, ForgeInfo forgeInfo, bool singlecommand, string command) 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; bool retry = false;
this.sessionid = sessionID; this.sessionid = sessionID;
this.uuid = uuid; this.uuid = uuid;
@ -387,6 +391,58 @@ namespace MinecraftClient
bot.AfterGameJoined(); bot.AfterGameJoined();
} }
/// <summary>
/// Called when the player respawns, which happens on login, respawn and world change.
/// </summary>
public void OnRespawn()
{
if (terrainAndMovementsRequested)
{
terrainAndMovementsEnabled = true;
terrainAndMovementsRequested = false;
ConsoleIO.WriteLogLine("Terrain and Movements is now enabled.");
}
if (terrainAndMovementsEnabled)
{
world.Clear();
}
}
/// <summary>
/// Get Terrain and Movements status.
/// </summary>
public bool GetTerrainEnabled()
{
return terrainAndMovementsEnabled;
}
/// <summary>
/// Enable or disable Terrain and Movements.
/// Please note that Enabling will be deferred until next relog, respawn or world change.
/// </summary>
/// <param name="enabled">Enabled</param>
/// <returns>TRUE if the setting was applied immediately, FALSE if delayed.</returns>
public bool SetTerrainEnabled(bool enabled)
{
if (enabled)
{
if (!terrainAndMovementsEnabled)
{
terrainAndMovementsRequested = true;
return false;
}
}
else
{
terrainAndMovementsEnabled = false;
terrainAndMovementsRequested = false;
locationReceived = false;
world.Clear();
}
return true;
}
/// <summary> /// <summary>
/// Called when the server sends a new player location, /// Called when the server sends a new player location,
/// or if a ChatBot whishes to update the player's location. /// or if a ChatBot whishes to update the player's location.
@ -538,6 +594,8 @@ namespace MinecraftClient
/// </summary> /// </summary>
public void OnConnectionLost(ChatBot.DisconnectReason reason, string message) public void OnConnectionLost(ChatBot.DisconnectReason reason, string message)
{ {
world.Clear();
bool will_restart = false; bool will_restart = false;
switch (reason) switch (reason)
@ -587,7 +645,7 @@ namespace MinecraftClient
} }
} }
if (Settings.TerrainAndMovements && locationReceived) if (terrainAndMovementsEnabled && locationReceived)
{ {
lock (locationLock) lock (locationLock)
{ {

View file

@ -35,10 +35,12 @@ namespace MinecraftClient.Protocol.Handlers
this.protocolversion = ProtocolVersion; this.protocolversion = ProtocolVersion;
this.handler = Handler; this.handler = Handler;
if (Settings.TerrainAndMovements) if (Handler.GetTerrainEnabled())
{ {
ConsoleIO.WriteLineFormatted("§8Terrain & Movements currently not handled for that MC version."); 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);
} }
} }

View file

@ -460,9 +460,10 @@ namespace MinecraftClient.Protocol.Handlers
readNextByte(packetData); readNextByte(packetData);
readNextByte(packetData); readNextByte(packetData);
readNextString(packetData); readNextString(packetData);
handler.OnRespawn();
break; break;
case PacketIncomingType.PlayerPositionAndLook: case PacketIncomingType.PlayerPositionAndLook:
if (Settings.TerrainAndMovements) if (handler.GetTerrainEnabled())
{ {
double x = readNextDouble(packetData); double x = readNextDouble(packetData);
double y = readNextDouble(packetData); double y = readNextDouble(packetData);
@ -490,7 +491,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
break; break;
case PacketIncomingType.ChunkData: case PacketIncomingType.ChunkData:
if (Settings.TerrainAndMovements) if (handler.GetTerrainEnabled())
{ {
int chunkX = readNextInt(packetData); int chunkX = readNextInt(packetData);
int chunkZ = readNextInt(packetData); int chunkZ = readNextInt(packetData);
@ -514,7 +515,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
break; break;
case PacketIncomingType.MultiBlockChange: case PacketIncomingType.MultiBlockChange:
if (Settings.TerrainAndMovements) if (handler.GetTerrainEnabled())
{ {
int chunkX = readNextInt(packetData); int chunkX = readNextInt(packetData);
int chunkZ = readNextInt(packetData); int chunkZ = readNextInt(packetData);
@ -549,7 +550,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
break; break;
case PacketIncomingType.BlockChange: case PacketIncomingType.BlockChange:
if (Settings.TerrainAndMovements) if (handler.GetTerrainEnabled())
{ {
if (protocolversion < MC18Version) if (protocolversion < MC18Version)
{ {
@ -564,7 +565,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
break; break;
case PacketIncomingType.MapChunkBulk: case PacketIncomingType.MapChunkBulk:
if (protocolversion < MC19Version && Settings.TerrainAndMovements) if (protocolversion < MC19Version && handler.GetTerrainEnabled())
{ {
int chunkCount; int chunkCount;
bool hasSkyLight; bool hasSkyLight;
@ -607,7 +608,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
break; break;
case PacketIncomingType.UnloadChunk: case PacketIncomingType.UnloadChunk:
if (protocolversion >= MC19Version && Settings.TerrainAndMovements) if (protocolversion >= MC19Version && handler.GetTerrainEnabled())
{ {
int chunkX = readNextInt(packetData); int chunkX = readNextInt(packetData);
int chunkZ = readNextInt(packetData); int chunkZ = readNextInt(packetData);
@ -1818,7 +1819,7 @@ namespace MinecraftClient.Protocol.Handlers
/// <returns>True if the location update was successfully sent</returns> /// <returns>True if the location update was successfully sent</returns>
public bool SendLocationUpdate(Location location, bool onGround, float? yaw = null, float? pitch = null) public bool SendLocationUpdate(Location location, bool onGround, float? yaw = null, float? pitch = null)
{ {
if (Settings.TerrainAndMovements) if (handler.GetTerrainEnabled())
{ {
byte[] yawpitch = new byte[0]; byte[] yawpitch = new byte[0];
PacketOutgoingType packetType = PacketOutgoingType.PlayerPosition; PacketOutgoingType packetType = PacketOutgoingType.PlayerPosition;

View file

@ -26,6 +26,8 @@ namespace MinecraftClient.Protocol
Dictionary<string, string> GetOnlinePlayersWithUUID(); Dictionary<string, string> GetOnlinePlayersWithUUID();
Location GetCurrentLocation(); Location GetCurrentLocation();
World GetWorld(); World GetWorld();
bool GetTerrainEnabled();
bool SetTerrainEnabled(bool enabled);
/// <summary> /// <summary>
/// Called when a server was successfully joined /// Called when a server was successfully joined
@ -39,6 +41,11 @@ namespace MinecraftClient.Protocol
/// <param name="isJson">TRUE if the text is JSON-Encoded</param> /// <param name="isJson">TRUE if the text is JSON-Encoded</param>
void OnTextReceived(string text, bool isJson); void OnTextReceived(string text, bool isJson);
/// <summary>
/// Called when the player respawns, which happens on login, respawn and world change.
/// </summary>
void OnRespawn();
/// <summary> /// <summary>
/// This method is called when a new player joins the game /// This method is called when a new player joins the game
/// </summary> /// </summary>