mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
feat: add packet palette, data components, and protocol fixes for MC 1.21.2
Packet Palette (Phase 2.1): - Create PacketPalette1212.cs with complete ID mapping for protocol 768 (131 clientbound + 60 serverbound play packets, plus config packets) - Add new PacketTypesIn enum values: EntityPositionSync, MoveMinecartAlongTrack, PlayerRotation, RecipeBookAdd/Remove/Settings, SetCursorItem, SetHeldSlot, SetPlayerInventory - Add new PacketTypesOut enum values: BundleItemSelected, ClientTickEnd - Update PacketType18Handler routing for 1.21.2 Data Components (Phase 1.4): - Create StructuredComponentsRegistry1212 with 67 components (was 57 in 1.21) reflecting the new 1.21.2 DataComponents ordering - Implement 11 new component parsers: ConsumableComponent, UseRemainderComponent, UseCooldownComponent, DamageResistantComponent, EnchantableComponent, EquippableComponent, RepairableComponent, GliderComponent, TooltipStyleComponent, DeathProtectionComponent, ItemModelComponent - Create FoodComponent1212 (simplified: nutrition/saturation/canAlwaysEat only; eatSeconds/effects/usingConvertsTo moved to consumable/use_remainder) - Create SubComponentRegistry1212 and route in StructuredComponentsHandler Protocol Fixes: - Fix PlayerPositionAndLook packet for 1.21.2 (new format: teleportId first, added deltaMovement Vec3, flags as Int instead of Byte) - Fix login success packet (remove strictErrorHandling read for >= 1.21.2) - Fix ClientSettings/ClientInformation packet (add particleStatus VarInt) - Add SetHeldSlot as alias for HeldItemChange in packet handler Verified: MCC connects to 1.21.2 vanilla server, stays connected, chat works. Made-with: Cursor
This commit is contained in:
parent
df833ae2a8
commit
57a0dedb33
20 changed files with 953 additions and 33 deletions
|
|
@ -0,0 +1,129 @@
|
|||
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_2;
|
||||
|
||||
public class ConsumableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public float ConsumeSeconds { get; set; }
|
||||
public int Animation { get; set; }
|
||||
public SoundEventSubComponent? Sound { get; set; }
|
||||
public bool HasConsumeParticles { get; set; }
|
||||
public List<ConsumeEffectData> Effects { get; set; } = new();
|
||||
|
||||
public override void Parse(Queue<byte> data)
|
||||
{
|
||||
ConsumeSeconds = dataTypes.ReadNextFloat(data);
|
||||
Animation = dataTypes.ReadNextVarInt(data);
|
||||
Sound = (SoundEventSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
|
||||
HasConsumeParticles = dataTypes.ReadNextBool(data);
|
||||
|
||||
var effectCount = dataTypes.ReadNextVarInt(data);
|
||||
for (var i = 0; i < effectCount; i++)
|
||||
{
|
||||
var effectTypeId = dataTypes.ReadNextVarInt(data);
|
||||
var effectData = ReadConsumeEffectPayload(effectTypeId, data);
|
||||
Effects.Add(new ConsumeEffectData(effectTypeId, effectData));
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] ReadConsumeEffectPayload(int effectTypeId, Queue<byte> data)
|
||||
{
|
||||
var payload = new List<byte>();
|
||||
switch (effectTypeId)
|
||||
{
|
||||
case 0: // apply_effects: List<MobEffectInstance> + probability(float)
|
||||
var effectCount = dataTypes.ReadNextVarInt(data);
|
||||
payload.AddRange(DataTypes.GetVarInt(effectCount));
|
||||
for (var i = 0; i < effectCount; i++)
|
||||
payload.AddRange(ReadMobEffectInstance(data));
|
||||
payload.AddRange(DataTypes.GetFloat(dataTypes.ReadNextFloat(data)));
|
||||
break;
|
||||
case 1: // remove_effects: HolderSet<MobEffect>
|
||||
payload.AddRange(ReadHolderSet(data));
|
||||
break;
|
||||
case 2: // clear_all_effects: empty
|
||||
break;
|
||||
case 3: // teleport_randomly: float diameter
|
||||
payload.AddRange(DataTypes.GetFloat(dataTypes.ReadNextFloat(data)));
|
||||
break;
|
||||
case 4: // play_sound: Holder<SoundEvent>
|
||||
var sound = (SoundEventSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
|
||||
payload.AddRange(sound.Serialize());
|
||||
break;
|
||||
}
|
||||
return payload.ToArray();
|
||||
}
|
||||
|
||||
private byte[] ReadMobEffectInstance(Queue<byte> data)
|
||||
{
|
||||
var result = new List<byte>();
|
||||
var effectId = dataTypes.ReadNextVarInt(data);
|
||||
result.AddRange(DataTypes.GetVarInt(effectId));
|
||||
result.AddRange(ReadMobEffectDetails(data));
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private byte[] ReadMobEffectDetails(Queue<byte> data)
|
||||
{
|
||||
var result = new List<byte>();
|
||||
var amplifier = dataTypes.ReadNextVarInt(data);
|
||||
result.AddRange(DataTypes.GetVarInt(amplifier));
|
||||
var duration = dataTypes.ReadNextVarInt(data);
|
||||
result.AddRange(DataTypes.GetVarInt(duration));
|
||||
var ambient = dataTypes.ReadNextBool(data);
|
||||
result.AddRange(DataTypes.GetBool(ambient));
|
||||
var showParticles = dataTypes.ReadNextBool(data);
|
||||
result.AddRange(DataTypes.GetBool(showParticles));
|
||||
var showIcon = dataTypes.ReadNextBool(data);
|
||||
result.AddRange(DataTypes.GetBool(showIcon));
|
||||
var hasHiddenEffect = dataTypes.ReadNextBool(data);
|
||||
result.AddRange(DataTypes.GetBool(hasHiddenEffect));
|
||||
if (hasHiddenEffect)
|
||||
result.AddRange(ReadMobEffectDetails(data));
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private byte[] ReadHolderSet(Queue<byte> data)
|
||||
{
|
||||
var result = new List<byte>();
|
||||
var type = dataTypes.ReadNextVarInt(data);
|
||||
result.AddRange(DataTypes.GetVarInt(type));
|
||||
if (type == 0)
|
||||
{
|
||||
var tagName = dataTypes.ReadNextString(data);
|
||||
result.AddRange(DataTypes.GetString(tagName));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < type - 1; i++)
|
||||
{
|
||||
var id = dataTypes.ReadNextVarInt(data);
|
||||
result.AddRange(DataTypes.GetVarInt(id));
|
||||
}
|
||||
}
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetFloat(ConsumeSeconds));
|
||||
data.AddRange(DataTypes.GetVarInt(Animation));
|
||||
if (Sound != null) data.AddRange(Sound.Serialize());
|
||||
data.AddRange(DataTypes.GetBool(HasConsumeParticles));
|
||||
data.AddRange(DataTypes.GetVarInt(Effects.Count));
|
||||
foreach (var effect in Effects)
|
||||
{
|
||||
data.AddRange(DataTypes.GetVarInt(effect.EffectTypeId));
|
||||
data.AddRange(effect.Payload);
|
||||
}
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
|
||||
public record ConsumeEffectData(int EffectTypeId, byte[] Payload);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections.Generic;
|
||||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||
|
||||
public class DamageResistantComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public string Types { get; set; } = null!;
|
||||
|
||||
public override void Parse(Queue<byte> data)
|
||||
{
|
||||
Types = dataTypes.ReadNextString(data);
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetString(Types));
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
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_2;
|
||||
|
||||
public class DeathProtectionComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public List<ConsumeEffectData> DeathEffects { get; set; } = new();
|
||||
|
||||
public override void Parse(Queue<byte> data)
|
||||
{
|
||||
var effectCount = dataTypes.ReadNextVarInt(data);
|
||||
for (var i = 0; i < effectCount; i++)
|
||||
{
|
||||
var effectTypeId = dataTypes.ReadNextVarInt(data);
|
||||
var effectData = ReadConsumeEffectPayload(effectTypeId, data);
|
||||
DeathEffects.Add(new ConsumeEffectData(effectTypeId, effectData));
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] ReadConsumeEffectPayload(int effectTypeId, Queue<byte> data)
|
||||
{
|
||||
var payload = new List<byte>();
|
||||
switch (effectTypeId)
|
||||
{
|
||||
case 0: // apply_effects
|
||||
var effectCount = dataTypes.ReadNextVarInt(data);
|
||||
payload.AddRange(DataTypes.GetVarInt(effectCount));
|
||||
for (var i = 0; i < effectCount; i++)
|
||||
payload.AddRange(ReadMobEffectInstance(data));
|
||||
payload.AddRange(DataTypes.GetFloat(dataTypes.ReadNextFloat(data)));
|
||||
break;
|
||||
case 1: // remove_effects
|
||||
payload.AddRange(ReadHolderSet(data));
|
||||
break;
|
||||
case 2: // clear_all_effects
|
||||
break;
|
||||
case 3: // teleport_randomly
|
||||
payload.AddRange(DataTypes.GetFloat(dataTypes.ReadNextFloat(data)));
|
||||
break;
|
||||
case 4: // play_sound
|
||||
var sound = (SoundEventSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
|
||||
payload.AddRange(sound.Serialize());
|
||||
break;
|
||||
}
|
||||
return payload.ToArray();
|
||||
}
|
||||
|
||||
private byte[] ReadMobEffectInstance(Queue<byte> data)
|
||||
{
|
||||
var result = new List<byte>();
|
||||
result.AddRange(DataTypes.GetVarInt(dataTypes.ReadNextVarInt(data)));
|
||||
result.AddRange(ReadMobEffectDetails(data));
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private byte[] ReadMobEffectDetails(Queue<byte> data)
|
||||
{
|
||||
var result = new List<byte>();
|
||||
result.AddRange(DataTypes.GetVarInt(dataTypes.ReadNextVarInt(data)));
|
||||
result.AddRange(DataTypes.GetVarInt(dataTypes.ReadNextVarInt(data)));
|
||||
result.AddRange(DataTypes.GetBool(dataTypes.ReadNextBool(data)));
|
||||
result.AddRange(DataTypes.GetBool(dataTypes.ReadNextBool(data)));
|
||||
result.AddRange(DataTypes.GetBool(dataTypes.ReadNextBool(data)));
|
||||
var hasHidden = dataTypes.ReadNextBool(data);
|
||||
result.AddRange(DataTypes.GetBool(hasHidden));
|
||||
if (hasHidden)
|
||||
result.AddRange(ReadMobEffectDetails(data));
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private byte[] ReadHolderSet(Queue<byte> data)
|
||||
{
|
||||
var result = new List<byte>();
|
||||
var type = dataTypes.ReadNextVarInt(data);
|
||||
result.AddRange(DataTypes.GetVarInt(type));
|
||||
if (type == 0)
|
||||
{
|
||||
result.AddRange(DataTypes.GetString(dataTypes.ReadNextString(data)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < type - 1; i++)
|
||||
result.AddRange(DataTypes.GetVarInt(dataTypes.ReadNextVarInt(data)));
|
||||
}
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetVarInt(DeathEffects.Count));
|
||||
foreach (var effect in DeathEffects)
|
||||
{
|
||||
data.AddRange(DataTypes.GetVarInt(effect.EffectTypeId));
|
||||
data.AddRange(effect.Payload);
|
||||
}
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
|
||||
public record ConsumeEffectData(int EffectTypeId, byte[] Payload);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections.Generic;
|
||||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||
|
||||
public class EnchantableComponent(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()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetVarInt(Value));
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
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_2;
|
||||
|
||||
public class EquippableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public int Slot { get; set; }
|
||||
public SoundEventSubComponent? EquipSound { get; set; }
|
||||
public bool HasModel { get; set; }
|
||||
public string? Model { 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 override void Parse(Queue<byte> data)
|
||||
{
|
||||
Slot = dataTypes.ReadNextVarInt(data);
|
||||
EquipSound = (SoundEventSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data);
|
||||
|
||||
HasModel = dataTypes.ReadNextBool(data);
|
||||
if (HasModel)
|
||||
Model = 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
AllowedEntitiesIds = new List<int>();
|
||||
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);
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetVarInt(Slot));
|
||||
if (EquipSound != null) data.AddRange(EquipSound.Serialize());
|
||||
|
||||
data.AddRange(DataTypes.GetBool(HasModel));
|
||||
if (HasModel && Model != null)
|
||||
data.AddRange(DataTypes.GetString(Model));
|
||||
|
||||
data.AddRange(DataTypes.GetBool(HasCameraOverlay));
|
||||
if (HasCameraOverlay && CameraOverlay != null)
|
||||
data.AddRange(DataTypes.GetString(CameraOverlay));
|
||||
|
||||
data.AddRange(DataTypes.GetBool(HasAllowedEntities));
|
||||
if (HasAllowedEntities)
|
||||
{
|
||||
data.AddRange(DataTypes.GetVarInt(AllowedEntitiesType));
|
||||
if (AllowedEntitiesType == 0 && AllowedEntitiesTag != null)
|
||||
{
|
||||
data.AddRange(DataTypes.GetString(AllowedEntitiesTag));
|
||||
}
|
||||
else if (AllowedEntitiesIds != 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));
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using System.Collections.Generic;
|
||||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||
|
||||
public class FoodComponent1212(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public int Nutrition { get; set; }
|
||||
public float Saturation { get; set; }
|
||||
public bool CanAlwaysEat { get; set; }
|
||||
|
||||
public override void Parse(Queue<byte> data)
|
||||
{
|
||||
Nutrition = dataTypes.ReadNextVarInt(data);
|
||||
Saturation = dataTypes.ReadNextFloat(data);
|
||||
CanAlwaysEat = dataTypes.ReadNextBool(data);
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetVarInt(Nutrition));
|
||||
data.AddRange(DataTypes.GetFloat(Saturation));
|
||||
data.AddRange(DataTypes.GetBool(CanAlwaysEat));
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||
|
||||
public class GliderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: EmptyComponent(dataTypes, itemPalette, subComponentRegistry);
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections.Generic;
|
||||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||
|
||||
public class ItemModelComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public string Identifier { get; set; } = null!;
|
||||
|
||||
public override void Parse(Queue<byte> data)
|
||||
{
|
||||
Identifier = dataTypes.ReadNextString(data);
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetString(Identifier));
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
using System.Collections.Generic;
|
||||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||
|
||||
public class RepairableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public int Type { get; set; }
|
||||
public string? TagName { get; set; }
|
||||
public List<int>? ItemIds { get; set; }
|
||||
|
||||
public override void Parse(Queue<byte> data)
|
||||
{
|
||||
Type = dataTypes.ReadNextVarInt(data);
|
||||
if (Type == 0)
|
||||
{
|
||||
TagName = dataTypes.ReadNextString(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemIds = new List<int>();
|
||||
for (var i = 0; i < Type - 1; i++)
|
||||
ItemIds.Add(dataTypes.ReadNextVarInt(data));
|
||||
}
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetVarInt(Type));
|
||||
if (Type == 0 && TagName != null)
|
||||
{
|
||||
data.AddRange(DataTypes.GetString(TagName));
|
||||
}
|
||||
else if (ItemIds != null)
|
||||
{
|
||||
foreach (var id in ItemIds)
|
||||
data.AddRange(DataTypes.GetVarInt(id));
|
||||
}
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections.Generic;
|
||||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||
|
||||
public class TooltipStyleComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public string Identifier { get; set; } = null!;
|
||||
|
||||
public override void Parse(Queue<byte> data)
|
||||
{
|
||||
Identifier = dataTypes.ReadNextString(data);
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetString(Identifier));
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
using System.Collections.Generic;
|
||||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||
|
||||
public class UseCooldownComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public float Seconds { get; set; }
|
||||
public bool HasCooldownGroup { get; set; }
|
||||
public string? CooldownGroup { get; set; }
|
||||
|
||||
public override void Parse(Queue<byte> data)
|
||||
{
|
||||
Seconds = dataTypes.ReadNextFloat(data);
|
||||
HasCooldownGroup = dataTypes.ReadNextBool(data);
|
||||
if (HasCooldownGroup)
|
||||
CooldownGroup = dataTypes.ReadNextString(data);
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(DataTypes.GetFloat(Seconds));
|
||||
data.AddRange(DataTypes.GetBool(HasCooldownGroup));
|
||||
if (HasCooldownGroup && CooldownGroup != null)
|
||||
data.AddRange(DataTypes.GetString(CooldownGroup));
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
using System.Collections.Generic;
|
||||
using MinecraftClient.Inventory;
|
||||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2;
|
||||
|
||||
public class UseRemainderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: StructuredComponent(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
public Item? ConvertInto { get; set; }
|
||||
|
||||
public override void Parse(Queue<byte> data)
|
||||
{
|
||||
ConvertInto = dataTypes.ReadNextItemSlot(data, ItemPalette);
|
||||
}
|
||||
|
||||
public override Queue<byte> Serialize()
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddRange(dataTypes.GetItemSlot(ConvertInto, ItemPalette));
|
||||
return new Queue<byte>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
using MinecraftClient.Inventory.ItemPalettes;
|
||||
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_2;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries;
|
||||
|
||||
public class StructuredComponentsRegistry1212 : StructuredComponentRegistry
|
||||
{
|
||||
public StructuredComponentsRegistry1212(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry)
|
||||
: base(dataTypes, itemPalette, subComponentRegistry)
|
||||
{
|
||||
RegisterComponent<CustomDataComponent>(0, "minecraft:custom_data");
|
||||
RegisterComponent<MaxStackSizeComponent>(1, "minecraft:max_stack_size");
|
||||
RegisterComponent<MaxDamageComponent>(2, "minecraft:max_damage");
|
||||
RegisterComponent<DamageComponent>(3, "minecraft:damage");
|
||||
RegisterComponent<UnbrekableComponent1206>(4, "minecraft:unbreakable");
|
||||
RegisterComponent<CustomNameComponent>(5, "minecraft:custom_name");
|
||||
RegisterComponent<ItemNameComponent>(6, "minecraft:item_name");
|
||||
RegisterComponent<ItemModelComponent>(7, "minecraft:item_model");
|
||||
RegisterComponent<LoreNameComponent1206>(8, "minecraft:lore");
|
||||
RegisterComponent<RarityComponent>(9, "minecraft:rarity");
|
||||
RegisterComponent<EnchantmentsComponent>(10, "minecraft:enchantments");
|
||||
RegisterComponent<CanPlaceOnComponent>(11, "minecraft:can_place_on");
|
||||
RegisterComponent<CanBreakComponent>(12, "minecraft:can_break");
|
||||
RegisterComponent<AttributeModifiersComponent>(13, "minecraft:attribute_modifiers");
|
||||
RegisterComponent<CustomModelDataComponent>(14, "minecraft:custom_model_data");
|
||||
RegisterComponent<HideAdditionalTooltipComponent>(15, "minecraft:hide_additional_tooltip");
|
||||
RegisterComponent<HideTooltipComponent>(16, "minecraft:hide_tooltip");
|
||||
RegisterComponent<RepairCostComponent>(17, "minecraft:repair_cost");
|
||||
RegisterComponent<CreativeSlotLockComponent>(18, "minecraft:creative_slot_lock");
|
||||
RegisterComponent<EnchantmentGlintOverrideComponent>(19, "minecraft:enchantment_glint_override");
|
||||
RegisterComponent<IntangibleProjectileComponent>(20, "minecraft:intangible_projectile");
|
||||
RegisterComponent<FoodComponent1212>(21, "minecraft:food");
|
||||
RegisterComponent<ConsumableComponent>(22, "minecraft:consumable");
|
||||
RegisterComponent<UseRemainderComponent>(23, "minecraft:use_remainder");
|
||||
RegisterComponent<UseCooldownComponent>(24, "minecraft:use_cooldown");
|
||||
RegisterComponent<DamageResistantComponent>(25, "minecraft:damage_resistant");
|
||||
RegisterComponent<ToolComponent>(26, "minecraft:tool");
|
||||
RegisterComponent<EnchantableComponent>(27, "minecraft:enchantable");
|
||||
RegisterComponent<EquippableComponent>(28, "minecraft:equippable");
|
||||
RegisterComponent<RepairableComponent>(29, "minecraft:repairable");
|
||||
RegisterComponent<GliderComponent>(30, "minecraft:glider");
|
||||
RegisterComponent<TooltipStyleComponent>(31, "minecraft:tooltip_style");
|
||||
RegisterComponent<DeathProtectionComponent>(32, "minecraft:death_protection");
|
||||
RegisterComponent<StoredEnchantmentsComponent>(33, "minecraft:stored_enchantments");
|
||||
RegisterComponent<DyeColorComponent>(34, "minecraft:dyed_color");
|
||||
RegisterComponent<MapColorComponent>(35, "minecraft:map_color");
|
||||
RegisterComponent<MapIdComponent>(36, "minecraft:map_id");
|
||||
RegisterComponent<MapDecorationsComponent>(37, "minecraft:map_decorations");
|
||||
RegisterComponent<MapPostProcessingComponent>(38, "minecraft:map_post_processing");
|
||||
RegisterComponent<ChargedProjectilesComponent>(39, "minecraft:charged_projectiles");
|
||||
RegisterComponent<BundleContentsComponent>(40, "minecraft:bundle_contents");
|
||||
RegisterComponent<PotionContentsComponent>(41, "minecraft:potion_contents");
|
||||
RegisterComponent<SuspiciousStewEffectsComponent>(42, "minecraft:suspicious_stew_effects");
|
||||
RegisterComponent<WritableBlookContentComponent>(43, "minecraft:writable_book_content");
|
||||
RegisterComponent<WrittenBlookContentComponent>(44, "minecraft:written_book_content");
|
||||
RegisterComponent<TrimComponent>(45, "minecraft:trim");
|
||||
RegisterComponent<DebugStickStateComponent>(46, "minecraft:debug_stick_state");
|
||||
RegisterComponent<EntityDataComponent>(47, "minecraft:entity_data");
|
||||
RegisterComponent<BucketEntityDataComponent>(48, "minecraft:bucket_entity_data");
|
||||
RegisterComponent<BlockEntityDataComponent>(49, "minecraft:block_entity_data");
|
||||
RegisterComponent<InstrumentComponent>(50, "minecraft:instrument");
|
||||
RegisterComponent<OmniousBottleAmplifierComponent>(51, "minecraft:ominous_bottle_amplifier");
|
||||
RegisterComponent<JukeBoxPlayableComponent>(52, "minecraft:jukebox_playable");
|
||||
RegisterComponent<RecipesComponent>(53, "minecraft:recipes");
|
||||
RegisterComponent<LodestoneTrackerComponent>(54, "minecraft:lodestone_tracker");
|
||||
RegisterComponent<FireworkExplosionComponent>(55, "minecraft:firework_explosion");
|
||||
RegisterComponent<FireworksComponent>(56, "minecraft:fireworks");
|
||||
RegisterComponent<ProfileComponent>(57, "minecraft:profile");
|
||||
RegisterComponent<NoteBlockSoundComponent>(58, "minecraft:note_block_sound");
|
||||
RegisterComponent<BannerPatternsComponent>(59, "minecraft:banner_patterns");
|
||||
RegisterComponent<BaseColorComponent>(60, "minecraft:base_color");
|
||||
RegisterComponent<PotDecorationsComponent>(61, "minecraft:pot_decorations");
|
||||
RegisterComponent<ContainerComponent>(62, "minecraft:container");
|
||||
RegisterComponent<BlockStateComponent>(63, "minecraft:block_state");
|
||||
RegisterComponent<BeesComponent>(64, "minecraft:bees");
|
||||
RegisterComponent<LockComponent>(65, "minecraft:lock");
|
||||
RegisterComponent<ContainerLootComponent>(66, "minecraft:container_loot");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21;
|
||||
using MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries.Subcomponents;
|
||||
|
||||
public class SubComponentRegistry1212 : SubComponentRegistry121
|
||||
{
|
||||
public SubComponentRegistry1212(DataTypes dataTypes) : base(dataTypes)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ public class StructuredComponentsHandler
|
|||
{
|
||||
Protocol18Handler.MC_1_20_6_Version => typeof(SubComponentRegistry1206),
|
||||
Protocol18Handler.MC_1_21_Version => typeof(SubComponentRegistry121),
|
||||
>= Protocol18Handler.MC_1_21_2_Version => typeof(SubComponentRegistry1212),
|
||||
_ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for subcomponent registries!")
|
||||
};
|
||||
|
||||
|
|
@ -32,6 +33,7 @@ public class StructuredComponentsHandler
|
|||
{
|
||||
Protocol18Handler.MC_1_20_6_Version => typeof(StructuredComponentsRegistry1206),
|
||||
Protocol18Handler.MC_1_21_Version => typeof(StructuredComponentsRegistry121),
|
||||
>= Protocol18Handler.MC_1_21_2_Version => typeof(StructuredComponentsRegistry1212),
|
||||
_ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for structured component registries!")
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue