diff --git a/MinecraftClient/ChatBot.cs b/MinecraftClient/ChatBot.cs
index b00e64ec..0fafcb6b 100644
--- a/MinecraftClient/ChatBot.cs
+++ b/MinecraftClient/ChatBot.cs
@@ -745,14 +745,12 @@ namespace MinecraftClient
}
///
- /// Dig block
+ /// Attempt to dig a block at the specified location
///
- /// 0 to start digging, 1 to cancel, 2 to finish ( https://wiki.vg/Protocol#Player_Digging )
/// Location
- /// Block face
- protected void DigBlock(int status, Location location, Direction blockFace)
+ protected bool DigBlock(Location location)
{
- Handler.DigBlock(status, location, blockFace);
+ return Handler.DigBlock(location);
}
///
@@ -977,9 +975,9 @@ namespace MinecraftClient
/// Item type
/// Item count
/// TRUE if item given successfully
- protected bool CreativeGive(int slot, ItemType itemType, int count, Dictionary NBT = null)
+ protected bool CreativeGive(int slot, ItemType itemType, int count, Dictionary nbt = null)
{
- return Handler.DoCreativeGive(slot, itemType, count, NBT);
+ return Handler.DoCreativeGive(slot, itemType, count, nbt);
}
///
diff --git a/MinecraftClient/Commands/ChangeSlot.cs b/MinecraftClient/Commands/ChangeSlot.cs
index e012bbd7..a9f0061e 100644
--- a/MinecraftClient/Commands/ChangeSlot.cs
+++ b/MinecraftClient/Commands/ChangeSlot.cs
@@ -12,7 +12,9 @@ namespace MinecraftClient.Commands
public override string Run(McClient handler, string command, Dictionary localVars)
{
- if (!handler.GetInventoryEnabled()) return "Please enable InventoryHandling in the config file first.";
+ if (!handler.GetTerrainEnabled())
+ return "Please enable InventoryHandling in the config file first.";
+
if (hasArg(command))
{
short slot;
diff --git a/MinecraftClient/Commands/Dig.cs b/MinecraftClient/Commands/Dig.cs
new file mode 100644
index 00000000..d3dfc7f4
--- /dev/null
+++ b/MinecraftClient/Commands/Dig.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MinecraftClient.Mapping;
+
+namespace MinecraftClient.Commands
+{
+ public class Dig : Command
+ {
+ public override string CMDName { get { return "dig"; } }
+ public override string CMDDesc { get { return "dig : attempt to break a block"; } }
+
+ public override string Run(McClient handler, string command, Dictionary localVars)
+ {
+ if (!handler.GetTerrainEnabled())
+ return "Please enable Terrain and Movements to use this command.";
+
+ if (hasArg(command))
+ {
+ string[] args = getArgs(command);
+ if (args.Length == 3)
+ {
+ try
+ {
+ int x = int.Parse(args[0]);
+ int y = int.Parse(args[1]);
+ int z = int.Parse(args[2]);
+ Location blockToBreak = new Location(x, y, z);
+ if (blockToBreak.DistanceSquared(handler.GetCurrentLocation()) >= 16)
+ return "You are too far away from this block.";
+ if (handler.GetWorld().GetBlock(blockToBreak).Type == Material.Air)
+ return "No block at this location (Air)";
+ if (handler.DigBlock(blockToBreak))
+ return String.Format("Attempting to dig block at {0} {1} {2}", x, y, z);
+ else return "Failed to start digging block.";
+ }
+ catch (FormatException) { return CMDDesc; }
+ }
+ else return CMDDesc;
+ }
+ else return CMDDesc;
+ }
+ }
+}
diff --git a/MinecraftClient/Inventory/Item.cs b/MinecraftClient/Inventory/Item.cs
index 0aefaadb..29198e88 100644
--- a/MinecraftClient/Inventory/Item.cs
+++ b/MinecraftClient/Inventory/Item.cs
@@ -30,7 +30,7 @@ namespace MinecraftClient.Inventory
///
/// Item Type ID
/// Item Count
- /// Item Metadata
+ /// Item Metadata
public Item(int id, int count, Dictionary nbt)
{
this.Type = (ItemType)id;
diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs
index bee01020..7ca3c7d6 100644
--- a/MinecraftClient/McClient.cs
+++ b/MinecraftClient/McClient.cs
@@ -953,11 +953,11 @@ namespace MinecraftClient
/// Destination inventory slot
/// Item type
/// Item count
- /// Item NBT
+ /// Item NBT
/// TRUE if item given successfully
- public bool DoCreativeGive(int slot, ItemType itemType, int count, Dictionary NBT = null)
+ public bool DoCreativeGive(int slot, ItemType itemType, int count, Dictionary nbt = null)
{
- return handler.SendCreativeInventoryAction(slot, itemType, count, NBT);
+ return handler.SendCreativeInventoryAction(slot, itemType, count, nbt);
}
///
@@ -1023,14 +1023,25 @@ namespace MinecraftClient
}
///
- /// Dig block. This method needs to be called at least twice: Once to begin digging, then a second time to finish digging
+ /// Attempt to dig a block at the specified location
///
- /// 0 to start digging, 1 to cancel, 2 to finish ( https://wiki.vg/Protocol#Player_Digging )
/// Location of block to dig
- /// Block face (e.g. Direction.Up when digging from above)
- public bool DigBlock(int status, Location location, Direction blockFace)
+ public bool DigBlock(Location location)
{
- return handler.SendPlayerDigging(status, location, blockFace);
+ if (GetTerrainEnabled())
+ {
+ // TODO select best face from current player location
+ Direction blockFace = Direction.Down;
+
+ // Look at block before attempting to break it
+ UpdateLocation(GetCurrentLocation(), location);
+
+ // Send dig start and dig end, will need to wait for server response to know dig result
+ // See https://wiki.vg/How_to_Write_a_Client#Digging for more details
+ return handler.SendPlayerDigging(0, location, blockFace)
+ && handler.SendPlayerDigging(2, location, blockFace);
+ }
+ else return false;
}
///
@@ -1045,25 +1056,21 @@ namespace MinecraftClient
CurrentSlot = Convert.ToByte(slot);
return handler.SendHeldItemChange(slot);
}
- else
- {
- return false;
- }
+ else return false;
}
///
/// Update sign text
///
- /// sign location
- /// text one
- /// text two
- /// text three
- /// text1 four
+ /// sign location
+ /// text one
+ /// text two
+ /// text three
+ /// text1 four
public bool UpdateSign(Location location, string line1, string line2, string line3, string line4)
{
- if (line1.Length <= 23 & line2.Length <= 23 & line3.Length <= 23 & line4.Length <= 23)
- return handler.SendUpdateSign(location, line1, line2, line3, line4);
- else { return false; }
+ // TODO Open sign editor first https://wiki.vg/Protocol#Open_Sign_Editor
+ return handler.SendUpdateSign(location, line1, line2, line3, line4);
}
#endregion
diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj
index 7d0ef066..9d89fbef 100644
--- a/MinecraftClient/MinecraftClient.csproj
+++ b/MinecraftClient/MinecraftClient.csproj
@@ -93,6 +93,7 @@
+
diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs
index b2ef0c6c..f46537c6 100644
--- a/MinecraftClient/Program.cs
+++ b/MinecraftClient/Program.cs
@@ -27,7 +27,7 @@ namespace MinecraftClient
///
static class Program
{
- private static McClient Client;
+ private static McClient client;
public static string[] startupargs;
public const string Version = MCHighestVersion;
@@ -264,9 +264,9 @@ namespace MinecraftClient
//Start the main TCP client
if (Settings.SingleCommand != "")
{
- Client = new McClient(session.PlayerName, session.PlayerID, session.ID, Settings.ServerIP, Settings.ServerPort, protocolversion, forgeInfo, Settings.SingleCommand);
+ client = new McClient(session.PlayerName, session.PlayerID, session.ID, Settings.ServerIP, Settings.ServerPort, protocolversion, forgeInfo, Settings.SingleCommand);
}
- else Client = new McClient(session.PlayerName, session.PlayerID, session.ID, protocolversion, forgeInfo, Settings.ServerIP, Settings.ServerPort);
+ else client = new McClient(session.PlayerName, session.PlayerID, session.ID, protocolversion, forgeInfo, Settings.ServerIP, Settings.ServerPort);
//Update console title
if (Settings.ConsoleTitle != "")
@@ -309,7 +309,7 @@ namespace MinecraftClient
{
new Thread(new ThreadStart(delegate
{
- if (Client != null) { Client.Disconnect(); ConsoleIO.Reset(); }
+ if (client != null) { client.Disconnect(); ConsoleIO.Reset(); }
if (offlinePrompt != null) { offlinePrompt.Abort(); offlinePrompt = null; ConsoleIO.Reset(); }
if (delaySeconds > 0)
{
@@ -328,7 +328,7 @@ namespace MinecraftClient
{
new Thread(new ThreadStart(delegate
{
- if (Client != null) { Client.Disconnect(); ConsoleIO.Reset(); }
+ if (client != null) { client.Disconnect(); ConsoleIO.Reset(); }
if (offlinePrompt != null) { offlinePrompt.Abort(); offlinePrompt = null; ConsoleIO.Reset(); }
if (Settings.playerHeadAsIcon) { ConsoleIcon.revertToMCCIcon(); }
Environment.Exit(0);
diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs
index a33c5545..5a077073 100644
--- a/MinecraftClient/Protocol/Handlers/DataTypes.cs
+++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs
@@ -336,8 +336,8 @@ namespace MinecraftClient.Protocol.Handlers
{
int itemID = ReadNextVarInt(cache);
byte itemCount = ReadNextByte(cache);
- Dictionary NBT = ReadNextNbt(cache);
- return new Item(itemID, itemCount, NBT);
+ Dictionary nbt = ReadNextNbt(cache);
+ return new Item(itemID, itemCount, nbt);
}
else return null;
}
@@ -349,8 +349,8 @@ namespace MinecraftClient.Protocol.Handlers
return null;
byte itemCount = ReadNextByte(cache);
short itemDamage = ReadNextShort(cache);
- Dictionary NBT = ReadNextNbt(cache);
- return new Item(itemID, itemCount, NBT);
+ Dictionary nbt = ReadNextNbt(cache);
+ return new Item(itemID, itemCount, nbt);
}
}
@@ -398,14 +398,14 @@ namespace MinecraftClient.Protocol.Handlers
///
private Dictionary ReadNextNbt(Queue cache, bool root)
{
- Dictionary NbtData = new Dictionary();
+ Dictionary nbtData = new Dictionary();
if (root)
{
if (cache.Peek() == 0) // TAG_End
{
cache.Dequeue();
- return NbtData;
+ return nbtData;
}
if (cache.Peek() != 10) // TAG_Compound
throw new System.IO.InvalidDataException("Failed to decode NBT: Does not start with TAG_Compound");
@@ -414,7 +414,7 @@ namespace MinecraftClient.Protocol.Handlers
// NBT root name
string rootName = Encoding.ASCII.GetString(ReadData(ReadNextUShort(cache), cache));
if (!String.IsNullOrEmpty(rootName))
- NbtData[""] = rootName;
+ nbtData[""] = rootName;
}
while (true)
@@ -422,14 +422,14 @@ namespace MinecraftClient.Protocol.Handlers
int fieldType = ReadNextByte(cache);
if (fieldType == 0) // TAG_End
- return NbtData;
+ return nbtData;
int fieldNameLength = ReadNextUShort(cache);
string fieldName = Encoding.ASCII.GetString(ReadData(fieldNameLength, cache));
object fieldValue = ReadNbtField(cache, fieldType);
// This will override previous tags with the same name
- NbtData[fieldName] = fieldValue;
+ nbtData[fieldName] = fieldValue;
}
}
diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs
index 9c14ffec..c6fe04d5 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol16.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs
@@ -703,7 +703,7 @@ namespace MinecraftClient.Protocol.Handlers
return false; //Currently not implemented
}
- public bool SendCreativeInventoryAction(int slot, ItemType item, int count, Dictionary NBT)
+ public bool SendCreativeInventoryAction(int slot, ItemType item, int count, Dictionary nbt)
{
return false; //Currently not implemented
}
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs
index 7e35711a..9e0dafb3 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs
@@ -1500,13 +1500,13 @@ namespace MinecraftClient.Protocol.Handlers
catch (ObjectDisposedException) { return false; }
}
- public bool SendCreativeInventoryAction(int slot, ItemType itemType, int count, Dictionary NBT)
+ public bool SendCreativeInventoryAction(int slot, ItemType itemType, int count, Dictionary nbt)
{
try
{
List packet = new List();
packet.AddRange(dataTypes.GetShort((short)slot));
- packet.AddRange(dataTypes.GetItemSlot(new Item((int)itemType, count, NBT)));
+ packet.AddRange(dataTypes.GetItemSlot(new Item((int)itemType, count, nbt)));
SendPacket(PacketOutgoingType.CreativeInventoryAction, packet);
return true;
}
@@ -1549,6 +1549,7 @@ namespace MinecraftClient.Protocol.Handlers
catch (System.IO.IOException) { return false; }
catch (ObjectDisposedException) { return false; }
}
+
public bool SendCloseWindow(int windowId)
{
try
@@ -1565,10 +1566,20 @@ namespace MinecraftClient.Protocol.Handlers
catch (System.IO.IOException) { return false; }
catch (ObjectDisposedException) { return false; }
}
+
public bool SendUpdateSign(Location sign, string line1, string line2, string line3, string line4)
{
try
{
+ if (line1.Length > 23)
+ line1 = line1.Substring(0, 23);
+ if (line2.Length > 23)
+ line2 = line1.Substring(0, 23);
+ if (line3.Length > 23)
+ line3 = line1.Substring(0, 23);
+ if (line4.Length > 23)
+ line4 = line1.Substring(0, 23);
+
List packet = new List();
packet.AddRange(dataTypes.GetLocation(sign));
packet.AddRange(dataTypes.GetString(line1));
diff --git a/MinecraftClient/Protocol/IMinecraftCom.cs b/MinecraftClient/Protocol/IMinecraftCom.cs
index b190384f..546b0dc5 100644
--- a/MinecraftClient/Protocol/IMinecraftCom.cs
+++ b/MinecraftClient/Protocol/IMinecraftCom.cs
@@ -156,8 +156,9 @@ namespace MinecraftClient.Protocol
/// Destination inventory slot
/// Item type
/// Item count
+ /// Optional item NBT
/// TRUE if item given successfully
- bool SendCreativeInventoryAction(int slot, ItemType itemType, int count, Dictionary NBT);
+ bool SendCreativeInventoryAction(int slot, ItemType itemType, int count, Dictionary nbt);
///
/// Plays animation
@@ -183,7 +184,7 @@ namespace MinecraftClient.Protocol
bool SendPlayerBlockPlacement(int hand, Location location, Direction face);
///
- /// Send player blog digging packet to the server
+ /// Send player blog digging packet to the server. This packet needs to be called at least twice: Once to begin digging, then a second time to finish digging
///
/// 0 to start digging, 1 to cancel, 2 to finish ( https://wiki.vg/Protocol#Player_Digging )
/// Location