Added basic auto fishing

This commit is contained in:
ReinforceZwei 2020-03-22 20:12:06 +08:00 committed by ORelio
parent 850eae86d7
commit 51d03b9ced
11 changed files with 222 additions and 18 deletions

View file

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MinecraftClient.Commands
{
class Fishing : Command
{
public override string CMDName { get { return "fishing"; } }
public override string CMDDesc { get { return "fishing <on|off>: Auto fishing"; } }
public override string Run(McTcpClient handler, string command)
{
if (hasArg(command))
{
string state = getArg(command);
if (state.ToLower() == "on")
{
if (!handler.AutoFishing)
{
handler.AutoFishing = true;
handler.useItemOnHand();
return "Auto fishing turned on.";
}
else
{
return "Auto fishing is on.";
}
}
else if (state.ToLower() == "off")
{
if (handler.AutoFishing)
{
handler.AutoFishing = false;
handler.useItemOnHand();
return "Auto fishing turned off.";
}
else
{
return "Auto fishing is off.";
}
}
}
return CMDDesc;
}
}
}

View file

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MinecraftClient.Commands
{
class UseItem : Command
{
public override string CMDName { get { return "useitem"; } }
public override string CMDDesc { get { return "useitem: Use (left click) an item on the hand"; } }
public override string Run(McTcpClient handler, string command)
{
handler.useItemOnHand();
return "Use an item";
}
}
}

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using System.IO; using System.IO;
using System.Net; using System.Net;
using MinecraftClient.Protocol; using MinecraftClient.Protocol;
@ -1081,7 +1082,32 @@ namespace MinecraftClient
} }
} }
private Dictionary<int,Entity> fishingRod = new Dictionary<int, Entity>();
private Double fishingHookThreshold = -0.3; // must be negetive
public bool AutoFishing { get; set; } = false;
public void OnSpawnEntity(int EntityID, int EntityType, Guid UUID, Location location)
{
if (EntityType == 102 && AutoFishing)
{
ConsoleIO.WriteLine("Threw a fishing rod");
fishingRod.Add(EntityID,new Entity(EntityID, EntityType, "fishing bobber", location));
}
}
public void OnEntityStatus(int EntityID, byte EntityStatus)
{
if (fishingRod.ContainsKey(EntityID))
{
if (EntityStatus == 31)
{
ConsoleIO.WriteLine("Status is bobber");
}
else
{
ConsoleIO.WriteLine("Status is " + EntityStatus);
}
}
}
/// <summary> /// <summary>
/// Called when an Entity was created/spawned. /// Called when an Entity was created/spawned.
@ -1092,15 +1118,17 @@ namespace MinecraftClient
/// <param name="location"></param> /// <param name="location"></param>
public void OnSpawnLivingEntity(int EntityID, int EntityType, Guid UUID, Location location) public void OnSpawnLivingEntity(int EntityID, int EntityType, Guid UUID, Location location)
{ {
if (!Settings.AutoAttackMobs) return;
string name = getEntityName(EntityType); string name = getEntityName(EntityType);
if (name != "") if (name != "")
{ {
Entity entity = new Entity(EntityID, EntityType, name, location); Entity entity = new Entity(EntityID, EntityType, name, location);
entitiesToTrack.Add(EntityID, entity); entitiesToTrack.Add(EntityID, entity);
if (calculateDistance(location, GetCurrentLocation()) < attackRange) if (Settings.AutoAttackMobs)
{ {
entitiesToAttack.Add(EntityID, entity); if (calculateDistance(location, GetCurrentLocation()) < attackRange)
{
entitiesToAttack.Add(EntityID, entity);
}
} }
} }
} }
@ -1111,7 +1139,6 @@ namespace MinecraftClient
/// <param name="Entities"></param> /// <param name="Entities"></param>
public void OnDestroyEntities(int[] Entities) public void OnDestroyEntities(int[] Entities)
{ {
if (!Settings.AutoAttackMobs) return;
foreach (int a in Entities) foreach (int a in Entities)
{ {
if (entitiesToTrack.ContainsKey(a)) if (entitiesToTrack.ContainsKey(a))
@ -1119,6 +1146,11 @@ namespace MinecraftClient
entitiesToAttack.Remove(a); entitiesToAttack.Remove(a);
entitiesToTrack.Remove(a); entitiesToTrack.Remove(a);
} }
if (fishingRod.ContainsKey(a))
{
fishingRod.Remove(a);
}
} }
} }
@ -1161,6 +1193,23 @@ namespace MinecraftClient
entitiesToAttack.Remove(EntityID); entitiesToAttack.Remove(EntityID);
} }
} }
if (fishingRod.ContainsKey(EntityID))
{
Location L = fishingRod[EntityID].Location;
L.X += Dx;
L.Y += Dy;
L.Z += Dz;
fishingRod[EntityID].Location = L;
// check if fishing hook is stationary
if (Dx == 0 && Dz == 0)
{
if (Dy < fishingHookThreshold)
{
// caught
OnCaughtFish();
}
}
}
} }
/// <summary> /// <summary>
@ -1184,7 +1233,6 @@ namespace MinecraftClient
} }
} }
} }
/// <summary> /// <summary>
/// Called when server sent a Time Update packet. /// Called when server sent a Time Update packet.
@ -1224,11 +1272,46 @@ namespace MinecraftClient
/// <param name="onGround"></param> /// <param name="onGround"></param>
public void OnEntityTeleport(int EntityID, Double X, Double Y, Double Z, bool onGround) public void OnEntityTeleport(int EntityID, Double X, Double Y, Double Z, bool onGround)
{ {
if (!Settings.AutoAttackMobs) return; if (Settings.AutoAttackMobs)
if (entitiesToTrack.ContainsKey(EntityID))
{ {
entitiesToTrack[EntityID].Location = new Location(X, Y, Z); if (entitiesToTrack.ContainsKey(EntityID))
{
entitiesToTrack[EntityID].Location = new Location(X, Y, Z);
}
} }
if (fishingRod.ContainsKey(EntityID))
{
Location L = fishingRod[EntityID].Location;
Double Dy = L.Y - Y;
L.X = X;
L.Y = Y;
L.Z = Z;
fishingRod[EntityID].Location = L;
if (Dy < fishingHookThreshold)
{
// caught
OnCaughtFish();
}
}
}
/// <summary>
/// Called when detected a fish is caught
/// </summary>
public void OnCaughtFish()
{
ConsoleIO.WriteLine("Caught a fish!");
// retract fishing rod
useItemOnHand();
// retract fishing rod need some time
Task.Factory.StartNew(delegate
{
Thread.Sleep(500);
// throw again
// TODO: to check if hand have fishing rod
if(AutoFishing)
useItemOnHand();
});
} }
/// <summary> /// <summary>
@ -1287,6 +1370,9 @@ namespace MinecraftClient
playerEntityID = EntityID; playerEntityID = EntityID;
} }
public void useItemOnHand()
{
handler.SendUseItemPacket(0);
}
} }
} }

View file

@ -89,6 +89,7 @@
<Compile Include="Commands\AutoAttack.cs" /> <Compile Include="Commands\AutoAttack.cs" />
<Compile Include="Commands\Connect.cs" /> <Compile Include="Commands\Connect.cs" />
<Compile Include="Commands\Debug.cs" /> <Compile Include="Commands\Debug.cs" />
<Compile Include="Commands\Fishing.cs" />
<Compile Include="Commands\Look.cs" /> <Compile Include="Commands\Look.cs" />
<Compile Include="Commands\Move.cs" /> <Compile Include="Commands\Move.cs" />
<Compile Include="Commands\Exit.cs" /> <Compile Include="Commands\Exit.cs" />
@ -98,6 +99,7 @@
<Compile Include="Commands\Script.cs" /> <Compile Include="Commands\Script.cs" />
<Compile Include="Commands\Send.cs" /> <Compile Include="Commands\Send.cs" />
<Compile Include="Commands\Set.cs" /> <Compile Include="Commands\Set.cs" />
<Compile Include="Commands\UseItem.cs" />
<Compile Include="Mapping\BlockPalettes\Palette112.cs" /> <Compile Include="Mapping\BlockPalettes\Palette112.cs" />
<Compile Include="Mapping\BlockPalettes\Palette113.cs" /> <Compile Include="Mapping\BlockPalettes\Palette113.cs" />
<Compile Include="Mapping\BlockPalettes\Palette114.cs" /> <Compile Include="Mapping\BlockPalettes\Palette114.cs" />

View file

@ -40,6 +40,7 @@ namespace MinecraftClient.Protocol.Handlers
EntityPositionAndRotation, EntityPositionAndRotation,
EntityProperties, EntityProperties,
TimeUpdate, TimeUpdate,
EntityTeleport EntityTeleport,
EntityStatus
} }
} }

View file

@ -22,6 +22,7 @@ namespace MinecraftClient.Protocol.Handlers
TeleportConfirm, TeleportConfirm,
//modified by reinforce //modified by reinforce
HeldItemChange, HeldItemChange,
InteractEntity InteractEntity,
UseItem
} }
} }

View file

@ -747,5 +747,9 @@ namespace MinecraftClient.Protocol.Handlers
{ {
return true; return true;
} }
public bool SendUseItemPacket(int hand)
{
return true;
}
} }
} }

View file

@ -540,9 +540,7 @@ namespace MinecraftClient.Protocol.Handlers
SendPacket(PacketOutgoingType.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(3))); //Accepted pack SendPacket(PacketOutgoingType.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(3))); //Accepted pack
SendPacket(PacketOutgoingType.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(0))); //Successfully loaded SendPacket(PacketOutgoingType.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(0))); //Successfully loaded
break; break;
// modified by reinforce case PacketIncomingType.SpawnEntity:
case PacketIncomingType.SpawnLivingEntity:
if (login_phase) break;
int EntityID = dataTypes.ReadNextVarInt(packetData); int EntityID = dataTypes.ReadNextVarInt(packetData);
Guid EntityUUID = dataTypes.ReadNextUUID(packetData); Guid EntityUUID = dataTypes.ReadNextUUID(packetData);
int EntityType = dataTypes.ReadNextVarInt(packetData); int EntityType = dataTypes.ReadNextVarInt(packetData);
@ -551,13 +549,31 @@ namespace MinecraftClient.Protocol.Handlers
Double Z = dataTypes.ReadNextDouble(packetData); Double Z = dataTypes.ReadNextDouble(packetData);
byte EntityYaw = dataTypes.ReadNextByte(packetData); byte EntityYaw = dataTypes.ReadNextByte(packetData);
byte EntityPitch = dataTypes.ReadNextByte(packetData); byte EntityPitch = dataTypes.ReadNextByte(packetData);
byte EntityHeadPitch = dataTypes.ReadNextByte(packetData); int Data = dataTypes.ReadNextInt(packetData);
short VelocityX = dataTypes.ReadNextShort(packetData); short VelocityX = dataTypes.ReadNextShort(packetData);
short VelocityY = dataTypes.ReadNextShort(packetData); short VelocityY = dataTypes.ReadNextShort(packetData);
short VelocityZ = dataTypes.ReadNextShort(packetData); short VelocityZ = dataTypes.ReadNextShort(packetData);
Location EntityLocation = new Location(X, Y, Z); Location EntityLocation = new Location(X, Y, Z);
handler.OnSpawnEntity(EntityID, EntityType, EntityUUID, EntityLocation);
break;
case PacketIncomingType.SpawnLivingEntity:
if (login_phase) break;
EntityID = dataTypes.ReadNextVarInt(packetData);
EntityUUID = dataTypes.ReadNextUUID(packetData);
EntityType = dataTypes.ReadNextVarInt(packetData);
X = dataTypes.ReadNextDouble(packetData);
Y = dataTypes.ReadNextDouble(packetData);
Z = dataTypes.ReadNextDouble(packetData);
EntityYaw = dataTypes.ReadNextByte(packetData);
EntityPitch = dataTypes.ReadNextByte(packetData);
byte EntityHeadPitch = dataTypes.ReadNextByte(packetData);
VelocityX = dataTypes.ReadNextShort(packetData);
VelocityY = dataTypes.ReadNextShort(packetData);
VelocityZ = dataTypes.ReadNextShort(packetData);
EntityLocation = new Location(X, Y, Z);
handler.OnSpawnLivingEntity(EntityID,EntityType,EntityUUID,EntityLocation); handler.OnSpawnLivingEntity(EntityID,EntityType,EntityUUID,EntityLocation);
break; break;
@ -597,7 +613,7 @@ namespace MinecraftClient.Protocol.Handlers
DeltaX = DeltaX / (128 * 32); DeltaX = DeltaX / (128 * 32);
DeltaY = DeltaY / (128 * 32); DeltaY = DeltaY / (128 * 32);
DeltaZ = DeltaZ / (128 * 32); DeltaZ = DeltaZ / (128 * 32);
//handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround); handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround);
break; break;
case PacketIncomingType.EntityProperties: case PacketIncomingType.EntityProperties:
EntityID = dataTypes.ReadNextVarInt(packetData); EntityID = dataTypes.ReadNextVarInt(packetData);
@ -643,6 +659,11 @@ namespace MinecraftClient.Protocol.Handlers
OnGround = dataTypes.ReadNextBool(packetData); OnGround = dataTypes.ReadNextBool(packetData);
handler.OnEntityTeleport(EntityID, X, Y, Z, OnGround); handler.OnEntityTeleport(EntityID, X, Y, Z, OnGround);
break; break;
case PacketIncomingType.EntityStatus:
EntityID = dataTypes.ReadNextInt(packetData);
byte EntityStatus = dataTypes.ReadNextByte(packetData);
handler.OnEntityStatus(EntityID, EntityStatus);
break;
default: default:
return false; //Ignored packet return false; //Ignored packet
} }
@ -1162,5 +1183,19 @@ namespace MinecraftClient.Protocol.Handlers
{ {
return true; return true;
} }
public bool SendUseItemPacket(int hand)
{
try
{
List<byte> packet = new List<byte>();
packet.AddRange(dataTypes.GetVarInt(hand));
SendPacket(PacketOutgoingType.UseItem, packet);
return true;
}
catch (SocketException) { return false; }
catch (System.IO.IOException) { return false; }
catch (ObjectDisposedException) { return false; }
}
} }
} }

View file

@ -269,6 +269,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x2A: return PacketIncomingType.EntityPositionAndRotation; case 0x2A: return PacketIncomingType.EntityPositionAndRotation;
case 0x59: return PacketIncomingType.EntityProperties; case 0x59: return PacketIncomingType.EntityProperties;
case 0x57: return PacketIncomingType.EntityTeleport; case 0x57: return PacketIncomingType.EntityTeleport;
case 0x1C: return PacketIncomingType.EntityStatus;
default: return PacketIncomingType.UnknownPacket; default: return PacketIncomingType.UnknownPacket;
} }
} }
@ -383,6 +384,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.TeleportConfirm: return 0x00; case PacketOutgoingType.TeleportConfirm: return 0x00;
case PacketOutgoingType.HeldItemChange: return 0x23; case PacketOutgoingType.HeldItemChange: return 0x23;
case PacketOutgoingType.InteractEntity: return 0x0E; case PacketOutgoingType.InteractEntity: return 0x0E;
case PacketOutgoingType.UseItem: return 0x2D;
} }
} }

View file

@ -89,5 +89,7 @@ namespace MinecraftClient.Protocol
bool SendInteractEntityPacket(int EntityID, int type); bool SendInteractEntityPacket(int EntityID, int type);
bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand); bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand);
bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z); bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z);
bool SendUseItemPacket(int hand);
} }
} }

View file

@ -126,6 +126,8 @@ namespace MinecraftClient.Protocol
/// <param name="data">The data from the channel</param> /// <param name="data">The data from the channel</param>
void OnPluginChannelMessage(string channel, byte[] data); void OnPluginChannelMessage(string channel, byte[] data);
void OnSpawnEntity(int EntityID, int EntityType, Guid UUID, Location location);
void OnSpawnLivingEntity(int EntityID, int EntityType, Guid UUID, Location location); void OnSpawnLivingEntity(int EntityID, int EntityType, Guid UUID, Location location);
void OnDestroyEntities(int[] EntityID); void OnDestroyEntities(int[] EntityID);
@ -140,6 +142,8 @@ namespace MinecraftClient.Protocol
void OnEntityTeleport(int EntityID, Double X, Double Y, Double Z, bool onGround); void OnEntityTeleport(int EntityID, Double X, Double Y, Double Z, bool onGround);
void OnEntityStatus(int EntityID, byte EntityStatus);
void SetPlayerEntityID(int EntityID); void SetPlayerEntityID(int EntityID);
} }
} }