mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Added slab handling for 1.20/.1
Added Farm bot crops handling for 1.20/.1 Added utilities for Containers/Inventories Added bot movement lock to prevent multiple bots that use movements from running at the same time. General code improvements.
This commit is contained in:
parent
497a1174de
commit
272900d52e
11 changed files with 941 additions and 797 deletions
|
|
@ -8,7 +8,6 @@ namespace MinecraftClient.ChatBots
|
|||
/// <summary>
|
||||
/// This bot sends a command every 60 seconds in order to stay non-afk.
|
||||
/// </summary>
|
||||
|
||||
public class AntiAFK : ChatBot
|
||||
{
|
||||
public static Configs Config = new();
|
||||
|
|
@ -16,8 +15,7 @@ namespace MinecraftClient.ChatBots
|
|||
[TomlDoNotInlineObject]
|
||||
public class Configs
|
||||
{
|
||||
[NonSerialized]
|
||||
private const string BotName = "AntiAFK";
|
||||
[NonSerialized] private const string BotName = "AntiAFK";
|
||||
|
||||
public bool Enabled = false;
|
||||
|
||||
|
|
@ -99,6 +97,13 @@ namespace MinecraftClient.ChatBots
|
|||
{
|
||||
LogToConsole(Translations.bot_antiafk_not_using_terrain_handling);
|
||||
}
|
||||
else
|
||||
{
|
||||
var movementLock = BotMovementLock.Instance;
|
||||
if (movementLock is { IsLocked: true })
|
||||
LogToConsole(
|
||||
$"§§6§1§0{string.Format(Translations.bot_antiafk_may_not_move, movementLock.LockedBy)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,25 +111,22 @@ namespace MinecraftClient.ChatBots
|
|||
{
|
||||
count++;
|
||||
|
||||
if (count >= nextrun)
|
||||
{
|
||||
if (count < nextrun) return;
|
||||
DoAntiAfkStuff();
|
||||
count = 0;
|
||||
nextrun = random.Next(Settings.DoubleToTick(Config.Delay.min), Settings.DoubleToTick(Config.Delay.max));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void DoAntiAfkStuff()
|
||||
{
|
||||
if (Config.Use_Terrain_Handling && GetTerrainEnabled())
|
||||
var isMovementLocked = BotMovementLock.Instance;
|
||||
if (Config.Use_Terrain_Handling && GetTerrainEnabled() && isMovementLocked is {IsLocked: false})
|
||||
{
|
||||
Location currentLocation = GetCurrentLocation();
|
||||
Location goal;
|
||||
var currentLocation = GetCurrentLocation();
|
||||
|
||||
bool moved = false;
|
||||
bool useAlternativeMethod = false;
|
||||
int triesCounter = 0;
|
||||
var moved = false;
|
||||
var useAlternativeMethod = false;
|
||||
var triesCounter = 0;
|
||||
|
||||
while (!moved)
|
||||
{
|
||||
|
|
@ -134,10 +136,11 @@ namespace MinecraftClient.ChatBots
|
|||
break;
|
||||
}
|
||||
|
||||
goal = GetRandomLocationWithinRangeXZ(currentLocation, Config.Walk_Range);
|
||||
var goal = GetRandomLocationWithinRangeXZ(currentLocation, Config.Walk_Range);
|
||||
|
||||
// Prevent getting the same location
|
||||
while ((currentLocation.X == goal.X) && (currentLocation.Y == goal.Y) && (currentLocation.Z == goal.Z))
|
||||
while ((currentLocation.X == goal.X) && (currentLocation.Y == goal.Y) &&
|
||||
(currentLocation.Z == goal.Z))
|
||||
{
|
||||
LogToConsole("Same location!, generating new one");
|
||||
goal = GetRandomLocationWithinRangeXZ(currentLocation, Config.Walk_Range);
|
||||
|
|
@ -148,11 +151,9 @@ namespace MinecraftClient.ChatBots
|
|||
useAlternativeMethod = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
moved = MoveToLocation(goal, allowUnsafe: false, allowDirectTeleport: false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!useAlternativeMethod && Config.Use_Sneak)
|
||||
{
|
||||
|
|
@ -169,12 +170,14 @@ namespace MinecraftClient.ChatBots
|
|||
Sneak(previousSneakState);
|
||||
previousSneakState = !previousSneakState;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
}
|
||||
|
||||
private Location GetRandomLocationWithinRangeXZ(Location currentLocation, int range)
|
||||
{
|
||||
return new Location(currentLocation.X + random.Next(range * -1, range), currentLocation.Y, currentLocation.Z + random.Next(range * -1, range));
|
||||
return new Location(currentLocation.X + random.Next(range * -1, range), currentLocation.Y,
|
||||
currentLocation.Z + random.Next(range * -1, range));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ using Brigadier.NET;
|
|||
using Brigadier.NET.Builder;
|
||||
using MinecraftClient.CommandHandler;
|
||||
using MinecraftClient.CommandHandler.Patch;
|
||||
using MinecraftClient.Commands;
|
||||
using MinecraftClient.Inventory;
|
||||
using MinecraftClient.Mapping;
|
||||
using MinecraftClient.Protocol.Handlers;
|
||||
|
|
@ -24,8 +25,7 @@ namespace MinecraftClient.ChatBots
|
|||
[TomlDoNotInlineObject]
|
||||
public class Configs
|
||||
{
|
||||
[NonSerialized]
|
||||
private const string BotName = "Farmer";
|
||||
[NonSerialized] private const string BotName = "Farmer";
|
||||
|
||||
public bool Enabled = false;
|
||||
|
||||
|
|
@ -39,12 +39,12 @@ namespace MinecraftClient.ChatBots
|
|||
}
|
||||
}
|
||||
|
||||
public enum State
|
||||
private enum State
|
||||
{
|
||||
SearchingForCropsToBreak = 0,
|
||||
SearchingForFarmlandToPlant,
|
||||
PlantingCrops,
|
||||
BonemealingCrops
|
||||
BoneMealingCrops,
|
||||
CollectingItems
|
||||
}
|
||||
|
||||
public enum CropType
|
||||
|
|
@ -52,7 +52,7 @@ namespace MinecraftClient.ChatBots
|
|||
Beetroot,
|
||||
Carrot,
|
||||
Melon,
|
||||
Netherwart,
|
||||
NetherWart,
|
||||
Pumpkin,
|
||||
Potato,
|
||||
Wheat
|
||||
|
|
@ -66,9 +66,10 @@ namespace MinecraftClient.ChatBots
|
|||
private bool allowTeleport = false;
|
||||
private bool debugEnabled = false;
|
||||
|
||||
public int Delay_Between_Tasks_Millisecond => (int)Math.Round(Config.Delay_Between_Tasks * 1000);
|
||||
private int Delay_Between_Tasks_Millisecond => (int)Math.Round(Config.Delay_Between_Tasks * 1000);
|
||||
|
||||
private const string commandDescription = "farmer <start <crop type> [radius:<radius = 30>] [unsafe:<true/false>] [teleport:<true/false>] [debug:<true/false>]|stop>";
|
||||
private const string commandDescription =
|
||||
"farmer <start <crop type> [radius:<radius = 30>] [unsafe:<true/false>] [teleport:<true/false>] [debug:<true/false>]|stop>";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -103,7 +104,8 @@ namespace MinecraftClient.ChatBots
|
|||
.Then(l => l.Argument("CropType", MccArguments.FarmerCropType())
|
||||
.Executes(r => OnCommandStart(r.Source, MccArguments.GetFarmerCropType(r, "CropType"), null))
|
||||
.Then(l => l.Argument("OtherArgs", Arguments.GreedyString())
|
||||
.Executes(r => OnCommandStart(r.Source, MccArguments.GetFarmerCropType(r, "CropType"), Arguments.GetString(r, "OtherArgs"))))))
|
||||
.Executes(r => OnCommandStart(r.Source, MccArguments.GetFarmerCropType(r, "CropType"),
|
||||
Arguments.GetString(r, "OtherArgs"))))))
|
||||
.Then(l => l.Literal("_help")
|
||||
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||
|
|
@ -112,6 +114,8 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
public override void OnUnload()
|
||||
{
|
||||
running = false;
|
||||
BotMovementLock.Instance?.UnLock("Farmer");
|
||||
McClient.dispatcher.Unregister(CommandName);
|
||||
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||
}
|
||||
|
|
@ -145,7 +149,12 @@ namespace MinecraftClient.ChatBots
|
|||
if (running)
|
||||
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_farmer_already_running);
|
||||
|
||||
int radius = 30;
|
||||
var movementLock = BotMovementLock.Instance;
|
||||
if (movementLock is { IsLocked: true })
|
||||
return r.SetAndReturn(CmdResult.Status.Fail,
|
||||
string.Format(Translations.bot_common_movement_lock_held, "Farmer", movementLock.LockedBy));
|
||||
|
||||
var radius = 30;
|
||||
|
||||
state = State.SearchingForFarmlandToPlant;
|
||||
cropType = whatToFarm;
|
||||
|
|
@ -155,20 +164,22 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
if (!string.IsNullOrWhiteSpace(otherArgs))
|
||||
{
|
||||
string[] args = otherArgs.ToLower().Split(' ', StringSplitOptions.TrimEntries);
|
||||
foreach (string currentArg in args)
|
||||
var args = otherArgs.ToLower().Split(' ', StringSplitOptions.TrimEntries);
|
||||
foreach (var currentArg in args)
|
||||
{
|
||||
if (!currentArg.Contains(':'))
|
||||
{
|
||||
LogToConsole("§§6§1§0" + string.Format(Translations.bot_farmer_warining_invalid_parameter, currentArg));
|
||||
LogToConsole(
|
||||
$"§§6§1§0{string.Format(Translations.bot_farmer_warining_invalid_parameter, currentArg)}");
|
||||
continue;
|
||||
}
|
||||
|
||||
string[] parts = currentArg.Split(":", StringSplitOptions.TrimEntries);
|
||||
var parts = currentArg.Split(":", StringSplitOptions.TrimEntries);
|
||||
|
||||
if (parts.Length != 2)
|
||||
{
|
||||
LogToConsole("§§6§1§0" + string.Format(Translations.bot_farmer_warining_invalid_parameter, currentArg));
|
||||
LogToConsole(
|
||||
$"§§6§1§0{string.Format(Translations.bot_farmer_warining_invalid_parameter, currentArg)}");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -177,11 +188,11 @@ namespace MinecraftClient.ChatBots
|
|||
case "r":
|
||||
case "radius":
|
||||
if (!int.TryParse(parts[1], NumberStyles.Any, CultureInfo.CurrentCulture, out radius))
|
||||
LogToConsole("§§6§1§0" + Translations.bot_farmer_invalid_radius);
|
||||
LogToConsole($"§§6§1§0{Translations.bot_farmer_invalid_radius}");
|
||||
|
||||
if (radius <= 0)
|
||||
{
|
||||
LogToConsole("§§6§1§0" + Translations.bot_farmer_invalid_radius);
|
||||
LogToConsole($"§§6§1§0{Translations.bot_farmer_invalid_radius}");
|
||||
radius = 30;
|
||||
}
|
||||
|
||||
|
|
@ -194,7 +205,7 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
if (parts[1].Equals("true") || parts[1].Equals("1"))
|
||||
{
|
||||
LogToConsole("§§6§1§0" + Translations.bot_farmer_warining_force_unsafe);
|
||||
LogToConsole($"§§6§1§0{Translations.bot_farmer_warining_force_unsafe}");
|
||||
allowUnsafe = true;
|
||||
}
|
||||
else allowUnsafe = false;
|
||||
|
|
@ -208,7 +219,7 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
if (parts[1].Equals("true") || parts[1].Equals("1"))
|
||||
{
|
||||
LogToConsole("§§4§1§f" + Translations.bot_farmer_warining_allow_teleport);
|
||||
LogToConsole($"§§4§1§f{Translations.bot_farmer_warining_allow_teleport}");
|
||||
allowTeleport = true;
|
||||
}
|
||||
else allowTeleport = false;
|
||||
|
|
@ -234,27 +245,57 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
farmingRadius = radius;
|
||||
running = true;
|
||||
new Thread(() => MainPorcess()).Start();
|
||||
new Thread(() => MainProcess()).Start();
|
||||
|
||||
return r.SetAndReturn(CmdResult.Status.Done);
|
||||
}
|
||||
|
||||
public override void AfterGameJoined()
|
||||
{
|
||||
BotMovementLock.Instance?.UnLock("Farmer");
|
||||
running = false;
|
||||
}
|
||||
|
||||
public override bool OnDisconnect(DisconnectReason reason, string message)
|
||||
{
|
||||
BotMovementLock.Instance?.UnLock("Farmer");
|
||||
running = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void MainPorcess()
|
||||
private void MainProcess()
|
||||
{
|
||||
LogToConsole("§§2§1§f" + Translations.bot_farmer_started);
|
||||
LogToConsole("§§2§1§f " + Translations.bot_farmer_crop_type + ": " + cropType);
|
||||
LogToConsole("§§2§1§f " + Translations.bot_farmer_radius + ": " + farmingRadius);
|
||||
var movementLock = BotMovementLock.Instance;
|
||||
switch (movementLock)
|
||||
{
|
||||
case { IsLocked: false }:
|
||||
if (!movementLock.Lock("Farmer"))
|
||||
{
|
||||
running = false;
|
||||
LogToConsole($"§§6§1§0Farmer bot failed to obtain the movement lock for some reason!");
|
||||
LogToConsole($"§§6§1§0Disable other bots who have movement mechanics, and try again!");
|
||||
return;
|
||||
}
|
||||
|
||||
LogDebug($"Locked the movement for other bots!");
|
||||
break;
|
||||
case { IsLocked: true }:
|
||||
running = false;
|
||||
LogToConsole($"§§6§1§0Farmer bot failed to obtain the movement lock for some reason!");
|
||||
LogToConsole($"§§6§1§0Disable other bots who have movement mechanics, and try again!");
|
||||
return;
|
||||
}
|
||||
|
||||
LogToConsole($"§§2§1§f{Translations.bot_farmer_started}");
|
||||
LogToConsole($"§§2§1§f {Translations.bot_farmer_crop_type}: {cropType}");
|
||||
LogToConsole($"§§2§1§f {Translations.bot_farmer_radius}: {farmingRadius}");
|
||||
|
||||
var itemTypes = new List<ItemType>
|
||||
{
|
||||
GetSeedItemTypeForCropType(cropType),
|
||||
GetCropItemTypeForCropType(cropType)
|
||||
};
|
||||
itemTypes = itemTypes.Distinct().ToList();
|
||||
|
||||
while (running)
|
||||
{
|
||||
|
|
@ -271,7 +312,7 @@ namespace MinecraftClient.ChatBots
|
|||
case State.SearchingForFarmlandToPlant:
|
||||
LogDebug("Looking for farmland...");
|
||||
|
||||
ItemType cropTypeToPlant = GetSeedItemTypeForCropType(cropType);
|
||||
var cropTypeToPlant = GetSeedItemTypeForCropType(cropType);
|
||||
|
||||
// If we don't have any seeds on our hot bar, skip this step and try collecting some
|
||||
if (!SwitchToItem(cropTypeToPlant))
|
||||
|
|
@ -282,7 +323,7 @@ namespace MinecraftClient.ChatBots
|
|||
continue;
|
||||
}
|
||||
|
||||
List<Location> farmlandToPlantOn = findEmptyFarmland(farmingRadius);
|
||||
var farmlandToPlantOn = FindEmptyFarmland(farmingRadius);
|
||||
|
||||
if (farmlandToPlantOn.Count == 0)
|
||||
{
|
||||
|
|
@ -292,11 +333,9 @@ namespace MinecraftClient.ChatBots
|
|||
continue;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
foreach (Location location in farmlandToPlantOn)
|
||||
var i = 0;
|
||||
foreach (var location in farmlandToPlantOn.TakeWhile(location => running))
|
||||
{
|
||||
if (!running) break;
|
||||
|
||||
// Check only every second iteration, minor optimization xD
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
|
|
@ -309,14 +348,15 @@ namespace MinecraftClient.ChatBots
|
|||
}
|
||||
}
|
||||
|
||||
double yValue = Math.Floor(location.Y) + 1;
|
||||
var yValue = Math.Floor(location.Y) + 1;
|
||||
|
||||
// TODO: Figure out why this is not working.
|
||||
// Why we need this: sometimes the server kicks the player for "invalid movement" packets.
|
||||
/*if (cropType == CropType.Netherwart)
|
||||
/*if (cropType == CropType.NetherWart)
|
||||
yValue = (double)(Math.Floor(location.Y) - 1.0) + (double)0.87500;*/
|
||||
|
||||
Location location2 = new Location(Math.Floor(location.X) + 0.5, yValue, Math.Floor(location.Z) + 0.5);
|
||||
var location2 = new Location(Math.Floor(location.X) + 0.5, yValue,
|
||||
Math.Floor(location.Z) + 0.5);
|
||||
|
||||
if (WaitForMoveToLocation(location2))
|
||||
{
|
||||
|
|
@ -329,7 +369,8 @@ namespace MinecraftClient.ChatBots
|
|||
break;
|
||||
}
|
||||
|
||||
Location loc = new Location(Math.Floor(location.X), Math.Floor(location2.Y), Math.Floor(location.Z));
|
||||
var loc = new Location(Math.Floor(location.X), Math.Floor(location2.Y),
|
||||
Math.Floor(location.Z));
|
||||
LogDebug("Sending placeblock to: " + loc);
|
||||
|
||||
SendPlaceBlock(loc, Direction.Up);
|
||||
|
|
@ -347,21 +388,21 @@ namespace MinecraftClient.ChatBots
|
|||
case State.SearchingForCropsToBreak:
|
||||
LogDebug("Searching for crops to break...");
|
||||
|
||||
List<Location> cropsToCollect = findCrops(farmingRadius, cropType, true);
|
||||
var cropsToCollect = findCrops(farmingRadius, cropType, true);
|
||||
|
||||
if (cropsToCollect.Count == 0)
|
||||
{
|
||||
LogToConsole("No crops to break, trying to bonemeal ungrown ones");
|
||||
state = State.BonemealingCrops;
|
||||
LogToConsole("No crops to break, trying to bone meal un-grown ones");
|
||||
state = State.BoneMealingCrops;
|
||||
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Switch to an axe for faster breaking if the bot has one in his inventory
|
||||
if (cropType == CropType.Melon || cropType == CropType.Pumpkin)
|
||||
if (cropType is CropType.Melon or CropType.Pumpkin)
|
||||
{
|
||||
// Start from Diamond axe, if not found, try a tier lower axe
|
||||
bool switched = SwitchToItem(ItemType.DiamondAxe);
|
||||
var switched = SwitchToItem(ItemType.DiamondAxe);
|
||||
|
||||
if (!switched)
|
||||
switched = SwitchToItem(ItemType.IronAxe);
|
||||
|
|
@ -373,10 +414,8 @@ namespace MinecraftClient.ChatBots
|
|||
SwitchToItem(ItemType.StoneAxe);
|
||||
}
|
||||
|
||||
foreach (Location location in cropsToCollect)
|
||||
foreach (var location in cropsToCollect.TakeWhile(location => running))
|
||||
{
|
||||
if (!running) break;
|
||||
|
||||
// God damn C# rounding it to 0.94
|
||||
// This will be needed when bot bone meals carrots or potatoes which are at the first stage of growth,
|
||||
// because sometimes the bot walks over crops and breaks them
|
||||
|
|
@ -387,16 +426,16 @@ namespace MinecraftClient.ChatBots
|
|||
WaitForDigBlock(location);
|
||||
|
||||
// Allow some time to pickup the item
|
||||
Thread.Sleep(cropType == CropType.Melon || cropType == CropType.Pumpkin ? 400 : 200);
|
||||
Thread.Sleep(cropType is CropType.Melon or CropType.Pumpkin ? 400 : 200);
|
||||
}
|
||||
|
||||
LogDebug("Finished breaking crops!");
|
||||
state = State.BonemealingCrops;
|
||||
state = State.BoneMealingCrops;
|
||||
break;
|
||||
|
||||
case State.BonemealingCrops:
|
||||
case State.BoneMealingCrops:
|
||||
// Can't be bone mealed
|
||||
if (cropType == CropType.Netherwart)
|
||||
if (cropType == CropType.NetherWart)
|
||||
{
|
||||
state = State.SearchingForFarmlandToPlant;
|
||||
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||
|
|
@ -412,7 +451,7 @@ namespace MinecraftClient.ChatBots
|
|||
continue;
|
||||
}
|
||||
|
||||
List<Location> cropsToBonemeal = findCrops(farmingRadius, cropType, false);
|
||||
var cropsToBonemeal = findCrops(farmingRadius, cropType, false);
|
||||
|
||||
if (cropsToBonemeal.Count == 0)
|
||||
{
|
||||
|
|
@ -422,11 +461,9 @@ namespace MinecraftClient.ChatBots
|
|||
continue;
|
||||
}
|
||||
|
||||
int i2 = 0;
|
||||
foreach (Location location in cropsToBonemeal)
|
||||
var i2 = 0;
|
||||
foreach (var location in cropsToBonemeal.TakeWhile(location => running))
|
||||
{
|
||||
if (!running) break;
|
||||
|
||||
// Check only every second iteration, minor optimization xD
|
||||
if (i2 % 2 == 0)
|
||||
{
|
||||
|
|
@ -448,11 +485,14 @@ namespace MinecraftClient.ChatBots
|
|||
break;
|
||||
}
|
||||
|
||||
Location location2 = new Location(Math.Floor(location.X) + 0.5, location.Y, Math.Floor(location.Z) + 0.5);
|
||||
var location2 = new Location(Math.Floor(location.X) + 0.5, location.Y,
|
||||
Math.Floor(location.Z) + 0.5);
|
||||
LogDebug("Trying to bone meal: " + location2);
|
||||
|
||||
// Send like 4 bone meal attempts, it should do the job with 2-3, but sometimes doesn't do
|
||||
for (int boneMealTimes = 0; boneMealTimes < (cropType == CropType.Beetroot ? 6 : 5); boneMealTimes++)
|
||||
for (var boneMealTimes = 0;
|
||||
boneMealTimes < (cropType == CropType.Beetroot ? 6 : 5);
|
||||
boneMealTimes++)
|
||||
{
|
||||
// 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)
|
||||
|
|
@ -466,99 +506,117 @@ namespace MinecraftClient.ChatBots
|
|||
}
|
||||
|
||||
LogDebug("Finished bone mealing crops!");
|
||||
state = State.CollectingItems;
|
||||
break;
|
||||
|
||||
case State.CollectingItems:
|
||||
LogDebug("Searching for items to collect...");
|
||||
|
||||
var currentLocation = GetCurrentLocation();
|
||||
var items = GetEntities()
|
||||
.Where(x =>
|
||||
x.Value.Type == EntityType.Item &&
|
||||
x.Value.Location.Distance(currentLocation) <= farmingRadius &&
|
||||
itemTypes.Contains(x.Value.Item.Type))
|
||||
.Select(x => x.Value)
|
||||
.ToList();
|
||||
items = items.OrderBy(x => x.Location.Distance(currentLocation)).ToList();
|
||||
|
||||
if (items.Any())
|
||||
{
|
||||
LogDebug("Collecting items...");
|
||||
|
||||
foreach (var entity in items.TakeWhile(entity => running))
|
||||
WaitForMoveToLocation(entity.Location);
|
||||
|
||||
LogDebug("Finished collecting items!");
|
||||
}
|
||||
else LogDebug("No items to collect!");
|
||||
|
||||
state = State.SearchingForFarmlandToPlant;
|
||||
break;
|
||||
}
|
||||
|
||||
LogDebug(string.Format("Waiting for {0:0.00} seconds for next cycle.", Config.Delay_Between_Tasks));
|
||||
LogDebug($"Waiting for {Config.Delay_Between_Tasks:0.00} seconds for next cycle.");
|
||||
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||
}
|
||||
|
||||
movementLock?.UnLock("Farmer");
|
||||
LogDebug($"Unlocked the movement for other bots!");
|
||||
LogToConsole(Translations.bot_farmer_stopped);
|
||||
}
|
||||
|
||||
private Material GetMaterialForCropType(CropType type)
|
||||
private static Material GetMaterialForCropType(CropType type)
|
||||
{
|
||||
switch (type)
|
||||
return type switch
|
||||
{
|
||||
case CropType.Beetroot:
|
||||
return Material.Beetroots;
|
||||
|
||||
case CropType.Carrot:
|
||||
return Material.Carrots;
|
||||
|
||||
case CropType.Melon:
|
||||
return Material.Melon;
|
||||
|
||||
case CropType.Netherwart:
|
||||
return Material.NetherWart;
|
||||
|
||||
case CropType.Pumpkin:
|
||||
return Material.Pumpkin;
|
||||
|
||||
case CropType.Potato:
|
||||
return Material.Potatoes;
|
||||
|
||||
case CropType.Wheat:
|
||||
return Material.Wheat;
|
||||
CropType.Beetroot => Material.Beetroots,
|
||||
CropType.Carrot => Material.Carrots,
|
||||
CropType.Melon => Material.Melon,
|
||||
CropType.NetherWart => Material.NetherWart,
|
||||
CropType.Pumpkin => Material.Pumpkin,
|
||||
CropType.Potato => Material.Potatoes,
|
||||
CropType.Wheat => Material.Wheat,
|
||||
_ => throw new Exception("Material type for " + type.GetType().Name + " has not been mapped!")
|
||||
};
|
||||
}
|
||||
|
||||
throw new Exception("Material type for " + type.GetType().Name + " has not been mapped!");
|
||||
}
|
||||
|
||||
private ItemType GetSeedItemTypeForCropType(CropType type)
|
||||
private static ItemType GetSeedItemTypeForCropType(CropType type)
|
||||
{
|
||||
switch (type)
|
||||
return type switch
|
||||
{
|
||||
case CropType.Beetroot:
|
||||
return ItemType.BeetrootSeeds;
|
||||
|
||||
case CropType.Carrot:
|
||||
return ItemType.Carrot;
|
||||
|
||||
case CropType.Melon:
|
||||
return ItemType.MelonSeeds;
|
||||
|
||||
case CropType.Netherwart:
|
||||
return ItemType.NetherWart;
|
||||
|
||||
case CropType.Pumpkin:
|
||||
return ItemType.PumpkinSeeds;
|
||||
|
||||
case CropType.Potato:
|
||||
return ItemType.Potato;
|
||||
|
||||
case CropType.Wheat:
|
||||
return ItemType.WheatSeeds;
|
||||
CropType.Beetroot => ItemType.BeetrootSeeds,
|
||||
CropType.Carrot => ItemType.Carrot,
|
||||
CropType.Melon => ItemType.MelonSeeds,
|
||||
CropType.NetherWart => ItemType.NetherWart,
|
||||
CropType.Pumpkin => ItemType.PumpkinSeeds,
|
||||
CropType.Potato => ItemType.Potato,
|
||||
CropType.Wheat => ItemType.WheatSeeds,
|
||||
_ => throw new Exception("Seed type for " + type.GetType().Name + " has not been mapped!")
|
||||
};
|
||||
}
|
||||
|
||||
throw new Exception("Seed type for " + type.GetType().Name + " has not been mapped!");
|
||||
private static ItemType GetCropItemTypeForCropType(CropType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
CropType.Beetroot => ItemType.Beetroot,
|
||||
CropType.Carrot => ItemType.Carrot,
|
||||
CropType.Melon => ItemType.Melon,
|
||||
CropType.NetherWart => ItemType.NetherWart,
|
||||
CropType.Pumpkin => ItemType.Pumpkin,
|
||||
CropType.Potato => ItemType.Potato,
|
||||
CropType.Wheat => ItemType.Wheat,
|
||||
_ => throw new Exception("Item type for " + type.GetType().Name + " has not been mapped!")
|
||||
};
|
||||
}
|
||||
|
||||
private List<Location> findEmptyFarmland(int radius)
|
||||
private List<Location> FindEmptyFarmland(int radius)
|
||||
{
|
||||
return GetWorld()
|
||||
.FindBlock(GetCurrentLocation(), cropType == CropType.Netherwart ? Material.SoulSand : Material.Farmland, radius)
|
||||
.Where(location => GetWorld().GetBlock(new Location(location.X, location.Y + 1, location.Z)).Type == Material.Air)
|
||||
.FindBlock(GetCurrentLocation(),
|
||||
cropType == CropType.NetherWart ? Material.SoulSand : Material.Farmland, radius)
|
||||
.Where(location => GetWorld().GetBlock(new Location(location.X, location.Y + 1, location.Z)).Type ==
|
||||
Material.Air)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private List<Location> findCrops(int radius, CropType cropType, bool fullyGrown)
|
||||
{
|
||||
Material material = GetMaterialForCropType(cropType);
|
||||
var material = GetMaterialForCropType(cropType);
|
||||
|
||||
// A bit of a hack to enable bone mealing melon and pumpkin stems
|
||||
if (!fullyGrown && (cropType == CropType.Melon || cropType == CropType.Pumpkin))
|
||||
if (!fullyGrown && cropType is CropType.Melon or CropType.Pumpkin)
|
||||
material = cropType == CropType.Melon ? Material.MelonStem : Material.PumpkinStem;
|
||||
|
||||
return GetWorld()
|
||||
.FindBlock(GetCurrentLocation(), material, radius)
|
||||
.Where(location =>
|
||||
{
|
||||
if (fullyGrown && (material == Material.Melon || material == Material.Pumpkin))
|
||||
if (fullyGrown && material is Material.Melon or Material.Pumpkin)
|
||||
return true;
|
||||
|
||||
bool isFullyGrown = IsCropFullyGrown(GetWorld().GetBlock(location), cropType);
|
||||
var isFullyGrown = IsCropFullyGrown(GetWorld().GetBlock(location), cropType);
|
||||
return fullyGrown ? isFullyGrown : !isFullyGrown;
|
||||
})
|
||||
.ToList();
|
||||
|
|
@ -566,83 +624,47 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
private bool IsCropFullyGrown(Block block, CropType cropType)
|
||||
{
|
||||
int protocolVersion = GetProtocolVersion();
|
||||
var protocolVersion = GetProtocolVersion();
|
||||
|
||||
switch (cropType)
|
||||
{
|
||||
case CropType.Beetroot:
|
||||
if (protocolVersion == Protocol18Handler.MC_1_19_4_Version)
|
||||
switch (protocolVersion)
|
||||
{
|
||||
if (block.BlockId == 12356)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion == Protocol18Handler.MC_1_19_3_Version)
|
||||
{
|
||||
if (block.BlockId == 11887)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_19_Version && protocolVersion <= Protocol18Handler.MC_1_19_2_Version)
|
||||
{
|
||||
if (block.BlockId == 10103)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_17_Version && protocolVersion <= Protocol18Handler.MC_1_18_2_Version)
|
||||
{
|
||||
if (block.BlockId == 9472)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_16_Version && protocolVersion <= Protocol18Handler.MC_1_16_5_Version)
|
||||
{
|
||||
if (block.BlockId == 9226)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_14_Version && protocolVersion <= Protocol18Handler.MC_1_15_2_Version)
|
||||
{
|
||||
if (block.BlockId == 8686)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_13_Version && protocolVersion < Protocol18Handler.MC_1_14_Version)
|
||||
{
|
||||
if (block.BlockId == 8162)
|
||||
case Protocol18Handler.MC_1_20_Version when block.BlockId == 12371:
|
||||
case Protocol18Handler.MC_1_19_4_Version when block.BlockId == 12356:
|
||||
case Protocol18Handler.MC_1_19_3_Version when block.BlockId == 11887:
|
||||
case >= Protocol18Handler.MC_1_19_Version and <= Protocol18Handler.MC_1_19_2_Version
|
||||
when block.BlockId == 10103:
|
||||
case >= Protocol18Handler.MC_1_17_Version and <= Protocol18Handler.MC_1_18_2_Version
|
||||
when block.BlockId == 9472:
|
||||
case >= Protocol18Handler.MC_1_16_Version and <= Protocol18Handler.MC_1_16_5_Version
|
||||
when block.BlockId == 9226:
|
||||
case >= Protocol18Handler.MC_1_14_Version and <= Protocol18Handler.MC_1_15_2_Version
|
||||
when block.BlockId == 8686:
|
||||
case >= Protocol18Handler.MC_1_13_Version and < Protocol18Handler.MC_1_14_Version
|
||||
when block.BlockId == 8162:
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CropType.Carrot:
|
||||
if (protocolVersion == Protocol18Handler.MC_1_19_4_Version)
|
||||
switch (protocolVersion)
|
||||
{
|
||||
if (block.BlockId == 8598)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion == Protocol18Handler.MC_1_19_3_Version)
|
||||
{
|
||||
if (block.BlockId == 8370)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_19_Version && protocolVersion <= Protocol18Handler.MC_1_19_2_Version)
|
||||
{
|
||||
if (block.BlockId == 6930)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_17_Version && protocolVersion <= Protocol18Handler.MC_1_18_2_Version)
|
||||
{
|
||||
if (block.BlockId == 6543)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_16_Version && protocolVersion <= Protocol18Handler.MC_1_16_5_Version)
|
||||
{
|
||||
if (block.BlockId == 6341)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_14_Version && protocolVersion <= Protocol18Handler.MC_1_15_2_Version)
|
||||
{
|
||||
if (block.BlockId == 5801)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_13_Version && protocolVersion < Protocol18Handler.MC_1_14_Version)
|
||||
{
|
||||
if (block.BlockId == 5295)
|
||||
case Protocol18Handler.MC_1_20_Version when block.BlockId == 8602:
|
||||
case Protocol18Handler.MC_1_19_4_Version when block.BlockId == 8598:
|
||||
case Protocol18Handler.MC_1_19_3_Version when block.BlockId == 8370:
|
||||
case >= Protocol18Handler.MC_1_19_Version and <= Protocol18Handler.MC_1_19_2_Version
|
||||
when block.BlockId == 6930:
|
||||
case >= Protocol18Handler.MC_1_17_Version and <= Protocol18Handler.MC_1_18_2_Version
|
||||
when block.BlockId == 6543:
|
||||
case >= Protocol18Handler.MC_1_16_Version and <= Protocol18Handler.MC_1_16_5_Version
|
||||
when block.BlockId == 6341:
|
||||
case >= Protocol18Handler.MC_1_14_Version and <= Protocol18Handler.MC_1_15_2_Version
|
||||
when block.BlockId == 5801:
|
||||
case >= Protocol18Handler.MC_1_13_Version and < Protocol18Handler.MC_1_14_Version
|
||||
when block.BlockId == 5295:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -650,193 +672,106 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
// Checkin for stems and attached stems instead of Melons themselves
|
||||
case CropType.Melon:
|
||||
if (protocolVersion == Protocol18Handler.MC_1_19_4_Version)
|
||||
switch (protocolVersion)
|
||||
{
|
||||
if (block.BlockId == 6808 || block.BlockId == 6606)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion == Protocol18Handler.MC_1_19_3_Version)
|
||||
{
|
||||
if (block.BlockId == 6582 || block.BlockId == 6832)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_19_Version && protocolVersion <= Protocol18Handler.MC_1_19_2_Version)
|
||||
{
|
||||
if (block.BlockId == 5166 || block.BlockId == 5150)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_17_Version && protocolVersion <= Protocol18Handler.MC_1_18_2_Version)
|
||||
{
|
||||
if (block.BlockId == 4860 || block.BlockId == 4844)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_16_Version && protocolVersion <= Protocol18Handler.MC_1_16_5_Version)
|
||||
{
|
||||
if (block.BlockId == 4791 || block.BlockId == 4775)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_14_Version && protocolVersion <= Protocol18Handler.MC_1_15_2_Version)
|
||||
{
|
||||
if (block.BlockId == 4771 || block.BlockId == 4755)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_13_Version && protocolVersion < Protocol18Handler.MC_1_14_Version)
|
||||
{
|
||||
if (block.BlockId == 4268 || block.BlockId == 4252)
|
||||
case Protocol18Handler.MC_1_20_Version when block.BlockId is 6836 or 6820:
|
||||
case Protocol18Handler.MC_1_19_4_Version when block.BlockId is 6808 or 6606:
|
||||
case Protocol18Handler.MC_1_19_3_Version when block.BlockId is 6582 or 6832:
|
||||
case >= Protocol18Handler.MC_1_19_Version and <= Protocol18Handler.MC_1_19_2_Version
|
||||
when block.BlockId is 5166 or 5150:
|
||||
case >= Protocol18Handler.MC_1_17_Version and <= Protocol18Handler.MC_1_18_2_Version
|
||||
when block.BlockId is 4860 or 4844:
|
||||
case >= Protocol18Handler.MC_1_16_Version and <= Protocol18Handler.MC_1_16_5_Version
|
||||
when block.BlockId is 4791 or 4775:
|
||||
case >= Protocol18Handler.MC_1_14_Version and <= Protocol18Handler.MC_1_15_2_Version
|
||||
when block.BlockId is 4771 or 4755:
|
||||
case >= Protocol18Handler.MC_1_13_Version and < Protocol18Handler.MC_1_14_Version
|
||||
when block.BlockId is 4268 or 4252:
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CropType.Netherwart:
|
||||
if (protocolVersion == Protocol18Handler.MC_1_19_4_Version)
|
||||
case CropType.NetherWart:
|
||||
switch (protocolVersion)
|
||||
{
|
||||
if (block.BlockId == 7384)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion == Protocol18Handler.MC_1_19_3_Version)
|
||||
{
|
||||
if (block.BlockId == 7158)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_19_Version && protocolVersion <= Protocol18Handler.MC_1_19_2_Version)
|
||||
{
|
||||
if (block.BlockId == 5718)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_17_Version && protocolVersion <= Protocol18Handler.MC_1_18_2_Version)
|
||||
{
|
||||
if (block.BlockId == 5332)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_16_Version && protocolVersion <= Protocol18Handler.MC_1_16_5_Version)
|
||||
{
|
||||
if (block.BlockId == 5135)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_14_Version && protocolVersion <= Protocol18Handler.MC_1_15_2_Version)
|
||||
{
|
||||
if (block.BlockId == 5115)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_13_Version && protocolVersion < Protocol18Handler.MC_1_14_Version)
|
||||
{
|
||||
if (block.BlockId == 4612)
|
||||
case Protocol18Handler.MC_1_20_Version when block.BlockId == 7388:
|
||||
case Protocol18Handler.MC_1_19_4_Version when block.BlockId == 7384:
|
||||
case Protocol18Handler.MC_1_19_3_Version when block.BlockId == 7158:
|
||||
case >= Protocol18Handler.MC_1_19_Version and <= Protocol18Handler.MC_1_19_2_Version
|
||||
when block.BlockId == 5718:
|
||||
case >= Protocol18Handler.MC_1_17_Version and <= Protocol18Handler.MC_1_18_2_Version
|
||||
when block.BlockId == 5332:
|
||||
case >= Protocol18Handler.MC_1_16_Version and <= Protocol18Handler.MC_1_16_5_Version
|
||||
when block.BlockId == 5135:
|
||||
case >= Protocol18Handler.MC_1_14_Version and <= Protocol18Handler.MC_1_15_2_Version
|
||||
when block.BlockId == 5115:
|
||||
case >= Protocol18Handler.MC_1_13_Version and < Protocol18Handler.MC_1_14_Version
|
||||
when block.BlockId == 4612:
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Checkin for stems and attached stems instead of Pumpkins themselves
|
||||
case CropType.Pumpkin:
|
||||
if (protocolVersion == Protocol18Handler.MC_1_19_4_Version)
|
||||
switch (protocolVersion)
|
||||
{
|
||||
if (block.BlockId == 5845 || block.BlockId == 6824)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion == Protocol18Handler.MC_1_19_3_Version)
|
||||
{
|
||||
if (block.BlockId == 5683 || block.BlockId == 6598)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_19_Version && protocolVersion <= Protocol18Handler.MC_1_19_2_Version)
|
||||
{
|
||||
if (block.BlockId == 5158 || block.BlockId == 5146)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_17_Version && protocolVersion <= Protocol18Handler.MC_1_18_2_Version)
|
||||
{
|
||||
if (block.BlockId == 4852 || block.BlockId == 4840)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_16_Version && protocolVersion <= Protocol18Handler.MC_1_16_5_Version)
|
||||
{
|
||||
if (block.BlockId == 4783 || block.BlockId == 4771)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_14_Version && protocolVersion <= Protocol18Handler.MC_1_15_2_Version)
|
||||
{
|
||||
if (block.BlockId == 4763 || block.BlockId == 4751)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_13_Version && protocolVersion < Protocol18Handler.MC_1_14_Version)
|
||||
{
|
||||
if (block.BlockId == 4260 || block.BlockId == 4248)
|
||||
case Protocol18Handler.MC_1_20_Version when block.BlockId is 5849 or 6816:
|
||||
case Protocol18Handler.MC_1_19_4_Version when block.BlockId is 5845 or 6824:
|
||||
case Protocol18Handler.MC_1_19_3_Version when block.BlockId is 5683 or 6598:
|
||||
case >= Protocol18Handler.MC_1_19_Version and <= Protocol18Handler.MC_1_19_2_Version
|
||||
when block.BlockId is 5158 or 5146:
|
||||
case >= Protocol18Handler.MC_1_17_Version and <= Protocol18Handler.MC_1_18_2_Version
|
||||
when block.BlockId is 4852 or 4840:
|
||||
case >= Protocol18Handler.MC_1_16_Version and <= Protocol18Handler.MC_1_16_5_Version
|
||||
when block.BlockId is 4783 or 4771:
|
||||
case >= Protocol18Handler.MC_1_14_Version and <= Protocol18Handler.MC_1_15_2_Version
|
||||
when block.BlockId is 4763 or 4751:
|
||||
case >= Protocol18Handler.MC_1_13_Version and < Protocol18Handler.MC_1_14_Version
|
||||
when block.BlockId is 4260 or 4248:
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CropType.Potato:
|
||||
if (protocolVersion == Protocol18Handler.MC_1_19_4_Version)
|
||||
switch (protocolVersion)
|
||||
{
|
||||
if (block.BlockId == 8606)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion == Protocol18Handler.MC_1_19_3_Version)
|
||||
{
|
||||
if (block.BlockId == 8378)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_19_Version && protocolVersion <= Protocol18Handler.MC_1_19_2_Version)
|
||||
{
|
||||
if (block.BlockId == 6938)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_17_Version && protocolVersion <= Protocol18Handler.MC_1_18_2_Version)
|
||||
{
|
||||
if (block.BlockId == 6551)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_16_Version && protocolVersion <= Protocol18Handler.MC_1_16_5_Version)
|
||||
{
|
||||
if (block.BlockId == 6349)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_14_Version && protocolVersion <= Protocol18Handler.MC_1_15_2_Version)
|
||||
{
|
||||
if (block.BlockId == 5809)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_13_Version && protocolVersion < Protocol18Handler.MC_1_14_Version)
|
||||
{
|
||||
if (block.BlockId == 5303)
|
||||
case Protocol18Handler.MC_1_20_Version when block.BlockId == 8610:
|
||||
case Protocol18Handler.MC_1_19_4_Version when block.BlockId == 8606:
|
||||
case Protocol18Handler.MC_1_19_3_Version when block.BlockId == 8378:
|
||||
case >= Protocol18Handler.MC_1_19_Version and <= Protocol18Handler.MC_1_19_2_Version
|
||||
when block.BlockId == 6938:
|
||||
case >= Protocol18Handler.MC_1_17_Version and <= Protocol18Handler.MC_1_18_2_Version
|
||||
when block.BlockId == 6551:
|
||||
case >= Protocol18Handler.MC_1_16_Version and <= Protocol18Handler.MC_1_16_5_Version
|
||||
when block.BlockId == 6349:
|
||||
case >= Protocol18Handler.MC_1_14_Version and <= Protocol18Handler.MC_1_15_2_Version
|
||||
when block.BlockId == 5809:
|
||||
case >= Protocol18Handler.MC_1_13_Version and < Protocol18Handler.MC_1_14_Version
|
||||
when block.BlockId == 5303:
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CropType.Wheat:
|
||||
if (protocolVersion == Protocol18Handler.MC_1_19_4_Version)
|
||||
switch (protocolVersion)
|
||||
{
|
||||
if (block.BlockId == 4281)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion == Protocol18Handler.MC_1_19_3_Version)
|
||||
{
|
||||
if (block.BlockId == 4233)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_19_Version && protocolVersion <= Protocol18Handler.MC_1_19_2_Version)
|
||||
{
|
||||
if (block.BlockId == 3619)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_17_Version && protocolVersion <= Protocol18Handler.MC_1_18_2_Version)
|
||||
{
|
||||
if (block.BlockId == 3421)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_16_Version && protocolVersion <= Protocol18Handler.MC_1_16_5_Version)
|
||||
{
|
||||
if (block.BlockId == 3364)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_14_Version && protocolVersion <= Protocol18Handler.MC_1_15_2_Version)
|
||||
{
|
||||
if (block.BlockId == 3362)
|
||||
return true;
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_13_Version && protocolVersion < Protocol18Handler.MC_1_14_Version)
|
||||
{
|
||||
if (block.BlockId == 3059)
|
||||
case Protocol18Handler.MC_1_20_Version when block.BlockId == 4285:
|
||||
case Protocol18Handler.MC_1_19_4_Version when block.BlockId == 4281:
|
||||
case Protocol18Handler.MC_1_19_3_Version when block.BlockId == 4233:
|
||||
case >= Protocol18Handler.MC_1_19_Version and <= Protocol18Handler.MC_1_19_2_Version
|
||||
when block.BlockId == 3619:
|
||||
case >= Protocol18Handler.MC_1_17_Version and <= Protocol18Handler.MC_1_18_2_Version
|
||||
when block.BlockId == 3421:
|
||||
case >= Protocol18Handler.MC_1_16_Version and <= Protocol18Handler.MC_1_16_5_Version
|
||||
when block.BlockId == 3364:
|
||||
case >= Protocol18Handler.MC_1_14_Version and <= Protocol18Handler.MC_1_15_2_Version
|
||||
when block.BlockId == 3362:
|
||||
case >= Protocol18Handler.MC_1_13_Version and < Protocol18Handler.MC_1_14_Version
|
||||
when block.BlockId == 3059:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -849,28 +784,27 @@ namespace MinecraftClient.ChatBots
|
|||
// Yoinked from ReinforceZwei's AutoTree and adapted to search the whole of inventory in additon to the hotbar
|
||||
private bool SwitchToItem(ItemType itemType)
|
||||
{
|
||||
Container playerInventory = GetPlayerInventory();
|
||||
var playerInventory = GetPlayerInventory();
|
||||
|
||||
if (playerInventory.Items.ContainsKey(GetCurrentSlot() - 36)
|
||||
&& playerInventory.Items[GetCurrentSlot() - 36].Type == itemType)
|
||||
if (playerInventory.Items.TryGetValue(GetCurrentSlot() - 36, out Item value) && value.Type == itemType)
|
||||
return true; // Already selected
|
||||
|
||||
// Search the full inventory
|
||||
List<int> fullInventorySearch = new List<int>(playerInventory.SearchItem(itemType));
|
||||
var fullInventorySearch = new List<int>(playerInventory.SearchItem(itemType));
|
||||
|
||||
// Search for the seed in the hot bar
|
||||
List<int> hotbarSerch = fullInventorySearch.Where(slot => slot >= 36 && slot <= 44).ToList();
|
||||
var hotBarSearch = fullInventorySearch.Where(slot => slot is >= 36 and <= 44).ToList();
|
||||
|
||||
if (hotbarSerch.Count > 0)
|
||||
if (hotBarSearch.Count > 0)
|
||||
{
|
||||
ChangeSlot((short)(hotbarSerch[0] - 36));
|
||||
ChangeSlot((short)(hotBarSearch[0] - 36));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fullInventorySearch.Count == 0)
|
||||
return false;
|
||||
|
||||
ItemMovingHelper movingHelper = new ItemMovingHelper(playerInventory, Handler);
|
||||
var movingHelper = new ItemMovingHelper(playerInventory, Handler);
|
||||
movingHelper.Swap(fullInventorySearch[0], 36);
|
||||
ChangeSlot(0);
|
||||
|
||||
|
|
@ -897,8 +831,7 @@ namespace MinecraftClient.ChatBots
|
|||
// Yoinked from Daenges's Sugarcane Farmer
|
||||
private bool WaitForDigBlock(Location block, int digTimeout = 1000)
|
||||
{
|
||||
if (DigBlock(block.ToFloor()))
|
||||
{
|
||||
if (!DigBlock(block.ToFloor())) return false;
|
||||
short i = 0; // Maximum wait time of 10 sec.
|
||||
while (GetWorld().GetBlock(block).Type != Material.Air && i <= digTimeout)
|
||||
{
|
||||
|
|
@ -909,9 +842,6 @@ namespace MinecraftClient.ChatBots
|
|||
return i <= digTimeout;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool HasItemOfTypeInInventory(ItemType itemType)
|
||||
{
|
||||
return GetPlayerInventory().SearchItem(itemType).Length > 0;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ namespace MinecraftClient.ChatBots
|
|||
[TomlDoNotInlineObject]
|
||||
public class Configs
|
||||
{
|
||||
[NonSerialized]
|
||||
private const string BotName = "FollowPlayer";
|
||||
[NonSerialized] private const string BotName = "FollowPlayer";
|
||||
|
||||
public bool Enabled = false;
|
||||
|
||||
|
|
@ -73,7 +72,8 @@ namespace MinecraftClient.ChatBots
|
|||
.Then(l => l.Argument("PlayerName", MccArguments.PlayerName())
|
||||
.Executes(r => OnCommandStart(r.Source, Arguments.GetString(r, "PlayerName"), takeRisk: false))
|
||||
.Then(l => l.Literal("-f")
|
||||
.Executes(r => OnCommandStart(r.Source, Arguments.GetString(r, "PlayerName"), takeRisk: true)))))
|
||||
.Executes(r =>
|
||||
OnCommandStart(r.Source, Arguments.GetString(r, "PlayerName"), takeRisk: true)))))
|
||||
.Then(l => l.Literal("stop")
|
||||
.Executes(r => OnCommandStop(r.Source)))
|
||||
.Then(l => l.Literal("_help")
|
||||
|
|
@ -84,6 +84,7 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
public override void OnUnload()
|
||||
{
|
||||
BotMovementLock.Instance?.UnLock("Follow Player");
|
||||
McClient.dispatcher.Unregister(CommandName);
|
||||
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||
}
|
||||
|
|
@ -104,7 +105,7 @@ namespace MinecraftClient.ChatBots
|
|||
if (!IsValidName(name))
|
||||
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_follow_invalid_name);
|
||||
|
||||
Entity? player = GetEntities().Values.ToList().Find(entity =>
|
||||
var player = GetEntities().Values.ToList().Find(entity =>
|
||||
entity.Type == EntityType.Player
|
||||
&& !string.IsNullOrEmpty(entity.Name)
|
||||
&& entity.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
|
|
@ -116,22 +117,37 @@ namespace MinecraftClient.ChatBots
|
|||
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_follow_cant_reach_player);
|
||||
|
||||
if (_playerToFollow != null && _playerToFollow.Equals(name, StringComparison.OrdinalIgnoreCase))
|
||||
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_follow_already_following, _playerToFollow));
|
||||
return r.SetAndReturn(CmdResult.Status.Fail,
|
||||
string.Format(Translations.cmd_follow_already_following, _playerToFollow));
|
||||
|
||||
string result;
|
||||
if (_playerToFollow != null)
|
||||
result = string.Format(Translations.cmd_follow_switched, player.Name!);
|
||||
else
|
||||
result = string.Format(Translations.cmd_follow_started, player.Name!);
|
||||
var movementLock = BotMovementLock.Instance;
|
||||
if (movementLock is { IsLocked: true })
|
||||
return r.SetAndReturn(CmdResult.Status.Fail,
|
||||
string.Format(Translations.bot_common_movement_lock_held, "Follow Player", movementLock.LockedBy));
|
||||
|
||||
var result =
|
||||
string.Format(
|
||||
_playerToFollow != null ? Translations.cmd_follow_switched : Translations.cmd_follow_started,
|
||||
player.Name!);
|
||||
_playerToFollow = name.ToLower();
|
||||
|
||||
if (takeRisk)
|
||||
switch (movementLock)
|
||||
{
|
||||
_unsafeEnabled = true;
|
||||
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_follow_note + '\n' + Translations.cmd_follow_unsafe_enabled);
|
||||
case { IsLocked: false }:
|
||||
if (!movementLock.Lock("Follow Player"))
|
||||
{
|
||||
LogToConsole($"§§6§1§0Follow Player bot failed to obtain the movement lock for some reason!");
|
||||
LogToConsole($"§§6§1§0Disable other bots who have movement mechanics, and try again!");
|
||||
return r.SetAndReturn(CmdResult.Status.Fail);
|
||||
}
|
||||
else
|
||||
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_follow_note);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!takeRisk) return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_follow_note);
|
||||
_unsafeEnabled = true;
|
||||
return r.SetAndReturn(CmdResult.Status.Done,
|
||||
Translations.cmd_follow_note + '\n' + Translations.cmd_follow_unsafe_enabled);
|
||||
}
|
||||
|
||||
private int OnCommandStop(CmdResult r)
|
||||
|
|
@ -139,6 +155,8 @@ namespace MinecraftClient.ChatBots
|
|||
if (_playerToFollow == null)
|
||||
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_follow_already_stopped);
|
||||
|
||||
var movementLock = BotMovementLock.Instance;
|
||||
movementLock?.UnLock("Follow Player");
|
||||
_playerToFollow = null;
|
||||
|
||||
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_follow_stopping);
|
||||
|
|
@ -168,8 +186,8 @@ namespace MinecraftClient.ChatBots
|
|||
if (!CanMoveThere(entity.Location))
|
||||
return;
|
||||
|
||||
// Stop at specified distance from plater (prevents pushing player around)
|
||||
double distance = entity.Location.Distance(GetCurrentLocation());
|
||||
// Stop at specified distance from player (prevents pushing player around)
|
||||
var distance = entity.Location.Distance(GetCurrentLocation());
|
||||
|
||||
if (distance < Config.Stop_At_Distance)
|
||||
return;
|
||||
|
|
@ -182,7 +200,8 @@ namespace MinecraftClient.ChatBots
|
|||
if (entity.Type != EntityType.Player)
|
||||
return;
|
||||
|
||||
if (_playerToFollow != null && !string.IsNullOrEmpty(entity.Name) && _playerToFollow.Equals(entity.Name, StringComparison.OrdinalIgnoreCase))
|
||||
if (_playerToFollow != null && !string.IsNullOrEmpty(entity.Name) &&
|
||||
_playerToFollow.Equals(entity.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
LogToConsole(string.Format(Translations.cmd_follow_player_came_to_the_range, _playerToFollow));
|
||||
LogToConsole(Translations.cmd_follow_resuming);
|
||||
|
|
@ -194,7 +213,8 @@ namespace MinecraftClient.ChatBots
|
|||
if (entity.Type != EntityType.Player)
|
||||
return;
|
||||
|
||||
if (_playerToFollow != null && !string.IsNullOrEmpty(entity.Name) && _playerToFollow.Equals(entity.Name, StringComparison.OrdinalIgnoreCase))
|
||||
if (_playerToFollow != null && !string.IsNullOrEmpty(entity.Name) &&
|
||||
_playerToFollow.Equals(entity.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
LogToConsole(string.Format(Translations.cmd_follow_player_left_the_range, _playerToFollow));
|
||||
LogToConsole(Translations.cmd_follow_pausing);
|
||||
|
|
@ -203,7 +223,8 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
public override void OnPlayerLeave(Guid uuid, string? name)
|
||||
{
|
||||
if (_playerToFollow != null && !string.IsNullOrEmpty(name) && _playerToFollow.Equals(name, StringComparison.OrdinalIgnoreCase))
|
||||
if (_playerToFollow != null && !string.IsNullOrEmpty(name) &&
|
||||
_playerToFollow.Equals(name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
LogToConsole(string.Format(Translations.cmd_follow_player_left, _playerToFollow));
|
||||
LogToConsole(Translations.cmd_follow_stopping);
|
||||
|
|
@ -213,12 +234,8 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
private bool CanMoveThere(Location location)
|
||||
{
|
||||
ChunkColumn? chunkColumn = GetWorld().GetChunkColumn(location);
|
||||
|
||||
if (chunkColumn == null || chunkColumn.FullyLoaded == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
var chunkColumn = GetWorld().GetChunkColumn(location);
|
||||
return chunkColumn != null && chunkColumn.FullyLoaded != false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -89,6 +89,7 @@ public class ItemsCollector : ChatBot
|
|||
|
||||
public override void OnUnload()
|
||||
{
|
||||
StopTheMainProcess();
|
||||
McClient.dispatcher.Unregister(CommandName);
|
||||
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||
}
|
||||
|
|
@ -109,6 +110,18 @@ public class ItemsCollector : ChatBot
|
|||
if (running)
|
||||
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_items_collector_already_collecting);
|
||||
|
||||
var movementLock = BotMovementLock.Instance;
|
||||
if (movementLock is { IsLocked: true })
|
||||
return r.SetAndReturn(CmdResult.Status.Fail,
|
||||
string.Format(Translations.bot_common_movement_lock_held, "Items Collector", movementLock.LockedBy));
|
||||
|
||||
if (!movementLock!.Lock("Items Collector"))
|
||||
{
|
||||
LogToConsole($"§§6§1§0Items Collector bot failed to obtain the movement lock for some reason!");
|
||||
LogToConsole($"§§6§1§0Disable other bots who have movement mechanics, and try again!");
|
||||
return r.SetAndReturn(CmdResult.Status.Fail);
|
||||
}
|
||||
|
||||
StartTheMainProcess();
|
||||
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_items_collector_started);
|
||||
}
|
||||
|
|
@ -132,6 +145,7 @@ public class ItemsCollector : ChatBot
|
|||
private void StopTheMainProcess()
|
||||
{
|
||||
running = false;
|
||||
BotMovementLock.Instance?.UnLock("Items Collector");
|
||||
}
|
||||
|
||||
private void MainProcess()
|
||||
|
|
@ -163,14 +177,9 @@ public class ItemsCollector : ChatBot
|
|||
|
||||
if (items.Any())
|
||||
{
|
||||
foreach (var entity in items)
|
||||
{
|
||||
if (!running)
|
||||
break;
|
||||
|
||||
foreach (var entity in items.TakeWhile(entity => running))
|
||||
WaitForMoveToLocation(entity.Location);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (startingLocation.Distance(currentLocation) > 2f && Config.Always_Return_To_Start)
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ public class WebSocketBot : ChatBot
|
|||
public int Port = 8043;
|
||||
|
||||
[TomlInlineComment("$ChatBot.WebSocketBot.Password$")]
|
||||
public string? Password = "wspass12345";
|
||||
public string? Password = Guid.NewGuid().ToString().Replace("-", "").Trim().ToLower();
|
||||
|
||||
[TomlInlineComment("$ChatBot.WebSocketBot.DebugMode$")]
|
||||
public bool DebugMode = false;
|
||||
|
|
|
|||
58
MinecraftClient/Inventory/ContainerExtensions.cs
Normal file
58
MinecraftClient/Inventory/ContainerExtensions.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
|
||||
namespace MinecraftClient.Inventory;
|
||||
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
public enum ComparisonType
|
||||
{
|
||||
Equals,
|
||||
NotEquals,
|
||||
Less,
|
||||
LessOrEqual,
|
||||
Greater,
|
||||
GreaterOrEqual
|
||||
}
|
||||
|
||||
public static class ContainerExtensions
|
||||
{
|
||||
public static bool IsFull(this Container container) =>
|
||||
container.Items.Values.All(item => item.Count >= item.Type.StackCount());
|
||||
|
||||
public static int FirstEmptySlot(this Container container) =>
|
||||
container.Items.FirstOrDefault(slot => slot.Value.IsEmpty).Key;
|
||||
|
||||
public static int FirstSlotWithItem(this Container container, ItemType type, int? count = null,
|
||||
ComparisonType comparison = ComparisonType.Equals) =>
|
||||
container.Items.FirstOrDefault(slot =>
|
||||
slot.Value.Type == type &&
|
||||
(!count.HasValue || CompareCounts(slot.Value.Count, count.Value, comparison))).Key;
|
||||
|
||||
public static int LastSlotWithItem(this Container container, ItemType type, int? count = null,
|
||||
ComparisonType comparison = ComparisonType.Equals) =>
|
||||
container.Items.LastOrDefault(slot =>
|
||||
slot.Value.Type == type &&
|
||||
(!count.HasValue || CompareCounts(slot.Value.Count, count.Value, comparison)))
|
||||
.Key;
|
||||
|
||||
// We could have used "Expression<Func<int, int, bool>> comparison = null" instead of "ComparisonType comparison", but it would look ugly to use
|
||||
private static bool CompareCounts(int value1, int value2, ComparisonType comparison)
|
||||
{
|
||||
var left = Expression.Constant(value1);
|
||||
var right = Expression.Constant(value2);
|
||||
|
||||
Expression binaryExpression = comparison switch
|
||||
{
|
||||
ComparisonType.Less => Expression.LessThan(left, right),
|
||||
ComparisonType.LessOrEqual => Expression.LessThanOrEqual(left, right),
|
||||
ComparisonType.Greater => Expression.GreaterThan(left, right),
|
||||
ComparisonType.GreaterOrEqual => Expression.GreaterThanOrEqual(left, right),
|
||||
ComparisonType.Equals => Expression.Equal(left, right),
|
||||
ComparisonType.NotEquals => Expression.NotEqual(left, right),
|
||||
_ => Expression.Equal(left, right)
|
||||
};
|
||||
|
||||
return Expression.Lambda<Func<bool>>(binaryExpression).Compile().Invoke();
|
||||
}
|
||||
}
|
||||
|
|
@ -6,8 +6,68 @@ public static class BlockExtension
|
|||
{
|
||||
public static bool IsTopSlab(this Block block, int protocolVersion)
|
||||
{
|
||||
if (protocolVersion >= Protocol18Handler.MC_1_19_4_Version)
|
||||
switch (protocolVersion)
|
||||
{
|
||||
case >= Protocol18Handler.MC_1_20_Version:
|
||||
switch (block.BlockId)
|
||||
{
|
||||
case 11022: //OakSlab
|
||||
case 11028: //SpruceSlab
|
||||
case 11034: //BirchSlab
|
||||
case 11040: //JungleSlab
|
||||
case 11046: //AcaciaSlab
|
||||
case 11058: //DarkOakSlab
|
||||
case 11064: //MangroveSlab
|
||||
case 18528: //CrimsonSlab
|
||||
case 18534: //WarpedSlab
|
||||
case 11082: //StoneSlab
|
||||
case 11112: //CobblestoneSlab
|
||||
case 13966: //MossyCobblestoneSlab
|
||||
case 11088: //SmoothStoneSlab
|
||||
case 11124: //StoneBrickSlab
|
||||
case 13954: //MossyStoneBrickSlab
|
||||
case 13990: //GraniteSlab
|
||||
case 13942: //PolishedGraniteSlab
|
||||
case 14014: //DioriteSlab
|
||||
case 13960: //PolishedDioriteSlab
|
||||
case 13996: //AndesiteSlab
|
||||
case 14008: //PolishedAndesiteSlab
|
||||
case 22534: //CobbledDeepslateSlab
|
||||
case 22945: //PolishedDeepslateSlab
|
||||
case 23767: //DeepslateBrickSlab
|
||||
case 23356: //DeepslateTileSlab
|
||||
case 11118: //BrickSlab
|
||||
case 11130: //MudBrickSlab
|
||||
case 11094: //SandstoneSlab
|
||||
case 13978: //SmoothSandstoneSlab
|
||||
case 11100: //CutSandstoneSlab
|
||||
case 11148: //RedSandstoneSlab
|
||||
case 13948: //SmoothRedSandstoneSlab
|
||||
case 11154: //CutRedSandstoneSlab
|
||||
case 10566: //PrismarineSlab
|
||||
case 10572: //PrismarineBrickSlab
|
||||
case 10578: //DarkPrismarineSlab
|
||||
case 11136: //NetherBrickSlab
|
||||
case 14002: //RedNetherBrickSlab
|
||||
case 19725: //BlackstoneSlab
|
||||
case 20226: //PolishedBlackstoneSlab
|
||||
case 19735: //PolishedBlackstoneBrickSlab
|
||||
case 13972: //EndStoneBrickSlab
|
||||
case 11160: //PurpurSlab
|
||||
case 11142: //QuartzSlab
|
||||
case 13984: //SmoothQuartzSlab
|
||||
case 21912: //CutCopperSlab
|
||||
case 21906: //ExposedCutCopperSlab
|
||||
case 21900: //WeatheredCutCopperSlab
|
||||
case 21894: //OxidizedCutCopperSlab
|
||||
case 22264: //WaxedCutCopperSlab
|
||||
case 22258: //WaxedExposedCutCopperSlab
|
||||
case 22252: //WaxedWeatheredCutCopperSlab
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case Protocol18Handler.MC_1_19_4_Version:
|
||||
switch (block.BlockId)
|
||||
{
|
||||
case 11018: // OakSlab
|
||||
|
|
@ -65,9 +125,9 @@ public static class BlockExtension
|
|||
case 21844: // WaxedOxidizedCutCopperSlab
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (protocolVersion == Protocol18Handler.MC_1_19_3_Version)
|
||||
{
|
||||
|
||||
break;
|
||||
case Protocol18Handler.MC_1_19_3_Version:
|
||||
switch (block.BlockId)
|
||||
{
|
||||
case 10686: // OakSlab
|
||||
|
|
@ -125,9 +185,9 @@ public static class BlockExtension
|
|||
case 21375: // WaxedOxidizedCutCopperSlab
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_19_Version)
|
||||
{
|
||||
|
||||
break;
|
||||
case >= Protocol18Handler.MC_1_19_Version:
|
||||
switch (block.BlockId)
|
||||
{
|
||||
case 19257: // CutCopperSlab
|
||||
|
|
@ -186,9 +246,9 @@ public static class BlockExtension
|
|||
case 17464: // PolishedBlackstoneBrickSlab
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_17_Version)
|
||||
{
|
||||
|
||||
break;
|
||||
case >= Protocol18Handler.MC_1_17_Version:
|
||||
switch (block.BlockId)
|
||||
{
|
||||
case 18163: // CutCopperSlab
|
||||
|
|
@ -245,9 +305,9 @@ public static class BlockExtension
|
|||
case 16509: // PolishedBlackstoneBrickSlab
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_16_Version)
|
||||
{
|
||||
|
||||
break;
|
||||
case >= Protocol18Handler.MC_1_16_Version:
|
||||
switch (block.BlockId)
|
||||
{
|
||||
case 8305: // OakSlab
|
||||
|
|
@ -292,9 +352,9 @@ public static class BlockExtension
|
|||
case 16263: // PolishedBlackstoneBrickSlab
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_15_Version)
|
||||
{
|
||||
|
||||
break;
|
||||
case >= Protocol18Handler.MC_1_15_Version:
|
||||
switch (block.BlockId)
|
||||
{
|
||||
case 7765: // OakSlab
|
||||
|
|
@ -333,9 +393,9 @@ public static class BlockExtension
|
|||
case 10326: // DioriteSlab
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (protocolVersion >= Protocol18Handler.MC_1_14_Version)
|
||||
{
|
||||
|
||||
break;
|
||||
case >= Protocol18Handler.MC_1_14_Version:
|
||||
switch (block.BlockId)
|
||||
{
|
||||
case 7765: // OakSlab
|
||||
|
|
@ -375,6 +435,8 @@ public static class BlockExtension
|
|||
case 10326: // DioriteSlab
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ using MinecraftClient.Protocol.ProfileKey;
|
|||
using MinecraftClient.Protocol.Session;
|
||||
using MinecraftClient.Proxy;
|
||||
using MinecraftClient.Scripting;
|
||||
using Newtonsoft.Json;
|
||||
using static MinecraftClient.Settings;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers
|
||||
|
|
@ -2348,6 +2349,17 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
// TODO: Use
|
||||
break;
|
||||
|
||||
// Temporarily disabled until I find a fix
|
||||
/*case PacketTypesIn.BlockEntityData:
|
||||
var location_ = dataTypes.ReadNextLocation(packetData);
|
||||
var type_ = dataTypes.ReadNextInt(packetData);
|
||||
var nbt = dataTypes.ReadNextNbt(packetData);
|
||||
var nbtJson = JsonConvert.SerializeObject(nbt["messages"]);
|
||||
|
||||
//log.Info($"BLOCK ENTITY DATA -> {location_.ToString()} [{type_}] -> NBT: {nbtJson}");
|
||||
|
||||
break;*/
|
||||
|
||||
default:
|
||||
return false; //Ignored packet
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
|
|
@ -3956,5 +3956,17 @@ namespace MinecraftClient {
|
|||
return ResourceManager.GetString("cmd.nameitem.desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string bot_antiafk_may_not_move {
|
||||
get {
|
||||
return ResourceManager.GetString("bot.antiafk.may.not.move", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string bot_common_movement_lock_held {
|
||||
get {
|
||||
return ResourceManager.GetString("bot.common.movement.lock.held", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2109,4 +2109,10 @@ Logging in...</value>
|
|||
<data name="cmd.nameitem.desc" xml:space="preserve">
|
||||
<value>Set an item name when an Anvil inventory is active and the item is in the first slot.</value>
|
||||
</data>
|
||||
<data name="bot.antiafk.may.not.move" xml:space="preserve">
|
||||
<value>Bot movement lock is held by bot {0}, so the Anti AFK bot might not move!</value>
|
||||
</data>
|
||||
<data name="bot.common.movement.lock.held" xml:space="preserve">
|
||||
<value>You can not start/run/use the '{0}' bot because it requires movement, the movement is currently utilized by the '{1}' bot, stop it if you want to use this one.</value>
|
||||
</data>
|
||||
</root>
|
||||
35
MinecraftClient/Scripting/BotMovementLock.cs
Normal file
35
MinecraftClient/Scripting/BotMovementLock.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
namespace MinecraftClient.Scripting;
|
||||
|
||||
public class BotMovementLock
|
||||
{
|
||||
private static BotMovementLock? InstancePrivate;
|
||||
private string _heldBy = string.Empty;
|
||||
|
||||
private BotMovementLock()
|
||||
{
|
||||
InstancePrivate = this;
|
||||
}
|
||||
|
||||
public static BotMovementLock? Instance => InstancePrivate ??= new BotMovementLock();
|
||||
|
||||
public bool Lock(string owner)
|
||||
{
|
||||
if (owner.Trim().Length == 0 || _heldBy.Length > 0)
|
||||
return false;
|
||||
|
||||
_heldBy = owner.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool UnLock(string owner)
|
||||
{
|
||||
if (owner.Trim().Length == 0 || _heldBy.Length == 0 || !_heldBy.ToLower().Equals(owner.ToLower().Trim()))
|
||||
return false;
|
||||
|
||||
_heldBy = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsLocked => _heldBy.Length > 0;
|
||||
public string LockedBy => _heldBy;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue