diff --git a/MinecraftClient/ChatBots/AutoAttack.cs b/MinecraftClient/ChatBots/AutoAttack.cs
index 2f03d26c..19d62538 100644
--- a/MinecraftClient/ChatBots/AutoAttack.cs
+++ b/MinecraftClient/ChatBots/AutoAttack.cs
@@ -6,6 +6,9 @@ using System.Text;
namespace MinecraftClient.ChatBots
{
+ ///
+ /// The AutoAttack bot will automatically attack any hostile mob close to the player
+ ///
class AutoAttack : ChatBot
{
private Dictionary entitiesToAttack = new Dictionary(); // mobs within attack range
@@ -48,7 +51,7 @@ namespace MinecraftClient.ChatBots
public override void OnEntitySpawn(Entity entity)
{
- if (entity.GetMobName() != "")
+ if (entity.IsHostile())
{
entitiesToTrack.Add(entity.ID, entity);
}
@@ -64,10 +67,9 @@ namespace MinecraftClient.ChatBots
{
if (entitiesToTrack.ContainsKey(entity.ID))
{
- Double distance = Entity.CalculateDistance(GetCurrentLocation(), entity.Location);
- if(distance < attackRange)
+ if (GetCurrentLocation().Distance(entity.Location) < attackRange)
{
- if(!entitiesToAttack.ContainsKey(entity.ID))
+ if (!entitiesToAttack.ContainsKey(entity.ID))
entitiesToAttack.Add(entity.ID, entity);
}
}
diff --git a/MinecraftClient/ChatBots/AutoFishing.cs b/MinecraftClient/ChatBots/AutoFishing.cs
index a17bd258..e91d30e2 100644
--- a/MinecraftClient/ChatBots/AutoFishing.cs
+++ b/MinecraftClient/ChatBots/AutoFishing.cs
@@ -8,6 +8,10 @@ using MinecraftClient.Mapping;
namespace MinecraftClient.ChatBots
{
+ ///
+ /// The AutoFishing bot semi-automates fishing.
+ /// The player needs to have a fishing rod in hand, then manually send it using the UseItem command.
+ ///
class AutoFishing : ChatBot
{
private Entity fishingRod;
@@ -32,7 +36,7 @@ namespace MinecraftClient.ChatBots
{
if (entity.TypeID == 102)
{
- if (Entity.CalculateDistance(GetCurrentLocation(), entity.Location) < 2 && !isFishing)
+ if (GetCurrentLocation().Distance(entity.Location) < 2 && !isFishing)
{
ConsoleIO.WriteLine("Threw a fishing rod");
fishingRod = entity;
@@ -41,6 +45,7 @@ namespace MinecraftClient.ChatBots
}
}
}
+
public override void OnEntityDespawn(Entity entity)
{
if(entity.TypeID == 102)
@@ -51,6 +56,7 @@ namespace MinecraftClient.ChatBots
}
}
}
+
public override void OnEntityMove(Entity entity)
{
if (isFishing)
@@ -107,9 +113,14 @@ namespace MinecraftClient.ChatBots
});
}
+ ///
+ /// Check whether the player has a fishing rod in inventory
+ ///
+ /// TRUE if the player has a fishing rod
public bool hasFishingRod()
{
- if (!inventoryEnabled) return false;
+ if (!inventoryEnabled)
+ return false;
int start = 36;
int end = 44;
Inventory.Container container = GetPlayerInventory();
diff --git a/MinecraftClient/Mapping/Entity.cs b/MinecraftClient/Mapping/Entity.cs
index 5439d271..f069d885 100644
--- a/MinecraftClient/Mapping/Entity.cs
+++ b/MinecraftClient/Mapping/Entity.cs
@@ -5,97 +5,117 @@ using System.Text;
namespace MinecraftClient.Mapping
{
+ ///
+ /// Represents an entity evolving into a Minecraft world
+ ///
public class Entity
{
+ ///
+ /// ID of the entity on the Minecraft server
+ ///
public int ID;
- public int TypeID;
+
+ ///
+ /// Entity type determined by Minecraft Console Client
+ ///
public EntityType Type;
- public string Name;
+
+ ///
+ /// Entity type ID (more precise than Type, but may change between Minecraft versions)
+ ///
+ public int TypeID;
+
+ ///
+ /// Entity location in the Minecraft world
+ ///
public Location Location;
+
+ ///
+ /// Create a new entity based on Entity ID and location
+ ///
+ /// Entity ID
+ /// Entity location
public Entity(int ID, Location location)
{
this.ID = ID;
this.Location = location;
}
+
+ ///
+ /// Create a new entity based on Entity ID, Entity Type and location
+ ///
+ /// Entity ID
+ /// Entity Type ID
+ /// Entity location
public Entity(int ID, int TypeID, Location location)
{
this.ID = ID;
this.TypeID = TypeID;
- this.Name = GetMobName(TypeID);
this.Location = location;
}
+
+ ///
+ /// Create a new entity based on Entity ID, Entity Type and location
+ ///
+ /// Entity ID
+ /// Entity Type ID
+ /// Entity Type Enum
+ /// Entity location
public Entity(int ID, int TypeID, EntityType type, Location location)
{
this.ID = ID;
this.TypeID = TypeID;
this.Type = type;
- this.Name = GetMobName(TypeID);
this.Location = location;
}
+
+ ///
+ /// Create a new entity based on Entity ID, Entity Type and location
+ ///
+ /// Entity ID
+ /// Entity Type Enum
+ /// Entity location
public Entity(int ID, EntityType type, Location location)
{
this.ID = ID;
this.Type = type;
this.Location = location;
}
- public Entity(int ID, int TypeID, string Name, Location location)
- {
- this.ID = ID;
- this.TypeID = TypeID;
- this.Name = Name;
- this.Location = location;
- }
-
///
- /// Calculate the distance between two coordinate
+ /// Return TRUE if the Entity is an hostile mob
///
- ///
- ///
- ///
- public static double CalculateDistance(Location l1, Location l2)
+ /// New mobs added in newer Minecraft versions might be absent from the list
+ /// TRUE if hostile
+ public bool IsHostile()
{
- return Math.Sqrt(Math.Pow(l2.X - l1.X, 2) + Math.Pow(l2.Y - l1.Y, 2) + Math.Pow(l2.Z - l1.Z, 2));
- }
- ///
- /// Get the mob name by entity type ID.
- ///
- ///
- ///
- public static string GetMobName(int EntityType)
- {
- // only mobs in this list will be auto attacked
- switch (EntityType)
+ switch (TypeID)
{
- case 5: return "Blaze";
- case 12: return "Creeper";
- case 16: return "Drowned";
- case 23: return "Evoker";
- case 29: return "Ghast";
- case 31: return "Guardian";
- case 33: return "Husk";
- case 41: return "Magma Cube";
- case 57: return "Zombie Pigman";
- case 63: return "Shulker";
- case 65: return "Silverfish";
- case 66: return "Skeleton";
- case 68: return "Slime";
- case 75: return "Stray";
- case 84: return "Vex";
- case 87: return "Vindicator";
- case 88: return "Pillager";
- case 90: return "Witch";
- case 92: return "Wither Skeleton";
- case 95: return "Zombie";
- case 97: return "Zombie Villager";
- case 98: return "Phantom";
- case 99: return "Ravager";
- default: return "";
+ case 5: return true; // Blaze;
+ case 12: return true; // Creeper
+ case 16: return true; // Drowned
+ case 23: return true; // Evoker
+ case 29: return true; // Ghast
+ case 31: return true; // Guardian
+ case 33: return true; // Husk
+ case 41: return true; // Magma Cube
+ case 57: return true; // Zombie Pigman
+ case 63: return true; // Shulker
+ case 65: return true; // Silverfish
+ case 66: return true; // Skeleton
+ case 68: return true; // Slime
+ case 75: return true; // Stray
+ case 84: return true; // Vex
+ case 87: return true; // Vindicator
+ case 88: return true; // Pillager
+ case 90: return true; // Witch
+ case 92: return true; // Wither Skeleton
+ case 95: return true; // Zombie
+ case 97: return true; // Zombie Villager
+ case 98: return true; // Phantom
+ case 99: return true; // Ravager
+ default: return false;
}
}
- public string GetMobName()
- {
- return GetMobName(TypeID);
- }
}
}
diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs
index 05585454..0047e205 100644
--- a/MinecraftClient/McTcpClient.cs
+++ b/MinecraftClient/McTcpClient.cs
@@ -565,6 +565,12 @@ namespace MinecraftClient
return entityHandlingEnabled;
}
+ ///
+ /// Enable or disable Entity handling.
+ /// Please note that Enabling will be deferred until next relog.
+ ///
+ /// Enabled
+ /// TRUE if the setting was applied immediately, FALSE if delayed.
public bool SetEntityHandlingEnabled(bool enabled)
{
if (!enabled)
@@ -594,7 +600,6 @@ namespace MinecraftClient
{
return playerInventory;
}
- // TODO: add command for displaying player inventory
///
/// Called when the server sends a new player location,
@@ -791,8 +796,8 @@ namespace MinecraftClient
///
/// When received window items from server.
///
- ///
- ///
+ /// Inventory type
+ /// Item list
public void OnWindowItems(int type, Dictionary itemList)
{
// 0 is player inventory
@@ -800,15 +805,28 @@ namespace MinecraftClient
playerInventory.Items = itemList;
}
- public void OnSetSlot(byte WindowID, short SlotID, bool Present)
+ ///
+ /// When a slot is cleared inside window items
+ ///
+ /// Window ID
+ /// Slot ID
+ public void OnSlotClear(byte WindowID, short SlotID)
{
- if(WindowID == 0)
+ if (WindowID == 0 && playerInventory.Items.ContainsKey(SlotID))
{
- if (playerInventory.Items.ContainsKey(SlotID))
- playerInventory.Items.Remove(SlotID);
+ playerInventory.Items.Remove(SlotID);
}
}
- public void OnSetSlot(byte WindowID, short SlotID, bool Present, int ItemID, byte Count, Dictionary NBT)
+
+ ///
+ /// When a slot is set inside window items
+ ///
+ /// Window ID
+ /// Slot ID
+ /// Item ID
+ /// Item Count
+ /// Item Metadata
+ public void OnSetSlot(byte WindowID, short SlotID, int ItemID, byte Count, Dictionary NBT)
{
if (WindowID == 0)
{
@@ -912,8 +930,6 @@ namespace MinecraftClient
pitch = null;
}
}
-
-
}
///
@@ -1275,12 +1291,16 @@ namespace MinecraftClient
///
/// Set client player's ID for later receiving player's own properties
///
- ///
+ /// Player Entity ID
public void SetPlayerEntityID(int EntityID)
{
playerEntityID = EntityID;
}
+ ///
+ /// Use the item currently in the player's hand
+ ///
+ /// TRUE if the item was successfully used
public bool UseItemOnHand()
{
return handler.SendUseItemPacket(0);
@@ -1296,13 +1316,24 @@ namespace MinecraftClient
{
return handler.SendInteractEntityPacket(EntityID, type);
}
- // not work :(
+
+ ///
+ /// Place the block at hand in the Minecraft world
+ ///
+ /// Location to place block to
+ /// TRUE if successfully placed
public bool PlaceBlock(Location location)
{
+ //WORK IN PROGRESS. MAY NOT WORK YET
ConsoleIO.WriteLine(location.ToString());
return handler.SendPlayerBlockPlacement(0, location, 1, 0.5f, 0.5f, 0.5f, false);
}
+ ///
+ /// Change active slot in the player inventory
+ ///
+ /// Slot to activate (0 to 8)
+ ///
public bool ChangeSlot(short slot)
{
if (slot >= 0 && slot <= 8)
diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs
index 03ad7561..5c2eb0a4 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol16.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs
@@ -641,30 +641,34 @@ namespace MinecraftClient.Protocol.Handlers
return false; //Currently not implemented
}
- //Currently not implemented
public bool SendInteractEntityPacket(int EntityID, int type)
{
- return false;
+ return false; //Currently not implemented
}
+
public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand)
{
- return false;
+ return false; //Currently not implemented
}
+
public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z)
{
- return false;
+ return false; //Currently not implemented
}
+
public bool SendUseItemPacket(int hand)
{
- return false;
+ return false; //Currently not implemented
}
+
public bool SendPlayerBlockPlacement(int hand, Location location, int face, float CursorX, float CursorY, float CursorZ, bool insideBlock)
{
- return false;
+ return false; //Currently not implemented
}
+
public bool SendHeldItemChange(short slot)
{
- return false;
+ return false; //Currently not implemented
}
///
@@ -672,7 +676,6 @@ namespace MinecraftClient.Protocol.Handlers
///
/// Channel to send packet on
/// packet Data
-
public bool SendPluginChannelPacket(string channel, byte[] data)
{
try {
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs
index 152910e6..89dbdcdb 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs
@@ -589,7 +589,7 @@ namespace MinecraftClient.Protocol.Handlers
short ItemID = dataTypes.ReadNextShort(packetData);
if (ItemID == -1)
{
- handler.OnSetSlot(WindowID, SlotID, false);
+ handler.OnSlotClear(WindowID, SlotID);
}
else
{
@@ -601,7 +601,7 @@ namespace MinecraftClient.Protocol.Handlers
{
NBT = dataTypes.ReadNextNbt(packetData);
}
- handler.OnSetSlot(WindowID, SlotID, true, ItemID, Count, NBT);
+ handler.OnSetSlot(WindowID, SlotID, ItemID, Count, NBT);
}
}
else
@@ -615,11 +615,11 @@ namespace MinecraftClient.Protocol.Handlers
int ItemID = dataTypes.ReadNextVarInt(packetData);
byte Count = dataTypes.ReadNextByte(packetData);
Dictionary NBT = dataTypes.ReadNextNbt(packetData);
- handler.OnSetSlot(WindowID, SlotID, Present, ItemID, Count, NBT);
+ handler.OnSetSlot(WindowID, SlotID, ItemID, Count, NBT);
}
else
{
- handler.OnSetSlot(WindowID, SlotID, Present);
+ handler.OnSlotClear(WindowID, SlotID);
}
}
}
diff --git a/MinecraftClient/Protocol/IMinecraftCom.cs b/MinecraftClient/Protocol/IMinecraftCom.cs
index afded88e..60aa7a33 100644
--- a/MinecraftClient/Protocol/IMinecraftCom.cs
+++ b/MinecraftClient/Protocol/IMinecraftCom.cs
@@ -85,14 +85,62 @@ namespace MinecraftClient.Protocol
/// True if message was successfully sent
bool SendPluginChannelPacket(string channel, byte[] data);
+ ///
+ /// Send a held item change packet to the server.
+ ///
+ /// New active slot in the inventory hotbar
+ /// True if packet was successfully sent
bool SendHeldItemChange(short slot);
+ ///
+ /// Send an entity interaction packet to the server.
+ ///
+ /// Entity ID to interact with
+ /// Type of interaction (0: interact, 1: attack, 2: interact at)
+ /// True if packet was successfully sent
bool SendInteractEntityPacket(int EntityID, int type);
+
+ ///
+ /// Send an entity interaction packet to the server.
+ ///
+ /// Entity ID to interact with
+ /// Type of interaction (0: interact, 1: attack, 2: interact at)
+ /// X coordinate for "interact at"
+ /// Y coordinate for "interact at"
+ /// Z coordinate for "interact at"
+ /// Player hand (0: main hand, 1: off hand)
+ /// True if packet was successfully sent
bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand);
+
+ ///
+ /// Send an entity interaction packet to the server.
+ ///
+ /// Entity ID to interact with
+ /// Type of interaction (0: interact, 1: attack, 2: interact at)
+ /// X coordinate for "interact at"
+ /// Y coordinate for "interact at"
+ /// Z coordinate for "interact at"
+ /// True if packet was successfully sent
bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z);
+ ///
+ /// Send a use item packet to the server
+ ///
+ /// 0: main hand, 1: off hand
+ /// True if packet was successfully sent
bool SendUseItemPacket(int hand);
+ ///
+ /// Send player block placement packet to the server
+ ///
+ /// 0: main hand, 1: off hand
+ /// Location to place block at
+ /// Block face
+ /// Cursor X
+ /// Cursor Y
+ /// Cursor Z
+ /// TRUE if inside block
+ /// True if packet was successfully sent
bool SendPlayerBlockPlacement(int hand, Location location, int face, float CursorX, float CursorY, float CursorZ, bool insideBlock);
}
}
diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs
index 0c060076..2771a664 100644
--- a/MinecraftClient/Protocol/IMinecraftComHandler.cs
+++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs
@@ -128,27 +128,102 @@ namespace MinecraftClient.Protocol
/// The data from the channel
void OnPluginChannelMessage(string channel, byte[] data);
+ ///
+ /// Called when a non-living entity has spawned
+ ///
+ /// Entity ID
+ /// Entity Type ID
+ /// Entity UUID
+ /// Entity location
void OnSpawnEntity(int EntityID, int EntityType, Guid UUID, Location location);
+ ///
+ /// Called when a living entity has spawned
+ ///
+ /// Entity ID
+ /// Entity Type ID
+ /// Entity UUID
+ /// Entity location
void OnSpawnLivingEntity(int EntityID, int EntityType, Guid UUID, Location location);
+ ///
+ /// Called when a player has spawned
+ ///
+ /// Entity ID
+ /// Entity UUID
+ /// Entity location
+ /// Player head yaw
+ /// Player head pitch
void OnSpawnPlayer(int EntityID, Guid UUID, Location location, byte Yaw, byte Pitch);
+ ///
+ /// Called when entities have despawned
+ ///
+ /// List of Entity ID that have despawned
void OnDestroyEntities(int[] EntityID);
+ ///
+ /// Called when an entity moved by coordinate offset
+ ///
+ /// Entity ID
+ /// X offset
+ /// Y offset
+ /// Z offset
+ /// TRUE if on ground
void OnEntityPosition(int EntityID, Double Dx, Double Dy, Double Dz,bool onGround);
- void OnEntityProperties(int EntityID, Dictionary prop);
-
- void OnTimeUpdate(long WorldAge, long TimeOfDay);
-
+ ///
+ /// Called when an entity moved to fixed coordinates
+ ///
+ /// Entity ID
+ /// X
+ /// Y
+ /// Z
+ /// TRUE if on ground
void OnEntityTeleport(int EntityID, Double X, Double Y, Double Z, bool onGround);
+ ///
+ /// Called when additional properties have been received for an entity
+ ///
+ /// Entity ID
+ /// Dictionary of properties
+ void OnEntityProperties(int EntityID, Dictionary prop);
+
+ ///
+ /// Called when the world age has been updated
+ ///
+ /// World age
+ /// Time of Day
+ void OnTimeUpdate(long WorldAge, long TimeOfDay);
+
+ ///
+ /// Called when inventory items have been received
+ ///
+ /// Inventory type
+ /// Item list
void OnWindowItems(int type, Dictionary itemList);
- void OnSetSlot(byte WindowID, short SlotID, bool Present);
- void OnSetSlot(byte WindowID, short SlotID, bool Present, int ItemID, byte Count, Dictionary NBT);
+ ///
+ /// Called when a single slot has been cleared inside an inventory
+ ///
+ /// Inventory ID
+ /// Slot ID
+ void OnSlotClear(byte WindowID, short SlotID);
+ ///
+ /// Called when a single slot has been updated inside an inventory
+ ///
+ /// Inventory ID
+ /// Slot ID
+ /// Item ID
+ /// Item Count
+ /// Item Metadata
+ void OnSetSlot(byte WindowID, short SlotID, int ItemID, byte Count, Dictionary NBT);
+
+ ///
+ /// Called when the Player entity ID has been received from the server
+ ///
+ /// Player entity ID
void SetPlayerEntityID(int EntityID);
}
}
diff --git a/MinecraftClient/config/README.md b/MinecraftClient/config/README.md
index 88d00c8b..c0371f67 100644
--- a/MinecraftClient/config/README.md
+++ b/MinecraftClient/config/README.md
@@ -261,7 +261,7 @@ Also, remember that when you connect to a server with this program, you will app
This means that **you can die if you log in in an unsafe place on a survival server!**
Use the script scheduler bot to send a teleport command after logging in.
-You have been reminded that **you may get banned** by your server for using this program. Use accordinly with server rules.
+We remind you that **you may get banned** by your server for using this program. Use accordingly with server rules.
License
------
diff --git a/README.md b/README.md
index 9e54ccde..34f2b17c 100644
--- a/README.md
+++ b/README.md
@@ -32,15 +32,15 @@ Edit `MinecraftClient.csproj` to set the Build target to `Release` on [line 4](h
### On Windows
-1. Locate MSBuild.exe for .NET 4 inside `C:\Windows\Microsoft.NET\Framework\v4.X.XXXXX`
+1. Locate `MSBuild.exe` for .NET 4 inside `C:\Windows\Microsoft.NET\Framework\v4.X.XXXXX`
2. Drag and drop `MinecraftClient.csproj` over `MSBuild.exe` to launch the build
-3. If the build succeededs, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release`
+3. If the build succeeds, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release`
### On Mac and Linux
1. Install the [Mono Framework](https://www.mono-project.com/download/stable/#download-lin) if not already installed
2. Run `msbuild MinecraftClient.csproj` in a terminal
-3. If the build succeededs, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release`
+3. If the build succeeds, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release`
## How to contribute