mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-29 13:04:59 +00:00
Fixed transfering breaking on multiple versions
This commit is contained in:
parent
52eda4ccdd
commit
41a1a1db9b
4 changed files with 81 additions and 17 deletions
|
|
@ -75,8 +75,8 @@ namespace MinecraftClient
|
||||||
private int sequenceId; // User for player block synchronization (Aka. digging, placing blocks, etc..)
|
private int sequenceId; // User for player block synchronization (Aka. digging, placing blocks, etc..)
|
||||||
private bool CanSendMessage = false;
|
private bool CanSendMessage = false;
|
||||||
|
|
||||||
private readonly string host;
|
private string host;
|
||||||
private readonly int port;
|
private int port;
|
||||||
private readonly int protocolversion;
|
private readonly int protocolversion;
|
||||||
private readonly string username;
|
private readonly string username;
|
||||||
private Guid uuid;
|
private Guid uuid;
|
||||||
|
|
@ -159,6 +159,7 @@ namespace MinecraftClient
|
||||||
SessionToken _sessionToken;
|
SessionToken _sessionToken;
|
||||||
CancellationTokenSource? cmdprompt = null;
|
CancellationTokenSource? cmdprompt = null;
|
||||||
Tuple<Thread, CancellationTokenSource>? timeoutdetector = null;
|
Tuple<Thread, CancellationTokenSource>? timeoutdetector = null;
|
||||||
|
private int transferInProgress = 0;
|
||||||
|
|
||||||
public ILogger Log;
|
public ILogger Log;
|
||||||
|
|
||||||
|
|
@ -335,16 +336,34 @@ namespace MinecraftClient
|
||||||
|
|
||||||
public void Transfer(string newHost, int newPort)
|
public void Transfer(string newHost, int newPort)
|
||||||
{
|
{
|
||||||
|
// Do not block here: a new handler can start processing packets before the
|
||||||
|
// previous transfer call fully unwinds, and waiting can deadlock main-thread work.
|
||||||
|
if (Interlocked.CompareExchange(ref transferInProgress, 1, 0) != 0)
|
||||||
|
{
|
||||||
|
Log.Warn($"Ignoring overlapping transfer to {newHost}:{newPort} because another transfer is still in progress.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMinecraftCom oldHandler = handler;
|
||||||
|
TcpClient oldClient = client;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.Info($"Initiating a transfer to: {host}:{port}");
|
Log.Info($"Initiating a transfer to: {newHost}:{newPort}");
|
||||||
|
|
||||||
// Unload bots
|
// Unload bots
|
||||||
UnloadAllBots();
|
UnloadAllBots();
|
||||||
bots.Clear();
|
bots.Clear();
|
||||||
|
|
||||||
|
ResetStateForTransfer();
|
||||||
|
|
||||||
// Close existing connection
|
// Retire the old handler so its updater exits without reporting a stale disconnect.
|
||||||
client.Close();
|
oldHandler.Dispose();
|
||||||
|
oldClient.Close();
|
||||||
|
|
||||||
|
host = newHost;
|
||||||
|
port = newPort;
|
||||||
|
UpdateKeepAlive();
|
||||||
|
|
||||||
// Establish new connection
|
// Establish new connection
|
||||||
client = ProxyHandler.NewTcpClient(newHost, newPort);
|
client = ProxyHandler.NewTcpClient(newHost, newPort);
|
||||||
|
|
@ -353,20 +372,17 @@ namespace MinecraftClient
|
||||||
|
|
||||||
// Reinitialize the protocol handler
|
// Reinitialize the protocol handler
|
||||||
handler = Protocol.ProtocolHandler.GetProtocolHandler(client, protocolversion, null, this);
|
handler = Protocol.ProtocolHandler.GetProtocolHandler(client, protocolversion, null, this);
|
||||||
Log.Info($"Connected to {host}:{port}");
|
Log.Info($"Connected to {newHost}:{newPort}");
|
||||||
|
|
||||||
// Retry login process
|
// Retry login process
|
||||||
if (handler.Login(playerKeyPair, _sessionToken))
|
if (handler.Login(playerKeyPair, _sessionToken, isTransfer: true))
|
||||||
{
|
{
|
||||||
foreach (var bot in botsOnHold)
|
foreach (var bot in botsOnHold)
|
||||||
BotLoad(bot, false);
|
BotLoad(bot, false);
|
||||||
botsOnHold.Clear();
|
botsOnHold.Clear();
|
||||||
|
|
||||||
Log.Info("Successfully transferred connection and logged in.");
|
UpdateKeepAlive();
|
||||||
cmdprompt = new CancellationTokenSource();
|
Log.Info($"Successfully transferred connection and logged in to {newHost}:{newPort}.");
|
||||||
ConsoleInteractive.ConsoleReader.BeginReadThread();
|
|
||||||
ConsoleInteractive.ConsoleReader.MessageReceived += ConsoleReaderOnMessageReceived;
|
|
||||||
ConsoleInteractive.ConsoleReader.OnInputChange += ConsoleIO.AutocompleteHandler;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -378,6 +394,22 @@ namespace MinecraftClient
|
||||||
{
|
{
|
||||||
Log.Error($"Transfer to {newHost}:{newPort} failed: {ex.Message}");
|
Log.Error($"Transfer to {newHost}:{newPort} failed: {ex.Message}");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
handler.Dispose();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
client.Close();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Handle reconnection attempts
|
// Handle reconnection attempts
|
||||||
if (timeoutdetector is not null)
|
if (timeoutdetector is not null)
|
||||||
{
|
{
|
||||||
|
|
@ -400,8 +432,35 @@ namespace MinecraftClient
|
||||||
Program.HandleFailure();
|
Program.HandleFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Exception("Transfer failed and reconnection attempts exhausted.");
|
throw new Exception("Transfer failed and reconnection attempts exhausted.", ex);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Interlocked.Exchange(ref transferInProgress, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetStateForTransfer()
|
||||||
|
{
|
||||||
|
ClearTasks();
|
||||||
|
ConsoleIO.CancelAutocomplete();
|
||||||
|
SetCanSendMessage(false);
|
||||||
|
|
||||||
|
locationReceived = false;
|
||||||
|
physicsInitialized = false;
|
||||||
|
isUnderSlab = false;
|
||||||
|
path = null;
|
||||||
|
pathTarget = null;
|
||||||
|
_yaw = null;
|
||||||
|
_pitch = null;
|
||||||
|
LastDigPosition = null;
|
||||||
|
RemainingDiggingTime = 0;
|
||||||
|
nextSneakingUpdate = DateTime.Now;
|
||||||
|
|
||||||
|
physicsInput.Reset();
|
||||||
|
world.Clear();
|
||||||
|
entities.Clear();
|
||||||
|
ClearInventories();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -618,7 +618,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Login(PlayerKeyPair? playerKeyPair, SessionToken session)
|
public bool Login(PlayerKeyPair? playerKeyPair, SessionToken session, bool isTransfer = false)
|
||||||
{
|
{
|
||||||
if (Handshake(handler.GetUserUuidStr(), handler.GetUsername(), handler.GetSessionID(), handler.GetServerHost(), handler.GetServerPort(), session))
|
if (Handshake(handler.GetUserUuidStr(), handler.GetUsername(), handler.GetSessionID(), handler.GetServerHost(), handler.GetServerPort(), session))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3188,8 +3188,13 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
/// Do the Minecraft login.
|
/// Do the Minecraft login.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if login successful</returns>
|
/// <returns>True if login successful</returns>
|
||||||
public bool Login(PlayerKeyPair? playerKeyPair, SessionToken session)
|
public bool Login(PlayerKeyPair? playerKeyPair, SessionToken session, bool isTransfer = false)
|
||||||
{
|
{
|
||||||
|
int nextState = isTransfer && protocolVersion >= MC_1_20_6_Version ? 3 : 2;
|
||||||
|
|
||||||
|
if (nextState == 3)
|
||||||
|
log.Debug("Using transfer handshake intent for transferred login.");
|
||||||
|
|
||||||
// 1. Send the handshake packet
|
// 1. Send the handshake packet
|
||||||
SendPacket(0x00, dataTypes.ConcatBytes(
|
SendPacket(0x00, dataTypes.ConcatBytes(
|
||||||
// Protocol Version (use raw version for snapshot/RC servers)
|
// Protocol Version (use raw version for snapshot/RC servers)
|
||||||
|
|
@ -3202,7 +3207,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
dataTypes.GetUShort((ushort)handler.GetServerPort()),
|
dataTypes.GetUShort((ushort)handler.GetServerPort()),
|
||||||
|
|
||||||
// Next State
|
// Next State
|
||||||
DataTypes.GetVarInt(2)) // 2 is for the Login state
|
DataTypes.GetVarInt(nextState)) // 2 is Login, 3 is Transfer
|
||||||
);
|
);
|
||||||
|
|
||||||
// 2. Send the Login Start packet
|
// 2. Send the Login Start packet
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace MinecraftClient.Protocol
|
||||||
/// Start the login procedure once connected to the server
|
/// Start the login procedure once connected to the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if login was successful</returns>
|
/// <returns>True if login was successful</returns>
|
||||||
bool Login(PlayerKeyPair? playerKeyPair, Session.SessionToken session);
|
bool Login(PlayerKeyPair? playerKeyPair, Session.SessionToken session, bool isTransfer = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disconnect from the server
|
/// Disconnect from the server
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue