mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-11-07 17:36:07 +00:00
Upgrade Auto Fishing
This commit is contained in:
parent
223c13561c
commit
eb517a8e78
6 changed files with 182 additions and 53 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit b4fd7da2595ad54479880fc1c9c6e14975412d92
|
Subproject commit 7acaa0ab31809f0f6512e6a76e53e15441de8e7c
|
||||||
|
|
@ -13,13 +13,30 @@ namespace MinecraftClient.ChatBots
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class AutoFishing : ChatBot
|
class AutoFishing : ChatBot
|
||||||
{
|
{
|
||||||
private Entity fishingRod;
|
private int fishCount = 0;
|
||||||
private Double fishingHookThreshold = 0.2;
|
|
||||||
private Location LastPos = new Location();
|
|
||||||
private DateTime CaughtTime = DateTime.Now;
|
|
||||||
private bool inventoryEnabled;
|
private bool inventoryEnabled;
|
||||||
|
|
||||||
private bool isFishing = false;
|
private bool isFishing = false;
|
||||||
private int useItemCounter = 0;
|
private Entity? fishingBobber;
|
||||||
|
private Location LastPos = Location.Zero;
|
||||||
|
private DateTime CaughtTime = DateTime.Now;
|
||||||
|
|
||||||
|
private int counter = 0;
|
||||||
|
private readonly object stateLock = new();
|
||||||
|
private FishingState state = FishingState.WaitJoinGame;
|
||||||
|
|
||||||
|
private int castTimeout = 12;
|
||||||
|
|
||||||
|
private enum FishingState
|
||||||
|
{
|
||||||
|
WaitJoinGame,
|
||||||
|
WaitingToCast,
|
||||||
|
CastingRod,
|
||||||
|
WaitingFishingBobber,
|
||||||
|
WaitingFishBite,
|
||||||
|
Preparing,
|
||||||
|
Stopping,
|
||||||
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
|
|
@ -32,42 +49,94 @@ namespace MinecraftClient.ChatBots
|
||||||
inventoryEnabled = GetInventoryEnabled();
|
inventoryEnabled = GetInventoryEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void AfterGameJoined()
|
||||||
|
{
|
||||||
|
double delay = Settings.AutoFishing_FishingDelay;
|
||||||
|
LogToConsole(Translations.Get("bot.autoFish.start", delay));
|
||||||
|
lock (stateLock)
|
||||||
|
{
|
||||||
|
counter = (int)(delay * 10);
|
||||||
|
state = FishingState.WaitingToCast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
if (useItemCounter > 0)
|
lock (stateLock)
|
||||||
{
|
{
|
||||||
useItemCounter--;
|
switch (state)
|
||||||
if (useItemCounter <= 0)
|
|
||||||
{
|
{
|
||||||
UseItemInHand();
|
case FishingState.WaitJoinGame:
|
||||||
|
break;
|
||||||
|
case FishingState.WaitingToCast:
|
||||||
|
if (--counter < 0)
|
||||||
|
state = FishingState.CastingRod;
|
||||||
|
break;
|
||||||
|
case FishingState.CastingRod:
|
||||||
|
UseFishRod();
|
||||||
|
counter = 0;
|
||||||
|
state = FishingState.WaitingFishingBobber;
|
||||||
|
break;
|
||||||
|
case FishingState.WaitingFishingBobber:
|
||||||
|
if (++counter > castTimeout)
|
||||||
|
{
|
||||||
|
if (castTimeout < 6000)
|
||||||
|
castTimeout *= 2;
|
||||||
|
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.cast_timeout", castTimeout / 10.0));
|
||||||
|
|
||||||
|
counter = (int)(Settings.AutoFishing_FishingCastDelay * 10);
|
||||||
|
state = FishingState.WaitingToCast;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FishingState.WaitingFishBite:
|
||||||
|
if (++counter > (int)(Settings.AutoFishing_FishingTimeout * 10))
|
||||||
|
{
|
||||||
|
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.fishing_timeout"));
|
||||||
|
|
||||||
|
counter = (int)(Settings.AutoFishing_FishingCastDelay * 10);
|
||||||
|
state = FishingState.WaitingToCast;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FishingState.Preparing:
|
||||||
|
break;
|
||||||
|
case FishingState.Stopping:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnEntitySpawn(Entity entity)
|
public override void OnEntitySpawn(Entity entity)
|
||||||
{
|
{
|
||||||
if (entity.Type == EntityType.FishingBobber)
|
if (entity.Type == EntityType.FishingBobber && entity.ObjectData == GetPlayerEntityID())
|
||||||
{
|
{
|
||||||
if (GetCurrentLocation().Distance(entity.Location) < 2 && !isFishing)
|
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.throw"));
|
||||||
|
lock (stateLock)
|
||||||
{
|
{
|
||||||
LogToConsoleTranslated("bot.autoFish.throw");
|
fishingBobber = entity;
|
||||||
fishingRod = entity;
|
|
||||||
LastPos = entity.Location;
|
LastPos = entity.Location;
|
||||||
isFishing = true;
|
isFishing = true;
|
||||||
|
|
||||||
|
castTimeout = 24;
|
||||||
|
counter = 0;
|
||||||
|
state = FishingState.WaitingFishBite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnEntityDespawn(Entity entity)
|
public override void OnEntityDespawn(Entity entity)
|
||||||
{
|
{
|
||||||
if (entity.Type == EntityType.FishingBobber)
|
if (isFishing && entity.Type == EntityType.FishingBobber && entity.ID == fishingBobber!.ID)
|
||||||
{
|
{
|
||||||
if(entity.ID == fishingRod.ID)
|
isFishing = false;
|
||||||
|
|
||||||
|
if (Settings.AutoFishing_Antidespawn)
|
||||||
{
|
{
|
||||||
isFishing = false;
|
LogToConsoleTranslated("bot.autoFish.despawn");
|
||||||
if (Settings.AutoFishing_Antidespawn)
|
|
||||||
|
lock (stateLock)
|
||||||
{
|
{
|
||||||
useItemCounter = 5; // 500ms
|
counter = (int)(Settings.AutoFishing_FishingCastDelay * 10);
|
||||||
|
state = FishingState.WaitingToCast;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -75,75 +144,95 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
public override void OnEntityMove(Entity entity)
|
public override void OnEntityMove(Entity entity)
|
||||||
{
|
{
|
||||||
if (isFishing)
|
if (isFishing && fishingBobber!.ID == entity.ID)
|
||||||
{
|
{
|
||||||
if (fishingRod.ID == entity.ID)
|
Location Pos = entity.Location;
|
||||||
|
double Dx = LastPos.X - Pos.X;
|
||||||
|
double Dy = LastPos.Y - Pos.Y;
|
||||||
|
double Dz = LastPos.Z - Pos.Z;
|
||||||
|
LastPos = Pos;
|
||||||
|
|
||||||
|
// check if fishing hook is stationary
|
||||||
|
if (Dx == 0 && Dz == 0)
|
||||||
{
|
{
|
||||||
Location Pos = entity.Location;
|
if (Math.Abs(Dy) > Settings.AutoFishing_FishingHookThreshold)
|
||||||
Double Dx = LastPos.X - Pos.X;
|
|
||||||
Double Dy = LastPos.Y - Pos.Y;
|
|
||||||
Double Dz = LastPos.Z - Pos.Z;
|
|
||||||
LastPos = Pos;
|
|
||||||
// check if fishing hook is stationary
|
|
||||||
if (Dx == 0 && Dz == 0)
|
|
||||||
{
|
{
|
||||||
if (Math.Abs(Dy) > fishingHookThreshold)
|
// caught
|
||||||
|
// prevent triggering multiple time
|
||||||
|
if ((DateTime.Now - CaughtTime).TotalSeconds > 1)
|
||||||
{
|
{
|
||||||
// caught
|
CaughtTime = DateTime.Now;
|
||||||
// prevent triggering multiple time
|
OnCaughtFish();
|
||||||
if ((DateTime.Now - CaughtTime).TotalSeconds > 1)
|
|
||||||
{
|
|
||||||
OnCaughtFish();
|
|
||||||
CaughtTime = DateTime.Now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fishingRod = entity;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnDisconnect(DisconnectReason reason, string message)
|
public override bool OnDisconnect(DisconnectReason reason, string message)
|
||||||
{
|
{
|
||||||
fishingRod = null;
|
lock (stateLock)
|
||||||
LastPos = new Location();
|
{
|
||||||
|
isFishing = false;
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
state = FishingState.Stopping;
|
||||||
|
}
|
||||||
|
|
||||||
|
fishingBobber = null;
|
||||||
|
LastPos = Location.Zero;
|
||||||
CaughtTime = DateTime.Now;
|
CaughtTime = DateTime.Now;
|
||||||
isFishing = false;
|
|
||||||
useItemCounter = 0;
|
|
||||||
return base.OnDisconnect(reason, message);
|
return base.OnDisconnect(reason, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UseFishRod()
|
||||||
|
{
|
||||||
|
UseItemInHand();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when detected a fish is caught
|
/// Called when detected a fish is caught
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OnCaughtFish()
|
public void OnCaughtFish()
|
||||||
{
|
{
|
||||||
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.caught"));
|
lock (stateLock)
|
||||||
// retract fishing rod
|
{
|
||||||
UseItemInHand();
|
state = FishingState.Preparing;
|
||||||
|
}
|
||||||
|
|
||||||
|
UseFishRod();
|
||||||
|
|
||||||
|
++fishCount;
|
||||||
|
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.caught", fishCount));
|
||||||
|
|
||||||
if (inventoryEnabled)
|
if (inventoryEnabled)
|
||||||
{
|
{
|
||||||
if (!hasFishingRod())
|
if (!HasFishingRod())
|
||||||
{
|
{
|
||||||
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.no_rod"));
|
LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.no_rod"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// thread-safe
|
|
||||||
useItemCounter = 8; // 800ms
|
lock (stateLock)
|
||||||
|
{
|
||||||
|
counter = (int)(Settings.AutoFishing_FishingCastDelay * 10);
|
||||||
|
state = FishingState.WaitingToCast;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check whether the player has a fishing rod in inventory
|
/// Check whether the player has a fishing rod in inventory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>TRUE if the player has a fishing rod</returns>
|
/// <returns>TRUE if the player has a fishing rod</returns>
|
||||||
public bool hasFishingRod()
|
public bool HasFishingRod()
|
||||||
{
|
{
|
||||||
if (!inventoryEnabled)
|
if (!inventoryEnabled)
|
||||||
return false;
|
return false;
|
||||||
int start = 36;
|
int start = 36;
|
||||||
int end = 44;
|
int end = 44;
|
||||||
Inventory.Container container = GetPlayerInventory();
|
Container container = GetPlayerInventory();
|
||||||
|
|
||||||
foreach (KeyValuePair<int, Item> a in container.Items)
|
foreach (KeyValuePair<int, Item> a in container.Items)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,10 @@ interaction=Attack # Possible values: Interact, Attack (default)
|
||||||
# /!\ Make sure server rules allow automated farming before using this bot
|
# /!\ Make sure server rules allow automated farming before using this bot
|
||||||
enabled=false
|
enabled=false
|
||||||
antidespawn=false
|
antidespawn=false
|
||||||
|
fishing_delay=3.0 # How long after entering the game to start fishing (seconds).
|
||||||
|
fishing_timeout=600.0 # Fishing timeout (seconds). Timeout will re-cast the rod
|
||||||
|
fishing_hook_threshold=0.2 # Fish hooks moving on the Y-axis above this threshold will be considered to have caught a fish.
|
||||||
|
fishing_cast_delay=0.4 # How soon to re-cast after successful fishing.
|
||||||
|
|
||||||
[AutoEat]
|
[AutoEat]
|
||||||
# Automatically eat food when your Hunger value is low
|
# Automatically eat food when your Hunger value is low
|
||||||
|
|
|
||||||
|
|
@ -447,9 +447,13 @@ bot.autoDrop.no_mode=Cannot read drop mode from config. Using include mode.
|
||||||
bot.autoDrop.no_inventory=Cannot find inventory {0}!
|
bot.autoDrop.no_inventory=Cannot find inventory {0}!
|
||||||
|
|
||||||
# AutoFish
|
# AutoFish
|
||||||
bot.autoFish.throw=Threw a fishing rod
|
bot.autoFish.start=Fishing will start in {0:0.0} second(s).
|
||||||
bot.autoFish.caught=Caught a fish!
|
bot.autoFish.throw=Casting successfully.
|
||||||
|
bot.autoFish.caught=Caught a fish! (Count: {0})
|
||||||
bot.autoFish.no_rod=No Fishing Rod on hand. Maybe broken?
|
bot.autoFish.no_rod=No Fishing Rod on hand. Maybe broken?
|
||||||
|
bot.autoFish.despawn=Fish floating despawn, will re-cast.
|
||||||
|
bot.autoFish.fishing_timeout=Fishing timeout, will soon re-cast.
|
||||||
|
bot.autoFish.cast_timeout=Casting timeout and will soon retry. (Timeout increased to {0:0.0} sec).
|
||||||
|
|
||||||
# AutoRelog
|
# AutoRelog
|
||||||
bot.autoRelog.launch=Launching with {0} reconnection attempts
|
bot.autoRelog.launch=Launching with {0} reconnection attempts
|
||||||
|
|
|
||||||
|
|
@ -1113,6 +1113,15 @@ namespace MinecraftClient
|
||||||
return Handler.GetUserUuidStr();
|
return Handler.GetUserUuidStr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the EntityID of the current player
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>EntityID of the current player</returns>
|
||||||
|
protected int GetPlayerEntityID()
|
||||||
|
{
|
||||||
|
return Handler.GetPlayerEntityID();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the list of currently online players
|
/// Return the list of currently online players
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,10 @@ namespace MinecraftClient
|
||||||
//Auto Fishing
|
//Auto Fishing
|
||||||
public static bool AutoFishing_Enabled = false;
|
public static bool AutoFishing_Enabled = false;
|
||||||
public static bool AutoFishing_Antidespawn = false;
|
public static bool AutoFishing_Antidespawn = false;
|
||||||
|
public static double AutoFishing_FishingDelay = 3.0;
|
||||||
|
public static double AutoFishing_FishingTimeout = 600.0;
|
||||||
|
public static double AutoFishing_FishingHookThreshold = 0.2;
|
||||||
|
public static double AutoFishing_FishingCastDelay = 0.4;
|
||||||
|
|
||||||
//Auto Eating
|
//Auto Eating
|
||||||
public static bool AutoEat_Enabled = false;
|
public static bool AutoEat_Enabled = false;
|
||||||
|
|
@ -711,6 +715,10 @@ namespace MinecraftClient
|
||||||
{
|
{
|
||||||
case "enabled": AutoFishing_Enabled = str2bool(argValue); return true;
|
case "enabled": AutoFishing_Enabled = str2bool(argValue); return true;
|
||||||
case "antidespawn": AutoFishing_Antidespawn = str2bool(argValue); return true;
|
case "antidespawn": AutoFishing_Antidespawn = str2bool(argValue); return true;
|
||||||
|
case "fishing_delay": AutoFishing_FishingDelay = str2double(argValue); return true;
|
||||||
|
case "fishing_timeout": AutoFishing_FishingTimeout = str2double(argValue); return true;
|
||||||
|
case "fishing_hook_threshold": AutoFishing_FishingHookThreshold = str2double(argValue); return true;
|
||||||
|
case "fishing_cast_delay": AutoFishing_FishingCastDelay = str2double(argValue); return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -863,8 +871,23 @@ namespace MinecraftClient
|
||||||
/// <returns>Float number</returns>
|
/// <returns>Float number</returns>
|
||||||
public static float str2float(string str)
|
public static float str2float(string str)
|
||||||
{
|
{
|
||||||
float f;
|
if (float.TryParse(str.Trim(), out float f))
|
||||||
if (float.TryParse(str.Trim(), out f))
|
return f;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConsoleIO.WriteLogLine(Translations.Get("error.setting.str2int", str));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert the specified string to a double number, defaulting to zero if invalid argument
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">String to parse as a float number</param>
|
||||||
|
/// <returns>Double number</returns>
|
||||||
|
public static double str2double(string str)
|
||||||
|
{
|
||||||
|
if (double.TryParse(str.Trim(), out double f))
|
||||||
return f;
|
return f;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue