Fully implemented Map Data packet.

This commit is contained in:
Milutinke 2022-09-18 00:18:27 +02:00
parent 59e02c2da9
commit f47c240920
6 changed files with 175 additions and 61 deletions

View file

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MinecraftClient.Protocol.Handlers;
namespace MinecraftClient.Mapping
{
public class MapIcon
{
public MapIconType Type { set; get; }
public byte X { set; get; }
public byte Z { set; get; }
public byte Direction { set; get; }
public string? DisplayName { set; get; } = null;
}
}

View file

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MinecraftClient.Mapping
{
public enum MapIconType
{
White_Arrow = 0,
Green_Arrow,
Red_Arrow,
Blue_Arrow,
White_Cross,
Red_Pointer,
White_Circle,
Small_White_Circle,
Mansion,
Temple,
White_Banner,
Orange_Banner,
Magenta_Banner,
Light_Blue_Banner,
Yellow_Banner,
Lime_Banner,
Pink_Banner,
Gray_Banner,
Light_Gray_Banner,
Cyan_Banner,
Purple_Banner,
Blue_Banner,
Brown_Banner,
Green_Banner,
Red_Banner,
Black_Banner,
Treasure_Marker
}
}

View file

@ -3063,16 +3063,22 @@ namespace MinecraftClient
} }
/// <summary> /// <summary>
/// Called map data /// Called when an update of the map is sent by the server, take a look at https://wiki.vg/Protocol#Map_Data for more info on the fields
/// Map format and colors: https://minecraft.fandom.com/wiki/Map_item_format
/// </summary> /// </summary>
/// <param name="mapid"></param> /// <param name="mapid">Map ID of the map being modified</param>
/// <param name="scale"></param> /// <param name="scale">A scale of the Map, from 0 for a fully zoomed-in map (1 block per pixel) to 4 for a fully zoomed-out map (16 blocks per pixel)</param>
/// <param name="trackingposition"></param> /// <param name="trackingposition">Specifies whether player and item frame icons are shown </param>
/// <param name="locked"></param> /// <param name="locked">True if the map has been locked in a cartography table </param>
/// <param name="iconcount"></param> /// <param name="icons">A list of MapIcon objects of map icons, send only if trackingPosition is true</param>
public void OnMapData(int mapid, byte scale, bool trackingposition, bool locked, int iconcount) /// <param name="columnsUpdated">Numbs of columns that were updated (map width) (NOTE: If it is 0, the next fields are not used/are set to default values of 0 and null respectively)</param>
/// <param name="rowsUpdated">Map height</param>
/// <param name="mapCoulmnX">x offset of the westernmost column</param>
/// <param name="mapRowZ">z offset of the northernmost row</param>
/// <param name="colors">a byte array of colors on the map</param>
public void OnMapData(int mapid, byte scale, bool trackingPosition, bool locked, List<MapIcon> icons, byte columnsUpdated, byte rowsUpdated, byte mapCoulmnX, byte mapCoulmnZ, byte[]? colors)
{ {
DispatchBotEvent(bot => bot.OnMapData(mapid, scale, trackingposition, locked, iconcount)); DispatchBotEvent(bot => bot.OnMapData(mapid, scale, trackingPosition, locked, icons, columnsUpdated, rowsUpdated, mapCoulmnX, mapCoulmnZ, colors));
} }
/// <summary> /// <summary>

View file

@ -783,7 +783,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketTypesIn.MapData: case PacketTypesIn.MapData:
int mapid = dataTypes.ReadNextVarInt(packetData); int mapid = dataTypes.ReadNextVarInt(packetData);
byte scale = dataTypes.ReadNextByte(packetData); byte scale = dataTypes.ReadNextByte(packetData);
bool trackingposition = protocolVersion >= MC_1_17_Version ? false : dataTypes.ReadNextBool(packetData); bool trackingPosition = protocolVersion >= MC_1_17_Version ? false : dataTypes.ReadNextBool(packetData);
bool locked = false; bool locked = false;
if (protocolVersion >= MC_1_14_Version) if (protocolVersion >= MC_1_14_Version)
{ {
@ -791,10 +791,48 @@ namespace MinecraftClient.Protocol.Handlers
} }
if (protocolVersion >= MC_1_17_Version) if (protocolVersion >= MC_1_17_Version)
{ {
trackingposition = dataTypes.ReadNextBool(packetData); trackingPosition = dataTypes.ReadNextBool(packetData);
} }
int iconcount = dataTypes.ReadNextVarInt(packetData);
handler.OnMapData(mapid, scale, trackingposition, locked, iconcount); int iconcount = 0;
List<MapIcon> icons = new();
if (trackingPosition)
{
iconcount = dataTypes.ReadNextVarInt(packetData);
for (int i = 0; i < iconcount; i++)
{
MapIcon mapIcon = new();
mapIcon.Type = (MapIconType)dataTypes.ReadNextVarInt(packetData);
mapIcon.X = dataTypes.ReadNextByte(packetData);
mapIcon.Z = dataTypes.ReadNextByte(packetData);
mapIcon.Direction = dataTypes.ReadNextByte(packetData);
bool mapIconHasDisplayName = dataTypes.ReadNextBool(packetData);
if (mapIconHasDisplayName)
mapIcon.DisplayName = ChatParser.ParseText(dataTypes.ReadNextString(packetData));
icons.Add(mapIcon);
}
}
byte columnsUpdated = dataTypes.ReadNextByte(packetData); // width
byte rowsUpdated = 0; // height
byte mapCoulmnX = 0;
byte mapRowZ = 0;
byte[]? colors = null;
if (columnsUpdated > 0)
{
rowsUpdated = dataTypes.ReadNextByte(packetData); // height
mapCoulmnX = dataTypes.ReadNextByte(packetData);
mapRowZ = dataTypes.ReadNextByte(packetData);
colors = dataTypes.ReadNextByteArray(packetData);
}
handler.OnMapData(mapid, scale, trackingPosition, locked, icons, columnsUpdated, rowsUpdated, mapCoulmnX, mapRowZ, colors);
break; break;
case PacketTypesIn.TradeList: case PacketTypesIn.TradeList:
if ((protocolVersion >= MC_1_14_Version) && (handler.GetInventoryEnabled())) if ((protocolVersion >= MC_1_14_Version) && (handler.GetInventoryEnabled()))
@ -1657,7 +1695,8 @@ namespace MinecraftClient.Protocol.Handlers
{ {
netMain.Item2.Cancel(); netMain.Item2.Cancel();
} }
if (netReader != null){ if (netReader != null)
{
netReader.Item2.Cancel(); netReader.Item2.Cancel();
socketWrapper.Disconnect(); socketWrapper.Disconnect();
} }

View file

@ -358,14 +358,20 @@ namespace MinecraftClient.Protocol
void OnHeldItemChange(byte slot); void OnHeldItemChange(byte slot);
/// <summary> /// <summary>
/// Called map data /// Called when an update of the map is sent by the server, take a look at https://wiki.vg/Protocol#Map_Data for more info on the fields
/// Map format and colors: https://minecraft.fandom.com/wiki/Map_item_format
/// </summary> /// </summary>
/// <param name="mapid"></param> /// <param name="mapid">Map ID of the map being modified</param>
/// <param name="scale"></param> /// <param name="scale">A scale of the Map, from 0 for a fully zoomed-in map (1 block per pixel) to 4 for a fully zoomed-out map (16 blocks per pixel)</param>
/// <param name="trackingposition"></param> /// <param name="trackingposition">Specifies whether player and item frame icons are shown </param>
/// <param name="locked"></param> /// <param name="locked">True if the map has been locked in a cartography table </param>
/// <param name="iconcount"></param> /// <param name="icons">A list of MapIcon objects of map icons, send only if trackingPosition is true</param>
void OnMapData(int mapid, byte scale, bool trackingposition, bool locked, int iconcount); /// <param name="columnsUpdated">Numbs of columns that were updated (map width) (NOTE: If it is 0, the next fields are not used/are set to default values of 0 and null respectively)</param>
/// <param name="rowsUpdated">Map height</param>
/// <param name="mapCoulmnX">x offset of the westernmost column</param>
/// <param name="mapRowZ">z offset of the northernmost row</param>
/// <param name="colors">a byte array of colors on the map</param>
void OnMapData(int mapid, byte scale, bool trackingPosition, bool locked, List<MapIcon> icons, byte columnsUpdated, byte rowsUpdated, byte mapCoulmnX, byte mapRowZ, byte[]? colors);
/// <summary> /// <summary>
/// Called when the Player entity ID has been received from the server /// Called when the Player entity ID has been received from the server

View file

@ -264,14 +264,20 @@ namespace MinecraftClient
public virtual void OnLatencyUpdate(Entity entity, string playername, Guid uuid, int latency) { } public virtual void OnLatencyUpdate(Entity entity, string playername, Guid uuid, int latency) { }
/// <summary> /// <summary>
/// Called when a map was updated /// Called when an update of the map is sent by the server, take a look at https://wiki.vg/Protocol#Map_Data for more info on the fields
/// Map format and colors: https://minecraft.fandom.com/wiki/Map_item_format
/// </summary> /// </summary>
/// <param name="mapid"></param> /// <param name="mapid">Map ID of the map being modified</param>
/// <param name="scale"></param> /// <param name="scale">A scale of the Map, from 0 for a fully zoomed-in map (1 block per pixel) to 4 for a fully zoomed-out map (16 blocks per pixel)</param>
/// <param name="trackingposition"></param> /// <param name="trackingposition">Specifies whether player and item frame icons are shown </param>
/// <param name="locked"></param> /// <param name="locked">True if the map has been locked in a cartography table </param>
/// <param name="iconcount"></param> /// <param name="icons">A list of MapIcon objects of map icons, send only if trackingPosition is true</param>
public virtual void OnMapData(int mapid, byte scale, bool trackingposition, bool locked, int iconcount) { } /// <param name="columnsUpdated">Numbs of columns that were updated (map width) (NOTE: If it is 0, the next fields are not used/are set to default values of 0 and null respectively)</param>
/// <param name="rowsUpdated">Map height</param>
/// <param name="mapCoulmnX">x offset of the westernmost column</param>
/// <param name="mapRowZ">z offset of the northernmost row</param>
/// <param name="colors">a byte array of colors on the map</param>
public virtual void OnMapData(int mapid, byte scale, bool trackingPosition, bool locked, List<MapIcon> icons, byte columnsUpdated, byte rowsUpdated, byte mapCoulmnX, byte mapRowZ, byte[]? colors) { }
/// <summary> /// <summary>
/// Called when tradeList is received from server /// Called when tradeList is received from server
@ -451,14 +457,14 @@ namespace MinecraftClient
/// </summary> /// </summary>
public static string GetVerbatim(string text) public static string GetVerbatim(string text)
{ {
if ( String.IsNullOrEmpty(text) ) if (String.IsNullOrEmpty(text))
return String.Empty; return String.Empty;
int idx = 0; int idx = 0;
var data = new char[text.Length]; var data = new char[text.Length];
for ( int i = 0; i < text.Length; i++ ) for (int i = 0; i < text.Length; i++)
if ( text[i] != '§' ) if (text[i] != '§')
data[idx++] = text[i]; data[idx++] = text[i];
else else
i++; i++;
@ -478,7 +484,7 @@ namespace MinecraftClient
if (!((c >= 'a' && c <= 'z') if (!((c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z') || (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9') || (c >= '0' && c <= '9')
|| c == '_') ) || c == '_'))
return false; return false;
return true; return true;