Add AutoEat

#923
This commit is contained in:
ReinforceZwei 2020-04-08 00:28:03 +08:00 committed by ORelio
parent 70e5ae85d7
commit 2e1e79bcef
10 changed files with 128 additions and 11 deletions

View file

@ -850,5 +850,15 @@ namespace MinecraftClient
Container container = Handler.GetPlayerInventory();
return new Container(container.ID, container.Type, container.Title, container.Items);
}
/// <summary>
/// Check if player is eating or not
/// </summary>
/// <remarks>Some bot like AutoAttack need this. We don't want to attack while eating</remarks>
/// <returns>True if is eating</returns>
protected bool GetIsEating()
{
return Handler.GetIsEating();
}
}
}

View file

@ -32,20 +32,23 @@ namespace MinecraftClient.ChatBots
public override void Update()
{
if (attackCooldownCounter == 0)
if (!GetIsEating())
{
attackCooldownCounter = attackCooldown;
if (entitiesToAttack.Count > 0)
if (attackCooldownCounter == 0)
{
foreach (KeyValuePair<int, Entity> a in entitiesToAttack)
attackCooldownCounter = attackCooldown;
if (entitiesToAttack.Count > 0)
{
InteractEntity(a.Key, 1);
foreach (KeyValuePair<int, Entity> a in entitiesToAttack)
{
InteractEntity(a.Key, 1);
}
}
}
}
else
{
attackCooldownCounter--;
else
{
attackCooldownCounter--;
}
}
}

View file

@ -43,6 +43,7 @@ namespace MinecraftClient.Commands
response.Add(String.Format(" #{0}: {1} x{2}", item.Key, item.Value.Type, item.Value.Count));
else response.Add(String.Format(" #{0}: {1} x{2} - {3}§8", item.Key, item.Value.Type, item.Value.Count, displayName));
}
response.Add("Your selected hotbar is " + (handler.GetCurrentSlot() + 1));
return String.Join("\n", response.ToArray());
case "click":
if (args.Length == 3)

View file

@ -70,5 +70,24 @@ namespace MinecraftClient.Inventory
return null;
}
}
/// <summary>
/// Check item is a food
/// </summary>
/// <returns>True if is a food</returns>
public bool IsFood()
{
// non-poison and stackable food
// remarks: auto eat may works with non-stackable food <- not tested
int[] foods = { 524, 765, 821, 823, 562, 763, 680, 629, 801, 585, 788, 630, 670, 674, 588, 587, 768, 673, 764, 777, 677, 679, 625, 800, 584, 787, 626, 678, 876, 627 };
if (foods.Contains((int)Type))
{
return true;
}
else
{
return false;
}
}
}
}

View file

@ -59,8 +59,13 @@ namespace MinecraftClient
private int playerEntityID;
// player health and hunger
private float playerHealth;
private int playerFoodSaturation;
private bool Eating = false;
private int HungerThreshold = 6;
private byte CurrentSlot = 0;
private byte LastSlot = 0; // for switch back to origin slot after eating
// Entity handling
private Dictionary<int, Entity> entities = new Dictionary<int, Entity>();
@ -80,6 +85,8 @@ namespace MinecraftClient
public Double GetServerTPS() { return serverTPS; }
public float GetHealth() { return playerHealth; }
public int GetSaturation() { return playerFoodSaturation; }
public byte GetCurrentSlot() { return CurrentSlot; }
public bool GetIsEating() { return Eating; }
// get bots list for unloading them by commands
public List<ChatBot> GetLoadedChatBots()
@ -1530,6 +1537,7 @@ namespace MinecraftClient
{
if (slot >= 0 && slot <= 8)
{
CurrentSlot = Convert.ToByte(slot);
return handler.SendHeldItemChange(slot);
}
else
@ -1558,6 +1566,61 @@ namespace MinecraftClient
ConsoleIO.WriteLogLine("You are dead. Type /respawn to respawn.");
}
}
if (Settings.AutoEat)
{
if (food <= HungerThreshold || (food < 20 && health < 20))
{
Eating = true;
FindFoodAndEat();
}
// keep eating until full
if (food < 20 && Eating)
{
FindFoodAndEat();
}
if (food >= 20 && Eating)
{
Eating = false;
ChangeSlot(LastSlot);
}
}
}
public void OnHeldItemChange(byte slot)
{
CurrentSlot = slot;
}
/// <summary>
/// Try to find food in the hotbar and eat it
/// </summary>
/// <returns>True if found</returns>
public bool FindFoodAndEat()
{
Container inventory = inventories[0];
bool found = false;
if (inventory.Items.ContainsKey(CurrentSlot + 36) && inventory.Items[CurrentSlot + 36].IsFood())
{
// no need to change slot
found = true;
}
else
{
LastSlot = CurrentSlot;
for (int i = 36; i <= 44; i++)
{
if (!inventory.Items.ContainsKey(i)) continue;
if (inventory.Items[i].IsFood())
{
int slot = i - 36;
ChangeSlot((short)slot);
found = true;
break;
}
}
}
if (found) UseItemOnHand();
return found;
}
}
}

View file

@ -42,6 +42,7 @@ namespace MinecraftClient.Protocol.Handlers
EntityTeleport,
EntityStatus,
UpdateHealth,
HeldItemChange,
UnknownPacket
}
}

View file

@ -730,6 +730,10 @@ namespace MinecraftClient.Protocol.Handlers
dataTypes.ReadNextFloat(packetData);
handler.OnUpdateHealth(health, food);
break;
case PacketIncomingType.HeldItemChange:
byte slot = dataTypes.ReadNextByte(packetData);
handler.OnHeldItemChange(slot);
break;
default:
return false; //Ignored packet
}

View file

@ -277,7 +277,8 @@ namespace MinecraftClient.Protocol.Handlers
case 0x59: return PacketIncomingType.EntityProperties;
case 0x57: return PacketIncomingType.EntityTeleport;
case 0x1C: return PacketIncomingType.EntityStatus;
case 0x49: return PacketIncomingType.UpdateHealth; // TODO: Add backwards support for this packet
case 0x49: return PacketIncomingType.UpdateHealth; // TODO: Add backwards support
case 0x40: return PacketIncomingType.HeldItemChange; // TODO: Add backwards support
default: return PacketIncomingType.UnknownPacket;
}
}

View file

@ -212,8 +212,20 @@ namespace MinecraftClient.Protocol
/// <param name="item">Item (may be null for empty slot)</param>
void OnSetSlot(byte inventoryID, short slotID, Item item);
/// <summary>
/// Called when player health or hunger changed.
/// </summary>
/// <param name="health"></param>
/// <param name="food"></param>
void OnUpdateHealth(float health, int food);
/// <summary>
/// Called when client need to change slot.
/// </summary>
/// <remarks>Used for setting player slot after joining game</remarks>
/// <param name="slot"></param>
void OnHeldItemChange(byte slot);
/// <summary>
/// Called when the Player entity ID has been received from the server
/// </summary>

View file

@ -97,6 +97,7 @@ namespace MinecraftClient
public static bool ResolveSrvRecordsShortTimeout = true;
public static bool EntityHandling = false;
public static bool AutoRespawn = false;
public static bool AutoEat = false;
//AntiAFK Settings
public static bool AntiAFK_Enabled = false;
@ -244,6 +245,7 @@ namespace MinecraftClient
case "botmessagedelay": botMessageDelay = TimeSpan.FromSeconds(str2int(argValue)); break;
case "debugmessages": DebugMessages = str2bool(argValue); break;
case "autorespawn": AutoRespawn = str2bool(argValue); break;
case "autoeat": AutoEat = str2bool(argValue); break;
case "botowners":
Bots_Owners.Clear();
@ -589,6 +591,7 @@ namespace MinecraftClient
+ "scriptcache=true # Cache compiled scripts for faster load on low-end devices\r\n"
+ "timestamps=false # Prepend timestamps to chat messages\r\n"
+ "autorespawn=false # Toggle auto respawn if client player was dead (make sure your spawn point is safe)\r\n"
+ "autoeat=false # Toggle auto eat when player is hungry\r\n"
+ "\r\n"
+ "[AppVars]\r\n"
+ "# yourvar=yourvalue\r\n"