mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Merge remote-tracking branch 'origin/master' into copilot/reimplement-chat-formatting-feature
# Conflicts: # MinecraftClient/Protocol/Message/ChatParser.cs
This commit is contained in:
commit
7e9be430db
27 changed files with 883 additions and 81 deletions
|
|
@ -436,13 +436,29 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
|
|
||||||
var numberOfComponentsToAdd = ReadNextVarInt(cache);
|
var numberOfComponentsToAdd = ReadNextVarInt(cache);
|
||||||
var numberofComponentsToRemove = ReadNextVarInt(cache);
|
var numberofComponentsToRemove = ReadNextVarInt(cache);
|
||||||
|
var structuredComponentHandler = new StructuredComponentsHandler(protocolversion, this, itemPalette);
|
||||||
|
var parsedComponents = new List<string>(numberOfComponentsToAdd);
|
||||||
|
|
||||||
for (var i = 0; i < numberOfComponentsToAdd; i++)
|
for (var i = 0; i < numberOfComponentsToAdd; i++)
|
||||||
{
|
{
|
||||||
var componentTypeId = ReadNextVarInt(cache);
|
var componentTypeId = ReadNextVarInt(cache);
|
||||||
|
var componentName = structuredComponentHandler.GetComponentName(componentTypeId);
|
||||||
|
parsedComponents.Add($"{i}:{componentTypeId}:{componentName}:next={GetQueuePreview(cache, 24)}");
|
||||||
|
|
||||||
var strcuturedComponentHandler = new StructuredComponentsHandler(protocolversion, this, itemPalette);
|
try
|
||||||
strcturedComponentsToAdd.Add(strcuturedComponentHandler.Parse(componentTypeId, cache));
|
{
|
||||||
|
strcturedComponentsToAdd.Add(structuredComponentHandler.Parse(componentTypeId, cache));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var preview = GetQueuePreview(cache, 48);
|
||||||
|
throw new System.IO.InvalidDataException(
|
||||||
|
$"Failed to decode item component {componentTypeId} ({componentName}) for itemId {itemId}, " +
|
||||||
|
$"itemCount {itemCount}, addCount {numberOfComponentsToAdd}, removeCount {numberofComponentsToRemove}, " +
|
||||||
|
$"componentIndex {i}, remainingBytes {cache.Count}, nextBytes {preview}, " +
|
||||||
|
$"componentTrace [{string.Join(" | ", parsedComponents)}].",
|
||||||
|
ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < numberofComponentsToRemove; i++)
|
for (var i = 0; i < numberofComponentsToRemove; i++)
|
||||||
|
|
@ -516,6 +532,29 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetQueuePreview(Queue<byte> cache, int maxBytes)
|
||||||
|
{
|
||||||
|
if (cache.Count == 0)
|
||||||
|
return "<empty>";
|
||||||
|
|
||||||
|
var bytes = cache.ToArray();
|
||||||
|
var length = Math.Min(bytes.Length, maxBytes);
|
||||||
|
var preview = new StringBuilder(length * 3);
|
||||||
|
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
preview.Append(' ');
|
||||||
|
|
||||||
|
preview.Append(bytes[i].ToString("X2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes.Length > maxBytes)
|
||||||
|
preview.Append(" ...");
|
||||||
|
|
||||||
|
return preview.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read entity information from a cache of bytes and remove it from the cache
|
/// Read entity information from a cache of bytes and remove it from the cache
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,47 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2
|
||||||
|
|
||||||
public class CustomModelDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
public class CustomModelDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
{
|
{
|
||||||
public int Value { get; set; }
|
public List<float> Floats { get; set; } = [];
|
||||||
|
public List<bool> Flags { get; set; } = [];
|
||||||
|
public List<string> Strings { get; set; } = [];
|
||||||
|
public List<int> Colors { get; set; } = [];
|
||||||
|
|
||||||
public override void Parse(Queue<byte> data)
|
public override void Parse(Queue<byte> data)
|
||||||
{
|
{
|
||||||
Value = DataTypes.ReadNextVarInt(data);
|
Floats = ReadList(data, static (dataTypes, componentData) => dataTypes.ReadNextFloat(componentData));
|
||||||
|
Flags = ReadList(data, static (dataTypes, componentData) => dataTypes.ReadNextBool(componentData));
|
||||||
|
Strings = ReadList(data, static (dataTypes, componentData) => dataTypes.ReadNextString(componentData));
|
||||||
|
Colors = ReadList(data, static (dataTypes, componentData) => dataTypes.ReadNextInt(componentData));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Queue<byte> Serialize()
|
public override Queue<byte> Serialize()
|
||||||
{
|
{
|
||||||
var data = new List<byte>();
|
var data = new List<byte>();
|
||||||
data.AddRange(DataTypes.GetVarInt(Value));
|
WriteList(data, Floats, static (dataTypes, value) => dataTypes.GetFloat(value));
|
||||||
|
WriteList(data, Flags, static (dataTypes, value) => dataTypes.GetBool(value));
|
||||||
|
WriteList(data, Strings, static (dataTypes, value) => dataTypes.GetString(value));
|
||||||
|
WriteList(data, Colors, static (_, value) => DataTypes.GetInt(value));
|
||||||
return new Queue<byte>(data);
|
return new Queue<byte>(data);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private List<T> ReadList<T>(Queue<byte> data, ReadDelegate<T> read)
|
||||||
|
{
|
||||||
|
var count = DataTypes.ReadNextVarInt(data);
|
||||||
|
var values = new List<T>(count);
|
||||||
|
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
values.Add(read(DataTypes, data));
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WriteList<T>(List<byte> data, List<T> values, WriteDelegate<T> write)
|
||||||
|
{
|
||||||
|
data.AddRange(DataTypes.GetVarInt(values.Count));
|
||||||
|
foreach (var value in values)
|
||||||
|
data.AddRange(write(DataTypes, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate T ReadDelegate<out T>(DataTypes dataTypes, Queue<byte> data);
|
||||||
|
private delegate byte[] WriteDelegate<in T>(DataTypes dataTypes, T value);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
|
||||||
|
|
||||||
|
public class CustomModelDataComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public int Value { get; set; }
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
Value = DataTypes.ReadNextVarInt(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
return new Queue<byte>(DataTypes.GetVarInt(Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
using MinecraftClient.Protocol.Message;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21;
|
||||||
|
|
||||||
|
public class JukeBoxPlayableComponent121(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public bool IsHolder { get; set; }
|
||||||
|
public int HolderId { get; set; }
|
||||||
|
public string? ResourceKey { get; set; }
|
||||||
|
public SoundEventSubComponent? SoundEvent { get; set; }
|
||||||
|
public Dictionary<string, object>? DescriptionNbt { get; set; }
|
||||||
|
public string Description { get; set; } = string.Empty;
|
||||||
|
public float Duration { get; set; }
|
||||||
|
public int ComparatorOutput { get; set; }
|
||||||
|
public bool ShowTooltip { get; set; }
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
IsHolder = DataTypes.ReadNextBool(data);
|
||||||
|
|
||||||
|
if (IsHolder)
|
||||||
|
{
|
||||||
|
HolderId = DataTypes.ReadNextVarInt(data);
|
||||||
|
if (HolderId == 0)
|
||||||
|
{
|
||||||
|
SoundEvent = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
|
||||||
|
DescriptionNbt = DataTypes.ReadNextNbt(data);
|
||||||
|
Description = ChatParser.ParseText(DescriptionNbt);
|
||||||
|
Duration = DataTypes.ReadNextFloat(data);
|
||||||
|
ComparatorOutput = DataTypes.ReadNextVarInt(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResourceKey = DataTypes.ReadNextString(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowTooltip = DataTypes.ReadNextBool(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
var data = new List<byte>();
|
||||||
|
data.AddRange(DataTypes.GetBool(IsHolder));
|
||||||
|
|
||||||
|
if (IsHolder)
|
||||||
|
{
|
||||||
|
data.AddRange(DataTypes.GetVarInt(HolderId));
|
||||||
|
if (HolderId == 0)
|
||||||
|
{
|
||||||
|
if (SoundEvent is null)
|
||||||
|
throw new ArgumentNullException(nameof(SoundEvent), "Inline jukebox song requires a sound event.");
|
||||||
|
|
||||||
|
if (DescriptionNbt is null)
|
||||||
|
throw new ArgumentNullException(nameof(DescriptionNbt), "Inline jukebox song requires a description.");
|
||||||
|
|
||||||
|
data.AddRange(SoundEvent.Serialize());
|
||||||
|
data.AddRange(DataTypes.GetNbt(DescriptionNbt));
|
||||||
|
data.AddRange(DataTypes.GetFloat(Duration));
|
||||||
|
data.AddRange(DataTypes.GetVarInt(ComparatorOutput));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(ResourceKey))
|
||||||
|
throw new ArgumentNullException(nameof(ResourceKey), "Resource key is required for key-backed jukebox songs.");
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetString(ResourceKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(ShowTooltip));
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||||
|
|
||||||
|
public class PotionContentsComponent1212(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public bool HasPotionId { get; set; }
|
||||||
|
public int PotionId { get; set; }
|
||||||
|
public bool HasCustomColor { get; set; }
|
||||||
|
public int CustomColor { get; set; }
|
||||||
|
public List<PotionEffectSubComponent> Effects { get; set; } = [];
|
||||||
|
public bool HasCustomName { get; set; }
|
||||||
|
public string? CustomName { get; set; }
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
HasPotionId = DataTypes.ReadNextBool(data);
|
||||||
|
if (HasPotionId)
|
||||||
|
PotionId = DataTypes.ReadNextVarInt(data);
|
||||||
|
|
||||||
|
HasCustomColor = DataTypes.ReadNextBool(data);
|
||||||
|
if (HasCustomColor)
|
||||||
|
CustomColor = DataTypes.ReadNextInt(data);
|
||||||
|
|
||||||
|
var numberOfEffects = DataTypes.ReadNextVarInt(data);
|
||||||
|
Effects = new List<PotionEffectSubComponent>(numberOfEffects);
|
||||||
|
for (var i = 0; i < numberOfEffects; i++)
|
||||||
|
Effects.Add((PotionEffectSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data));
|
||||||
|
|
||||||
|
HasCustomName = DataTypes.ReadNextBool(data);
|
||||||
|
if (HasCustomName)
|
||||||
|
CustomName = DataTypes.ReadNextString(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
var data = new List<byte>();
|
||||||
|
data.AddRange(DataTypes.GetBool(HasPotionId));
|
||||||
|
if (HasPotionId)
|
||||||
|
data.AddRange(DataTypes.GetVarInt(PotionId));
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(HasCustomColor));
|
||||||
|
if (HasCustomColor)
|
||||||
|
data.AddRange(DataTypes.GetInt(CustomColor));
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetVarInt(Effects.Count));
|
||||||
|
foreach (var effect in Effects)
|
||||||
|
data.AddRange(effect.Serialize());
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(HasCustomName));
|
||||||
|
if (HasCustomName && CustomName is not null)
|
||||||
|
data.AddRange(DataTypes.GetString(CustomName));
|
||||||
|
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5;
|
||||||
|
|
||||||
|
public class AttributeModifiersComponent1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public int NumberOfAttributes { get; set; }
|
||||||
|
public List<SubComponent> Attributes { get; set; } = [];
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
NumberOfAttributes = DataTypes.ReadNextVarInt(data);
|
||||||
|
Attributes = new List<SubComponent>(NumberOfAttributes);
|
||||||
|
|
||||||
|
for (var i = 0; i < NumberOfAttributes; i++)
|
||||||
|
Attributes.Add(SubComponentRegistry.ParseSubComponent(SubComponents.Attribute, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
var data = new List<byte>();
|
||||||
|
data.AddRange(DataTypes.GetVarInt(NumberOfAttributes));
|
||||||
|
|
||||||
|
if (Attributes.Count != NumberOfAttributes)
|
||||||
|
throw new ArgumentNullException(nameof(Attributes), "Attributes count must match NumberOfAttributes.");
|
||||||
|
|
||||||
|
foreach (var attribute in Attributes)
|
||||||
|
data.AddRange(attribute.Serialize());
|
||||||
|
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5;
|
||||||
|
|
||||||
|
public class EquippableComponent1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public int Slot { get; set; }
|
||||||
|
public SoundEventSubComponent? EquipSound { get; set; }
|
||||||
|
public bool HasAssetId { get; set; }
|
||||||
|
public string? AssetId { get; set; }
|
||||||
|
public bool HasCameraOverlay { get; set; }
|
||||||
|
public string? CameraOverlay { get; set; }
|
||||||
|
public bool HasAllowedEntities { get; set; }
|
||||||
|
public int AllowedEntitiesType { get; set; }
|
||||||
|
public string? AllowedEntitiesTag { get; set; }
|
||||||
|
public List<int>? AllowedEntitiesIds { get; set; }
|
||||||
|
public bool Dispensable { get; set; }
|
||||||
|
public bool Swappable { get; set; }
|
||||||
|
public bool DamageOnHurt { get; set; }
|
||||||
|
public bool EquipOnInteract { get; set; }
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
Slot = DataTypes.ReadNextVarInt(data);
|
||||||
|
EquipSound = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
|
||||||
|
|
||||||
|
HasAssetId = DataTypes.ReadNextBool(data);
|
||||||
|
if (HasAssetId)
|
||||||
|
AssetId = DataTypes.ReadNextString(data);
|
||||||
|
|
||||||
|
HasCameraOverlay = DataTypes.ReadNextBool(data);
|
||||||
|
if (HasCameraOverlay)
|
||||||
|
CameraOverlay = DataTypes.ReadNextString(data);
|
||||||
|
|
||||||
|
HasAllowedEntities = DataTypes.ReadNextBool(data);
|
||||||
|
if (HasAllowedEntities)
|
||||||
|
{
|
||||||
|
AllowedEntitiesType = DataTypes.ReadNextVarInt(data);
|
||||||
|
if (AllowedEntitiesType == 0)
|
||||||
|
{
|
||||||
|
AllowedEntitiesTag = DataTypes.ReadNextString(data);
|
||||||
|
AllowedEntitiesIds = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AllowedEntitiesTag = null;
|
||||||
|
AllowedEntitiesIds = new List<int>(Math.Max(AllowedEntitiesType - 1, 0));
|
||||||
|
for (var i = 0; i < AllowedEntitiesType - 1; i++)
|
||||||
|
AllowedEntitiesIds.Add(DataTypes.ReadNextVarInt(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dispensable = DataTypes.ReadNextBool(data);
|
||||||
|
Swappable = DataTypes.ReadNextBool(data);
|
||||||
|
DamageOnHurt = DataTypes.ReadNextBool(data);
|
||||||
|
EquipOnInteract = DataTypes.ReadNextBool(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
var data = new List<byte>();
|
||||||
|
data.AddRange(DataTypes.GetVarInt(Slot));
|
||||||
|
|
||||||
|
if (EquipSound is null)
|
||||||
|
throw new ArgumentNullException(nameof(EquipSound), "EquipSound is required.");
|
||||||
|
|
||||||
|
data.AddRange(EquipSound.Serialize());
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(HasAssetId));
|
||||||
|
if (HasAssetId && AssetId is not null)
|
||||||
|
data.AddRange(DataTypes.GetString(AssetId));
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(HasCameraOverlay));
|
||||||
|
if (HasCameraOverlay && CameraOverlay is not null)
|
||||||
|
data.AddRange(DataTypes.GetString(CameraOverlay));
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(HasAllowedEntities));
|
||||||
|
if (HasAllowedEntities)
|
||||||
|
{
|
||||||
|
data.AddRange(DataTypes.GetVarInt(AllowedEntitiesType));
|
||||||
|
if (AllowedEntitiesType == 0 && AllowedEntitiesTag is not null)
|
||||||
|
{
|
||||||
|
data.AddRange(DataTypes.GetString(AllowedEntitiesTag));
|
||||||
|
}
|
||||||
|
else if (AllowedEntitiesIds is not null)
|
||||||
|
{
|
||||||
|
foreach (var id in AllowedEntitiesIds)
|
||||||
|
data.AddRange(DataTypes.GetVarInt(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(Dispensable));
|
||||||
|
data.AddRange(DataTypes.GetBool(Swappable));
|
||||||
|
data.AddRange(DataTypes.GetBool(DamageOnHurt));
|
||||||
|
data.AddRange(DataTypes.GetBool(EquipOnInteract));
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,7 @@ public class InstrumentComponent1215(DataTypes dataTypes, ItemPalette itemPalett
|
||||||
var holderId = DataTypes.ReadNextVarInt(data);
|
var holderId = DataTypes.ReadNextVarInt(data);
|
||||||
if (holderId == 0)
|
if (holderId == 0)
|
||||||
{
|
{
|
||||||
// Inline Instrument: SoundEvent holder + VarInt useDuration + Float range + Component description
|
// Inline Instrument: SoundEvent holder + Float useDuration + Float range + Component description
|
||||||
var soundHolderId = DataTypes.ReadNextVarInt(data);
|
var soundHolderId = DataTypes.ReadNextVarInt(data);
|
||||||
if (soundHolderId == 0)
|
if (soundHolderId == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -25,9 +25,10 @@ public class InstrumentComponent1215(DataTypes dataTypes, ItemPalette itemPalett
|
||||||
if (hasFixedRange)
|
if (hasFixedRange)
|
||||||
DataTypes.ReadNextFloat(data);
|
DataTypes.ReadNextFloat(data);
|
||||||
}
|
}
|
||||||
DataTypes.ReadNextVarInt(data); // useDuration
|
DataTypes.ReadNextFloat(data); // useDuration
|
||||||
DataTypes.ReadNextFloat(data); // range
|
DataTypes.ReadNextFloat(data); // range
|
||||||
DataTypes.ReadNextString(data); // description (Component as JSON string)
|
// ComponentSerialization.STREAM_CODEC is NBT-backed, not a plain string.
|
||||||
|
DataTypes.ReadNextNbt(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
using MinecraftClient.Protocol.Message;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5;
|
||||||
|
|
||||||
|
public class JukeBoxPlayableComponent1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public bool IsHolder { get; set; }
|
||||||
|
public int HolderId { get; set; }
|
||||||
|
public string? ResourceKey { get; set; }
|
||||||
|
public SoundEventSubComponent? SoundEvent { get; set; }
|
||||||
|
public Dictionary<string, object>? DescriptionNbt { get; set; }
|
||||||
|
public string Description { get; set; } = string.Empty;
|
||||||
|
public float Duration { get; set; }
|
||||||
|
public int ComparatorOutput { get; set; }
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
IsHolder = DataTypes.ReadNextBool(data);
|
||||||
|
|
||||||
|
if (IsHolder)
|
||||||
|
{
|
||||||
|
HolderId = DataTypes.ReadNextVarInt(data);
|
||||||
|
if (HolderId == 0)
|
||||||
|
{
|
||||||
|
SoundEvent = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
|
||||||
|
DescriptionNbt = DataTypes.ReadNextNbt(data);
|
||||||
|
Description = ChatParser.ParseText(DescriptionNbt);
|
||||||
|
Duration = DataTypes.ReadNextFloat(data);
|
||||||
|
ComparatorOutput = DataTypes.ReadNextVarInt(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResourceKey = DataTypes.ReadNextString(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
var data = new List<byte>();
|
||||||
|
data.AddRange(DataTypes.GetBool(IsHolder));
|
||||||
|
|
||||||
|
if (IsHolder)
|
||||||
|
{
|
||||||
|
data.AddRange(DataTypes.GetVarInt(HolderId));
|
||||||
|
if (HolderId == 0)
|
||||||
|
{
|
||||||
|
if (SoundEvent is null)
|
||||||
|
throw new ArgumentNullException(nameof(SoundEvent), "Inline jukebox song requires a sound event.");
|
||||||
|
|
||||||
|
if (DescriptionNbt is null)
|
||||||
|
throw new ArgumentNullException(nameof(DescriptionNbt), "Inline jukebox song requires a description.");
|
||||||
|
|
||||||
|
data.AddRange(SoundEvent.Serialize());
|
||||||
|
data.AddRange(DataTypes.GetNbt(DescriptionNbt));
|
||||||
|
data.AddRange(DataTypes.GetFloat(Duration));
|
||||||
|
data.AddRange(DataTypes.GetVarInt(ComparatorOutput));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(ResourceKey))
|
||||||
|
throw new ArgumentNullException(nameof(ResourceKey), "Resource key is required for key-backed jukebox songs.");
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetString(ResourceKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,11 +20,11 @@ public class PaintingVariantHolderComponent(DataTypes dataTypes, ItemPalette ite
|
||||||
|
|
||||||
// Optional<Component> title
|
// Optional<Component> title
|
||||||
if (DataTypes.ReadNextBool(data))
|
if (DataTypes.ReadNextBool(data))
|
||||||
DataTypes.ReadNextString(data);
|
DataTypes.ReadNextNbt(data);
|
||||||
|
|
||||||
// Optional<Component> author
|
// Optional<Component> author
|
||||||
if (DataTypes.ReadNextBool(data))
|
if (DataTypes.ReadNextBool(data))
|
||||||
DataTypes.ReadNextString(data);
|
DataTypes.ReadNextNbt(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ public class ProvidesTrimMaterialComponent(DataTypes dataTypes, ItemPalette item
|
||||||
DataTypes.ReadNextString(data); // ResourceKey<EquipmentAsset>
|
DataTypes.ReadNextString(data); // ResourceKey<EquipmentAsset>
|
||||||
DataTypes.ReadNextString(data); // override suffix
|
DataTypes.ReadNextString(data); // override suffix
|
||||||
}
|
}
|
||||||
// description Component
|
// ComponentSerialization.STREAM_CODEC is NBT-backed, not a plain string.
|
||||||
DataTypes.ReadNextString(data);
|
DataTypes.ReadNextNbt(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5;
|
||||||
|
|
||||||
|
public class ToolComponent1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public int NumberOfRules { get; set; }
|
||||||
|
public List<RuleSubComponent> Rules { get; set; } = [];
|
||||||
|
public float DefaultMiningSpeed { get; set; }
|
||||||
|
public int DamagePerBlock { get; set; }
|
||||||
|
public bool CanDestroyBlocksInCreative { get; set; }
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
NumberOfRules = DataTypes.ReadNextVarInt(data);
|
||||||
|
Rules = new List<RuleSubComponent>(NumberOfRules);
|
||||||
|
|
||||||
|
for (var i = 0; i < NumberOfRules; i++)
|
||||||
|
Rules.Add((RuleSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.Rule, data));
|
||||||
|
|
||||||
|
DefaultMiningSpeed = DataTypes.ReadNextFloat(data);
|
||||||
|
DamagePerBlock = DataTypes.ReadNextVarInt(data);
|
||||||
|
CanDestroyBlocksInCreative = DataTypes.ReadNextBool(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
var data = new List<byte>();
|
||||||
|
data.AddRange(DataTypes.GetVarInt(NumberOfRules));
|
||||||
|
|
||||||
|
if (Rules.Count != NumberOfRules)
|
||||||
|
throw new ArgumentNullException(nameof(Rules), "Rules count must match NumberOfRules.");
|
||||||
|
|
||||||
|
foreach (var rule in Rules)
|
||||||
|
data.AddRange(rule.Serialize());
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetFloat(DefaultMiningSpeed));
|
||||||
|
data.AddRange(DataTypes.GetVarInt(DamagePerBlock));
|
||||||
|
data.AddRange(DataTypes.GetBool(CanDestroyBlocksInCreative));
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
using MinecraftClient.Protocol.Message;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_8;
|
||||||
|
|
||||||
|
public class AttributeModifiersComponent1218(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public int NumberOfAttributes { get; set; }
|
||||||
|
public List<SubComponent> Attributes { get; set; } = [];
|
||||||
|
public List<AttributeModifierDisplay> Displays { get; set; } = [];
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
NumberOfAttributes = DataTypes.ReadNextVarInt(data);
|
||||||
|
Attributes = new List<SubComponent>(NumberOfAttributes);
|
||||||
|
Displays = new List<AttributeModifierDisplay>(NumberOfAttributes);
|
||||||
|
|
||||||
|
for (var i = 0; i < NumberOfAttributes; i++)
|
||||||
|
{
|
||||||
|
Attributes.Add(SubComponentRegistry.ParseSubComponent(SubComponents.Attribute, data));
|
||||||
|
Displays.Add(ReadDisplay(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
var data = new List<byte>();
|
||||||
|
data.AddRange(DataTypes.GetVarInt(NumberOfAttributes));
|
||||||
|
|
||||||
|
if (Attributes.Count != NumberOfAttributes)
|
||||||
|
throw new ArgumentNullException(nameof(Attributes), "Attributes count must match NumberOfAttributes.");
|
||||||
|
|
||||||
|
if (Displays.Count != NumberOfAttributes)
|
||||||
|
throw new ArgumentNullException(nameof(Displays), "Displays count must match NumberOfAttributes.");
|
||||||
|
|
||||||
|
for (var i = 0; i < NumberOfAttributes; i++)
|
||||||
|
{
|
||||||
|
data.AddRange(Attributes[i].Serialize());
|
||||||
|
data.AddRange(SerializeDisplay(Displays[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AttributeModifierDisplay ReadDisplay(Queue<byte> data)
|
||||||
|
{
|
||||||
|
var displayType = DataTypes.ReadNextVarInt(data);
|
||||||
|
return displayType switch
|
||||||
|
{
|
||||||
|
0 => new AttributeModifierDisplay(AttributeModifierDisplayType.Default),
|
||||||
|
1 => new AttributeModifierDisplay(AttributeModifierDisplayType.Hidden),
|
||||||
|
2 => ReadOverrideDisplay(data),
|
||||||
|
_ => throw new InvalidDataException($"Unknown attribute modifier display type: {displayType}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private AttributeModifierDisplay ReadOverrideDisplay(Queue<byte> data)
|
||||||
|
{
|
||||||
|
var overrideTextNbt = DataTypes.ReadNextNbt(data);
|
||||||
|
var overrideText = ChatParser.ParseText(overrideTextNbt);
|
||||||
|
return new AttributeModifierDisplay(AttributeModifierDisplayType.Override, overrideTextNbt, overrideText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Queue<byte> SerializeDisplay(AttributeModifierDisplay display)
|
||||||
|
{
|
||||||
|
var data = new List<byte>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
data.AddRange(DataTypes.GetVarInt((int)display.Type));
|
||||||
|
|
||||||
|
if (display.Type == AttributeModifierDisplayType.Override)
|
||||||
|
{
|
||||||
|
if (display.OverrideTextNbt is null)
|
||||||
|
throw new ArgumentNullException(nameof(display.OverrideTextNbt), "Override display requires component NBT.");
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetNbt(display.OverrideTextNbt));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed record AttributeModifierDisplay(
|
||||||
|
AttributeModifierDisplayType Type,
|
||||||
|
Dictionary<string, object>? OverrideTextNbt = null,
|
||||||
|
string? OverrideText = null);
|
||||||
|
|
||||||
|
public enum AttributeModifierDisplayType
|
||||||
|
{
|
||||||
|
Default = 0,
|
||||||
|
Hidden = 1,
|
||||||
|
Override = 2
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_8;
|
||||||
|
|
||||||
|
public class EquippableComponent1218(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public int Slot { get; set; }
|
||||||
|
public SoundEventSubComponent? EquipSound { get; set; }
|
||||||
|
public bool HasAssetId { get; set; }
|
||||||
|
public string? AssetId { get; set; }
|
||||||
|
public bool HasCameraOverlay { get; set; }
|
||||||
|
public string? CameraOverlay { get; set; }
|
||||||
|
public bool HasAllowedEntities { get; set; }
|
||||||
|
public int AllowedEntitiesType { get; set; }
|
||||||
|
public string? AllowedEntitiesTag { get; set; }
|
||||||
|
public List<int>? AllowedEntitiesIds { get; set; }
|
||||||
|
public bool Dispensable { get; set; }
|
||||||
|
public bool Swappable { get; set; }
|
||||||
|
public bool DamageOnHurt { get; set; }
|
||||||
|
public bool EquipOnInteract { get; set; }
|
||||||
|
public bool CanBeSheared { get; set; }
|
||||||
|
public SoundEventSubComponent? ShearingSound { get; set; }
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
Slot = DataTypes.ReadNextVarInt(data);
|
||||||
|
EquipSound = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
|
||||||
|
|
||||||
|
HasAssetId = DataTypes.ReadNextBool(data);
|
||||||
|
if (HasAssetId)
|
||||||
|
AssetId = DataTypes.ReadNextString(data);
|
||||||
|
|
||||||
|
HasCameraOverlay = DataTypes.ReadNextBool(data);
|
||||||
|
if (HasCameraOverlay)
|
||||||
|
CameraOverlay = DataTypes.ReadNextString(data);
|
||||||
|
|
||||||
|
HasAllowedEntities = DataTypes.ReadNextBool(data);
|
||||||
|
if (HasAllowedEntities)
|
||||||
|
{
|
||||||
|
AllowedEntitiesType = DataTypes.ReadNextVarInt(data);
|
||||||
|
if (AllowedEntitiesType == 0)
|
||||||
|
{
|
||||||
|
AllowedEntitiesTag = DataTypes.ReadNextString(data);
|
||||||
|
AllowedEntitiesIds = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AllowedEntitiesTag = null;
|
||||||
|
AllowedEntitiesIds = new List<int>(Math.Max(AllowedEntitiesType - 1, 0));
|
||||||
|
for (var i = 0; i < AllowedEntitiesType - 1; i++)
|
||||||
|
AllowedEntitiesIds.Add(DataTypes.ReadNextVarInt(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dispensable = DataTypes.ReadNextBool(data);
|
||||||
|
Swappable = DataTypes.ReadNextBool(data);
|
||||||
|
DamageOnHurt = DataTypes.ReadNextBool(data);
|
||||||
|
EquipOnInteract = DataTypes.ReadNextBool(data);
|
||||||
|
CanBeSheared = DataTypes.ReadNextBool(data);
|
||||||
|
ShearingSound = (SoundEventSubComponent)SubComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
var data = new List<byte>();
|
||||||
|
data.AddRange(DataTypes.GetVarInt(Slot));
|
||||||
|
|
||||||
|
if (EquipSound is null)
|
||||||
|
throw new ArgumentNullException(nameof(EquipSound), "EquipSound is required.");
|
||||||
|
|
||||||
|
if (ShearingSound is null)
|
||||||
|
throw new ArgumentNullException(nameof(ShearingSound), "ShearingSound is required.");
|
||||||
|
|
||||||
|
data.AddRange(EquipSound.Serialize());
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(HasAssetId));
|
||||||
|
if (HasAssetId && AssetId is not null)
|
||||||
|
data.AddRange(DataTypes.GetString(AssetId));
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(HasCameraOverlay));
|
||||||
|
if (HasCameraOverlay && CameraOverlay is not null)
|
||||||
|
data.AddRange(DataTypes.GetString(CameraOverlay));
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(HasAllowedEntities));
|
||||||
|
if (HasAllowedEntities)
|
||||||
|
{
|
||||||
|
data.AddRange(DataTypes.GetVarInt(AllowedEntitiesType));
|
||||||
|
if (AllowedEntitiesType == 0 && AllowedEntitiesTag is not null)
|
||||||
|
{
|
||||||
|
data.AddRange(DataTypes.GetString(AllowedEntitiesTag));
|
||||||
|
}
|
||||||
|
else if (AllowedEntitiesIds is not null)
|
||||||
|
{
|
||||||
|
foreach (var id in AllowedEntitiesIds)
|
||||||
|
data.AddRange(DataTypes.GetVarInt(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.AddRange(DataTypes.GetBool(Dispensable));
|
||||||
|
data.AddRange(DataTypes.GetBool(Swappable));
|
||||||
|
data.AddRange(DataTypes.GetBool(DamageOnHurt));
|
||||||
|
data.AddRange(DataTypes.GetBool(EquipOnInteract));
|
||||||
|
data.AddRange(DataTypes.GetBool(CanBeSheared));
|
||||||
|
data.AddRange(ShearingSound.Serialize());
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MinecraftClient.Inventory.ItemPalettes;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_9;
|
||||||
|
|
||||||
|
public class BeesComponent1219(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
|
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||||
|
{
|
||||||
|
public int NumberOfBees { get; set; }
|
||||||
|
public List<TypedBee> Bees { get; set; } = [];
|
||||||
|
|
||||||
|
public override void Parse(Queue<byte> data)
|
||||||
|
{
|
||||||
|
NumberOfBees = DataTypes.ReadNextVarInt(data);
|
||||||
|
Bees = new List<TypedBee>(NumberOfBees);
|
||||||
|
|
||||||
|
for (var i = 0; i < NumberOfBees; i++)
|
||||||
|
{
|
||||||
|
Bees.Add(
|
||||||
|
new TypedBee(
|
||||||
|
DataTypes.ReadNextVarInt(data),
|
||||||
|
DataTypes.ReadNextNbt(data),
|
||||||
|
DataTypes.ReadNextVarInt(data),
|
||||||
|
DataTypes.ReadNextVarInt(data)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Queue<byte> Serialize()
|
||||||
|
{
|
||||||
|
var data = new List<byte>();
|
||||||
|
data.AddRange(DataTypes.GetVarInt(NumberOfBees));
|
||||||
|
|
||||||
|
if (NumberOfBees != Bees.Count)
|
||||||
|
throw new InvalidOperationException("Can't serialize the BeesComponent1219 because NumberOfBees and Bees.Count differ!");
|
||||||
|
|
||||||
|
foreach (var bee in Bees)
|
||||||
|
{
|
||||||
|
data.AddRange(DataTypes.GetVarInt(bee.EntityTypeId));
|
||||||
|
data.AddRange(DataTypes.GetNbt(bee.EntityDataNbt));
|
||||||
|
data.AddRange(DataTypes.GetVarInt(bee.TicksInHive));
|
||||||
|
data.AddRange(DataTypes.GetVarInt(bee.MinTicksInHive));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Queue<byte>(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed record TypedBee(int EntityTypeId, Dictionary<string, object>? EntityDataNbt, int TicksInHive, int MinTicksInHive);
|
||||||
|
|
@ -22,7 +22,7 @@ public class StructuredComponentsRegistry1206 : StructuredComponentRegistry
|
||||||
RegisterComponent<CanPlaceOnComponent>(10, "minecraft:can_place_on");
|
RegisterComponent<CanPlaceOnComponent>(10, "minecraft:can_place_on");
|
||||||
RegisterComponent<CanBreakComponent>(11, "minecraft:can_break");
|
RegisterComponent<CanBreakComponent>(11, "minecraft:can_break");
|
||||||
RegisterComponent<AttributeModifiersComponent>(12, "minecraft:attribute_modifiers");
|
RegisterComponent<AttributeModifiersComponent>(12, "minecraft:attribute_modifiers");
|
||||||
RegisterComponent<CustomModelDataComponent>(13, "minecraft:custom_model_data");
|
RegisterComponent<CustomModelDataComponent1206>(13, "minecraft:custom_model_data");
|
||||||
RegisterComponent<HideAdditionalTooltipComponent>(14, "minecraft:hide_additional_tooltip");
|
RegisterComponent<HideAdditionalTooltipComponent>(14, "minecraft:hide_additional_tooltip");
|
||||||
RegisterComponent<HideTooltipComponent>(15, "minecraft:hide_tooltip");
|
RegisterComponent<HideTooltipComponent>(15, "minecraft:hide_tooltip");
|
||||||
RegisterComponent<RepairCostComponent>(16, "minecraft:repair_cost");
|
RegisterComponent<RepairCostComponent>(16, "minecraft:repair_cost");
|
||||||
|
|
@ -66,4 +66,4 @@ public class StructuredComponentsRegistry1206 : StructuredComponentRegistry
|
||||||
RegisterComponent<LockComponent>(54, "minecraft:lock");
|
RegisterComponent<LockComponent>(54, "minecraft:lock");
|
||||||
RegisterComponent<ContainerLootComponent>(55, "minecraft:container_loot");
|
RegisterComponent<ContainerLootComponent>(55, "minecraft:container_loot");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public class StructuredComponentsRegistry121 : StructuredComponentRegistry
|
||||||
RegisterComponent<CanPlaceOnComponent>(10, "minecraft:can_place_on");
|
RegisterComponent<CanPlaceOnComponent>(10, "minecraft:can_place_on");
|
||||||
RegisterComponent<CanBreakComponent>(11, "minecraft:can_break");
|
RegisterComponent<CanBreakComponent>(11, "minecraft:can_break");
|
||||||
RegisterComponent<AttributeModifiersComponent>(12, "minecraft:attribute_modifiers");
|
RegisterComponent<AttributeModifiersComponent>(12, "minecraft:attribute_modifiers");
|
||||||
RegisterComponent<CustomModelDataComponent>(13, "minecraft:custom_model_data");
|
RegisterComponent<CustomModelDataComponent1206>(13, "minecraft:custom_model_data");
|
||||||
RegisterComponent<HideAdditionalTooltipComponent>(14, "minecraft:hide_additional_tooltip");
|
RegisterComponent<HideAdditionalTooltipComponent>(14, "minecraft:hide_additional_tooltip");
|
||||||
RegisterComponent<HideTooltipComponent>(15, "minecraft:hide_tooltip");
|
RegisterComponent<HideTooltipComponent>(15, "minecraft:hide_tooltip");
|
||||||
RegisterComponent<RepairCostComponent>(16, "minecraft:repair_cost");
|
RegisterComponent<RepairCostComponent>(16, "minecraft:repair_cost");
|
||||||
|
|
@ -52,7 +52,7 @@ public class StructuredComponentsRegistry121 : StructuredComponentRegistry
|
||||||
RegisterComponent<BlockEntityDataComponent>(39, "minecraft:block_entity_data");
|
RegisterComponent<BlockEntityDataComponent>(39, "minecraft:block_entity_data");
|
||||||
RegisterComponent<InstrumentComponent>(40, "minecraft:instrument");
|
RegisterComponent<InstrumentComponent>(40, "minecraft:instrument");
|
||||||
RegisterComponent<OmniousBottleAmplifierComponent>(41, "minecraft:ominous_bottle_amplifier");
|
RegisterComponent<OmniousBottleAmplifierComponent>(41, "minecraft:ominous_bottle_amplifier");
|
||||||
RegisterComponent<JukeBoxPlayableComponent>(42, "minecraft:jukebox_playable");
|
RegisterComponent<JukeBoxPlayableComponent121>(42, "minecraft:jukebox_playable");
|
||||||
RegisterComponent<RecipesComponent>(43, "minecraft:recipes");
|
RegisterComponent<RecipesComponent>(43, "minecraft:recipes");
|
||||||
RegisterComponent<LodestoneTrackerComponent>(44, "minecraft:lodestone_tracker");
|
RegisterComponent<LodestoneTrackerComponent>(44, "minecraft:lodestone_tracker");
|
||||||
RegisterComponent<FireworkExplosionComponent>(45, "minecraft:firework_explosion");
|
RegisterComponent<FireworkExplosionComponent>(45, "minecraft:firework_explosion");
|
||||||
|
|
@ -68,4 +68,4 @@ public class StructuredComponentsRegistry121 : StructuredComponentRegistry
|
||||||
RegisterComponent<LockComponent>(55, "minecraft:lock");
|
RegisterComponent<LockComponent>(55, "minecraft:lock");
|
||||||
RegisterComponent<ContainerLootComponent>(56, "minecraft:container_loot");
|
RegisterComponent<ContainerLootComponent>(56, "minecraft:container_loot");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
|
||||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21;
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21;
|
||||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5;
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_8;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_9;
|
||||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11;
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11;
|
||||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
|
||||||
|
|
@ -30,7 +32,7 @@ public class StructuredComponentsRegistry12111 : StructuredComponentRegistry
|
||||||
RegisterComponent<EnchantmentsComponent1215>(13, "minecraft:enchantments");
|
RegisterComponent<EnchantmentsComponent1215>(13, "minecraft:enchantments");
|
||||||
RegisterComponent<CanPlaceOnComponent>(14, "minecraft:can_place_on");
|
RegisterComponent<CanPlaceOnComponent>(14, "minecraft:can_place_on");
|
||||||
RegisterComponent<CanBreakComponent>(15, "minecraft:can_break");
|
RegisterComponent<CanBreakComponent>(15, "minecraft:can_break");
|
||||||
RegisterComponent<AttributeModifiersComponent>(16, "minecraft:attribute_modifiers");
|
RegisterComponent<AttributeModifiersComponent1218>(16, "minecraft:attribute_modifiers");
|
||||||
RegisterComponent<CustomModelDataComponent>(17, "minecraft:custom_model_data");
|
RegisterComponent<CustomModelDataComponent>(17, "minecraft:custom_model_data");
|
||||||
RegisterComponent<TooltipDisplayComponent>(18, "minecraft:tooltip_display");
|
RegisterComponent<TooltipDisplayComponent>(18, "minecraft:tooltip_display");
|
||||||
RegisterComponent<RepairCostComponent>(19, "minecraft:repair_cost");
|
RegisterComponent<RepairCostComponent>(19, "minecraft:repair_cost");
|
||||||
|
|
@ -42,11 +44,11 @@ public class StructuredComponentsRegistry12111 : StructuredComponentRegistry
|
||||||
RegisterComponent<UseRemainderComponent>(25, "minecraft:use_remainder");
|
RegisterComponent<UseRemainderComponent>(25, "minecraft:use_remainder");
|
||||||
RegisterComponent<UseCooldownComponent>(26, "minecraft:use_cooldown");
|
RegisterComponent<UseCooldownComponent>(26, "minecraft:use_cooldown");
|
||||||
RegisterComponent<DamageResistantComponent>(27, "minecraft:damage_resistant");
|
RegisterComponent<DamageResistantComponent>(27, "minecraft:damage_resistant");
|
||||||
RegisterComponent<ToolComponent>(28, "minecraft:tool");
|
RegisterComponent<ToolComponent1215>(28, "minecraft:tool");
|
||||||
RegisterComponent<WeaponComponent>(29, "minecraft:weapon");
|
RegisterComponent<WeaponComponent>(29, "minecraft:weapon");
|
||||||
RegisterComponent<AttackRangeComponent>(30, "minecraft:attack_range");
|
RegisterComponent<AttackRangeComponent>(30, "minecraft:attack_range");
|
||||||
RegisterComponent<EnchantableComponent>(31, "minecraft:enchantable");
|
RegisterComponent<EnchantableComponent>(31, "minecraft:enchantable");
|
||||||
RegisterComponent<EquippableComponent>(32, "minecraft:equippable");
|
RegisterComponent<EquippableComponent1218>(32, "minecraft:equippable");
|
||||||
RegisterComponent<RepairableComponent>(33, "minecraft:repairable");
|
RegisterComponent<RepairableComponent>(33, "minecraft:repairable");
|
||||||
RegisterComponent<GliderComponent>(34, "minecraft:glider");
|
RegisterComponent<GliderComponent>(34, "minecraft:glider");
|
||||||
RegisterComponent<TooltipStyleComponent>(35, "minecraft:tooltip_style");
|
RegisterComponent<TooltipStyleComponent>(35, "minecraft:tooltip_style");
|
||||||
|
|
@ -63,7 +65,7 @@ public class StructuredComponentsRegistry12111 : StructuredComponentRegistry
|
||||||
RegisterComponent<MapPostProcessingComponent>(46, "minecraft:map_post_processing");
|
RegisterComponent<MapPostProcessingComponent>(46, "minecraft:map_post_processing");
|
||||||
RegisterComponent<ChargedProjectilesComponent>(47, "minecraft:charged_projectiles");
|
RegisterComponent<ChargedProjectilesComponent>(47, "minecraft:charged_projectiles");
|
||||||
RegisterComponent<BundleContentsComponent>(48, "minecraft:bundle_contents");
|
RegisterComponent<BundleContentsComponent>(48, "minecraft:bundle_contents");
|
||||||
RegisterComponent<PotionContentsComponent>(49, "minecraft:potion_contents");
|
RegisterComponent<PotionContentsComponent1212>(49, "minecraft:potion_contents");
|
||||||
RegisterComponent<PotionDurationScaleComponent>(50, "minecraft:potion_duration_scale");
|
RegisterComponent<PotionDurationScaleComponent>(50, "minecraft:potion_duration_scale");
|
||||||
RegisterComponent<SuspiciousStewEffectsComponent>(51, "minecraft:suspicious_stew_effects");
|
RegisterComponent<SuspiciousStewEffectsComponent>(51, "minecraft:suspicious_stew_effects");
|
||||||
RegisterComponent<WritableBlookContentComponent>(52, "minecraft:writable_book_content");
|
RegisterComponent<WritableBlookContentComponent>(52, "minecraft:writable_book_content");
|
||||||
|
|
@ -76,7 +78,7 @@ public class StructuredComponentsRegistry12111 : StructuredComponentRegistry
|
||||||
RegisterComponent<InstrumentComponent1215>(59, "minecraft:instrument");
|
RegisterComponent<InstrumentComponent1215>(59, "minecraft:instrument");
|
||||||
RegisterComponent<ProvidesTrimMaterialComponent>(60, "minecraft:provides_trim_material");
|
RegisterComponent<ProvidesTrimMaterialComponent>(60, "minecraft:provides_trim_material");
|
||||||
RegisterComponent<OmniousBottleAmplifierComponent>(61, "minecraft:ominous_bottle_amplifier");
|
RegisterComponent<OmniousBottleAmplifierComponent>(61, "minecraft:ominous_bottle_amplifier");
|
||||||
RegisterComponent<JukeBoxPlayableComponent>(62, "minecraft:jukebox_playable");
|
RegisterComponent<JukeBoxPlayableComponent1215>(62, "minecraft:jukebox_playable");
|
||||||
RegisterComponent<ProvidesBannerPatternsComponent>(63, "minecraft:provides_banner_patterns");
|
RegisterComponent<ProvidesBannerPatternsComponent>(63, "minecraft:provides_banner_patterns");
|
||||||
RegisterComponent<RecipesComponent>(64, "minecraft:recipes");
|
RegisterComponent<RecipesComponent>(64, "minecraft:recipes");
|
||||||
RegisterComponent<LodestoneTrackerComponent>(65, "minecraft:lodestone_tracker");
|
RegisterComponent<LodestoneTrackerComponent>(65, "minecraft:lodestone_tracker");
|
||||||
|
|
@ -89,7 +91,7 @@ public class StructuredComponentsRegistry12111 : StructuredComponentRegistry
|
||||||
RegisterComponent<PotDecorationsComponent>(72, "minecraft:pot_decorations");
|
RegisterComponent<PotDecorationsComponent>(72, "minecraft:pot_decorations");
|
||||||
RegisterComponent<ContainerComponent>(73, "minecraft:container");
|
RegisterComponent<ContainerComponent>(73, "minecraft:container");
|
||||||
RegisterComponent<BlockStateComponent>(74, "minecraft:block_state");
|
RegisterComponent<BlockStateComponent>(74, "minecraft:block_state");
|
||||||
RegisterComponent<BeesComponent>(75, "minecraft:bees");
|
RegisterComponent<BeesComponent1219>(75, "minecraft:bees");
|
||||||
RegisterComponent<LockComponent>(76, "minecraft:lock");
|
RegisterComponent<LockComponent>(76, "minecraft:lock");
|
||||||
RegisterComponent<ContainerLootComponent>(77, "minecraft:container_loot");
|
RegisterComponent<ContainerLootComponent>(77, "minecraft:container_loot");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ public class StructuredComponentsRegistry1212 : StructuredComponentRegistry
|
||||||
RegisterComponent<CanPlaceOnComponent>(11, "minecraft:can_place_on");
|
RegisterComponent<CanPlaceOnComponent>(11, "minecraft:can_place_on");
|
||||||
RegisterComponent<CanBreakComponent>(12, "minecraft:can_break");
|
RegisterComponent<CanBreakComponent>(12, "minecraft:can_break");
|
||||||
RegisterComponent<AttributeModifiersComponent>(13, "minecraft:attribute_modifiers");
|
RegisterComponent<AttributeModifiersComponent>(13, "minecraft:attribute_modifiers");
|
||||||
RegisterComponent<CustomModelDataComponent>(14, "minecraft:custom_model_data");
|
RegisterComponent<CustomModelDataComponent1206>(14, "minecraft:custom_model_data");
|
||||||
RegisterComponent<HideAdditionalTooltipComponent>(15, "minecraft:hide_additional_tooltip");
|
RegisterComponent<HideAdditionalTooltipComponent>(15, "minecraft:hide_additional_tooltip");
|
||||||
RegisterComponent<HideTooltipComponent>(16, "minecraft:hide_tooltip");
|
RegisterComponent<HideTooltipComponent>(16, "minecraft:hide_tooltip");
|
||||||
RegisterComponent<RepairCostComponent>(17, "minecraft:repair_cost");
|
RegisterComponent<RepairCostComponent>(17, "minecraft:repair_cost");
|
||||||
|
|
@ -52,7 +52,7 @@ public class StructuredComponentsRegistry1212 : StructuredComponentRegistry
|
||||||
RegisterComponent<MapPostProcessingComponent>(38, "minecraft:map_post_processing");
|
RegisterComponent<MapPostProcessingComponent>(38, "minecraft:map_post_processing");
|
||||||
RegisterComponent<ChargedProjectilesComponent>(39, "minecraft:charged_projectiles");
|
RegisterComponent<ChargedProjectilesComponent>(39, "minecraft:charged_projectiles");
|
||||||
RegisterComponent<BundleContentsComponent>(40, "minecraft:bundle_contents");
|
RegisterComponent<BundleContentsComponent>(40, "minecraft:bundle_contents");
|
||||||
RegisterComponent<PotionContentsComponent>(41, "minecraft:potion_contents");
|
RegisterComponent<PotionContentsComponent1212>(41, "minecraft:potion_contents");
|
||||||
RegisterComponent<SuspiciousStewEffectsComponent>(42, "minecraft:suspicious_stew_effects");
|
RegisterComponent<SuspiciousStewEffectsComponent>(42, "minecraft:suspicious_stew_effects");
|
||||||
RegisterComponent<WritableBlookContentComponent>(43, "minecraft:writable_book_content");
|
RegisterComponent<WritableBlookContentComponent>(43, "minecraft:writable_book_content");
|
||||||
RegisterComponent<WrittenBlookContentComponent>(44, "minecraft:written_book_content");
|
RegisterComponent<WrittenBlookContentComponent>(44, "minecraft:written_book_content");
|
||||||
|
|
@ -63,7 +63,7 @@ public class StructuredComponentsRegistry1212 : StructuredComponentRegistry
|
||||||
RegisterComponent<BlockEntityDataComponent>(49, "minecraft:block_entity_data");
|
RegisterComponent<BlockEntityDataComponent>(49, "minecraft:block_entity_data");
|
||||||
RegisterComponent<InstrumentComponent>(50, "minecraft:instrument");
|
RegisterComponent<InstrumentComponent>(50, "minecraft:instrument");
|
||||||
RegisterComponent<OmniousBottleAmplifierComponent>(51, "minecraft:ominous_bottle_amplifier");
|
RegisterComponent<OmniousBottleAmplifierComponent>(51, "minecraft:ominous_bottle_amplifier");
|
||||||
RegisterComponent<JukeBoxPlayableComponent>(52, "minecraft:jukebox_playable");
|
RegisterComponent<JukeBoxPlayableComponent121>(52, "minecraft:jukebox_playable");
|
||||||
RegisterComponent<RecipesComponent>(53, "minecraft:recipes");
|
RegisterComponent<RecipesComponent>(53, "minecraft:recipes");
|
||||||
RegisterComponent<LodestoneTrackerComponent>(54, "minecraft:lodestone_tracker");
|
RegisterComponent<LodestoneTrackerComponent>(54, "minecraft:lodestone_tracker");
|
||||||
RegisterComponent<FireworkExplosionComponent>(55, "minecraft:firework_explosion");
|
RegisterComponent<FireworkExplosionComponent>(55, "minecraft:firework_explosion");
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6;
|
||||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21;
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21;
|
||||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5;
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_8;
|
||||||
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_9;
|
||||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||||
|
|
||||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries;
|
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries;
|
||||||
|
|
@ -13,6 +15,9 @@ public class StructuredComponentsRegistry1215 : StructuredComponentRegistry
|
||||||
public StructuredComponentsRegistry1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
public StructuredComponentsRegistry1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||||
: base(dataTypes, itemPalette, subComponentRegistry)
|
: base(dataTypes, itemPalette, subComponentRegistry)
|
||||||
{
|
{
|
||||||
|
var uses1218AttributeAndEquippableFormats = dataTypes.ProtocolVersion >= Protocol18Handler.MC_1_21_6_Version;
|
||||||
|
var usesTypedBeesFormat = dataTypes.ProtocolVersion >= Protocol18Handler.MC_1_21_9_Version;
|
||||||
|
|
||||||
RegisterComponent<CustomDataComponent>(0, "minecraft:custom_data");
|
RegisterComponent<CustomDataComponent>(0, "minecraft:custom_data");
|
||||||
RegisterComponent<MaxStackSizeComponent>(1, "minecraft:max_stack_size");
|
RegisterComponent<MaxStackSizeComponent>(1, "minecraft:max_stack_size");
|
||||||
RegisterComponent<MaxDamageComponent>(2, "minecraft:max_damage");
|
RegisterComponent<MaxDamageComponent>(2, "minecraft:max_damage");
|
||||||
|
|
@ -26,7 +31,10 @@ public class StructuredComponentsRegistry1215 : StructuredComponentRegistry
|
||||||
RegisterComponent<EnchantmentsComponent1215>(10, "minecraft:enchantments");
|
RegisterComponent<EnchantmentsComponent1215>(10, "minecraft:enchantments");
|
||||||
RegisterComponent<CanPlaceOnComponent>(11, "minecraft:can_place_on");
|
RegisterComponent<CanPlaceOnComponent>(11, "minecraft:can_place_on");
|
||||||
RegisterComponent<CanBreakComponent>(12, "minecraft:can_break");
|
RegisterComponent<CanBreakComponent>(12, "minecraft:can_break");
|
||||||
RegisterComponent<AttributeModifiersComponent>(13, "minecraft:attribute_modifiers");
|
if (uses1218AttributeAndEquippableFormats)
|
||||||
|
RegisterComponent<AttributeModifiersComponent1218>(13, "minecraft:attribute_modifiers");
|
||||||
|
else
|
||||||
|
RegisterComponent<AttributeModifiersComponent1215>(13, "minecraft:attribute_modifiers");
|
||||||
RegisterComponent<CustomModelDataComponent>(14, "minecraft:custom_model_data");
|
RegisterComponent<CustomModelDataComponent>(14, "minecraft:custom_model_data");
|
||||||
// 15: tooltip_display (NEW, replaces hide_additional_tooltip + hide_tooltip)
|
// 15: tooltip_display (NEW, replaces hide_additional_tooltip + hide_tooltip)
|
||||||
RegisterComponent<TooltipDisplayComponent>(15, "minecraft:tooltip_display");
|
RegisterComponent<TooltipDisplayComponent>(15, "minecraft:tooltip_display");
|
||||||
|
|
@ -39,10 +47,13 @@ public class StructuredComponentsRegistry1215 : StructuredComponentRegistry
|
||||||
RegisterComponent<UseRemainderComponent>(22, "minecraft:use_remainder");
|
RegisterComponent<UseRemainderComponent>(22, "minecraft:use_remainder");
|
||||||
RegisterComponent<UseCooldownComponent>(23, "minecraft:use_cooldown");
|
RegisterComponent<UseCooldownComponent>(23, "minecraft:use_cooldown");
|
||||||
RegisterComponent<DamageResistantComponent>(24, "minecraft:damage_resistant");
|
RegisterComponent<DamageResistantComponent>(24, "minecraft:damage_resistant");
|
||||||
RegisterComponent<ToolComponent>(25, "minecraft:tool");
|
RegisterComponent<ToolComponent1215>(25, "minecraft:tool");
|
||||||
RegisterComponent<WeaponComponent>(26, "minecraft:weapon"); // NEW
|
RegisterComponent<WeaponComponent>(26, "minecraft:weapon"); // NEW
|
||||||
RegisterComponent<EnchantableComponent>(27, "minecraft:enchantable");
|
RegisterComponent<EnchantableComponent>(27, "minecraft:enchantable");
|
||||||
RegisterComponent<EquippableComponent>(28, "minecraft:equippable");
|
if (uses1218AttributeAndEquippableFormats)
|
||||||
|
RegisterComponent<EquippableComponent1218>(28, "minecraft:equippable");
|
||||||
|
else
|
||||||
|
RegisterComponent<EquippableComponent1215>(28, "minecraft:equippable");
|
||||||
RegisterComponent<RepairableComponent>(29, "minecraft:repairable");
|
RegisterComponent<RepairableComponent>(29, "minecraft:repairable");
|
||||||
RegisterComponent<GliderComponent>(30, "minecraft:glider");
|
RegisterComponent<GliderComponent>(30, "minecraft:glider");
|
||||||
RegisterComponent<TooltipStyleComponent>(31, "minecraft:tooltip_style");
|
RegisterComponent<TooltipStyleComponent>(31, "minecraft:tooltip_style");
|
||||||
|
|
@ -56,7 +67,7 @@ public class StructuredComponentsRegistry1215 : StructuredComponentRegistry
|
||||||
RegisterComponent<MapPostProcessingComponent>(39, "minecraft:map_post_processing");
|
RegisterComponent<MapPostProcessingComponent>(39, "minecraft:map_post_processing");
|
||||||
RegisterComponent<ChargedProjectilesComponent>(40, "minecraft:charged_projectiles");
|
RegisterComponent<ChargedProjectilesComponent>(40, "minecraft:charged_projectiles");
|
||||||
RegisterComponent<BundleContentsComponent>(41, "minecraft:bundle_contents");
|
RegisterComponent<BundleContentsComponent>(41, "minecraft:bundle_contents");
|
||||||
RegisterComponent<PotionContentsComponent>(42, "minecraft:potion_contents");
|
RegisterComponent<PotionContentsComponent1212>(42, "minecraft:potion_contents");
|
||||||
RegisterComponent<PotionDurationScaleComponent>(43, "minecraft:potion_duration_scale"); // NEW
|
RegisterComponent<PotionDurationScaleComponent>(43, "minecraft:potion_duration_scale"); // NEW
|
||||||
RegisterComponent<SuspiciousStewEffectsComponent>(44, "minecraft:suspicious_stew_effects");
|
RegisterComponent<SuspiciousStewEffectsComponent>(44, "minecraft:suspicious_stew_effects");
|
||||||
RegisterComponent<WritableBlookContentComponent>(45, "minecraft:writable_book_content");
|
RegisterComponent<WritableBlookContentComponent>(45, "minecraft:writable_book_content");
|
||||||
|
|
@ -69,7 +80,7 @@ public class StructuredComponentsRegistry1215 : StructuredComponentRegistry
|
||||||
RegisterComponent<InstrumentComponent1215>(52, "minecraft:instrument"); // Changed to EitherHolder<Instrument> in 1.21.5
|
RegisterComponent<InstrumentComponent1215>(52, "minecraft:instrument"); // Changed to EitherHolder<Instrument> in 1.21.5
|
||||||
RegisterComponent<ProvidesTrimMaterialComponent>(53, "minecraft:provides_trim_material"); // NEW
|
RegisterComponent<ProvidesTrimMaterialComponent>(53, "minecraft:provides_trim_material"); // NEW
|
||||||
RegisterComponent<OmniousBottleAmplifierComponent>(54, "minecraft:ominous_bottle_amplifier");
|
RegisterComponent<OmniousBottleAmplifierComponent>(54, "minecraft:ominous_bottle_amplifier");
|
||||||
RegisterComponent<JukeBoxPlayableComponent>(55, "minecraft:jukebox_playable");
|
RegisterComponent<JukeBoxPlayableComponent1215>(55, "minecraft:jukebox_playable");
|
||||||
RegisterComponent<ProvidesBannerPatternsComponent>(56, "minecraft:provides_banner_patterns"); // NEW
|
RegisterComponent<ProvidesBannerPatternsComponent>(56, "minecraft:provides_banner_patterns"); // NEW
|
||||||
RegisterComponent<RecipesComponent>(57, "minecraft:recipes");
|
RegisterComponent<RecipesComponent>(57, "minecraft:recipes");
|
||||||
RegisterComponent<LodestoneTrackerComponent>(58, "minecraft:lodestone_tracker");
|
RegisterComponent<LodestoneTrackerComponent>(58, "minecraft:lodestone_tracker");
|
||||||
|
|
@ -82,7 +93,10 @@ public class StructuredComponentsRegistry1215 : StructuredComponentRegistry
|
||||||
RegisterComponent<PotDecorationsComponent>(65, "minecraft:pot_decorations");
|
RegisterComponent<PotDecorationsComponent>(65, "minecraft:pot_decorations");
|
||||||
RegisterComponent<ContainerComponent>(66, "minecraft:container");
|
RegisterComponent<ContainerComponent>(66, "minecraft:container");
|
||||||
RegisterComponent<BlockStateComponent>(67, "minecraft:block_state");
|
RegisterComponent<BlockStateComponent>(67, "minecraft:block_state");
|
||||||
RegisterComponent<BeesComponent>(68, "minecraft:bees"); // Wire format unchanged in 1.21.5
|
if (usesTypedBeesFormat)
|
||||||
|
RegisterComponent<BeesComponent1219>(68, "minecraft:bees");
|
||||||
|
else
|
||||||
|
RegisterComponent<BeesComponent>(68, "minecraft:bees");
|
||||||
RegisterComponent<LockComponent>(69, "minecraft:lock");
|
RegisterComponent<LockComponent>(69, "minecraft:lock");
|
||||||
RegisterComponent<ContainerLootComponent>(70, "minecraft:container_loot");
|
RegisterComponent<ContainerLootComponent>(70, "minecraft:container_loot");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,4 +48,16 @@ public class StructuredComponentsHandler
|
||||||
{
|
{
|
||||||
return ComponentRegistry.ParseComponent(componentId, data);
|
return ComponentRegistry.ParseComponent(componentId, data);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public string GetComponentName(int componentId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ComponentRegistry.GetComponentNameById(componentId);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return "<unknown>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="AppVars.Variables" xml:space="preserve">
|
<data name="AppVars.Variables" xml:space="preserve">
|
||||||
<value>can be used in some other fields as %yourvar%
|
<value>can be used in some other fields as %yourvar%
|
||||||
%username% and %serverip% are reserved variables.</value>
|
%username%, %login%, %serverip%, %serverport%, %datetime% and %players% are reserved read-only variables.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ChatBot" xml:space="preserve">
|
<data name="ChatBot" xml:space="preserve">
|
||||||
<value>=============================== #
|
<value>=============================== #
|
||||||
|
|
@ -930,4 +930,4 @@ Note: This does NOT require a Bot Token, only an Application ID. Discord must be
|
||||||
<data name="Main.General.AuthlibUser" xml:space="preserve">
|
<data name="Main.General.AuthlibUser" xml:space="preserve">
|
||||||
<value>Yggdrasil authlib multi-user selection.</value>
|
<value>Yggdrasil authlib multi-user selection.</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,8 @@ namespace MinecraftClient.Scripting.DynamicRun.Builder
|
||||||
// Facade assemblies needed for compiling scripts that reference netstandard libraries (e.g. Brigadier.NET)
|
// Facade assemblies needed for compiling scripts that reference netstandard libraries (e.g. Brigadier.NET)
|
||||||
assemblyrefs.Add(new("netstandard"));
|
assemblyrefs.Add(new("netstandard"));
|
||||||
assemblyrefs.Add(new("System.Runtime"));
|
assemblyrefs.Add(new("System.Runtime"));
|
||||||
|
assemblyrefs.Add(new("System.Private.Uri"));
|
||||||
|
assemblyrefs.Add(new("System.Net.Requests"));
|
||||||
|
|
||||||
foreach (var refs in assemblyrefs) {
|
foreach (var refs in assemblyrefs) {
|
||||||
Assembly? loadedAssembly;
|
Assembly? loadedAssembly;
|
||||||
|
|
@ -180,7 +182,7 @@ namespace MinecraftClient.Scripting.DynamicRun.Builder
|
||||||
// Add facade assemblies needed for Roslyn compilation when referencing
|
// Add facade assemblies needed for Roslyn compilation when referencing
|
||||||
// libraries that target netstandard (e.g. Brigadier.NET).
|
// libraries that target netstandard (e.g. Brigadier.NET).
|
||||||
var runtimeDir = Path.GetDirectoryName(SystemPrivateCoreLib)!;
|
var runtimeDir = Path.GetDirectoryName(SystemPrivateCoreLib)!;
|
||||||
foreach (var facadeName in new[] { "netstandard.dll", "System.Runtime.dll" })
|
foreach (var facadeName in new[] { "netstandard.dll", "System.Runtime.dll", "System.Private.Uri.dll", "System.Net.Requests.dll" })
|
||||||
{
|
{
|
||||||
var facadePath = Path.Combine(runtimeDir, facadeName);
|
var facadePath = Path.Combine(runtimeDir, facadeName);
|
||||||
if (File.Exists(facadePath))
|
if (File.Exists(facadePath))
|
||||||
|
|
|
||||||
|
|
@ -1024,6 +1024,34 @@ namespace MinecraftClient
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
readonly Lock varLock = new();
|
readonly Lock varLock = new();
|
||||||
|
|
||||||
|
private static bool TryGetReadOnlyVar(string varName, [NotNullWhen(true)] out object? varData)
|
||||||
|
{
|
||||||
|
switch (Settings.ToLowerIfNeed(varName))
|
||||||
|
{
|
||||||
|
case "username":
|
||||||
|
varData = InternalConfig.Username;
|
||||||
|
return true;
|
||||||
|
case "login":
|
||||||
|
varData = InternalConfig.Account.Login;
|
||||||
|
return true;
|
||||||
|
case "serverip":
|
||||||
|
varData = InternalConfig.ServerIP;
|
||||||
|
return true;
|
||||||
|
case "serverport":
|
||||||
|
varData = InternalConfig.ServerPort;
|
||||||
|
return true;
|
||||||
|
case "datetime":
|
||||||
|
varData = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
|
return true;
|
||||||
|
case "players":
|
||||||
|
varData = string.Join(", ", McClient.Instance?.GetOnlinePlayers() ?? []);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
varData = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set a custom %variable% which will be available through expandVars()
|
/// Set a custom %variable% which will be available through expandVars()
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -1066,6 +1094,8 @@ namespace MinecraftClient
|
||||||
/// <returns>The value or null if the variable does not exists</returns>
|
/// <returns>The value or null if the variable does not exists</returns>
|
||||||
public object? GetVar(string varName)
|
public object? GetVar(string varName)
|
||||||
{
|
{
|
||||||
|
if (TryGetReadOnlyVar(varName, out object? readOnlyVar))
|
||||||
|
return readOnlyVar;
|
||||||
if (VarStirng.TryGetValue(varName, out string? valueString))
|
if (VarStirng.TryGetValue(varName, out string? valueString))
|
||||||
return valueString;
|
return valueString;
|
||||||
else if (VarObject.TryGetValue(varName, out object? valueObject))
|
else if (VarObject.TryGetValue(varName, out object? valueObject))
|
||||||
|
|
@ -1081,6 +1111,8 @@ namespace MinecraftClient
|
||||||
/// <returns>The value or null if the variable does not exists</returns>
|
/// <returns>The value or null if the variable does not exists</returns>
|
||||||
public bool TryGetVar(string varName, [NotNullWhen(true)] out object? varData)
|
public bool TryGetVar(string varName, [NotNullWhen(true)] out object? varData)
|
||||||
{
|
{
|
||||||
|
if (TryGetReadOnlyVar(varName, out varData))
|
||||||
|
return true;
|
||||||
if (VarStirng.TryGetValue(varName, out string? valueString))
|
if (VarStirng.TryGetValue(varName, out string? valueString))
|
||||||
{
|
{
|
||||||
varData = valueString;
|
varData = valueString;
|
||||||
|
|
@ -1142,32 +1174,22 @@ namespace MinecraftClient
|
||||||
string varname = var_name.ToString();
|
string varname = var_name.ToString();
|
||||||
string varname_lower = Settings.ToLowerIfNeed(varname);
|
string varname_lower = Settings.ToLowerIfNeed(varname);
|
||||||
i = i + varname.Length + 1;
|
i = i + varname.Length + 1;
|
||||||
|
|
||||||
switch (varname_lower)
|
if (TryGetReadOnlyVar(varname_lower, out object? readOnlyVar))
|
||||||
{
|
{
|
||||||
case "username": result.Append(InternalConfig.Username); break;
|
result.Append(readOnlyVar.ToString());
|
||||||
case "login": result.Append(InternalConfig.Account.Login); break;
|
}
|
||||||
case "serverip": result.Append(InternalConfig.ServerIP); break;
|
else if (localVars is not null && localVars.ContainsKey(varname_lower))
|
||||||
case "serverport": result.Append(InternalConfig.ServerPort); break;
|
{
|
||||||
case "datetime":
|
result.Append(localVars[varname_lower].ToString());
|
||||||
DateTime time = DateTime.Now;
|
}
|
||||||
result.Append(String.Format("{0}-{1}-{2} {3}:{4}:{5}",
|
else if (TryGetVar(varname_lower, out object? var_value))
|
||||||
time.Year.ToString("0000"),
|
{
|
||||||
time.Month.ToString("00"),
|
result.Append(var_value.ToString());
|
||||||
time.Day.ToString("00"),
|
}
|
||||||
time.Hour.ToString("00"),
|
else
|
||||||
time.Minute.ToString("00"),
|
{
|
||||||
time.Second.ToString("00")));
|
result.Append("%" + varname + '%');
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (localVars is not null && localVars.ContainsKey(varname_lower))
|
|
||||||
result.Append(localVars[varname_lower].ToString());
|
|
||||||
else if (TryGetVar(varname_lower, out object? var_value))
|
|
||||||
result.Append(var_value.ToString());
|
|
||||||
else
|
|
||||||
result.Append("%" + varname + '%');
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else result.Append(str[i]);
|
else result.Append(str[i]);
|
||||||
|
|
|
||||||
|
|
@ -5,30 +5,19 @@ MCC.LogToConsole(mojangStatus);
|
||||||
|
|
||||||
//MCCScript Extensions
|
//MCCScript Extensions
|
||||||
|
|
||||||
|
private static readonly System.Net.Http.HttpClient s_httpClient = new();
|
||||||
|
|
||||||
string PerformHttpRequest(string uri)
|
string PerformHttpRequest(string uri)
|
||||||
{
|
{
|
||||||
var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
|
return s_httpClient.GetStringAsync(uri).GetAwaiter().GetResult();
|
||||||
var response = (System.Net.HttpWebResponse)request.GetResponse();
|
|
||||||
string responseString;
|
|
||||||
using (var stream = response.GetResponseStream())
|
|
||||||
using (var reader = new StreamReader(stream))
|
|
||||||
responseString = reader.ReadToEnd();
|
|
||||||
return responseString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendHttpPostAsync(string uri, string text)
|
void SendHttpPostAsync(string uri, string text)
|
||||||
{
|
{
|
||||||
new Thread(() => {
|
new Thread(() => {
|
||||||
var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
|
using var content = new System.Net.Http.StringContent(text, System.Text.Encoding.UTF8, "text/plain");
|
||||||
request.ContentType = "text/plain";
|
using var response = s_httpClient.PostAsync(uri, content).GetAwaiter().GetResult();
|
||||||
request.Method = "POST";
|
string responseString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||||
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
|
|
||||||
streamWriter.Write(text);
|
|
||||||
var response = (System.Net.HttpWebResponse)request.GetResponse();
|
|
||||||
string responseString;
|
|
||||||
using (var stream = response.GetResponseStream())
|
|
||||||
using (var reader = new StreamReader(stream))
|
|
||||||
responseString = reader.ReadToEnd();
|
|
||||||
//LogToConsole(responseString);
|
//LogToConsole(responseString);
|
||||||
}).Start();
|
}).Start();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1066,7 +1066,7 @@ Coordinate = { x = 145, y = 64, z = 2045 }
|
||||||
|
|
||||||
<div class="custom-container tip"><p class="custom-container-title">Tip</p>
|
<div class="custom-container tip"><p class="custom-container-title">Tip</p>
|
||||||
|
|
||||||
**`%username%`, `%serverip%`, `%datetime%` are reserved variables**
|
**`%username%`, `%login%`, `%serverip%`, `%serverport%`, `%datetime%`, `%players%` are reserved read-only variables**
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ title: Creating Simple Script
|
||||||
|
|
||||||
A simple script is a text file with one command per line. See the [Internal Commands](usage.md#internal-commands) section, or type `/help` in the console to see the available commands. Any line beginning with `#` is ignored and treated as a comment.
|
A simple script is a text file with one command per line. See the [Internal Commands](usage.md#internal-commands) section, or type `/help` in the console to see the available commands. Any line beginning with `#` is ignored and treated as a comment.
|
||||||
|
|
||||||
Application variables defined with the `set` command or in the `[AppVars]` config section can be used. The following read-only variables are also available: `%username%`, `%login%`, `%serverip%`, `%serverport%`, `%datetime%`.
|
Application variables defined with the `set` command or in the `[AppVars]` config section can be used. The following read-only variables are also available: `%username%`, `%login%`, `%serverip%`, `%serverport%`, `%datetime%`, `%players%` (`%players%` expands to the current online player names separated by commas, or an empty string when not connected).
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue