dye color + count structured components

This commit is contained in:
MeexReay 2025-05-11 17:46:45 +03:00
parent d29824798b
commit 79e0f9c6dc
2 changed files with 121 additions and 217 deletions

View File

@ -70,3 +70,23 @@ pub struct Property {
pub value: String, pub value: String,
pub signature: Option<String>, pub signature: Option<String>,
} }
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum DyeColor {
White,
Orange,
Magenta,
LightBlue,
Yellow,
Lime,
Pink,
Gray,
LightGray,
Cyan,
Purple,
Blue,
Brown,
Green,
Red,
Black,
}

View File

@ -6,7 +6,7 @@ use uuid::Uuid;
use crate::ServerError; use crate::ServerError;
use super::{IdOr, IdSet, Property, component::TextComponent, sound::SoundEvent}; use super::{DyeColor, IdOr, IdSet, Property, component::TextComponent, sound::SoundEvent};
pub const SLOT_COMPONENT_LENGTH: u16 = 96; pub const SLOT_COMPONENT_LENGTH: u16 = 96;
@ -164,24 +164,7 @@ pub struct BannerLayer {
pub pattern_type: i32, pub pattern_type: i32,
pub asset_id: Option<String>, pub asset_id: Option<String>,
pub translation_key: Option<String>, pub translation_key: Option<String>,
/// Can be one of the following: pub color: DyeColor,
/// - 0 - White
/// - 1 - Orange
/// - 2 - Magenta
/// - 3 - Light Blue
/// - 4 - Yellow
/// - 5 - Lime
/// - 6 - Pink
/// - 7 - Gray
/// - 8 - Light Gray
/// - 9 - Cyan
/// - 10 - Purple
/// - 11 - Blue
/// - 12 - Brown
/// - 13 - Green
/// - 14 - Red
/// - 15 - Black
pub color: u8,
} }
#[derive(Clone)] #[derive(Clone)]
@ -229,52 +212,52 @@ pub struct DamageReduction {
/// https://minecraft.wiki/w/Java_Edition_protocol/Slot_data#Structured_components /// https://minecraft.wiki/w/Java_Edition_protocol/Slot_data#Structured_components
#[derive(Clone, EnumIndex)] #[derive(Clone, EnumIndex)]
pub enum StructuredComponent { pub enum StructuredComponent {
CustomData(DynNBT), CustomData(DynNBT), // 0
/// 1 - 99 /// 1 - 99
MaxStackSize(i32), MaxStackSize(i32), // 1
MaxDamage(i32), MaxDamage(i32), // 2
Damage(i32), Damage(i32), // 3
Unbreakable, Unbreakable, // 4
CustomName(TextComponent), CustomName(TextComponent), // 5
ItemName(TextComponent), ItemName(TextComponent), // 6
ItemModel(String), ItemModel(String), // 7
Lore(TextComponent), Lore(TextComponent), // 8
/// Can be one of the following: /// Can be one of the following:
/// - 0 - Common (white) /// - 0 - Common (white)
/// - 1 - Uncommon (yellow) /// - 1 - Uncommon (yellow)
/// - 2 - Rare (aqua) /// - 2 - Rare (aqua)
/// - 3 - Epic (pink) /// - 3 - Epic (pink)
Rarity(u8), Rarity(u8), // 9
/// Key: The ID of the enchantment in the enchantment registry. \ /// Key: The ID of the enchantment in the enchantment registry. \
/// Value: The level of the enchantment. /// Value: The level of the enchantment.
Enchantments(Vec<(u64, i32)>), Enchantments(Vec<(u64, i32)>), // 10
CanPlaceOn(Vec<BlockPredicate>), CanPlaceOn(Vec<BlockPredicate>), // 11
CanBreak(Vec<BlockPredicate>), CanBreak(Vec<BlockPredicate>), // 12
AttributeModifiers(Vec<AttributeModifier>), AttributeModifiers(Vec<AttributeModifier>), // 13
/// Floats, Flags, Strings, Colors /// Floats, Flags, Strings, Colors
CustomModelData(Vec<f32>, Vec<bool>, Vec<String>, Vec<i32>), CustomModelData(Vec<f32>, Vec<bool>, Vec<String>, Vec<i32>), // 14
/// Parameters: /// Parameters:
/// - Hide Tooltip /// - Hide Tooltip
/// - The IDs of data components in the minecraft:data_component_type registry to hide. /// - The IDs of data components in the minecraft:data_component_type registry to hide.
TooltipDisplay(bool, Vec<u64>), TooltipDisplay(bool, Vec<u64>), // 15
/// Accumulated anvil usage cost. /// Accumulated anvil usage cost.
/// The client displays "Too Expensive" if the value is greater than 40 and /// The client displays "Too Expensive" if the value is greater than 40 and
/// the player is not in creative mode (more specifically, /// the player is not in creative mode (more specifically,
/// if they don't have the insta-build flag enabled). /// if they don't have the insta-build flag enabled).
/// This behavior can be overridden by setting the level /// This behavior can be overridden by setting the level
/// with the Set Container Property packet. /// with the Set Container Property packet.
RepairCost(i32), RepairCost(i32), // 16
/// Marks the item as non-interactive on the creative inventory (the first 5 rows of items). \ /// Marks the item as non-interactive on the creative inventory (the first 5 rows of items). \
/// This is used internally by the client on the paper icon in the saved hot-bars tab. /// This is used internally by the client on the paper icon in the saved hot-bars tab.
CreativeSlotLock, CreativeSlotLock, // 17
EnchantmentGlintOverride(bool), EnchantmentGlintOverride(bool), // 18
/// Marks the projectile as intangible (cannot be picked-up). /// Marks the projectile as intangible (cannot be picked-up).
IntangibleProjectile, IntangibleProjectile, // 19
/// Parameters: /// Parameters:
/// - Nutrition, Non-negative /// - Nutrition, Non-negative
/// - How much saturation will be given after consuming the item. /// - How much saturation will be given after consuming the item.
/// - Whether the item can always be eaten, even at full hunger. /// - Whether the item can always be eaten, even at full hunger.
Food(u32, f32, bool), Food(u32, f32, bool), // 20
/// Animation: 0: none, 1: eat, 2: drink, 3: block, 4: bow, 5: spear, 6: crossbow, 7: spyglass, 8: toot_horn, 9: brush /// Animation: 0: none, 1: eat, 2: drink, 3: block, 4: bow, 5: spear, 6: crossbow, 7: spyglass, 8: toot_horn, 9: brush
Consumable { Consumable {
consume_seconds: f32, consume_seconds: f32,
@ -282,26 +265,26 @@ pub enum StructuredComponent {
sound: IdOr<SoundEvent>, sound: IdOr<SoundEvent>,
has_particles: bool, has_particles: bool,
effects: Vec<ConsumeEffect>, effects: Vec<ConsumeEffect>,
}, }, // 21
UseRemainder(Slot), UseRemainder(Slot), // 22
/// Group of items to apply the cooldown to. Only present if Has cooldown group is true; otherwise defaults to the item's identifier. /// Group of items to apply the cooldown to. Only present if Has cooldown group is true; otherwise defaults to the item's identifier.
UseCooldown { UseCooldown {
seconds: f32, seconds: f32,
group: Option<String>, group: Option<String>,
}, }, // 23
/// Parameter - Types, Tag specifying damage types the item is immune to. Not prefixed by '#'!. /// Parameter - Types, Tag specifying damage types the item is immune to. Not prefixed by '#'!.
DamageResistant(String), DamageResistant(String), // 24
Tool { Tool {
rules: Vec<ToolRule>, rules: Vec<ToolRule>,
default_mining_speed: f32, default_mining_speed: f32,
damage_per_block: i32, damage_per_block: i32,
}, }, // 25
Weapon { Weapon {
damage_per_attack: i32, damage_per_attack: i32,
disable_blocking_for_seconds: f32, disable_blocking_for_seconds: f32,
}, }, // 26
// Opaque internal value controlling how expensive enchantments may be offered. // Opaque internal value controlling how expensive enchantments may be offered.
Enchantable(i32), Enchantable(i32), // 27
Equippable { Equippable {
slot: u8, slot: u8,
equip_sound: IdOr<SoundEvent>, equip_sound: IdOr<SoundEvent>,
@ -311,14 +294,14 @@ pub enum StructuredComponent {
dispensable: bool, dispensable: bool,
swappable: bool, swappable: bool,
damage_on_hurt: bool, damage_on_hurt: bool,
}, }, // 28
/// Items that can be combined with this item in an anvil to repair it. /// Items that can be combined with this item in an anvil to repair it.
Repairable(IdSet), Repairable(IdSet), // 29
/// Makes the item function like elytra. /// Makes the item function like elytra.
Glider, Glider, // 30
TooltipStyle(String), TooltipStyle(String), // 31
/// Makes the item function like a totem of undying. /// Makes the item function like a totem of undying.
DeathProtection(Vec<ConsumeEffect>), DeathProtection(Vec<ConsumeEffect>), // 32
BlockAttacks { BlockAttacks {
block_delay_seconds: f32, block_delay_seconds: f32,
disable_cooldown_scale: f32, disable_cooldown_scale: f32,
@ -329,38 +312,38 @@ pub enum StructuredComponent {
bypassed_by: Option<String>, bypassed_by: Option<String>,
block_sound: Option<IdOr<SoundEvent>>, block_sound: Option<IdOr<SoundEvent>>,
disable_sound: Option<IdOr<SoundEvent>>, disable_sound: Option<IdOr<SoundEvent>>,
}, }, // 33
/// The enchantments stored in this enchanted book. /// The enchantments stored in this enchanted book.
/// Key: The ID of the enchantment in the enchantment registry. \ /// Key: The ID of the enchantment in the enchantment registry. \
/// Value: The level of the enchantment. /// Value: The level of the enchantment.
StoredEnchantments(Vec<(u64, i32)>), StoredEnchantments(Vec<(u64, i32)>), // 34
DyedColor(i32), DyedColor(i32), // 35
MapColor(i32), MapColor(i32), // 36
MapId(i32), MapId(i32), // 37
MapDecorations(DynNBT), MapDecorations(DynNBT), // 38
/// Type of post processing. Can be either: /// Type of post processing. Can be either:
/// - 0 - Lock /// - 0 - Lock
/// - 1 - Scale /// - 1 - Scale
MapPostProcessing(u8), MapPostProcessing(u8), // 39
/// Projectiles loaded into a charged crossbow. /// Projectiles loaded into a charged crossbow.
ChargedProjectiles(Vec<Slot>), ChargedProjectiles(Vec<Slot>), // 40
BundleContents(Vec<Slot>), BundleContents(Vec<Slot>), // 41
PotionContents { PotionContents {
potion_id: Option<u64>, potion_id: Option<u64>,
custom_color: Option<i32>, custom_color: Option<i32>,
custom_effects: Vec<PotionEffect>, custom_effects: Vec<PotionEffect>,
custom_name: String, custom_name: String,
}, }, // 42
/// Parameter - Effect Multiplier /// Parameter - Effect Multiplier
PotionDurationScale(f32), PotionDurationScale(f32), // 43
/// Key - The ID of the effect in the potion effect type registry. /// Key - The ID of the effect in the potion effect type registry.
/// Value - The duration of the effect. /// Value - The duration of the effect.
SuspiciousStewEffects(Vec<(u64, i32)>), SuspiciousStewEffects(Vec<(u64, i32)>), // 44
/// Parameter - Pages /// Parameter - Pages
/// Page: /// Page:
/// - The raw text of the page /// - The raw text of the page
/// - The content after passing through chat filters /// - The content after passing through chat filters
WritableBookContent(Vec<(String, Option<String>)>), WritableBookContent(Vec<(String, Option<String>)>), // 45
WrittenBookContent { WrittenBookContent {
raw_title: String, raw_title: String,
filtered_title: Option<String>, filtered_title: Option<String>,
@ -371,183 +354,81 @@ pub enum StructuredComponent {
/// - The content after passing through chat filters /// - The content after passing through chat filters
pages: Vec<(String, Option<String>)>, pages: Vec<(String, Option<String>)>,
resolved: bool, resolved: bool,
}, }, // 46
/// Armor's trim pattern and color /// Armor's trim pattern and color
Trim(IdOr<TrimMaterial>, IdOr<TrimPattern>), Trim(IdOr<TrimMaterial>, IdOr<TrimPattern>), // 47
DebugStrickState(DynNBT), DebugStrickState(DynNBT), // 48
EntityData(DynNBT), EntityData(DynNBT), // 49
BucketEntityData(DynNBT), BucketEntityData(DynNBT), // 50
BlockEntityData(DynNBT), BlockEntityData(DynNBT), // 51
Instrument(IdOr<Instrument>), Instrument(IdOr<Instrument>), // 52
ProvidesTrimMaterial(ProvidesTrimMaterial), ProvidesTrimMaterial(ProvidesTrimMaterial), // 53
/// Between 0 and 4. /// Between 0 and 4.
OminousBottleAmplifier(u8), OminousBottleAmplifier(u8), // 54
JukeboxPlayable(JukeboxPlayable), JukeboxPlayable(JukeboxPlayable), // 55
/// A pattern identifier like #minecraft:pattern_item/globe /// A pattern identifier like #minecraft:pattern_item/globe
ProvidesBannerPatterns(String), ProvidesBannerPatterns(String), // 56
Recipes(DynNBT), Recipes(DynNBT), // 57
LodestoneTracker { LodestoneTracker {
has_global_position: bool, has_global_position: bool,
dimension: String, dimension: String,
position: (f64, f64, f64), position: (f64, f64, f64),
tracked: bool, tracked: bool,
}, }, // 58
FireworkExplosion(FireworkExplosion), FireworkExplosion(FireworkExplosion), // 59
Fireworks { Fireworks {
flight_duration: i32, flight_duration: i32,
explosions: Vec<FireworkExplosion>, explosions: Vec<FireworkExplosion>,
}, }, // 60
Profile { Profile {
name: Option<String>, name: Option<String>,
unique_id: Option<Uuid>, unique_id: Option<Uuid>,
properties: Vec<Property>, properties: Vec<Property>,
}, }, // 61
NoteBlockSound(String), NoteBlockSound(String), // 62
BannerPatterns(Vec<BannerLayer>), BannerPatterns(Vec<BannerLayer>), // 63
/// Can be one of the following: BaseColor(DyeColor), // 64
/// - 0 - White
/// - 1 - Orange
/// - 2 - Magenta
/// - 3 - Light Blue
/// - 4 - Yellow
/// - 5 - Lime
/// - 6 - Pink
/// - 7 - Gray
/// - 8 - Light Gray
/// - 9 - Cyan
/// - 10 - Purple
/// - 11 - Blue
/// - 12 - Brown
/// - 13 - Green
/// - 14 - Red
/// - 15 - Black
BaseColor(u8),
/// The ID of the items in the item registry. /// The ID of the items in the item registry.
PotDecorations([u64; 4]), PotDecorations([u64; 4]), // 65
/// Items inside a container of any type. /// Items inside a container of any type.
Container(Vec<Slot>), Container(Vec<Slot>), // 66
BlockState(Vec<(String, String)>), BlockState(Vec<(String, String)>), // 67
Bees(Vec<HiveBee>), Bees(Vec<HiveBee>), // 68
Lock(String), Lock(String), // 69
ContainerLoot(DynNBT), ContainerLoot(DynNBT), // 70
BreakSound(IdOr<SoundEvent>), BreakSound(IdOr<SoundEvent>), // 71
VillagerVariant(u64), VillagerVariant(u64), // 72
WolfVariant(u64), WolfVariant(u64), // 73
WolfSoundVariant(u64), WolfSoundVariant(u64), // 74
WolfCollar(u8), WolfCollar(u8), // 75
/// 0: red, 1: snow /// 0: red, 1: snow
FoxVariant(u8), FoxVariant(u8), // 76
/// 0: small, 1: medium, 2: large. /// 0: small, 1: medium, 2: large.
SalmonSize(u8), SalmonSize(u8), // 77
ParrotVariant(u64), ParrotVariant(u64), // 78
/// 0: kob, 1: sunstreak, 2: snooper, 3: dasher, 4: brinely, 5: spotty, 6: flopper, 7: stripey, 8: glitter, 9: blockfish, 10: betty, 11: clayfish. /// 0: kob, 1: sunstreak, 2: snooper, 3: dasher, 4: brinely, 5: spotty, 6: flopper, 7: stripey, 8: glitter, 9: blockfish, 10: betty, 11: clayfish.
TropicalFishPattern(u8), TropicalFishPattern(u8), // 79
/// Can be one of the following: TropicalFishBaseColor(DyeColor), // 80
/// - 0 - White TropicalFishPatternColor(DyeColor), // 81
/// - 1 - Orange
/// - 2 - Magenta
/// - 3 - Light Blue
/// - 4 - Yellow
/// - 5 - Lime
/// - 6 - Pink
/// - 7 - Gray
/// - 8 - Light Gray
/// - 9 - Cyan
/// - 10 - Purple
/// - 11 - Blue
/// - 12 - Brown
/// - 13 - Green
/// - 14 - Red
/// - 15 - Black
TropicalFishBaseColor(u8),
/// Can be one of the following:
/// - 0 - White
/// - 1 - Orange
/// - 2 - Magenta
/// - 3 - Light Blue
/// - 4 - Yellow
/// - 5 - Lime
/// - 6 - Pink
/// - 7 - Gray
/// - 8 - Light Gray
/// - 9 - Cyan
/// - 10 - Purple
/// - 11 - Blue
/// - 12 - Brown
/// - 13 - Green
/// - 14 - Red
/// - 15 - Black
TropicalFishPatternColor(u8),
/// 0: red, 1: brown. /// 0: red, 1: brown.
MooshroomVariant(u8), MooshroomVariant(u8), // 82
/// 0: brown, 1: white, 2: black, 3: white splotched, 4: gold, 5: salt, 6: evil. /// 0: brown, 1: white, 2: black, 3: white splotched, 4: gold, 5: salt, 6: evil.
RabbitVariant(u8), RabbitVariant(u8), // 83
PigVariant(u64), PigVariant(u64), // 84
CowVariant(u64), CowVariant(u64), // 85
ChickenVariant(ChickenVariant), ChickenVariant(ChickenVariant), // 86
FrogVariant(u64), FrogVariant(u64), // 87
/// 0: white, 1: creamy, 2: chestnut, 3: brown, 4: black, 5: gray, 6: dark brown. /// 0: white, 1: creamy, 2: chestnut, 3: brown, 4: black, 5: gray, 6: dark brown.
HorseVariant(u8), HorseVariant(u8), // 88
PaintingVariant(PaintingVariant), PaintingVariant(PaintingVariant), // 89
/// 0: creamy, 1: white, 2: brown, 3: gray. /// 0: creamy, 1: white, 2: brown, 3: gray.
LlamaVariant(u8), LlamaVariant(u8), // 90
/// 0: lucy, 1: wild, 2: gold, 3: cyan, 4: blue. /// 0: lucy, 1: wild, 2: gold, 3: cyan, 4: blue.
AxolotlVariant(u8), AxolotlVariant(u8), // 91
CatVariant(u64), CatVariant(u64), // 92
/// Can be one of the following: CatCollar(DyeColor), // 93
/// - 0 - White SheepColor(DyeColor), // 94
/// - 1 - Orange ShulkerColor(DyeColor), // 95
/// - 2 - Magenta
/// - 3 - Light Blue
/// - 4 - Yellow
/// - 5 - Lime
/// - 6 - Pink
/// - 7 - Gray
/// - 8 - Light Gray
/// - 9 - Cyan
/// - 10 - Purple
/// - 11 - Blue
/// - 12 - Brown
/// - 13 - Green
/// - 14 - Red
/// - 15 - Black
CatCollar(u8),
/// Can be one of the following:
/// - 0 - White
/// - 1 - Orange
/// - 2 - Magenta
/// - 3 - Light Blue
/// - 4 - Yellow
/// - 5 - Lime
/// - 6 - Pink
/// - 7 - Gray
/// - 8 - Light Gray
/// - 9 - Cyan
/// - 10 - Purple
/// - 11 - Blue
/// - 12 - Brown
/// - 13 - Green
/// - 14 - Red
/// - 15 - Black
SheepColor(u8),
/// Can be one of the following:
/// - 0 - White
/// - 1 - Orange
/// - 2 - Magenta
/// - 3 - Light Blue
/// - 4 - Yellow
/// - 5 - Lime
/// - 6 - Pink
/// - 7 - Gray
/// - 8 - Light Gray
/// - 9 - Cyan
/// - 10 - Purple
/// - 11 - Blue
/// - 12 - Brown
/// - 13 - Green
/// - 14 - Red
/// - 15 - Black
ShulkerColor(u8),
} }
pub trait ReadWriteSlotComponent: DataReader + DataWriter { pub trait ReadWriteSlotComponent: DataReader + DataWriter {
@ -561,6 +442,7 @@ impl ReadWriteSlotComponent for Packet {
todo!() todo!()
} }
fn write_slot_component(&mut self, val: &StructuredComponent) -> Result<(), ServerError> { fn write_slot_component(&mut self, val: &StructuredComponent) -> Result<(), ServerError> {
self.write_usize_varint(val.enum_index())?; self.write_usize_varint(val.enum_index())?;
@ -602,6 +484,7 @@ impl ReadWriteSlot for Packet {
Ok(None) Ok(None)
} }
} }
fn write_slot(&mut self, val: Option<Slot>) -> Result<(), ServerError> { fn write_slot(&mut self, val: Option<Slot>) -> Result<(), ServerError> {
if let Some(val) = val { if let Some(val) = val {
self.write_varint(val.amount)?; self.write_varint(val.amount)?;
@ -661,6 +544,7 @@ impl ReadWriteHashedSlot for Packet {
Ok(None) Ok(None)
} }
} }
fn write_hashed_slot(&mut self, val: Option<HashedSlot>) -> Result<(), ServerError> { fn write_hashed_slot(&mut self, val: Option<HashedSlot>) -> Result<(), ServerError> {
if let Some(val) = val { if let Some(val) = val {
self.write_varint(val.amount)?; self.write_varint(val.amount)?;