This commit is contained in:
TheMode 2022-09-05 13:54:58 +02:00 committed by GitHub
parent 5f8842084c
commit 1dd2cc72ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
83 changed files with 1603 additions and 450 deletions

View File

@ -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"

View File

@ -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");

View File

@ -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");
}

View File

@ -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");

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");

View File

@ -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";

View File

@ -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);
}
}

View File

@ -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 <T> the type of this parsed argument
*/
public abstract class Argument<T> {
@ApiStatus.Internal
public static final Registry.Container<ArgumentImpl> 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;

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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.<br>
* Built in validators:
* <ul>
* <li>{@link SignatureValidator#PASS}: will always report true</li>
* <li>{@link SignatureValidator#FAIL}: will always report false</li>
* <li>{@link SignatureValidator#YGGDRASIL}: Uses SHA1 with RSA and Yggdrasil Public Key for
* verifying signatures</li>
* <li>{@link SignatureValidator#from(Player)}: Uses SHA256 with RSA and the
* Player's {@link PlayerPublicKey#publicKey()}</li>
* <li>{@link SignatureValidator#from(PublicKey, KeyUtils.SignatureAlgorithm)}: General purpose factory method</li>
* </ul>
*/
@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<BinaryWriter> 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;
}
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -75,6 +75,7 @@ record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType {
private static Map<String, BiFunction<Entity, Metadata, EntityMeta>> createMetaMap() {
return Map.<String, BiFunction<Entity, Metadata, EntityMeta>>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),

View File

@ -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));
}
/**

View File

@ -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));
}
/**

View File

@ -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

View File

@ -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;

View File

@ -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()));
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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<Player> 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));
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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<byte[], SaltSignaturePair> 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);
}
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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<Component> components() {
return Collections.singleton(preview);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new ChatPreviewPacket(queryId, operator.apply(preview));
}
}

View File

@ -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
}
}

View File

@ -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<Node> 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<Node> 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<Node> nodes,
}
if (isArgument()) {
parser = reader.readSizedString();
final ProtocolObject object = Argument.CONTAINER.getId(reader.readVarInt());
parser = object.name();
properties = getProperties(reader, parser);
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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<String> worlds, NBTCompound dimensionCodec, NBTCompound dimension, String world,
List<String> 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

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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<Component> components() {
return Collections.singleton(signedContent);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new PlayerChatMessagePacket(signedContent, unsignedContent, type,
uuid, displayName, teamDisplayName, signature);
}
}

View File

@ -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<Property> properties, GameMode gameMode, int ping,
Component displayName) implements Entry, ComponentHolder<AddPlayer> {
@Nullable Component displayName,
@Nullable PlayerPublicKey playerPublicKey) implements Entry, ComponentHolder<AddPlayer> {
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<Component> 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,

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<Component> operator) {
return new ChatMessagePacket(operator.apply(message), position, uuid);
return new SystemChatPacket(operator.apply(message), overlay);
}
}

View File

@ -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{" +

View File

@ -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);
}
}
});

View File

@ -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));
}
/**

View File

@ -105,6 +105,10 @@ public final class Registry {
return ids.get(id);
}
public int toId(@NotNull String namespace) {
return get(namespace).id();
}
public Collection<T> 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"),

View File

@ -0,0 +1,20 @@
package net.minestom.server.utils;
import java.util.function.Function;
public record Either<L, R>(boolean isLeft, L left, R right) {
public static <T, U> Either<T, U> left(T left) {
return new Either<>(true, left, null);
}
public static <T, U> Either<U, T> right(T right) {
return new Either<>(false, null, right);
}
public <T> T map(Function<L, T> leftMapper, Function<R, T> rightMapper) {
if (isLeft) {
return leftMapper.apply(left);
} else {
return rightMapper.apply(right);
}
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.utils;
import java.util.function.BiConsumer;
public final class InterfaceUtils {
private InterfaceUtils() {
//no instance
}
public static <T, U> BiConsumer<T, U> flipBiConsumer(BiConsumer<U, T> biConsumer) {
return (t, u) -> biConsumer.accept(u, t);
}
}

View File

@ -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 <L, R> Either<L, R> readEither(Function<BinaryReader, L> leftReader, Function<BinaryReader, R> rightReader) {
if (readBoolean()) {
return Either.left(leftReader.apply(this));
} else {
return Either.right(rightReader.apply(this));
}
}
private <T> List<T> readList(int length, @NotNull Function<BinaryReader, T> supplier) {
List<T> list = new ArrayList<>(length);
for (int i = 0; i < length; i++) {

View File

@ -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 <L, R> void writeEither(Either<L, R> either, BiConsumer<BinaryWriter, L> leftWriter, BiConsumer<BinaryWriter, R> 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.
*

View File

@ -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);
}
}
}

View File

@ -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);
});
}

Binary file not shown.

View File

@ -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);

View File

@ -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();

View File

@ -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}));

View File

@ -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());