Items Collector Chat Bot

Items Collector Chat Bot
This commit is contained in:
Anon 2023-05-21 14:50:19 +02:00 committed by GitHub
commit 1bba41c395
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 1545 additions and 1873 deletions

View file

@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Brigadier.NET.Builder;
using MinecraftClient.CommandHandler;
using MinecraftClient.CommandHandler.Patch;
using MinecraftClient.Inventory;
using MinecraftClient.Mapping;
using MinecraftClient.Scripting;
using Tomlet.Attributes;
namespace MinecraftClient.ChatBots;
public class ItemsCollector : ChatBot
{
public const string CommandName = "itemscollector";
public static Configs Config = new();
[TomlDoNotInlineObject]
public class Configs
{
[NonSerialized] private const string BotName = "ItemsCollector";
public bool Enabled = false;
[TomlInlineComment("$ChatBot.ItemsCollector.Collect_All_Item_Types$")]
public bool Collect_All_Item_Types = true;
[TomlInlineComment("$ChatBot.ItemsCollector.Items_Whitelist$")]
public List<ItemType> Items_Whitelist = new() { ItemType.Diamond, ItemType.NetheriteIngot };
[TomlInlineComment("$ChatBot.ItemsCollector.Delay_Between_Tasks$")]
public int Delay_Between_Tasks = 300;
[TomlInlineComment("$ChatBot.ItemsCollector.Collection_Radius$")]
public double Collection_Radius = 30.0;
[TomlInlineComment("$ChatBot.ItemsCollector.Always_Return_To_Start$")]
public bool Always_Return_To_Start = true;
[TomlInlineComment("$ChatBot.ItemsCollector.Prioritize_Clusters$")]
public bool Prioritize_Clusters = false;
public void OnSettingUpdate()
{
if (Delay_Between_Tasks < 100)
Delay_Between_Tasks = 100;
}
}
private bool running = false;
private Thread? mainProcessThread;
public override void Initialize()
{
if (!GetEntityHandlingEnabled())
{
LogToConsole(Translations.extra_entity_required);
LogToConsole(Translations.general_bot_unload);
UnloadBot();
return;
}
if (!GetTerrainEnabled())
{
LogToConsole(Translations.extra_terrainandmovement_required);
LogToConsole(Translations.general_bot_unload);
UnloadBot();
return;
}
McClient.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)))
);
McClient.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("start")
.Executes(r => OnCommandStart(r.Source)))
.Then(l => l.Literal("stop")
.Executes(r => OnCommandStop(r.Source)))
.Then(l => l.Literal("_help")
.Executes(r => OnCommandHelp(r.Source, string.Empty))
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
);
}
public override void OnUnload()
{
McClient.dispatcher.Unregister(CommandName);
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
}
private int OnCommandHelp(CmdResult r, string? cmd)
{
return r.SetAndReturn(cmd switch
{
#pragma warning disable format // @formatter:off
_ => Translations.cmd_items_collector_desc + ": " + Translations.cmd_items_collector_usage
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on
});
}
private int OnCommandStart(CmdResult r)
{
if (running)
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_items_collector_already_collecting);
StartTheMainProcess();
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_items_collector_started);
}
private int OnCommandStop(CmdResult r)
{
if (!running)
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_items_collector_already_not_collecting);
StopTheMainProcess();
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_items_collector_stopping);
}
private void StartTheMainProcess()
{
running = true;
mainProcessThread = new Thread(MainProcess);
mainProcessThread.Start();
}
private void StopTheMainProcess()
{
running = false;
}
private void MainProcess()
{
var startingLocation = GetCurrentLocation();
while (running)
{
var currentLocation = GetCurrentLocation();
var items = GetEntities()
.Where(x =>
x.Value.Type == EntityType.Item &&
x.Value.Location.Distance(currentLocation) <= Config.Collection_Radius &&
(Config.Collect_All_Item_Types || Config.Items_Whitelist.Contains(x.Value.Item.Type)))
.Select(x => x.Value)
.ToList();
if (Config.Prioritize_Clusters && items.Count > 1)
{
var centroid = new Location(
items.Average(x => x.Location.X),
items.Average(x => x.Location.Y),
items.Average(x => x.Location.Z)
);
items = items.OrderBy(x => x.Location.Distance(centroid) / items.Count).ToList();
}
else items = items.OrderBy(x => x.Location.Distance(currentLocation)).ToList();
if (items.Any())
{
foreach (var entity in items)
{
if (!running)
break;
WaitForMoveToLocation(entity.Location);
}
}
else
{
if (startingLocation.Distance(currentLocation) > 2f && Config.Always_Return_To_Start)
WaitForMoveToLocation(startingLocation);
}
if (!running)
break;
Thread.Sleep(Config.Delay_Between_Tasks);
}
LogToConsole(Translations.cmd_items_collector_stopped);
}
public override void AfterGameJoined()
{
StopTheMainProcess();
}
public override bool OnDisconnect(DisconnectReason reason, string message)
{
StopTheMainProcess();
return true;
}
private bool WaitForMoveToLocation(Location location, float tolerance = 1f)
{
if (!MoveToLocation(location)) return false;
while (GetCurrentLocation().Distance(location) > tolerance)
Thread.Sleep(200);
return true;
}
}

View file

@ -296,6 +296,7 @@ namespace MinecraftClient
if (Config.ChatBot.ReplayCapture.Enabled && reload) { BotLoad(new ReplayCapture()); }
if (Config.ChatBot.ScriptScheduler.Enabled) { BotLoad(new ScriptScheduler()); }
if (Config.ChatBot.TelegramBridge.Enabled) { BotLoad(new TelegramBridge()); }
if (Config.ChatBot.ItemsCollector.Enabled) { BotLoad(new ItemsCollector()); }
//Add your ChatBot here by uncommenting and adapting
//BotLoad(new ChatBots.YourBot());
}
@ -3405,7 +3406,9 @@ namespace MinecraftClient
{
Entity entity = entities[entityID];
entity.Metadata = metadata;
if (entity.Type.ContainsItem() && metadata.TryGetValue(7, out object? itemObj) && itemObj != null && itemObj.GetType() == typeof(Item))
int itemEntityMetadataFieldIndex = protocolversion < Protocol18Handler.MC_1_17_Version ? 7 : 8;
if (entity.Type.ContainsItem() && metadata.TryGetValue(itemEntityMetadataFieldIndex, out object? itemObj) && itemObj != null && itemObj.GetType() == typeof(Item))
{
Item item = (Item)itemObj;
if (item == null)

File diff suppressed because it is too large Load diff

View file

@ -807,4 +807,25 @@ If the connection to the Minecraft game server is blocked by the firewall, set E
<data name="Signature.SignMessageInCommand" xml:space="preserve">
<value>Whether to sign the messages contained in the commands sent by MCC. For example, the message in "/msg" and "/me"</value>
</data>
<data name="ChatBot.ItemsCollector.Collect_All_Item_Types" xml:space="preserve">
<value>If set to true, the bot will collect all items, regardless of their type. If you want to use the whitelisted item types, disable this by setting it to false</value>
</data>
<data name="ChatBot.ItemsCollector.Items_Whitelist" xml:space="preserve">
<value>In this list you can specify which items the bot will collect. To enable this, set the Collect_All_Item_Types to false. (NOTE: This does not prevent the bot from accidentally picking up other items, it only goes to positions where it finds the whitelisted items)\nYou can see the list of item types here: https://raw.githubusercontent.com/MCCTeam/Minecraft-Console-Client/master/MinecraftClient/Inventory/ItemType.cs</value>
</data>
<data name="ChatBot.ItemsCollector.Delay_Between_Tasks" xml:space="preserve">
<value>Delay in milliseconds between bot scanning items (Recommended: 300-500)</value>
</data>
<data name="ChatBot.ItemsCollector.Collection_Radius" xml:space="preserve">
<value>The radius in which bot will look for items to collect (Default: 30)</value>
</data>
<data name="ChatBot.ItemsCollector.Always_Return_To_Start" xml:space="preserve">
<value>If set to true, the bot will return to it's starting position after there are no items to collect</value>
</data>
<data name="ChatBot.ItemsCollector.Prioritize_Clusters" xml:space="preserve">
<value>If set to true, the bot will go after clustered items instead for the closest ones</value>
</data>
<data name="ChatBot.ItemsCollector" xml:space="preserve">
<value>A Chat Bot that collects items on the ground</value>
</data>
</root>

View file

@ -3812,5 +3812,47 @@ namespace MinecraftClient {
return ResourceManager.GetString("bot.TelegramBridge.quit_disabled", resourceCulture);
}
}
internal static string cmd_items_collector_desc {
get {
return ResourceManager.GetString("cmd.items.collector.desc", resourceCulture);
}
}
internal static string cmd_items_collector_usage {
get {
return ResourceManager.GetString("cmd.items.collector.usage", resourceCulture);
}
}
internal static string cmd_items_collector_already_collecting {
get {
return ResourceManager.GetString("cmd.items.collector.already.collecting", resourceCulture);
}
}
internal static string cmd_items_collector_started {
get {
return ResourceManager.GetString("cmd.items.collector.started", resourceCulture);
}
}
internal static string cmd_items_collector_already_not_collecting {
get {
return ResourceManager.GetString("cmd.items.collector.already.not.collecting", resourceCulture);
}
}
internal static string cmd_items_collector_stopping {
get {
return ResourceManager.GetString("cmd.items.collector.stopping", resourceCulture);
}
}
internal static string cmd_items_collector_stopped {
get {
return ResourceManager.GetString("cmd.items.collector.stopped", resourceCulture);
}
}
}
}

View file

@ -2037,4 +2037,25 @@ Logging in...</value>
<data name="bot.TelegramBridge.quit_disabled" xml:space="preserve">
<value>This command has been disabled due to Telegram caching causing issues, please stop your client manually.</value>
</data>
<data name="cmd.items.collector.desc" xml:space="preserve">
<value>Collect items on the ground</value>
</data>
<data name="cmd.items.collector.usage" xml:space="preserve">
<value>itemscollector &lt;start/stop&gt;</value>
</data>
<data name="cmd.items.collector.already.collecting" xml:space="preserve">
<value>Already collecting items!</value>
</data>
<data name="cmd.items.collector.started" xml:space="preserve">
<value>Started collecting items!</value>
</data>
<data name="cmd.items.collector.already.not.collecting" xml:space="preserve">
<value>Already not collecting items!</value>
</data>
<data name="cmd.items.collector.stopping" xml:space="preserve">
<value>Stopping item collection...</value>
</data>
<data name="cmd.items.collector.stopped" xml:space="preserve">
<value>Stopped collecting items.</value>
</data>
</root>

View file

@ -1397,6 +1397,13 @@ namespace MinecraftClient
get { return ChatBots.TelegramBridge.Config; }
set { ChatBots.TelegramBridge.Config = value; ChatBots.TelegramBridge.Config.OnSettingUpdate(); }
}
[TomlPrecedingComment("$ChatBot.ItemsCollector$")]
public ChatBots.ItemsCollector.Configs ItemsCollector
{
get { return ChatBots.ItemsCollector.Config; }
set { ChatBots.ItemsCollector.Config = value; ChatBots.ItemsCollector.Config.OnSettingUpdate(); }
}
}
}