diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3455b119a..f949e6c58 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ adventure = "4.11.0" kotlin = "1.6.20" hydrazine = "1.7.2" dependencyGetter = "v1.0.1" -minestomData = "3e211f3953" +minestomData = "1c1921cd41" hephaistos = "2.5.0" jetbrainsAnnotations = "23.0.0" diff --git a/src/autogenerated/java/net/minestom/server/entity/EntityTypes.java b/src/autogenerated/java/net/minestom/server/entity/EntityTypes.java index 310701719..6bc13e84e 100644 --- a/src/autogenerated/java/net/minestom/server/entity/EntityTypes.java +++ b/src/autogenerated/java/net/minestom/server/entity/EntityTypes.java @@ -5,6 +5,8 @@ package net.minestom.server.entity; */ @SuppressWarnings("unused") interface EntityTypes { + EntityType ALLAY = EntityTypeImpl.get("minecraft:allay"); + EntityType AREA_EFFECT_CLOUD = EntityTypeImpl.get("minecraft:area_effect_cloud"); EntityType ARMOR_STAND = EntityTypeImpl.get("minecraft:armor_stand"); @@ -21,6 +23,8 @@ interface EntityTypes { EntityType BOAT = EntityTypeImpl.get("minecraft:boat"); + EntityType CHEST_BOAT = EntityTypeImpl.get("minecraft:chest_boat"); + EntityType CAT = EntityTypeImpl.get("minecraft:cat"); EntityType CAVE_SPIDER = EntityTypeImpl.get("minecraft:cave_spider"); @@ -65,6 +69,8 @@ interface EntityTypes { EntityType FOX = EntityTypeImpl.get("minecraft:fox"); + EntityType FROG = EntityTypeImpl.get("minecraft:frog"); + EntityType GHAST = EntityTypeImpl.get("minecraft:ghast"); EntityType GIANT = EntityTypeImpl.get("minecraft:giant"); @@ -183,6 +189,8 @@ interface EntityTypes { EntityType STRIDER = EntityTypeImpl.get("minecraft:strider"); + EntityType TADPOLE = EntityTypeImpl.get("minecraft:tadpole"); + EntityType EGG = EntityTypeImpl.get("minecraft:egg"); EntityType ENDER_PEARL = EntityTypeImpl.get("minecraft:ender_pearl"); @@ -207,6 +215,8 @@ interface EntityTypes { EntityType WANDERING_TRADER = EntityTypeImpl.get("minecraft:wandering_trader"); + EntityType WARDEN = EntityTypeImpl.get("minecraft:warden"); + EntityType WITCH = EntityTypeImpl.get("minecraft:witch"); EntityType WITHER = EntityTypeImpl.get("minecraft:wither"); diff --git a/src/autogenerated/java/net/minestom/server/instance/block/Blocks.java b/src/autogenerated/java/net/minestom/server/instance/block/Blocks.java index efaa0d900..c2603501f 100644 --- a/src/autogenerated/java/net/minestom/server/instance/block/Blocks.java +++ b/src/autogenerated/java/net/minestom/server/instance/block/Blocks.java @@ -43,6 +43,8 @@ interface Blocks { Block DARK_OAK_PLANKS = BlockImpl.get("minecraft:dark_oak_planks"); + Block MANGROVE_PLANKS = BlockImpl.get("minecraft:mangrove_planks"); + Block OAK_SAPLING = BlockImpl.get("minecraft:oak_sapling"); Block SPRUCE_SAPLING = BlockImpl.get("minecraft:spruce_sapling"); @@ -55,6 +57,8 @@ interface Blocks { Block DARK_OAK_SAPLING = BlockImpl.get("minecraft:dark_oak_sapling"); + Block MANGROVE_PROPAGULE = BlockImpl.get("minecraft:mangrove_propagule"); + Block BEDROCK = BlockImpl.get("minecraft:bedrock"); Block WATER = BlockImpl.get("minecraft:water"); @@ -93,6 +97,12 @@ interface Blocks { Block DARK_OAK_LOG = BlockImpl.get("minecraft:dark_oak_log"); + Block MANGROVE_LOG = BlockImpl.get("minecraft:mangrove_log"); + + Block MANGROVE_ROOTS = BlockImpl.get("minecraft:mangrove_roots"); + + Block MUDDY_MANGROVE_ROOTS = BlockImpl.get("minecraft:muddy_mangrove_roots"); + Block STRIPPED_SPRUCE_LOG = BlockImpl.get("minecraft:stripped_spruce_log"); Block STRIPPED_BIRCH_LOG = BlockImpl.get("minecraft:stripped_birch_log"); @@ -105,6 +115,8 @@ interface Blocks { Block STRIPPED_OAK_LOG = BlockImpl.get("minecraft:stripped_oak_log"); + Block STRIPPED_MANGROVE_LOG = BlockImpl.get("minecraft:stripped_mangrove_log"); + Block OAK_WOOD = BlockImpl.get("minecraft:oak_wood"); Block SPRUCE_WOOD = BlockImpl.get("minecraft:spruce_wood"); @@ -117,6 +129,8 @@ interface Blocks { Block DARK_OAK_WOOD = BlockImpl.get("minecraft:dark_oak_wood"); + Block MANGROVE_WOOD = BlockImpl.get("minecraft:mangrove_wood"); + Block STRIPPED_OAK_WOOD = BlockImpl.get("minecraft:stripped_oak_wood"); Block STRIPPED_SPRUCE_WOOD = BlockImpl.get("minecraft:stripped_spruce_wood"); @@ -129,6 +143,8 @@ interface Blocks { Block STRIPPED_DARK_OAK_WOOD = BlockImpl.get("minecraft:stripped_dark_oak_wood"); + Block STRIPPED_MANGROVE_WOOD = BlockImpl.get("minecraft:stripped_mangrove_wood"); + Block OAK_LEAVES = BlockImpl.get("minecraft:oak_leaves"); Block SPRUCE_LEAVES = BlockImpl.get("minecraft:spruce_leaves"); @@ -141,6 +157,8 @@ interface Blocks { Block DARK_OAK_LEAVES = BlockImpl.get("minecraft:dark_oak_leaves"); + Block MANGROVE_LEAVES = BlockImpl.get("minecraft:mangrove_leaves"); + Block AZALEA_LEAVES = BlockImpl.get("minecraft:azalea_leaves"); Block FLOWERING_AZALEA_LEAVES = BlockImpl.get("minecraft:flowering_azalea_leaves"); @@ -341,6 +359,8 @@ interface Blocks { Block DARK_OAK_SIGN = BlockImpl.get("minecraft:dark_oak_sign"); + Block MANGROVE_SIGN = BlockImpl.get("minecraft:mangrove_sign"); + Block OAK_DOOR = BlockImpl.get("minecraft:oak_door"); Block LADDER = BlockImpl.get("minecraft:ladder"); @@ -361,6 +381,8 @@ interface Blocks { Block DARK_OAK_WALL_SIGN = BlockImpl.get("minecraft:dark_oak_wall_sign"); + Block MANGROVE_WALL_SIGN = BlockImpl.get("minecraft:mangrove_wall_sign"); + Block LEVER = BlockImpl.get("minecraft:lever"); Block STONE_PRESSURE_PLATE = BlockImpl.get("minecraft:stone_pressure_plate"); @@ -379,6 +401,8 @@ interface Blocks { Block DARK_OAK_PRESSURE_PLATE = BlockImpl.get("minecraft:dark_oak_pressure_plate"); + Block MANGROVE_PRESSURE_PLATE = BlockImpl.get("minecraft:mangrove_pressure_plate"); + Block REDSTONE_ORE = BlockImpl.get("minecraft:redstone_ore"); Block DEEPSLATE_REDSTONE_ORE = BlockImpl.get("minecraft:deepslate_redstone_ore"); @@ -477,6 +501,8 @@ interface Blocks { Block DARK_OAK_TRAPDOOR = BlockImpl.get("minecraft:dark_oak_trapdoor"); + Block MANGROVE_TRAPDOOR = BlockImpl.get("minecraft:mangrove_trapdoor"); + Block STONE_BRICKS = BlockImpl.get("minecraft:stone_bricks"); Block MOSSY_STONE_BRICKS = BlockImpl.get("minecraft:mossy_stone_bricks"); @@ -485,6 +511,10 @@ interface Blocks { Block CHISELED_STONE_BRICKS = BlockImpl.get("minecraft:chiseled_stone_bricks"); + Block PACKED_MUD = BlockImpl.get("minecraft:packed_mud"); + + Block MUD_BRICKS = BlockImpl.get("minecraft:mud_bricks"); + Block INFESTED_STONE = BlockImpl.get("minecraft:infested_stone"); Block INFESTED_COBBLESTONE = BlockImpl.get("minecraft:infested_cobblestone"); @@ -529,6 +559,8 @@ interface Blocks { Block STONE_BRICK_STAIRS = BlockImpl.get("minecraft:stone_brick_stairs"); + Block MUD_BRICK_STAIRS = BlockImpl.get("minecraft:mud_brick_stairs"); + Block MYCELIUM = BlockImpl.get("minecraft:mycelium"); Block LILY_PAD = BlockImpl.get("minecraft:lily_pad"); @@ -607,6 +639,8 @@ interface Blocks { Block POTTED_DARK_OAK_SAPLING = BlockImpl.get("minecraft:potted_dark_oak_sapling"); + Block POTTED_MANGROVE_PROPAGULE = BlockImpl.get("minecraft:potted_mangrove_propagule"); + Block POTTED_FERN = BlockImpl.get("minecraft:potted_fern"); Block POTTED_DANDELION = BlockImpl.get("minecraft:potted_dandelion"); @@ -659,6 +693,8 @@ interface Blocks { Block DARK_OAK_BUTTON = BlockImpl.get("minecraft:dark_oak_button"); + Block MANGROVE_BUTTON = BlockImpl.get("minecraft:mangrove_button"); + Block SKELETON_SKULL = BlockImpl.get("minecraft:skeleton_skull"); Block SKELETON_WALL_SKULL = BlockImpl.get("minecraft:skeleton_wall_skull"); @@ -785,6 +821,8 @@ interface Blocks { Block DARK_OAK_STAIRS = BlockImpl.get("minecraft:dark_oak_stairs"); + Block MANGROVE_STAIRS = BlockImpl.get("minecraft:mangrove_stairs"); + Block SLIME_BLOCK = BlockImpl.get("minecraft:slime_block"); Block BARRIER = BlockImpl.get("minecraft:barrier"); @@ -949,6 +987,8 @@ interface Blocks { Block DARK_OAK_SLAB = BlockImpl.get("minecraft:dark_oak_slab"); + Block MANGROVE_SLAB = BlockImpl.get("minecraft:mangrove_slab"); + Block STONE_SLAB = BlockImpl.get("minecraft:stone_slab"); Block SMOOTH_STONE_SLAB = BlockImpl.get("minecraft:smooth_stone_slab"); @@ -965,6 +1005,8 @@ interface Blocks { Block STONE_BRICK_SLAB = BlockImpl.get("minecraft:stone_brick_slab"); + Block MUD_BRICK_SLAB = BlockImpl.get("minecraft:mud_brick_slab"); + Block NETHER_BRICK_SLAB = BlockImpl.get("minecraft:nether_brick_slab"); Block QUARTZ_SLAB = BlockImpl.get("minecraft:quartz_slab"); @@ -993,6 +1035,8 @@ interface Blocks { Block DARK_OAK_FENCE_GATE = BlockImpl.get("minecraft:dark_oak_fence_gate"); + Block MANGROVE_FENCE_GATE = BlockImpl.get("minecraft:mangrove_fence_gate"); + Block SPRUCE_FENCE = BlockImpl.get("minecraft:spruce_fence"); Block BIRCH_FENCE = BlockImpl.get("minecraft:birch_fence"); @@ -1003,6 +1047,8 @@ interface Blocks { Block DARK_OAK_FENCE = BlockImpl.get("minecraft:dark_oak_fence"); + Block MANGROVE_FENCE = BlockImpl.get("minecraft:mangrove_fence"); + Block SPRUCE_DOOR = BlockImpl.get("minecraft:spruce_door"); Block BIRCH_DOOR = BlockImpl.get("minecraft:birch_door"); @@ -1013,6 +1059,8 @@ interface Blocks { Block DARK_OAK_DOOR = BlockImpl.get("minecraft:dark_oak_door"); + Block MANGROVE_DOOR = BlockImpl.get("minecraft:mangrove_door"); + Block END_ROD = BlockImpl.get("minecraft:end_rod"); Block CHORUS_PLANT = BlockImpl.get("minecraft:chorus_plant"); @@ -1353,6 +1401,8 @@ interface Blocks { Block STONE_BRICK_WALL = BlockImpl.get("minecraft:stone_brick_wall"); + Block MUD_BRICK_WALL = BlockImpl.get("minecraft:mud_brick_wall"); + Block NETHER_BRICK_WALL = BlockImpl.get("minecraft:nether_brick_wall"); Block ANDESITE_WALL = BlockImpl.get("minecraft:andesite_wall"); @@ -1649,6 +1699,14 @@ interface Blocks { Block SCULK_SENSOR = BlockImpl.get("minecraft:sculk_sensor"); + Block SCULK = BlockImpl.get("minecraft:sculk"); + + Block SCULK_VEIN = BlockImpl.get("minecraft:sculk_vein"); + + Block SCULK_CATALYST = BlockImpl.get("minecraft:sculk_catalyst"); + + Block SCULK_SHRIEKER = BlockImpl.get("minecraft:sculk_shrieker"); + Block OXIDIZED_COPPER = BlockImpl.get("minecraft:oxidized_copper"); Block WEATHERED_COPPER = BlockImpl.get("minecraft:weathered_copper"); @@ -1747,6 +1805,8 @@ interface Blocks { Block ROOTED_DIRT = BlockImpl.get("minecraft:rooted_dirt"); + Block MUD = BlockImpl.get("minecraft:mud"); + Block DEEPSLATE = BlockImpl.get("minecraft:deepslate"); Block COBBLED_DEEPSLATE = BlockImpl.get("minecraft:cobbled_deepslate"); @@ -1800,4 +1860,14 @@ interface Blocks { Block POTTED_AZALEA_BUSH = BlockImpl.get("minecraft:potted_azalea_bush"); Block POTTED_FLOWERING_AZALEA_BUSH = BlockImpl.get("minecraft:potted_flowering_azalea_bush"); + + Block OCHRE_FROGLIGHT = BlockImpl.get("minecraft:ochre_froglight"); + + Block VERDANT_FROGLIGHT = BlockImpl.get("minecraft:verdant_froglight"); + + Block PEARLESCENT_FROGLIGHT = BlockImpl.get("minecraft:pearlescent_froglight"); + + Block FROGSPAWN = BlockImpl.get("minecraft:frogspawn"); + + Block REINFORCED_DEEPSLATE = BlockImpl.get("minecraft:reinforced_deepslate"); } diff --git a/src/autogenerated/java/net/minestom/server/item/Enchantments.java b/src/autogenerated/java/net/minestom/server/item/Enchantments.java index 469874132..1de0916b1 100644 --- a/src/autogenerated/java/net/minestom/server/item/Enchantments.java +++ b/src/autogenerated/java/net/minestom/server/item/Enchantments.java @@ -29,6 +29,8 @@ interface Enchantments { Enchantment SOUL_SPEED = EnchantmentImpl.get("minecraft:soul_speed"); + Enchantment SWIFT_SNEAK = EnchantmentImpl.get("minecraft:swift_sneak"); + Enchantment SHARPNESS = EnchantmentImpl.get("minecraft:sharpness"); Enchantment SMITE = EnchantmentImpl.get("minecraft:smite"); diff --git a/src/autogenerated/java/net/minestom/server/item/Materials.java b/src/autogenerated/java/net/minestom/server/item/Materials.java index 766a4e1de..d7718bf99 100644 --- a/src/autogenerated/java/net/minestom/server/item/Materials.java +++ b/src/autogenerated/java/net/minestom/server/item/Materials.java @@ -43,6 +43,8 @@ interface Materials { Material ROOTED_DIRT = MaterialImpl.get("minecraft:rooted_dirt"); + Material MUD = MaterialImpl.get("minecraft:mud"); + Material CRIMSON_NYLIUM = MaterialImpl.get("minecraft:crimson_nylium"); Material WARPED_NYLIUM = MaterialImpl.get("minecraft:warped_nylium"); @@ -61,6 +63,8 @@ interface Materials { Material DARK_OAK_PLANKS = MaterialImpl.get("minecraft:dark_oak_planks"); + Material MANGROVE_PLANKS = MaterialImpl.get("minecraft:mangrove_planks"); + Material CRIMSON_PLANKS = MaterialImpl.get("minecraft:crimson_planks"); Material WARPED_PLANKS = MaterialImpl.get("minecraft:warped_planks"); @@ -77,6 +81,8 @@ interface Materials { Material DARK_OAK_SAPLING = MaterialImpl.get("minecraft:dark_oak_sapling"); + Material MANGROVE_PROPAGULE = MaterialImpl.get("minecraft:mangrove_propagule"); + Material BEDROCK = MaterialImpl.get("minecraft:bedrock"); Material SAND = MaterialImpl.get("minecraft:sand"); @@ -219,6 +225,12 @@ interface Materials { Material DARK_OAK_LOG = MaterialImpl.get("minecraft:dark_oak_log"); + Material MANGROVE_LOG = MaterialImpl.get("minecraft:mangrove_log"); + + Material MANGROVE_ROOTS = MaterialImpl.get("minecraft:mangrove_roots"); + + Material MUDDY_MANGROVE_ROOTS = MaterialImpl.get("minecraft:muddy_mangrove_roots"); + Material CRIMSON_STEM = MaterialImpl.get("minecraft:crimson_stem"); Material WARPED_STEM = MaterialImpl.get("minecraft:warped_stem"); @@ -235,6 +247,8 @@ interface Materials { Material STRIPPED_DARK_OAK_LOG = MaterialImpl.get("minecraft:stripped_dark_oak_log"); + Material STRIPPED_MANGROVE_LOG = MaterialImpl.get("minecraft:stripped_mangrove_log"); + Material STRIPPED_CRIMSON_STEM = MaterialImpl.get("minecraft:stripped_crimson_stem"); Material STRIPPED_WARPED_STEM = MaterialImpl.get("minecraft:stripped_warped_stem"); @@ -251,6 +265,8 @@ interface Materials { Material STRIPPED_DARK_OAK_WOOD = MaterialImpl.get("minecraft:stripped_dark_oak_wood"); + Material STRIPPED_MANGROVE_WOOD = MaterialImpl.get("minecraft:stripped_mangrove_wood"); + Material STRIPPED_CRIMSON_HYPHAE = MaterialImpl.get("minecraft:stripped_crimson_hyphae"); Material STRIPPED_WARPED_HYPHAE = MaterialImpl.get("minecraft:stripped_warped_hyphae"); @@ -267,6 +283,8 @@ interface Materials { Material DARK_OAK_WOOD = MaterialImpl.get("minecraft:dark_oak_wood"); + Material MANGROVE_WOOD = MaterialImpl.get("minecraft:mangrove_wood"); + Material CRIMSON_HYPHAE = MaterialImpl.get("minecraft:crimson_hyphae"); Material WARPED_HYPHAE = MaterialImpl.get("minecraft:warped_hyphae"); @@ -283,6 +301,8 @@ interface Materials { Material DARK_OAK_LEAVES = MaterialImpl.get("minecraft:dark_oak_leaves"); + Material MANGROVE_LEAVES = MaterialImpl.get("minecraft:mangrove_leaves"); + Material AZALEA_LEAVES = MaterialImpl.get("minecraft:azalea_leaves"); Material FLOWERING_AZALEA_LEAVES = MaterialImpl.get("minecraft:flowering_azalea_leaves"); @@ -425,6 +445,8 @@ interface Materials { Material DARK_OAK_SLAB = MaterialImpl.get("minecraft:dark_oak_slab"); + Material MANGROVE_SLAB = MaterialImpl.get("minecraft:mangrove_slab"); + Material CRIMSON_SLAB = MaterialImpl.get("minecraft:crimson_slab"); Material WARPED_SLAB = MaterialImpl.get("minecraft:warped_slab"); @@ -445,6 +467,8 @@ interface Materials { Material STONE_BRICK_SLAB = MaterialImpl.get("minecraft:stone_brick_slab"); + Material MUD_BRICK_SLAB = MaterialImpl.get("minecraft:mud_brick_slab"); + Material NETHER_BRICK_SLAB = MaterialImpl.get("minecraft:nether_brick_slab"); Material QUARTZ_SLAB = MaterialImpl.get("minecraft:quartz_slab"); @@ -493,8 +517,6 @@ interface Materials { Material SPAWNER = MaterialImpl.get("minecraft:spawner"); - Material OAK_STAIRS = MaterialImpl.get("minecraft:oak_stairs"); - Material CHEST = MaterialImpl.get("minecraft:chest"); Material CRAFTING_TABLE = MaterialImpl.get("minecraft:crafting_table"); @@ -531,6 +553,8 @@ interface Materials { Material DARK_OAK_FENCE = MaterialImpl.get("minecraft:dark_oak_fence"); + Material MANGROVE_FENCE = MaterialImpl.get("minecraft:mangrove_fence"); + Material CRIMSON_FENCE = MaterialImpl.get("minecraft:crimson_fence"); Material WARPED_FENCE = MaterialImpl.get("minecraft:warped_fence"); @@ -579,6 +603,10 @@ interface Materials { Material CHISELED_STONE_BRICKS = MaterialImpl.get("minecraft:chiseled_stone_bricks"); + Material PACKED_MUD = MaterialImpl.get("minecraft:packed_mud"); + + Material MUD_BRICKS = MaterialImpl.get("minecraft:mud_bricks"); + Material DEEPSLATE_BRICKS = MaterialImpl.get("minecraft:deepslate_bricks"); Material CRACKED_DEEPSLATE_BRICKS = MaterialImpl.get("minecraft:cracked_deepslate_bricks"); @@ -589,6 +617,8 @@ interface Materials { Material CHISELED_DEEPSLATE = MaterialImpl.get("minecraft:chiseled_deepslate"); + Material REINFORCED_DEEPSLATE = MaterialImpl.get("minecraft:reinforced_deepslate"); + Material BROWN_MUSHROOM_BLOCK = MaterialImpl.get("minecraft:brown_mushroom_block"); Material RED_MUSHROOM_BLOCK = MaterialImpl.get("minecraft:red_mushroom_block"); @@ -611,6 +641,8 @@ interface Materials { Material STONE_BRICK_STAIRS = MaterialImpl.get("minecraft:stone_brick_stairs"); + Material MUD_BRICK_STAIRS = MaterialImpl.get("minecraft:mud_brick_stairs"); + Material MYCELIUM = MaterialImpl.get("minecraft:mycelium"); Material LILY_PAD = MaterialImpl.get("minecraft:lily_pad"); @@ -625,6 +657,14 @@ interface Materials { Material NETHER_BRICK_STAIRS = MaterialImpl.get("minecraft:nether_brick_stairs"); + Material SCULK = MaterialImpl.get("minecraft:sculk"); + + Material SCULK_VEIN = MaterialImpl.get("minecraft:sculk_vein"); + + Material SCULK_CATALYST = MaterialImpl.get("minecraft:sculk_catalyst"); + + Material SCULK_SHRIEKER = MaterialImpl.get("minecraft:sculk_shrieker"); + Material ENCHANTING_TABLE = MaterialImpl.get("minecraft:enchanting_table"); Material END_PORTAL_FRAME = MaterialImpl.get("minecraft:end_portal_frame"); @@ -641,12 +681,20 @@ interface Materials { Material EMERALD_BLOCK = MaterialImpl.get("minecraft:emerald_block"); + Material OAK_STAIRS = MaterialImpl.get("minecraft:oak_stairs"); + Material SPRUCE_STAIRS = MaterialImpl.get("minecraft:spruce_stairs"); Material BIRCH_STAIRS = MaterialImpl.get("minecraft:birch_stairs"); Material JUNGLE_STAIRS = MaterialImpl.get("minecraft:jungle_stairs"); + Material ACACIA_STAIRS = MaterialImpl.get("minecraft:acacia_stairs"); + + Material DARK_OAK_STAIRS = MaterialImpl.get("minecraft:dark_oak_stairs"); + + Material MANGROVE_STAIRS = MaterialImpl.get("minecraft:mangrove_stairs"); + Material CRIMSON_STAIRS = MaterialImpl.get("minecraft:crimson_stairs"); Material WARPED_STAIRS = MaterialImpl.get("minecraft:warped_stairs"); @@ -671,6 +719,8 @@ interface Materials { Material STONE_BRICK_WALL = MaterialImpl.get("minecraft:stone_brick_wall"); + Material MUD_BRICK_WALL = MaterialImpl.get("minecraft:mud_brick_wall"); + Material NETHER_BRICK_WALL = MaterialImpl.get("minecraft:nether_brick_wall"); Material ANDESITE_WALL = MaterialImpl.get("minecraft:andesite_wall"); @@ -787,10 +837,6 @@ interface Materials { Material PACKED_ICE = MaterialImpl.get("minecraft:packed_ice"); - Material ACACIA_STAIRS = MaterialImpl.get("minecraft:acacia_stairs"); - - Material DARK_OAK_STAIRS = MaterialImpl.get("minecraft:dark_oak_stairs"); - Material DIRT_PATH = MaterialImpl.get("minecraft:dirt_path"); Material SUNFLOWER = MaterialImpl.get("minecraft:sunflower"); @@ -1239,6 +1285,8 @@ interface Materials { Material DARK_OAK_BUTTON = MaterialImpl.get("minecraft:dark_oak_button"); + Material MANGROVE_BUTTON = MaterialImpl.get("minecraft:mangrove_button"); + Material CRIMSON_BUTTON = MaterialImpl.get("minecraft:crimson_button"); Material WARPED_BUTTON = MaterialImpl.get("minecraft:warped_button"); @@ -1263,6 +1311,8 @@ interface Materials { Material DARK_OAK_PRESSURE_PLATE = MaterialImpl.get("minecraft:dark_oak_pressure_plate"); + Material MANGROVE_PRESSURE_PLATE = MaterialImpl.get("minecraft:mangrove_pressure_plate"); + Material CRIMSON_PRESSURE_PLATE = MaterialImpl.get("minecraft:crimson_pressure_plate"); Material WARPED_PRESSURE_PLATE = MaterialImpl.get("minecraft:warped_pressure_plate"); @@ -1281,6 +1331,8 @@ interface Materials { Material DARK_OAK_DOOR = MaterialImpl.get("minecraft:dark_oak_door"); + Material MANGROVE_DOOR = MaterialImpl.get("minecraft:mangrove_door"); + Material CRIMSON_DOOR = MaterialImpl.get("minecraft:crimson_door"); Material WARPED_DOOR = MaterialImpl.get("minecraft:warped_door"); @@ -1299,6 +1351,8 @@ interface Materials { Material DARK_OAK_TRAPDOOR = MaterialImpl.get("minecraft:dark_oak_trapdoor"); + Material MANGROVE_TRAPDOOR = MaterialImpl.get("minecraft:mangrove_trapdoor"); + Material CRIMSON_TRAPDOOR = MaterialImpl.get("minecraft:crimson_trapdoor"); Material WARPED_TRAPDOOR = MaterialImpl.get("minecraft:warped_trapdoor"); @@ -1315,6 +1369,8 @@ interface Materials { Material DARK_OAK_FENCE_GATE = MaterialImpl.get("minecraft:dark_oak_fence_gate"); + Material MANGROVE_FENCE_GATE = MaterialImpl.get("minecraft:mangrove_fence_gate"); + Material CRIMSON_FENCE_GATE = MaterialImpl.get("minecraft:crimson_fence_gate"); Material WARPED_FENCE_GATE = MaterialImpl.get("minecraft:warped_fence_gate"); @@ -1347,16 +1403,32 @@ interface Materials { Material OAK_BOAT = MaterialImpl.get("minecraft:oak_boat"); + Material OAK_CHEST_BOAT = MaterialImpl.get("minecraft:oak_chest_boat"); + Material SPRUCE_BOAT = MaterialImpl.get("minecraft:spruce_boat"); + Material SPRUCE_CHEST_BOAT = MaterialImpl.get("minecraft:spruce_chest_boat"); + Material BIRCH_BOAT = MaterialImpl.get("minecraft:birch_boat"); + Material BIRCH_CHEST_BOAT = MaterialImpl.get("minecraft:birch_chest_boat"); + Material JUNGLE_BOAT = MaterialImpl.get("minecraft:jungle_boat"); + Material JUNGLE_CHEST_BOAT = MaterialImpl.get("minecraft:jungle_chest_boat"); + Material ACACIA_BOAT = MaterialImpl.get("minecraft:acacia_boat"); + Material ACACIA_CHEST_BOAT = MaterialImpl.get("minecraft:acacia_chest_boat"); + Material DARK_OAK_BOAT = MaterialImpl.get("minecraft:dark_oak_boat"); + Material DARK_OAK_CHEST_BOAT = MaterialImpl.get("minecraft:dark_oak_chest_boat"); + + Material MANGROVE_BOAT = MaterialImpl.get("minecraft:mangrove_boat"); + + Material MANGROVE_CHEST_BOAT = MaterialImpl.get("minecraft:mangrove_chest_boat"); + Material STRUCTURE_BLOCK = MaterialImpl.get("minecraft:structure_block"); Material JIGSAW = MaterialImpl.get("minecraft:jigsaw"); @@ -1553,6 +1625,8 @@ interface Materials { Material DARK_OAK_SIGN = MaterialImpl.get("minecraft:dark_oak_sign"); + Material MANGROVE_SIGN = MaterialImpl.get("minecraft:mangrove_sign"); + Material CRIMSON_SIGN = MaterialImpl.get("minecraft:crimson_sign"); Material WARPED_SIGN = MaterialImpl.get("minecraft:warped_sign"); @@ -1581,6 +1655,8 @@ interface Materials { Material AXOLOTL_BUCKET = MaterialImpl.get("minecraft:axolotl_bucket"); + Material TADPOLE_BUCKET = MaterialImpl.get("minecraft:tadpole_bucket"); + Material BRICK = MaterialImpl.get("minecraft:brick"); Material CLAY_BALL = MaterialImpl.get("minecraft:clay_ball"); @@ -1597,6 +1673,8 @@ interface Materials { Material COMPASS = MaterialImpl.get("minecraft:compass"); + Material RECOVERY_COMPASS = MaterialImpl.get("minecraft:recovery_compass"); + Material BUNDLE = MaterialImpl.get("minecraft:bundle"); Material FISHING_ROD = MaterialImpl.get("minecraft:fishing_rod"); @@ -1751,6 +1829,8 @@ interface Materials { Material GLISTERING_MELON_SLICE = MaterialImpl.get("minecraft:glistering_melon_slice"); + Material ALLAY_SPAWN_EGG = MaterialImpl.get("minecraft:allay_spawn_egg"); + Material AXOLOTL_SPAWN_EGG = MaterialImpl.get("minecraft:axolotl_spawn_egg"); Material BAT_SPAWN_EGG = MaterialImpl.get("minecraft:bat_spawn_egg"); @@ -1787,6 +1867,8 @@ interface Materials { Material FOX_SPAWN_EGG = MaterialImpl.get("minecraft:fox_spawn_egg"); + Material FROG_SPAWN_EGG = MaterialImpl.get("minecraft:frog_spawn_egg"); + Material GHAST_SPAWN_EGG = MaterialImpl.get("minecraft:ghast_spawn_egg"); Material GLOW_SQUID_SPAWN_EGG = MaterialImpl.get("minecraft:glow_squid_spawn_egg"); @@ -1855,6 +1937,8 @@ interface Materials { Material STRIDER_SPAWN_EGG = MaterialImpl.get("minecraft:strider_spawn_egg"); + Material TADPOLE_SPAWN_EGG = MaterialImpl.get("minecraft:tadpole_spawn_egg"); + Material TRADER_LLAMA_SPAWN_EGG = MaterialImpl.get("minecraft:trader_llama_spawn_egg"); Material TROPICAL_FISH_SPAWN_EGG = MaterialImpl.get("minecraft:tropical_fish_spawn_egg"); @@ -1869,6 +1953,8 @@ interface Materials { Material WANDERING_TRADER_SPAWN_EGG = MaterialImpl.get("minecraft:wandering_trader_spawn_egg"); + Material WARDEN_SPAWN_EGG = MaterialImpl.get("minecraft:warden_spawn_egg"); + Material WITCH_SPAWN_EGG = MaterialImpl.get("minecraft:witch_spawn_egg"); Material WITHER_SKELETON_SPAWN_EGG = MaterialImpl.get("minecraft:wither_skeleton_spawn_egg"); @@ -2061,8 +2147,12 @@ interface Materials { Material MUSIC_DISC_OTHERSIDE = MaterialImpl.get("minecraft:music_disc_otherside"); + Material MUSIC_DISC_5 = MaterialImpl.get("minecraft:music_disc_5"); + Material MUSIC_DISC_PIGSTEP = MaterialImpl.get("minecraft:music_disc_pigstep"); + Material DISC_FRAGMENT_5 = MaterialImpl.get("minecraft:disc_fragment_5"); + Material TRIDENT = MaterialImpl.get("minecraft:trident"); Material PHANTOM_MEMBRANE = MaterialImpl.get("minecraft:phantom_membrane"); @@ -2089,6 +2179,8 @@ interface Materials { Material PIGLIN_BANNER_PATTERN = MaterialImpl.get("minecraft:piglin_banner_pattern"); + Material GOAT_HORN = MaterialImpl.get("minecraft:goat_horn"); + Material COMPOSTER = MaterialImpl.get("minecraft:composter"); Material BARREL = MaterialImpl.get("minecraft:barrel"); @@ -2206,4 +2298,14 @@ interface Materials { Material AMETHYST_CLUSTER = MaterialImpl.get("minecraft:amethyst_cluster"); Material POINTED_DRIPSTONE = MaterialImpl.get("minecraft:pointed_dripstone"); + + Material OCHRE_FROGLIGHT = MaterialImpl.get("minecraft:ochre_froglight"); + + Material VERDANT_FROGLIGHT = MaterialImpl.get("minecraft:verdant_froglight"); + + Material PEARLESCENT_FROGLIGHT = MaterialImpl.get("minecraft:pearlescent_froglight"); + + Material FROGSPAWN = MaterialImpl.get("minecraft:frogspawn"); + + Material ECHO_SHARD = MaterialImpl.get("minecraft:echo_shard"); } diff --git a/src/autogenerated/java/net/minestom/server/particle/Particles.java b/src/autogenerated/java/net/minestom/server/particle/Particles.java index 0b619f0ce..1d099e927 100644 --- a/src/autogenerated/java/net/minestom/server/particle/Particles.java +++ b/src/autogenerated/java/net/minestom/server/particle/Particles.java @@ -53,6 +53,8 @@ interface Particles { Particle EXPLOSION = ParticleImpl.get("minecraft:explosion"); + Particle SONIC_BOOM = ParticleImpl.get("minecraft:sonic_boom"); + Particle FALLING_DUST = ParticleImpl.get("minecraft:falling_dust"); Particle FIREWORK = ParticleImpl.get("minecraft:firework"); @@ -61,6 +63,12 @@ interface Particles { Particle FLAME = ParticleImpl.get("minecraft:flame"); + Particle SCULK_SOUL = ParticleImpl.get("minecraft:sculk_soul"); + + Particle SCULK_CHARGE = ParticleImpl.get("minecraft:sculk_charge"); + + Particle SCULK_CHARGE_POP = ParticleImpl.get("minecraft:sculk_charge_pop"); + Particle SOUL_FIRE_FLAME = ParticleImpl.get("minecraft:soul_fire_flame"); Particle SOUL = ParticleImpl.get("minecraft:soul"); @@ -180,4 +188,6 @@ interface Particles { Particle ELECTRIC_SPARK = ParticleImpl.get("minecraft:electric_spark"); Particle SCRAPE = ParticleImpl.get("minecraft:scrape"); + + Particle SHRIEK = ParticleImpl.get("minecraft:shriek"); } diff --git a/src/autogenerated/java/net/minestom/server/potion/PotionEffects.java b/src/autogenerated/java/net/minestom/server/potion/PotionEffects.java index 33d94d878..00189dc46 100644 --- a/src/autogenerated/java/net/minestom/server/potion/PotionEffects.java +++ b/src/autogenerated/java/net/minestom/server/potion/PotionEffects.java @@ -68,4 +68,6 @@ interface PotionEffects { PotionEffect BAD_OMEN = PotionEffectImpl.get("minecraft:bad_omen"); PotionEffect HERO_OF_THE_VILLAGE = PotionEffectImpl.get("minecraft:hero_of_the_village"); + + PotionEffect DARKNESS = PotionEffectImpl.get("minecraft:darkness"); } diff --git a/src/autogenerated/java/net/minestom/server/sound/SoundEvents.java b/src/autogenerated/java/net/minestom/server/sound/SoundEvents.java index d5f714776..9240da48b 100644 --- a/src/autogenerated/java/net/minestom/server/sound/SoundEvents.java +++ b/src/autogenerated/java/net/minestom/server/sound/SoundEvents.java @@ -5,6 +5,20 @@ package net.minestom.server.sound; */ @SuppressWarnings("unused") interface SoundEvents { + SoundEvent ENTITY_ALLAY_AMBIENT_WITH_ITEM = SoundEventImpl.get("minecraft:entity.allay.ambient_with_item"); + + SoundEvent ENTITY_ALLAY_AMBIENT_WITHOUT_ITEM = SoundEventImpl.get("minecraft:entity.allay.ambient_without_item"); + + SoundEvent ENTITY_ALLAY_DEATH = SoundEventImpl.get("minecraft:entity.allay.death"); + + SoundEvent ENTITY_ALLAY_HURT = SoundEventImpl.get("minecraft:entity.allay.hurt"); + + SoundEvent ENTITY_ALLAY_ITEM_GIVEN = SoundEventImpl.get("minecraft:entity.allay.item_given"); + + SoundEvent ENTITY_ALLAY_ITEM_TAKEN = SoundEventImpl.get("minecraft:entity.allay.item_taken"); + + SoundEvent ENTITY_ALLAY_ITEM_THROWN = SoundEventImpl.get("minecraft:entity.allay.item_thrown"); + SoundEvent AMBIENT_CAVE = SoundEventImpl.get("minecraft:ambient.cave"); SoundEvent AMBIENT_BASALT_DELTAS_ADDITIONS = SoundEventImpl.get("minecraft:ambient.basalt_deltas.additions"); @@ -313,6 +327,8 @@ interface SoundEvents { SoundEvent ITEM_BUCKET_EMPTY_POWDER_SNOW = SoundEventImpl.get("minecraft:item.bucket.empty_powder_snow"); + SoundEvent ITEM_BUCKET_EMPTY_TADPOLE = SoundEventImpl.get("minecraft:item.bucket.empty_tadpole"); + SoundEvent ITEM_BUCKET_FILL = SoundEventImpl.get("minecraft:item.bucket.fill"); SoundEvent ITEM_BUCKET_FILL_AXOLOTL = SoundEventImpl.get("minecraft:item.bucket.fill_axolotl"); @@ -323,6 +339,8 @@ interface SoundEvents { SoundEvent ITEM_BUCKET_FILL_POWDER_SNOW = SoundEventImpl.get("minecraft:item.bucket.fill_powder_snow"); + SoundEvent ITEM_BUCKET_FILL_TADPOLE = SoundEventImpl.get("minecraft:item.bucket.fill_tadpole"); + SoundEvent ITEM_BUNDLE_DROP_CONTENTS = SoundEventImpl.get("minecraft:item.bundle.drop_contents"); SoundEvent ITEM_BUNDLE_INSERT = SoundEventImpl.get("minecraft:item.bundle.insert"); @@ -787,6 +805,44 @@ interface SoundEvents { SoundEvent ENTITY_FOX_TELEPORT = SoundEventImpl.get("minecraft:entity.fox.teleport"); + SoundEvent BLOCK_FROGLIGHT_BREAK = SoundEventImpl.get("minecraft:block.froglight.break"); + + SoundEvent BLOCK_FROGLIGHT_FALL = SoundEventImpl.get("minecraft:block.froglight.fall"); + + SoundEvent BLOCK_FROGLIGHT_HIT = SoundEventImpl.get("minecraft:block.froglight.hit"); + + SoundEvent BLOCK_FROGLIGHT_PLACE = SoundEventImpl.get("minecraft:block.froglight.place"); + + SoundEvent BLOCK_FROGLIGHT_STEP = SoundEventImpl.get("minecraft:block.froglight.step"); + + SoundEvent BLOCK_FROGSPAWN_STEP = SoundEventImpl.get("minecraft:block.frogspawn.step"); + + SoundEvent BLOCK_FROGSPAWN_BREAK = SoundEventImpl.get("minecraft:block.frogspawn.break"); + + SoundEvent BLOCK_FROGSPAWN_FALL = SoundEventImpl.get("minecraft:block.frogspawn.fall"); + + SoundEvent BLOCK_FROGSPAWN_HATCH = SoundEventImpl.get("minecraft:block.frogspawn.hatch"); + + SoundEvent BLOCK_FROGSPAWN_HIT = SoundEventImpl.get("minecraft:block.frogspawn.hit"); + + SoundEvent BLOCK_FROGSPAWN_PLACE = SoundEventImpl.get("minecraft:block.frogspawn.place"); + + SoundEvent ENTITY_FROG_AMBIENT = SoundEventImpl.get("minecraft:entity.frog.ambient"); + + SoundEvent ENTITY_FROG_DEATH = SoundEventImpl.get("minecraft:entity.frog.death"); + + SoundEvent ENTITY_FROG_EAT = SoundEventImpl.get("minecraft:entity.frog.eat"); + + SoundEvent ENTITY_FROG_HURT = SoundEventImpl.get("minecraft:entity.frog.hurt"); + + SoundEvent ENTITY_FROG_LAY_SPAWN = SoundEventImpl.get("minecraft:entity.frog.lay_spawn"); + + SoundEvent ENTITY_FROG_LONG_JUMP = SoundEventImpl.get("minecraft:entity.frog.long_jump"); + + SoundEvent ENTITY_FROG_STEP = SoundEventImpl.get("minecraft:entity.frog.step"); + + SoundEvent ENTITY_FROG_TONGUE = SoundEventImpl.get("minecraft:entity.frog.tongue"); + SoundEvent BLOCK_ROOTS_BREAK = SoundEventImpl.get("minecraft:block.roots.break"); SoundEvent BLOCK_ROOTS_STEP = SoundEventImpl.get("minecraft:block.roots.step"); @@ -889,6 +945,10 @@ interface SoundEvents { SoundEvent ENTITY_GOAT_RAM_IMPACT = SoundEventImpl.get("minecraft:entity.goat.ram_impact"); + SoundEvent ENTITY_GOAT_HORN_BREAK = SoundEventImpl.get("minecraft:entity.goat.horn_break"); + + SoundEvent ITEM_GOAT_HORN_PLAY = SoundEventImpl.get("minecraft:item.goat_horn.play"); + SoundEvent ENTITY_GOAT_SCREAMING_AMBIENT = SoundEventImpl.get("minecraft:entity.goat.screaming.ambient"); SoundEvent ENTITY_GOAT_SCREAMING_DEATH = SoundEventImpl.get("minecraft:entity.goat.screaming.death"); @@ -905,6 +965,8 @@ interface SoundEvents { SoundEvent ENTITY_GOAT_SCREAMING_RAM_IMPACT = SoundEventImpl.get("minecraft:entity.goat.screaming.ram_impact"); + SoundEvent ENTITY_GOAT_SCREAMING_HORN_BREAK = SoundEventImpl.get("minecraft:entity.goat.screaming.horn_break"); + SoundEvent ENTITY_GOAT_STEP = SoundEventImpl.get("minecraft:entity.goat.step"); SoundEvent BLOCK_GRASS_BREAK = SoundEventImpl.get("minecraft:block.grass.break"); @@ -991,6 +1053,22 @@ interface SoundEvents { SoundEvent ITEM_HONEY_BOTTLE_DRINK = SoundEventImpl.get("minecraft:item.honey_bottle.drink"); + SoundEvent ITEM_GOAT_HORN_SOUND_0 = SoundEventImpl.get("minecraft:item.goat_horn.sound.0"); + + SoundEvent ITEM_GOAT_HORN_SOUND_1 = SoundEventImpl.get("minecraft:item.goat_horn.sound.1"); + + SoundEvent ITEM_GOAT_HORN_SOUND_2 = SoundEventImpl.get("minecraft:item.goat_horn.sound.2"); + + SoundEvent ITEM_GOAT_HORN_SOUND_3 = SoundEventImpl.get("minecraft:item.goat_horn.sound.3"); + + SoundEvent ITEM_GOAT_HORN_SOUND_4 = SoundEventImpl.get("minecraft:item.goat_horn.sound.4"); + + SoundEvent ITEM_GOAT_HORN_SOUND_5 = SoundEventImpl.get("minecraft:item.goat_horn.sound.5"); + + SoundEvent ITEM_GOAT_HORN_SOUND_6 = SoundEventImpl.get("minecraft:item.goat_horn.sound.6"); + + SoundEvent ITEM_GOAT_HORN_SOUND_7 = SoundEventImpl.get("minecraft:item.goat_horn.sound.7"); + SoundEvent ENTITY_HORSE_AMBIENT = SoundEventImpl.get("minecraft:entity.horse.ambient"); SoundEvent ENTITY_HORSE_ANGRY = SoundEventImpl.get("minecraft:entity.horse.angry"); @@ -1175,6 +1253,16 @@ interface SoundEvents { SoundEvent ENTITY_MAGMA_CUBE_SQUISH_SMALL = SoundEventImpl.get("minecraft:entity.magma_cube.squish_small"); + SoundEvent BLOCK_MANGROVE_ROOTS_BREAK = SoundEventImpl.get("minecraft:block.mangrove_roots.break"); + + SoundEvent BLOCK_MANGROVE_ROOTS_FALL = SoundEventImpl.get("minecraft:block.mangrove_roots.fall"); + + SoundEvent BLOCK_MANGROVE_ROOTS_HIT = SoundEventImpl.get("minecraft:block.mangrove_roots.hit"); + + SoundEvent BLOCK_MANGROVE_ROOTS_PLACE = SoundEventImpl.get("minecraft:block.mangrove_roots.place"); + + SoundEvent BLOCK_MANGROVE_ROOTS_STEP = SoundEventImpl.get("minecraft:block.mangrove_roots.step"); + SoundEvent BLOCK_MEDIUM_AMETHYST_BUD_BREAK = SoundEventImpl.get("minecraft:block.medium_amethyst_bud.break"); SoundEvent BLOCK_MEDIUM_AMETHYST_BUD_PLACE = SoundEventImpl.get("minecraft:block.medium_amethyst_bud.place"); @@ -1229,6 +1317,36 @@ interface SoundEvents { SoundEvent BLOCK_MOSS_STEP = SoundEventImpl.get("minecraft:block.moss.step"); + SoundEvent BLOCK_MUD_BREAK = SoundEventImpl.get("minecraft:block.mud.break"); + + SoundEvent BLOCK_MUD_FALL = SoundEventImpl.get("minecraft:block.mud.fall"); + + SoundEvent BLOCK_MUD_HIT = SoundEventImpl.get("minecraft:block.mud.hit"); + + SoundEvent BLOCK_MUD_PLACE = SoundEventImpl.get("minecraft:block.mud.place"); + + SoundEvent BLOCK_MUD_STEP = SoundEventImpl.get("minecraft:block.mud.step"); + + SoundEvent BLOCK_MUD_BRICKS_BREAK = SoundEventImpl.get("minecraft:block.mud_bricks.break"); + + SoundEvent BLOCK_MUD_BRICKS_FALL = SoundEventImpl.get("minecraft:block.mud_bricks.fall"); + + SoundEvent BLOCK_MUD_BRICKS_HIT = SoundEventImpl.get("minecraft:block.mud_bricks.hit"); + + SoundEvent BLOCK_MUD_BRICKS_PLACE = SoundEventImpl.get("minecraft:block.mud_bricks.place"); + + SoundEvent BLOCK_MUD_BRICKS_STEP = SoundEventImpl.get("minecraft:block.mud_bricks.step"); + + SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_BREAK = SoundEventImpl.get("minecraft:block.muddy_mangrove_roots.break"); + + SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_FALL = SoundEventImpl.get("minecraft:block.muddy_mangrove_roots.fall"); + + SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_HIT = SoundEventImpl.get("minecraft:block.muddy_mangrove_roots.hit"); + + SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_PLACE = SoundEventImpl.get("minecraft:block.muddy_mangrove_roots.place"); + + SoundEvent BLOCK_MUDDY_MANGROVE_ROOTS_STEP = SoundEventImpl.get("minecraft:block.muddy_mangrove_roots.step"); + SoundEvent ENTITY_MULE_AMBIENT = SoundEventImpl.get("minecraft:entity.mule.ambient"); SoundEvent ENTITY_MULE_ANGRY = SoundEventImpl.get("minecraft:entity.mule.angry"); @@ -1245,6 +1363,8 @@ interface SoundEvents { SoundEvent MUSIC_CREDITS = SoundEventImpl.get("minecraft:music.credits"); + SoundEvent MUSIC_DISC_5 = SoundEventImpl.get("minecraft:music_disc.5"); + SoundEvent MUSIC_DISC_11 = SoundEventImpl.get("minecraft:music_disc.11"); SoundEvent MUSIC_DISC_13 = SoundEventImpl.get("minecraft:music_disc.13"); @@ -1285,6 +1405,8 @@ interface SoundEvents { SoundEvent MUSIC_NETHER_CRIMSON_FOREST = SoundEventImpl.get("minecraft:music.nether.crimson_forest"); + SoundEvent MUSIC_OVERWORLD_DEEP_DARK = SoundEventImpl.get("minecraft:music.overworld.deep_dark"); + SoundEvent MUSIC_OVERWORLD_DRIPSTONE_CAVES = SoundEventImpl.get("minecraft:music.overworld.dripstone_caves"); SoundEvent MUSIC_OVERWORLD_GROVE = SoundEventImpl.get("minecraft:music.overworld.grove"); @@ -1293,6 +1415,12 @@ interface SoundEvents { SoundEvent MUSIC_OVERWORLD_LUSH_CAVES = SoundEventImpl.get("minecraft:music.overworld.lush_caves"); + SoundEvent MUSIC_OVERWORLD_SWAMP = SoundEventImpl.get("minecraft:music.overworld.swamp"); + + SoundEvent MUSIC_OVERWORLD_JUNGLE_AND_FOREST = SoundEventImpl.get("minecraft:music.overworld.jungle_and_forest"); + + SoundEvent MUSIC_OVERWORLD_OLD_GROWTH_TAIGA = SoundEventImpl.get("minecraft:music.overworld.old_growth_taiga"); + SoundEvent MUSIC_OVERWORLD_MEADOW = SoundEventImpl.get("minecraft:music.overworld.meadow"); SoundEvent MUSIC_NETHER_NETHER_WASTES = SoundEventImpl.get("minecraft:music.nether.nether_wastes"); @@ -1323,6 +1451,16 @@ interface SoundEvents { SoundEvent ITEM_NETHER_WART_PLANT = SoundEventImpl.get("minecraft:item.nether_wart.plant"); + SoundEvent BLOCK_PACKED_MUD_BREAK = SoundEventImpl.get("minecraft:block.packed_mud.break"); + + SoundEvent BLOCK_PACKED_MUD_FALL = SoundEventImpl.get("minecraft:block.packed_mud.fall"); + + SoundEvent BLOCK_PACKED_MUD_HIT = SoundEventImpl.get("minecraft:block.packed_mud.hit"); + + SoundEvent BLOCK_PACKED_MUD_PLACE = SoundEventImpl.get("minecraft:block.packed_mud.place"); + + SoundEvent BLOCK_PACKED_MUD_STEP = SoundEventImpl.get("minecraft:block.packed_mud.step"); + SoundEvent BLOCK_STEM_BREAK = SoundEventImpl.get("minecraft:block.stem.break"); SoundEvent BLOCK_STEM_STEP = SoundEventImpl.get("minecraft:block.stem.step"); @@ -1529,6 +1667,8 @@ interface SoundEvents { SoundEvent ENTITY_PARROT_IMITATE_VINDICATOR = SoundEventImpl.get("minecraft:entity.parrot.imitate.vindicator"); + SoundEvent ENTITY_PARROT_IMITATE_WARDEN = SoundEventImpl.get("minecraft:entity.parrot.imitate.warden"); + SoundEvent ENTITY_PARROT_IMITATE_WITCH = SoundEventImpl.get("minecraft:entity.parrot.imitate.witch"); SoundEvent ENTITY_PARROT_IMITATE_WITHER = SoundEventImpl.get("minecraft:entity.parrot.imitate.wither"); @@ -1799,6 +1939,32 @@ interface SoundEvents { SoundEvent BLOCK_SCAFFOLDING_STEP = SoundEventImpl.get("minecraft:block.scaffolding.step"); + SoundEvent BLOCK_SCULK_SPREAD = SoundEventImpl.get("minecraft:block.sculk.spread"); + + SoundEvent BLOCK_SCULK_CHARGE = SoundEventImpl.get("minecraft:block.sculk.charge"); + + SoundEvent BLOCK_SCULK_BREAK = SoundEventImpl.get("minecraft:block.sculk.break"); + + SoundEvent BLOCK_SCULK_FALL = SoundEventImpl.get("minecraft:block.sculk.fall"); + + SoundEvent BLOCK_SCULK_HIT = SoundEventImpl.get("minecraft:block.sculk.hit"); + + SoundEvent BLOCK_SCULK_PLACE = SoundEventImpl.get("minecraft:block.sculk.place"); + + SoundEvent BLOCK_SCULK_STEP = SoundEventImpl.get("minecraft:block.sculk.step"); + + SoundEvent BLOCK_SCULK_CATALYST_BLOOM = SoundEventImpl.get("minecraft:block.sculk_catalyst.bloom"); + + SoundEvent BLOCK_SCULK_CATALYST_BREAK = SoundEventImpl.get("minecraft:block.sculk_catalyst.break"); + + SoundEvent BLOCK_SCULK_CATALYST_FALL = SoundEventImpl.get("minecraft:block.sculk_catalyst.fall"); + + SoundEvent BLOCK_SCULK_CATALYST_HIT = SoundEventImpl.get("minecraft:block.sculk_catalyst.hit"); + + SoundEvent BLOCK_SCULK_CATALYST_PLACE = SoundEventImpl.get("minecraft:block.sculk_catalyst.place"); + + SoundEvent BLOCK_SCULK_CATALYST_STEP = SoundEventImpl.get("minecraft:block.sculk_catalyst.step"); + SoundEvent BLOCK_SCULK_SENSOR_CLICKING = SoundEventImpl.get("minecraft:block.sculk_sensor.clicking"); SoundEvent BLOCK_SCULK_SENSOR_CLICKING_STOP = SoundEventImpl.get("minecraft:block.sculk_sensor.clicking_stop"); @@ -1813,6 +1979,28 @@ interface SoundEvents { SoundEvent BLOCK_SCULK_SENSOR_STEP = SoundEventImpl.get("minecraft:block.sculk_sensor.step"); + SoundEvent BLOCK_SCULK_SHRIEKER_BREAK = SoundEventImpl.get("minecraft:block.sculk_shrieker.break"); + + SoundEvent BLOCK_SCULK_SHRIEKER_FALL = SoundEventImpl.get("minecraft:block.sculk_shrieker.fall"); + + SoundEvent BLOCK_SCULK_SHRIEKER_HIT = SoundEventImpl.get("minecraft:block.sculk_shrieker.hit"); + + SoundEvent BLOCK_SCULK_SHRIEKER_PLACE = SoundEventImpl.get("minecraft:block.sculk_shrieker.place"); + + SoundEvent BLOCK_SCULK_SHRIEKER_SHRIEK = SoundEventImpl.get("minecraft:block.sculk_shrieker.shriek"); + + SoundEvent BLOCK_SCULK_SHRIEKER_STEP = SoundEventImpl.get("minecraft:block.sculk_shrieker.step"); + + SoundEvent BLOCK_SCULK_VEIN_BREAK = SoundEventImpl.get("minecraft:block.sculk_vein.break"); + + SoundEvent BLOCK_SCULK_VEIN_FALL = SoundEventImpl.get("minecraft:block.sculk_vein.fall"); + + SoundEvent BLOCK_SCULK_VEIN_HIT = SoundEventImpl.get("minecraft:block.sculk_vein.hit"); + + SoundEvent BLOCK_SCULK_VEIN_PLACE = SoundEventImpl.get("minecraft:block.sculk_vein.place"); + + SoundEvent BLOCK_SCULK_VEIN_STEP = SoundEventImpl.get("minecraft:block.sculk_vein.step"); + SoundEvent ENTITY_SHEEP_AMBIENT = SoundEventImpl.get("minecraft:entity.sheep.ambient"); SoundEvent ENTITY_SHEEP_DEATH = SoundEventImpl.get("minecraft:entity.sheep.death"); @@ -2073,6 +2261,14 @@ interface SoundEvents { SoundEvent BLOCK_SWEET_BERRY_BUSH_PICK_BERRIES = SoundEventImpl.get("minecraft:block.sweet_berry_bush.pick_berries"); + SoundEvent ENTITY_TADPOLE_DEATH = SoundEventImpl.get("minecraft:entity.tadpole.death"); + + SoundEvent ENTITY_TADPOLE_FLOP = SoundEventImpl.get("minecraft:entity.tadpole.flop"); + + SoundEvent ENTITY_TADPOLE_GROW_UP = SoundEventImpl.get("minecraft:entity.tadpole.grow_up"); + + SoundEvent ENTITY_TADPOLE_HURT = SoundEventImpl.get("minecraft:entity.tadpole.hurt"); + SoundEvent ENCHANT_THORNS_HIT = SoundEventImpl.get("minecraft:enchant.thorns.hit"); SoundEvent ENTITY_TNT_PRIMED = SoundEventImpl.get("minecraft:entity.tnt.primed"); @@ -2251,6 +2447,46 @@ interface SoundEvents { SoundEvent ENTITY_WANDERING_TRADER_YES = SoundEventImpl.get("minecraft:entity.wandering_trader.yes"); + SoundEvent ENTITY_WARDEN_AGITATED = SoundEventImpl.get("minecraft:entity.warden.agitated"); + + SoundEvent ENTITY_WARDEN_AMBIENT = SoundEventImpl.get("minecraft:entity.warden.ambient"); + + SoundEvent ENTITY_WARDEN_ANGRY = SoundEventImpl.get("minecraft:entity.warden.angry"); + + SoundEvent ENTITY_WARDEN_ATTACK_IMPACT = SoundEventImpl.get("minecraft:entity.warden.attack_impact"); + + SoundEvent ENTITY_WARDEN_DEATH = SoundEventImpl.get("minecraft:entity.warden.death"); + + SoundEvent ENTITY_WARDEN_DIG = SoundEventImpl.get("minecraft:entity.warden.dig"); + + SoundEvent ENTITY_WARDEN_EMERGE = SoundEventImpl.get("minecraft:entity.warden.emerge"); + + SoundEvent ENTITY_WARDEN_HEARTBEAT = SoundEventImpl.get("minecraft:entity.warden.heartbeat"); + + SoundEvent ENTITY_WARDEN_HURT = SoundEventImpl.get("minecraft:entity.warden.hurt"); + + SoundEvent ENTITY_WARDEN_LISTENING = SoundEventImpl.get("minecraft:entity.warden.listening"); + + SoundEvent ENTITY_WARDEN_LISTENING_ANGRY = SoundEventImpl.get("minecraft:entity.warden.listening_angry"); + + SoundEvent ENTITY_WARDEN_NEARBY_CLOSE = SoundEventImpl.get("minecraft:entity.warden.nearby_close"); + + SoundEvent ENTITY_WARDEN_NEARBY_CLOSER = SoundEventImpl.get("minecraft:entity.warden.nearby_closer"); + + SoundEvent ENTITY_WARDEN_NEARBY_CLOSEST = SoundEventImpl.get("minecraft:entity.warden.nearby_closest"); + + SoundEvent ENTITY_WARDEN_ROAR = SoundEventImpl.get("minecraft:entity.warden.roar"); + + SoundEvent ENTITY_WARDEN_SNIFF = SoundEventImpl.get("minecraft:entity.warden.sniff"); + + SoundEvent ENTITY_WARDEN_SONIC_BOOM = SoundEventImpl.get("minecraft:entity.warden.sonic_boom"); + + SoundEvent ENTITY_WARDEN_SONIC_CHARGE = SoundEventImpl.get("minecraft:entity.warden.sonic_charge"); + + SoundEvent ENTITY_WARDEN_STEP = SoundEventImpl.get("minecraft:entity.warden.step"); + + SoundEvent ENTITY_WARDEN_TENDRIL_CLICKS = SoundEventImpl.get("minecraft:entity.warden.tendril_clicks"); + SoundEvent BLOCK_WATER_AMBIENT = SoundEventImpl.get("minecraft:block.water.ambient"); SoundEvent WEATHER_RAIN = SoundEventImpl.get("minecraft:weather.rain"); diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index 414916722..7b43a30b0 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -46,8 +46,8 @@ public final class MinecraftServer { public final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class); - public static final String VERSION_NAME = "1.18.2"; - public static final int PROTOCOL_VERSION = 758; + public static final String VERSION_NAME = "1.19.2"; + public static final int PROTOCOL_VERSION = 760; // Threads public static final String THREAD_NAME_BENCHMARK = "Ms-Benchmark"; diff --git a/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java b/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java index abd6bb528..d5ef48364 100644 --- a/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java +++ b/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java @@ -112,10 +112,10 @@ public class AdventurePacketConvertor { final SoundEvent minestomSound = SoundEvent.fromNamespaceId(sound.name().asString()); if (minestomSound == null) { return new NamedSoundEffectPacket(sound.name().asString(), sound.source(), - (int) x, (int) y, (int) z, sound.volume(), sound.pitch()); + (int) x, (int) y, (int) z, sound.volume(), sound.pitch(), 0); } else { return new SoundEffectPacket(minestomSound.id(), sound.source(), - (int) x, (int) y, (int) z, sound.volume(), sound.pitch()); + (int) x, (int) y, (int) z, sound.volume(), sound.pitch(), 0); } } @@ -135,11 +135,11 @@ public class AdventurePacketConvertor { final SoundEvent minestomSound = SoundEvent.fromNamespaceId(sound.name().asString()); if (minestomSound != null) { - return new EntitySoundEffectPacket(minestomSound.id(), sound.source(), entity.getEntityId(), sound.volume(), sound.pitch()); + return new EntitySoundEffectPacket(minestomSound.id(), sound.source(), entity.getEntityId(), sound.volume(), sound.pitch(), 0); } else { final Pos pos = entity.getPosition(); return new NamedSoundEffectPacket(sound.name().asString(), sound.source(), - (int) pos.x(), (int) pos.y(), (int) pos.z(), sound.volume(), sound.pitch()); + (int) pos.x(), (int) pos.y(), (int) pos.z(), sound.volume(), sound.pitch(), 0); } } diff --git a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java index ff5f6c7d8..d30cfc9a5 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java @@ -6,6 +6,9 @@ import net.minestom.server.command.builder.CommandExecutor; import net.minestom.server.command.builder.arguments.minecraft.SuggestionType; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; import net.minestom.server.command.builder.suggestion.SuggestionCallback; +import net.minestom.server.registry.ProtocolObject; +import net.minestom.server.registry.Registry; +import net.minestom.server.utils.NamespaceID; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,6 +27,16 @@ import java.util.function.Supplier; * @param the type of this parsed argument */ public abstract class Argument { + @ApiStatus.Internal + public static final Registry.Container CONTAINER = Registry.createContainer(Registry.Resource.COMMAND_ARGUMENTS, + (namespace, properties) -> new ArgumentImpl(NamespaceID.from(namespace), properties.getInt("id"))); + + record ArgumentImpl(NamespaceID namespace, int id) implements ProtocolObject { + @Override + public String toString() { + return name(); + } + } private final String id; protected final boolean allowSpace; diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentWord.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentWord.java index 5f7915369..c4ec674d7 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentWord.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentWord.java @@ -1,6 +1,7 @@ package net.minestom.server.command.builder.arguments; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; +import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.utils.StringUtils; import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.validate.Check; diff --git a/src/main/java/net/minestom/server/crypto/ArgumentSignatures.java b/src/main/java/net/minestom/server/crypto/ArgumentSignatures.java new file mode 100644 index 000000000..45e8627f9 --- /dev/null +++ b/src/main/java/net/minestom/server/crypto/ArgumentSignatures.java @@ -0,0 +1,35 @@ +package net.minestom.server.crypto; + +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.binary.Writeable; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public record ArgumentSignatures(@NotNull List<@NotNull Entry> entries) implements Writeable { + public ArgumentSignatures { + entries = List.copyOf(entries); + } + + public ArgumentSignatures(BinaryReader reader) { + this(reader.readVarIntList(Entry::new)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeVarIntList(entries, BinaryWriter::write); + } + + public record Entry(@NotNull String name, @NotNull MessageSignature signature) implements Writeable { + public Entry(BinaryReader reader) { + this(reader.readSizedString(), new MessageSignature(reader)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeSizedString(name); + writer.write(signature); + } + } +} diff --git a/src/main/java/net/minestom/server/crypto/LastSeenMessages.java b/src/main/java/net/minestom/server/crypto/LastSeenMessages.java new file mode 100644 index 000000000..f18f04ccc --- /dev/null +++ b/src/main/java/net/minestom/server/crypto/LastSeenMessages.java @@ -0,0 +1,50 @@ +package net.minestom.server.crypto; + +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.binary.Writeable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.UUID; + +public record LastSeenMessages(@NotNull List<@NotNull Entry> entries) implements Writeable { + public LastSeenMessages { + entries = List.copyOf(entries); + } + + public LastSeenMessages(BinaryReader reader) { + this(reader.readVarIntList(Entry::new)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + + } + + public record Entry(UUID from, MessageSignature lastSignature) implements Writeable { + public Entry(BinaryReader reader) { + this(reader.readUuid(), new MessageSignature(reader)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeUuid(from); + writer.write(lastSignature); + } + } + + public record Update(LastSeenMessages lastSeen, @Nullable Entry lastReceived) implements Writeable { + public Update(BinaryReader reader) { + this(new LastSeenMessages(reader), reader.readBoolean() ? new Entry(reader) : null); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.write(lastSeen); + writer.writeBoolean(lastReceived != null); + if (lastReceived != null) writer.write(lastReceived); + } + } +} diff --git a/src/main/java/net/minestom/server/crypto/MessageSignature.java b/src/main/java/net/minestom/server/crypto/MessageSignature.java new file mode 100644 index 000000000..70b8496c0 --- /dev/null +++ b/src/main/java/net/minestom/server/crypto/MessageSignature.java @@ -0,0 +1,17 @@ +package net.minestom.server.crypto; + +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.binary.Writeable; +import org.jetbrains.annotations.NotNull; + +public record MessageSignature(byte @NotNull [] signature) implements Writeable { + public MessageSignature(BinaryReader reader) { + this(reader.readByteArray()); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeByteArray(signature); + } +} diff --git a/src/main/java/net/minestom/server/crypto/PlayerPublicKey.java b/src/main/java/net/minestom/server/crypto/PlayerPublicKey.java new file mode 100644 index 000000000..62cc0f0cf --- /dev/null +++ b/src/main/java/net/minestom/server/crypto/PlayerPublicKey.java @@ -0,0 +1,36 @@ +package net.minestom.server.crypto; + +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.binary.Writeable; +import net.minestom.server.utils.crypto.KeyUtils; + +import java.security.PublicKey; +import java.time.Instant; +import java.util.Arrays; + +/** + * Player's public key used to sign chat messages + */ +public record PlayerPublicKey(Instant expiresAt, PublicKey publicKey, byte[] signature) implements Writeable { + public PlayerPublicKey(BinaryReader reader) { + this(Instant.ofEpochMilli(reader.readLong()), + KeyUtils.publicRSAKeyFrom(reader.readByteArray()), reader.readByteArray()); + } + + @Override + public void write(BinaryWriter writer) { + writer.writeLong(expiresAt().toEpochMilli()); + writer.writeByteArray(publicKey.getEncoded()); + writer.writeByteArray(signature()); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof PlayerPublicKey ppk) { + return expiresAt.equals(ppk.expiresAt) && publicKey.equals(ppk.publicKey) && Arrays.equals(signature, ppk.signature); + } else { + return false; + } + } +} diff --git a/src/main/java/net/minestom/server/crypto/SaltSignaturePair.java b/src/main/java/net/minestom/server/crypto/SaltSignaturePair.java new file mode 100644 index 000000000..feb751235 --- /dev/null +++ b/src/main/java/net/minestom/server/crypto/SaltSignaturePair.java @@ -0,0 +1,18 @@ +package net.minestom.server.crypto; + +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.binary.Writeable; +import org.jetbrains.annotations.NotNull; + +public record SaltSignaturePair(long salt, byte[] signature) implements Writeable { + public SaltSignaturePair(BinaryReader reader) { + this(reader.readLong(), reader.readByteArray()); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeLong(salt); + writer.writeByteArray(signature); + } +} diff --git a/src/main/java/net/minestom/server/crypto/SignatureValidator.java b/src/main/java/net/minestom/server/crypto/SignatureValidator.java new file mode 100644 index 000000000..52eae5651 --- /dev/null +++ b/src/main/java/net/minestom/server/crypto/SignatureValidator.java @@ -0,0 +1,79 @@ +package net.minestom.server.crypto; + +import net.minestom.server.MinecraftServer; +import net.minestom.server.entity.Player; +import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.crypto.KeyUtils; +import org.jetbrains.annotations.Nullable; + +import java.security.*; +import java.util.function.Consumer; + +/** + * General purpose functional interface to verify signatures.
+ * Built in validators: + *
    + *
  • {@link SignatureValidator#PASS}: will always report true
  • + *
  • {@link SignatureValidator#FAIL}: will always report false
  • + *
  • {@link SignatureValidator#YGGDRASIL}: Uses SHA1 with RSA and Yggdrasil Public Key for + * verifying signatures
  • + *
  • {@link SignatureValidator#from(Player)}: Uses SHA256 with RSA and the + * Player's {@link PlayerPublicKey#publicKey()}
  • + *
  • {@link SignatureValidator#from(PublicKey, KeyUtils.SignatureAlgorithm)}: General purpose factory method
  • + *
+ */ +@FunctionalInterface +public interface SignatureValidator { + SignatureValidator PASS = (payload, signature) -> true; + SignatureValidator FAIL = (payload, signature) -> false; + SignatureValidator YGGDRASIL = createYggdrasilValidator(); + + /** + * Validate signature. This should not throw any exception instead it should + * return false. + * + * @return true only if the signature is valid + */ + boolean validate(byte[] payload, byte[] signature); + + default boolean validate(Consumer payload, byte[] signature) { + return validate(BinaryWriter.makeArray(payload), signature); + } + + static SignatureValidator from(PublicKey publicKey, KeyUtils.SignatureAlgorithm algorithm) { + return ((payload, signature) -> { + try { + final Signature sig = Signature.getInstance(algorithm.name()); + sig.initVerify(publicKey); + sig.update(payload); + return sig.verify(signature); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + return false; + } + }); + } + + /** + * Creates a validator from the player's public key using SHA256 with RSA + * + * @param player source of the key + * @return null if the player didn't send a public key + */ + static @Nullable SignatureValidator from(Player player) { + if (player.getPlayerConnection().playerPublicKey() == null) return null; + return from(player.getPlayerConnection().playerPublicKey().publicKey(), KeyUtils.SignatureAlgorithm.SHA256withRSA); + } + + private static SignatureValidator createYggdrasilValidator() { + try (var stream = SignatureValidator.class.getResourceAsStream("/yggdrasil_session_pubkey.der")) { + if (stream == null) { + MinecraftServer.LOGGER.error("Couldn't find Yggdrasil public key, falling back to prohibiting validator!"); + return FAIL; + } + return from(KeyUtils.publicRSAKeyFrom(stream.readAllBytes()), KeyUtils.SignatureAlgorithm.SHA1withRSA); + } catch (Exception e) { + MinecraftServer.LOGGER.error("Exception while reading Yggdrasil public key, falling back to prohibiting validator!", e); + return FAIL; + } + } +} diff --git a/src/main/java/net/minestom/server/crypto/SignedMessageHeader.java b/src/main/java/net/minestom/server/crypto/SignedMessageHeader.java new file mode 100644 index 000000000..036e2cd6d --- /dev/null +++ b/src/main/java/net/minestom/server/crypto/SignedMessageHeader.java @@ -0,0 +1,22 @@ +package net.minestom.server.crypto; + +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.binary.Writeable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; + +public record SignedMessageHeader(@Nullable MessageSignature previousSignature, UUID sender) implements Writeable { + public SignedMessageHeader(BinaryReader reader) { + this(reader.readBoolean() ? new MessageSignature(reader) : null, reader.readUuid()); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeBoolean(previousSignature != null); + if (previousSignature != null) writer.write(previousSignature); + writer.writeUuid(sender); + } +} diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 70c0d2328..72f3f4df8 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -1307,7 +1307,10 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev // Fix head rotation PacketUtils.prepareViewablePacket(chunk, new EntityHeadLookPacket(getEntityId(), position.yaw()), this); } else if (positionChange) { - PacketUtils.prepareViewablePacket(chunk, EntityPositionPacket.getPacket(getEntityId(), position, lastSyncedPosition, onGround), this); + // This is a confusing fix for a confusing issue. If rotation is only sent when the entity actually changes, then spawning an entity + // on the ground causes the entity not to update its rotation correctly. It works fine if the entity is spawned in the air. Very weird. + PacketUtils.prepareViewablePacket(chunk, EntityPositionAndRotationPacket.getPacket(getEntityId(), position, + lastSyncedPosition, onGround), this); } else if (viewChange) { PacketUtils.prepareViewablePacket(chunk, new EntityHeadLookPacket(getEntityId(), position.yaw()), this); PacketUtils.prepareViewablePacket(chunk, new EntityRotationPacket(getEntityId(), position.yaw(), position.pitch(), onGround), this); diff --git a/src/main/java/net/minestom/server/entity/EntitySpawnType.java b/src/main/java/net/minestom/server/entity/EntitySpawnType.java index 9c2fd41e4..c1d23ebdb 100644 --- a/src/main/java/net/minestom/server/entity/EntitySpawnType.java +++ b/src/main/java/net/minestom/server/entity/EntitySpawnType.java @@ -1,40 +1,24 @@ package net.minestom.server.entity; -import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; -import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.metadata.ObjectDataProvider; import net.minestom.server.entity.metadata.other.ExperienceOrbMeta; -import net.minestom.server.entity.metadata.other.PaintingMeta; import net.minestom.server.network.packet.server.ServerPacket; -import net.minestom.server.network.packet.server.play.*; +import net.minestom.server.network.packet.server.play.SpawnEntityPacket; +import net.minestom.server.network.packet.server.play.SpawnExperienceOrbPacket; +import net.minestom.server.network.packet.server.play.SpawnPlayerPacket; public enum EntitySpawnType { BASE { @Override public ServerPacket getSpawnPacket(Entity entity) { - int data = 0; - short velocityX = 0, velocityZ = 0, velocityY = 0; - if (entity.getEntityMeta() instanceof ObjectDataProvider objectDataProvider) { - data = objectDataProvider.getObjectData(); - if (objectDataProvider.requiresVelocityPacketAtSpawn()) { - final var velocity = entity.getVelocityForPacket(); - velocityX = (short) velocity.x(); - velocityY = (short) velocity.y(); - velocityZ = (short) velocity.z(); - } - } - return new SpawnEntityPacket(entity.getEntityId(), entity.getUuid(), entity.getEntityType().id(), - entity.getPosition(), data, velocityX, velocityY, velocityZ); + return EntitySpawnType.basicEntity(entity); } }, LIVING { @Override public ServerPacket getSpawnPacket(Entity entity) { - final Pos position = entity.getPosition(); - final Vec velocity = entity.getVelocityForPacket(); - return new SpawnLivingEntityPacket(entity.getEntityId(), entity.getUuid(), entity.getEntityType().id(), - position, position.yaw(), (short) velocity.x(), (short) velocity.y(), (short) velocity.z()); + return EntitySpawnType.basicEntity(entity); } }, PLAYER { @@ -54,7 +38,8 @@ public enum EntitySpawnType { PAINTING { @Override public ServerPacket getSpawnPacket(Entity entity) { - int motive = 0; + return EntitySpawnType.basicEntity(entity); + /* int motive = 0; Point position = Vec.ZERO; byte direction = 0; if (entity.getEntityMeta() instanceof PaintingMeta paintingMeta) { @@ -72,9 +57,26 @@ public enum EntitySpawnType { default -> 0; }; } - return new SpawnPaintingPacket(entity.getEntityId(), entity.getUuid(), motive, position, direction); + return new SpawnPaintingPacket(entity.getEntityId(), entity.getUuid(), motive, position, direction);*/ } }; public abstract ServerPacket getSpawnPacket(Entity entity); + + private static SpawnEntityPacket basicEntity(Entity entity) { + int data = 0; + short velocityX = 0, velocityZ = 0, velocityY = 0; + if (entity.getEntityMeta() instanceof ObjectDataProvider objectDataProvider) { + data = objectDataProvider.getObjectData(); + if (objectDataProvider.requiresVelocityPacketAtSpawn()) { + final var velocity = entity.getVelocityForPacket(); + velocityX = (short) velocity.x(); + velocityY = (short) velocity.y(); + velocityZ = (short) velocity.z(); + } + } + final Pos position = entity.getPosition(); + return new SpawnEntityPacket(entity.getEntityId(), entity.getUuid(), entity.getEntityType().id(), + position, position.yaw(), data, velocityX, velocityY, velocityZ); + } } diff --git a/src/main/java/net/minestom/server/entity/EntityTypeImpl.java b/src/main/java/net/minestom/server/entity/EntityTypeImpl.java index 75f302d57..1c9ac145b 100644 --- a/src/main/java/net/minestom/server/entity/EntityTypeImpl.java +++ b/src/main/java/net/minestom/server/entity/EntityTypeImpl.java @@ -75,6 +75,7 @@ record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType { private static Map> createMetaMap() { return Map.>ofEntries( + entry("minecraft:allay", EntityMeta::new), // TODO dedicated metadata entry("minecraft:area_effect_cloud", AreaEffectCloudMeta::new), entry("minecraft:armor_stand", ArmorStandMeta::new), entry("minecraft:arrow", ArrowMeta::new), @@ -83,6 +84,7 @@ record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType { entry("minecraft:bee", BeeMeta::new), entry("minecraft:blaze", BlazeMeta::new), entry("minecraft:boat", BoatMeta::new), + entry("minecraft:chest_boat", EntityMeta::new), // TODO dedicated metadata entry("minecraft:cat", CatMeta::new), entry("minecraft:cave_spider", CaveSpiderMeta::new), entry("minecraft:chicken", ChickenMeta::new), @@ -105,6 +107,7 @@ record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType { entry("minecraft:falling_block", FallingBlockMeta::new), entry("minecraft:firework_rocket", FireworkRocketMeta::new), entry("minecraft:fox", FoxMeta::new), + entry("minecraft:frog", EntityMeta::new), // TODO dedicated metadata entry("minecraft:ghast", GhastMeta::new), entry("minecraft:giant", GiantMeta::new), entry("minecraft:glow_item_frame", GlowItemFrameMeta::new), @@ -164,6 +167,7 @@ record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType { entry("minecraft:squid", SquidMeta::new), entry("minecraft:stray", StrayMeta::new), entry("minecraft:strider", StriderMeta::new), + entry("minecraft:tadpole", EntityMeta::new), // TODO dedicated metadata entry("minecraft:egg", ThrownEggMeta::new), entry("minecraft:ender_pearl", ThrownEnderPearlMeta::new), entry("minecraft:experience_bottle", ThrownExperienceBottleMeta::new), @@ -176,6 +180,7 @@ record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType { entry("minecraft:villager", VillagerMeta::new), entry("minecraft:vindicator", VindicatorMeta::new), entry("minecraft:wandering_trader", WanderingTraderMeta::new), + entry("minecraft:warden", EntityMeta::new), // TODO dedicated metadata entry("minecraft:witch", WitchMeta::new), entry("minecraft:wither", WitherMeta::new), entry("minecraft:wither_skeleton", WitherSkeletonMeta::new), diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 3b67896ac..a95545f13 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -51,7 +51,6 @@ import net.minestom.server.network.ConnectionManager; import net.minestom.server.network.ConnectionState; import net.minestom.server.network.PlayerProvider; import net.minestom.server.network.packet.client.ClientPacket; -import net.minestom.server.network.packet.client.play.ClientChatMessagePacket; import net.minestom.server.network.packet.server.SendablePacket; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.login.LoginDisconnectPacket; @@ -247,10 +246,11 @@ public class Player extends LivingEntity implements CommandSender, Localizable, this.dimensionType = spawnInstance.getDimensionType(); NBTCompound nbt = NBT.Compound(Map.of( + "minecraft:chat_type", Messenger.chatRegistry(), "minecraft:dimension_type", MinecraftServer.getDimensionTypeManager().toNBT(), "minecraft:worldgen/biome", MinecraftServer.getBiomeManager().toNBT())); final JoinGamePacket joinGamePacket = new JoinGamePacket(getEntityId(), false, gameMode, null, - List.of("minestom:world"), nbt, dimensionType.toNBT(), dimensionType.getName().asString(), + List.of("minestom:world"), nbt, dimensionType.toString(), "minestom:world", 0, 0, MinecraftServer.getChunkViewDistance(), MinecraftServer.getChunkViewDistance(), false, true, false, levelFlat); sendPacket(joinGamePacket); @@ -430,7 +430,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, setFireForDuration(0); setOnFire(false); refreshHealth(); - sendPacket(new RespawnPacket(getDimensionType(), getDimensionType().getName().asString(), + sendPacket(new RespawnPacket(getDimensionType().toString(), getDimensionType().getName().asString(), 0, gameMode, gameMode, false, levelFlat, true)); PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(this); @@ -664,15 +664,6 @@ public class Player extends LivingEntity implements CommandSender, Localizable, Messenger.sendMessage(this, message, ChatPosition.fromMessageType(type), source.uuid()); } - /** - * Makes the player send a message (can be used for commands). - * - * @param message the message that the player will send - */ - public void chat(@NotNull String message) { - addPacketToQueue(new ClientChatMessagePacket(message)); - } - @Override public void playSound(@NotNull Sound sound) { this.playSound(sound, this.position.x(), this.position.y(), this.position.z()); @@ -937,7 +928,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, final PlayerInfoPacket removePlayerPacket = getRemovePlayerToList(); final PlayerInfoPacket addPlayerPacket = getAddPlayerToList(); - RespawnPacket respawnPacket = new RespawnPacket(getDimensionType(), getDimensionType().getName().asString(), + RespawnPacket respawnPacket = new RespawnPacket(getDimensionType().toString(), "minestom:world", 0, gameMode, gameMode, false, levelFlat, true); sendPacket(removePlayerPacket); @@ -1310,7 +1301,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, Check.argCondition(dimensionType.equals(getDimensionType()), "The dimension needs to be different than the current one!"); this.dimensionType = dimensionType; - sendPacket(new RespawnPacket(dimensionType, dimensionType.getName().asString(), + sendPacket(new RespawnPacket(dimensionType.toString(), "minestom:world", 0, gameMode, gameMode, false, levelFlat, true)); refreshClientStateAfterRespawn(); } @@ -1889,7 +1880,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, List.of(new PlayerInfoPacket.AddPlayer.Property("textures", skin.textures(), skin.signature())) : Collections.emptyList(); return new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER, - new PlayerInfoPacket.AddPlayer(getUuid(), getUsername(), prop, getGameMode(), getLatency(), displayName)); + new PlayerInfoPacket.AddPlayer(getUuid(), getUsername(), prop, getGameMode(), getLatency(), displayName, null)); } /** diff --git a/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java b/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java index fa48a645f..841e274ae 100644 --- a/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java +++ b/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java @@ -139,7 +139,7 @@ public class FakePlayerController { * @param hand The hand in which an ite mshould be. */ public void useItem(Player.Hand hand) { - addToQueue(new ClientUseItemPacket(hand)); + addToQueue(new ClientUseItemPacket(hand, 0)); } /** @@ -159,7 +159,7 @@ public class FakePlayerController { * @param blockFace From where the block is struck. */ public void startDigging(Point blockPosition, BlockFace blockFace) { - addToQueue(new ClientPlayerDiggingPacket(ClientPlayerDiggingPacket.Status.STARTED_DIGGING, blockPosition, blockFace)); + addToQueue(new ClientPlayerDiggingPacket(ClientPlayerDiggingPacket.Status.STARTED_DIGGING, blockPosition, blockFace, 0)); } /** @@ -169,7 +169,7 @@ public class FakePlayerController { * @param blockFace From where the block is struck. */ public void stopDigging(Point blockPosition, BlockFace blockFace) { - addToQueue(new ClientPlayerDiggingPacket(ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING, blockPosition, blockFace)); + addToQueue(new ClientPlayerDiggingPacket(ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING, blockPosition, blockFace, 0)); } /** @@ -179,7 +179,7 @@ public class FakePlayerController { * @param blockFace From where the block is struck. */ public void finishDigging(Point blockPosition, BlockFace blockFace) { - addToQueue(new ClientPlayerDiggingPacket(ClientPlayerDiggingPacket.Status.FINISHED_DIGGING, blockPosition, blockFace)); + addToQueue(new ClientPlayerDiggingPacket(ClientPlayerDiggingPacket.Status.FINISHED_DIGGING, blockPosition, blockFace, 0)); } /** diff --git a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java index ad1ce8817..0b5f955c6 100644 --- a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java +++ b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java @@ -21,6 +21,7 @@ import net.minestom.server.inventory.PlayerInventory; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; import net.minestom.server.network.packet.client.play.ClientPlayerBlockPlacementPacket; +import net.minestom.server.network.packet.server.play.AcknowledgeBlockChangePacket; import net.minestom.server.network.packet.server.play.BlockChangePacket; import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.server.utils.validate.Check; @@ -139,6 +140,7 @@ public class BlockPlacementListener { return; } // Place the block + player.sendPacket(new AcknowledgeBlockChangePacket(packet.sequence())); instance.placeBlock(new BlockHandler.PlayerPlacement(resultBlock, instance, placementPosition, player, hand, blockFace, packet.cursorPositionX(), packet.cursorPositionY(), packet.cursorPositionZ())); // Block consuming diff --git a/src/main/java/net/minestom/server/listener/ChatMessageListener.java b/src/main/java/net/minestom/server/listener/ChatMessageListener.java index 2aadf723a..f82ca0e91 100644 --- a/src/main/java/net/minestom/server/listener/ChatMessageListener.java +++ b/src/main/java/net/minestom/server/listener/ChatMessageListener.java @@ -11,6 +11,7 @@ import net.minestom.server.message.ChatPosition; import net.minestom.server.message.Messenger; import net.minestom.server.network.ConnectionManager; import net.minestom.server.network.packet.client.play.ClientChatMessagePacket; +import net.minestom.server.network.packet.client.play.ClientCommandChatPacket; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -21,26 +22,17 @@ public class ChatMessageListener { private static final CommandManager COMMAND_MANAGER = MinecraftServer.getCommandManager(); private static final ConnectionManager CONNECTION_MANAGER = MinecraftServer.getConnectionManager(); - public static void listener(ClientChatMessagePacket packet, Player player) { - String message = packet.message(); - - final String cmdPrefix = CommandManager.COMMAND_PREFIX; - if (message.startsWith(cmdPrefix)) { - // The message is a command - final String command = message.replaceFirst(cmdPrefix, ""); - - // check if we can receive commands - if (Messenger.canReceiveCommand(player)) { - COMMAND_MANAGER.execute(player, command); - } else { - Messenger.sendRejectionMessage(player); - } - - // Do not call chat event - return; + public static void commandChatListener(ClientCommandChatPacket packet, Player player) { + final String command = packet.message(); + if (Messenger.canReceiveCommand(player)) { + COMMAND_MANAGER.execute(player, command); + } else { + Messenger.sendRejectionMessage(player); } + } - // check if we can receive messages + public static void chatMessageListener(ClientChatMessagePacket packet, Player player) { + final String message = packet.message(); if (!Messenger.canReceiveMessage(player)) { Messenger.sendRejectionMessage(player); return; diff --git a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java index 43eb03a94..733066519 100644 --- a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java +++ b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java @@ -15,7 +15,7 @@ import net.minestom.server.inventory.PlayerInventory; import net.minestom.server.item.ItemStack; import net.minestom.server.item.StackingRule; import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket; -import net.minestom.server.network.packet.server.play.AcknowledgePlayerDiggingPacket; +import net.minestom.server.network.packet.server.play.AcknowledgeBlockChangePacket; import org.jetbrains.annotations.NotNull; public final class PlayerDiggingListener { @@ -47,8 +47,7 @@ public final class PlayerDiggingListener { } // Acknowledge start/cancel/finish digging status if (diggingResult != null) { - player.sendPacket(new AcknowledgePlayerDiggingPacket(blockPosition, diggingResult.block, - status, diggingResult.success)); + player.sendPacket(new AcknowledgeBlockChangePacket(packet.sequence())); } } diff --git a/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java b/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java index b8c52f069..863a86eb9 100644 --- a/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java +++ b/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java @@ -26,7 +26,8 @@ public final class PacketListenerManager { this.serverProcess = serverProcess; setListener(ClientKeepAlivePacket.class, KeepAliveListener::listener); - setListener(ClientChatMessagePacket.class, ChatMessageListener::listener); + setListener(ClientCommandChatPacket.class, ChatMessageListener::commandChatListener); + setListener(ClientChatMessagePacket.class, ChatMessageListener::chatMessageListener); setListener(ClientClickWindowPacket.class, WindowListener::clickWindowListener); setListener(ClientCloseWindowPacket.class, WindowListener::closeWindowListener); setListener(ClientPongPacket.class, WindowListener::pong); diff --git a/src/main/java/net/minestom/server/message/ChatPosition.java b/src/main/java/net/minestom/server/message/ChatPosition.java index 2c9ab538c..bedb62a22 100644 --- a/src/main/java/net/minestom/server/message/ChatPosition.java +++ b/src/main/java/net/minestom/server/message/ChatPosition.java @@ -67,7 +67,7 @@ public enum ChatPosition { * @param id the id * @return the chat position */ - public static @NotNull ChatPosition fromPacketID(byte id) { + public static @NotNull ChatPosition fromPacketID(int id) { return switch (id) { case 0 -> CHAT; case 1 -> SYSTEM_MESSAGE; diff --git a/src/main/java/net/minestom/server/message/Messenger.java b/src/main/java/net/minestom/server/message/Messenger.java index 3fff681de..2c3a29257 100644 --- a/src/main/java/net/minestom/server/message/Messenger.java +++ b/src/main/java/net/minestom/server/message/Messenger.java @@ -3,11 +3,15 @@ package net.minestom.server.message; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minestom.server.entity.Player; -import net.minestom.server.network.packet.server.play.ChatMessagePacket; +import net.minestom.server.network.packet.server.play.SystemChatPacket; import net.minestom.server.utils.PacketUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; +import org.jglrxavpok.hephaistos.nbt.NBTException; +import org.jglrxavpok.hephaistos.parser.SNBTParser; +import java.io.StringReader; import java.util.Collection; import java.util.Objects; import java.util.UUID; @@ -21,7 +25,47 @@ public final class Messenger { */ public static final Component CANNOT_SEND_MESSAGE = Component.translatable("chat.cannotSend", NamedTextColor.RED); private static final UUID NO_SENDER = new UUID(0, 0); - private static final ChatMessagePacket CANNOT_SEND_PACKET = new ChatMessagePacket(CANNOT_SEND_MESSAGE, ChatPosition.SYSTEM_MESSAGE, NO_SENDER); + private static final SystemChatPacket CANNOT_SEND_PACKET = new SystemChatPacket(CANNOT_SEND_MESSAGE, false); + + private static final NBTCompound CHAT_REGISTRY; + + static { + try { + CHAT_REGISTRY = (NBTCompound) new SNBTParser(new StringReader( + "{\n" + + " \"type\": \"minecraft:chat_type\",\n" + + " \"value\": [\n" + + " {\n" + + " \"name\":\"minecraft:chat\",\n" + + " \"id\":1,\n" + + " \"element\":{\n" + + " \"chat\":{\n" + + " \"translation_key\":\"chat.type.text\",\n" + + " \"parameters\":[\n" + + " \"sender\",\n" + + " \"content\"\n" + + " ]\n" + + " },\n" + + " \"narration\":{\n" + + " \"translation_key\":\"chat.type.text.narrate\",\n" + + " \"parameters\":[\n" + + " \"sender\",\n" + + " \"content\"\n" + + " ]\n" + + " }\n" + + " }\n" + + " }" + + " ]\n" + + "}" + )).parse(); + } catch (NBTException e) { + throw new RuntimeException(e); + } + } + + public static @NotNull NBTCompound chatRegistry() { + return CHAT_REGISTRY; + } /** * Sends a message to a player, respecting their chat settings. @@ -34,7 +78,7 @@ public final class Messenger { */ public static boolean sendMessage(@NotNull Player player, @NotNull Component message, @NotNull ChatPosition position, @Nullable UUID uuid) { if (getChatMessageType(player).accepts(position)) { - player.sendPacket(new ChatMessagePacket(message, position, Objects.requireNonNullElse(uuid, NO_SENDER))); + player.sendPacket(new SystemChatPacket(message, false)); return true; } return false; @@ -50,7 +94,7 @@ public final class Messenger { */ public static void sendMessage(@NotNull Collection players, @NotNull Component message, @NotNull ChatPosition position, @Nullable UUID uuid) { - PacketUtils.sendGroupedPacket(players, new ChatMessagePacket(message, position, Objects.requireNonNullElse(uuid, NO_SENDER)), + PacketUtils.sendGroupedPacket(players, new SystemChatPacket(message, false), player -> getChatMessageType(player).accepts(position)); } diff --git a/src/main/java/net/minestom/server/network/ConnectionManager.java b/src/main/java/net/minestom/server/network/ConnectionManager.java index 8c0105cb3..b080de14e 100644 --- a/src/main/java/net/minestom/server/network/ConnectionManager.java +++ b/src/main/java/net/minestom/server/network/ConnectionManager.java @@ -218,7 +218,7 @@ public final class ConnectionManager { } } // Send login success packet - LoginSuccessPacket loginSuccessPacket = new LoginSuccessPacket(player.getUuid(), player.getUsername()); + LoginSuccessPacket loginSuccessPacket = new LoginSuccessPacket(player.getUuid(), player.getUsername(), 0); playerConnection.sendPacket(loginSuccessPacket); playerConnection.setConnectionState(ConnectionState.PLAY); if (register) registerPlayer(player); diff --git a/src/main/java/net/minestom/server/network/PacketProcessor.java b/src/main/java/net/minestom/server/network/PacketProcessor.java index e96ad530e..5d5f5fd0d 100644 --- a/src/main/java/net/minestom/server/network/PacketProcessor.java +++ b/src/main/java/net/minestom/server/network/PacketProcessor.java @@ -39,7 +39,7 @@ public record PacketProcessor(@NotNull ClientPacketsHandler statusHandler, }; } - public void process(@NotNull PlayerConnection connection, int packetId, ByteBuffer body) { + public ClientPacket process(@NotNull PlayerConnection connection, int packetId, ByteBuffer body) { final ClientPacket packet = create(connection.getConnectionState(), packetId, body); if (packet instanceof ClientPreplayPacket prePlayPacket) { prePlayPacket.process(connection); @@ -48,5 +48,6 @@ public record PacketProcessor(@NotNull ClientPacketsHandler statusHandler, assert player != null; player.addPacketToQueue(packet); } + return packet; } } diff --git a/src/main/java/net/minestom/server/network/packet/client/ClientPacketsHandler.java b/src/main/java/net/minestom/server/network/packet/client/ClientPacketsHandler.java index 28dc79beb..e25f66280 100644 --- a/src/main/java/net/minestom/server/network/packet/client/ClientPacketsHandler.java +++ b/src/main/java/net/minestom/server/network/packet/client/ClientPacketsHandler.java @@ -54,53 +54,55 @@ public sealed class ClientPacketsHandler permits ClientPacketsHandler.Status, Cl public Play() { register(0x00, ClientTeleportConfirmPacket::new); register(0x01, ClientQueryBlockNbtPacket::new); - register(0x03, ClientChatMessagePacket::new); - register(0x04, ClientStatusPacket::new); - register(0x05, ClientSettingsPacket::new); - register(0x06, ClientTabCompletePacket::new); - register(0x07, ClientClickWindowButtonPacket::new); - register(0x08, ClientClickWindowPacket::new); - register(0x09, ClientCloseWindowPacket::new); - register(0x0A, ClientPluginMessagePacket::new); - register(0x0B, ClientEditBookPacket::new); - register(0x0C, ClientQueryEntityNbtPacket::new); - register(0x0D, ClientInteractEntityPacket::new); - register(0x0E, ClientGenerateStructurePacket::new); - register(0x0F, ClientKeepAlivePacket::new); - - // 0x10 packet not used server-side - register(0x11, ClientPlayerPositionPacket::new); - register(0x12, ClientPlayerPositionAndRotationPacket::new); - register(0x13, ClientPlayerRotationPacket::new); - register(0x14, ClientPlayerPacket::new); - register(0x15, ClientVehicleMovePacket::new); - register(0x16, ClientSteerBoatPacket::new); - register(0x17, ClientPickItemPacket::new); - register(0x18, ClientCraftRecipeRequest::new); - register(0x19, ClientPlayerAbilitiesPacket::new); - register(0x1A, ClientPlayerDiggingPacket::new); - register(0x1B, ClientEntityActionPacket::new); - register(0x1C, ClientSteerVehiclePacket::new); - register(0x1D, ClientPongPacket::new); - register(0x1E, ClientSetRecipeBookStatePacket::new); - register(0x1F, ClientSetDisplayedRecipePacket::new); - - register(0x20, ClientNameItemPacket::new); - register(0x21, ClientResourcePackStatusPacket::new); - register(0x22, ClientAdvancementTabPacket::new); - register(0x23, ClientSelectTradePacket::new); - register(0x24, ClientSetBeaconEffectPacket::new); - register(0x25, ClientHeldItemChangePacket::new); - register(0x26, ClientUpdateCommandBlockPacket::new); - register(0x27, ClientUpdateCommandBlockMinecartPacket::new); - register(0x28, ClientCreativeInventoryActionPacket::new); - //Update Jigsaw Block?? - register(0x2A, ClientUpdateStructureBlockPacket::new); - register(0x2B, ClientUpdateSignPacket::new); - register(0x2C, ClientAnimationPacket::new); - register(0x2D, ClientSpectatePacket::new); - register(0x2E, ClientPlayerBlockPlacementPacket::new); - register(0x2F, ClientUseItemPacket::new); + // 0x02 difficulty packet + register(0x03, ClientChatAckPacket::new); + register(0x04, ClientCommandChatPacket::new); + register(0x05, ClientChatMessagePacket::new); + register(0x06, ClientChatPreviewPacket::new); + register(0x07, ClientStatusPacket::new); + register(0x08, ClientSettingsPacket::new); + register(0x09, ClientTabCompletePacket::new); + register(0x0A, ClientClickWindowButtonPacket::new); + register(0x0B, ClientClickWindowPacket::new); + register(0x0C, ClientCloseWindowPacket::new); + register(0x0D, ClientPluginMessagePacket::new); + register(0x0E, ClientEditBookPacket::new); + register(0x0F, ClientQueryEntityNbtPacket::new); + register(0x10, ClientInteractEntityPacket::new); + register(0x11, ClientGenerateStructurePacket::new); + register(0x12, ClientKeepAlivePacket::new); + // 0x12 packet not used server-side + register(0x14, ClientPlayerPositionPacket::new); + register(0x15, ClientPlayerPositionAndRotationPacket::new); + register(0x16, ClientPlayerRotationPacket::new); + register(0x17, ClientPlayerPacket::new); + register(0x18, ClientVehicleMovePacket::new); + register(0x19, ClientSteerBoatPacket::new); + register(0x1A, ClientPickItemPacket::new); + register(0x1B, ClientCraftRecipeRequest::new); + register(0x1C, ClientPlayerAbilitiesPacket::new); + register(0x1D, ClientPlayerDiggingPacket::new); + register(0x1E, ClientEntityActionPacket::new); + register(0x1F, ClientSteerVehiclePacket::new); + register(0x20, ClientPongPacket::new); + register(0x21, ClientSetRecipeBookStatePacket::new); + register(0x22, ClientSetDisplayedRecipePacket::new); + register(0x23, ClientNameItemPacket::new); + register(0x24, ClientResourcePackStatusPacket::new); + register(0x25, ClientAdvancementTabPacket::new); + register(0x26, ClientSelectTradePacket::new); + register(0x27, ClientSetBeaconEffectPacket::new); + register(0x28, ClientHeldItemChangePacket::new); + register(0x29, ClientUpdateCommandBlockPacket::new); + register(0x2A, ClientUpdateCommandBlockMinecartPacket::new); + register(0x2B, ClientCreativeInventoryActionPacket::new); + // 0x2B Update Jigsaw Block + register(0x2D, ClientUpdateStructureBlockPacket::new); + register(0x2E, ClientUpdateSignPacket::new); + register(0x2F, ClientAnimationPacket::new); + register(0x30, ClientSpectatePacket::new); + register(0x31, ClientPlayerBlockPlacementPacket::new); + register(0x32, ClientUseItemPacket::new); } } } diff --git a/src/main/java/net/minestom/server/network/packet/client/login/EncryptionResponsePacket.java b/src/main/java/net/minestom/server/network/packet/client/login/EncryptionResponsePacket.java index 68562fa35..5c10f3f32 100644 --- a/src/main/java/net/minestom/server/network/packet/client/login/EncryptionResponsePacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/login/EncryptionResponsePacket.java @@ -3,14 +3,19 @@ package net.minestom.server.network.packet.client.login; import com.google.gson.Gson; import com.google.gson.JsonObject; import net.minestom.server.MinecraftServer; +import net.minestom.server.crypto.SaltSignaturePair; +import net.minestom.server.crypto.SignatureValidator; import net.minestom.server.extras.MojangAuth; import net.minestom.server.extras.mojangAuth.MojangCrypt; import net.minestom.server.network.packet.client.ClientPreplayPacket; import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.network.player.PlayerSocketConnection; +import net.minestom.server.utils.Either; +import net.minestom.server.utils.InterfaceUtils; import net.minestom.server.utils.async.AsyncUtils; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.crypto.KeyUtils; import org.jetbrains.annotations.NotNull; import javax.crypto.SecretKey; @@ -24,11 +29,11 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.UUID; -public record EncryptionResponsePacket(byte[] sharedSecret, byte[] verifyToken) implements ClientPreplayPacket { +public record EncryptionResponsePacket(byte[] sharedSecret, Either nonceOrSignature) implements ClientPreplayPacket { private static final Gson GSON = new Gson(); public EncryptionResponsePacket(BinaryReader reader) { - this(reader.readByteArray(), reader.readByteArray()); + this(reader.readByteArray(), reader.readEither(BinaryReader::readByteArray, SaltSignaturePair::new)); } @Override @@ -41,8 +46,20 @@ public record EncryptionResponsePacket(byte[] sharedSecret, byte[] verifyToken) // Shouldn't happen return; } - if (!Arrays.equals(socketConnection.getNonce(), getNonce())) { - MinecraftServer.LOGGER.error("{} tried to login with an invalid nonce!", loginUsername); + + final boolean hasPublicKey = connection.playerPublicKey() != null; + final boolean verificationFailed = nonceOrSignature.map( + nonce -> hasPublicKey || !Arrays.equals(socketConnection.getNonce(), + MojangCrypt.decryptUsingKey(MojangAuth.getKeyPair().getPrivate(), nonce)), + signature -> !hasPublicKey || !SignatureValidator + .from(connection.playerPublicKey().publicKey(), KeyUtils.SignatureAlgorithm.SHA256withRSA) + .validate(binaryWriter -> { + binaryWriter.writeBytes(socketConnection.getNonce()); + binaryWriter.writeLong(signature.salt()); + }, signature.signature())); + + if (verificationFailed) { + MinecraftServer.LOGGER.error("Encryption failed for {}", loginUsername); return; } @@ -65,12 +82,14 @@ public record EncryptionResponsePacket(byte[] sharedSecret, byte[] verifyToken) client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).whenComplete((response, throwable) -> { if (throwable != null) { MinecraftServer.getExceptionManager().handleException(throwable); + //todo disconnect with reason return; } try { final JsonObject gameProfile = GSON.fromJson(response.body(), JsonObject.class); if (gameProfile == null) { // Invalid response + //todo disconnect with reason return; } socketConnection.setEncryptionKey(getSecretKey()); @@ -90,15 +109,10 @@ public record EncryptionResponsePacket(byte[] sharedSecret, byte[] verifyToken) @Override public void write(@NotNull BinaryWriter writer) { writer.writeByteArray(sharedSecret); - writer.writeByteArray(verifyToken); + writer.writeEither(nonceOrSignature, BinaryWriter::writeByteArray, InterfaceUtils.flipBiConsumer(SaltSignaturePair::write)); } private SecretKey getSecretKey() { return MojangCrypt.decryptByteToSecretKey(MojangAuth.getKeyPair().getPrivate(), sharedSecret); } - - private byte[] getNonce() { - return MojangAuth.getKeyPair().getPrivate() == null ? - this.verifyToken : MojangCrypt.decryptUsingKey(MojangAuth.getKeyPair().getPrivate(), this.verifyToken); - } } diff --git a/src/main/java/net/minestom/server/network/packet/client/login/LoginStartPacket.java b/src/main/java/net/minestom/server/network/packet/client/login/LoginStartPacket.java index bfd5c24cf..418c82c6e 100644 --- a/src/main/java/net/minestom/server/network/packet/client/login/LoginStartPacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/login/LoginStartPacket.java @@ -2,6 +2,9 @@ package net.minestom.server.network.packet.client.login; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; +import net.minestom.server.MinecraftServer; +import net.minestom.server.crypto.PlayerPublicKey; +import net.minestom.server.crypto.SignatureValidator; import net.minestom.server.entity.Player; import net.minestom.server.extras.MojangAuth; import net.minestom.server.extras.bungee.BungeeCordProxy; @@ -16,19 +19,47 @@ import net.minestom.server.network.player.PlayerSocketConnection; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.time.Instant; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; -public record LoginStartPacket(@NotNull String username) implements ClientPreplayPacket { +public record LoginStartPacket(@NotNull String username, + @Nullable PlayerPublicKey publicKey, + @Nullable UUID profileId) implements ClientPreplayPacket { private static final Component ALREADY_CONNECTED = Component.text("You are already on this server", NamedTextColor.RED); public LoginStartPacket(BinaryReader reader) { - this(reader.readSizedString(16)); + this(reader.readSizedString(16), + reader.readBoolean() ? new PlayerPublicKey(reader) : null, + reader.readBoolean() ? reader.readUuid() : null); } @Override public void process(@NotNull PlayerConnection connection) { + // TODO use uuid + // TODO configurable check & messages + if (publicKey != null) { + if (!SignatureValidator.YGGDRASIL.validate(binaryWriter -> { + if (profileId != null) { + binaryWriter.writeLong(profileId.getMostSignificantBits()); + binaryWriter.writeLong(profileId.getLeastSignificantBits()); + } else { + MinecraftServer.LOGGER.warn("Profile ID was null for player {}, signature will not match!", username); + } + binaryWriter.writeLong(publicKey.expiresAt().toEpochMilli()); + binaryWriter.writeBytes(publicKey.publicKey().getEncoded()); + }, publicKey.signature())) { + connection.sendPacket(new LoginDisconnectPacket(Component.text("Invalid Profile Public Key!"))); + connection.disconnect(); + } + if (publicKey.expiresAt().isBefore(Instant.now())) { + connection.sendPacket(new LoginDisconnectPacket(Component.text("Expired Profile Public Key!"))); + connection.disconnect(); + } + connection.setPlayerPublicKey(publicKey); + } final boolean isSocketConnection = connection instanceof PlayerSocketConnection; // Proxy support (only for socket clients) and cache the login username if (isSocketConnection) { diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientChatAckPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientChatAckPacket.java new file mode 100644 index 000000000..4032d1932 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientChatAckPacket.java @@ -0,0 +1,18 @@ +package net.minestom.server.network.packet.client.play; + +import net.minestom.server.crypto.LastSeenMessages; +import net.minestom.server.network.packet.client.ClientPacket; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; + +public record ClientChatAckPacket(@NotNull LastSeenMessages.Update update) implements ClientPacket { + public ClientChatAckPacket(BinaryReader reader) { + this(new LastSeenMessages.Update(reader)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.write(update); + } +} diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientChatMessagePacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientChatMessagePacket.java index 900c68caf..73192ad85 100644 --- a/src/main/java/net/minestom/server/network/packet/client/play/ClientChatMessagePacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientChatMessagePacket.java @@ -1,11 +1,16 @@ package net.minestom.server.network.packet.client.play; +import net.minestom.server.crypto.LastSeenMessages; +import net.minestom.server.crypto.MessageSignature; import net.minestom.server.network.packet.client.ClientPacket; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; -public record ClientChatMessagePacket(@NotNull String message) implements ClientPacket { +public record ClientChatMessagePacket(@NotNull String message, + long timestamp, long salt, @NotNull MessageSignature signature, + boolean signedPreview, + @NotNull LastSeenMessages.Update lastSeenMessages) implements ClientPacket { public ClientChatMessagePacket { if (message.length() > 256) { throw new IllegalArgumentException("Message cannot be more than 256 characters long."); @@ -13,11 +18,19 @@ public record ClientChatMessagePacket(@NotNull String message) implements Client } public ClientChatMessagePacket(BinaryReader reader) { - this(reader.readSizedString(256)); + this(reader.readSizedString(256), + reader.readLong(), reader.readLong(), new MessageSignature(reader), + reader.readBoolean(), + new LastSeenMessages.Update(reader)); } @Override public void write(@NotNull BinaryWriter writer) { writer.writeSizedString(message); + writer.writeLong(timestamp); + writer.writeLong(salt); + writer.write(signature); + writer.writeBoolean(signedPreview); + writer.write(lastSeenMessages); } } diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientChatPreviewPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientChatPreviewPacket.java new file mode 100644 index 000000000..d2ec1fc09 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientChatPreviewPacket.java @@ -0,0 +1,18 @@ +package net.minestom.server.network.packet.client.play; + +import net.minestom.server.network.packet.client.ClientPacket; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; + +public record ClientChatPreviewPacket(int queryId, @NotNull String query) implements ClientPacket { + public ClientChatPreviewPacket(BinaryReader reader) { + this(reader.readInt(), reader.readSizedString(256)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeInt(queryId); + writer.writeSizedString(query); + } +} diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientCommandChatPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientCommandChatPacket.java new file mode 100644 index 000000000..910f16fc9 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientCommandChatPacket.java @@ -0,0 +1,29 @@ +package net.minestom.server.network.packet.client.play; + +import net.minestom.server.crypto.ArgumentSignatures; +import net.minestom.server.crypto.LastSeenMessages; +import net.minestom.server.network.packet.client.ClientPacket; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; + +public record ClientCommandChatPacket(@NotNull String message, long timestamp, + long salt, @NotNull ArgumentSignatures signatures, + boolean signedPreview, + LastSeenMessages.@NotNull Update lastSeenMessages) implements ClientPacket { + + public ClientCommandChatPacket(BinaryReader reader) { + this(reader.readSizedString(256), reader.readLong(), + reader.readLong(), new ArgumentSignatures(reader), reader.readBoolean(), new LastSeenMessages.Update(reader)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeSizedString(message); + writer.writeLong(timestamp); + writer.writeLong(salt); + writer.write(signatures); + writer.writeBoolean(signedPreview); + writer.write(lastSeenMessages); + } +} diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerBlockPlacementPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerBlockPlacementPacket.java index 6f3b1b8f6..d8ea14ddb 100644 --- a/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerBlockPlacementPacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerBlockPlacementPacket.java @@ -11,12 +11,12 @@ import org.jetbrains.annotations.NotNull; public record ClientPlayerBlockPlacementPacket(@NotNull Player.Hand hand, @NotNull Point blockPosition, @NotNull BlockFace blockFace, float cursorPositionX, float cursorPositionY, float cursorPositionZ, - boolean insideBlock) implements ClientPacket { + boolean insideBlock, int sequence) implements ClientPacket { public ClientPlayerBlockPlacementPacket(BinaryReader reader) { this(Player.Hand.values()[reader.readVarInt()], reader.readBlockPosition(), BlockFace.values()[reader.readVarInt()], reader.readFloat(), reader.readFloat(), reader.readFloat(), - reader.readBoolean()); + reader.readBoolean(), reader.readVarInt()); } @Override @@ -28,5 +28,6 @@ public record ClientPlayerBlockPlacementPacket(@NotNull Player.Hand hand, @NotNu writer.writeFloat(cursorPositionY); writer.writeFloat(cursorPositionZ); writer.writeBoolean(insideBlock); + writer.writeVarInt(sequence); } } diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerDiggingPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerDiggingPacket.java index 189604a07..d9fc1e491 100644 --- a/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerDiggingPacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerDiggingPacket.java @@ -8,10 +8,10 @@ import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; public record ClientPlayerDiggingPacket(@NotNull Status status, @NotNull Point blockPosition, - @NotNull BlockFace blockFace) implements ClientPacket { + @NotNull BlockFace blockFace, int sequence) implements ClientPacket { public ClientPlayerDiggingPacket(BinaryReader reader) { this(Status.values()[reader.readVarInt()], reader.readBlockPosition(), - BlockFace.values()[reader.readByte()]); + BlockFace.values()[reader.readByte()], reader.readVarInt()); } @Override @@ -19,6 +19,7 @@ public record ClientPlayerDiggingPacket(@NotNull Status status, @NotNull Point b writer.writeVarInt(status.ordinal()); writer.writeBlockPosition(blockPosition); writer.writeByte((byte) blockFace.ordinal()); + writer.writeVarInt(sequence); } public enum Status { diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientSetBeaconEffectPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientSetBeaconEffectPacket.java index 0b0424437..f532ad54c 100644 --- a/src/main/java/net/minestom/server/network/packet/client/play/ClientSetBeaconEffectPacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientSetBeaconEffectPacket.java @@ -1,18 +1,24 @@ package net.minestom.server.network.packet.client.play; import net.minestom.server.network.packet.client.ClientPacket; +import net.minestom.server.potion.PotionType; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public record ClientSetBeaconEffectPacket(int primaryEffect, int secondaryEffect) implements ClientPacket { +public record ClientSetBeaconEffectPacket(@Nullable PotionType primaryEffect, + @Nullable PotionType secondaryEffect) implements ClientPacket { public ClientSetBeaconEffectPacket(BinaryReader reader) { - this(reader.readVarInt(), reader.readVarInt()); + this(reader.readBoolean() ? PotionType.fromId(reader.readVarInt()) : null, + reader.readBoolean() ? PotionType.fromId(reader.readVarInt()) : null); } @Override public void write(@NotNull BinaryWriter writer) { - writer.writeVarInt(primaryEffect); - writer.writeVarInt(secondaryEffect); + writer.writeBoolean(primaryEffect != null); + if (primaryEffect != null) writer.writeVarInt(primaryEffect.id()); + writer.writeBoolean(secondaryEffect != null); + if (secondaryEffect != null) writer.writeVarInt(secondaryEffect.id()); } } diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientUseItemPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientUseItemPacket.java index ed9798aff..3ea3af30b 100644 --- a/src/main/java/net/minestom/server/network/packet/client/play/ClientUseItemPacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientUseItemPacket.java @@ -6,13 +6,14 @@ import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; -public record ClientUseItemPacket(@NotNull Player.Hand hand) implements ClientPacket { +public record ClientUseItemPacket(@NotNull Player.Hand hand, int sequence) implements ClientPacket { public ClientUseItemPacket(BinaryReader reader) { - this(Player.Hand.values()[reader.readVarInt()]); + this(Player.Hand.values()[reader.readVarInt()], reader.readVarInt()); } @Override public void write(@NotNull BinaryWriter writer) { writer.writeVarInt(hand.ordinal()); + writer.writeVarInt(sequence); } } diff --git a/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java b/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java index 91b313869..fc4a119e5 100644 --- a/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java +++ b/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java @@ -1,6 +1,9 @@ package net.minestom.server.network.packet.server; -public class ServerPacketIdentifier { +import java.util.concurrent.atomic.AtomicInteger; + +public final class ServerPacketIdentifier { + private static final AtomicInteger PLAY_ID = new AtomicInteger(0); public static final int LOGIN_DISCONNECT = 0x00; public static final int LOGIN_ENCRYPTION_REQUEST = 0x01; @@ -8,108 +11,116 @@ public class ServerPacketIdentifier { public static final int LOGIN_SET_COMPRESSION = 0x03; public static final int LOGIN_PLUGIN_REQUEST = 0x04; - public static final int SPAWN_ENTITY = 0x00; - public static final int SPAWN_EXPERIENCE_ORB = 0x01; - public static final int SPAWN_LIVING_ENTITY = 0x02; - public static final int SPAWN_PAINTING = 0x03; - public static final int SPAWN_PLAYER = 0x04; - public static final int SCULK_VIBRATION_SIGNAL = 0x05; - public static final int ENTITY_ANIMATION = 0x06; - public static final int STATISTICS = 0x07; - public static final int ACKNOWLEDGE_PLAYER_DIGGING = 0x08; - public static final int BLOCK_BREAK_ANIMATION = 0x09; - public static final int BLOCK_ENTITY_DATA = 0x0A; - public static final int BLOCK_ACTION = 0x0B; - public static final int BLOCK_CHANGE = 0x0C; - public static final int BOSS_BAR = 0x0D; - public static final int SERVER_DIFFICULTY = 0x0E; - public static final int CHAT_MESSAGE = 0x0F; - public static final int CLEAR_TITLES = 0x10; - public static final int TAB_COMPLETE = 0x11; - public static final int DECLARE_COMMANDS = 0x12; - public static final int CLOSE_WINDOW = 0x13; - public static final int WINDOW_ITEMS = 0x14; - public static final int WINDOW_PROPERTY = 0x15; - public static final int SET_SLOT = 0x16; - public static final int SET_COOLDOWN = 0x17; - public static final int PLUGIN_MESSAGE = 0x18; - public static final int NAMED_SOUND_EFFECT = 0x19; - public static final int DISCONNECT = 0x1A; - public static final int ENTITY_STATUS = 0x1B; - public static final int EXPLOSION = 0x1C; - public static final int UNLOAD_CHUNK = 0x1D; - public static final int CHANGE_GAME_STATE = 0x1E; - public static final int OPEN_HORSE_WINDOW = 0x1F; - public static final int INITIALIZE_WORLD_BORDER = 0x20; - public static final int KEEP_ALIVE = 0x21; - public static final int CHUNK_DATA = 0x22; - public static final int EFFECT = 0x23; - public static final int PARTICLE = 0x24; - public static final int UPDATE_LIGHT = 0x25; - public static final int JOIN_GAME = 0x26; - public static final int MAP_DATA = 0x27; - public static final int TRADE_LIST = 0x28; - public static final int ENTITY_POSITION = 0x29; - public static final int ENTITY_POSITION_AND_ROTATION = 0x2A; - public static final int ENTITY_ROTATION = 0x2B; - public static final int VEHICLE_MOVE = 0x2C; - public static final int OPEN_BOOK = 0x2D; - public static final int OPEN_WINDOW = 0x2E; - public static final int OPEN_SIGN_EDITOR = 0x2F; - public static final int PING = 0x30; - public static final int CRAFT_RECIPE_RESPONSE = 0x31; - public static final int PLAYER_ABILITIES = 0x32; - public static final int END_COMBAT_EVENT = 0x33; - public static final int ENTER_COMBAT_EVENT = 0x34; - public static final int DEATH_COMBAT_EVENT = 0x35; - public static final int PLAYER_INFO = 0x36; - public static final int FACE_PLAYER = 0x37; - public static final int PLAYER_POSITION_AND_LOOK = 0x38; - public static final int UNLOCK_RECIPES = 0x39; - public static final int DESTROY_ENTITIES = 0x3A; - public static final int REMOVE_ENTITY_EFFECT = 0x3B; - public static final int RESOURCE_PACK_SEND = 0x3C; - public static final int RESPAWN = 0x3D; - public static final int ENTITY_HEAD_LOOK = 0x3E; - public static final int MULTI_BLOCK_CHANGE = 0x3F; - public static final int SELECT_ADVANCEMENT_TAB = 0x40; - public static final int ACTION_BAR = 0x41; - public static final int WORLD_BORDER_CENTER = 0x42; - public static final int WORLD_BORDER_LERP_SIZE = 0x43; - public static final int WORLD_BORDER_SIZE = 0x44; - public static final int WORLD_BORDER_WARNING_DELAY = 0x45; - public static final int WORLD_BORDER_WARNING_REACH = 0x46; - public static final int CAMERA = 0x47; - public static final int HELD_ITEM_CHANGE = 0x48; - public static final int UPDATE_VIEW_POSITION = 0x49; - public static final int UPDATE_VIEW_DISTANCE = 0x4A; // Not used by the dedicated server - public static final int SPAWN_POSITION = 0x4B; - public static final int DISPLAY_SCOREBOARD = 0x4C; - public static final int ENTITY_METADATA = 0x4D; - public static final int ATTACH_ENTITY = 0x4E; - public static final int ENTITY_VELOCITY = 0x4F; - public static final int ENTITY_EQUIPMENT = 0x50; - public static final int SET_EXPERIENCE = 0x51; - public static final int UPDATE_HEALTH = 0x52; - public static final int SCOREBOARD_OBJECTIVE = 0x53; - public static final int SET_PASSENGERS = 0x54; - public static final int TEAMS = 0x55; - public static final int UPDATE_SCORE = 0x56; - public static final int SET_SIMULATION_DISTANCE = 0x57; - public static final int SET_TITLE_SUBTITLE = 0x58; - public static final int TIME_UPDATE = 0x59; - public static final int SET_TITLE_TEXT = 0x5A; - public static final int SET_TITLE_TIME = 0x5B; - public static final int ENTITY_SOUND_EFFECT = 0x5C; - public static final int SOUND_EFFECT = 0x5D; - public static final int STOP_SOUND = 0x5E; - public static final int PLAYER_LIST_HEADER_AND_FOOTER = 0x5F; - public static final int NBT_QUERY_RESPONSE = 0x60; - public static final int COLLECT_ITEM = 0x61; - public static final int ENTITY_TELEPORT = 0x62; - public static final int ADVANCEMENTS = 0x63; - public static final int ENTITY_PROPERTIES = 0x64; - public static final int ENTITY_EFFECT = 0x65; - public static final int DECLARE_RECIPES = 0x66; - public static final int TAGS = 0x67; + public static final int SPAWN_ENTITY = nextPlayId(); + public static final int SPAWN_EXPERIENCE_ORB = nextPlayId(); + public static final int SPAWN_PLAYER = nextPlayId(); + public static final int ENTITY_ANIMATION = nextPlayId(); + public static final int STATISTICS = nextPlayId(); + public static final int ACKNOWLEDGE_BLOCK_CHANGE = nextPlayId(); + public static final int BLOCK_BREAK_ANIMATION = nextPlayId(); + public static final int BLOCK_ENTITY_DATA = nextPlayId(); + public static final int BLOCK_ACTION = nextPlayId(); + public static final int BLOCK_CHANGE = nextPlayId(); + public static final int BOSS_BAR = nextPlayId(); + public static final int SERVER_DIFFICULTY = nextPlayId(); + public static final int CHAT_PREVIEW = nextPlayId(); + public static final int CLEAR_TITLES = nextPlayId(); + public static final int TAB_COMPLETE = nextPlayId(); + public static final int DECLARE_COMMANDS = nextPlayId(); + public static final int CLOSE_WINDOW = nextPlayId(); + public static final int WINDOW_ITEMS = nextPlayId(); + public static final int WINDOW_PROPERTY = nextPlayId(); + public static final int SET_SLOT = nextPlayId(); + public static final int SET_COOLDOWN = nextPlayId(); + public static final int CUSTOM_CHAT_COMPLETIONS = nextPlayId(); + public static final int PLUGIN_MESSAGE = nextPlayId(); + public static final int NAMED_SOUND_EFFECT = nextPlayId(); + public static final int DELETE_CHAT_MESSAGE = nextPlayId(); + public static final int DISCONNECT = nextPlayId(); + public static final int ENTITY_STATUS = nextPlayId(); + public static final int EXPLOSION = nextPlayId(); + public static final int UNLOAD_CHUNK = nextPlayId(); + public static final int CHANGE_GAME_STATE = nextPlayId(); + public static final int OPEN_HORSE_WINDOW = nextPlayId(); + public static final int INITIALIZE_WORLD_BORDER = nextPlayId(); + public static final int KEEP_ALIVE = nextPlayId(); + public static final int CHUNK_DATA = nextPlayId(); + public static final int EFFECT = nextPlayId(); + public static final int PARTICLE = nextPlayId(); + public static final int UPDATE_LIGHT = nextPlayId(); + public static final int JOIN_GAME = nextPlayId(); + public static final int MAP_DATA = nextPlayId(); + public static final int TRADE_LIST = nextPlayId(); + public static final int ENTITY_POSITION = nextPlayId(); + public static final int ENTITY_POSITION_AND_ROTATION = nextPlayId(); + public static final int ENTITY_ROTATION = nextPlayId(); + public static final int VEHICLE_MOVE = nextPlayId(); + public static final int OPEN_BOOK = nextPlayId(); + public static final int OPEN_WINDOW = nextPlayId(); + public static final int OPEN_SIGN_EDITOR = nextPlayId(); + public static final int PING = nextPlayId(); + public static final int CRAFT_RECIPE_RESPONSE = nextPlayId(); + public static final int PLAYER_ABILITIES = nextPlayId(); + public static final int PLAYER_CHAT_HEADER = nextPlayId(); + public static final int PLAYER_CHAT = nextPlayId(); + public static final int END_COMBAT_EVENT = nextPlayId(); + public static final int ENTER_COMBAT_EVENT = nextPlayId(); + public static final int DEATH_COMBAT_EVENT = nextPlayId(); + public static final int PLAYER_INFO = nextPlayId(); + public static final int FACE_PLAYER = nextPlayId(); + public static final int PLAYER_POSITION_AND_LOOK = nextPlayId(); + public static final int UNLOCK_RECIPES = nextPlayId(); + public static final int DESTROY_ENTITIES = nextPlayId(); + public static final int REMOVE_ENTITY_EFFECT = nextPlayId(); + public static final int RESOURCE_PACK_SEND = nextPlayId(); + public static final int RESPAWN = nextPlayId(); + public static final int ENTITY_HEAD_LOOK = nextPlayId(); + public static final int MULTI_BLOCK_CHANGE = nextPlayId(); + public static final int SELECT_ADVANCEMENT_TAB = nextPlayId(); + public static final int SERVER_DATA = nextPlayId(); + public static final int ACTION_BAR = nextPlayId(); + public static final int WORLD_BORDER_CENTER = nextPlayId(); + public static final int WORLD_BORDER_LERP_SIZE = nextPlayId(); + public static final int WORLD_BORDER_SIZE = nextPlayId(); + public static final int WORLD_BORDER_WARNING_DELAY = nextPlayId(); + public static final int WORLD_BORDER_WARNING_REACH = nextPlayId(); + public static final int CAMERA = nextPlayId(); + public static final int HELD_ITEM_CHANGE = nextPlayId(); + public static final int UPDATE_VIEW_POSITION = nextPlayId(); + public static final int UPDATE_VIEW_DISTANCE = nextPlayId(); // Not used by the dedicated server + public static final int SPAWN_POSITION = nextPlayId(); + public static final int SET_DISPLAY_CHAT_PREVIEW = nextPlayId(); + public static final int DISPLAY_SCOREBOARD = nextPlayId(); + public static final int ENTITY_METADATA = nextPlayId(); + public static final int ATTACH_ENTITY = nextPlayId(); + public static final int ENTITY_VELOCITY = nextPlayId(); + public static final int ENTITY_EQUIPMENT = nextPlayId(); + public static final int SET_EXPERIENCE = nextPlayId(); + public static final int UPDATE_HEALTH = nextPlayId(); + public static final int SCOREBOARD_OBJECTIVE = nextPlayId(); + public static final int SET_PASSENGERS = nextPlayId(); + public static final int TEAMS = nextPlayId(); + public static final int UPDATE_SCORE = nextPlayId(); + public static final int SET_SIMULATION_DISTANCE = nextPlayId(); + public static final int SET_TITLE_SUBTITLE = nextPlayId(); + public static final int TIME_UPDATE = nextPlayId(); + public static final int SET_TITLE_TEXT = nextPlayId(); + public static final int SET_TITLE_TIME = nextPlayId(); + public static final int ENTITY_SOUND_EFFECT = nextPlayId(); + public static final int SOUND_EFFECT = nextPlayId(); + public static final int STOP_SOUND = nextPlayId(); + public static final int SYSTEM_CHAT = nextPlayId(); + public static final int PLAYER_LIST_HEADER_AND_FOOTER = nextPlayId(); + public static final int NBT_QUERY_RESPONSE = nextPlayId(); + public static final int COLLECT_ITEM = nextPlayId(); + public static final int ENTITY_TELEPORT = nextPlayId(); + public static final int ADVANCEMENTS = nextPlayId(); + public static final int ENTITY_PROPERTIES = nextPlayId(); + public static final int ENTITY_EFFECT = nextPlayId(); + public static final int DECLARE_RECIPES = nextPlayId(); + public static final int TAGS = nextPlayId(); + + private static int nextPlayId() { + return PLAY_ID.getAndIncrement(); + } } diff --git a/src/main/java/net/minestom/server/network/packet/server/login/LoginSuccessPacket.java b/src/main/java/net/minestom/server/network/packet/server/login/LoginSuccessPacket.java index 7cf8c200f..85ecb01d5 100644 --- a/src/main/java/net/minestom/server/network/packet/server/login/LoginSuccessPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/login/LoginSuccessPacket.java @@ -8,15 +8,16 @@ import org.jetbrains.annotations.NotNull; import java.util.UUID; -public record LoginSuccessPacket(@NotNull UUID uuid, @NotNull String username) implements ServerPacket { +public record LoginSuccessPacket(@NotNull UUID uuid, @NotNull String username, int properties) implements ServerPacket { public LoginSuccessPacket(BinaryReader reader) { - this(reader.readUuid(), reader.readSizedString()); + this(reader.readUuid(), reader.readSizedString(), reader.readVarInt()); } @Override public void write(@NotNull BinaryWriter writer) { writer.writeUuid(uuid); writer.writeSizedString(username); + writer.writeVarInt(properties); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgeBlockChangePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgeBlockChangePacket.java new file mode 100644 index 000000000..1f11ccde8 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgeBlockChangePacket.java @@ -0,0 +1,23 @@ +package net.minestom.server.network.packet.server.play; + +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; + +public record AcknowledgeBlockChangePacket(int sequence) implements ServerPacket { + public AcknowledgeBlockChangePacket(BinaryReader reader) { + this(reader.readVarInt()); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeVarInt(sequence); + } + + @Override + public int getId() { + return ServerPacketIdentifier.ACKNOWLEDGE_BLOCK_CHANGE; + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgePlayerDiggingPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgePlayerDiggingPacket.java deleted file mode 100644 index ff31908b2..000000000 --- a/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgePlayerDiggingPacket.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.minestom.server.network.packet.server.play; - -import net.minestom.server.coordinate.Point; -import net.minestom.server.instance.block.Block; -import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket; -import net.minestom.server.network.packet.server.ServerPacket; -import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.binary.BinaryReader; -import net.minestom.server.utils.binary.BinaryWriter; -import org.jetbrains.annotations.NotNull; - -public record AcknowledgePlayerDiggingPacket(@NotNull Point blockPosition, int blockStateId, - @NotNull ClientPlayerDiggingPacket.Status status, - boolean successful) implements ServerPacket { - public AcknowledgePlayerDiggingPacket(@NotNull Point blockPosition, Block block, - @NotNull ClientPlayerDiggingPacket.Status status, boolean successful) { - this(blockPosition, block.stateId(), status, successful); - } - - public AcknowledgePlayerDiggingPacket(BinaryReader reader) { - this(reader.readBlockPosition(), reader.readVarInt(), - ClientPlayerDiggingPacket.Status.values()[reader.readVarInt()], reader.readBoolean()); - } - - @Override - public void write(@NotNull BinaryWriter writer) { - writer.writeBlockPosition(blockPosition); - writer.writeVarInt(blockStateId); - writer.writeVarInt(status.ordinal()); - writer.writeBoolean(successful); - } - - @Override - public int getId() { - return ServerPacketIdentifier.ACKNOWLEDGE_PLAYER_DIGGING; - } -} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/BlockActionPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/BlockActionPacket.java index 2a5908946..7e1842d69 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/BlockActionPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/BlockActionPacket.java @@ -15,7 +15,8 @@ public record BlockActionPacket(@NotNull Point blockPosition, byte actionId, } public BlockActionPacket(BinaryReader reader) { - this(reader.readBlockPosition(), reader.readByte(), reader.readByte(), reader.readVarInt()); + this(reader.readBlockPosition(), reader.readByte(), + reader.readByte(), reader.readVarInt()); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ChatPreviewPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ChatPreviewPacket.java new file mode 100644 index 000000000..63cc452c1 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/play/ChatPreviewPacket.java @@ -0,0 +1,42 @@ +package net.minestom.server.network.packet.server.play; + +import net.kyori.adventure.text.Component; +import net.minestom.server.network.packet.server.ComponentHoldingServerPacket; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Collections; +import java.util.function.UnaryOperator; + +public record ChatPreviewPacket(int queryId, @Nullable Component preview) implements ComponentHoldingServerPacket { + public ChatPreviewPacket(BinaryReader reader) { + this(reader.readInt(), reader.readBoolean() ? reader.readComponent() : null); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeInt(queryId); + writer.writeBoolean(preview != null); + if (preview != null) writer.writeComponent(preview); + } + + @Override + public int getId() { + return ServerPacketIdentifier.CHAT_PREVIEW; + } + + @Override + public @NotNull Collection components() { + return Collections.singleton(preview); + } + + @Override + public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator operator) { + return new ChatPreviewPacket(queryId, operator.apply(preview)); + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/CustomChatCompletionPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/CustomChatCompletionPacket.java new file mode 100644 index 000000000..dd22d8927 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/play/CustomChatCompletionPacket.java @@ -0,0 +1,35 @@ +package net.minestom.server.network.packet.server.play; + +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public record CustomChatCompletionPacket(@NotNull Action action, + @NotNull List<@NotNull String> entries) implements ServerPacket { + public CustomChatCompletionPacket { + entries = List.copyOf(entries); + } + + public CustomChatCompletionPacket(BinaryReader reader) { + this(Action.values()[reader.readVarInt()], reader.readVarIntList(BinaryReader::readSizedString)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeVarInt(action.ordinal()); + writer.writeVarIntList(entries, BinaryWriter::writeSizedString); + } + + @Override + public int getId() { + return ServerPacketIdentifier.CUSTOM_CHAT_COMPLETIONS; + } + + public enum Action { + ADD, REMOVE, SET + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/DeclareCommandsPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/DeclareCommandsPacket.java index 5a1a0c95e..10a4571a1 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/DeclareCommandsPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/DeclareCommandsPacket.java @@ -1,7 +1,9 @@ package net.minestom.server.network.packet.server.play; +import net.minestom.server.command.builder.arguments.Argument; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.registry.ProtocolObject; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.Readable; @@ -41,7 +43,7 @@ public record DeclareCommandsPacket(@NotNull List nodes, public int[] children = new int[0]; public int redirectedNode; // Only if flags & 0x08 public String name = ""; // Only for literal and argument - public String parser = ""; // Only for argument + public String parser; // Only for argument public byte[] properties; // Only for argument public String suggestionsType = ""; // Only if flags 0x10 @@ -63,7 +65,8 @@ public record DeclareCommandsPacket(@NotNull List nodes, } if (isArgument()) { - writer.writeSizedString(parser); + final int parserId = Argument.CONTAINER.toId(parser); + writer.writeVarInt(parserId); if (properties != null) { writer.writeBytes(properties); } @@ -87,7 +90,8 @@ public record DeclareCommandsPacket(@NotNull List nodes, } if (isArgument()) { - parser = reader.readSizedString(); + final ProtocolObject object = Argument.CONTAINER.getId(reader.readVarInt()); + parser = object.name(); properties = getProperties(reader, parser); } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/DeleteChatPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/DeleteChatPacket.java new file mode 100644 index 000000000..7796c6c9d --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/play/DeleteChatPacket.java @@ -0,0 +1,24 @@ +package net.minestom.server.network.packet.server.play; + +import net.minestom.server.crypto.MessageSignature; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; + +public record DeleteChatPacket(@NotNull MessageSignature signature) implements ServerPacket { + public DeleteChatPacket(BinaryReader reader) { + this(new MessageSignature(reader)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.write(signature); + } + + @Override + public int getId() { + return ServerPacketIdentifier.DELETE_CHAT_MESSAGE; + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/EntityEffectPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/EntityEffectPacket.java index 1c25936c1..451e1a954 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/EntityEffectPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/EntityEffectPacket.java @@ -6,16 +6,22 @@ import net.minestom.server.potion.Potion; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; -public record EntityEffectPacket(int entityId, @NotNull Potion potion) implements ServerPacket { +public record EntityEffectPacket(int entityId, @NotNull Potion potion, + @Nullable NBTCompound factorCodec) implements ServerPacket { public EntityEffectPacket(BinaryReader reader) { - this(reader.readVarInt(), new Potion(reader)); + this(reader.readVarInt(), new Potion(reader), + reader.readBoolean() ? (NBTCompound) reader.readTag() : null); } @Override public void write(@NotNull BinaryWriter writer) { writer.writeVarInt(entityId); writer.write(potion); + writer.writeBoolean(factorCodec != null); + if (factorCodec != null) writer.writeNBT("", factorCodec); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/EntitySoundEffectPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/EntitySoundEffectPacket.java index 9004d49e3..08db2a702 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/EntitySoundEffectPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/EntitySoundEffectPacket.java @@ -9,9 +9,10 @@ import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; public record EntitySoundEffectPacket(int soundId, Sound.Source source, int entityId, - float volume, float pitch) implements ServerPacket { + float volume, float pitch, long seed) implements ServerPacket { public EntitySoundEffectPacket(BinaryReader reader) { - this(reader.readVarInt(), Sound.Source.values()[reader.readVarInt()], reader.readVarInt(), reader.readFloat(), reader.readFloat()); + this(reader.readVarInt(), Sound.Source.values()[reader.readVarInt()], reader.readVarInt(), + reader.readFloat(), reader.readFloat(), reader.readLong()); } @Override @@ -21,6 +22,7 @@ public record EntitySoundEffectPacket(int soundId, Sound.Source source, int enti writer.writeVarInt(entityId); writer.writeFloat(volume); writer.writeFloat(pitch); + writer.writeLong(seed); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/JoinGamePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/JoinGamePacket.java index 8c399b684..f1e7496c7 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/JoinGamePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/JoinGamePacket.java @@ -11,13 +11,17 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound; import java.util.List; public record JoinGamePacket(int entityId, boolean isHardcore, GameMode gameMode, GameMode previousGameMode, - List worlds, NBTCompound dimensionCodec, NBTCompound dimension, String world, + List worlds, NBTCompound dimensionCodec, String dimensionType, String world, long hashedSeed, int maxPlayers, int viewDistance, int simulationDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, boolean isFlat) implements ServerPacket { + public JoinGamePacket { + worlds = List.copyOf(worlds); + } + public JoinGamePacket(BinaryReader reader) { this(reader.readVarInt(), reader.readBoolean(), GameMode.fromId(reader.readByte()), GameMode.fromId(reader.readByte()), - List.of(reader.readSizedStringArray()), (NBTCompound) reader.readTag(), (NBTCompound) reader.readTag(), reader.readSizedString(), + List.of(reader.readSizedStringArray()), (NBTCompound) reader.readTag(), reader.readSizedString(), reader.readSizedString(), reader.readLong(), reader.readVarInt(), reader.readVarInt(), reader.readVarInt(), reader.readBoolean(), reader.readBoolean(), reader.readBoolean(), reader.readBoolean()); } @@ -34,10 +38,9 @@ public record JoinGamePacket(int entityId, boolean isHardcore, GameMode gameMode } writer.writeVarIntList(worlds, BinaryWriter::writeSizedString); - writer.writeNBT("", dimensionCodec); - writer.writeNBT("", dimension); + writer.writeSizedString(dimensionType); writer.writeSizedString(world); writer.writeLong(hashedSeed); writer.writeVarInt(maxPlayers); @@ -49,6 +52,8 @@ public record JoinGamePacket(int entityId, boolean isHardcore, GameMode gameMode writer.writeBoolean(isDebug); //is flat writer.writeBoolean(isFlat); + + writer.writeBoolean(false); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/NamedSoundEffectPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/NamedSoundEffectPacket.java index 54f848a92..f45b95a4b 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/NamedSoundEffectPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/NamedSoundEffectPacket.java @@ -9,11 +9,11 @@ import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; public record NamedSoundEffectPacket(String soundName, Source source, int x, int y, int z, - float volume, float pitch) implements ServerPacket { + float volume, float pitch, long seed) implements ServerPacket { public NamedSoundEffectPacket(BinaryReader reader) { this(reader.readSizedString(), Source.values()[reader.readVarInt()], reader.readInt() / 8, reader.readInt() / 8, reader.readInt() / 8, - reader.readFloat(), reader.readFloat()); + reader.readFloat(), reader.readFloat(), reader.readLong()); } @Override @@ -25,6 +25,7 @@ public record NamedSoundEffectPacket(String soundName, Source source, int x, int writer.writeInt(z * 8); writer.writeFloat(volume); writer.writeFloat(pitch); + writer.writeLong(seed); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ParticlePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ParticlePacket.java index 3c717308a..c557cb542 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/ParticlePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/ParticlePacket.java @@ -11,7 +11,7 @@ public record ParticlePacket(int particleId, boolean longDistance, float offsetX, float offsetY, float offsetZ, float particleData, int particleCount, byte[] data) implements ServerPacket { public ParticlePacket(BinaryReader reader) { - this(reader.readInt(), reader.readBoolean(), + this(reader.readVarInt(), reader.readBoolean(), reader.readDouble(), reader.readDouble(), reader.readDouble(), reader.readFloat(), reader.readFloat(), reader.readFloat(), reader.readFloat(), reader.readInt(), reader.readRemainingBytes()); @@ -19,7 +19,7 @@ public record ParticlePacket(int particleId, boolean longDistance, @Override public void write(@NotNull BinaryWriter writer) { - writer.writeInt(particleId); + writer.writeVarInt(particleId); writer.writeBoolean(longDistance); writer.writeDouble(x); writer.writeDouble(y); diff --git a/src/main/java/net/minestom/server/network/packet/server/play/PlayerChatHeaderPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/PlayerChatHeaderPacket.java new file mode 100644 index 000000000..65741a7ce --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/play/PlayerChatHeaderPacket.java @@ -0,0 +1,28 @@ +package net.minestom.server.network.packet.server.play; + +import net.minestom.server.crypto.MessageSignature; +import net.minestom.server.crypto.SignedMessageHeader; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; + +public record PlayerChatHeaderPacket(@NotNull SignedMessageHeader messageHeader, @NotNull MessageSignature signature, + byte[] bodyDigest) implements ServerPacket { + public PlayerChatHeaderPacket(BinaryReader reader) { + this(new SignedMessageHeader(reader), new MessageSignature(reader), reader.readByteArray()); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.write(messageHeader); + writer.write(signature); + writer.writeByteArray(bodyDigest); + } + + @Override + public int getId() { + return ServerPacketIdentifier.PLAYER_CHAT_HEADER; + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/PlayerChatMessagePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/PlayerChatMessagePacket.java new file mode 100644 index 000000000..2bed23388 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/play/PlayerChatMessagePacket.java @@ -0,0 +1,60 @@ +package net.minestom.server.network.packet.server.play; + +import net.kyori.adventure.text.Component; +import net.minestom.server.crypto.MessageSignature; +import net.minestom.server.network.packet.server.ComponentHoldingServerPacket; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; +import java.util.function.UnaryOperator; + +/** + * Represents an outgoing chat message packet. + */ +public record PlayerChatMessagePacket(@NotNull Component signedContent, @Nullable Component unsignedContent, + int type, @NotNull UUID uuid, + @NotNull Component displayName, @Nullable Component teamDisplayName, + @NotNull MessageSignature signature) implements ComponentHoldingServerPacket { + public PlayerChatMessagePacket(BinaryReader reader) { + this(reader.readComponent(), reader.readBoolean() ? reader.readComponent() : null, + reader.readVarInt(), reader.readUuid(), + reader.readComponent(), reader.readBoolean() ? reader.readComponent() : null, + new MessageSignature(reader)); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeComponent(signedContent); + writer.writeBoolean(unsignedContent != null); + if (unsignedContent != null) writer.writeComponent(unsignedContent); + writer.writeVarInt(type); + writer.writeUuid(uuid); + writer.writeComponent(displayName); + writer.writeBoolean(teamDisplayName != null); + if (teamDisplayName != null) writer.writeComponent(teamDisplayName); + writer.write(signature); + } + + @Override + public int getId() { + return ServerPacketIdentifier.PLAYER_CHAT; + } + + @Override + public @NotNull Collection components() { + return Collections.singleton(signedContent); + } + + @Override + public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator operator) { + return new PlayerChatMessagePacket(signedContent, unsignedContent, type, + uuid, displayName, teamDisplayName, signature); + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/PlayerInfoPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/PlayerInfoPacket.java index 1918e9abf..2621e2dae 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/PlayerInfoPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/PlayerInfoPacket.java @@ -2,6 +2,7 @@ package net.minestom.server.network.packet.server.play; import net.kyori.adventure.text.Component; import net.minestom.server.adventure.ComponentHolder; +import net.minestom.server.crypto.PlayerPublicKey; import net.minestom.server.entity.GameMode; import net.minestom.server.network.packet.server.ComponentHoldingServerPacket; import net.minestom.server.network.packet.server.ServerPacket; @@ -128,7 +129,8 @@ public record PlayerInfoPacket(@NotNull Action action, } public record AddPlayer(UUID uuid, String name, List properties, GameMode gameMode, int ping, - Component displayName) implements Entry, ComponentHolder { + @Nullable Component displayName, + @Nullable PlayerPublicKey playerPublicKey) implements Entry, ComponentHolder { public AddPlayer { properties = List.copyOf(properties); } @@ -137,7 +139,8 @@ public record PlayerInfoPacket(@NotNull Action action, this(uuid, reader.readSizedString(), reader.readVarIntList(Property::new), GameMode.values()[reader.readVarInt()], reader.readVarInt(), - reader.readBoolean() ? reader.readComponent() : null); + reader.readBoolean() ? reader.readComponent() : null, + reader.readBoolean() ? new PlayerPublicKey(reader) : null); } @Override @@ -148,6 +151,8 @@ public record PlayerInfoPacket(@NotNull Action action, writer.writeVarInt(ping); writer.writeBoolean(displayName != null); if (displayName != null) writer.writeComponent(displayName); + writer.writeBoolean(playerPublicKey != null); + if (playerPublicKey != null) writer.write(playerPublicKey); } @Override @@ -158,7 +163,7 @@ public record PlayerInfoPacket(@NotNull Action action, @Override public @NotNull AddPlayer copyWithOperator(@NotNull UnaryOperator operator) { return displayName != null ? - new AddPlayer(uuid, name, properties, gameMode, ping, operator.apply(displayName)) : this; + new AddPlayer(uuid, name, properties, gameMode, ping, operator.apply(displayName), playerPublicKey) : this; } public record Property(@NotNull String name, @NotNull String value, diff --git a/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java index d5d3d1723..eeb9ecaab 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java @@ -5,22 +5,20 @@ import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; -import net.minestom.server.world.DimensionType; import org.jetbrains.annotations.NotNull; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; -public record RespawnPacket(DimensionType dimensionType, String worldName, +public record RespawnPacket(String dimensionType, String worldName, long hashedSeed, GameMode gameMode, GameMode previousGameMode, boolean isDebug, boolean isFlat, boolean copyMeta) implements ServerPacket { public RespawnPacket(BinaryReader reader) { - this(DimensionType.fromNBT((NBTCompound) reader.readTag()), reader.readSizedString(), + this(reader.readSizedString(), reader.readSizedString(), reader.readLong(), GameMode.values()[reader.readByte()], GameMode.values()[reader.readByte()], reader.readBoolean(), reader.readBoolean(), reader.readBoolean()); } @Override public void write(@NotNull BinaryWriter writer) { - writer.writeNBT("", dimensionType.toNBT()); + writer.writeSizedString(dimensionType); writer.writeSizedString(worldName); writer.writeLong(hashedSeed); writer.writeByte(gameMode.id()); @@ -28,6 +26,8 @@ public record RespawnPacket(DimensionType dimensionType, String worldName, writer.writeBoolean(isDebug); writer.writeBoolean(isFlat); writer.writeBoolean(copyMeta); + + writer.writeBoolean(false); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ServerDataPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ServerDataPacket.java new file mode 100644 index 000000000..a38e59e99 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/play/ServerDataPacket.java @@ -0,0 +1,32 @@ +package net.minestom.server.network.packet.server.play; + +import net.kyori.adventure.text.Component; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.binary.BinaryReader; +import net.minestom.server.utils.binary.BinaryWriter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public record ServerDataPacket(@Nullable Component motd, @Nullable String iconBase64, + boolean previewsChat, boolean enforcesSecureChat) implements ServerPacket { + public ServerDataPacket(BinaryReader reader) { + this(reader.readBoolean() ? reader.readComponent() : null, reader.readBoolean() ? reader.readSizedString() : null, + reader.readBoolean(), reader.readBoolean()); + } + + @Override + public void write(@NotNull BinaryWriter writer) { + writer.writeBoolean(motd != null); + if (motd != null) writer.writeComponent(motd); + writer.writeBoolean(iconBase64 != null); + if (iconBase64 != null) writer.writeSizedString(iconBase64); + writer.writeBoolean(previewsChat); + writer.writeBoolean(enforcesSecureChat); + } + + @Override + public int getId() { + return ServerPacketIdentifier.SERVER_DATA; + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SculkVibrationSignal.java b/src/main/java/net/minestom/server/network/packet/server/play/SetChatPreviewPacket.java similarity index 55% rename from src/main/java/net/minestom/server/network/packet/server/play/SculkVibrationSignal.java rename to src/main/java/net/minestom/server/network/packet/server/play/SetChatPreviewPacket.java index c43a9197c..903dc468e 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/SculkVibrationSignal.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/SetChatPreviewPacket.java @@ -1,25 +1,23 @@ package net.minestom.server.network.packet.server.play; -import net.minestom.server.coordinate.Point; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; -public class SculkVibrationSignal implements ServerPacket { - - public Point position; - public String destinationIdentifier; - // TODO 'varies' destination - public int arrivalTicks; +public record SetChatPreviewPacket(boolean enable) implements ServerPacket { + public SetChatPreviewPacket(BinaryReader reader) { + this(reader.readBoolean()); + } @Override public void write(@NotNull BinaryWriter writer) { - + writer.writeBoolean(enable); } @Override public int getId() { - return ServerPacketIdentifier.SCULK_VIBRATION_SIGNAL; + return ServerPacketIdentifier.SET_DISPLAY_CHAT_PREVIEW; } } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SoundEffectPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SoundEffectPacket.java index b128b95a7..50c629f71 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/SoundEffectPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/SoundEffectPacket.java @@ -12,17 +12,17 @@ import org.jetbrains.annotations.NotNull; public record SoundEffectPacket(int soundId, @NotNull Source source, int x, int y, int z, - float volume, float pitch) implements ServerPacket { + float volume, float pitch, long seed) implements ServerPacket { public SoundEffectPacket(BinaryReader reader) { this(reader.readVarInt(), Source.values()[reader.readVarInt()], reader.readInt() * 8, reader.readInt() * 8, reader.readInt() * 8, - reader.readFloat(), reader.readFloat()); + reader.readFloat(), reader.readFloat(), reader.readLong()); } public SoundEffectPacket(@NotNull SoundEvent sound, @NotNull Source source, @NotNull Point position, float volume, float pitch) { - this(sound.id(), source, - (int) position.x(), (int) position.y(), (int) position.z(), volume, pitch); + this(sound.id(), source, (int) position.x(), (int) position.y(), (int) position.z(), + volume, pitch, 0); } @Override @@ -34,6 +34,7 @@ public record SoundEffectPacket(int soundId, @NotNull Source source, writer.writeInt(z * 8); writer.writeFloat(volume); writer.writeFloat(pitch); + writer.writeLong(seed); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SpawnEntityPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SpawnEntityPacket.java index 3281ea50f..50eaad520 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/SpawnEntityPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/SpawnEntityPacket.java @@ -10,13 +10,13 @@ import org.jetbrains.annotations.NotNull; import java.util.UUID; public record SpawnEntityPacket(int entityId, @NotNull UUID uuid, int type, - @NotNull Pos position, int data, + @NotNull Pos position, float headRot, int data, short velocityX, short velocityY, short velocityZ) implements ServerPacket { public SpawnEntityPacket(BinaryReader reader) { this(reader.readVarInt(), reader.readUuid(), reader.readVarInt(), new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(), - reader.readByte() * 360f / 256f, reader.readByte() * 360f / 256f), - reader.readInt(), reader.readShort(), reader.readShort(), reader.readShort()); + reader.readByte() * 360f / 256f, reader.readByte() * 360f / 256f), reader.readByte() * 360f / 256f, + reader.readVarInt(), reader.readShort(), reader.readShort(), reader.readShort()); } @Override @@ -31,8 +31,9 @@ public record SpawnEntityPacket(int entityId, @NotNull UUID uuid, int type, writer.writeByte((byte) (position.yaw() * 256 / 360)); writer.writeByte((byte) (position.pitch() * 256 / 360)); + writer.writeByte((byte) (headRot * 256 / 360)); - writer.writeInt(data); + writer.writeVarInt(data); writer.writeShort(velocityX); writer.writeShort(velocityY); diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SpawnLivingEntityPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SpawnLivingEntityPacket.java deleted file mode 100644 index 8f8d768d6..000000000 --- a/src/main/java/net/minestom/server/network/packet/server/play/SpawnLivingEntityPacket.java +++ /dev/null @@ -1,46 +0,0 @@ -package net.minestom.server.network.packet.server.play; - -import net.minestom.server.coordinate.Pos; -import net.minestom.server.network.packet.server.ServerPacket; -import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.binary.BinaryReader; -import net.minestom.server.utils.binary.BinaryWriter; -import org.jetbrains.annotations.NotNull; - -import java.util.UUID; - -public record SpawnLivingEntityPacket(int entityId, @NotNull UUID entityUuid, int entityType, - @NotNull Pos position, float headYaw, - short velocityX, short velocityY, short velocityZ) implements ServerPacket { - public SpawnLivingEntityPacket(BinaryReader reader) { - this(reader.readVarInt(), reader.readUuid(), reader.readVarInt(), - new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(), - reader.readByte() * 360f / 256f, - reader.readByte() * 360f / 256f), reader.readByte() * 360f / 256f, - reader.readShort(), reader.readShort(), reader.readShort()); - } - - @Override - public void write(@NotNull BinaryWriter writer) { - writer.writeVarInt(entityId); - writer.writeUuid(entityUuid); - writer.writeVarInt(entityType); - - writer.writeDouble(position.x()); - writer.writeDouble(position.y()); - writer.writeDouble(position.z()); - - writer.writeByte((byte) (position.yaw() * 256 / 360)); - writer.writeByte((byte) (position.pitch() * 256 / 360)); - writer.writeByte((byte) (headYaw * 256 / 360)); - - writer.writeShort(velocityX); - writer.writeShort(velocityY); - writer.writeShort(velocityZ); - } - - @Override - public int getId() { - return ServerPacketIdentifier.SPAWN_LIVING_ENTITY; - } -} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SpawnPaintingPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SpawnPaintingPacket.java deleted file mode 100644 index abcb6cdab..000000000 --- a/src/main/java/net/minestom/server/network/packet/server/play/SpawnPaintingPacket.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.minestom.server.network.packet.server.play; - -import net.minestom.server.coordinate.Point; -import net.minestom.server.network.packet.server.ServerPacket; -import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.binary.BinaryReader; -import net.minestom.server.utils.binary.BinaryWriter; -import org.jetbrains.annotations.NotNull; - -import java.util.UUID; - -public record SpawnPaintingPacket(int entityId, @NotNull UUID entityUuid, int motive, - @NotNull Point position, byte direction) implements ServerPacket { - public SpawnPaintingPacket(BinaryReader reader) { - this(reader.readVarInt(), reader.readUuid(), reader.readVarInt(), - reader.readBlockPosition(), reader.readByte()); - } - - @Override - public void write(@NotNull BinaryWriter writer) { - writer.writeVarInt(entityId); - writer.writeUuid(entityUuid); - writer.writeVarInt(motive); - writer.writeBlockPosition(position); - writer.writeByte(direction); - } - - @Override - public int getId() { - return ServerPacketIdentifier.SPAWN_PAINTING; - } -} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ChatMessagePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SystemChatPacket.java similarity index 57% rename from src/main/java/net/minestom/server/network/packet/server/play/ChatMessagePacket.java rename to src/main/java/net/minestom/server/network/packet/server/play/SystemChatPacket.java index 1521ce7b6..99b67614e 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/ChatMessagePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/SystemChatPacket.java @@ -1,7 +1,6 @@ package net.minestom.server.network.packet.server.play; import net.kyori.adventure.text.Component; -import net.minestom.server.message.ChatPosition; import net.minestom.server.network.packet.server.ComponentHoldingServerPacket; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; @@ -11,29 +10,22 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.List; -import java.util.UUID; import java.util.function.UnaryOperator; -/** - * Represents an outgoing chat message packet. - */ -public record ChatMessagePacket(@NotNull Component message, @NotNull ChatPosition position, - @NotNull UUID uuid) implements ComponentHoldingServerPacket { - public ChatMessagePacket(BinaryReader reader) { - this(reader.readComponent(), ChatPosition.fromPacketID(reader.readByte()), - reader.readUuid()); +public record SystemChatPacket(@NotNull Component message, boolean overlay) implements ComponentHoldingServerPacket { + public SystemChatPacket(BinaryReader reader) { + this(reader.readComponent(), reader.readBoolean()); } @Override public void write(@NotNull BinaryWriter writer) { writer.writeComponent(message); - writer.writeByte((byte) position.ordinal()); - writer.writeUuid(uuid); + writer.writeBoolean(overlay); } @Override public int getId() { - return ServerPacketIdentifier.CHAT_MESSAGE; + return ServerPacketIdentifier.SYSTEM_CHAT; } @Override @@ -43,6 +35,6 @@ public record ChatMessagePacket(@NotNull Component message, @NotNull ChatPositio @Override public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator operator) { - return new ChatMessagePacket(operator.apply(message), position, uuid); + return new SystemChatPacket(operator.apply(message), overlay); } } diff --git a/src/main/java/net/minestom/server/network/player/PlayerConnection.java b/src/main/java/net/minestom/server/network/player/PlayerConnection.java index ac00bbbc7..7a388357b 100644 --- a/src/main/java/net/minestom/server/network/player/PlayerConnection.java +++ b/src/main/java/net/minestom/server/network/player/PlayerConnection.java @@ -1,6 +1,7 @@ package net.minestom.server.network.player; import net.minestom.server.MinecraftServer; +import net.minestom.server.crypto.PlayerPublicKey; import net.minestom.server.entity.Entity; import net.minestom.server.entity.Player; import net.minestom.server.network.ConnectionState; @@ -20,6 +21,7 @@ import java.util.List; public abstract class PlayerConnection { private Player player; private volatile ConnectionState connectionState; + private PlayerPublicKey playerPublicKey; volatile boolean online; public PlayerConnection() { @@ -150,6 +152,14 @@ public abstract class PlayerConnection { return connectionState; } + public PlayerPublicKey playerPublicKey() { + return playerPublicKey; + } + + public void setPlayerPublicKey(PlayerPublicKey playerPublicKey) { + this.playerPublicKey = playerPublicKey; + } + @Override public String toString() { return "PlayerConnection{" + diff --git a/src/main/java/net/minestom/server/network/player/PlayerSocketConnection.java b/src/main/java/net/minestom/server/network/player/PlayerSocketConnection.java index b68327924..7e8f4faf9 100644 --- a/src/main/java/net/minestom/server/network/player/PlayerSocketConnection.java +++ b/src/main/java/net/minestom/server/network/player/PlayerSocketConnection.java @@ -11,6 +11,7 @@ import net.minestom.server.event.player.PlayerPacketOutEvent; import net.minestom.server.extras.mojangAuth.MojangCrypt; import net.minestom.server.network.ConnectionState; import net.minestom.server.network.PacketProcessor; +import net.minestom.server.network.packet.client.ClientPacket; import net.minestom.server.network.packet.server.*; import net.minestom.server.network.packet.server.login.SetCompressionPacket; import net.minestom.server.network.socket.Worker; @@ -107,14 +108,15 @@ public class PlayerSocketConnection extends PlayerConnection { (id, payload) -> { if (!isOnline()) return; // Prevent packet corruption + ClientPacket packet = null; try { - packetProcessor.process(this, id, payload); + packet = packetProcessor.process(this, id, payload); } catch (Exception e) { // Error while reading the packet MinecraftServer.getExceptionManager().handleException(e); } finally { if (payload.position() != payload.limit()) { - LOGGER.warn("WARNING: Packet 0x{} not fully read ({})", Integer.toHexString(id), payload); + LOGGER.warn("WARNING: Packet 0x{} not fully read ({}) {}", Integer.toHexString(id), payload, packet); } } }); diff --git a/src/main/java/net/minestom/server/potion/Potion.java b/src/main/java/net/minestom/server/potion/Potion.java index 181bfb37b..e7ddecf47 100644 --- a/src/main/java/net/minestom/server/potion/Potion.java +++ b/src/main/java/net/minestom/server/potion/Potion.java @@ -93,7 +93,7 @@ public record Potion(@NotNull PotionEffect effect, byte amplifier, * @param entity the entity to add the effect to */ public void sendAddPacket(@NotNull Entity entity) { - entity.sendPacketToViewersAndSelf(new EntityEffectPacket(entity.getEntityId(), this)); + entity.sendPacketToViewersAndSelf(new EntityEffectPacket(entity.getEntityId(), this, null)); } /** diff --git a/src/main/java/net/minestom/server/registry/Registry.java b/src/main/java/net/minestom/server/registry/Registry.java index 60b9931f4..3e0a05ab6 100644 --- a/src/main/java/net/minestom/server/registry/Registry.java +++ b/src/main/java/net/minestom/server/registry/Registry.java @@ -105,6 +105,10 @@ public final class Registry { return ids.get(id); } + public int toId(@NotNull String namespace) { + return get(namespace).id(); + } + public Collection values() { return namespaces.values(); } @@ -133,6 +137,7 @@ public final class Registry { ENTITIES("entities.json"), ENCHANTMENTS("enchantments.json"), SOUNDS("sounds.json"), + COMMAND_ARGUMENTS("command_arguments.json"), STATISTICS("custom_statistics.json"), POTION_EFFECTS("potion_effects.json"), POTION_TYPES("potions.json"), diff --git a/src/main/java/net/minestom/server/utils/Either.java b/src/main/java/net/minestom/server/utils/Either.java new file mode 100644 index 000000000..29271acff --- /dev/null +++ b/src/main/java/net/minestom/server/utils/Either.java @@ -0,0 +1,20 @@ +package net.minestom.server.utils; + +import java.util.function.Function; + +public record Either(boolean isLeft, L left, R right) { + public static Either left(T left) { + return new Either<>(true, left, null); + } + public static Either right(T right) { + return new Either<>(false, null, right); + } + + public T map(Function leftMapper, Function rightMapper) { + if (isLeft) { + return leftMapper.apply(left); + } else { + return rightMapper.apply(right); + } + } +} diff --git a/src/main/java/net/minestom/server/utils/InterfaceUtils.java b/src/main/java/net/minestom/server/utils/InterfaceUtils.java new file mode 100644 index 000000000..e2a158831 --- /dev/null +++ b/src/main/java/net/minestom/server/utils/InterfaceUtils.java @@ -0,0 +1,13 @@ +package net.minestom.server.utils; + +import java.util.function.BiConsumer; + +public final class InterfaceUtils { + private InterfaceUtils() { + //no instance + } + + public static BiConsumer flipBiConsumer(BiConsumer biConsumer) { + return (t, u) -> biConsumer.accept(u, t); + } +} diff --git a/src/main/java/net/minestom/server/utils/binary/BinaryReader.java b/src/main/java/net/minestom/server/utils/binary/BinaryReader.java index da7cd5b3d..c804bdf36 100644 --- a/src/main/java/net/minestom/server/utils/binary/BinaryReader.java +++ b/src/main/java/net/minestom/server/utils/binary/BinaryReader.java @@ -5,6 +5,7 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Point; import net.minestom.server.item.ItemStack; +import net.minestom.server.utils.Either; import net.minestom.server.utils.NBTUtils; import net.minestom.server.utils.SerializerUtils; import net.minestom.server.utils.Utils; @@ -246,6 +247,14 @@ public class BinaryReader extends InputStream { return readList(readByte(), supplier); } + public Either readEither(Function leftReader, Function rightReader) { + if (readBoolean()) { + return Either.left(leftReader.apply(this)); + } else { + return Either.right(rightReader.apply(this)); + } + } + private List readList(int length, @NotNull Function supplier) { List list = new ArrayList<>(length); for (int i = 0; i < length; i++) { diff --git a/src/main/java/net/minestom/server/utils/binary/BinaryWriter.java b/src/main/java/net/minestom/server/utils/binary/BinaryWriter.java index e759e58ef..93f475eaa 100644 --- a/src/main/java/net/minestom/server/utils/binary/BinaryWriter.java +++ b/src/main/java/net/minestom/server/utils/binary/BinaryWriter.java @@ -5,6 +5,7 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Point; import net.minestom.server.item.ItemStack; +import net.minestom.server.utils.Either; import net.minestom.server.utils.SerializerUtils; import net.minestom.server.utils.Utils; import org.jetbrains.annotations.ApiStatus; @@ -325,6 +326,16 @@ public class BinaryWriter extends OutputStream { } } + public void writeEither(Either either, BiConsumer leftWriter, BiConsumer rightWriter) { + if (either.isLeft()) { + writeBoolean(true); + leftWriter.accept(this, either.left()); + } else { + writeBoolean(false); + rightWriter.accept(this, either.right()); + } + } + /** * Writes the given writeable object into this writer. * diff --git a/src/main/java/net/minestom/server/utils/crypto/KeyUtils.java b/src/main/java/net/minestom/server/utils/crypto/KeyUtils.java new file mode 100644 index 000000000..7d092c01f --- /dev/null +++ b/src/main/java/net/minestom/server/utils/crypto/KeyUtils.java @@ -0,0 +1,50 @@ +package net.minestom.server.utils.crypto; + +import org.jetbrains.annotations.ApiStatus; + +import java.nio.charset.StandardCharsets; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +@ApiStatus.Internal +public final class KeyUtils { + private static final Base64.Encoder MIME_ENCODER = Base64.getMimeEncoder(76, "\n".getBytes(StandardCharsets.UTF_8)); + private static final String RSA_HEADER = "-----BEGIN RSA PUBLIC KEY-----\n"; + private static final String RSA_FOOTER = "\n-----END RSA PUBLIC KEY-----\n"; + + public enum SignatureAlgorithm { + SHA256withRSA, + SHA1withRSA + } + + public enum KeyAlgorithm { + RSA + } + + private KeyUtils() { + //no instance + } + + public static String rsaPublicKeyToString(PublicKey publicKey) { + if (!publicKey.getAlgorithm().equals(KeyAlgorithm.RSA.name())) { + throw new IllegalArgumentException("The provided key isn't an RSA key!"); + } else { + return RSA_HEADER + MIME_ENCODER.encodeToString(publicKey.getEncoded()) + RSA_FOOTER; + } + } + + public static PublicKey publicRSAKeyFrom(byte[] data) { + final X509EncodedKeySpec spec = new X509EncodedKeySpec(data); + final KeyFactory keyFactory; + try { + keyFactory = KeyFactory.getInstance(KeyAlgorithm.RSA.name()); + return keyFactory.generatePublic(spec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/net/minestom/server/world/DimensionType.java b/src/main/java/net/minestom/server/world/DimensionType.java index bbd7d72ec..08f34beba 100644 --- a/src/main/java/net/minestom/server/world/DimensionType.java +++ b/src/main/java/net/minestom/server/world/DimensionType.java @@ -136,6 +136,8 @@ public class DimensionType { nbt.setInt("logical_height", logicalHeight); nbt.setInt("coordinate_scale", coordinateScale); nbt.setString("name", name.toString()); + nbt.setInt("monster_spawn_block_light_limit", 0); + nbt.setInt("monster_spawn_light_level", 11); if (fixedTime != null) nbt.setLong("fixed_time", fixedTime); }); } diff --git a/src/main/resources/yggdrasil_session_pubkey.der b/src/main/resources/yggdrasil_session_pubkey.der new file mode 100644 index 000000000..9c79a3aa4 Binary files /dev/null and b/src/main/resources/yggdrasil_session_pubkey.der differ diff --git a/src/test/java/net/minestom/server/entity/EntityViewIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityViewIntegrationTest.java index eee3e6ba9..eeea3f9d6 100644 --- a/src/test/java/net/minestom/server/entity/EntityViewIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityViewIntegrationTest.java @@ -3,7 +3,7 @@ package net.minestom.server.entity; import net.minestom.server.api.Env; import net.minestom.server.api.EnvTest; import net.minestom.server.coordinate.Pos; -import net.minestom.server.network.packet.server.play.SpawnLivingEntityPacket; +import net.minestom.server.network.packet.server.play.SpawnEntityPacket; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -131,7 +131,7 @@ public class EntityViewIntegrationTest { var vehicle = new Entity(EntityType.ZOMBIE); var passenger = new Entity(EntityType.ZOMBIE); - var tracker = connection.trackIncoming(SpawnLivingEntityPacket.class); + var tracker = connection.trackIncoming(SpawnEntityPacket.class); vehicle.setInstance(instance, new Pos(0, 40, 0)).join(); vehicle.addPassenger(passenger); diff --git a/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java b/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java index b63b4b8a9..f4e9c6d1f 100644 --- a/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java @@ -36,7 +36,7 @@ public class PlayerBlockPlacementIntegrationTest { var packet = new ClientPlayerBlockPlacementPacket( Player.Hand.MAIN, new Pos(2, 41, 0), BlockFace.WEST, 1f, 1f, 1f, - false + false, 0 ); player.addPacketToQueue(packet); player.interpretPacketQueue(); diff --git a/src/test/java/net/minestom/server/network/PacketWriteReadTest.java b/src/test/java/net/minestom/server/network/PacketWriteReadTest.java index e5b32168e..7ec686fe7 100644 --- a/src/test/java/net/minestom/server/network/PacketWriteReadTest.java +++ b/src/test/java/net/minestom/server/network/PacketWriteReadTest.java @@ -9,10 +9,8 @@ import net.minestom.server.entity.GameMode; import net.minestom.server.entity.Metadata; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; -import net.minestom.server.message.ChatPosition; import net.minestom.server.network.packet.client.ClientPacket; import net.minestom.server.network.packet.client.handshake.HandshakePacket; -import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.handshake.ResponsePacket; import net.minestom.server.network.packet.server.login.LoginDisconnectPacket; @@ -58,10 +56,10 @@ public class PacketWriteReadTest { //SERVER_PACKETS.add(new EncryptionRequestPacket("server", generateByteArray(16), generateByteArray(16))); SERVER_PACKETS.add(new LoginDisconnectPacket(COMPONENT)); //SERVER_PACKETS.add(new LoginPluginRequestPacket(5, "id", generateByteArray(16))); - SERVER_PACKETS.add(new LoginSuccessPacket(UUID.randomUUID(), "TheMode911")); + SERVER_PACKETS.add(new LoginSuccessPacket(UUID.randomUUID(), "TheMode911", 0)); SERVER_PACKETS.add(new SetCompressionPacket(256)); // Play - SERVER_PACKETS.add(new AcknowledgePlayerDiggingPacket(VEC, 5, ClientPlayerDiggingPacket.Status.STARTED_DIGGING, true)); + SERVER_PACKETS.add(new AcknowledgeBlockChangePacket(0)); SERVER_PACKETS.add(new ActionBarPacket(COMPONENT)); SERVER_PACKETS.add(new AttachEntityPacket(5, 10)); SERVER_PACKETS.add(new BlockActionPacket(VEC, (byte) 5, (byte) 5, 5)); @@ -76,7 +74,7 @@ public class PacketWriteReadTest { SERVER_PACKETS.add(new BossBarPacket(UUID.randomUUID(), new BossBarPacket.UpdateFlagsAction((byte) 5))); SERVER_PACKETS.add(new CameraPacket(5)); SERVER_PACKETS.add(new ChangeGameStatePacket(ChangeGameStatePacket.Reason.RAIN_LEVEL_CHANGE, 2)); - SERVER_PACKETS.add(new ChatMessagePacket(COMPONENT, ChatPosition.CHAT, UUID.randomUUID())); + SERVER_PACKETS.add(new SystemChatPacket(COMPONENT, false)); SERVER_PACKETS.add(new ClearTitlesPacket(false)); SERVER_PACKETS.add(new CloseWindowPacket((byte) 2)); SERVER_PACKETS.add(new CollectItemPacket(5, 5, 5)); @@ -124,7 +122,8 @@ public class PacketWriteReadTest { SERVER_PACKETS.add(new PlayerInfoPacket(PlayerInfoPacket.Action.UPDATE_LATENCY, new PlayerInfoPacket.UpdateLatency(UUID.randomUUID(), 5))); SERVER_PACKETS.add(new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER, - new PlayerInfoPacket.AddPlayer(UUID.randomUUID(), "TheMode911", List.of(new PlayerInfoPacket.AddPlayer.Property("name", "value")), GameMode.CREATIVE, 5, COMPONENT))); + new PlayerInfoPacket.AddPlayer(UUID.randomUUID(), "TheMode911", + List.of(new PlayerInfoPacket.AddPlayer.Property("name", "value")), GameMode.CREATIVE, 5, COMPONENT, null))); SERVER_PACKETS.add(new PlayerInfoPacket(PlayerInfoPacket.Action.REMOVE_PLAYER, new PlayerInfoPacket.RemovePlayer(UUID.randomUUID()))); //SERVER_PACKETS.add(new MultiBlockChangePacket(5,5,5,true, new long[]{0,5,543534,1321})); diff --git a/src/test/java/net/minestom/server/network/SendablePacketTest.java b/src/test/java/net/minestom/server/network/SendablePacketTest.java index edfd6f906..e1f052060 100644 --- a/src/test/java/net/minestom/server/network/SendablePacketTest.java +++ b/src/test/java/net/minestom/server/network/SendablePacketTest.java @@ -1,14 +1,12 @@ package net.minestom.server.network; import net.kyori.adventure.text.Component; -import net.minestom.server.message.ChatPosition; import net.minestom.server.network.packet.server.CachedPacket; import net.minestom.server.network.packet.server.LazyPacket; -import net.minestom.server.network.packet.server.play.ChatMessagePacket; +import net.minestom.server.network.packet.server.play.SystemChatPacket; import net.minestom.server.utils.PacketUtils; import org.junit.jupiter.api.Test; -import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import static org.junit.jupiter.api.Assertions.*; @@ -17,7 +15,7 @@ public class SendablePacketTest { @Test public void lazy() { - var packet = new ChatMessagePacket(Component.text("Hello World!"), ChatPosition.CHAT, UUID.randomUUID()); + var packet = new SystemChatPacket(Component.text("Hello World!"), false); AtomicBoolean called = new AtomicBoolean(false); var lazy = new LazyPacket(() -> { if (called.getAndSet(true)) @@ -30,7 +28,7 @@ public class SendablePacketTest { @Test public void cached() { - var packet = new ChatMessagePacket(Component.text("Hello World!"), ChatPosition.CHAT, UUID.randomUUID()); + var packet = new SystemChatPacket(Component.text("Hello World!"), false); var cached = new CachedPacket(packet); assertSame(packet, cached.packet());