mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
fix: isolate queued restart settings
This commit is contained in:
parent
1686d00f30
commit
9b90b535d8
5 changed files with 99 additions and 21 deletions
|
|
@ -47,8 +47,9 @@ namespace MinecraftClient.Commands
|
|||
|
||||
if (Settings.Config.Main.SetServerIP(new Settings.MainConfigHelper.MainConfig.ServerInfoConfig(server), true))
|
||||
{
|
||||
Program.Restart(keepAccountAndServerSettings: true);
|
||||
return r.SetAndReturn(Status.Done);
|
||||
return r.SetAndReturn(Program.TryRestart(keepAccountAndServerSettings: true)
|
||||
? Status.Done
|
||||
: Status.Fail);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -64,8 +65,9 @@ namespace MinecraftClient.Commands
|
|||
|
||||
if (Settings.Config.Main.SetServerIP(new Settings.MainConfigHelper.MainConfig.ServerInfoConfig(args[0]), true))
|
||||
{
|
||||
Program.Restart(keepAccountAndServerSettings: true);
|
||||
return string.Empty;
|
||||
return Program.TryRestart(keepAccountAndServerSettings: true)
|
||||
? string.Empty
|
||||
: Translations.general_fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ namespace MinecraftClient.Commands
|
|||
if (!Settings.Config.Main.Advanced.SetAccount(account))
|
||||
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_connect_unknown, account));
|
||||
}
|
||||
Program.Restart(keepAccountAndServerSettings: true);
|
||||
return r.SetAndReturn(CmdResult.Status.Done);
|
||||
return r.SetAndReturn(Program.TryRestart(keepAccountAndServerSettings: true)
|
||||
? CmdResult.Status.Done
|
||||
: CmdResult.Status.Fail);
|
||||
}
|
||||
|
||||
internal static string DoReconnect(string command)
|
||||
|
|
@ -62,8 +63,9 @@ namespace MinecraftClient.Commands
|
|||
return string.Format(Translations.cmd_connect_unknown, account);
|
||||
}
|
||||
}
|
||||
Program.Restart(keepAccountAndServerSettings: true);
|
||||
return String.Empty;
|
||||
return Program.TryRestart(keepAccountAndServerSettings: true)
|
||||
? String.Empty
|
||||
: Translations.general_fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -923,10 +923,15 @@ namespace MinecraftClient
|
|||
if (delay < TimeSpan.Zero)
|
||||
delay = TimeSpan.Zero;
|
||||
|
||||
RestartSettingsSnapshot? settingsSnapshot = keepAccountAndServerSettings
|
||||
? new RestartSettingsSnapshot(InternalConfig.Account, InternalConfig.ServerIP, InternalConfig.ServerPort)
|
||||
: null;
|
||||
|
||||
return restartCoordinator.TrySchedule(new RestartRequest(
|
||||
Volatile.Read(ref connectionAttempt),
|
||||
delay,
|
||||
keepAccountAndServerSettings));
|
||||
keepAccountAndServerSettings,
|
||||
settingsSnapshot));
|
||||
}
|
||||
|
||||
private static async Task ExecuteRestartAsync(RestartRequest request, CancellationToken cancellationToken)
|
||||
|
|
@ -951,6 +956,12 @@ namespace MinecraftClient
|
|||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ConsoleIO.WriteLine(Translations.mcc_restart);
|
||||
ReloadSettings(request.KeepAccountAndServerSettings);
|
||||
if (request.SettingsSnapshot is RestartSettingsSnapshot settingsSnapshot)
|
||||
{
|
||||
InternalConfig.Account = settingsSnapshot.Account;
|
||||
InternalConfig.ServerIP = settingsSnapshot.ServerIP;
|
||||
InternalConfig.ServerPort = settingsSnapshot.ServerPort;
|
||||
}
|
||||
InitializeClient();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,14 @@ namespace MinecraftClient
|
|||
internal readonly record struct RestartRequest(
|
||||
long ConnectionAttempt,
|
||||
TimeSpan Delay,
|
||||
bool KeepAccountAndServerSettings);
|
||||
bool KeepAccountAndServerSettings,
|
||||
RestartSettingsSnapshot? SettingsSnapshot = null,
|
||||
long RequestId = 0);
|
||||
|
||||
internal readonly record struct RestartSettingsSnapshot(
|
||||
Settings.MainConfigHelper.MainConfig.AccountInfoConfig Account,
|
||||
string ServerIP,
|
||||
ushort ServerPort);
|
||||
|
||||
internal sealed class RestartCoordinator : IDisposable
|
||||
{
|
||||
|
|
@ -19,8 +26,9 @@ namespace MinecraftClient
|
|||
private readonly Func<RestartRequest, CancellationToken, Task> restart;
|
||||
private readonly Action<Exception> reportFailure;
|
||||
private readonly Task worker;
|
||||
private readonly HashSet<long> pendingAttempts = [];
|
||||
private readonly Dictionary<long, long> pendingAttempts = [];
|
||||
private long highestScheduledAttempt = -1;
|
||||
private long nextRequestId;
|
||||
private bool stopped;
|
||||
|
||||
internal RestartCoordinator(
|
||||
|
|
@ -44,22 +52,28 @@ namespace MinecraftClient
|
|||
internal bool HasScheduledRestart(long connectionAttempt)
|
||||
{
|
||||
lock (stateLock)
|
||||
return !stopped && pendingAttempts.Contains(connectionAttempt);
|
||||
return !stopped && pendingAttempts.ContainsKey(connectionAttempt);
|
||||
}
|
||||
|
||||
internal bool TrySchedule(RestartRequest request)
|
||||
{
|
||||
lock (stateLock)
|
||||
{
|
||||
if (stopped || request.ConnectionAttempt <= highestScheduledAttempt)
|
||||
bool hasPendingRequest = pendingAttempts.TryGetValue(request.ConnectionAttempt, out long previousRequestId);
|
||||
if (stopped || request.ConnectionAttempt < highestScheduledAttempt
|
||||
|| (request.ConnectionAttempt == highestScheduledAttempt && !hasPendingRequest))
|
||||
return false;
|
||||
|
||||
highestScheduledAttempt = request.ConnectionAttempt;
|
||||
pendingAttempts.Add(request.ConnectionAttempt);
|
||||
highestScheduledAttempt = Math.Max(highestScheduledAttempt, request.ConnectionAttempt);
|
||||
request = request with { RequestId = ++nextRequestId };
|
||||
pendingAttempts[request.ConnectionAttempt] = request.RequestId;
|
||||
if (requests.Writer.TryWrite(request))
|
||||
return true;
|
||||
|
||||
pendingAttempts.Remove(request.ConnectionAttempt);
|
||||
if (hasPendingRequest)
|
||||
pendingAttempts[request.ConnectionAttempt] = previousRequestId;
|
||||
else
|
||||
pendingAttempts.Remove(request.ConnectionAttempt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -84,6 +98,13 @@ namespace MinecraftClient
|
|||
{
|
||||
await foreach (RestartRequest request in requests.Reader.ReadAllAsync(shutdown.Token).ConfigureAwait(false))
|
||||
{
|
||||
lock (stateLock)
|
||||
{
|
||||
if (!pendingAttempts.TryGetValue(request.ConnectionAttempt, out long requestId)
|
||||
|| requestId != request.RequestId)
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await restart(request, shutdown.Token).ConfigureAwait(false);
|
||||
|
|
@ -99,7 +120,11 @@ namespace MinecraftClient
|
|||
finally
|
||||
{
|
||||
lock (stateLock)
|
||||
pendingAttempts.Remove(request.ConnectionAttempt);
|
||||
{
|
||||
if (pendingAttempts.TryGetValue(request.ConnectionAttempt, out long requestId)
|
||||
&& requestId == request.RequestId)
|
||||
pendingAttempts.Remove(request.ConnectionAttempt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue