mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Fix AutoRelog retry accounting
This commit is contained in:
parent
f39fe2d067
commit
47de24cf1d
2 changed files with 113 additions and 21 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using MinecraftClient.Scripting;
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
|
|
@ -77,7 +78,9 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Random random = new();
|
private static readonly Lock s_reconnectStateLock = new();
|
||||||
|
private static readonly TimeSpan s_stableJoinBeforeRetryReset = TimeSpan.FromSeconds(60);
|
||||||
|
private static DateTime? s_lastJoinUtc;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This bot automatically re-join the server if kick message contains predefined string
|
/// This bot automatically re-join the server if kick message contains predefined string
|
||||||
|
|
@ -97,7 +100,13 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
public override void AfterGameJoined()
|
public override void AfterGameJoined()
|
||||||
{
|
{
|
||||||
Configs._BotRecoAttempts = 0;
|
lock (s_reconnectStateLock)
|
||||||
|
s_lastJoinUtc = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
ResetRetriesAfterStableJoin();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _Initialize()
|
private void _Initialize()
|
||||||
|
|
@ -115,7 +124,11 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
LogDebugToConsole(Translations.bot_autoRelog_ignore_user_logout);
|
LogDebugToConsole(Translations.bot_autoRelog_ignore_user_logout);
|
||||||
}
|
}
|
||||||
else if (Config.Retries < 0 || Configs._BotRecoAttempts < Config.Retries)
|
else if (Program.HasRestartPendingForAnotherThread)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (CanReconnect())
|
||||||
{
|
{
|
||||||
message = GetVerbatim(message);
|
message = GetVerbatim(message);
|
||||||
string comp = message.ToLower();
|
string comp = message.ToLower();
|
||||||
|
|
@ -124,18 +137,14 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
if (Config.Ignore_Kick_Message)
|
if (Config.Ignore_Kick_Message)
|
||||||
{
|
{
|
||||||
Configs._BotRecoAttempts++;
|
return LaunchDelayedReconnection(null);
|
||||||
LaunchDelayedReconnection(null);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string msg in Config.Kick_Messages)
|
foreach (string msg in Config.Kick_Messages)
|
||||||
{
|
{
|
||||||
if (comp.Contains(msg))
|
if (comp.Contains(msg))
|
||||||
{
|
{
|
||||||
Configs._BotRecoAttempts++;
|
return LaunchDelayedReconnection(msg);
|
||||||
LaunchDelayedReconnection(msg);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,21 +154,83 @@ namespace MinecraftClient.ChatBots
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LaunchDelayedReconnection(string? msg)
|
private static bool CanReconnect()
|
||||||
{
|
{
|
||||||
double delay = random.NextDouble() * (Config.Delay.max - Config.Delay.min) + Config.Delay.min;
|
lock (s_reconnectStateLock)
|
||||||
|
return Config.Retries < 0 || Configs._BotRecoAttempts < Config.Retries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ResetRetriesAfterStableJoin()
|
||||||
|
{
|
||||||
|
lock (s_reconnectStateLock)
|
||||||
|
{
|
||||||
|
if (Configs._BotRecoAttempts <= 0 || s_lastJoinUtc is not DateTime lastJoinUtc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (DateTime.UtcNow - lastJoinUtc < s_stableJoinBeforeRetryReset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Configs._BotRecoAttempts = 0;
|
||||||
|
s_lastJoinUtc = null;
|
||||||
|
McClient.ReconnectionAttemptsLeft = Config.Retries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryConsumeReconnectAttempt(out int retriesLeft)
|
||||||
|
{
|
||||||
|
lock (s_reconnectStateLock)
|
||||||
|
{
|
||||||
|
bool unlimitedRetries = HasUnlimitedRetries();
|
||||||
|
if (!unlimitedRetries && Configs._BotRecoAttempts >= Config.Retries)
|
||||||
|
{
|
||||||
|
retriesLeft = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Configs._BotRecoAttempts++;
|
||||||
|
s_lastJoinUtc = null;
|
||||||
|
retriesLeft = unlimitedRetries ? int.MaxValue : Config.Retries - Configs._BotRecoAttempts;
|
||||||
|
if (retriesLeft < 0)
|
||||||
|
retriesLeft = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool HasUnlimitedRetries()
|
||||||
|
{
|
||||||
|
return Config.Retries < 0 || Config.Retries == int.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RollBackReconnectAttempt()
|
||||||
|
{
|
||||||
|
lock (s_reconnectStateLock)
|
||||||
|
{
|
||||||
|
if (Configs._BotRecoAttempts > 0)
|
||||||
|
Configs._BotRecoAttempts--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool LaunchDelayedReconnection(string? msg)
|
||||||
|
{
|
||||||
|
if (!TryConsumeReconnectAttempt(out int retriesLeft))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
double delay = Random.Shared.NextDouble() * (Config.Delay.max - Config.Delay.min) + Config.Delay.min;
|
||||||
LogDebugToConsole(string.Format(string.IsNullOrEmpty(msg) ? Translations.bot_autoRelog_reconnect_always : Translations.bot_autoRelog_reconnect, msg));
|
LogDebugToConsole(string.Format(string.IsNullOrEmpty(msg) ? Translations.bot_autoRelog_reconnect_always : Translations.bot_autoRelog_reconnect, msg));
|
||||||
|
|
||||||
int retriesLeft = Config.Retries - Configs._BotRecoAttempts;
|
string retriesDisplay = HasUnlimitedRetries()
|
||||||
if (retriesLeft < 0)
|
|
||||||
retriesLeft = 0;
|
|
||||||
|
|
||||||
string retriesDisplay = Config.Retries == int.MaxValue
|
|
||||||
? Translations.bot_autoRelog_retries_unlimited
|
? Translations.bot_autoRelog_retries_unlimited
|
||||||
: retriesLeft.ToString();
|
: retriesLeft.ToString();
|
||||||
|
|
||||||
LogToConsole(string.Format(Translations.bot_autoRelog_wait_with_retries, delay, retriesDisplay));
|
McClient.ReconnectionAttemptsLeft = retriesLeft;
|
||||||
ReconnectToTheServer(retriesLeft, (int)Math.Floor(delay), true);
|
if (Program.TryRestart((int)Math.Floor(delay), true))
|
||||||
|
{
|
||||||
|
LogToConsole(string.Format(Translations.bot_autoRelog_wait_with_retries, delay, retriesDisplay));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RollBackReconnectAttempt();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool OnDisconnectStatic(DisconnectReason reason, string message)
|
public static bool OnDisconnectStatic(DisconnectReason reason, string message)
|
||||||
|
|
|
||||||
|
|
@ -899,12 +899,25 @@ namespace MinecraftClient
|
||||||
/// <param name="delaySeconds">Optional delay, in seconds, before restarting</param>
|
/// <param name="delaySeconds">Optional delay, in seconds, before restarting</param>
|
||||||
/// <param name="keepAccountAndServerSettings">Optional, keep account and server settings</param>
|
/// <param name="keepAccountAndServerSettings">Optional, keep account and server settings</param>
|
||||||
public static void Restart(int delaySeconds = 0, bool keepAccountAndServerSettings = false)
|
public static void Restart(int delaySeconds = 0, bool keepAccountAndServerSettings = false)
|
||||||
|
{
|
||||||
|
TryRestart(delaySeconds, keepAccountAndServerSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool HasRestartPendingForAnotherThread
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_restartLock)
|
||||||
|
return HasRestartPendingForAnotherThreadNoLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool TryRestart(int delaySeconds = 0, bool keepAccountAndServerSettings = false)
|
||||||
{
|
{
|
||||||
lock (_restartLock)
|
lock (_restartLock)
|
||||||
{
|
{
|
||||||
if (_restartThread is not null && _restartThread.IsAlive
|
if (HasRestartPendingForAnotherThreadNoLock())
|
||||||
&& _restartThread != Thread.CurrentThread)
|
return false;
|
||||||
return;
|
|
||||||
|
|
||||||
ConsoleIO.Backend?.StopReadThread();
|
ConsoleIO.Backend?.StopReadThread();
|
||||||
var thread = new Thread(new ThreadStart(delegate
|
var thread = new Thread(new ThreadStart(delegate
|
||||||
|
|
@ -938,9 +951,17 @@ namespace MinecraftClient
|
||||||
}));
|
}));
|
||||||
_restartThread = thread;
|
_restartThread = thread;
|
||||||
thread.Start();
|
thread.Start();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool HasRestartPendingForAnotherThreadNoLock()
|
||||||
|
{
|
||||||
|
return _restartThread is not null
|
||||||
|
&& _restartThread.IsAlive
|
||||||
|
&& _restartThread != Thread.CurrentThread;
|
||||||
|
}
|
||||||
|
|
||||||
public static void DoExit(int exitcode = 0)
|
public static void DoExit(int exitcode = 0)
|
||||||
{
|
{
|
||||||
WriteBackSettings();
|
WriteBackSettings();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue