mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Add connection timeout using server keepalives
Vanilla client will consider that connection has been lost when no server keepalive was received during the last 30 seconds. This commit implements a similar mechanism in MCC. See #802
This commit is contained in:
parent
1406c00abd
commit
877e50579d
4 changed files with 61 additions and 6 deletions
|
|
@ -52,6 +52,8 @@ namespace MinecraftClient
|
||||||
private string uuid;
|
private string uuid;
|
||||||
private string sessionid;
|
private string sessionid;
|
||||||
private Inventory playerInventory;
|
private Inventory playerInventory;
|
||||||
|
private DateTime lastKeepAlive;
|
||||||
|
private object lastKeepAliveLock = new object();
|
||||||
|
|
||||||
public int GetServerPort() { return port; }
|
public int GetServerPort() { return port; }
|
||||||
public string GetServerHost() { return host; }
|
public string GetServerHost() { return host; }
|
||||||
|
|
@ -64,6 +66,7 @@ namespace MinecraftClient
|
||||||
TcpClient client;
|
TcpClient client;
|
||||||
IMinecraftCom handler;
|
IMinecraftCom handler;
|
||||||
Thread cmdprompt;
|
Thread cmdprompt;
|
||||||
|
Thread timeoutdetector;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts the main chat client
|
/// Starts the main chat client
|
||||||
|
|
@ -167,6 +170,10 @@ namespace MinecraftClient
|
||||||
cmdprompt = new Thread(new ThreadStart(CommandPrompt));
|
cmdprompt = new Thread(new ThreadStart(CommandPrompt));
|
||||||
cmdprompt.Name = "MCC Command prompt";
|
cmdprompt.Name = "MCC Command prompt";
|
||||||
cmdprompt.Start();
|
cmdprompt.Start();
|
||||||
|
|
||||||
|
timeoutdetector = new Thread(new ThreadStart(TimeoutDetector));
|
||||||
|
timeoutdetector.Name = "MCC Connection timeout detector";
|
||||||
|
timeoutdetector.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -253,6 +260,29 @@ namespace MinecraftClient
|
||||||
catch (NullReferenceException) { }
|
catch (NullReferenceException) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Periodically checks for server keepalives and consider that connection has been lost if the last received keepalive is too old.
|
||||||
|
/// </summary>
|
||||||
|
private void TimeoutDetector()
|
||||||
|
{
|
||||||
|
lock (lastKeepAliveLock)
|
||||||
|
{
|
||||||
|
lastKeepAlive = DateTime.Now;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Thread.Sleep(TimeSpan.FromSeconds(15));
|
||||||
|
lock (lastKeepAliveLock)
|
||||||
|
{
|
||||||
|
if (lastKeepAlive.AddSeconds(30) < DateTime.Now)
|
||||||
|
{
|
||||||
|
OnConnectionLost(ChatBot.DisconnectReason.ConnectionLost, "Connection Timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (true);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
|
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -336,6 +366,9 @@ namespace MinecraftClient
|
||||||
if (cmdprompt != null)
|
if (cmdprompt != null)
|
||||||
cmdprompt.Abort();
|
cmdprompt.Abort();
|
||||||
|
|
||||||
|
if (timeoutdetector != null)
|
||||||
|
timeoutdetector.Abort();
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
|
|
||||||
if (client != null)
|
if (client != null)
|
||||||
|
|
@ -607,6 +640,10 @@ namespace MinecraftClient
|
||||||
/// <param name="links">Links embedded in text</param>
|
/// <param name="links">Links embedded in text</param>
|
||||||
public void OnTextReceived(string text, bool isJson)
|
public void OnTextReceived(string text, bool isJson)
|
||||||
{
|
{
|
||||||
|
lock (lastKeepAliveLock)
|
||||||
|
{
|
||||||
|
lastKeepAlive = DateTime.Now;
|
||||||
|
}
|
||||||
List<string> links = new List<string>();
|
List<string> links = new List<string>();
|
||||||
string json = null;
|
string json = null;
|
||||||
if (isJson)
|
if (isJson)
|
||||||
|
|
@ -637,11 +674,22 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Received a connection keep-alive from the server
|
||||||
|
/// </summary>
|
||||||
|
public void OnServerKeepAlive()
|
||||||
|
{
|
||||||
|
lock (lastKeepAliveLock)
|
||||||
|
{
|
||||||
|
lastKeepAlive = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When an inventory is opened
|
/// When an inventory is opened
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="inventory">Location to reach</param>
|
/// <param name="inventory">Location to reach</param>
|
||||||
public void onInventoryOpen(Inventory inventory)
|
public void OnInventoryOpen(Inventory inventory)
|
||||||
{
|
{
|
||||||
//TODO: Handle Inventory
|
//TODO: Handle Inventory
|
||||||
if (!inventories.Contains(inventory))
|
if (!inventories.Contains(inventory))
|
||||||
|
|
@ -654,7 +702,7 @@ namespace MinecraftClient
|
||||||
/// When an inventory is close
|
/// When an inventory is close
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="inventoryID">Location to reach</param>
|
/// <param name="inventoryID">Location to reach</param>
|
||||||
public void onInventoryClose(byte inventoryID)
|
public void OnInventoryClose(byte inventoryID)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < inventories.Count; i++)
|
for (int i = 0; i < inventories.Count; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
{
|
{
|
||||||
case 0x00: byte[] keepalive = new byte[5] { 0, 0, 0, 0, 0 };
|
case 0x00: byte[] keepalive = new byte[5] { 0, 0, 0, 0, 0 };
|
||||||
Receive(keepalive, 1, 4, SocketFlags.None);
|
Receive(keepalive, 1, 4, SocketFlags.None);
|
||||||
|
handler.OnServerKeepAlive();
|
||||||
Send(keepalive); break;
|
Send(keepalive); break;
|
||||||
case 0x01: readData(4); readNextString(); readData(5); break;
|
case 0x01: readData(4); readNextString(); readData(5); break;
|
||||||
case 0x02: readData(1); readNextString(); readNextString(); readData(4); break;
|
case 0x02: readData(1); readNextString(); readNextString(); readData(4); break;
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
{
|
{
|
||||||
case PacketIncomingType.KeepAlive:
|
case PacketIncomingType.KeepAlive:
|
||||||
SendPacket(PacketOutgoingType.KeepAlive, packetData);
|
SendPacket(PacketOutgoingType.KeepAlive, packetData);
|
||||||
|
handler.OnServerKeepAlive();
|
||||||
break;
|
break;
|
||||||
case PacketIncomingType.JoinGame:
|
case PacketIncomingType.JoinGame:
|
||||||
handler.OnGameJoined();
|
handler.OnGameJoined();
|
||||||
|
|
@ -481,7 +482,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
byte slots = dataTypes.ReadNextByte(packetData);
|
byte slots = dataTypes.ReadNextByte(packetData);
|
||||||
Inventory inventory = new Inventory(windowID, inventoryType, title, slots);
|
Inventory inventory = new Inventory(windowID, inventoryType, title, slots);
|
||||||
|
|
||||||
handler.onInventoryOpen(inventory);
|
handler.OnInventoryOpen(inventory);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PacketIncomingType.CloseWindow:
|
case PacketIncomingType.CloseWindow:
|
||||||
|
|
@ -489,7 +490,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
{
|
{
|
||||||
byte windowID = dataTypes.ReadNextByte(packetData);
|
byte windowID = dataTypes.ReadNextByte(packetData);
|
||||||
|
|
||||||
handler.onInventoryClose(windowID);
|
handler.OnInventoryClose(windowID);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PacketIncomingType.WindowItems:
|
case PacketIncomingType.WindowItems:
|
||||||
|
|
|
||||||
|
|
@ -43,15 +43,20 @@ namespace MinecraftClient.Protocol
|
||||||
/// <param name="isJson">TRUE if the text is JSON-Encoded</param>
|
/// <param name="isJson">TRUE if the text is JSON-Encoded</param>
|
||||||
void OnTextReceived(string text, bool isJson);
|
void OnTextReceived(string text, bool isJson);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when receiving a connection keep-alive from the server
|
||||||
|
/// </summary>
|
||||||
|
void OnServerKeepAlive();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when an inventory is opened
|
/// Called when an inventory is opened
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void onInventoryOpen(Inventory inventory);
|
void OnInventoryOpen(Inventory inventory);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when an inventory is closed
|
/// Called when an inventory is closed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void onInventoryClose(byte inventoryID);
|
void OnInventoryClose(byte inventoryID);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the player respawns, which happens on login, respawn and world change.
|
/// Called when the player respawns, which happens on login, respawn and world change.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue