mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Fix missing packet IDs for older MC versions
Fix packets not implemented for versions older than 1.14 Please implement all versions when adding a new packet!
This commit is contained in:
parent
86e5fe54ea
commit
b2e6953075
7 changed files with 265 additions and 192 deletions
|
|
@ -1490,7 +1490,7 @@ namespace MinecraftClient
|
|||
/// <returns>TRUE if animation successfully done</returns>
|
||||
public bool DoAnimation(int animation)
|
||||
{
|
||||
return handler.SendAnimation(animation);
|
||||
return handler.SendAnimation(animation, playerEntityID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
/// <summary>
|
||||
/// Abstract incoming packet numbering
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please add new entries at the bottom of the list (but above UnknownPakcket)
|
||||
/// You'll also need to add them to Protocol18PacketTypes for all MC versions since MC 1.7
|
||||
/// </remarks>
|
||||
enum PacketIncomingType
|
||||
{
|
||||
KeepAlive,
|
||||
|
|
@ -38,11 +42,14 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
EntityPosition,
|
||||
EntityPositionAndRotation,
|
||||
EntityProperties,
|
||||
TimeUpdate,
|
||||
EntityTeleport,
|
||||
EntityStatus,
|
||||
TimeUpdate,
|
||||
UpdateHealth,
|
||||
HeldItemChange,
|
||||
UnknownPacket
|
||||
|
||||
/// <summary>
|
||||
/// Represents a packet not implemented in MCC.
|
||||
/// </summary>
|
||||
UnknownPacket,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
/// <summary>
|
||||
/// Abstract outgoing packet numbering
|
||||
/// </summary>
|
||||
/// /// <remarks>
|
||||
/// Please add new entries at the bottom of the list
|
||||
/// You'll also need to add them to Protocol18PacketTypes for all MC versions since MC 1.7
|
||||
/// </remarks>
|
||||
enum PacketOutgoingType
|
||||
{
|
||||
KeepAlive,
|
||||
|
|
@ -28,6 +32,6 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
CloseWindow,
|
||||
PlayerBlockPlacement,
|
||||
CreativeInventoryAction,
|
||||
Animation
|
||||
Animation,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -693,7 +693,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return false; //Currently not implemented
|
||||
}
|
||||
|
||||
public bool SendAnimation(int animation)
|
||||
public bool SendAnimation(int animation, int playerid)
|
||||
{
|
||||
return false; //Currently not implemented
|
||||
}
|
||||
|
|
|
|||
|
|
@ -706,9 +706,12 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
break;
|
||||
case PacketIncomingType.UpdateHealth:
|
||||
float health = dataTypes.ReadNextFloat(packetData);
|
||||
int food = dataTypes.ReadNextVarInt(packetData);
|
||||
// Food Saturation, not useful
|
||||
dataTypes.ReadNextFloat(packetData);
|
||||
int food;
|
||||
if (protocolversion >= MC18Version)
|
||||
food = dataTypes.ReadNextVarInt(packetData);
|
||||
else
|
||||
food = dataTypes.ReadNextShort(packetData);
|
||||
dataTypes.ReadNextFloat(packetData); // Food Saturation
|
||||
handler.OnUpdateHealth(health, food);
|
||||
break;
|
||||
case PacketIncomingType.HeldItemChange:
|
||||
|
|
@ -911,6 +914,128 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnect from the server
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
{
|
||||
socketWrapper.Disconnect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Autocomplete text while typing username or command
|
||||
/// </summary>
|
||||
/// <param name="BehindCursor">Text behind cursor</param>
|
||||
/// <returns>Completed text</returns>
|
||||
IEnumerable<string> IAutoComplete.AutoComplete(string BehindCursor)
|
||||
{
|
||||
if (String.IsNullOrEmpty(BehindCursor))
|
||||
return new string[] { };
|
||||
|
||||
byte[] transaction_id = dataTypes.GetVarInt(autocomplete_transaction_id);
|
||||
byte[] assume_command = new byte[] { 0x00 };
|
||||
byte[] has_position = new byte[] { 0x00 };
|
||||
|
||||
byte[] tabcomplete_packet = new byte[] { };
|
||||
|
||||
if (protocolversion >= MC18Version)
|
||||
{
|
||||
if (protocolversion >= MC113Version)
|
||||
{
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, transaction_id);
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, dataTypes.GetString(BehindCursor));
|
||||
}
|
||||
else
|
||||
{
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, dataTypes.GetString(BehindCursor));
|
||||
|
||||
if (protocolversion >= MC19Version)
|
||||
{
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, assume_command);
|
||||
}
|
||||
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, has_position);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(dataTypes.GetString(BehindCursor));
|
||||
}
|
||||
|
||||
autocomplete_received = false;
|
||||
autocomplete_result.Clear();
|
||||
autocomplete_result.Add(BehindCursor);
|
||||
SendPacket(PacketOutgoingType.TabComplete, tabcomplete_packet);
|
||||
|
||||
int wait_left = 50; //do not wait more than 5 seconds (50 * 100 ms)
|
||||
while (wait_left > 0 && !autocomplete_received) { System.Threading.Thread.Sleep(100); wait_left--; }
|
||||
if (autocomplete_result.Count > 0)
|
||||
ConsoleIO.WriteLineFormatted("§8" + String.Join(" ", autocomplete_result), false);
|
||||
return autocomplete_result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ping a Minecraft server to get information about the server
|
||||
/// </summary>
|
||||
/// <returns>True if ping was successful</returns>
|
||||
public static bool doPing(string host, int port, ref int protocolversion, ref ForgeInfo forgeInfo)
|
||||
{
|
||||
string version = "";
|
||||
TcpClient tcp = ProxyHandler.newTcpClient(host, port);
|
||||
tcp.ReceiveBufferSize = 1024 * 1024;
|
||||
SocketWrapper socketWrapper = new SocketWrapper(tcp);
|
||||
DataTypes dataTypes = new DataTypes(MC18Version);
|
||||
|
||||
byte[] packet_id = dataTypes.GetVarInt(0);
|
||||
byte[] protocol_version = dataTypes.GetVarInt(-1);
|
||||
byte[] server_port = BitConverter.GetBytes((ushort)port); Array.Reverse(server_port);
|
||||
byte[] next_state = dataTypes.GetVarInt(1);
|
||||
byte[] packet = dataTypes.ConcatBytes(packet_id, protocol_version, dataTypes.GetString(host), server_port, next_state);
|
||||
byte[] tosend = dataTypes.ConcatBytes(dataTypes.GetVarInt(packet.Length), packet);
|
||||
|
||||
socketWrapper.SendDataRAW(tosend);
|
||||
|
||||
byte[] status_request = dataTypes.GetVarInt(0);
|
||||
byte[] request_packet = dataTypes.ConcatBytes(dataTypes.GetVarInt(status_request.Length), status_request);
|
||||
|
||||
socketWrapper.SendDataRAW(request_packet);
|
||||
|
||||
int packetLength = dataTypes.ReadNextVarIntRAW(socketWrapper);
|
||||
if (packetLength > 0) //Read Response length
|
||||
{
|
||||
Queue<byte> packetData = new Queue<byte>(socketWrapper.ReadDataRAW(packetLength));
|
||||
if (dataTypes.ReadNextVarInt(packetData) == 0x00) //Read Packet ID
|
||||
{
|
||||
string result = dataTypes.ReadNextString(packetData); //Get the Json data
|
||||
|
||||
if (!String.IsNullOrEmpty(result) && result.StartsWith("{") && result.EndsWith("}"))
|
||||
{
|
||||
Json.JSONData jsonData = Json.ParseJson(result);
|
||||
if (jsonData.Type == Json.JSONData.DataType.Object && jsonData.Properties.ContainsKey("version"))
|
||||
{
|
||||
Json.JSONData versionData = jsonData.Properties["version"];
|
||||
|
||||
//Retrieve display name of the Minecraft version
|
||||
if (versionData.Properties.ContainsKey("name"))
|
||||
version = versionData.Properties["name"].StringValue;
|
||||
|
||||
//Retrieve protocol version number for handling this server
|
||||
if (versionData.Properties.ContainsKey("protocol"))
|
||||
protocolversion = dataTypes.Atoi(versionData.Properties["protocol"].StringValue);
|
||||
|
||||
// Check for forge on the server.
|
||||
Protocol18Forge.ServerInfoCheckForge(jsonData, ref forgeInfo);
|
||||
|
||||
ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + (forgeInfo != null ? ", with Forge)." : ")."));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get max length for chat messages
|
||||
/// </summary>
|
||||
|
|
@ -1104,128 +1229,6 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
catch (ObjectDisposedException) { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnect from the server
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
{
|
||||
socketWrapper.Disconnect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Autocomplete text while typing username or command
|
||||
/// </summary>
|
||||
/// <param name="BehindCursor">Text behind cursor</param>
|
||||
/// <returns>Completed text</returns>
|
||||
IEnumerable<string> IAutoComplete.AutoComplete(string BehindCursor)
|
||||
{
|
||||
if (String.IsNullOrEmpty(BehindCursor))
|
||||
return new string[] { };
|
||||
|
||||
byte[] transaction_id = dataTypes.GetVarInt(autocomplete_transaction_id);
|
||||
byte[] assume_command = new byte[] { 0x00 };
|
||||
byte[] has_position = new byte[] { 0x00 };
|
||||
|
||||
byte[] tabcomplete_packet = new byte[] { };
|
||||
|
||||
if (protocolversion >= MC18Version)
|
||||
{
|
||||
if (protocolversion >= MC113Version)
|
||||
{
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, transaction_id);
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, dataTypes.GetString(BehindCursor));
|
||||
}
|
||||
else
|
||||
{
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, dataTypes.GetString(BehindCursor));
|
||||
|
||||
if (protocolversion >= MC19Version)
|
||||
{
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, assume_command);
|
||||
}
|
||||
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, has_position);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tabcomplete_packet = dataTypes.ConcatBytes(dataTypes.GetString(BehindCursor));
|
||||
}
|
||||
|
||||
autocomplete_received = false;
|
||||
autocomplete_result.Clear();
|
||||
autocomplete_result.Add(BehindCursor);
|
||||
SendPacket(PacketOutgoingType.TabComplete, tabcomplete_packet);
|
||||
|
||||
int wait_left = 50; //do not wait more than 5 seconds (50 * 100 ms)
|
||||
while (wait_left > 0 && !autocomplete_received) { System.Threading.Thread.Sleep(100); wait_left--; }
|
||||
if (autocomplete_result.Count > 0)
|
||||
ConsoleIO.WriteLineFormatted("§8" + String.Join(" ", autocomplete_result), false);
|
||||
return autocomplete_result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ping a Minecraft server to get information about the server
|
||||
/// </summary>
|
||||
/// <returns>True if ping was successful</returns>
|
||||
public static bool doPing(string host, int port, ref int protocolversion, ref ForgeInfo forgeInfo)
|
||||
{
|
||||
string version = "";
|
||||
TcpClient tcp = ProxyHandler.newTcpClient(host, port);
|
||||
tcp.ReceiveBufferSize = 1024 * 1024;
|
||||
SocketWrapper socketWrapper = new SocketWrapper(tcp);
|
||||
DataTypes dataTypes = new DataTypes(MC18Version);
|
||||
|
||||
byte[] packet_id = dataTypes.GetVarInt(0);
|
||||
byte[] protocol_version = dataTypes.GetVarInt(-1);
|
||||
byte[] server_port = BitConverter.GetBytes((ushort)port); Array.Reverse(server_port);
|
||||
byte[] next_state = dataTypes.GetVarInt(1);
|
||||
byte[] packet = dataTypes.ConcatBytes(packet_id, protocol_version, dataTypes.GetString(host), server_port, next_state);
|
||||
byte[] tosend = dataTypes.ConcatBytes(dataTypes.GetVarInt(packet.Length), packet);
|
||||
|
||||
socketWrapper.SendDataRAW(tosend);
|
||||
|
||||
byte[] status_request = dataTypes.GetVarInt(0);
|
||||
byte[] request_packet = dataTypes.ConcatBytes(dataTypes.GetVarInt(status_request.Length), status_request);
|
||||
|
||||
socketWrapper.SendDataRAW(request_packet);
|
||||
|
||||
int packetLength = dataTypes.ReadNextVarIntRAW(socketWrapper);
|
||||
if (packetLength > 0) //Read Response length
|
||||
{
|
||||
Queue<byte> packetData = new Queue<byte>(socketWrapper.ReadDataRAW(packetLength));
|
||||
if (dataTypes.ReadNextVarInt(packetData) == 0x00) //Read Packet ID
|
||||
{
|
||||
string result = dataTypes.ReadNextString(packetData); //Get the Json data
|
||||
|
||||
if (!String.IsNullOrEmpty(result) && result.StartsWith("{") && result.EndsWith("}"))
|
||||
{
|
||||
Json.JSONData jsonData = Json.ParseJson(result);
|
||||
if (jsonData.Type == Json.JSONData.DataType.Object && jsonData.Properties.ContainsKey("version"))
|
||||
{
|
||||
Json.JSONData versionData = jsonData.Properties["version"];
|
||||
|
||||
//Retrieve display name of the Minecraft version
|
||||
if (versionData.Properties.ContainsKey("name"))
|
||||
version = versionData.Properties["name"].StringValue;
|
||||
|
||||
//Retrieve protocol version number for handling this server
|
||||
if (versionData.Properties.ContainsKey("protocol"))
|
||||
protocolversion = dataTypes.Atoi(versionData.Properties["protocol"].StringValue);
|
||||
|
||||
// Check for forge on the server.
|
||||
Protocol18Forge.ServerInfoCheckForge(jsonData, ref forgeInfo);
|
||||
|
||||
ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + (forgeInfo != null ? ", with Forge)." : ")."));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send an Interact Entity Packet to server
|
||||
/// </summary>
|
||||
|
|
@ -1246,6 +1249,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
catch (System.IO.IOException) { return false; }
|
||||
catch (ObjectDisposedException) { return false; }
|
||||
}
|
||||
|
||||
// TODO: Interact at block location (e.g. chest minecart)
|
||||
public bool SendInteractEntity(int EntityID, int type, float X, float Y, float Z, int hand)
|
||||
{
|
||||
|
|
@ -1272,6 +1276,11 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
|
||||
public bool SendUseItem(int hand)
|
||||
{
|
||||
if (protocolversion < MC19Version)
|
||||
return false; // Packet does not exist prior to MC 1.9
|
||||
// According to https://wiki.vg/index.php?title=Protocol&oldid=5486#Player_Block_Placement
|
||||
// MC 1.7 does this using Player Block Placement with special values
|
||||
// TODO once Player Block Placement is implemented for older versions
|
||||
try
|
||||
{
|
||||
List<byte> packet = new List<byte>();
|
||||
|
|
@ -1286,6 +1295,8 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
|
||||
public bool SendPlayerBlockPlacement(int hand, Location location, int face, float CursorX, float CursorY, float CursorZ, bool insideBlock)
|
||||
{
|
||||
if (protocolversion < MC114Version)
|
||||
return false; // NOT IMPLEMENTED for older MC versions
|
||||
try
|
||||
{
|
||||
List<byte> packet = new List<byte>();
|
||||
|
|
@ -1296,6 +1307,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
packet.AddRange(dataTypes.GetFloat(CursorY));
|
||||
packet.AddRange(dataTypes.GetFloat(CursorZ));
|
||||
packet.Add(Convert.ToByte(insideBlock ? 1 : 0));
|
||||
|
||||
SendPacket(PacketOutgoingType.PlayerBlockPlacement, packet);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1382,7 +1394,6 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
List<byte> packet = new List<byte>();
|
||||
packet.AddRange(dataTypes.GetShort((short)slot));
|
||||
packet.AddRange(dataTypes.GetItemSlot(new Item((int)itemType, count, null)));
|
||||
|
||||
SendPacket(PacketOutgoingType.CreativeInventoryAction, packet);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1391,14 +1402,27 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
catch (ObjectDisposedException) { return false; }
|
||||
}
|
||||
|
||||
public bool SendAnimation(int animation)
|
||||
public bool SendAnimation(int animation, int playerid)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (animation == 0 || animation == 1)
|
||||
{
|
||||
List<byte> packet = new List<byte>();
|
||||
|
||||
if (protocolversion < MC18Version)
|
||||
{
|
||||
packet.AddRange(dataTypes.GetInt(playerid));
|
||||
packet.Add((byte)1); // Swing arm
|
||||
}
|
||||
else if (protocolversion < MC19Version)
|
||||
{
|
||||
// No fields in 1.8.X
|
||||
}
|
||||
else // MC 1.9+
|
||||
{
|
||||
packet.AddRange(dataTypes.GetVarInt(animation));
|
||||
}
|
||||
|
||||
SendPacket(PacketOutgoingType.Animation, packet);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,12 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
/// <summary>
|
||||
/// Get abstract numbering of the specified packet ID
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When adding a new packet, see https://wiki.vg/Protocol_version_numbers
|
||||
/// For each switch below, see the corresponding page (e.g. MC 1.7, then 1.9) and add the ID
|
||||
/// By the way, also look for packet layout changes across versions and handle them in Protocol18.cs
|
||||
/// Please add entries in the same order as they are displayed in PacketIncomingType.cs
|
||||
/// </remarks>
|
||||
/// <param name="packetID">Packet ID</param>
|
||||
/// <param name="protocol">Protocol version</param>
|
||||
/// <returns>Abstract numbering</returns>
|
||||
|
|
@ -31,30 +37,29 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 0x22: return PacketIncomingType.MultiBlockChange;
|
||||
case 0x23: return PacketIncomingType.BlockChange;
|
||||
case 0x26: return PacketIncomingType.MapChunkBulk;
|
||||
case 0x30: return PacketIncomingType.WindowItems;
|
||||
//UnloadChunk does not exists prior to 1.9
|
||||
// UnloadChunk does not exist prior to 1.9
|
||||
case 0x38: return PacketIncomingType.PlayerListUpdate;
|
||||
case 0x3A: return PacketIncomingType.TabCompleteResult;
|
||||
case 0x3F: return PacketIncomingType.PluginMessage;
|
||||
case 0x40: return PacketIncomingType.KickPacket;
|
||||
case 0x46: return PacketIncomingType.NetworkCompressionTreshold;
|
||||
case 0x48: return PacketIncomingType.ResourcePackSend;
|
||||
case 0x2D: return PacketIncomingType.OpenWindow;
|
||||
case 0x2E: return PacketIncomingType.CloseWindow;
|
||||
case 0x2D: return PacketIncomingType.OpenWindow;
|
||||
case 0x30: return PacketIncomingType.WindowItems;
|
||||
case 0x2F: return PacketIncomingType.SetSlot;
|
||||
|
||||
// Set Cooldown does not exists
|
||||
case 0x03: return PacketIncomingType.TimeUpdate;
|
||||
// Entity handling
|
||||
case 0x0E: return PacketIncomingType.SpawnEntity;
|
||||
case 0x0F: return PacketIncomingType.SpawnLivingEntity;
|
||||
case 0x05: return PacketIncomingType.SpawnPlayer;
|
||||
case 0x13: return PacketIncomingType.DestroyEntities;
|
||||
// SetCooldown does not exist prior to 1.9
|
||||
case 0x15: return PacketIncomingType.EntityPosition;
|
||||
case 0x17: return PacketIncomingType.EntityPositionAndRotation;
|
||||
case 0x20: return PacketIncomingType.EntityProperties;
|
||||
case 0x18: return PacketIncomingType.EntityTeleport;
|
||||
default: return PacketIncomingType.UnknownPacket;
|
||||
case 0x03: return PacketIncomingType.TimeUpdate;
|
||||
case 0x06: return PacketIncomingType.UpdateHealth;
|
||||
case 0x09: return PacketIncomingType.HeldItemChange;
|
||||
}
|
||||
}
|
||||
else if (protocol <= Protocol18Handler.MC1112Version) // MC 1.9, 1.10 and 1.11
|
||||
|
|
@ -69,31 +74,30 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 0x20: return PacketIncomingType.ChunkData;
|
||||
case 0x10: return PacketIncomingType.MultiBlockChange;
|
||||
case 0x0B: return PacketIncomingType.BlockChange;
|
||||
//MapChunkBulk removed in 1.9
|
||||
// MapChunkBulk has been removed in 1.9
|
||||
case 0x1D: return PacketIncomingType.UnloadChunk;
|
||||
case 0x2D: return PacketIncomingType.PlayerListUpdate;
|
||||
case 0x0E: return PacketIncomingType.TabCompleteResult;
|
||||
case 0x18: return PacketIncomingType.PluginMessage;
|
||||
case 0x1A: return PacketIncomingType.KickPacket;
|
||||
// NetworkCompressionTreshold has been removed in 1.9
|
||||
case 0x32: return PacketIncomingType.ResourcePackSend;
|
||||
case 0x12: return PacketIncomingType.CloseWindow;
|
||||
case 0x13: return PacketIncomingType.OpenWindow;
|
||||
case 0x14: return PacketIncomingType.WindowItems;
|
||||
case 0x16: return PacketIncomingType.SetSlot;
|
||||
//NetworkCompressionTreshold removed in 1.9
|
||||
case 0x32: return PacketIncomingType.ResourcePackSend;
|
||||
|
||||
case 0x17: return PacketIncomingType.SetCooldown;
|
||||
case 0x44: return PacketIncomingType.TimeUpdate;
|
||||
// Entity handling
|
||||
case 0x00: return PacketIncomingType.SpawnEntity;
|
||||
case 0x03: return PacketIncomingType.SpawnLivingEntity;
|
||||
case 0x05: return PacketIncomingType.SpawnPlayer;
|
||||
case 0x30: return PacketIncomingType.DestroyEntities;
|
||||
case 0x17: return PacketIncomingType.SetCooldown;
|
||||
case 0x25: return PacketIncomingType.EntityPosition;
|
||||
case 0x26: return PacketIncomingType.EntityPositionAndRotation;
|
||||
case 0x4A: return PacketIncomingType.EntityProperties;
|
||||
case 0x49: return PacketIncomingType.EntityTeleport;
|
||||
default: return PacketIncomingType.UnknownPacket;
|
||||
case 0x44: return PacketIncomingType.TimeUpdate;
|
||||
case 0x3E: return PacketIncomingType.UpdateHealth;
|
||||
case 0x37: return PacketIncomingType.HeldItemChange;
|
||||
}
|
||||
}
|
||||
else if (protocol <= Protocol18Handler.MC112Version) // MC 1.12.0
|
||||
|
|
@ -107,30 +111,31 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 0x2E: return PacketIncomingType.PlayerPositionAndLook;
|
||||
case 0x20: return PacketIncomingType.ChunkData;
|
||||
case 0x10: return PacketIncomingType.MultiBlockChange;
|
||||
case 0x14: return PacketIncomingType.WindowItems;
|
||||
case 0x16: return PacketIncomingType.SetSlot;
|
||||
case 0x0B: return PacketIncomingType.BlockChange;
|
||||
// MapChunkBulk does not exist since 1.9
|
||||
case 0x1D: return PacketIncomingType.UnloadChunk;
|
||||
case 0x2D: return PacketIncomingType.PlayerListUpdate;
|
||||
case 0x0E: return PacketIncomingType.TabCompleteResult;
|
||||
case 0x18: return PacketIncomingType.PluginMessage;
|
||||
case 0x1A: return PacketIncomingType.KickPacket;
|
||||
// NetworkCompressionTreshold does not exist since 1.9
|
||||
case 0x33: return PacketIncomingType.ResourcePackSend;
|
||||
case 0x12: return PacketIncomingType.CloseWindow;
|
||||
case 0x13: return PacketIncomingType.OpenWindow;
|
||||
case 0x33: return PacketIncomingType.ResourcePackSend;
|
||||
|
||||
case 0x17: return PacketIncomingType.SetCooldown;
|
||||
case 0x46: return PacketIncomingType.TimeUpdate;
|
||||
// Entity handling
|
||||
case 0x14: return PacketIncomingType.WindowItems;
|
||||
case 0x16: return PacketIncomingType.SetSlot;
|
||||
case 0x00: return PacketIncomingType.SpawnEntity;
|
||||
case 0x03: return PacketIncomingType.SpawnLivingEntity;
|
||||
case 0x05: return PacketIncomingType.SpawnPlayer;
|
||||
case 0x31: return PacketIncomingType.DestroyEntities;
|
||||
case 0x17: return PacketIncomingType.SetCooldown;
|
||||
case 0x26: return PacketIncomingType.EntityPosition;
|
||||
case 0x27: return PacketIncomingType.EntityPositionAndRotation;
|
||||
case 0x4D: return PacketIncomingType.EntityProperties;
|
||||
case 0x4B: return PacketIncomingType.EntityTeleport;
|
||||
default: return PacketIncomingType.UnknownPacket;
|
||||
case 0x46: return PacketIncomingType.TimeUpdate;
|
||||
case 0x40: return PacketIncomingType.UpdateHealth;
|
||||
case 0x39: return PacketIncomingType.HeldItemChange;
|
||||
}
|
||||
}
|
||||
else if (protocol <= Protocol18Handler.MC1122Version) // MC 1.12.2
|
||||
|
|
@ -145,29 +150,30 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 0x20: return PacketIncomingType.ChunkData;
|
||||
case 0x10: return PacketIncomingType.MultiBlockChange;
|
||||
case 0x0B: return PacketIncomingType.BlockChange;
|
||||
// MapChunkBulk does not exist since 1.9
|
||||
case 0x1D: return PacketIncomingType.UnloadChunk;
|
||||
case 0x2E: return PacketIncomingType.PlayerListUpdate;
|
||||
case 0x0E: return PacketIncomingType.TabCompleteResult;
|
||||
case 0x18: return PacketIncomingType.PluginMessage;
|
||||
case 0x1A: return PacketIncomingType.KickPacket;
|
||||
// NetworkCompressionTreshold does not exist since 1.9
|
||||
case 0x34: return PacketIncomingType.ResourcePackSend;
|
||||
case 0x12: return PacketIncomingType.CloseWindow;
|
||||
case 0x13: return PacketIncomingType.OpenWindow;
|
||||
case 0x14: return PacketIncomingType.WindowItems;
|
||||
case 0x16: return PacketIncomingType.SetSlot;
|
||||
case 0x34: return PacketIncomingType.ResourcePackSend;
|
||||
|
||||
case 0x17: return PacketIncomingType.SetCooldown;
|
||||
case 0x47: return PacketIncomingType.TimeUpdate;
|
||||
// Entity handling
|
||||
case 0x00: return PacketIncomingType.SpawnEntity;
|
||||
case 0x03: return PacketIncomingType.SpawnLivingEntity;
|
||||
case 0x05: return PacketIncomingType.SpawnPlayer;
|
||||
case 0x32: return PacketIncomingType.DestroyEntities;
|
||||
case 0x17: return PacketIncomingType.SetCooldown;
|
||||
case 0x26: return PacketIncomingType.EntityPosition;
|
||||
case 0x27: return PacketIncomingType.EntityPositionAndRotation;
|
||||
case 0x4E: return PacketIncomingType.EntityProperties;
|
||||
case 0x4C: return PacketIncomingType.EntityTeleport;
|
||||
default: return PacketIncomingType.UnknownPacket;
|
||||
case 0x47: return PacketIncomingType.TimeUpdate;
|
||||
case 0x41: return PacketIncomingType.UpdateHealth;
|
||||
case 0x3A: return PacketIncomingType.HeldItemChange;
|
||||
}
|
||||
}
|
||||
else if (protocol < Protocol18Handler.MC114Version) // MC 1.13 to 1.13.2
|
||||
|
|
@ -182,29 +188,30 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 0x22: return PacketIncomingType.ChunkData;
|
||||
case 0x0F: return PacketIncomingType.MultiBlockChange;
|
||||
case 0x0B: return PacketIncomingType.BlockChange;
|
||||
// MapChunkBulk does not exist since 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 does not exist since 1.9
|
||||
case 0x37: return PacketIncomingType.ResourcePackSend;
|
||||
case 0x13: return PacketIncomingType.CloseWindow;
|
||||
case 0x14: return PacketIncomingType.OpenWindow;
|
||||
case 0x15: return PacketIncomingType.WindowItems;
|
||||
case 0x17: return PacketIncomingType.SetSlot;
|
||||
|
||||
case 0x18: return PacketIncomingType.SetCooldown;
|
||||
case 0x4A: return PacketIncomingType.TimeUpdate;
|
||||
// Entity handling
|
||||
case 0x00: return PacketIncomingType.SpawnEntity;
|
||||
case 0x03: return PacketIncomingType.SpawnLivingEntity;
|
||||
case 0x05: return PacketIncomingType.SpawnPlayer;
|
||||
case 0x35: return PacketIncomingType.DestroyEntities;
|
||||
case 0x18: return PacketIncomingType.SetCooldown;
|
||||
case 0x28: return PacketIncomingType.EntityPosition;
|
||||
case 0x29: return PacketIncomingType.EntityPositionAndRotation;
|
||||
case 0x52: return PacketIncomingType.EntityProperties;
|
||||
case 0x50: return PacketIncomingType.EntityTeleport;
|
||||
default: return PacketIncomingType.UnknownPacket;
|
||||
case 0x4A: return PacketIncomingType.TimeUpdate;
|
||||
case 0x44: return PacketIncomingType.UpdateHealth;
|
||||
case 0x3D: return PacketIncomingType.HeldItemChange;
|
||||
}
|
||||
}
|
||||
else if (protocol < Protocol18Handler.MC115Version) // MC 1.14 to 1.14.4
|
||||
|
|
@ -219,28 +226,30 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 0x21: return PacketIncomingType.ChunkData;
|
||||
case 0x0F: return PacketIncomingType.MultiBlockChange;
|
||||
case 0x0B: return PacketIncomingType.BlockChange;
|
||||
// MapChunkBulk does not exist since 1.9
|
||||
case 0x1D: return PacketIncomingType.UnloadChunk;
|
||||
case 0x33: return PacketIncomingType.PlayerListUpdate;
|
||||
case 0x10: return PacketIncomingType.TabCompleteResult;
|
||||
case 0x18: return PacketIncomingType.PluginMessage;
|
||||
case 0x1A: return PacketIncomingType.KickPacket;
|
||||
// NetworkCompressionTreshold does not exist since 1.9
|
||||
case 0x39: return PacketIncomingType.ResourcePackSend;
|
||||
case 0x2E: return PacketIncomingType.OpenWindow;
|
||||
case 0x13: return PacketIncomingType.CloseWindow;
|
||||
case 0x2E: return PacketIncomingType.OpenWindow;
|
||||
case 0x14: return PacketIncomingType.WindowItems;
|
||||
case 0x16: return PacketIncomingType.SetSlot;
|
||||
case 0x17: return PacketIncomingType.SetCooldown;
|
||||
case 0x4E: return PacketIncomingType.TimeUpdate;
|
||||
// Entity handling
|
||||
case 0x00: return PacketIncomingType.SpawnEntity;
|
||||
case 0x03: return PacketIncomingType.SpawnLivingEntity;
|
||||
case 0x05: return PacketIncomingType.SpawnPlayer;
|
||||
case 0x37: return PacketIncomingType.DestroyEntities;
|
||||
case 0x17: return PacketIncomingType.SetCooldown;
|
||||
case 0x28: return PacketIncomingType.EntityPosition;
|
||||
case 0x29: return PacketIncomingType.EntityPositionAndRotation;
|
||||
case 0x58: return PacketIncomingType.EntityProperties;
|
||||
case 0x56: return PacketIncomingType.EntityTeleport;
|
||||
default: return PacketIncomingType.UnknownPacket;
|
||||
case 0x4E: return PacketIncomingType.TimeUpdate;
|
||||
case 0x48: return PacketIncomingType.UpdateHealth;
|
||||
case 0x3F: return PacketIncomingType.HeldItemChange;
|
||||
}
|
||||
}
|
||||
else // MC 1.15
|
||||
|
|
@ -255,38 +264,45 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 0x22: return PacketIncomingType.ChunkData;
|
||||
case 0x10: return PacketIncomingType.MultiBlockChange;
|
||||
case 0x0C: return PacketIncomingType.BlockChange;
|
||||
// MapChunkBulk does not exist since 1.9
|
||||
case 0x1E: return PacketIncomingType.UnloadChunk;
|
||||
case 0x34: return PacketIncomingType.PlayerListUpdate;
|
||||
case 0x11: return PacketIncomingType.TabCompleteResult;
|
||||
case 0x19: return PacketIncomingType.PluginMessage;
|
||||
case 0x1B: return PacketIncomingType.KickPacket;
|
||||
// NetworkCompressionTreshold does not exist since 1.9
|
||||
case 0x3A: return PacketIncomingType.ResourcePackSend;
|
||||
case 0x2F: return PacketIncomingType.OpenWindow;
|
||||
case 0x14: return PacketIncomingType.CloseWindow;
|
||||
case 0x2F: return PacketIncomingType.OpenWindow;
|
||||
case 0x15: return PacketIncomingType.WindowItems;
|
||||
case 0x17: return PacketIncomingType.SetSlot;
|
||||
case 0x18: return PacketIncomingType.SetCooldown;
|
||||
case 0x4F: return PacketIncomingType.TimeUpdate;
|
||||
// Entity handling
|
||||
case 0x00: return PacketIncomingType.SpawnEntity;
|
||||
case 0x03: return PacketIncomingType.SpawnLivingEntity;
|
||||
case 0x05: return PacketIncomingType.SpawnPlayer;
|
||||
case 0x38: return PacketIncomingType.DestroyEntities;
|
||||
case 0x18: return PacketIncomingType.SetCooldown;
|
||||
case 0x29: return PacketIncomingType.EntityPosition;
|
||||
case 0x2A: return PacketIncomingType.EntityPositionAndRotation;
|
||||
case 0x59: return PacketIncomingType.EntityProperties;
|
||||
case 0x57: return PacketIncomingType.EntityTeleport;
|
||||
case 0x1C: return PacketIncomingType.EntityStatus;
|
||||
case 0x49: return PacketIncomingType.UpdateHealth; // TODO: Add backwards support
|
||||
case 0x40: return PacketIncomingType.HeldItemChange; // TODO: Add backwards support
|
||||
default: return PacketIncomingType.UnknownPacket;
|
||||
case 0x4F: return PacketIncomingType.TimeUpdate;
|
||||
case 0x49: return PacketIncomingType.UpdateHealth;
|
||||
case 0x40: return PacketIncomingType.HeldItemChange;
|
||||
}
|
||||
}
|
||||
|
||||
return PacketIncomingType.UnknownPacket;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get packet ID of the specified outgoing packet
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When adding a new packet, see https://wiki.vg/Protocol_version_numbers
|
||||
/// For each switch below, see the corresponding page (e.g. MC 1.7, then 1.9) and add the ID
|
||||
/// By the way, also look for packet layout changes across versions and handle them in Protocol18.cs
|
||||
/// Please add entries in the same order as they are displayed in PacketOutgoingType.cs
|
||||
/// </remarks>
|
||||
/// <param name="packet">Abstract packet numbering</param>
|
||||
/// <param name="protocol">Protocol version</param>
|
||||
/// <returns>Packet ID</returns>
|
||||
|
|
@ -303,14 +319,18 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.ClientSettings: return 0x15;
|
||||
case PacketOutgoingType.PluginMessage: return 0x17;
|
||||
case PacketOutgoingType.TabComplete: return 0x14;
|
||||
case PacketOutgoingType.EntityAction: return 0x0B;
|
||||
case PacketOutgoingType.PlayerPosition: return 0x04;
|
||||
case PacketOutgoingType.PlayerPositionAndLook: return 0x06;
|
||||
case PacketOutgoingType.TeleportConfirm: throw new InvalidOperationException("Teleport confirm is not supported in protocol " + protocol);
|
||||
case PacketOutgoingType.HeldItemChange: return 0x17;
|
||||
case PacketOutgoingType.InteractEntity: return 0x02;
|
||||
case PacketOutgoingType.TeleportConfirm: throw new InvalidOperationException("Teleport confirm is not supported in protocol " + protocol);
|
||||
case PacketOutgoingType.UseItem: throw new InvalidOperationException("Use item is not supported in protocol " + protocol);
|
||||
case PacketOutgoingType.ClickWindow: return 0x0E;
|
||||
case PacketOutgoingType.CloseWindow: return 0x0D;
|
||||
case PacketOutgoingType.EntityAction: return 0x0B;
|
||||
case PacketOutgoingType.PlayerBlockPlacement: return 0x08;
|
||||
case PacketOutgoingType.CreativeInventoryAction: return 0x10;
|
||||
case PacketOutgoingType.Animation: return 0x0A;
|
||||
}
|
||||
}
|
||||
else if (protocol <= Protocol18Handler.MC1112Version) // MC 1.9, 1,10 and 1.11
|
||||
|
|
@ -324,14 +344,18 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.ClientSettings: return 0x04;
|
||||
case PacketOutgoingType.PluginMessage: return 0x09;
|
||||
case PacketOutgoingType.TabComplete: return 0x01;
|
||||
case PacketOutgoingType.EntityAction: return 0x14;
|
||||
case PacketOutgoingType.PlayerPosition: return 0x0C;
|
||||
case PacketOutgoingType.PlayerPositionAndLook: return 0x0D;
|
||||
case PacketOutgoingType.TeleportConfirm: return 0x00;
|
||||
case PacketOutgoingType.HeldItemChange: return 0x17;
|
||||
case PacketOutgoingType.InteractEntity: return 0x0A;
|
||||
case PacketOutgoingType.UseItem: return 0x1D;
|
||||
case PacketOutgoingType.ClickWindow: return 0x07;
|
||||
case PacketOutgoingType.CloseWindow: return 0x08;
|
||||
case PacketOutgoingType.EntityAction: return 0x14;
|
||||
case PacketOutgoingType.PlayerBlockPlacement: return 0x1C;
|
||||
case PacketOutgoingType.CreativeInventoryAction: return 0x18;
|
||||
case PacketOutgoingType.Animation: return 0x1A;
|
||||
}
|
||||
}
|
||||
else if (protocol <= Protocol18Handler.MC112Version) // MC 1.12
|
||||
|
|
@ -345,14 +369,18 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.ClientSettings: return 0x05;
|
||||
case PacketOutgoingType.PluginMessage: return 0x0A;
|
||||
case PacketOutgoingType.TabComplete: return 0x02;
|
||||
case PacketOutgoingType.EntityAction: return 0x15;
|
||||
case PacketOutgoingType.PlayerPosition: return 0x0E;
|
||||
case PacketOutgoingType.PlayerPositionAndLook: return 0x0F;
|
||||
case PacketOutgoingType.TeleportConfirm: return 0x00;
|
||||
case PacketOutgoingType.HeldItemChange: return 0x1A;
|
||||
case PacketOutgoingType.InteractEntity: return 0x0B;
|
||||
case PacketOutgoingType.UseItem: return 0x20;
|
||||
case PacketOutgoingType.ClickWindow: return 0x07;
|
||||
case PacketOutgoingType.CloseWindow: return 0x08;
|
||||
case PacketOutgoingType.EntityAction: return 0x15;
|
||||
case PacketOutgoingType.PlayerBlockPlacement: return 0x1F;
|
||||
case PacketOutgoingType.CreativeInventoryAction: return 0x1B;
|
||||
case PacketOutgoingType.Animation: return 0x1D;
|
||||
}
|
||||
}
|
||||
else if (protocol <= Protocol18Handler.MC1122Version) // 1.12.2
|
||||
|
|
@ -366,14 +394,18 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.ClientSettings: return 0x04;
|
||||
case PacketOutgoingType.PluginMessage: return 0x09;
|
||||
case PacketOutgoingType.TabComplete: return 0x01;
|
||||
case PacketOutgoingType.EntityAction: return 0x15;
|
||||
case PacketOutgoingType.PlayerPosition: return 0x0D;
|
||||
case PacketOutgoingType.PlayerPositionAndLook: return 0x0E;
|
||||
case PacketOutgoingType.TeleportConfirm: return 0x00;
|
||||
case PacketOutgoingType.HeldItemChange: return 0x1F;
|
||||
case PacketOutgoingType.InteractEntity: return 0x0A;
|
||||
case PacketOutgoingType.UseItem: return 0x20;
|
||||
case PacketOutgoingType.ClickWindow: return 0x07;
|
||||
case PacketOutgoingType.CloseWindow: return 0x08;
|
||||
case PacketOutgoingType.EntityAction: return 0x15;
|
||||
case PacketOutgoingType.PlayerBlockPlacement: return 0x1F;
|
||||
case PacketOutgoingType.CreativeInventoryAction: return 0x1B;
|
||||
case PacketOutgoingType.Animation: return 0x1D;
|
||||
}
|
||||
}
|
||||
else if (protocol < Protocol18Handler.MC114Version) // MC 1.13 to 1.13.2
|
||||
|
|
@ -387,14 +419,18 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.ClientSettings: return 0x04;
|
||||
case PacketOutgoingType.PluginMessage: return 0x0A;
|
||||
case PacketOutgoingType.TabComplete: return 0x05;
|
||||
case PacketOutgoingType.EntityAction: return 0x19;
|
||||
case PacketOutgoingType.PlayerPosition: return 0x10;
|
||||
case PacketOutgoingType.PlayerPositionAndLook: return 0x11;
|
||||
case PacketOutgoingType.TeleportConfirm: return 0x00;
|
||||
case PacketOutgoingType.HeldItemChange: return 0x21;
|
||||
case PacketOutgoingType.InteractEntity: return 0x0D;
|
||||
case PacketOutgoingType.UseItem: return 0x2A;
|
||||
case PacketOutgoingType.ClickWindow: return 0x08;
|
||||
case PacketOutgoingType.CloseWindow: return 0x09;
|
||||
case PacketOutgoingType.EntityAction: return 0x19;
|
||||
case PacketOutgoingType.PlayerBlockPlacement: return 0x29;
|
||||
case PacketOutgoingType.CreativeInventoryAction: return 0x24;
|
||||
case PacketOutgoingType.Animation: return 0x27;
|
||||
}
|
||||
}
|
||||
else // MC 1.14 to 1.15
|
||||
|
|
@ -408,16 +444,17 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.ClientSettings: return 0x05;
|
||||
case PacketOutgoingType.PluginMessage: return 0x0B;
|
||||
case PacketOutgoingType.TabComplete: return 0x06;
|
||||
case PacketOutgoingType.EntityAction: return 0x1B;
|
||||
case PacketOutgoingType.PlayerPosition: return 0x11;
|
||||
case PacketOutgoingType.PlayerPositionAndLook: return 0x12;
|
||||
case PacketOutgoingType.TeleportConfirm: return 0x00;
|
||||
case PacketOutgoingType.HeldItemChange: return 0x23;
|
||||
case PacketOutgoingType.InteractEntity: return 0x0E;
|
||||
case PacketOutgoingType.UseItem: return 0x2D;
|
||||
case PacketOutgoingType.PlayerBlockPlacement: return 0x2C;
|
||||
case PacketOutgoingType.ClickWindow: return 0x09;
|
||||
case PacketOutgoingType.CloseWindow: return 0x0A;
|
||||
case PacketOutgoingType.EntityAction: return 0x1B;
|
||||
case PacketOutgoingType.PlayerBlockPlacement: return 0x2C;
|
||||
case PacketOutgoingType.CreativeInventoryAction: return 0x26;
|
||||
case PacketOutgoingType.Animation: return 0x2A;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,9 +162,10 @@ namespace MinecraftClient.Protocol
|
|||
/// <summary>
|
||||
/// Plays animation
|
||||
/// </summary>
|
||||
/// <param name="animation"> <0|1></param>
|
||||
/// <param name="animation">0 for left arm, 1 for right arm</param>
|
||||
/// <param name="playerid">Player Entity ID</param>
|
||||
/// <returns>TRUE if item given successfully</returns>
|
||||
bool SendAnimation(int animation);
|
||||
bool SendAnimation(int animation, int playerid);
|
||||
|
||||
/// <summary>
|
||||
/// Send a close window packet to the server
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue