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.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System.Net;
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>
/// Called when an Entity was created/spawned.
@ -1092,18 +1118,20 @@ namespace MinecraftClient
/// <param name="location"></param>
public void OnSpawnLivingEntity(int EntityID, int EntityType, Guid UUID, Location location)
{
if (!Settings.AutoAttackMobs) return;
string name = getEntityName(EntityType);
if (name != "")
{
Entity entity = new Entity(EntityID, EntityType, name, location);
entitiesToTrack.Add(EntityID, entity);
if (Settings.AutoAttackMobs)
{
if (calculateDistance(location, GetCurrentLocation()) < attackRange)
{
entitiesToAttack.Add(EntityID, entity);
}
}
}
}
/// <summary>
/// Called when entities dead/despawn.
@ -1111,7 +1139,6 @@ namespace MinecraftClient
/// <param name="Entities"></param>
public void OnDestroyEntities(int[] Entities)
{
if (!Settings.AutoAttackMobs) return;
foreach (int a in Entities)
{
if (entitiesToTrack.ContainsKey(a))
@ -1119,6 +1146,11 @@ namespace MinecraftClient
entitiesToAttack.Remove(a);
entitiesToTrack.Remove(a);
}
if (fishingRod.ContainsKey(a))
{
fishingRod.Remove(a);
}
}
}
@ -1161,6 +1193,23 @@ namespace MinecraftClient
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>
@ -1185,7 +1234,6 @@ namespace MinecraftClient
}
}
/// <summary>
/// Called when server sent a Time Update packet.
/// </summary>
@ -1224,12 +1272,47 @@ namespace MinecraftClient
/// <param name="onGround"></param>
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 (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>
/// Calculate the distance between two coordinate
@ -1287,6 +1370,9 @@ namespace MinecraftClient
playerEntityID = EntityID;
}
public void useItemOnHand()
{
handler.SendUseItemPacket(0);
}
}
}

View file

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

View file

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

View file

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

View file

@ -747,5 +747,9 @@ namespace MinecraftClient.Protocol.Handlers
{
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(0))); //Successfully loaded
break;
// modified by reinforce
case PacketIncomingType.SpawnLivingEntity:
if (login_phase) break;
case PacketIncomingType.SpawnEntity:
int EntityID = dataTypes.ReadNextVarInt(packetData);
Guid EntityUUID = dataTypes.ReadNextUUID(packetData);
int EntityType = dataTypes.ReadNextVarInt(packetData);
@ -551,13 +549,31 @@ namespace MinecraftClient.Protocol.Handlers
Double Z = dataTypes.ReadNextDouble(packetData);
byte EntityYaw = dataTypes.ReadNextByte(packetData);
byte EntityPitch = dataTypes.ReadNextByte(packetData);
byte EntityHeadPitch = dataTypes.ReadNextByte(packetData);
int Data = dataTypes.ReadNextInt(packetData);
short VelocityX = dataTypes.ReadNextShort(packetData);
short VelocityY = dataTypes.ReadNextShort(packetData);
short VelocityZ = dataTypes.ReadNextShort(packetData);
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);
break;
@ -597,7 +613,7 @@ namespace MinecraftClient.Protocol.Handlers
DeltaX = DeltaX / (128 * 32);
DeltaY = DeltaY / (128 * 32);
DeltaZ = DeltaZ / (128 * 32);
//handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround);
handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround);
break;
case PacketIncomingType.EntityProperties:
EntityID = dataTypes.ReadNextVarInt(packetData);
@ -643,6 +659,11 @@ namespace MinecraftClient.Protocol.Handlers
OnGround = dataTypes.ReadNextBool(packetData);
handler.OnEntityTeleport(EntityID, X, Y, Z, OnGround);
break;
case PacketIncomingType.EntityStatus:
EntityID = dataTypes.ReadNextInt(packetData);
byte EntityStatus = dataTypes.ReadNextByte(packetData);
handler.OnEntityStatus(EntityID, EntityStatus);
break;
default:
return false; //Ignored packet
}
@ -1162,5 +1183,19 @@ namespace MinecraftClient.Protocol.Handlers
{
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 0x59: return PacketIncomingType.EntityProperties;
case 0x57: return PacketIncomingType.EntityTeleport;
case 0x1C: return PacketIncomingType.EntityStatus;
default: return PacketIncomingType.UnknownPacket;
}
}
@ -383,6 +384,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.TeleportConfirm: return 0x00;
case PacketOutgoingType.HeldItemChange: return 0x23;
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, float X, float Y, float Z, int hand);
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>
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 OnDestroyEntities(int[] EntityID);
@ -140,6 +142,8 @@ namespace MinecraftClient.Protocol
void OnEntityTeleport(int EntityID, Double X, Double Y, Double Z, bool onGround);
void OnEntityStatus(int EntityID, byte EntityStatus);
void SetPlayerEntityID(int EntityID);
}
}