diff --git a/MinecraftClient/ChatBot.cs b/MinecraftClient/ChatBot.cs
index 538b91c2..e5f92b35 100644
--- a/MinecraftClient/ChatBot.cs
+++ b/MinecraftClient/ChatBot.cs
@@ -156,6 +156,8 @@ namespace MinecraftClient
/// Entity with updated location
public virtual void OnEntityMove(Mapping.Entity entity) { }
+ public virtual void OnInternalCommand(string commandName,string commandParams, string Result) { }
+
///
/// Called when an entity spawned nearby
///
@@ -662,6 +664,32 @@ namespace MinecraftClient
{
return Handler.GetInventoryEnabled();
}
+ public Dictionary GetInventories()
+ {
+ return Handler.GetInventories();
+ }
+
+ ///
+ /// start Sneaking
+ ///
+ protected bool Sneak(bool on)
+ {
+ return SendEntityAction(on ? Protocol.EntityActionType.StartSneaking : Protocol.EntityActionType.StopSneaking);
+ }
+ ///
+ /// Send Entity Action
+ ///
+ private bool SendEntityAction(Protocol.EntityActionType entityAction)
+ {
+ return Handler.sendEntityAction(entityAction);
+ }
+ ///
+ /// SetSlot
+ ///
+ protected void SetSlot(int slotNum)
+ {
+ Handler.ChangeSlot((short) slotNum);
+ }
///
/// Get the current Minecraft World
@@ -862,7 +890,7 @@ namespace MinecraftClient
/// Use item currently in the player's hand (active inventory bar slot)
///
///
- protected bool UseItemOnHand()
+ protected bool UseItemInHand()
{
return Handler.UseItemOnHand();
}
diff --git a/MinecraftClient/ChatBots/AutoEat.cs b/MinecraftClient/ChatBots/AutoEat.cs
index 7597ab90..0a32d7ac 100644
--- a/MinecraftClient/ChatBots/AutoEat.cs
+++ b/MinecraftClient/ChatBots/AutoEat.cs
@@ -83,7 +83,7 @@ namespace MinecraftClient.ChatBots
}
}
}
- if (found) UseItemOnHand();
+ if (found) UseItemInHand();
return found;
}
}
diff --git a/MinecraftClient/ChatBots/AutoFishing.cs b/MinecraftClient/ChatBots/AutoFishing.cs
index 92d22165..dc2d7432 100644
--- a/MinecraftClient/ChatBots/AutoFishing.cs
+++ b/MinecraftClient/ChatBots/AutoFishing.cs
@@ -95,7 +95,7 @@ namespace MinecraftClient.ChatBots
{
LogToConsole(GetTimestamp() + ": Caught a fish!");
// retract fishing rod
- UseItemOnHand();
+ UseItemInHand();
if (inventoryEnabled)
{
if (!hasFishingRod())
@@ -110,7 +110,7 @@ namespace MinecraftClient.ChatBots
// retract fishing rod need some time
Thread.Sleep(800);
// throw again
- UseItemOnHand();
+ UseItemInHand();
});
}
diff --git a/MinecraftClient/ChatBots/ChatLog.cs b/MinecraftClient/ChatBots/ChatLog.cs
index 38faec79..dbd028e3 100644
--- a/MinecraftClient/ChatBots/ChatLog.cs
+++ b/MinecraftClient/ChatBots/ChatLog.cs
@@ -12,11 +12,12 @@ namespace MinecraftClient.ChatBots
public class ChatLog : ChatBot
{
- public enum MessageFilter { AllText, AllMessages, OnlyChat, OnlyWhispers };
+ public enum MessageFilter { AllText, AllMessages, OnlyChat, OnlyWhispers, OnlyInternalCommands };
private bool dateandtime;
private bool saveOther = true;
private bool saveChat = true;
private bool savePrivate = true;
+ private bool saveInternal = true;
private string logfile;
///
@@ -52,6 +53,12 @@ namespace MinecraftClient.ChatBots
savePrivate = true;
saveChat = false;
break;
+ case MessageFilter.OnlyInternalCommands:
+ saveOther = false;
+ savePrivate = false;
+ saveChat = false;
+ saveInternal = true;
+ break;
}
if (String.IsNullOrEmpty(file) || file.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
{
@@ -68,6 +75,7 @@ namespace MinecraftClient.ChatBots
case "messages": return MessageFilter.AllMessages;
case "chat": return MessageFilter.OnlyChat;
case "private": return MessageFilter.OnlyWhispers;
+ case "internal": return MessageFilter.OnlyInternalCommands;
default: return MessageFilter.AllText;
}
}
@@ -92,6 +100,14 @@ namespace MinecraftClient.ChatBots
}
}
+ public override void OnInternalCommand(string commandName,string commandParams, string result)
+ {
+ if (saveInternal)
+ {
+ save(string.Format("Internal {0}({1}): {2}", commandName, commandParams, result));
+ }
+ }
+
private void save(string tosave)
{
if (dateandtime)
diff --git a/MinecraftClient/Commands/Sneak.cs b/MinecraftClient/Commands/Sneak.cs
new file mode 100644
index 00000000..51067b53
--- /dev/null
+++ b/MinecraftClient/Commands/Sneak.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MinecraftClient.Commands
+{
+ public class Sneak : Command
+ {
+ private bool sneaking = false;
+ public override string CMDName { get { return "Sneak"; } }
+ public override string CMDDesc { get { return "Sneak: Toggles sneaking"; } }
+
+ public override string Run(McTcpClient handler, string command, Dictionary localVars)
+ {
+ Console.WriteLine(command);
+ if (sneaking)
+ {
+ var result = handler.sendEntityAction(Protocol.EntityActionType.StopSneaking);
+ sneaking = false;
+ return result ? "Success" : "Fail";
+ }
+ else
+ {
+ var result = handler.sendEntityAction(Protocol.EntityActionType.StartSneaking);
+ sneaking = true;
+ return result ? "Success" : "Fail";
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs
index d95af69d..9881148a 100644
--- a/MinecraftClient/McTcpClient.cs
+++ b/MinecraftClient/McTcpClient.cs
@@ -6,6 +6,7 @@ using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Net;
+using MinecraftClient.ChatBots;
using MinecraftClient.Protocol;
using MinecraftClient.Proxy;
using MinecraftClient.Protocol.Handlers.Forge;
@@ -170,6 +171,7 @@ namespace MinecraftClient
if (Settings.AutoAttack_Enabled) { BotLoad(new ChatBots.AutoAttack()); }
if (Settings.AutoFishing_Enabled) { BotLoad(new ChatBots.AutoFishing()); }
if (Settings.AutoEat_Enabled) { BotLoad(new ChatBots.AutoEat(Settings.AutoEat_hungerThreshold)); }
+
//Add your ChatBot here by uncommenting and adapting
//BotLoad(new ChatBots.YourBot());
}
@@ -324,6 +326,7 @@ namespace MinecraftClient
}
while (true);
}
+
///
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
@@ -334,6 +337,7 @@ namespace MinecraftClient
/// TRUE if the command was indeed an internal MCC command
public bool PerformInternalCommand(string command, ref string response_msg, Dictionary localVars = null)
{
+
/* Load commands from the 'Commands' namespace */
if (cmds.Count == 0)
@@ -382,12 +386,28 @@ namespace MinecraftClient
else if (cmds.ContainsKey(command_name))
{
response_msg = cmds[command_name].Run(this, command, localVars);
+ foreach (ChatBot bot in bots.ToArray())
+ {
+ try
+ {
+ bot.OnInternalCommand(command_name, string.Join(" ",Command.getArgs(command)),response_msg);
+ }
+ catch (Exception e)
+ {
+ if (!(e is ThreadAbortException))
+ {
+ ConsoleIO.WriteLogLine("OnInternalCommand: Got error from " + bot.ToString() + ": " + e.ToString());
+ }
+ else throw; //ThreadAbortException should not be caught
+ }
+ }
}
else
{
response_msg = "Unknown command '" + command_name + "'. Use '" + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + "help' for help.";
return false;
}
+
return true;
}
@@ -1356,6 +1376,7 @@ namespace MinecraftClient
}
}
+
///
/// Called when an entity moved over 8 block.
///
@@ -1469,6 +1490,14 @@ namespace MinecraftClient
playerEntityID = EntityID;
}
+ ///
+ /// Send the Entity Action packet with the Specified ID
+ ///
+ /// TRUE if the item was successfully used
+ public bool sendEntityAction(EntityActionType entityAction)
+ {
+ return handler.SendEntityAction(playerEntityID, (int) entityAction);
+ }
///
/// Use the item currently in the player's hand
///
diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj
index b13b53a3..ed121f24 100644
--- a/MinecraftClient/MinecraftClient.csproj
+++ b/MinecraftClient/MinecraftClient.csproj
@@ -103,6 +103,7 @@
+
@@ -119,6 +120,7 @@
+
diff --git a/MinecraftClient/Protocol/EntityActionType.cs b/MinecraftClient/Protocol/EntityActionType.cs
new file mode 100644
index 00000000..7d560e07
--- /dev/null
+++ b/MinecraftClient/Protocol/EntityActionType.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MinecraftClient.Protocol
+{
+ public enum EntityActionType
+ {
+ StartSneaking,
+ StopSneaking,
+ LeaveBed,
+ StartSprinting,
+ StopSprinting
+ }
+}
\ No newline at end of file
diff --git a/MinecraftClient/Protocol/Handlers/PacketOutgoingType.cs b/MinecraftClient/Protocol/Handlers/PacketOutgoingType.cs
index 753558fa..5236aada 100644
--- a/MinecraftClient/Protocol/Handlers/PacketOutgoingType.cs
+++ b/MinecraftClient/Protocol/Handlers/PacketOutgoingType.cs
@@ -17,6 +17,7 @@ namespace MinecraftClient.Protocol.Handlers
ClientSettings,
PluginMessage,
TabComplete,
+ EntityAction,
PlayerPosition,
PlayerPositionAndLook,
TeleportConfirm,
@@ -27,4 +28,4 @@ namespace MinecraftClient.Protocol.Handlers
CloseWindow,
PlayerBlockPlacement
}
-}
+}
\ No newline at end of file
diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs
index 58b2aa1f..f5f0d07d 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol16.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs
@@ -239,6 +239,10 @@ namespace MinecraftClient.Protocol.Handlers
}
else return "";
}
+ public bool SendEntityAction(int PlayerEntityID, int ActionID)
+ {
+ return false;
+ }
private byte[] readNextByteArray()
{
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs
index fab2c9fc..d63241a1 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs
@@ -965,6 +965,22 @@ namespace MinecraftClient.Protocol.Handlers
catch (System.IO.IOException) { return false; }
catch (ObjectDisposedException) { return false; }
}
+
+ public bool SendEntityAction(int PlayerEntityID, int ActionID)
+ {
+ try
+ {
+ List fields = new List();
+ fields.AddRange(dataTypes.GetVarInt(PlayerEntityID));
+ fields.AddRange(dataTypes.GetVarInt(ActionID));
+ fields.AddRange(dataTypes.GetVarInt(0));
+ SendPacket(PacketOutgoingType.EntityAction, fields);
+ return true;
+ }
+ catch (SocketException) { return false; }
+ catch (System.IO.IOException) { return false; }
+ catch (ObjectDisposedException) { return false; }
+ }
///
/// Send a respawn packet to the server
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs b/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs
index 68ffef0a..feac66ab 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs
@@ -310,6 +310,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.TeleportConfirm: throw new InvalidOperationException("Teleport confirm is not supported in protocol " + protocol);
case PacketOutgoingType.ClickWindow: return 0x0E;
case PacketOutgoingType.CloseWindow: return 0x0D;
+ case PacketOutgoingType.EntityAction: return 0x0B;
}
}
else if (protocol <= Protocol18Handler.MC1112Version) // MC 1.9, 1,10 and 1.11
@@ -330,6 +331,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.InteractEntity: return 0x0A;
case PacketOutgoingType.ClickWindow: return 0x07;
case PacketOutgoingType.CloseWindow: return 0x08;
+ case PacketOutgoingType.EntityAction: return 0x0B;
}
}
else if (protocol <= Protocol18Handler.MC112Version) // MC 1.12
@@ -350,6 +352,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.InteractEntity: return 0x0B;
case PacketOutgoingType.ClickWindow: return 0x07;
case PacketOutgoingType.CloseWindow: return 0x08;
+ case PacketOutgoingType.EntityAction: return 0x0B;
}
}
else if (protocol <= Protocol18Handler.MC1122Version) // 1.12.2
@@ -370,6 +373,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.InteractEntity: return 0x0A;
case PacketOutgoingType.ClickWindow: return 0x07;
case PacketOutgoingType.CloseWindow: return 0x08;
+ case PacketOutgoingType.EntityAction: return 0x0B;
}
}
else if (protocol < Protocol18Handler.MC114Version) // MC 1.13 to 1.13.2
@@ -390,6 +394,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.InteractEntity: return 0x0D;
case PacketOutgoingType.ClickWindow: return 0x08;
case PacketOutgoingType.CloseWindow: return 0x09;
+ case PacketOutgoingType.EntityAction: return 0x19;
}
}
else // MC 1.14 to 1.15
@@ -412,6 +417,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.PlayerBlockPlacement: return 0x2C;
case PacketOutgoingType.ClickWindow: return 0x09;
case PacketOutgoingType.CloseWindow: return 0x0A;
+ case PacketOutgoingType.EntityAction: return 0x19;
}
}
diff --git a/MinecraftClient/Protocol/IMinecraftCom.cs b/MinecraftClient/Protocol/IMinecraftCom.cs
index 1b876db1..00e57790 100644
--- a/MinecraftClient/Protocol/IMinecraftCom.cs
+++ b/MinecraftClient/Protocol/IMinecraftCom.cs
@@ -85,7 +85,15 @@ namespace MinecraftClient.Protocol
/// packet Data
/// True if message was successfully sent
bool SendPluginChannelPacket(string channel, byte[] data);
-
+
+ ///
+ /// Send Entity Action packet to the server.
+ ///
+ /// PlayerID
+ /// Type of packet to send
+ /// True if packet was successfully sent
+ bool SendEntityAction(int EntityID, int type);
+
///
/// Send a held item change packet to the server.
///
diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs
index fca92a25..2afcafd9 100644
--- a/MinecraftClient/Settings.cs
+++ b/MinecraftClient/Settings.cs
@@ -466,7 +466,6 @@ namespace MinecraftClient
case "matchesfile": AutoRespond_Matches = argValue; break;
}
break;
-
case ParseMode.AutoAttack:
switch (argName.ToLower())
{
@@ -689,12 +688,13 @@ namespace MinecraftClient
+ "\r\n"
+ "[AutoFishing]\r\n"
+ "# Entity Handling NEED to be enabled first\r\n"
- + "enabled=false"
+ + "enabled=false\r\n"
+ "\r\n"
+ "[AutoEat]\r\n"
+ "# Inventory Handling NEED to be enabled first\r\n"
+ "enabled=false\r\n"
- + "threshold=6", Encoding.UTF8);
+ + "threshold=6\r\n"
+ + "\r\n", Encoding.UTF8);
}
///