https://github.com/ORelio/Minecraft-Console-Client/issues/525: general 1.13 support (v393 protocol). Note that terrainandmovements might cause some issues

This commit is contained in:
TheSnoozer 2018-09-25 07:38:28 -04:00 committed by ORelio
parent a92d023450
commit aad3d8b2ef
6 changed files with 251 additions and 33 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@
/MinecraftClientGUI.suo
/MinecraftClient.userprefs
/.vs/
SessionCache.ini

View file

@ -23,7 +23,7 @@ namespace MinecraftClient
public const string Version = MCHighestVersion;
public const string MCLowestVersion = "1.4.6";
public const string MCHighestVersion = "1.12.2";
public const string MCHighestVersion = "1.13";
public static readonly string BuildInfo = null;
private static Thread offlinePrompt = null;
@ -289,7 +289,7 @@ namespace MinecraftClient
/// <summary>
/// Disconnect the current client from the server and restart it
/// </summary>
/// <param name="delay">Optional delay, in seconds, before restarting</param>
/// <param name="delaySeconds">Optional delay, in seconds, before restarting</param>
public static void Restart(int delaySeconds = 0)
{
new Thread(new ThreadStart(delegate

View file

@ -96,10 +96,20 @@ namespace MinecraftClient.Protocol
try
{
string assets_index = DownloadString(Settings.TranslationsFile_Website_Index);
string[] tmp = assets_index.Split(new string[] { "minecraft/lang/" + Settings.Language + ".lang" }, StringSplitOptions.None);
string[] tmp = assets_index.Split(new string[] { "minecraft/lang/" + Settings.Language.ToLower() + ".json" }, StringSplitOptions.None);
tmp = tmp[1].Split(new string[] { "hash\": \"" }, StringSplitOptions.None);
string hash = tmp[1].Split('"')[0]; //Translations file identifier on Mojang's servers
System.IO.File.WriteAllText(Language_File, DownloadString(Settings.TranslationsFile_Website_Download + '/' + hash.Substring(0, 2) + '/' + hash));
string translation_file_location = Settings.TranslationsFile_Website_Download + '/' + hash.Substring(0, 2) + '/' + hash;
if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Performing request to " + translation_file_location);
StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<string, Json.JSONData> entry in Json.ParseJson(DownloadString(translation_file_location)).Properties)
{
stringBuilder.Append(entry.Key + "=" + entry.Value.StringValue + Environment.NewLine);
}
System.IO.File.WriteAllText(Language_File, stringBuilder.ToString());
ConsoleIO.WriteLineFormatted("§8Done. File saved as '" + Language_File + '\'');
}
catch

View file

@ -25,9 +25,18 @@ namespace MinecraftClient.Protocol.Handlers
private const int MC17w13aVersion = 318;
private const int MC112pre5Version = 332;
private const int MC17w31aVersion = 336;
private const int MC17w45aVersion = 343;
private const int MC17w46aVersion = 345;
private const int MC17w47aVersion = 346;
private const int MC18w01aVersion = 352;
private const int MC18w06aVersion = 357;
private const int MC113pre4Version = 386;
private const int MC113pre7Version = 389;
private const int MC113Version = 393;
private int compression_treshold = 0;
private bool autocomplete_received = false;
private int autocomplete_transaction_id = 0;
private readonly List<string> autocomplete_result = new List<string>();
private bool login_phase = true;
private bool encrypted = false;
@ -254,7 +263,7 @@ namespace MinecraftClient.Protocol.Handlers
default: return PacketIncomingType.UnknownPacket;
}
}
else
else if (protocol < MC17w45aVersion)
{
switch (packetID)
{
@ -277,6 +286,98 @@ namespace MinecraftClient.Protocol.Handlers
default: return PacketIncomingType.UnknownPacket;
}
}
else if (protocol < MC17w46aVersion)
{
switch (packetID)
{
case 0x1F: return PacketIncomingType.KeepAlive;
case 0x23: return PacketIncomingType.JoinGame;
case 0x0E: return PacketIncomingType.ChatMessage;
case 0x35: return PacketIncomingType.Respawn;
case 0x2F: return PacketIncomingType.PlayerPositionAndLook;
case 0x21: return PacketIncomingType.ChunkData;
case 0x0F: return PacketIncomingType.MultiBlockChange;
case 0x0B: return PacketIncomingType.BlockChange;
//MapChunkBulk removed in 1.9
case 0x1D: return PacketIncomingType.UnloadChunk;
case 0x2E: return PacketIncomingType.PlayerListUpdate;
//TabCompleteResult accidentely removed
case 0x18: return PacketIncomingType.PluginMessage;
case 0x1A: return PacketIncomingType.KickPacket;
//NetworkCompressionTreshold removed in 1.9
case 0x34: return PacketIncomingType.ResourcePackSend;
default: return PacketIncomingType.UnknownPacket;
}
}
else if (protocol < MC18w01aVersion)
{
switch (packetID)
{
case 0x20: return PacketIncomingType.KeepAlive;
case 0x24: return PacketIncomingType.JoinGame;
case 0x0E: return PacketIncomingType.ChatMessage;
case 0x36: return PacketIncomingType.Respawn;
case 0x30: return PacketIncomingType.PlayerPositionAndLook;
case 0x21: return PacketIncomingType.ChunkData;
case 0x0F: return PacketIncomingType.MultiBlockChange;
case 0x0B: return PacketIncomingType.BlockChange;
//MapChunkBulk removed in 1.9
case 0x1E: return PacketIncomingType.UnloadChunk;
case 0x2F: return PacketIncomingType.PlayerListUpdate;
case 0x10: return PacketIncomingType.TabCompleteResult;
case 0x19: return PacketIncomingType.PluginMessage;
case 0x1B: return PacketIncomingType.KickPacket;
//NetworkCompressionTreshold removed in 1.9
case 0x35: return PacketIncomingType.ResourcePackSend;
default: return PacketIncomingType.UnknownPacket;
}
}
else if (protocol < MC113pre7Version)
{
switch (packetID)
{
case 0x20: return PacketIncomingType.KeepAlive;
case 0x24: return PacketIncomingType.JoinGame;
case 0x0E: return PacketIncomingType.ChatMessage;
case 0x37: return PacketIncomingType.Respawn;
case 0x31: return PacketIncomingType.PlayerPositionAndLook;
case 0x21: return PacketIncomingType.ChunkData;
case 0x0F: return PacketIncomingType.MultiBlockChange;
case 0x0B: return PacketIncomingType.BlockChange;
//MapChunkBulk removed in 1.9
case 0x1E: return PacketIncomingType.UnloadChunk;
case 0x2F: return PacketIncomingType.PlayerListUpdate;
case 0x10: return PacketIncomingType.TabCompleteResult;
case 0x19: return PacketIncomingType.PluginMessage;
case 0x1B: return PacketIncomingType.KickPacket;
//NetworkCompressionTreshold removed in 1.9
case 0x36: return PacketIncomingType.ResourcePackSend;
default: return PacketIncomingType.UnknownPacket;
}
}
else
{
switch (packetID)
{
case 0x21: return PacketIncomingType.KeepAlive;
case 0x25: return PacketIncomingType.JoinGame;
case 0x0E: return PacketIncomingType.ChatMessage;
case 0x38: return PacketIncomingType.Respawn;
case 0x32: return PacketIncomingType.PlayerPositionAndLook;
case 0x22: return PacketIncomingType.ChunkData;
case 0x0F: return PacketIncomingType.MultiBlockChange;
case 0x0B: return PacketIncomingType.BlockChange;
//MapChunkBulk removed in 1.9
case 0x1F: return PacketIncomingType.UnloadChunk;
case 0x30: return PacketIncomingType.PlayerListUpdate;
case 0x10: return PacketIncomingType.TabCompleteResult;
case 0x19: return PacketIncomingType.PluginMessage;
case 0x1B: return PacketIncomingType.KickPacket;
//NetworkCompressionTreshold removed in 1.9
case 0x37: return PacketIncomingType.ResourcePackSend;
default: return PacketIncomingType.UnknownPacket;
}
}
}
/// <summary>
@ -368,7 +469,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.TeleportConfirm: return 0x00;
}
}
else
else if (protocol < MC17w45aVersion)
{
switch (packet)
{
@ -384,6 +485,70 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.TeleportConfirm: return 0x00;
}
}
else if (protocol < MC17w46aVersion)
{
switch (packet)
{
case PacketOutgoingType.KeepAlive: return 0x0A;
case PacketOutgoingType.ResourcePackStatus: return 0x17;
case PacketOutgoingType.ChatMessage: return 0x01;
case PacketOutgoingType.ClientStatus: return 0x02;
case PacketOutgoingType.ClientSettings: return 0x03;
case PacketOutgoingType.PluginMessage: return 0x08;
case PacketOutgoingType.TabComplete: throw new InvalidOperationException("TabComplete was accidentely removed in protocol " + protocol + ". Please use a more recent version.");
case PacketOutgoingType.PlayerPosition: return 0x0C;
case PacketOutgoingType.PlayerPositionAndLook: return 0x0D;
case PacketOutgoingType.TeleportConfirm: return 0x00;
}
}
else if (protocol < MC113pre4Version)
{
switch (packet)
{
case PacketOutgoingType.KeepAlive: return 0x0B;
case PacketOutgoingType.ResourcePackStatus: return 0x18;
case PacketOutgoingType.ChatMessage: return 0x01;
case PacketOutgoingType.ClientStatus: return 0x02;
case PacketOutgoingType.ClientSettings: return 0x03;
case PacketOutgoingType.PluginMessage: return 0x09;
case PacketOutgoingType.TabComplete: return 0x04;
case PacketOutgoingType.PlayerPosition: return 0x0D;
case PacketOutgoingType.PlayerPositionAndLook: return 0x0E;
case PacketOutgoingType.TeleportConfirm: return 0x00;
}
}
else if (protocol < MC113pre7Version)
{
switch (packet)
{
case PacketOutgoingType.KeepAlive: return 0x0C;
case PacketOutgoingType.ResourcePackStatus: return 0x1B;
case PacketOutgoingType.ChatMessage: return 0x01;
case PacketOutgoingType.ClientStatus: return 0x02;
case PacketOutgoingType.ClientSettings: return 0x03;
case PacketOutgoingType.PluginMessage: return 0x09;
case PacketOutgoingType.TabComplete: return 0x04;
case PacketOutgoingType.PlayerPosition: return 0x0E;
case PacketOutgoingType.PlayerPositionAndLook: return 0x0F;
case PacketOutgoingType.TeleportConfirm: return 0x00;
}
}
else
{
switch (packet)
{
case PacketOutgoingType.KeepAlive: return 0x0E;
case PacketOutgoingType.ResourcePackStatus: return 0x1D;
case PacketOutgoingType.ChatMessage: return 0x02;
case PacketOutgoingType.ClientStatus: return 0x03;
case PacketOutgoingType.ClientSettings: return 0x04;
case PacketOutgoingType.PluginMessage: return 0x0A;
case PacketOutgoingType.TabComplete: return 0x05;
case PacketOutgoingType.PlayerPosition: return 0x10;
case PacketOutgoingType.PlayerPositionAndLook: return 0x11;
case PacketOutgoingType.TeleportConfirm: return 0x00;
}
}
throw new System.ComponentModel.InvalidEnumArgumentException("Unknown PacketOutgoingType (protocol=" + protocol + ")", (int)packet, typeof(PacketOutgoingType));
}
@ -652,11 +817,31 @@ namespace MinecraftClient.Protocol.Handlers
}
break;
case PacketIncomingType.TabCompleteResult:
if (protocolversion >= MC17w46aVersion)
{
autocomplete_transaction_id = readNextVarInt(packetData);
}
if (protocolversion >= MC17w47aVersion)
{
// Start of the text to replace - currently unused
readNextVarInt(packetData);
}
if (protocolversion >= MC18w06aVersion)
{
// Length of the text to replace - currently unused
readNextVarInt(packetData);
}
int autocomplete_count = readNextVarInt(packetData);
autocomplete_result.Clear();
for (int i = 0; i < autocomplete_count; i++)
autocomplete_result.Add(readNextString(packetData));
autocomplete_received = true;
// In protocolversion >= MC18w06aVersion there is additional data if the match is a tooltip
// Don't worry about skipping remaining data since there is no useful for us (yet)
break;
case PacketIncomingType.PluginMessage:
String channel = readNextString(packetData);
@ -1313,7 +1498,7 @@ namespace MinecraftClient.Protocol.Handlers
/// <summary>
/// Get byte array representing a double
/// </summary>
/// <param name="array">Array to process</param>
/// <param name="number">Double to process</param>
/// <returns>Array ready to send</returns>
private byte[] getDouble(double number)
{
@ -1341,9 +1526,9 @@ namespace MinecraftClient.Protocol.Handlers
/// <summary>
/// Get a byte array from the given string for sending over the network, with length information prepended.
/// </summary>
/// <param name="array">String to process</param>
/// <param name="text">String to process</param>
/// <returns>Array ready to send</returns>
private byte[] getString(string text)
private static byte[] getString(string text)
{
byte[] bytes = Encoding.UTF8.GetBytes(text);
@ -1456,17 +1641,14 @@ namespace MinecraftClient.Protocol.Handlers
public bool Login()
{
byte[] protocol_version = getVarInt(protocolversion);
byte[] server_adress_val = Encoding.UTF8.GetBytes(handler.GetServerHost() + (forgeInfo != null ? "\0FML\0" : ""));
byte[] server_adress_len = getVarInt(server_adress_val.Length);
string server_address = handler.GetServerHost() + (forgeInfo != null ? "\0FML\0" : "");
byte[] server_port = BitConverter.GetBytes((ushort)handler.GetServerPort()); Array.Reverse(server_port);
byte[] next_state = getVarInt(2);
byte[] handshake_packet = concatBytes(protocol_version, server_adress_len, server_adress_val, server_port, next_state);
byte[] handshake_packet = concatBytes(protocol_version, getString(server_address), server_port, next_state);
SendPacket(0x00, handshake_packet);
byte[] username_val = Encoding.UTF8.GetBytes(handler.GetUsername());
byte[] username_len = getVarInt(username_val.Length);
byte[] login_packet = concatBytes(username_len, username_val);
byte[] login_packet = getString(handler.GetUsername());
SendPacket(0x00, login_packet);
@ -1621,9 +1803,7 @@ namespace MinecraftClient.Protocol.Handlers
return true;
try
{
byte[] message_val = Encoding.UTF8.GetBytes(message);
byte[] message_len = getVarInt(message_val.Length);
byte[] message_packet = concatBytes(message_len, message_val);
byte[] message_packet = getString(message);
SendPacket(PacketOutgoingType.ChatMessage, message_packet);
return true;
}
@ -1634,7 +1814,6 @@ namespace MinecraftClient.Protocol.Handlers
/// <summary>
/// Send a respawn packet to the server
/// </summary>
/// <param name="message">Message</param>
/// <returns>True if properly sent</returns>
public bool SendRespawnPacket()
{
@ -1655,9 +1834,17 @@ namespace MinecraftClient.Protocol.Handlers
{
if (String.IsNullOrEmpty(brandInfo))
return false;
// Plugin channels were significantly changed between Minecraft 1.12 and 1.13
// https://wiki.vg/index.php?title=Pre-release_protocol&oldid=14132#Plugin_Channels
if (protocolversion >= MC113Version)
{
return SendPluginChannelPacket("minecraft:brand", getString(brandInfo));
}
else
{
return SendPluginChannelPacket("MC|Brand", getString(brandInfo));
}
}
/// <summary>
/// Inform the server of the client's Minecraft settings
@ -1789,15 +1976,35 @@ namespace MinecraftClient.Protocol.Handlers
if (String.IsNullOrEmpty(BehindCursor))
return new string[] { };
byte[] tocomplete_val = Encoding.UTF8.GetBytes(BehindCursor);
byte[] tocomplete_len = getVarInt(tocomplete_val.Length);
byte[] transaction_id = getVarInt(autocomplete_transaction_id);
byte[] assume_command = new byte[] { 0x00 };
byte[] has_position = new byte[] { 0x00 };
byte[] tabcomplete_packet = protocolversion >= MC18Version
? protocolversion >= MC19Version
? concatBytes(tocomplete_len, tocomplete_val, assume_command, has_position)
: concatBytes(tocomplete_len, tocomplete_val, has_position)
: concatBytes(tocomplete_len, tocomplete_val);
byte[] tabcomplete_packet = new byte[] { };
if (protocolversion >= MC18Version)
{
if (protocolversion >= MC17w46aVersion)
{
tabcomplete_packet = concatBytes(tabcomplete_packet, transaction_id);
tabcomplete_packet = concatBytes(tabcomplete_packet, getString(BehindCursor));
}
else
{
tabcomplete_packet = concatBytes(tabcomplete_packet, getString(BehindCursor));
if (protocolversion >= MC19Version)
{
tabcomplete_packet = concatBytes(tabcomplete_packet, assume_command);
}
tabcomplete_packet = concatBytes(tabcomplete_packet, has_position);
}
}
else
{
tabcomplete_packet = concatBytes(getString(BehindCursor));
}
autocomplete_received = false;
autocomplete_result.Clear();
@ -1823,11 +2030,9 @@ namespace MinecraftClient.Protocol.Handlers
byte[] packet_id = getVarInt(0);
byte[] protocol_version = getVarInt(-1);
byte[] server_adress_val = Encoding.UTF8.GetBytes(host);
byte[] server_adress_len = getVarInt(server_adress_val.Length);
byte[] server_port = BitConverter.GetBytes((ushort)port); Array.Reverse(server_port);
byte[] next_state = getVarInt(1);
byte[] packet = concatBytes(packet_id, protocol_version, server_adress_len, server_adress_val, server_port, next_state);
byte[] packet = concatBytes(packet_id, protocol_version, getString(host), server_port, next_state);
byte[] tosend = concatBytes(getVarInt(packet.Length), packet);
tcp.Client.Send(tosend, SocketFlags.None);

View file

@ -106,7 +106,7 @@ namespace MinecraftClient.Protocol
int[] supportedVersions_Protocol16 = { 51, 60, 61, 72, 73, 74, 78 };
if (Array.IndexOf(supportedVersions_Protocol16, ProtocolVersion) > -1)
return new Protocol16Handler(Client, ProtocolVersion, Handler);
int[] supportedVersions_Protocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340 };
int[] supportedVersions_Protocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393 };
if (Array.IndexOf(supportedVersions_Protocol18, ProtocolVersion) > -1)
return new Protocol18Handler(Client, ProtocolVersion, Handler, forgeInfo);
throw new NotSupportedException("The protocol version no." + ProtocolVersion + " is not supported.");
@ -189,6 +189,8 @@ namespace MinecraftClient.Protocol
return 338;
case "1.12.2":
return 340;
case "1.13":
return 393;
default:
return 0;
}

View file

@ -73,7 +73,7 @@ namespace MinecraftClient
//Other Settings
public static string TranslationsFile_FromMCDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\.minecraft\assets\objects\ed\eda1518b15c711cf6e75d99003bd87753f67fac4"; //MC 1.10 en_GB.lang
public static string TranslationsFile_Website_Index = "https://s3.amazonaws.com/Minecraft.Download/indexes/1.10.json";
public static string TranslationsFile_Website_Index = "https://s3.amazonaws.com/Minecraft.Download/indexes/1.13.json";
public static string TranslationsFile_Website_Download = "http://resources.download.minecraft.net";
public static TimeSpan splitMessageDelay = TimeSpan.FromSeconds(2);
public static List<string> Bots_Owners = new List<string>();