Add AutoDig ChatBot

This commit is contained in:
BruceChen 2022-10-08 17:56:32 +08:00
parent 4cb95731bf
commit c57ac183d5
16 changed files with 579 additions and 64 deletions

View file

@ -38,9 +38,6 @@ namespace MinecraftClient.ChatBots
[TomlInlineComment("$config.ChatBot.AntiAfk.Walk_Retries$")]
public int Walk_Retries = 20;
[NonSerialized]
public int _DelayMin, _DelayMax;
public void OnSettingUpdate()
{
if (Walk_Range <= 0)
@ -61,9 +58,6 @@ namespace MinecraftClient.ChatBots
LogToConsole(BotName, Translations.TryGet("bot.antiafk.swapping"));
}
_DelayMin = (int)Math.Round(Delay.min * 10);
_DelayMax = (int)Math.Round(Delay.max * 10);
Command ??= string.Empty;
}
@ -115,7 +109,7 @@ namespace MinecraftClient.ChatBots
{
DoAntiAfkStuff();
count = 0;
nextrun = random.Next(Config._DelayMin, Config._DelayMax);
nextrun = random.Next(Settings.DoubleToTick(Config.Delay.min), Settings.DoubleToTick(Config.Delay.max));
}
}

View file

@ -0,0 +1,392 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MinecraftClient.Inventory;
using MinecraftClient.Mapping;
using MinecraftClient.Mapping.BlockPalettes;
using Tomlet.Attributes;
using static MinecraftClient.ChatBots.AutoCraft.Configs;
namespace MinecraftClient.ChatBots
{
public class AutoDig : ChatBot
{
public static Configs Config = new();
[TomlDoNotInlineObject]
public class Configs
{
[NonSerialized]
private const string BotName = "AutoDig";
public bool Enabled = false;
[NonSerialized]
[TomlInlineComment("$config.ChatBot.AutoDig.Auto_Tool_Switch$")]
public bool Auto_Tool_Switch = false;
[NonSerialized]
[TomlInlineComment("$config.ChatBot.AutoDig.Durability_Limit$")]
public int Durability_Limit = 2;
[NonSerialized]
[TomlInlineComment("$config.ChatBot.AutoDig.Drop_Low_Durability_Tools$")]
public bool Drop_Low_Durability_Tools = false;
[TomlInlineComment("$config.ChatBot.AutoDig.Mode$")]
public ModeType Mode = ModeType.lookat;
[TomlInlineComment("$config.ChatBot.AutoDig.Locations$")]
public Coordination[] Locations = new Coordination[] { new(123.5, 64, 234.5), new(124.5, 63, 235.5) };
[TomlInlineComment("$config.ChatBot.AutoDig.Auto_Start_Delay$")]
public double Auto_Start_Delay = 3.0;
[TomlInlineComment("$config.ChatBot.AutoDig.Dig_Timeout$")]
public double Dig_Timeout = 30.0;
[TomlInlineComment("$config.ChatBot.AutoDig.Log_Block_Dig$")]
public bool Log_Block_Dig = true;
[TomlInlineComment("$config.ChatBot.AutoDig.List_Type$")]
public ListType List_Type = ListType.whitelist;
public List<Material> Blocks = new() { Material.Cobblestone, Material.Stone };
[NonSerialized]
public Location[] _Locations = Array.Empty<Location>();
public void OnSettingUpdate()
{
if (Auto_Start_Delay >= 0)
Auto_Start_Delay = Math.Max(0.1, Auto_Start_Delay);
if (Dig_Timeout >= 0)
Dig_Timeout = Math.Max(0.1, Dig_Timeout);
_Locations = new Location[Locations.Length];
for (int i = 0; i < Locations.Length; ++i)
_Locations[i] = new(Locations[i].x, Locations[i].y, Locations[i].z);
}
public enum ModeType { lookat, fixedpos, both };
public enum ListType { blacklist, whitelist };
public struct Coordination
{
public double x, y, z;
public Coordination(double x, double y, double z)
{
this.x = x; this.y = y; this.z = z;
}
}
}
private bool inventoryEnabled;
private int counter = 0;
private readonly object stateLock = new();
private State state = State.WaitJoinGame;
bool AlreadyWaitting = false;
private Location currentDig = Location.Zero;
private enum State
{
WaitJoinGame,
WaitingStart,
Digging,
Stopping,
}
public override void Initialize()
{
if (!GetTerrainEnabled())
{
LogToConsoleTranslated("extra.terrainandmovement_required");
LogToConsoleTranslated("general.bot_unload");
UnloadBot();
return;
}
inventoryEnabled = GetInventoryEnabled();
if (!inventoryEnabled && Config.Auto_Tool_Switch)
LogToConsoleTranslated("bot.autodig.no_inv_handle");
RegisterChatBotCommand("digbot", Translations.Get("bot.digbot.cmd"), GetHelp(), CommandHandler);
}
public string CommandHandler(string cmd, string[] args)
{
if (args.Length > 0)
{
switch (args[0])
{
case "start":
lock (stateLock)
{
counter = 0;
state = State.WaitingStart;
}
return Translations.Get("bot.autodig.start");
case "stop":
StopDigging();
return Translations.Get("bot.autodig.stop");
case "help":
return GetCommandHelp(args.Length >= 2 ? args[1] : "");
default:
return GetHelp();
}
}
else return GetHelp();
}
private void StartDigging()
{
if (Config.Auto_Start_Delay > 0)
{
double delay = Config.Auto_Start_Delay;
LogToConsole(Translations.Get("bot.autodig.start_delay", delay));
lock (stateLock)
{
counter = Settings.DoubleToTick(delay);
state = State.WaitingStart;
}
}
else
{
lock (stateLock)
{
state = State.WaitJoinGame;
}
}
}
private void StopDigging()
{
state = State.Stopping;
lock (stateLock)
{
state = State.Stopping;
}
}
public override void Update()
{
lock (stateLock)
{
switch (state)
{
case State.WaitJoinGame:
break;
case State.WaitingStart:
if (--counter < 0)
{
if (DoDigging())
{
AlreadyWaitting = false;
state = State.Digging;
}
else
{
counter = 0;
state = State.WaitingStart;
}
}
break;
case State.Digging:
if (++counter > Settings.DoubleToTick(Config.Dig_Timeout))
{
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autodig.dig_timeout"));
state = State.WaitingStart;
counter = 0;
}
break;
case State.Stopping:
break;
}
}
}
private bool DoDigging()
{
if (Config.Mode == Configs.ModeType.lookat || Config.Mode == Configs.ModeType.both)
{
(bool hasBlock, Location blockLoc, Block block) = GetLookingBlock(4.5, false);
if (!hasBlock)
{
if (!AlreadyWaitting)
{
AlreadyWaitting = true;
if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("cmd.dig.too_far"));
}
return false;
}
else if (block.Type == Material.Air)
{
if (!AlreadyWaitting)
{
AlreadyWaitting = true;
if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("cmd.dig.no_block"));
}
return false;
}
else if ((Config.List_Type == Configs.ListType.whitelist && Config.Blocks.Contains(block.Type)) ||
(Config.List_Type == Configs.ListType.blacklist && !Config.Blocks.Contains(block.Type)))
{
if (Config.Mode == Configs.ModeType.lookat ||
(Config.Mode == Configs.ModeType.both && Config._Locations.Contains(blockLoc)))
{
if (DigBlock(blockLoc, lookAtBlock: false))
{
currentDig = blockLoc;
if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("cmd.dig.dig", blockLoc.X, blockLoc.Y, blockLoc.Z, block.Type));
return true;
}
else
{
LogToConsole(Translations.Get("cmd.dig.fail"));
return false;
}
}
else
{
if (!AlreadyWaitting)
{
AlreadyWaitting = true;
if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("bot.autodig.not_allow"));
}
return false;
}
}
else
{
if (!AlreadyWaitting)
{
AlreadyWaitting = true;
if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("bot.autodig.not_allow"));
}
return false;
}
}
else if (Config.Mode == Configs.ModeType.fixedpos)
{
Location current = GetCurrentLocation();
double minDistance = double.MaxValue;
Location target = Location.Zero;
Block targetBlock = Block.Air;
foreach (Location location in Config._Locations)
{
Block block = GetWorld().GetBlock(location);
if (block.Type != Material.Air &&
((Config.List_Type == Configs.ListType.whitelist && Config.Blocks.Contains(block.Type)) ||
(Config.List_Type == Configs.ListType.blacklist && !Config.Blocks.Contains(block.Type))))
{
double distance = current.Distance(location);
if (distance < minDistance)
{
minDistance = distance;
target = location;
targetBlock = block;
}
}
}
if (minDistance <= 6.0)
{
if (DigBlock(target, lookAtBlock: true))
{
currentDig = target;
if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("cmd.dig.dig", target.X, target.Y, target.Z, targetBlock.Type));
return true;
}
else
{
LogToConsole(Translations.Get("cmd.dig.fail"));
return false;
}
}
else
{
if (!AlreadyWaitting)
{
AlreadyWaitting = true;
if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("cmd.dig.no_block"));
}
return false;
}
}
return false;
}
public override void OnBlockChange(Location location, Block block)
{
if (location == currentDig)
{
lock (stateLock)
{
if (state == State.Digging && location == currentDig)
{
currentDig = Location.Zero;
counter = 0;
state = State.WaitingStart;
}
}
}
}
public override void AfterGameJoined()
{
StartDigging();
}
public override void OnRespawn()
{
StartDigging();
}
public override void OnDeath()
{
StopDigging();
}
public override bool OnDisconnect(DisconnectReason reason, string message)
{
StopDigging();
return base.OnDisconnect(reason, message);
}
private static string GetHelp()
{
return Translations.Get("bot.autodig.available_cmd", "start, stop, help");
}
private string GetCommandHelp(string cmd)
{
return cmd.ToLower() switch
{
#pragma warning disable format // @formatter:off
"start" => Translations.Get("bot.autodig.help.start"),
"stop" => Translations.Get("bot.autodig.help.stop"),
"help" => Translations.Get("bot.autodig.help.help"),
_ => GetHelp(),
#pragma warning restore format // @formatter:on
};
}
}
}

View file

@ -184,7 +184,7 @@ namespace MinecraftClient.ChatBots
LogToConsole(Translations.Get("bot.autoFish.start", delay));
lock (stateLock)
{
counter = (int)(delay * 10);
counter = Settings.DoubleToTick(delay);
state = FishingState.StartMove;
}
}
@ -224,7 +224,7 @@ namespace MinecraftClient.ChatBots
break;
case FishingState.WaitingToCast:
if (AutoEat.Eating)
counter = (int)(Config.Cast_Delay * 10);
counter = Settings.DoubleToTick(Config.Cast_Delay);
else if (--counter < 0)
state = FishingState.CastingRod;
break;
@ -240,16 +240,16 @@ namespace MinecraftClient.ChatBots
castTimeout *= 2; // Exponential backoff
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.cast_timeout", castTimeout / 10.0));
counter = (int)(Config.Cast_Delay * 10);
counter = Settings.DoubleToTick(Config.Cast_Delay);
state = FishingState.WaitingToCast;
}
break;
case FishingState.WaitingFishToBite:
if (++counter > (int)(Config.Fishing_Timeout * 10))
if (++counter > Settings.DoubleToTick(Config.Fishing_Timeout))
{
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.fishing_timeout"));
counter = (int)(Config.Cast_Delay * 10);
counter = Settings.DoubleToTick(Config.Cast_Delay);
state = FishingState.WaitingToCast;
}
break;
@ -271,7 +271,7 @@ namespace MinecraftClient.ChatBots
}
else
{
counter = (int)(Config.Cast_Delay * 10);
counter = Settings.DoubleToTick(Config.Cast_Delay);
state = FishingState.DurabilityCheck;
goto case FishingState.DurabilityCheck;
}
@ -290,7 +290,7 @@ namespace MinecraftClient.ChatBots
case FishingState.DurabilityCheck:
if (DurabilityCheck())
{
counter = (int)(Config.Cast_Delay * 10);
counter = Settings.DoubleToTick(Config.Cast_Delay);
state = FishingState.WaitingToCast;
}
break;
@ -338,7 +338,7 @@ namespace MinecraftClient.ChatBots
lock (stateLock)
{
counter = (int)(Config.Cast_Delay * 10);
counter = Settings.DoubleToTick(Config.Cast_Delay);
state = FishingState.WaitingToCast;
}
}

View file

@ -129,7 +129,7 @@ namespace MinecraftClient.ChatBots
private void LaunchDelayedReconnection(string? msg)
{
int delay = random.Next((int)Config.Delay.min, (int)Config.Delay.max);
int delay = random.Next(Settings.DoubleToTick(Config.Delay.min), Settings.DoubleToTick(Config.Delay.max));
LogDebugToConsoleTranslated(String.IsNullOrEmpty(msg) ? "bot.autoRelog.reconnect_always" : "bot.autoRelog.reconnect", msg);
LogToConsoleTranslated("bot.autoRelog.wait", delay);
System.Threading.Thread.Sleep(delay * 1000);

View file

@ -113,7 +113,7 @@ namespace MinecraftClient.ChatBots
public override void OnEntityMove(Entity entity)
{
if (_updateCounter < (int)(Config.Update_Limit * 10))
if (_updateCounter < Settings.DoubleToTick(Config.Update_Limit))
return;
_updateCounter = 0;

View file

@ -39,7 +39,7 @@ namespace MinecraftClient.ChatBots
public override void Update()
{
count++;
if (count == (int)(Config.Delay * 10))
if (count >= Settings.DoubleToTick(Config.Delay))
{
DateTime now = DateTime.Now;

View file

@ -26,7 +26,7 @@ namespace MinecraftClient.ChatBots
Trigger_On_First_Login: false,
Trigger_On_Login: false,
Trigger_On_Times: new(true, new TimeSpan[] { new(14, 00, 00) }),
Trigger_On_Interval: new(true, 10, 20),
Trigger_On_Interval: new(true, 3.6, 4.8),
Action: "send /hello"
),
new TaskConfig(
@ -43,8 +43,8 @@ namespace MinecraftClient.ChatBots
{
foreach (TaskConfig task in TaskList)
{
task.Trigger_On_Interval.MinTime = Math.Max(1, task.Trigger_On_Interval.MinTime);
task.Trigger_On_Interval.MaxTime = Math.Max(1, task.Trigger_On_Interval.MaxTime);
task.Trigger_On_Interval.MinTime = Math.Max(0.1, task.Trigger_On_Interval.MinTime);
task.Trigger_On_Interval.MaxTime = Math.Max(0.1, task.Trigger_On_Interval.MaxTime);
if (task.Trigger_On_Interval.MinTime > task.Trigger_On_Interval.MaxTime)
(task.Trigger_On_Interval.MinTime, task.Trigger_On_Interval.MaxTime) = (task.Trigger_On_Interval.MaxTime, task.Trigger_On_Interval.MinTime);
@ -59,7 +59,7 @@ namespace MinecraftClient.ChatBots
{
if (Settings.Config.Logging.DebugMessages)
LogToConsole(BotName, Translations.TryGet("bot.scriptScheduler.loaded_task", Task2String(task)));
task.Trigger_On_Interval_Countdown = task.Trigger_On_Interval.MinTime; //Init countdown for interval
task.Trigger_On_Interval_Countdown = Settings.DoubleToTick(task.Trigger_On_Interval.MinTime); //Init countdown for interval
}
else
{
@ -130,27 +130,27 @@ namespace MinecraftClient.ChatBots
public struct TriggerOnIntervalConfig
{
public bool Enable = false;
public int MinTime, MaxTime;
public double MinTime, MaxTime;
public TriggerOnIntervalConfig(int value)
public TriggerOnIntervalConfig(double value)
{
this.Enable = true;
MinTime = MaxTime = value;
}
public TriggerOnIntervalConfig(bool Enable, int value)
public TriggerOnIntervalConfig(bool Enable, double value)
{
this.Enable = Enable;
MinTime = MaxTime = value;
}
public TriggerOnIntervalConfig(int min, int max)
public TriggerOnIntervalConfig(double min, double max)
{
this.MinTime = min;
this.MaxTime = max;
}
public TriggerOnIntervalConfig(bool Enable, int min, int max)
public TriggerOnIntervalConfig(bool Enable, double min, double max)
{
this.Enable = Enable;
this.MinTime = min;
@ -199,16 +199,6 @@ namespace MinecraftClient.ChatBots
task.Trigger_On_Time_Already_Triggered = false;
}
if (task.Trigger_On_Interval.Enable)
{
if (task.Trigger_On_Interval_Countdown == 0)
{
task.Trigger_On_Interval_Countdown = random.Next(task.Trigger_On_Interval.MinTime, task.Trigger_On_Interval.MaxTime);
LogDebugToConsoleTranslated("bot.scriptScheduler.running_inverval", task.Action);
PerformInternalCommand(task.Action);
}
else task.Trigger_On_Interval_Countdown--;
}
}
}
else
@ -227,6 +217,22 @@ namespace MinecraftClient.ChatBots
}
}
else verifytasks_timeleft--;
foreach (TaskConfig task in Config.TaskList)
{
if (task.Trigger_On_Interval.Enable)
{
if (task.Trigger_On_Interval_Countdown == 0)
{
task.Trigger_On_Interval_Countdown = random.Next(
Settings.DoubleToTick(task.Trigger_On_Interval.MinTime), Settings.DoubleToTick(task.Trigger_On_Interval.MaxTime)
);
LogDebugToConsoleTranslated("bot.scriptScheduler.running_inverval", task.Action);
PerformInternalCommand(task.Action);
}
else task.Trigger_On_Interval_Countdown--;
}
}
}
public override bool OnDisconnect(DisconnectReason reason, string message)