mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
feat: Enable Farmer bot support for legacy 1.8 to 1.12.2
feat: Enable Farmer bot support for legacy 1.8 to 1.12.2
This commit is contained in:
commit
41b33b6599
9 changed files with 115 additions and 24 deletions
|
|
@ -73,7 +73,7 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
public override void Initialize()
|
||||
{
|
||||
if (GetProtocolVersion() < Protocol18Handler.MC_1_13_Version)
|
||||
if (GetProtocolVersion() < Protocol18Handler.MC_1_8_Version)
|
||||
{
|
||||
LogToConsole(Translations.bot_farmer_not_implemented);
|
||||
return;
|
||||
|
|
@ -149,6 +149,10 @@ namespace MinecraftClient.ChatBots
|
|||
if (running)
|
||||
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_farmer_already_running);
|
||||
|
||||
if (!IsCropAvailableForProtocol(whatToFarm, GetProtocolVersion()))
|
||||
return r.SetAndReturn(CmdResult.Status.Fail,
|
||||
string.Format(Translations.bot_farmer_crop_unavailable, whatToFarm, "1.9"));
|
||||
|
||||
var movementLock = BotMovementLock.Instance;
|
||||
if (movementLock is { IsLocked: true })
|
||||
return r.SetAndReturn(CmdResult.Status.Fail,
|
||||
|
|
@ -369,11 +373,11 @@ namespace MinecraftClient.ChatBots
|
|||
break;
|
||||
}
|
||||
|
||||
var loc = new Location(Math.Floor(location.X), Math.Floor(location2.Y),
|
||||
var loc = new Location(Math.Floor(location.X), Math.Floor(location.Y),
|
||||
Math.Floor(location.Z));
|
||||
LogDebug("Sending placeblock to: " + loc);
|
||||
|
||||
SendPlaceBlock(loc, Direction.Up);
|
||||
SendPlaceBlock(loc, Direction.Up, lookAtBlock: true);
|
||||
Thread.Sleep(300);
|
||||
}
|
||||
else LogDebug("Can't move to: " + location2);
|
||||
|
|
@ -496,7 +500,7 @@ namespace MinecraftClient.ChatBots
|
|||
{
|
||||
// TODO: Do a check if the carrot/potato is on the first growth stage
|
||||
// if so, use: new Location(location.X, (double)(location.Y - 1) + (double)0.93750, location.Z)
|
||||
SendPlaceBlock(location2, Direction.Down);
|
||||
SendPlaceBlock(location2, Direction.Down, lookAtBlock: true);
|
||||
}
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
|
@ -591,6 +595,15 @@ namespace MinecraftClient.ChatBots
|
|||
};
|
||||
}
|
||||
|
||||
private static bool IsCropAvailableForProtocol(CropType type, int protocolVersion)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
CropType.Beetroot => protocolVersion >= Protocol18Handler.MC_1_9_Version,
|
||||
_ => true
|
||||
};
|
||||
}
|
||||
|
||||
private List<Location> FindEmptyFarmland(int radius)
|
||||
{
|
||||
return GetWorld()
|
||||
|
|
@ -616,16 +629,19 @@ namespace MinecraftClient.ChatBots
|
|||
if (fullyGrown && material is Material.Melon or Material.Pumpkin)
|
||||
return true;
|
||||
|
||||
var isFullyGrown = IsCropFullyGrown(GetWorld().GetBlock(location), cropType);
|
||||
var isFullyGrown = IsCropFullyGrown(GetWorld().GetBlock(location), cropType, location);
|
||||
return fullyGrown ? isFullyGrown : !isFullyGrown;
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private bool IsCropFullyGrown(Block block, CropType cropType)
|
||||
private bool IsCropFullyGrown(Block block, CropType cropType, Location? location = null)
|
||||
{
|
||||
var protocolVersion = GetProtocolVersion();
|
||||
|
||||
if (protocolVersion < Protocol18Handler.MC_1_13_Version)
|
||||
return IsLegacyCropFullyGrown(block, cropType, location);
|
||||
|
||||
switch (cropType)
|
||||
{
|
||||
case CropType.Beetroot:
|
||||
|
|
@ -781,6 +797,44 @@ namespace MinecraftClient.ChatBots
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool IsLegacyCropFullyGrown(Block block, CropType cropType, Location? location)
|
||||
{
|
||||
return cropType switch
|
||||
{
|
||||
CropType.Beetroot => block.BlockId == 207 && block.BlockMeta >= 3,
|
||||
CropType.Carrot => block.BlockId == 141 && block.BlockMeta >= 7,
|
||||
CropType.Melon => block.BlockId == 105
|
||||
&& (block.BlockMeta >= 7 || HasAdjacentBlock(location, Material.Melon)),
|
||||
CropType.NetherWart => block.BlockId == 115 && block.BlockMeta >= 3,
|
||||
CropType.Pumpkin => block.BlockId == 104
|
||||
&& (block.BlockMeta >= 7 || HasAdjacentBlock(location, Material.Pumpkin)),
|
||||
CropType.Potato => block.BlockId == 142 && block.BlockMeta >= 7,
|
||||
CropType.Wheat => block.BlockId == 59 && block.BlockMeta >= 7,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
private bool HasAdjacentBlock(Location? location, Material material)
|
||||
{
|
||||
if (location is not Location stemLocation)
|
||||
return false;
|
||||
|
||||
var world = GetWorld();
|
||||
int x = (int)Math.Floor(stemLocation.X);
|
||||
int y = (int)Math.Floor(stemLocation.Y);
|
||||
int z = (int)Math.Floor(stemLocation.Z);
|
||||
|
||||
Location[] adjacentLocations =
|
||||
[
|
||||
new(x + 1, y, z),
|
||||
new(x - 1, y, z),
|
||||
new(x, y, z + 1),
|
||||
new(x, y, z - 1)
|
||||
];
|
||||
|
||||
return adjacentLocations.Any(adjacentLocation => world.GetBlock(adjacentLocation).Type == material);
|
||||
}
|
||||
|
||||
// Yoinked from ReinforceZwei's AutoTree and adapted to search the whole of inventory in additon to the hotbar
|
||||
private bool SwitchToItem(ItemType itemType)
|
||||
{
|
||||
|
|
@ -854,4 +908,4 @@ namespace MinecraftClient.ChatBots
|
|||
else LogDebugToConsole(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ namespace MinecraftClient.Mapping.BlockPalettes
|
|||
{ 173, Material.CoalBlock },
|
||||
{ 174, Material.PackedIce },
|
||||
{ 175, Material.TallGrass }, // DoublePlant
|
||||
{ 207, Material.Beetroots }, // BeetrootBlock
|
||||
};
|
||||
|
||||
protected override Dictionary<int, Material> GetDict()
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
>= MC_1_14_Version => new EntityPalette114(),
|
||||
>= MC_1_13_Version => new EntityPalette113(),
|
||||
>= MC_1_12_Version => new EntityPalette112(),
|
||||
>= MC_1_11_Version => new EntityPalette112(),
|
||||
_ => new EntityPalette18()
|
||||
};
|
||||
|
||||
|
|
@ -2968,7 +2969,9 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
double y = dataTypes.ReadNextInt(packetData) / 8.0D;
|
||||
double z = dataTypes.ReadNextInt(packetData) / 8.0D;
|
||||
float volume = dataTypes.ReadNextFloat(packetData);
|
||||
float pitch = dataTypes.ReadNextFloat(packetData);
|
||||
float pitch = protocolVersion < MC_1_10_Version
|
||||
? dataTypes.ReadNextByte(packetData) / 63.0f
|
||||
: dataTypes.ReadNextFloat(packetData);
|
||||
|
||||
handler.OnSoundEffect(soundName, new Location(x, y, z), category, volume, pitch, null);
|
||||
break;
|
||||
|
|
@ -2989,7 +2992,9 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
double y = dataTypes.ReadNextInt(packetData) / 8.0D;
|
||||
double z = dataTypes.ReadNextInt(packetData) / 8.0D;
|
||||
float volume = dataTypes.ReadNextFloat(packetData);
|
||||
float pitch = dataTypes.ReadNextFloat(packetData);
|
||||
float pitch = protocolVersion < MC_1_10_Version
|
||||
? dataTypes.ReadNextByte(packetData) / 63.0f
|
||||
: dataTypes.ReadNextFloat(packetData);
|
||||
|
||||
if (protocolVersion >= MC_1_19_Version)
|
||||
dataTypes.ReadNextLong(packetData); // Seed
|
||||
|
|
@ -5502,10 +5507,9 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
playerInventory.Items.TryGetValue(slotWindowIds[currentSlot], out var item);
|
||||
packet.AddRange(dataTypes.GetItemSlot(item, itemPalette));
|
||||
|
||||
packet.Add(0); // cursorX
|
||||
packet.Add(0); // cursorY
|
||||
packet.Add(0); // cursorZ
|
||||
AddLegacyBlockPlacementCursor(packet, cursorX, cursorY, cursorZ);
|
||||
|
||||
SendPacket(PacketTypesOut.PlayerBlockPlacement, packet);
|
||||
return true;
|
||||
case < MC_1_14_Version:
|
||||
packet.AddRange(dataTypes.GetLocation(location));
|
||||
|
|
@ -5519,9 +5523,14 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
break;
|
||||
}
|
||||
|
||||
packet.AddRange(dataTypes.GetFloat(cursorX)); // cursorX
|
||||
packet.AddRange(dataTypes.GetFloat(cursorY)); // cursorY
|
||||
packet.AddRange(dataTypes.GetFloat(cursorZ)); // cursorZ
|
||||
if (protocolVersion < MC_1_11_Version)
|
||||
AddLegacyBlockPlacementCursor(packet, cursorX, cursorY, cursorZ);
|
||||
else
|
||||
{
|
||||
packet.AddRange(dataTypes.GetFloat(cursorX)); // cursorX
|
||||
packet.AddRange(dataTypes.GetFloat(cursorY)); // cursorY
|
||||
packet.AddRange(dataTypes.GetFloat(cursorZ)); // cursorZ
|
||||
}
|
||||
|
||||
if (protocolVersion >= MC_1_14_Version)
|
||||
packet.Add(0); // insideBlock = false
|
||||
|
|
@ -5560,6 +5569,18 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
_ => (0.5f, 0.5f, 0.5f),
|
||||
};
|
||||
|
||||
private static void AddLegacyBlockPlacementCursor(List<byte> packet, float cursorX, float cursorY, float cursorZ)
|
||||
{
|
||||
packet.Add(ToLegacyBlockPlacementCursor(cursorX));
|
||||
packet.Add(ToLegacyBlockPlacementCursor(cursorY));
|
||||
packet.Add(ToLegacyBlockPlacementCursor(cursorZ));
|
||||
}
|
||||
|
||||
private static byte ToLegacyBlockPlacementCursor(float cursor)
|
||||
{
|
||||
return (byte)Math.Clamp((int)(cursor * 16.0f), 0, byte.MaxValue);
|
||||
}
|
||||
|
||||
public bool SendHeldItemChange(short slot)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -1221,6 +1221,15 @@ namespace MinecraftClient {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} is only available in Minecraft {1} and newer!.
|
||||
/// </summary>
|
||||
internal static string bot_farmer_crop_unavailable {
|
||||
get {
|
||||
return ResourceManager.GetString("bot.farmer.crop_unavailable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Farming bot.
|
||||
/// </summary>
|
||||
|
|
@ -1267,7 +1276,7 @@ namespace MinecraftClient {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Not implemented bellow 1.13!.
|
||||
/// Looks up a localized string similar to Not implemented below 1.8!.
|
||||
/// </summary>
|
||||
internal static string bot_farmer_not_implemented {
|
||||
get {
|
||||
|
|
|
|||
|
|
@ -505,6 +505,9 @@ cooldown: {6}</value>
|
|||
<data name="bot.farmer.crop_type" xml:space="preserve">
|
||||
<value>Crop type</value>
|
||||
</data>
|
||||
<data name="bot.farmer.crop_unavailable" xml:space="preserve">
|
||||
<value>{0} is only available in Minecraft {1} and newer!</value>
|
||||
</data>
|
||||
<data name="bot.farmer.desc" xml:space="preserve">
|
||||
<value>Farming bot</value>
|
||||
</data>
|
||||
|
|
@ -521,7 +524,7 @@ cooldown: {6}</value>
|
|||
<value>The Farmer bot needs Terrain Handling in order to work, please enable it!</value>
|
||||
</data>
|
||||
<data name="bot.farmer.not_implemented" xml:space="preserve">
|
||||
<value>Not implemented bellow 1.13!</value>
|
||||
<value>Not implemented below 1.8!</value>
|
||||
</data>
|
||||
<data name="bot.farmer.radius" xml:space="preserve">
|
||||
<value>Radius</value>
|
||||
|
|
|
|||
|
|
@ -1562,10 +1562,11 @@ namespace MinecraftClient.Scripting
|
|||
/// <param name="location">Location to place block to</param>
|
||||
/// <param name="blockFace">Block face (e.g. Direction.Down when clicking on the block below to place this block)</param>
|
||||
/// <param name="hand">Hand.MainHand or Hand.OffHand</param>
|
||||
/// <param name="lookAtBlock">Also look at the block before interacting</param>
|
||||
/// <returns>TRUE if successfully placed</returns>
|
||||
public bool SendPlaceBlock(Location location, Direction blockFace, Hand hand = Hand.MainHand)
|
||||
public bool SendPlaceBlock(Location location, Direction blockFace, Hand hand = Hand.MainHand, bool lookAtBlock = false)
|
||||
{
|
||||
return Handler.PlaceBlock(location, blockFace, hand);
|
||||
return Handler.PlaceBlock(location, blockFace, hand, lookAtBlock);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1957,7 +1957,7 @@ redirectFrom:
|
|||
|
||||
<div class="custom-container warning"><p class="custom-container-title">Warning</p>
|
||||
|
||||
**This a newly added bot, it is not perfect and was only tested in 1.19.2, there are some minor issues with it and you should treat it as an experimental bot.**
|
||||
**This bot is still experimental, has some known issues, and should be treated with extra caution on legacy versions.**
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -1976,6 +1976,8 @@ redirectFrom:
|
|||
- Potato
|
||||
- Wheat
|
||||
|
||||
Beetroot farming requires Minecraft `1.9+`.
|
||||
|
||||
**Current list of issues:**
|
||||
|
||||
- Sometimes the bot will not bone meal carrots/potatoes or melon/pumpkin stems (you will see it in a pattern of crops that have not been bonemealed)
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ Coordinate = { x = 145, y = 64, z = 2045 }
|
|||
|
||||
<div class="custom-container warning"><p class="custom-container-title">Warning</p>
|
||||
|
||||
**This feature is currently not supported in `1.4.6 - 1.9`. But we are working on getting it supported in 1.8 and 1.9.**
|
||||
**This feature is currently supported on `1.8+` and is unavailable on `1.4.6 - 1.7.10`.**
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1016,7 +1016,7 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q
|
|||
|
||||
<div class="custom-container warning"><p class="custom-container-title">Warning</p>
|
||||
|
||||
**The [Inventory Handling](configuration.md#inventoryhandling) is currently not supported in `1.4.6 - 1.9`**
|
||||
**The [Inventory Handling](configuration.md#inventoryhandling) is currently supported on `1.8+` and is unavailable on `1.4.6 - 1.7.10`.**
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -1063,7 +1063,7 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q
|
|||
|
||||
<div class="custom-container warning"><p class="custom-container-title">Warning</p>
|
||||
|
||||
**The [Inventory Handling](configuration.md#inventoryhandling) is currently not supported in `1.4.6 - 1.9`.**
|
||||
**The [Inventory Handling](configuration.md#inventoryhandling) is currently supported on `1.8+` and is unavailable on `1.4.6 - 1.7.10`.**
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -1298,7 +1298,7 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q
|
|||
|
||||
<div class="custom-container warning"><p class="custom-container-title">Warning</p>
|
||||
|
||||
**The [Inventory Handling](configuration.md#inventoryhandling) is currently not supported in `1.4.6 - 1.9`.**
|
||||
**The [Inventory Handling](configuration.md#inventoryhandling) is currently supported on `1.8+` and is unavailable on `1.4.6 - 1.7.10`.**
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue