mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Merge into master
This commit is contained in:
commit
892999ac98
155 changed files with 10911 additions and 9860 deletions
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
MCC.LoadBot(new AutoLeaveOnLowHp());
|
||||
|
||||
|
|
@ -19,4 +19,4 @@ namespace MinecraftClient.ChatBots
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,16 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
//using Brigadier.NET;
|
||||
//using Brigadier.NET.Builder;
|
||||
//using MinecraftClient;
|
||||
//using MinecraftClient.CommandHandler;
|
||||
//using MinecraftClient.CommandHandler.Patch;
|
||||
//using MinecraftClient.Inventory;
|
||||
//using MinecraftClient.Mapping;
|
||||
//using MinecraftClient.Scripting;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using static MinecraftClient.ChatBots.AutoCraft.Configs;
|
||||
//using System.Text;
|
||||
|
||||
MCC.LoadBot(new AutoTree());
|
||||
|
||||
|
|
@ -6,6 +18,8 @@ MCC.LoadBot(new AutoTree());
|
|||
|
||||
public class AutoTree : ChatBot
|
||||
{
|
||||
public const string CommandName = "autotree";
|
||||
|
||||
// Auto sapling placer - made for auto tree machine
|
||||
// Put your bot in designed position for placing sapling
|
||||
// Set the tree type by "/autotree type <Acacia|Birch|Oak|DarkOak|Jungle|Spruce>"
|
||||
|
|
@ -60,7 +74,8 @@ public class AutoTree : ChatBot
|
|||
}
|
||||
}
|
||||
}
|
||||
public override void Initialize()
|
||||
|
||||
public override void Initialize(CommandDispatcher<CmdResult> dispatcher)
|
||||
{
|
||||
if (!GetTerrainEnabled())
|
||||
{
|
||||
|
|
@ -74,11 +89,71 @@ public class AutoTree : ChatBot
|
|||
}
|
||||
else
|
||||
{
|
||||
RegisterChatBotCommand("autotree", "AutoTree ChatBot command", "Available commands: toggle, set, type", CommandHandler);
|
||||
dispatcher.Register(l => l.Literal("help")
|
||||
.Then(l => l.Literal(CommandName)
|
||||
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||
.Then(l => l.Literal("set")
|
||||
.Executes(r => OnCommandHelp(r.Source, "set")))
|
||||
.Then(l => l.Literal("type")
|
||||
.Executes(r => OnCommandHelp(r.Source, "type")))
|
||||
)
|
||||
);
|
||||
|
||||
dispatcher.Register(l => l.Literal(CommandName)
|
||||
.Then(l => l.Literal("toggle")
|
||||
.Executes(r => { return r.Source.SetAndReturn(CmdResult.Status.Done, Toggle() ? "Now is running" : "Now is stopping"); }))
|
||||
.Then(l => l.Literal("set")
|
||||
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||
.Executes(r => OnCommandSet(r.Source, MccArguments.GetLocation(r, "Location")))))
|
||||
.Then(l => l.Literal("type")
|
||||
.Then(l => l.Argument("TreeType", Arguments.String())
|
||||
.Executes(r => OnCommandType(r.Source, Arguments.GetString(r, "TreeType")))))
|
||||
.Then(l => l.Literal("_help")
|
||||
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||
);
|
||||
|
||||
LogToConsole("Loaded.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher)
|
||||
{
|
||||
dispatcher.Unregister(CommandName);
|
||||
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||
}
|
||||
|
||||
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||
{
|
||||
return r.SetAndReturn(cmd switch
|
||||
{
|
||||
#pragma warning disable format // @formatter:off
|
||||
"set" => "Set the location for placing sapling. Usage: set <x> <y> <z>",
|
||||
"type" => "Set the tree type. Usage: type <Acacia|Birch|Oak|DarkOak|Jungle|Spruce>",
|
||||
_ => "Available commands: toggle, set, type"
|
||||
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||
#pragma warning restore format // @formatter:on
|
||||
});
|
||||
}
|
||||
|
||||
private int OnCommandSet(CmdResult r, Location location)
|
||||
{
|
||||
SetLocation(location.ToAbsolute(GetCurrentLocation()));
|
||||
return r.SetAndReturn(CmdResult.Status.Done, "Location set to " + location.ToString());
|
||||
}
|
||||
|
||||
private int OnCommandType(CmdResult r, string treeType)
|
||||
{
|
||||
for (int i = 0; i < saplingItems.Length; i++)
|
||||
{
|
||||
if (saplingItems[i].ToString().ToLower().StartsWith(treeType))
|
||||
{
|
||||
treeTypeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return r.SetAndReturn(CmdResult.Status.Done, "Tree sapling type set to " + saplingItems[treeTypeIndex].ToString());
|
||||
}
|
||||
|
||||
public bool SetTreeType(int index)
|
||||
{
|
||||
if (index >= 0 && index < saplingItems.Length)
|
||||
|
|
@ -103,7 +178,7 @@ public class AutoTree : ChatBot
|
|||
public bool SwitchToSapling()
|
||||
{
|
||||
Container p = GetPlayerInventory();
|
||||
if (p.Items.ContainsKey(GetCurrentSlot() - 36)
|
||||
if (p.Items.ContainsKey(GetCurrentSlot() - 36)
|
||||
&& p.Items[GetCurrentSlot() - 36].Type == saplingItems[treeTypeIndex])
|
||||
{
|
||||
// Already selected
|
||||
|
|
@ -123,58 +198,4 @@ public class AutoTree : ChatBot
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public string CommandHandler(string cmd, string[] args)
|
||||
{
|
||||
if (args.Length <= 0)
|
||||
{
|
||||
return "Available commands: toggle, set, type";
|
||||
}
|
||||
string subCommand = args[0].ToLower();
|
||||
switch (subCommand)
|
||||
{
|
||||
case "toggle":
|
||||
{
|
||||
return Toggle() ? "Now is running" : "Now is stopping";
|
||||
}
|
||||
case "set":
|
||||
{
|
||||
if (args.Length < 4)
|
||||
{
|
||||
return "Set the location for placing sapling. Usage: set <x> <y> <z>";
|
||||
}
|
||||
try
|
||||
{
|
||||
int x = int.Parse(args[1]);
|
||||
int y = int.Parse(args[2]);
|
||||
int z = int.Parse(args[3]);
|
||||
var l = new Location(x, y, z);
|
||||
SetLocation(l);
|
||||
return "Location set to " + l.ToString();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "Please input numbers. Usage: set <x> <y> <z>";
|
||||
}
|
||||
}
|
||||
case "type":
|
||||
{
|
||||
if (args.Length < 2)
|
||||
{
|
||||
return "Set the tree type. Usage: type <Acacia|Birch|Oak|DarkOak|Jungle|Spruce>";
|
||||
}
|
||||
string typeString = args[1].ToLower();
|
||||
for (int i = 0; i < saplingItems.Length; i++)
|
||||
{
|
||||
if (saplingItems[i].ToString().ToLower().StartsWith(typeString))
|
||||
{
|
||||
treeTypeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "Tree sapling type set to " + saplingItems[treeTypeIndex].ToString();
|
||||
}
|
||||
default: return "Available commands: toggle, set, type";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,17 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
//using System.Collections.Specialized;
|
||||
//using MinecraftClient.Protocol;
|
||||
//using MinecraftClient.Scripting;
|
||||
//using MinecraftClient;
|
||||
//using static MinecraftClient.Scripting.ChatBot;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using System;
|
||||
//using Brigadier.NET.Builder;
|
||||
//using MinecraftClient.CommandHandler.Patch;
|
||||
//using MinecraftClient.CommandHandler;
|
||||
//using Brigadier.NET;
|
||||
|
||||
MCC.LoadBot(new DiscordWebhook());
|
||||
|
||||
|
|
@ -278,6 +289,8 @@ class MessageCache
|
|||
|
||||
class DiscordWebhook : ChatBot
|
||||
{
|
||||
public const string CommandName = "discordWebhook";
|
||||
|
||||
private WebhoookSettings settings = new WebhoookSettings();
|
||||
private SkinAPI sAPI;
|
||||
private MessageCache cache;
|
||||
|
|
@ -292,8 +305,19 @@ class DiscordWebhook : ChatBot
|
|||
{
|
||||
LogToConsole("Made by Daenges.\nSpecial thanks to Crafatar for providing the beautiful avatars!");
|
||||
LogToConsole("Please set a Webhook with '/dw changeurl [URL]'. For further information type '/discordwebhook help'.");
|
||||
RegisterChatBotCommand("discordWebhook", "/DiscordWebhook 'size', 'scale', 'fallbackSkin', 'overlay', 'skintype'", GetHelp(), CommandHandler);
|
||||
RegisterChatBotCommand("dw", "/DiscordWebhook 'size', 'scale', 'fallbackSkin', 'overlay', 'skintype'", GetHelp(), CommandHandler);
|
||||
|
||||
Handler.dispatcher.Register(l => l.Literal(CommandName)
|
||||
.Then(l => l.Argument("Commands", Arguments.GreedyString())
|
||||
.Executes(r => {
|
||||
CommandHandler(Arguments.GetString(r, "Commands").Split(' ', StringSplitOptions.TrimEntries));
|
||||
return r.Source.SetAndReturn(CmdResult.Status.Done);
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
public override void OnUnload()
|
||||
{
|
||||
Handler.dispatcher.Unregister(CommandName);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
|
|
@ -454,7 +478,7 @@ class DiscordWebhook : ChatBot
|
|||
{
|
||||
StringBuilder requestData = new StringBuilder();
|
||||
|
||||
requestData.Append("{");
|
||||
requestData.Append('{');
|
||||
requestData.Append("\"username\": \"" + msg.SenderName + "\", ");
|
||||
requestData.Append("\"content\": \"" + Sanizize(msg.Content) + "\", ");
|
||||
requestData.Append("\"avatar_url\": \"" + (msg.SenderName == "[Server]" ? sAPI.GetSkinURLCrafatar("f78a4d8dd51b4b3998a3230f2de0c670") : sAPI.GetSkinURLCrafatar(msg.SenderUUID)) + "\"");
|
||||
|
|
@ -530,10 +554,9 @@ class DiscordWebhook : ChatBot
|
|||
/// <summary>
|
||||
/// Handles all commands.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Whole command</param>
|
||||
/// <param name="args">Only arguments</param>
|
||||
/// <returns></returns>
|
||||
public string CommandHandler(string cmd, string[] args)
|
||||
public string CommandHandler(string[] args)
|
||||
{
|
||||
if (args.Length > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
MCC.LoadBot(new EntityCount());
|
||||
|
||||
|
|
@ -46,4 +46,4 @@ class EntityCount : ChatBot
|
|||
|
||||
return $"Found {counter} of entity type: {args[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,18 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
//using MinecraftClient.Inventory;
|
||||
//using MinecraftClient.Mapping;
|
||||
//using MinecraftClient.Scripting;
|
||||
//using MinecraftClient;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Threading.Tasks;
|
||||
//using System.Threading;
|
||||
//using System;
|
||||
//using Brigadier.NET.Builder;
|
||||
//using MinecraftClient.CommandHandler.Patch;
|
||||
//using Brigadier.NET;
|
||||
//using MinecraftClient.CommandHandler;
|
||||
|
||||
MCC.LoadBot(new MineCube());
|
||||
|
||||
|
|
@ -8,486 +22,499 @@ MCC.LoadBot(new MineCube());
|
|||
|
||||
class MineCube : ChatBot
|
||||
{
|
||||
private CancellationTokenSource cts;
|
||||
private Task currentMiningTask;
|
||||
private TimeSpan breakTimeout;
|
||||
private bool toolHandling;
|
||||
private int cacheSize;
|
||||
public const string CommandName = "mineup";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
if (!GetTerrainEnabled())
|
||||
{
|
||||
LogToConsole(Translations.extra_terrainandmovement_required);
|
||||
UnloadBot();
|
||||
return;
|
||||
}
|
||||
private CancellationTokenSource cts;
|
||||
private Task currentMiningTask;
|
||||
private TimeSpan breakTimeout;
|
||||
private bool toolHandling;
|
||||
private int cacheSize;
|
||||
|
||||
currentMiningTask = null;
|
||||
breakTimeout = TimeSpan.FromSeconds(15);
|
||||
cacheSize = 10;
|
||||
toolHandling = true;
|
||||
public override void Initialize()
|
||||
{
|
||||
if (!GetTerrainEnabled())
|
||||
{
|
||||
LogToConsole(Translations.extra_terrainandmovement_required);
|
||||
UnloadBot();
|
||||
return;
|
||||
}
|
||||
|
||||
RegisterChatBotCommand("mine", "Mine a cube from a to b", "/mine x y z OR /mine x1 y1 z1 x2 y2 z2", EvaluateMineCommand);
|
||||
RegisterChatBotCommand("mineup", "Walk over a flat cubic platform of blocks and mine everything above you", "/mine x1 y1 z1 x2 y2 z2 (y1 = y2)", EvaluateMineCommand);
|
||||
LogToConsole("Mining bot created by Daenges.");
|
||||
}
|
||||
currentMiningTask = null;
|
||||
breakTimeout = TimeSpan.FromSeconds(15);
|
||||
cacheSize = 10;
|
||||
toolHandling = true;
|
||||
|
||||
/// <summary>
|
||||
/// Walks in a 2 high area under an area of blocks and mines anything above its head.
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">The current world</param>
|
||||
/// <param name="startBlock">The start corner of walking</param>
|
||||
/// <param name="stopBlock">The stop corner of walking</param>
|
||||
/// <param name="ct">CancellationToken to stop the task on cancel</param>
|
||||
public void MineUp(World currentWorld, Location startBlock, Location stopBlock, CancellationToken ct)
|
||||
{
|
||||
if (startBlock.Y != stopBlock.Y)
|
||||
{
|
||||
LogToConsole("Command FAILED. Both coordinates must be on the same y level.");
|
||||
}
|
||||
LogToConsole("Mining bot created by Daenges.");
|
||||
|
||||
IEnumerable<int> xLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.X)), Convert.ToInt32(Math.Round(stopBlock.X)));
|
||||
IEnumerable<int> zLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.Z)), Convert.ToInt32(Math.Round(stopBlock.Z)));
|
||||
Handler.dispatcher.Register(l => l.Literal(CommandName)
|
||||
.Then(l => l.Argument("Commands", Arguments.GreedyString())
|
||||
.Executes(r => {
|
||||
EvaluateMineCommand(CommandName + ' ' + Arguments.GetString(r, "Commands"), Arguments.GetString(r, "Commands").Split(' ', StringSplitOptions.TrimEntries));
|
||||
return r.Source.SetAndReturn(CmdResult.Status.Done);
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
foreach (int currentXLoc in xLocationRange)
|
||||
{
|
||||
foreach (int currentZLoc in zLocationRange)
|
||||
{
|
||||
Location standLocation = new Location(currentXLoc, startBlock.Y, currentZLoc);
|
||||
public override void OnUnload()
|
||||
{
|
||||
Handler.dispatcher.Unregister(CommandName);
|
||||
}
|
||||
|
||||
// Walk to the new location.
|
||||
waitForMoveToLocation(standLocation, maxOffset: 1);
|
||||
/// <summary>
|
||||
/// Walks in a 2 high area under an area of blocks and mines anything above its head.
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">The current world</param>
|
||||
/// <param name="startBlock">The start corner of walking</param>
|
||||
/// <param name="stopBlock">The stop corner of walking</param>
|
||||
/// <param name="ct">CancellationToken to stop the task on cancel</param>
|
||||
public void MineUp(World currentWorld, Location startBlock, Location stopBlock, CancellationToken ct)
|
||||
{
|
||||
if (startBlock.Y != stopBlock.Y)
|
||||
{
|
||||
LogToConsole("Command FAILED. Both coordinates must be on the same y level.");
|
||||
}
|
||||
|
||||
for (int height = Convert.ToInt32(startBlock.Y) + 2; height < Convert.ToInt32(startBlock.Y) + 7; height++)
|
||||
{
|
||||
if (ct.IsCancellationRequested)
|
||||
{
|
||||
currentMiningTask = null;
|
||||
LogToConsole("Cancellation requested. STOP MINING.");
|
||||
return;
|
||||
}
|
||||
IEnumerable<int> xLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.X)), Convert.ToInt32(Math.Round(stopBlock.X)));
|
||||
IEnumerable<int> zLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.Z)), Convert.ToInt32(Math.Round(stopBlock.Z)));
|
||||
|
||||
Location mineLocation = new Location(currentXLoc, height, currentZLoc);
|
||||
Material mineLocationMaterial = currentWorld.GetBlock(mineLocation).Type;
|
||||
foreach (int currentXLoc in xLocationRange)
|
||||
{
|
||||
foreach (int currentZLoc in zLocationRange)
|
||||
{
|
||||
Location standLocation = new Location(currentXLoc, startBlock.Y, currentZLoc);
|
||||
|
||||
// Stop mining process if breaking the next block could endager the bot
|
||||
// through falling blocks or liquids.
|
||||
if (!IsGravitySave(currentWorld, mineLocation) || IsSorroundedByLiquid(currentWorld, mineLocation)) { break; }
|
||||
// Skip this block if it can not be mined.
|
||||
if (Material2Tool.IsUnbreakable(mineLocationMaterial)) { continue; }
|
||||
// Walk to the new location.
|
||||
waitForMoveToLocation(standLocation, maxOffset: 1);
|
||||
|
||||
if (GetInventoryEnabled() && toolHandling)
|
||||
{
|
||||
// Search this tool in hotbar and select the correct slot
|
||||
SelectCorrectSlotInHotbar(
|
||||
// Returns the correct tool for this type
|
||||
Material2Tool.GetCorrectToolForBlock(
|
||||
// returns the type of the current block
|
||||
mineLocationMaterial));
|
||||
}
|
||||
for (int height = Convert.ToInt32(startBlock.Y) + 2; height < Convert.ToInt32(startBlock.Y) + 7; height++)
|
||||
{
|
||||
if (ct.IsCancellationRequested)
|
||||
{
|
||||
currentMiningTask = null;
|
||||
LogToConsole("Cancellation requested. STOP MINING.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are able to reach the block && break sucessfully sent
|
||||
if (GetCurrentLocation().EyesLocation().DistanceSquared(mineLocation) <= 25 && DigBlock(mineLocation))
|
||||
{
|
||||
AutoTimeout.Perform(() =>
|
||||
{
|
||||
while (GetWorld().GetBlock(mineLocation).Type != Material.Air)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
Location mineLocation = new Location(currentXLoc, height, currentZLoc);
|
||||
Material mineLocationMaterial = currentWorld.GetBlock(mineLocation).Type;
|
||||
|
||||
if (ct.IsCancellationRequested)
|
||||
break;
|
||||
}
|
||||
}, breakTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDebugToConsole("Unable to break this block: " + mineLocation.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LogToConsole("Finished mining up.");
|
||||
}
|
||||
// Stop mining process if breaking the next block could endager the bot
|
||||
// through falling blocks or liquids.
|
||||
if (!IsGravitySave(currentWorld, mineLocation) || IsSorroundedByLiquid(currentWorld, mineLocation)) { break; }
|
||||
// Skip this block if it can not be mined.
|
||||
if (Material2Tool.IsUnbreakable(mineLocationMaterial)) { continue; }
|
||||
|
||||
/// <summary>
|
||||
/// Mine a cube of blocks from top to bottom between start and stop location
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">The current world</param>
|
||||
/// <param name="startBlock">The upper corner of the cube to mine</param>
|
||||
/// <param name="stopBlock">The lower corner of the cube to mine</param>
|
||||
/// <param name="ct">CancellationToken to stop the task on cancel</param>
|
||||
public void Mine(World currentWorld, Location startBlock, Location stopBlock, CancellationToken ct)
|
||||
{
|
||||
// Turn the cube around, so the bot always starts from the top.
|
||||
if (stopBlock.Y > startBlock.Y)
|
||||
{
|
||||
Location temp = stopBlock;
|
||||
stopBlock = startBlock;
|
||||
startBlock = temp;
|
||||
}
|
||||
if (GetInventoryEnabled() && toolHandling)
|
||||
{
|
||||
// Search this tool in hotbar and select the correct slot
|
||||
SelectCorrectSlotInHotbar(
|
||||
// Returns the correct tool for this type
|
||||
Material2Tool.GetCorrectToolForBlock(
|
||||
// returns the type of the current block
|
||||
mineLocationMaterial));
|
||||
}
|
||||
|
||||
IEnumerable<int> xLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.X)), Convert.ToInt32(Math.Round(stopBlock.X)));
|
||||
IEnumerable<int> yLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.Y)), Convert.ToInt32(Math.Round(stopBlock.Y)));
|
||||
IEnumerable<int> zLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.Z)), Convert.ToInt32(Math.Round(stopBlock.Z)));
|
||||
// If we are able to reach the block && break sucessfully sent
|
||||
if (GetCurrentLocation().EyesLocation().DistanceSquared(mineLocation) <= 25 && DigBlock(mineLocation))
|
||||
{
|
||||
AutoTimeout.Perform(() =>
|
||||
{
|
||||
while (GetWorld().GetBlock(mineLocation).Type != Material.Air)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
|
||||
foreach (int currentYLoc in yLocationRange)
|
||||
{
|
||||
foreach (int currentXLoc in xLocationRange)
|
||||
{
|
||||
if (ct.IsCancellationRequested)
|
||||
break;
|
||||
}
|
||||
}, breakTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDebugToConsole("Unable to break this block: " + mineLocation.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LogToConsole("Finished mining up.");
|
||||
}
|
||||
|
||||
if (ct.IsCancellationRequested)
|
||||
{
|
||||
currentMiningTask = null;
|
||||
LogToConsole("Cancellation requested. STOP MINING.");
|
||||
return;
|
||||
}
|
||||
/// <summary>
|
||||
/// Mine a cube of blocks from top to bottom between start and stop location
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">The current world</param>
|
||||
/// <param name="startBlock">The upper corner of the cube to mine</param>
|
||||
/// <param name="stopBlock">The lower corner of the cube to mine</param>
|
||||
/// <param name="ct">CancellationToken to stop the task on cancel</param>
|
||||
public void Mine(World currentWorld, Location startBlock, Location stopBlock, CancellationToken ct)
|
||||
{
|
||||
// Turn the cube around, so the bot always starts from the top.
|
||||
if (stopBlock.Y > startBlock.Y)
|
||||
{
|
||||
Location temp = stopBlock;
|
||||
stopBlock = startBlock;
|
||||
startBlock = temp;
|
||||
}
|
||||
|
||||
List<Location> blocksToMine = null;
|
||||
IEnumerable<int> xLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.X)), Convert.ToInt32(Math.Round(stopBlock.X)));
|
||||
IEnumerable<int> yLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.Y)), Convert.ToInt32(Math.Round(stopBlock.Y)));
|
||||
IEnumerable<int> zLocationRange = GetNumbersFromTo(Convert.ToInt32(Math.Round(startBlock.Z)), Convert.ToInt32(Math.Round(stopBlock.Z)));
|
||||
|
||||
// If the end of the new row is closer than the start, reverse the line and start here
|
||||
Location currentStandingLoc = GetCurrentLocation();
|
||||
Queue<int> currentZLocationRangeQueue = new Queue<int>(currentStandingLoc.DistanceSquared(new Location(currentXLoc, currentYLoc, zLocationRange.Last())) < currentStandingLoc.DistanceSquared(new Location(currentXLoc, currentYLoc, zLocationRange.First())) ?
|
||||
zLocationRange.Reverse() :
|
||||
zLocationRange);
|
||||
foreach (int currentYLoc in yLocationRange)
|
||||
{
|
||||
foreach (int currentXLoc in xLocationRange)
|
||||
{
|
||||
|
||||
while (!ct.IsCancellationRequested && (currentZLocationRangeQueue.Count > 0 || blocksToMine.Count > 0))
|
||||
{
|
||||
// Evaluate the next blocks to mine, while mining
|
||||
Task<List<Location>> cacheEval = Task<List<Location>>.Factory.StartNew(() => // Get a new chunk of blocks that can be mined
|
||||
EvaluateBlocks(currentWorld, currentXLoc, currentYLoc, currentZLocationRangeQueue, ct, cacheSize));
|
||||
if (ct.IsCancellationRequested)
|
||||
{
|
||||
currentMiningTask = null;
|
||||
LogToConsole("Cancellation requested. STOP MINING.");
|
||||
return;
|
||||
}
|
||||
|
||||
// On the first run, we need the task to finish, otherwise we would not have any results
|
||||
if (blocksToMine != null)
|
||||
{
|
||||
// For all blocks in this block chunk
|
||||
foreach (Location mineLocation in blocksToMine)
|
||||
{
|
||||
if (ct.IsCancellationRequested)
|
||||
break;
|
||||
List<Location> blocksToMine = null;
|
||||
|
||||
Location currentLoc = GetCurrentLocation();
|
||||
Location currentBlockUnderFeet = new Location(Math.Floor(currentLoc.X), Math.Floor(currentLoc.Y) - 1, Math.Floor(currentLoc.Z));
|
||||
// If the end of the new row is closer than the start, reverse the line and start here
|
||||
Location currentStandingLoc = GetCurrentLocation();
|
||||
Queue<int> currentZLocationRangeQueue = new Queue<int>(currentStandingLoc.DistanceSquared(new Location(currentXLoc, currentYLoc, zLocationRange.Last())) < currentStandingLoc.DistanceSquared(new Location(currentXLoc, currentYLoc, zLocationRange.First())) ?
|
||||
zLocationRange.Reverse() :
|
||||
zLocationRange);
|
||||
|
||||
// If we are too far away from the mining location
|
||||
if (currentLoc.EyesLocation().DistanceSquared(mineLocation) > 25)
|
||||
{
|
||||
// Walk to the new location
|
||||
waitForMoveToLocation(mineLocation, maxOffset:3);
|
||||
}
|
||||
while (!ct.IsCancellationRequested && (currentZLocationRangeQueue.Count > 0 || blocksToMine.Count > 0))
|
||||
{
|
||||
// Evaluate the next blocks to mine, while mining
|
||||
Task<List<Location>> cacheEval = Task<List<Location>>.Factory.StartNew(() => // Get a new chunk of blocks that can be mined
|
||||
EvaluateBlocks(currentWorld, currentXLoc, currentYLoc, currentZLocationRangeQueue, ct, cacheSize));
|
||||
|
||||
// Prevent falling into danger
|
||||
if (mineLocation == currentBlockUnderFeet && !Movement.IsSafe(currentWorld, currentBlockUnderFeet))
|
||||
waitForMoveToLocation(mineLocation, maxOffset: 4, minOffset:3);
|
||||
// On the first run, we need the task to finish, otherwise we would not have any results
|
||||
if (blocksToMine != null)
|
||||
{
|
||||
// For all blocks in this block chunk
|
||||
foreach (Location mineLocation in blocksToMine)
|
||||
{
|
||||
if (ct.IsCancellationRequested)
|
||||
break;
|
||||
|
||||
// Is inventoryhandling activated?
|
||||
if (GetInventoryEnabled() && toolHandling)
|
||||
{
|
||||
// Search this tool in hotbar and select the correct slot
|
||||
SelectCorrectSlotInHotbar(
|
||||
// Returns the correct tool for this type
|
||||
Material2Tool.GetCorrectToolForBlock(
|
||||
// returns the type of the current block
|
||||
currentWorld.GetBlock(mineLocation).Type));
|
||||
}
|
||||
Location currentLoc = GetCurrentLocation();
|
||||
Location currentBlockUnderFeet = new Location(Math.Floor(currentLoc.X), Math.Floor(currentLoc.Y) - 1, Math.Floor(currentLoc.Z));
|
||||
|
||||
// If we are able to reach the block && break sucessfully sent
|
||||
if (GetCurrentLocation().EyesLocation().DistanceSquared(mineLocation) <= 25 && DigBlock(mineLocation))
|
||||
{
|
||||
// Wait until the block is broken (== Air)
|
||||
AutoTimeout.Perform(() =>
|
||||
{
|
||||
while (GetWorld().GetBlock(mineLocation).Type != Material.Air)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
// If we are too far away from the mining location
|
||||
if (currentLoc.EyesLocation().DistanceSquared(mineLocation) > 25)
|
||||
{
|
||||
// Walk to the new location
|
||||
waitForMoveToLocation(mineLocation, maxOffset: 3);
|
||||
}
|
||||
|
||||
if (ct.IsCancellationRequested)
|
||||
break;
|
||||
}
|
||||
}, breakTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDebugToConsole("Unable to break this block: " + mineLocation.ToString());
|
||||
}
|
||||
// Prevent falling into danger
|
||||
if (mineLocation == currentBlockUnderFeet && !Movement.IsSafe(currentWorld, currentBlockUnderFeet))
|
||||
waitForMoveToLocation(mineLocation, maxOffset: 4, minOffset: 3);
|
||||
|
||||
}
|
||||
}
|
||||
// Is inventoryhandling activated?
|
||||
if (GetInventoryEnabled() && toolHandling)
|
||||
{
|
||||
// Search this tool in hotbar and select the correct slot
|
||||
SelectCorrectSlotInHotbar(
|
||||
// Returns the correct tool for this type
|
||||
Material2Tool.GetCorrectToolForBlock(
|
||||
// returns the type of the current block
|
||||
currentWorld.GetBlock(mineLocation).Type));
|
||||
}
|
||||
|
||||
if (!ct.IsCancellationRequested)
|
||||
{
|
||||
// Wait for the block evaluation task to finish (if not already) and save the result
|
||||
if (!cacheEval.IsCompleted)
|
||||
{
|
||||
cacheEval.Wait();
|
||||
}
|
||||
blocksToMine = cacheEval.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
currentMiningTask = null;
|
||||
LogToConsole("MINING FINISHED.");
|
||||
}
|
||||
// If we are able to reach the block && break sucessfully sent
|
||||
if (GetCurrentLocation().EyesLocation().DistanceSquared(mineLocation) <= 25 && DigBlock(mineLocation))
|
||||
{
|
||||
// Wait until the block is broken (== Air)
|
||||
AutoTimeout.Perform(() =>
|
||||
{
|
||||
while (GetWorld().GetBlock(mineLocation).Type != Material.Air)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
|
||||
/// <summary>
|
||||
/// This function selects a certain amount of minable blocks in a row
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">The current world</param>
|
||||
/// <param name="xLoc">The current x location of the row</param>
|
||||
/// <param name="yLoc">The current y location of the row</param>
|
||||
/// <param name="zLocationQueue">All Z blocks that will be mined</param>
|
||||
/// <param name="ct">CancellationToken to stop the task on cancel</param>
|
||||
/// <param name="cacheSize">Maximum amount of blocks to return</param>
|
||||
/// <returns></returns>
|
||||
private List<Location> EvaluateBlocks(World currentWorld, int xLoc, int yLoc, Queue<int> zLocationQueue, CancellationToken ct, int cacheSize = 10)
|
||||
{
|
||||
List<Location> blockMiningCache = new List<Location>();
|
||||
int i = 0;
|
||||
while (zLocationQueue.Count > 0 && i < cacheSize && !ct.IsCancellationRequested)
|
||||
{
|
||||
// Get the block to mine, relative to the startblock of the row
|
||||
Location mineLocation = new Location(xLoc, yLoc, zLocationQueue.Dequeue());
|
||||
if (ct.IsCancellationRequested)
|
||||
break;
|
||||
}
|
||||
}, breakTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDebugToConsole("Unable to break this block: " + mineLocation.ToString());
|
||||
}
|
||||
|
||||
// Add the current location to the mining cache if it is safe to mine
|
||||
if (currentWorld.GetBlock(mineLocation).Type != Material.Air &&
|
||||
IsGravitySave(currentWorld, mineLocation) &&
|
||||
!IsSorroundedByLiquid(currentWorld, mineLocation) &&
|
||||
!Material2Tool.IsUnbreakable(currentWorld.GetBlock(mineLocation).Type))
|
||||
{
|
||||
blockMiningCache.Add(mineLocation);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return blockMiningCache;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a sequence of numbers between a start and a stop number, including both
|
||||
/// </summary>
|
||||
/// <param name="start">Number to start from</param>
|
||||
/// <param name="stop">Number to end with</param>
|
||||
/// <returns>a sequence of numbers between a start and a stop number, including both</returns>
|
||||
private static IEnumerable<int> GetNumbersFromTo(int start, int stop)
|
||||
{
|
||||
return start <= stop ? Enumerable.Range(start, stop - start + 1) : Enumerable.Range(stop, start - stop + 1).Reverse();
|
||||
}
|
||||
if (!ct.IsCancellationRequested)
|
||||
{
|
||||
// Wait for the block evaluation task to finish (if not already) and save the result
|
||||
if (!cacheEval.IsCompleted)
|
||||
{
|
||||
cacheEval.Wait();
|
||||
}
|
||||
blocksToMine = cacheEval.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
currentMiningTask = null;
|
||||
LogToConsole("MINING FINISHED.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts walk and waits until the client arrives
|
||||
/// </summary>
|
||||
/// <param name="location">Location to reach</param>
|
||||
/// <param name="allowUnsafe">Allow possible but unsafe locations thay may hurt the player: lava, cactus...</param>
|
||||
/// <param name="allowDirectTeleport">Allow non-vanilla direct teleport instead of computing path, but may cause invalid moves and/or trigger anti-cheat plugins</param>
|
||||
/// <param name="maxOffset">If no valid path can be found, also allow locations within specified distance of destination</param>
|
||||
/// <param name="minOffset">Do not get closer of destination than specified distance</param>
|
||||
/// <param name="timeout">How long to wait before stopping computation (default: 5 seconds)</param>
|
||||
private void waitForMoveToLocation(Location goal, bool allowUnsafe = false, bool allowDirectTeleport = false, int maxOffset = 0, int minOffset = 0, TimeSpan? timeout = null)
|
||||
{
|
||||
if (MoveToLocation(goal, allowUnsafe, allowDirectTeleport, maxOffset, minOffset, timeout))
|
||||
{
|
||||
// Wait till the client stops moving
|
||||
while (ClientIsMoving())
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDebugToConsole("Unable to walk to: " + goal.ToString());
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// This function selects a certain amount of minable blocks in a row
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">The current world</param>
|
||||
/// <param name="xLoc">The current x location of the row</param>
|
||||
/// <param name="yLoc">The current y location of the row</param>
|
||||
/// <param name="zLocationQueue">All Z blocks that will be mined</param>
|
||||
/// <param name="ct">CancellationToken to stop the task on cancel</param>
|
||||
/// <param name="cacheSize">Maximum amount of blocks to return</param>
|
||||
/// <returns></returns>
|
||||
private List<Location> EvaluateBlocks(World currentWorld, int xLoc, int yLoc, Queue<int> zLocationQueue, CancellationToken ct, int cacheSize = 10)
|
||||
{
|
||||
List<Location> blockMiningCache = new List<Location>();
|
||||
int i = 0;
|
||||
while (zLocationQueue.Count > 0 && i < cacheSize && !ct.IsCancellationRequested)
|
||||
{
|
||||
// Get the block to mine, relative to the startblock of the row
|
||||
Location mineLocation = new Location(xLoc, yLoc, zLocationQueue.Dequeue());
|
||||
|
||||
/// <summary>
|
||||
/// Checks all slots of the hotbar for an Item and selects it if found
|
||||
/// </summary>
|
||||
/// <param name="tools">List of items that may be selected, from worst to best</param>
|
||||
private void SelectCorrectSlotInHotbar(ItemType[] tools)
|
||||
{
|
||||
if (GetInventoryEnabled())
|
||||
{
|
||||
foreach (ItemType tool in tools)
|
||||
{
|
||||
int[] tempArray = GetPlayerInventory().SearchItem(tool);
|
||||
// Check whether an item could be found and make sure that it is in
|
||||
// a hotbar slot (36-44).
|
||||
if (tempArray.Length > 0 && tempArray[0] > 35)
|
||||
{
|
||||
// Changeslot takes numbers from 0-8
|
||||
ChangeSlot(Convert.ToInt16(tempArray[0] - 36));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogToConsole("Activate Inventory Handling.");
|
||||
}
|
||||
}
|
||||
// Add the current location to the mining cache if it is safe to mine
|
||||
if (currentWorld.GetBlock(mineLocation).Type != Material.Air &&
|
||||
IsGravitySave(currentWorld, mineLocation) &&
|
||||
!IsSorroundedByLiquid(currentWorld, mineLocation) &&
|
||||
!Material2Tool.IsUnbreakable(currentWorld.GetBlock(mineLocation).Type))
|
||||
{
|
||||
blockMiningCache.Add(mineLocation);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return blockMiningCache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if mining the current block would update others
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">Current World</param>
|
||||
/// <param name="blockToMine">The block to be checked</param>
|
||||
/// <returns>true if mining the current block would not update others</returns>
|
||||
public bool IsGravitySave(World currentWorld, Location blockToMine)
|
||||
{
|
||||
Location currentLoc = GetCurrentLocation();
|
||||
Location block = new Location(Math.Round(blockToMine.X), Math.Round(blockToMine.Y), Math.Round(blockToMine.Z));
|
||||
List<Material> gravityBlockList = new List<Material>(new Material[] { Material.Gravel, Material.Sand, Material.RedSand, Material.Scaffolding, Material.Anvil, });
|
||||
Func<Location, bool> isGravityBlock = (Location blockToCheck) => gravityBlockList.Contains(currentWorld.GetBlock(blockToCheck).Type);
|
||||
Func<Location, bool> isBlockSolid = (Location blockToCheck) => currentWorld.GetBlock(blockToCheck).Type.IsSolid();
|
||||
/// <summary>
|
||||
/// Generates a sequence of numbers between a start and a stop number, including both
|
||||
/// </summary>
|
||||
/// <param name="start">Number to start from</param>
|
||||
/// <param name="stop">Number to end with</param>
|
||||
/// <returns>a sequence of numbers between a start and a stop number, including both</returns>
|
||||
private static IEnumerable<int> GetNumbersFromTo(int start, int stop)
|
||||
{
|
||||
return start <= stop ? Enumerable.Range(start, stop - start + 1) : Enumerable.Range(stop, start - stop + 1).Reverse();
|
||||
}
|
||||
|
||||
return
|
||||
// Block can not fall down on player e.g. Sand, Gravel etc.
|
||||
!isGravityBlock(Movement.Move(block, Direction.Up)) &&
|
||||
(Movement.Move(currentLoc, Direction.Down) != blockToMine || currentWorld.GetBlock(Movement.Move(currentLoc, Direction.Down, 2)).Type.IsSolid()) &&
|
||||
// Prevent updating flying sand/gravel under player
|
||||
!isGravityBlock(Movement.Move(block, Direction.Down)) || isBlockSolid(Movement.Move(block, Direction.Down, 2));
|
||||
}
|
||||
/// <summary>
|
||||
/// Starts walk and waits until the client arrives
|
||||
/// </summary>
|
||||
/// <param name="location">Location to reach</param>
|
||||
/// <param name="allowUnsafe">Allow possible but unsafe locations thay may hurt the player: lava, cactus...</param>
|
||||
/// <param name="allowDirectTeleport">Allow non-vanilla direct teleport instead of computing path, but may cause invalid moves and/or trigger anti-cheat plugins</param>
|
||||
/// <param name="maxOffset">If no valid path can be found, also allow locations within specified distance of destination</param>
|
||||
/// <param name="minOffset">Do not get closer of destination than specified distance</param>
|
||||
/// <param name="timeout">How long to wait before stopping computation (default: 5 seconds)</param>
|
||||
private void waitForMoveToLocation(Location goal, bool allowUnsafe = false, bool allowDirectTeleport = false, int maxOffset = 0, int minOffset = 0, TimeSpan? timeout = null)
|
||||
{
|
||||
if (MoveToLocation(goal, allowUnsafe, allowDirectTeleport, maxOffset, minOffset, timeout))
|
||||
{
|
||||
// Wait till the client stops moving
|
||||
while (ClientIsMoving())
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDebugToConsole("Unable to walk to: " + goal.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current block is sorrounded by liquids
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">Current World</param>
|
||||
/// <param name="blockToMine">The block to be checked</param>
|
||||
/// <returns>true if mining the current block results in liquid flow change</returns>
|
||||
public bool IsSorroundedByLiquid(World currentWorld, Location blockToMine)
|
||||
{
|
||||
Location block = new Location(Math.Round(blockToMine.X), Math.Round(blockToMine.Y), Math.Round(blockToMine.Z));
|
||||
Func<Location, bool> isLiquid = (Location blockToCheck) => currentWorld.GetBlock(blockToCheck).Type.IsLiquid();
|
||||
/// <summary>
|
||||
/// Checks all slots of the hotbar for an Item and selects it if found
|
||||
/// </summary>
|
||||
/// <param name="tools">List of items that may be selected, from worst to best</param>
|
||||
private void SelectCorrectSlotInHotbar(ItemType[] tools)
|
||||
{
|
||||
if (GetInventoryEnabled())
|
||||
{
|
||||
foreach (ItemType tool in tools)
|
||||
{
|
||||
int[] tempArray = GetPlayerInventory().SearchItem(tool);
|
||||
// Check whether an item could be found and make sure that it is in
|
||||
// a hotbar slot (36-44).
|
||||
if (tempArray.Length > 0 && tempArray[0] > 35)
|
||||
{
|
||||
// Changeslot takes numbers from 0-8
|
||||
ChangeSlot(Convert.ToInt16(tempArray[0] - 36));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogToConsole("Activate Inventory Handling.");
|
||||
}
|
||||
}
|
||||
|
||||
return // Liquid can not flow down the hole. Liquid is unable to flow diagonally.
|
||||
isLiquid(block) ||
|
||||
isLiquid(Movement.Move(block, Direction.Up)) ||
|
||||
isLiquid(Movement.Move(block, Direction.North)) ||
|
||||
isLiquid(Movement.Move(block, Direction.South)) ||
|
||||
isLiquid(Movement.Move(block, Direction.East)) ||
|
||||
isLiquid(Movement.Move(block, Direction.West));
|
||||
}
|
||||
/// <summary>
|
||||
/// Check if mining the current block would update others
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">Current World</param>
|
||||
/// <param name="blockToMine">The block to be checked</param>
|
||||
/// <returns>true if mining the current block would not update others</returns>
|
||||
public bool IsGravitySave(World currentWorld, Location blockToMine)
|
||||
{
|
||||
Location currentLoc = GetCurrentLocation();
|
||||
Location block = new Location(Math.Round(blockToMine.X), Math.Round(blockToMine.Y), Math.Round(blockToMine.Z));
|
||||
List<Material> gravityBlockList = new List<Material>(new Material[] { Material.Gravel, Material.Sand, Material.RedSand, Material.Scaffolding, Material.Anvil, });
|
||||
Func<Location, bool> isGravityBlock = (Location blockToCheck) => gravityBlockList.Contains(currentWorld.GetBlock(blockToCheck).Type);
|
||||
Func<Location, bool> isBlockSolid = (Location blockToCheck) => currentWorld.GetBlock(blockToCheck).Type.IsSolid();
|
||||
|
||||
/// <summary>
|
||||
/// The Help page for this command.
|
||||
/// </summary>
|
||||
/// <returns>a help page</returns>
|
||||
private string getHelpPage()
|
||||
{
|
||||
return
|
||||
"Usage of the mine bot:\n" +
|
||||
"/mine <x1> <y1> <z1> <x2> <y2> <z2> OR /mine <x> <y> <z>\n" +
|
||||
"to excavate a cube of blocks from top to bottom. (There must be a 2 high area of air above the cube you want to mine.)\n" +
|
||||
"/mineup <x1> <y1> <z1> <x2> <y1> <z2> OR /mineup <x> <y> <z>\n" +
|
||||
"to walk over a quadratic field of blocks and simultaniously mine everything above the head. \n" +
|
||||
"(Mines up to 5 Blocks, stops if gravel or lava would fall. There must be a 2 high area of air below the cube you want to mine.)\n" +
|
||||
"/mine OR /mineup cancel\n" +
|
||||
"to cancel the current mining process.\n" +
|
||||
"/mine OR /mineup cachesize\n" +
|
||||
"to set the current cache size\n" +
|
||||
"/mine OR /mineup breaktimeout\n" +
|
||||
"to set the time to wait until a block is broken."; ;
|
||||
return
|
||||
// Block can not fall down on player e.g. Sand, Gravel etc.
|
||||
!isGravityBlock(Movement.Move(block, Direction.Up)) &&
|
||||
(Movement.Move(currentLoc, Direction.Down) != blockToMine || currentWorld.GetBlock(Movement.Move(currentLoc, Direction.Down, 2)).Type.IsSolid()) &&
|
||||
// Prevent updating flying sand/gravel under player
|
||||
!isGravityBlock(Movement.Move(block, Direction.Down)) || isBlockSolid(Movement.Move(block, Direction.Down, 2));
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Checks if the current block is sorrounded by liquids
|
||||
/// </summary>
|
||||
/// <param name="currentWorld">Current World</param>
|
||||
/// <param name="blockToMine">The block to be checked</param>
|
||||
/// <returns>true if mining the current block results in liquid flow change</returns>
|
||||
public bool IsSorroundedByLiquid(World currentWorld, Location blockToMine)
|
||||
{
|
||||
Location block = new Location(Math.Round(blockToMine.X), Math.Round(blockToMine.Y), Math.Round(blockToMine.Z));
|
||||
Func<Location, bool> isLiquid = (Location blockToCheck) => currentWorld.GetBlock(blockToCheck).Type.IsLiquid();
|
||||
|
||||
private string EvaluateMineCommand(string command, string[] args)
|
||||
{
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
switch (args[i])
|
||||
{
|
||||
case "breaktimeout":
|
||||
int temp;
|
||||
if (int.TryParse(args[i + 1], out temp))
|
||||
breakTimeout = TimeSpan.FromMilliseconds(temp);
|
||||
else return "Please enter a valid number.";
|
||||
return string.Format("Set the break timout to {0} ms.", breakTimeout);
|
||||
return // Liquid can not flow down the hole. Liquid is unable to flow diagonally.
|
||||
isLiquid(block) ||
|
||||
isLiquid(Movement.Move(block, Direction.Up)) ||
|
||||
isLiquid(Movement.Move(block, Direction.North)) ||
|
||||
isLiquid(Movement.Move(block, Direction.South)) ||
|
||||
isLiquid(Movement.Move(block, Direction.East)) ||
|
||||
isLiquid(Movement.Move(block, Direction.West));
|
||||
}
|
||||
|
||||
case "cachesize":
|
||||
return int.TryParse(args[i + 1], out cacheSize) ? string.Format("Set cache size to {0} blocks.", cacheSize) : "Please enter a valid number";
|
||||
/// <summary>
|
||||
/// The Help page for this command.
|
||||
/// </summary>
|
||||
/// <returns>a help page</returns>
|
||||
private string getHelpPage()
|
||||
{
|
||||
return
|
||||
"Usage of the mine bot:\n" +
|
||||
"/mine <x1> <y1> <z1> <x2> <y2> <z2> OR /mine <x> <y> <z>\n" +
|
||||
"to excavate a cube of blocks from top to bottom. (There must be a 2 high area of air above the cube you want to mine.)\n" +
|
||||
"/mineup <x1> <y1> <z1> <x2> <y1> <z2> OR /mineup <x> <y> <z>\n" +
|
||||
"to walk over a quadratic field of blocks and simultaniously mine everything above the head. \n" +
|
||||
"(Mines up to 5 Blocks, stops if gravel or lava would fall. There must be a 2 high area of air below the cube you want to mine.)\n" +
|
||||
"/mine OR /mineup cancel\n" +
|
||||
"to cancel the current mining process.\n" +
|
||||
"/mine OR /mineup cachesize\n" +
|
||||
"to set the current cache size\n" +
|
||||
"/mine OR /mineup breaktimeout\n" +
|
||||
"to set the time to wait until a block is broken."; ;
|
||||
|
||||
case "cancel":
|
||||
cts.Cancel();
|
||||
currentMiningTask = null;
|
||||
return "Cancelled current mining process.";
|
||||
}
|
||||
|
||||
case "toolHandling":
|
||||
toolHandling = !toolHandling;
|
||||
return string.Format("Tool handling was set to: {0}", toolHandling.ToString());
|
||||
}
|
||||
}
|
||||
private string EvaluateMineCommand(string command, string[] args)
|
||||
{
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
switch (args[i])
|
||||
{
|
||||
case "breaktimeout":
|
||||
int temp;
|
||||
if (int.TryParse(args[i + 1], out temp))
|
||||
breakTimeout = TimeSpan.FromMilliseconds(temp);
|
||||
else return "Please enter a valid number.";
|
||||
return string.Format("Set the break timout to {0} ms.", breakTimeout);
|
||||
|
||||
if (args.Length > 2)
|
||||
{
|
||||
Location startBlock;
|
||||
Location stopBlock;
|
||||
case "cachesize":
|
||||
return int.TryParse(args[i + 1], out cacheSize) ? string.Format("Set cache size to {0} blocks.", cacheSize) : "Please enter a valid number";
|
||||
|
||||
if (args.Length > 5)
|
||||
{
|
||||
try
|
||||
{
|
||||
startBlock = new Location(
|
||||
double.Parse(args[0]),
|
||||
double.Parse(args[1]),
|
||||
double.Parse(args[2])
|
||||
);
|
||||
case "cancel":
|
||||
cts.Cancel();
|
||||
currentMiningTask = null;
|
||||
return "Cancelled current mining process.";
|
||||
|
||||
stopBlock = new Location(
|
||||
double.Parse(args[3]),
|
||||
double.Parse(args[4]),
|
||||
double.Parse(args[5])
|
||||
);
|
||||
case "toolHandling":
|
||||
toolHandling = !toolHandling;
|
||||
return string.Format("Tool handling was set to: {0}", toolHandling.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogDebugToConsole(e.ToString());
|
||||
return "Please enter correct coordinates as numbers.\n" + getHelpPage();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Location tempLoc = GetCurrentLocation();
|
||||
startBlock = new Location(Math.Round(tempLoc.X),
|
||||
Math.Round(tempLoc.Y),
|
||||
Math.Round(tempLoc.Z));
|
||||
if (args.Length > 2)
|
||||
{
|
||||
Location startBlock;
|
||||
Location stopBlock;
|
||||
|
||||
try
|
||||
{
|
||||
stopBlock = new Location(
|
||||
double.Parse(args[0]),
|
||||
double.Parse(args[1]),
|
||||
double.Parse(args[2])
|
||||
);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogDebugToConsole(e.ToString());
|
||||
return "Please enter correct coordinates as numbers.\n" + getHelpPage();
|
||||
}
|
||||
}
|
||||
if (args.Length > 5)
|
||||
{
|
||||
try
|
||||
{
|
||||
startBlock = new Location(
|
||||
double.Parse(args[0]),
|
||||
double.Parse(args[1]),
|
||||
double.Parse(args[2])
|
||||
);
|
||||
|
||||
if (currentMiningTask == null)
|
||||
{
|
||||
if (command.Contains("mineup"))
|
||||
{
|
||||
cts = new CancellationTokenSource();
|
||||
stopBlock = new Location(
|
||||
double.Parse(args[3]),
|
||||
double.Parse(args[4]),
|
||||
double.Parse(args[5])
|
||||
);
|
||||
|
||||
currentMiningTask = Task.Factory.StartNew(() => MineUp(GetWorld(), startBlock, stopBlock, cts.Token));
|
||||
return "Start mining up.";
|
||||
}
|
||||
else if (command.Contains("mine"))
|
||||
{
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogDebugToConsole(e.ToString());
|
||||
return "Please enter correct coordinates as numbers.\n" + getHelpPage();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Location tempLoc = GetCurrentLocation();
|
||||
startBlock = new Location(Math.Round(tempLoc.X),
|
||||
Math.Round(tempLoc.Y),
|
||||
Math.Round(tempLoc.Z));
|
||||
|
||||
cts = new CancellationTokenSource();
|
||||
try
|
||||
{
|
||||
stopBlock = new Location(
|
||||
double.Parse(args[0]),
|
||||
double.Parse(args[1]),
|
||||
double.Parse(args[2])
|
||||
);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogDebugToConsole(e.ToString());
|
||||
return "Please enter correct coordinates as numbers.\n" + getHelpPage();
|
||||
}
|
||||
}
|
||||
|
||||
currentMiningTask = Task.Factory.StartNew(() => Mine(GetWorld(), startBlock, stopBlock, cts.Token));
|
||||
return "Start mining cube.";
|
||||
}
|
||||
}
|
||||
else return "You are already mining. Cancel it with '/minecancel'";
|
||||
}
|
||||
if (currentMiningTask == null)
|
||||
{
|
||||
if (command.Contains("mineup"))
|
||||
{
|
||||
cts = new CancellationTokenSource();
|
||||
|
||||
return "Invalid command syntax.\n" + getHelpPage();
|
||||
}
|
||||
}
|
||||
currentMiningTask = Task.Factory.StartNew(() => MineUp(GetWorld(), startBlock, stopBlock, cts.Token));
|
||||
return "Start mining up.";
|
||||
}
|
||||
else if (command.Contains("mine"))
|
||||
{
|
||||
|
||||
cts = new CancellationTokenSource();
|
||||
|
||||
currentMiningTask = Task.Factory.StartNew(() => Mine(GetWorld(), startBlock, stopBlock, cts.Token));
|
||||
return "Start mining cube.";
|
||||
}
|
||||
}
|
||||
else return "You are already mining. Cancel it with '/minecancel'";
|
||||
}
|
||||
|
||||
return "Invalid command syntax.\n" + getHelpPage();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
//using System.Threading.Tasks;
|
||||
|
||||
//==== CONFIG START ====
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
//using System.Threading.Tasks;
|
||||
|
||||
MCC.LoadBot(new QIWI_DonationBot());
|
||||
|
|
@ -6,8 +6,8 @@ MCC.LoadBot(new QIWI_DonationBot());
|
|||
//MCCScript Extensions
|
||||
|
||||
public class QIWI_DonationBot : ChatBot
|
||||
{
|
||||
//More info: https://github.com/Nekiplay/QIWI-API
|
||||
{
|
||||
//More info: https://github.com/Nekiplay/QIWI-API
|
||||
public override void Initialize()
|
||||
{
|
||||
QIWI.Donation donation = new QIWI.Donation("token", OnDonate);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,15 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
//using MinecraftClient.Inventory;
|
||||
//using MinecraftClient.Mapping;
|
||||
//using MinecraftClient.Scripting;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Threading;
|
||||
//using System;
|
||||
//using Brigadier.NET.Builder;
|
||||
//using MinecraftClient.CommandHandler.Patch;
|
||||
//using Brigadier.NET;
|
||||
//using MinecraftClient.CommandHandler;
|
||||
//using System.Linq;
|
||||
|
||||
MCC.LoadBot(new SugarCaneFarmer());
|
||||
|
||||
|
|
@ -102,6 +113,8 @@ class SugarCaneFarmerBase : ChatBot
|
|||
|
||||
class SugarCaneFarmer : SugarCaneFarmerBase
|
||||
{
|
||||
public const string CommandName = "sugarcane";
|
||||
|
||||
public enum CoordinateType { X, Y, Z };
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -137,7 +150,19 @@ class SugarCaneFarmer : SugarCaneFarmerBase
|
|||
public override void Initialize()
|
||||
{
|
||||
LogToConsole("Sugar Cane farming bot created by Daenges.");
|
||||
RegisterChatBotCommand("sugarcane", "Farm sugar cane automatically", "/sugarcane [range x|y|z]/[stop]", commandHandler);
|
||||
|
||||
Handler.dispatcher.Register(l => l.Literal(CommandName)
|
||||
.Then(l => l.Argument("Commands", Arguments.GreedyString())
|
||||
.Executes(r => {
|
||||
CommandHandler(Arguments.GetString(r, "Commands").Split(' ', StringSplitOptions.TrimEntries));
|
||||
return r.Source.SetAndReturn(CmdResult.Status.Done);
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
public override void OnUnload()
|
||||
{
|
||||
Handler.dispatcher.Unregister(CommandName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -188,7 +213,7 @@ class SugarCaneFarmer : SugarCaneFarmerBase
|
|||
LogToConsole("[FARMING STOPPED]");
|
||||
}
|
||||
|
||||
private string commandHandler(string command, string[] args)
|
||||
private string CommandHandler(string[] args)
|
||||
{
|
||||
if (args.Length == 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
//using MinecraftClient.CommandHandler;
|
||||
//using MinecraftClient.Mapping;
|
||||
//using MinecraftClient.Scripting;
|
||||
|
||||
MCC.LoadBot(new SugarCaneMiner());
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
//using MinecraftClient.CommandHandler;
|
||||
//using MinecraftClient.Mapping;
|
||||
//using MinecraftClient.Scripting;
|
||||
//using System.Threading;
|
||||
|
||||
MCC.LoadBot(new TreeFarmer());
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,21 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
//using System.Threading.Tasks;
|
||||
//dll Newtonsoft.Json.dll
|
||||
//using Newtonsoft.Json;
|
||||
//using Newtonsoft.Json.Linq;
|
||||
//using Brigadier.NET;
|
||||
//using MinecraftClient.CommandHandler;
|
||||
//using MinecraftClient.Scripting;
|
||||
//using MinecraftClient;
|
||||
//using Newtonsoft.Json.Linq;
|
||||
//using Newtonsoft.Json;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Net;
|
||||
//using System.Text.RegularExpressions;
|
||||
//using System.Text;
|
||||
//using System.Threading.Tasks;
|
||||
//using System;
|
||||
//using System.Linq;
|
||||
|
||||
//==== INFO START ====
|
||||
// Download Newtonsoft.Json.dll and install it into the program folder Link: https://www.newtonsoft.com/json
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Minecraft Console Client
|
||||
# Minecraft Console Client
|
||||
# AutoRespond matches
|
||||
# Example config file
|
||||
|
||||
|
|
@ -71,4 +71,4 @@ match=§ahello
|
|||
action=send Hello back!
|
||||
|
||||
# Enjoy!
|
||||
# - ORelio
|
||||
# - ORelio
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
/* This script demonstrates how to use methods and arguments */
|
||||
|
||||
|
|
@ -28,4 +28,4 @@ void SleepBetweenSends()
|
|||
{
|
||||
MCC.LogToConsole("Sleeping for 5 seconds...");
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
MCC.LoadBot(new PMForwarder());
|
||||
|
||||
|
|
@ -36,4 +36,4 @@ public class PMForwarder : ChatBot
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
string[] commands = new[] {
|
||||
"send command1",
|
||||
|
|
@ -8,4 +8,4 @@ string[] commands = new[] {
|
|||
|
||||
int randomIndex = new Random().Next(0, commands.Length);
|
||||
string randomCommand = commands[randomIndex];
|
||||
MCC.PerformInternalCommand(randomCommand);
|
||||
MCC.PerformInternalCommand(randomCommand);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
/* This is a sample script that will load a ChatBot into Minecraft Console Client
|
||||
* Simply execute the script once with /script or the script scheduler to load the bot */
|
||||
|
|
@ -32,4 +32,4 @@ public class ExampleBot : ChatBot
|
|||
LogToConsole("Private message from " + username + ": " + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
string mojangStatus = PerformHttpRequest("https://status.mojang.com/check");
|
||||
MCC.LogToConsole(mojangStatus);
|
||||
|
|
@ -31,4 +31,4 @@ void SendHttpPostAsync(string uri, string text)
|
|||
responseString = reader.ReadToEnd();
|
||||
//LogToConsole(responseString);
|
||||
}).Start();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
MCC.LoadBot(new PeriodicTask());
|
||||
|
||||
|
|
@ -29,4 +29,4 @@ public class PeriodicTask : ChatBot
|
|||
nextTaskRun = dateNow.AddSeconds(60);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
MCC.LoadBot(new WatchLamp());
|
||||
|
||||
|
|
@ -58,4 +58,4 @@ class WatchLamp : ChatBot
|
|||
}
|
||||
else checkCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//MCCScript 1.0
|
||||
//MCCScript 1.0
|
||||
|
||||
/* This is a sample script for Minecraft Console Client
|
||||
* The code provided in this file will be compiled at runtime and executed
|
||||
|
|
@ -11,4 +11,4 @@ for (int i = 0; i < 5; i++)
|
|||
MCC.SendText("Hello World no. " + count);
|
||||
MCC.LogToConsole("Sleeping for 5 seconds...");
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue