diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 26a59d80c..066b4eb6d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: '19' + java-version: '21' cache: 'gradle' - name: Run gradle build lifecycle diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b0f9adc99..12ca758b8 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -26,7 +26,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: '19' + java-version: '21' cache: 'gradle' - name: Initialize CodeQL diff --git a/build.gradle b/build.gradle index fae984ae7..06a3f19e0 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ repositories { } dependencies { - implementation 'net.bytebuddy:byte-buddy:1.14.9' + implementation 'net.bytebuddy:byte-buddy:1.14.14' compileOnly 'org.spigotmc:spigot-api:1.20.5-R0.1-SNAPSHOT' compileOnly 'org.spigotmc:spigot:1.20.5-R0.1-SNAPSHOT' compileOnly 'io.netty:netty-all:4.0.23.Final' @@ -69,6 +69,9 @@ shadowJar { test { useJUnitPlatform() + testLogging { + exceptionFormat = 'full' + } } processResources { diff --git a/src/main/java/com/comphenix/protocol/PacketType.java b/src/main/java/com/comphenix/protocol/PacketType.java index 0b9cd1eb0..e4b39e50a 100644 --- a/src/main/java/com/comphenix/protocol/PacketType.java +++ b/src/main/java/com/comphenix/protocol/PacketType.java @@ -5,8 +5,17 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.util.*; -import java.util.function.Consumer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; +import java.util.function.BiConsumer; + +import org.apache.commons.lang.WordUtils; +import org.bukkit.Bukkit; import com.comphenix.protocol.PacketTypeLookup.ClassLookup; import com.comphenix.protocol.events.ConnectionSide; @@ -17,9 +26,6 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ComparisonChain; import com.google.common.collect.Iterables; - -import org.apache.commons.lang.WordUtils; -import org.bukkit.Bukkit; /** * Represents the type of a packet in a specific protocol. *

@@ -101,7 +107,7 @@ public static class Play { public static class Server extends PacketTypeEnum { private static final Sender SENDER = Sender.SERVER; - public static final PacketType BUNDLE = new PacketType(PROTOCOL, SENDER, 0x00, "Delimiter", "BundleDelimiterPacket"); + public static final PacketType BUNDLE = new PacketType(PROTOCOL, SENDER, 0x00, "BundleDelimiter", "Delimiter", "BundleDelimiterPacket"); public static final PacketType SPAWN_ENTITY = new PacketType(PROTOCOL, SENDER, 0x01, "SpawnEntity", "SPacketSpawnObject"); public static final PacketType SPAWN_ENTITY_EXPERIENCE_ORB = new PacketType(PROTOCOL, SENDER, 0x02, "SpawnEntityExperienceOrb", "SPacketSpawnExperienceOrb"); public static final PacketType ANIMATION = new PacketType(PROTOCOL, SENDER, 0x03, "Animation", "SPacketAnimation"); @@ -123,101 +129,106 @@ public static class Server extends PacketTypeEnum { public static final PacketType WINDOW_ITEMS = new PacketType(PROTOCOL, SENDER, 0x13, "WindowItems", "SPacketWindowItems"); public static final PacketType WINDOW_DATA = new PacketType(PROTOCOL, SENDER, 0x14, "WindowData", "SPacketWindowProperty"); public static final PacketType SET_SLOT = new PacketType(PROTOCOL, SENDER, 0x15, "SetSlot", "SPacketSetSlot"); - public static final PacketType SET_COOLDOWN = new PacketType(PROTOCOL, SENDER, 0x16, "SetCooldown", "SPacketCooldown"); - public static final PacketType CUSTOM_CHAT_COMPLETIONS = new PacketType(PROTOCOL, SENDER, 0x17, "CustomChatCompletions"); - public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x18, "CustomPayload", "SPacketCustomPayload"); - public static final PacketType DAMAGE_EVENT = new PacketType(PROTOCOL, SENDER, 0x19, "DamageEvent", "ClientboundDamageEventPacket"); - public static final PacketType DELETE_CHAT_MESSAGE = new PacketType(PROTOCOL, SENDER, 0x1A, "DeleteChat"); - public static final PacketType KICK_DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x1B, "KickDisconnect", "SPacketDisconnect"); - public static final PacketType DISGUISED_CHAT = new PacketType(PROTOCOL, SENDER, 0x1C, "DisguisedChat"); - public static final PacketType ENTITY_STATUS = new PacketType(PROTOCOL, SENDER, 0x1D, "EntityStatus", "SPacketEntityStatus"); - public static final PacketType EXPLOSION = new PacketType(PROTOCOL, SENDER, 0x1E, "Explosion", "SPacketExplosion"); - public static final PacketType UNLOAD_CHUNK = new PacketType(PROTOCOL, SENDER, 0x1F, "UnloadChunk", "SPacketUnloadChunk"); - public static final PacketType GAME_STATE_CHANGE = new PacketType(PROTOCOL, SENDER, 0x20, "GameStateChange", "SPacketChangeGameState"); - public static final PacketType OPEN_WINDOW_HORSE = new PacketType(PROTOCOL, SENDER, 0x21, "OpenWindowHorse"); - public static final PacketType HURT_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x22, "HurtAnimation", "ClientboundHurtAnimationPacket"); - public static final PacketType INITIALIZE_BORDER = new PacketType(PROTOCOL, SENDER, 0x23, "InitializeBorder"); - public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x24, "KeepAlive", "SPacketKeepAlive"); - public static final PacketType MAP_CHUNK = new PacketType(PROTOCOL, SENDER, 0x25, "LevelChunkWithLight", "MapChunk", "SPacketChunkData"); - public static final PacketType WORLD_EVENT = new PacketType(PROTOCOL, SENDER, 0x26, "WorldEvent", "SPacketEffect"); - public static final PacketType WORLD_PARTICLES = new PacketType(PROTOCOL, SENDER, 0x27, "WorldParticles", "SPacketParticles"); - public static final PacketType LIGHT_UPDATE = new PacketType(PROTOCOL, SENDER, 0x28, "LightUpdate"); - public static final PacketType LOGIN = new PacketType(PROTOCOL, SENDER, 0x29, "Login", "SPacketJoinGame"); - public static final PacketType MAP = new PacketType(PROTOCOL, SENDER, 0x2A, "Map", "SPacketMaps"); - public static final PacketType OPEN_WINDOW_MERCHANT = new PacketType(PROTOCOL, SENDER, 0x2B, "OpenWindowMerchant"); - public static final PacketType REL_ENTITY_MOVE = new PacketType(PROTOCOL, SENDER, 0x2C, "Entity$RelEntityMove", "Entity$PacketPlayOutRelEntityMove"); - public static final PacketType REL_ENTITY_MOVE_LOOK = new PacketType(PROTOCOL, SENDER, 0x2D, "Entity$RelEntityMoveLook", "Entity$PacketPlayOutRelEntityMoveLook"); - public static final PacketType ENTITY_LOOK = new PacketType(PROTOCOL, SENDER, 0x2E, "Entity$EntityLook", "Entity$PacketPlayOutEntityLook"); - public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x2F, "VehicleMove", "SPacketMoveVehicle"); - public static final PacketType OPEN_BOOK = new PacketType(PROTOCOL, SENDER, 0x30, "OpenBook"); - public static final PacketType OPEN_WINDOW = new PacketType(PROTOCOL, SENDER, 0x31, "OpenWindow", "SPacketOpenWindow"); - public static final PacketType OPEN_SIGN_EDITOR = new PacketType(PROTOCOL, SENDER, 0x32, "OpenSignEditor", "SPacketSignEditorOpen"); - public static final PacketType PING = new PacketType(PROTOCOL, SENDER, 0x33, "Ping"); - public static final PacketType PONG_RESPONSE = new PacketType(PROTOCOL, SENDER, 0x34, "PongResponse"); - public static final PacketType AUTO_RECIPE = new PacketType(PROTOCOL, SENDER, 0x35, "AutoRecipe", "SPacketPlaceGhostRecipe"); - public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x36, "Abilities", "SPacketPlayerAbilities"); - public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x37, "PlayerChat", "Chat", "SPacketChat"); - public static final PacketType PLAYER_COMBAT_END = new PacketType(PROTOCOL, SENDER, 0x38, "PlayerCombatEnd"); - public static final PacketType PLAYER_COMBAT_ENTER = new PacketType(PROTOCOL, SENDER, 0x39, "PlayerCombatEnter"); - public static final PacketType PLAYER_COMBAT_KILL = new PacketType(PROTOCOL, SENDER, 0x3A, "PlayerCombatKill"); - public static final PacketType PLAYER_INFO_REMOVE = new PacketType(PROTOCOL, SENDER, 0x3B, "PlayerInfoRemove"); - public static final PacketType PLAYER_INFO = new PacketType(PROTOCOL, SENDER, 0x3C, "PlayerInfoUpdate", "PlayerInfo"); - public static final PacketType LOOK_AT = new PacketType(PROTOCOL, SENDER, 0x3D, "LookAt", "SPacketPlayerPosLook"); - public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x3E, "Position"); - public static final PacketType RECIPES = new PacketType(PROTOCOL, SENDER, 0x3F, "Recipes", "SPacketRecipeBook"); - public static final PacketType ENTITY_DESTROY = new PacketType(PROTOCOL, SENDER, 0x40, "EntityDestroy", "SPacketDestroyEntities"); - public static final PacketType REMOVE_ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x41, "RemoveEntityEffect", "SPacketRemoveEntityEffect"); - public static final PacketType RESET_SCORE = new PacketType(PROTOCOL, SENDER, 0x42, "ResetScorePacket"); - public static final PacketType REMOVE_RESOURCE_PACK = new PacketType(PROTOCOL, SENDER, 0x43, "ResourcePackPopPacket"); - public static final PacketType ADD_RESOURCE_PACK = new PacketType(PROTOCOL, SENDER, 0x44, "ResourcePackPushPacket"); - public static final PacketType RESPAWN = new PacketType(PROTOCOL, SENDER, 0x45, "Respawn", "SPacketRespawn"); - public static final PacketType ENTITY_HEAD_ROTATION = new PacketType(PROTOCOL, SENDER, 0x46, "EntityHeadRotation", "SPacketEntityHeadLook"); - public static final PacketType MULTI_BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x47, "MultiBlockChange", "SPacketMultiBlockChange"); - public static final PacketType SELECT_ADVANCEMENT_TAB = new PacketType(PROTOCOL, SENDER, 0x48, "SelectAdvancementTab", "SPacketSelectAdvancementsTab"); - public static final PacketType SERVER_DATA = new PacketType(PROTOCOL, SENDER, 0x49, "ServerData"); - public static final PacketType SET_ACTION_BAR_TEXT = new PacketType(PROTOCOL, SENDER, 0x4A, "SetActionBarText"); - public static final PacketType SET_BORDER_CENTER = new PacketType(PROTOCOL, SENDER, 0x4B, "SetBorderCenter"); - public static final PacketType SET_BORDER_LERP_SIZE = new PacketType(PROTOCOL, SENDER, 0x4C, "SetBorderLerpSize"); - public static final PacketType SET_BORDER_SIZE = new PacketType(PROTOCOL, SENDER, 0x4D, "SetBorderSize"); - public static final PacketType SET_BORDER_WARNING_DELAY = new PacketType(PROTOCOL, SENDER, 0x4E, "SetBorderWarningDelay"); - public static final PacketType SET_BORDER_WARNING_DISTANCE = new PacketType(PROTOCOL, SENDER, 0x4F, "SetBorderWarningDistance"); - public static final PacketType CAMERA = new PacketType(PROTOCOL, SENDER, 0x50, "Camera", "SPacketCamera"); - public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x51, "HeldItemSlot", "SPacketHeldItemChange"); - public static final PacketType VIEW_CENTRE = new PacketType(PROTOCOL, SENDER, 0x52, "ViewCentre"); - public static final PacketType VIEW_DISTANCE = new PacketType(PROTOCOL, SENDER, 0x53, "ViewDistance"); - public static final PacketType SPAWN_POSITION = new PacketType(PROTOCOL, SENDER, 0x54, "SpawnPosition", "SPacketSpawnPosition"); - public static final PacketType SCOREBOARD_DISPLAY_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x55, "ScoreboardDisplayObjective", "SPacketDisplayObjective"); - public static final PacketType ENTITY_METADATA = new PacketType(PROTOCOL, SENDER, 0x56, "EntityMetadata", "SPacketEntityMetadata"); - public static final PacketType ATTACH_ENTITY = new PacketType(PROTOCOL, SENDER, 0x57, "AttachEntity", "SPacketEntityAttach"); - public static final PacketType ENTITY_VELOCITY = new PacketType(PROTOCOL, SENDER, 0x58, "EntityVelocity", "SPacketEntityVelocity"); - public static final PacketType ENTITY_EQUIPMENT = new PacketType(PROTOCOL, SENDER, 0x59, "EntityEquipment", "SPacketEntityEquipment"); - public static final PacketType EXPERIENCE = new PacketType(PROTOCOL, SENDER, 0x5A, "Experience", "SPacketSetExperience"); - public static final PacketType UPDATE_HEALTH = new PacketType(PROTOCOL, SENDER, 0x5B, "UpdateHealth", "SPacketUpdateHealth"); - public static final PacketType SCOREBOARD_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x5C, "ScoreboardObjective", "SPacketScoreboardObjective"); - public static final PacketType MOUNT = new PacketType(PROTOCOL, SENDER, 0x5D, "Mount", "SPacketSetPassengers"); - public static final PacketType SCOREBOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x5E, "ScoreboardTeam", "SPacketTeams"); - public static final PacketType SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x5F, "ScoreboardScore", "SPacketUpdateScore"); - public static final PacketType UPDATE_SIMULATION_DISTANCE = new PacketType(PROTOCOL, SENDER, 0x60, "SetSimulationDistance"); - public static final PacketType SET_SUBTITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x61, "SetSubtitleText"); - public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x62, "UpdateTime", "SPacketTimeUpdate"); - public static final PacketType SET_TITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x63, "SetTitleText"); - public static final PacketType SET_TITLES_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x64, "SetTitlesAnimation"); - public static final PacketType ENTITY_SOUND = new PacketType(PROTOCOL, SENDER, 0x65, "EntitySound", "SPacketSoundEffect"); - public static final PacketType NAMED_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x66, "NamedSoundEffect"); - public static final PacketType START_CONFIGURATION = new PacketType(PROTOCOL, SENDER, 0x67, "StartConfiguration"); - public static final PacketType STOP_SOUND = new PacketType(PROTOCOL, SENDER, 0x68, "StopSound"); - public static final PacketType SYSTEM_CHAT = new PacketType(PROTOCOL, SENDER, 0x69, "SystemChat"); - public static final PacketType PLAYER_LIST_HEADER_FOOTER = new PacketType(PROTOCOL, SENDER, 0x6A, "PlayerListHeaderFooter", "SPacketPlayerListHeaderFooter"); - public static final PacketType NBT_QUERY = new PacketType(PROTOCOL, SENDER, 0x6B, "NBTQuery"); - public static final PacketType COLLECT = new PacketType(PROTOCOL, SENDER, 0x6C, "Collect", "SPacketCollectItem"); - public static final PacketType ENTITY_TELEPORT = new PacketType(PROTOCOL, SENDER, 0x6D, "EntityTeleport", "SPacketEntityTeleport"); - public static final PacketType TICKING_STATE = new PacketType(PROTOCOL, SENDER, 0x6E, "TickingStatePacket"); - public static final PacketType TICKING_STEP_STATE = new PacketType(PROTOCOL, SENDER, 0x6F, "TickingStepPacket"); - public static final PacketType ADVANCEMENTS = new PacketType(PROTOCOL, SENDER, 0x70, "Advancements", "SPacketAdvancementInfo"); - public static final PacketType UPDATE_ATTRIBUTES = new PacketType(PROTOCOL, SENDER, 0x71, "UpdateAttributes", "SPacketEntityProperties"); - public static final PacketType ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x72, "EntityEffect", "SPacketEntityEffect"); - public static final PacketType RECIPE_UPDATE = new PacketType(PROTOCOL, SENDER, 0x73, "RecipeUpdate"); - public static final PacketType TAGS = new PacketType(PROTOCOL, SENDER, 0x74, "Tags"); + public static final PacketType COOKIE_REQUEST = new PacketType(PROTOCOL, SENDER, 0x16, "CookieRequest"); + public static final PacketType SET_COOLDOWN = new PacketType(PROTOCOL, SENDER, 0x17, "SetCooldown", "SPacketCooldown"); + public static final PacketType CUSTOM_CHAT_COMPLETIONS = new PacketType(PROTOCOL, SENDER, 0x18, "CustomChatCompletions"); + public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x19, "CustomPayload", "SPacketCustomPayload"); + public static final PacketType DAMAGE_EVENT = new PacketType(PROTOCOL, SENDER, 0x1A, "DamageEvent", "ClientboundDamageEventPacket"); + public static final PacketType DEBUG_SAMPLE = new PacketType(PROTOCOL, SENDER, 0x1B, "DebugSample"); + public static final PacketType DELETE_CHAT_MESSAGE = new PacketType(PROTOCOL, SENDER, 0x1C, "DeleteChat"); + public static final PacketType KICK_DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x1D, "Disconnect", "KickDisconnect", "SPacketDisconnect"); + public static final PacketType DISGUISED_CHAT = new PacketType(PROTOCOL, SENDER, 0x1E, "DisguisedChat"); + public static final PacketType ENTITY_STATUS = new PacketType(PROTOCOL, SENDER, 0x1F, "EntityStatus", "SPacketEntityStatus"); + public static final PacketType EXPLOSION = new PacketType(PROTOCOL, SENDER, 0x20, "Explosion", "SPacketExplosion"); + public static final PacketType UNLOAD_CHUNK = new PacketType(PROTOCOL, SENDER, 0x21, "ForgetLevelChunk", "UnloadChunk", "SPacketUnloadChunk"); + public static final PacketType GAME_STATE_CHANGE = new PacketType(PROTOCOL, SENDER, 0x22, "GameStateChange", "SPacketChangeGameState"); + public static final PacketType OPEN_WINDOW_HORSE = new PacketType(PROTOCOL, SENDER, 0x23, "OpenWindowHorse"); + public static final PacketType HURT_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x24, "HurtAnimation", "ClientboundHurtAnimationPacket"); + public static final PacketType INITIALIZE_BORDER = new PacketType(PROTOCOL, SENDER, 0x25, "InitializeBorder"); + public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x26, "KeepAlive", "SPacketKeepAlive"); + public static final PacketType MAP_CHUNK = new PacketType(PROTOCOL, SENDER, 0x27, "LevelChunkWithLight", "MapChunk", "SPacketChunkData"); + public static final PacketType WORLD_EVENT = new PacketType(PROTOCOL, SENDER, 0x28, "WorldEvent", "SPacketEffect"); + public static final PacketType WORLD_PARTICLES = new PacketType(PROTOCOL, SENDER, 0x29, "WorldParticles", "SPacketParticles"); + public static final PacketType LIGHT_UPDATE = new PacketType(PROTOCOL, SENDER, 0x2A, "LightUpdate"); + public static final PacketType LOGIN = new PacketType(PROTOCOL, SENDER, 0x2B, "Login", "SPacketJoinGame"); + public static final PacketType MAP = new PacketType(PROTOCOL, SENDER, 0x2C, "Map", "SPacketMaps"); + public static final PacketType OPEN_WINDOW_MERCHANT = new PacketType(PROTOCOL, SENDER, 0x2D, "OpenWindowMerchant"); + public static final PacketType REL_ENTITY_MOVE = new PacketType(PROTOCOL, SENDER, 0x2E, "Entity$RelEntityMove", "Entity$PacketPlayOutRelEntityMove"); + public static final PacketType REL_ENTITY_MOVE_LOOK = new PacketType(PROTOCOL, SENDER, 0x2F, "Entity$RelEntityMoveLook", "Entity$PacketPlayOutRelEntityMoveLook"); + public static final PacketType ENTITY_LOOK = new PacketType(PROTOCOL, SENDER, 0x30, "Entity$EntityLook", "Entity$PacketPlayOutEntityLook"); + public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x31, "VehicleMove", "SPacketMoveVehicle"); + public static final PacketType OPEN_BOOK = new PacketType(PROTOCOL, SENDER, 0x32, "OpenBook"); + public static final PacketType OPEN_WINDOW = new PacketType(PROTOCOL, SENDER, 0x33, "OpenWindow", "SPacketOpenWindow"); + public static final PacketType OPEN_SIGN_EDITOR = new PacketType(PROTOCOL, SENDER, 0x34, "OpenSignEditor", "SPacketSignEditorOpen"); + public static final PacketType PING = new PacketType(PROTOCOL, SENDER, 0x35, "Ping"); + public static final PacketType PONG_RESPONSE = new PacketType(PROTOCOL, SENDER, 0x36, "PongResponse"); + public static final PacketType AUTO_RECIPE = new PacketType(PROTOCOL, SENDER, 0x37, "AutoRecipe", "SPacketPlaceGhostRecipe"); + public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x38, "Abilities", "SPacketPlayerAbilities"); + public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x39, "PlayerChat", "Chat", "SPacketChat"); + public static final PacketType PLAYER_COMBAT_END = new PacketType(PROTOCOL, SENDER, 0x3A, "PlayerCombatEnd"); + public static final PacketType PLAYER_COMBAT_ENTER = new PacketType(PROTOCOL, SENDER, 0x3B, "PlayerCombatEnter"); + public static final PacketType PLAYER_COMBAT_KILL = new PacketType(PROTOCOL, SENDER, 0x3C, "PlayerCombatKill"); + public static final PacketType PLAYER_INFO_REMOVE = new PacketType(PROTOCOL, SENDER, 0x3D, "PlayerInfoRemove"); + public static final PacketType PLAYER_INFO = new PacketType(PROTOCOL, SENDER, 0x3E, "PlayerInfoUpdate", "PlayerInfo"); + public static final PacketType LOOK_AT = new PacketType(PROTOCOL, SENDER, 0x3F, "LookAt", "SPacketPlayerPosLook"); + public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x40, "Position"); + public static final PacketType RECIPES = new PacketType(PROTOCOL, SENDER, 0x41, "Recipes", "SPacketRecipeBook"); + public static final PacketType ENTITY_DESTROY = new PacketType(PROTOCOL, SENDER, 0x42, "EntityDestroy", "SPacketDestroyEntities"); + public static final PacketType REMOVE_ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x43, "RemoveEntityEffect", "SPacketRemoveEntityEffect"); + public static final PacketType RESET_SCORE = new PacketType(PROTOCOL, SENDER, 0x44, "ResetScore", "ResetScorePacket"); + public static final PacketType REMOVE_RESOURCE_PACK = new PacketType(PROTOCOL, SENDER, 0x45, "ResourcePackPop", "ResourcePackPopPacket"); + public static final PacketType ADD_RESOURCE_PACK = new PacketType(PROTOCOL, SENDER, 0x46, "ResourcePackPush", "ResourcePackPushPacket"); + public static final PacketType RESPAWN = new PacketType(PROTOCOL, SENDER, 0x47, "Respawn", "SPacketRespawn"); + public static final PacketType ENTITY_HEAD_ROTATION = new PacketType(PROTOCOL, SENDER, 0x48, "EntityHeadRotation", "SPacketEntityHeadLook"); + public static final PacketType MULTI_BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x49, "MultiBlockChange", "SPacketMultiBlockChange"); + public static final PacketType SELECT_ADVANCEMENT_TAB = new PacketType(PROTOCOL, SENDER, 0x4A, "SelectAdvancementTab", "SPacketSelectAdvancementsTab"); + public static final PacketType SERVER_DATA = new PacketType(PROTOCOL, SENDER, 0x4B, "ServerData"); + public static final PacketType SET_ACTION_BAR_TEXT = new PacketType(PROTOCOL, SENDER, 0x4C, "SetActionBarText"); + public static final PacketType SET_BORDER_CENTER = new PacketType(PROTOCOL, SENDER, 0x4D, "SetBorderCenter"); + public static final PacketType SET_BORDER_LERP_SIZE = new PacketType(PROTOCOL, SENDER, 0x4E, "SetBorderLerpSize"); + public static final PacketType SET_BORDER_SIZE = new PacketType(PROTOCOL, SENDER, 0x4F, "SetBorderSize"); + public static final PacketType SET_BORDER_WARNING_DELAY = new PacketType(PROTOCOL, SENDER, 0x50, "SetBorderWarningDelay"); + public static final PacketType SET_BORDER_WARNING_DISTANCE = new PacketType(PROTOCOL, SENDER, 0x51, "SetBorderWarningDistance"); + public static final PacketType CAMERA = new PacketType(PROTOCOL, SENDER, 0x52, "Camera", "SPacketCamera"); + public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x53, "HeldItemSlot", "SPacketHeldItemChange"); + public static final PacketType VIEW_CENTRE = new PacketType(PROTOCOL, SENDER, 0x54, "ViewCentre"); + public static final PacketType VIEW_DISTANCE = new PacketType(PROTOCOL, SENDER, 0x55, "ViewDistance"); + public static final PacketType SPAWN_POSITION = new PacketType(PROTOCOL, SENDER, 0x56, "SpawnPosition", "SPacketSpawnPosition"); + public static final PacketType SCOREBOARD_DISPLAY_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x57, "ScoreboardDisplayObjective", "SPacketDisplayObjective"); + public static final PacketType ENTITY_METADATA = new PacketType(PROTOCOL, SENDER, 0x58, "EntityMetadata", "SPacketEntityMetadata"); + public static final PacketType ATTACH_ENTITY = new PacketType(PROTOCOL, SENDER, 0x59, "AttachEntity", "SPacketEntityAttach"); + public static final PacketType ENTITY_VELOCITY = new PacketType(PROTOCOL, SENDER, 0x5A, "EntityVelocity", "SPacketEntityVelocity"); + public static final PacketType ENTITY_EQUIPMENT = new PacketType(PROTOCOL, SENDER, 0x5B, "EntityEquipment", "SPacketEntityEquipment"); + public static final PacketType EXPERIENCE = new PacketType(PROTOCOL, SENDER, 0x5C, "Experience", "SPacketSetExperience"); + public static final PacketType UPDATE_HEALTH = new PacketType(PROTOCOL, SENDER, 0x5D, "UpdateHealth", "SPacketUpdateHealth"); + public static final PacketType SCOREBOARD_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x5E, "ScoreboardObjective", "SPacketScoreboardObjective"); + public static final PacketType MOUNT = new PacketType(PROTOCOL, SENDER, 0x5F, "Mount", "SPacketSetPassengers"); + public static final PacketType SCOREBOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x60, "ScoreboardTeam", "SPacketTeams"); + public static final PacketType SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x61, "ScoreboardScore", "SPacketUpdateScore"); + public static final PacketType UPDATE_SIMULATION_DISTANCE = new PacketType(PROTOCOL, SENDER, 0x62, "SetSimulationDistance"); + public static final PacketType SET_SUBTITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x63, "SetSubtitleText"); + public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x64, "UpdateTime", "SPacketTimeUpdate"); + public static final PacketType SET_TITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x65, "SetTitleText"); + public static final PacketType SET_TITLES_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x66, "SetTitlesAnimation"); + public static final PacketType ENTITY_SOUND = new PacketType(PROTOCOL, SENDER, 0x67, "EntitySound", "SPacketSoundEffect"); + public static final PacketType NAMED_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x68, "NamedSoundEffect"); + public static final PacketType START_CONFIGURATION = new PacketType(PROTOCOL, SENDER, 0x69, "StartConfiguration"); + public static final PacketType STOP_SOUND = new PacketType(PROTOCOL, SENDER, 0x6A, "StopSound"); + public static final PacketType STORE_COOKIE = new PacketType(PROTOCOL, SENDER, 0x6B, "StoreCookie"); + public static final PacketType SYSTEM_CHAT = new PacketType(PROTOCOL, SENDER, 0x6C, "SystemChat"); + public static final PacketType PLAYER_LIST_HEADER_FOOTER = new PacketType(PROTOCOL, SENDER, 0x6D, "PlayerListHeaderFooter", "SPacketPlayerListHeaderFooter"); + public static final PacketType NBT_QUERY = new PacketType(PROTOCOL, SENDER, 0x6E, "NBTQuery"); + public static final PacketType COLLECT = new PacketType(PROTOCOL, SENDER, 0x6F, "Collect", "SPacketCollectItem"); + public static final PacketType ENTITY_TELEPORT = new PacketType(PROTOCOL, SENDER, 0x70, "EntityTeleport", "SPacketEntityTeleport"); + public static final PacketType TICKING_STATE = new PacketType(PROTOCOL, SENDER, 0x71, "TickingState", "TickingStatePacket"); + public static final PacketType TICKING_STEP_STATE = new PacketType(PROTOCOL, SENDER, 0x72, "TickingStep", "TickingStepPacket"); + public static final PacketType TRANSFER = new PacketType(PROTOCOL, SENDER, 0x73, "Transfer"); + public static final PacketType ADVANCEMENTS = new PacketType(PROTOCOL, SENDER, 0x74, "Advancements", "SPacketAdvancementInfo"); + public static final PacketType UPDATE_ATTRIBUTES = new PacketType(PROTOCOL, SENDER, 0x75, "UpdateAttributes", "SPacketEntityProperties"); + public static final PacketType ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x76, "EntityEffect", "SPacketEntityEffect"); + public static final PacketType RECIPE_UPDATE = new PacketType(PROTOCOL, SENDER, 0x77, "RecipeUpdate"); + public static final PacketType TAGS = new PacketType(PROTOCOL, SENDER, 0x78, "UpdateTags", "Tags"); + public static final PacketType PROJECTILE_POWER = new PacketType(PROTOCOL, SENDER, 0x79, "ProjectilePower"); // ---- Removed in 1.9 @@ -415,56 +426,59 @@ public static class Client extends PacketTypeEnum { public static final PacketType DIFFICULTY_CHANGE = new PacketType(PROTOCOL, SENDER, 0x02, "DifficultyChange"); public static final PacketType CHAT_ACK = new PacketType(PROTOCOL, SENDER, 0x03, "ChatAck"); public static final PacketType CHAT_COMMAND = new PacketType(PROTOCOL, SENDER, 0x04, "ChatCommand"); - public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x05, "Chat", "CPacketChatMessage"); - public static final PacketType CHAT_SESSION_UPDATE = new PacketType(PROTOCOL, SENDER, 0x06, "ChatSessionUpdate"); - public static final PacketType CHUNK_BATCH_RECEIVED = new PacketType(PROTOCOL, SENDER, 0x07, "ChunkBatchReceived"); - public static final PacketType CLIENT_COMMAND = new PacketType(PROTOCOL, SENDER, 0x08, "ClientCommand", "CPacketClientStatus"); - public static final PacketType SETTINGS = new PacketType(PROTOCOL, SENDER, 0x09, "Settings", "CPacketClientSettings"); - public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x0A, "TabComplete", "CPacketTabComplete"); - public static final PacketType CONFIGURATION_ACK = new PacketType(PROTOCOL, SENDER, 0x0B, "ConfigurationAcknowledged"); - public static final PacketType ENCHANT_ITEM = new PacketType(PROTOCOL, SENDER, 0x0C, "EnchantItem", "CPacketEnchantItem"); - public static final PacketType WINDOW_CLICK = new PacketType(PROTOCOL, SENDER, 0x0D, "WindowClick", "CPacketClickWindow"); - public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x0E, "CloseWindow", "CPacketCloseWindow"); - public static final PacketType CONTAINER_SLOT_STATE_CHANGED = new PacketType(PROTOCOL, SENDER, 0x0F, "ContainerSlotStateChangedPacket"); - public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x10, "CustomPayload", "CPacketCustomPayload"); - public static final PacketType B_EDIT = new PacketType(PROTOCOL, SENDER, 0x11, "BEdit"); - public static final PacketType ENTITY_NBT_QUERY = new PacketType(PROTOCOL, SENDER, 0x12, "EntityNBTQuery"); - public static final PacketType USE_ENTITY = new PacketType(PROTOCOL, SENDER, 0x13, "UseEntity", "CPacketUseEntity"); - public static final PacketType JIGSAW_GENERATE = new PacketType(PROTOCOL, SENDER, 0x14, "JigsawGenerate"); - public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x15, "KeepAlive", "CPacketKeepAlive"); - public static final PacketType DIFFICULTY_LOCK = new PacketType(PROTOCOL, SENDER, 0x16, "DifficultyLock"); - public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x17, "Flying$Position", "Flying$PacketPlayInPosition", "CPacketPlayer$Position"); - public static final PacketType POSITION_LOOK = new PacketType(PROTOCOL, SENDER, 0x18, "Flying$PositionLook", "Flying$PacketPlayInPositionLook", "CPacketPlayer$PositionRotation"); - public static final PacketType LOOK = new PacketType(PROTOCOL, SENDER, 0x19, "Flying$Look", "Flying$PacketPlayInLook", "CPacketPlayer$Rotation"); - public static final PacketType GROUND = new PacketType(PROTOCOL, SENDER, 0x1A, "Flying$d"); - public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x1B, "VehicleMove", "CPacketVehicleMove"); - public static final PacketType BOAT_MOVE = new PacketType(PROTOCOL, SENDER, 0x1C, "BoatMove", "CPacketSteerBoat"); - public static final PacketType PICK_ITEM = new PacketType(PROTOCOL, SENDER, 0x1D, "PickItem"); - public static final PacketType PING_REQUEST = new PacketType(PROTOCOL, SENDER, 0x1E, "PingRequest"); - public static final PacketType AUTO_RECIPE = new PacketType(PROTOCOL, SENDER, 0x1F, "AutoRecipe", "CPacketPlaceRecipe"); - public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x20, "Abilities", "CPacketPlayerAbilities"); - public static final PacketType BLOCK_DIG = new PacketType(PROTOCOL, SENDER, 0x21, "BlockDig", "CPacketPlayerDigging"); - public static final PacketType ENTITY_ACTION = new PacketType(PROTOCOL, SENDER, 0x22, "EntityAction", "CPacketEntityAction"); - public static final PacketType STEER_VEHICLE = new PacketType(PROTOCOL, SENDER, 0x23, "SteerVehicle", "CPacketInput"); - public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x24, "Pong"); - public static final PacketType RECIPE_SETTINGS = new PacketType(PROTOCOL, SENDER, 0x25, "RecipeSettings"); - public static final PacketType RECIPE_DISPLAYED = new PacketType(PROTOCOL, SENDER, 0x26, "RecipeDisplayed", "CPacketRecipeInfo"); - public static final PacketType ITEM_NAME = new PacketType(PROTOCOL, SENDER, 0x27, "ItemName"); - public static final PacketType RESOURCE_PACK_STATUS = new PacketType(PROTOCOL, SENDER, 0x28, "ResourcePackStatus", "CPacketResourcePackStatus"); - public static final PacketType ADVANCEMENTS = new PacketType(PROTOCOL, SENDER, 0x29, "Advancements", "CPacketSeenAdvancements"); - public static final PacketType TR_SEL = new PacketType(PROTOCOL, SENDER, 0x2A, "TrSel"); - public static final PacketType BEACON = new PacketType(PROTOCOL, SENDER, 0x2B, "Beacon"); - public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x2C, "HeldItemSlot", "CPacketHeldItemChange"); - public static final PacketType SET_COMMAND_BLOCK = new PacketType(PROTOCOL, SENDER, 0x2D, "SetCommandBlock"); - public static final PacketType SET_COMMAND_MINECART = new PacketType(PROTOCOL, SENDER, 0x2E, "SetCommandMinecart"); - public static final PacketType SET_CREATIVE_SLOT = new PacketType(PROTOCOL, SENDER, 0x2F, "SetCreativeSlot", "CPacketCreativeInventoryAction"); - public static final PacketType SET_JIGSAW = new PacketType(PROTOCOL, SENDER, 0x30, "SetJigsaw"); - public static final PacketType STRUCT = new PacketType(PROTOCOL, SENDER, 0x31, "Struct"); - public static final PacketType UPDATE_SIGN = new PacketType(PROTOCOL, SENDER, 0x32, "UpdateSign", "CPacketUpdateSign"); - public static final PacketType ARM_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x33, "ArmAnimation", "CPacketAnimation"); - public static final PacketType SPECTATE = new PacketType(PROTOCOL, SENDER, 0x34, "Spectate", "CPacketSpectate"); - public static final PacketType USE_ITEM = new PacketType(PROTOCOL, SENDER, 0x35, "UseItem", "CPacketPlayerTryUseItemOnBlock"); - public static final PacketType BLOCK_PLACE = new PacketType(PROTOCOL, SENDER, 0x36, "BlockPlace", "CPacketPlayerTryUseItem"); + public static final PacketType CHAT_COMMAND_SIGNED = new PacketType(PROTOCOL, SENDER, 0x05, "ChatCommandSigned"); + public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x06, "Chat", "CPacketChatMessage"); + public static final PacketType CHAT_SESSION_UPDATE = new PacketType(PROTOCOL, SENDER, 0x07, "ChatSessionUpdate"); + public static final PacketType CHUNK_BATCH_RECEIVED = new PacketType(PROTOCOL, SENDER, 0x08, "ChunkBatchReceived"); + public static final PacketType CLIENT_COMMAND = new PacketType(PROTOCOL, SENDER, 0x09, "ClientCommand", "CPacketClientStatus"); + public static final PacketType SETTINGS = new PacketType(PROTOCOL, SENDER, 0x0A, "ClientInformation", "Settings", "CPacketClientSettings"); + public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x0B, "TabComplete", "CPacketTabComplete"); + public static final PacketType CONFIGURATION_ACK = new PacketType(PROTOCOL, SENDER, 0x0C, "ConfigurationAcknowledged"); + public static final PacketType ENCHANT_ITEM = new PacketType(PROTOCOL, SENDER, 0x0D, "EnchantItem", "CPacketEnchantItem"); + public static final PacketType WINDOW_CLICK = new PacketType(PROTOCOL, SENDER, 0x0E, "WindowClick", "CPacketClickWindow"); + public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x0F, "CloseWindow", "CPacketCloseWindow"); + public static final PacketType CONTAINER_SLOT_STATE_CHANGED = new PacketType(PROTOCOL, SENDER, 0x10, "ContainerSlotStateChanged", "ContainerSlotStateChangedPacket"); + public static final PacketType COOKIE_RESPONSE = new PacketType(PROTOCOL, SENDER, 0x11, "CookieResponse"); + public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x12, "CustomPayload", "CPacketCustomPayload"); + public static final PacketType DEBUG_SAMPLE_SUBSCRIPTION = new PacketType(PROTOCOL, SENDER, 0x13, "DebugSampleSubscription"); + public static final PacketType B_EDIT = new PacketType(PROTOCOL, SENDER, 0x14, "BEdit"); + public static final PacketType ENTITY_NBT_QUERY = new PacketType(PROTOCOL, SENDER, 0x15, "EntityNBTQuery"); + public static final PacketType USE_ENTITY = new PacketType(PROTOCOL, SENDER, 0x16, "UseEntity", "CPacketUseEntity"); + public static final PacketType JIGSAW_GENERATE = new PacketType(PROTOCOL, SENDER, 0x17, "JigsawGenerate"); + public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x18, "KeepAlive", "CPacketKeepAlive"); + public static final PacketType DIFFICULTY_LOCK = new PacketType(PROTOCOL, SENDER, 0x19, "DifficultyLock"); + public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x1A, "Flying$Position", "Flying$PacketPlayInPosition", "CPacketPlayer$Position"); + public static final PacketType POSITION_LOOK = new PacketType(PROTOCOL, SENDER, 0x1B, "Flying$PositionLook", "Flying$PacketPlayInPositionLook", "CPacketPlayer$PositionRotation"); + public static final PacketType LOOK = new PacketType(PROTOCOL, SENDER, 0x1C, "Flying$Look", "Flying$PacketPlayInLook", "CPacketPlayer$Rotation"); + public static final PacketType GROUND = new PacketType(PROTOCOL, SENDER, 0x1D, "Flying$d"); + public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x1E, "VehicleMove", "CPacketVehicleMove"); + public static final PacketType BOAT_MOVE = new PacketType(PROTOCOL, SENDER, 0x1F, "BoatMove", "CPacketSteerBoat"); + public static final PacketType PICK_ITEM = new PacketType(PROTOCOL, SENDER, 0x20, "PickItem"); + public static final PacketType PING_REQUEST = new PacketType(PROTOCOL, SENDER, 0x21, "PingRequest"); + public static final PacketType AUTO_RECIPE = new PacketType(PROTOCOL, SENDER, 0x22, "AutoRecipe", "CPacketPlaceRecipe"); + public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x23, "Abilities", "CPacketPlayerAbilities"); + public static final PacketType BLOCK_DIG = new PacketType(PROTOCOL, SENDER, 0x24, "BlockDig", "CPacketPlayerDigging"); + public static final PacketType ENTITY_ACTION = new PacketType(PROTOCOL, SENDER, 0x25, "EntityAction", "CPacketEntityAction"); + public static final PacketType STEER_VEHICLE = new PacketType(PROTOCOL, SENDER, 0x26, "SteerVehicle", "CPacketInput"); + public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x27, "Pong"); + public static final PacketType RECIPE_SETTINGS = new PacketType(PROTOCOL, SENDER, 0x28, "RecipeSettings"); + public static final PacketType RECIPE_DISPLAYED = new PacketType(PROTOCOL, SENDER, 0x29, "RecipeDisplayed", "CPacketRecipeInfo"); + public static final PacketType ITEM_NAME = new PacketType(PROTOCOL, SENDER, 0x2A, "ItemName"); + public static final PacketType RESOURCE_PACK_STATUS = new PacketType(PROTOCOL, SENDER, 0x2B, "ResourcePack", "ResourcePackStatus", "CPacketResourcePackStatus"); + public static final PacketType ADVANCEMENTS = new PacketType(PROTOCOL, SENDER, 0x2C, "Advancements", "CPacketSeenAdvancements"); + public static final PacketType TR_SEL = new PacketType(PROTOCOL, SENDER, 0x2D, "TrSel"); + public static final PacketType BEACON = new PacketType(PROTOCOL, SENDER, 0x2E, "Beacon"); + public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x2F, "HeldItemSlot", "CPacketHeldItemChange"); + public static final PacketType SET_COMMAND_BLOCK = new PacketType(PROTOCOL, SENDER, 0x30, "SetCommandBlock"); + public static final PacketType SET_COMMAND_MINECART = new PacketType(PROTOCOL, SENDER, 0x31, "SetCommandMinecart"); + public static final PacketType SET_CREATIVE_SLOT = new PacketType(PROTOCOL, SENDER, 0x32, "SetCreativeSlot", "CPacketCreativeInventoryAction"); + public static final PacketType SET_JIGSAW = new PacketType(PROTOCOL, SENDER, 0x33, "SetJigsaw"); + public static final PacketType STRUCT = new PacketType(PROTOCOL, SENDER, 0x34, "Struct"); + public static final PacketType UPDATE_SIGN = new PacketType(PROTOCOL, SENDER, 0x35, "UpdateSign", "CPacketUpdateSign"); + public static final PacketType ARM_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x36, "ArmAnimation", "CPacketAnimation"); + public static final PacketType SPECTATE = new PacketType(PROTOCOL, SENDER, 0x37, "Spectate", "CPacketSpectate"); + public static final PacketType USE_ITEM = new PacketType(PROTOCOL, SENDER, 0x38, "UseItem", "CPacketPlayerTryUseItemOnBlock"); + public static final PacketType BLOCK_PLACE = new PacketType(PROTOCOL, SENDER, 0x39, "BlockPlace", "CPacketPlayerTryUseItem"); /** * @deprecated Removed in 1.17 @@ -519,7 +533,7 @@ public static class Server extends PacketTypeEnum { @ForceAsync public static final PacketType SERVER_INFO = new PacketType(PROTOCOL, SENDER, 0x00, "ServerInfo", "SPacketServerInfo"); @ForceAsync - public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x01, "Pong", "SPacketPong"); + public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x01, "PongResponse", "Pong", "SPacketPong"); /** * @deprecated Renamed to {@link #SERVER_INFO} @@ -550,7 +564,7 @@ public static class Client extends PacketTypeEnum { public static final PacketType START = new PacketType(PROTOCOL, SENDER, 0x00, "Start", "CPacketServerQuery"); @ForceAsync - public static final PacketType PING = new PacketType(PROTOCOL, SENDER, 0x01, "Ping", "CPacketPing"); + public static final PacketType PING = new PacketType(PROTOCOL, SENDER, 0x01, "PingRequest", "Ping", "CPacketPing"); private static final Client INSTANCE = new Client(); @@ -590,6 +604,7 @@ public static class Server extends PacketTypeEnum { public static final PacketType SUCCESS = new PacketType(PROTOCOL, SENDER, 0x02, "Success", "SPacketLoginSuccess"); public static final PacketType SET_COMPRESSION = new PacketType(PROTOCOL, SENDER, 0x03, "SetCompression", "SPacketEnableCompression"); public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x04, "CustomPayload", "SPacketCustomPayload"); + public static final PacketType COOKIE_REQUEST = new PacketType(PROTOCOL, SENDER, 0x05, "CookieRequest"); private static final Server INSTANCE = new Server(); @@ -613,8 +628,9 @@ public static class Client extends PacketTypeEnum { public static final PacketType START = new PacketType(PROTOCOL, SENDER, 0x00, "Start", "CPacketLoginStart"); public static final PacketType ENCRYPTION_BEGIN = new PacketType(PROTOCOL, SENDER, 0x01, "EncryptionBegin", "CPacketEncryptionResponse"); - public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x02, "CustomPayload", "CPacketCustomPayload"); + public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x02, "CustomQueryAnswer", "CustomPayload", "CPacketCustomPayload"); public static final PacketType LOGIN_ACK = new PacketType(PROTOCOL, SENDER, 0x03, "LoginAcknowledged"); + public static final PacketType COOKIE_RESPONSE = new PacketType(PROTOCOL, SENDER, 0x04, "CookieResponse"); private static final Client INSTANCE = new Client(); @@ -647,22 +663,36 @@ public static class Configuration { public static class Server extends PacketTypeEnum { private static final Sender SENDER = Sender.SERVER; - public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x00, "CustomPayload"); - public static final PacketType DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x01, "Disconnect"); - public static final PacketType FINISH_CONFIGURATION = new PacketType(PROTOCOL, SENDER, 0x02, "FinishConfiguration"); - public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x03, "KeepAlive"); - public static final PacketType PING = new PacketType(PROTOCOL, SENDER, 0x04, "Ping"); - public static final PacketType REGISTRY_DATA = new PacketType(PROTOCOL, SENDER, 0x05, "RegistryData"); - public static final PacketType REMOVE_RESOURCE_PACK = new PacketType(PROTOCOL, SENDER, 0x06, "ResourcePackPopPacket"); - public static final PacketType ADD_RESOURCE_PACK = new PacketType(PROTOCOL, SENDER, 0x07, "ResourcePackPushPacket"); - public static final PacketType UPDATE_ENABLED_FEATURES = new PacketType(PROTOCOL, SENDER, 0x08, "UpdateEnabledFeatures"); - public static final PacketType UPDATE_TAGS = new PacketType(PROTOCOL, SENDER, 0x09, "UpdateTags"); + public static final PacketType COOKIE_REQUEST = new PacketType(PROTOCOL, SENDER, 0x00, "CookieRequest"); + public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x01, "CustomPayload"); + public static final PacketType DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x02, "Disconnect"); + public static final PacketType FINISH_CONFIGURATION = new PacketType(PROTOCOL, SENDER, 0x03, "FinishConfiguration"); + public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x04, "KeepAlive"); + public static final PacketType PING = new PacketType(PROTOCOL, SENDER, 0x05, "Ping"); + public static final PacketType RESET_CHAT = new PacketType(PROTOCOL, SENDER, 0x06, "ResetChat"); + public static final PacketType REGISTRY_DATA = new PacketType(PROTOCOL, SENDER, 0x07, "RegistryData"); + public static final PacketType REMOVE_RESOURCE_PACK = new PacketType(PROTOCOL, SENDER, 0x08, "ResourcePackPop"); + public static final PacketType ADD_RESOURCE_PACK = new PacketType(PROTOCOL, SENDER, 0x09, "ResourcePackPush"); + public static final PacketType STORE_COOKIE = new PacketType(PROTOCOL, SENDER, 0x0A, "StoreCookie"); + public static final PacketType TRANSFER = new PacketType(PROTOCOL, SENDER, 0x0B, "Transfer"); + public static final PacketType UPDATE_ENABLED_FEATURES = new PacketType(PROTOCOL, SENDER, 0x0C, "UpdateEnabledFeatures"); + public static final PacketType UPDATE_TAGS = new PacketType(PROTOCOL, SENDER, 0x0D, "UpdateTags"); + public static final PacketType SELECT_KNOWN_PACKS = new PacketType(PROTOCOL, SENDER, 0x0E, "ClientboundSelectKnownPacks"); /** * @deprecated Removed in 1.20.4: replaced with new packets for removing and sending resource packs */ @Deprecated public static final PacketType RESOURCE_PACK = new PacketType(PROTOCOL, SENDER, 255, "ResourcePack"); + + private static final Server INSTANCE = new Server(); + + // Prevent accidental construction + private Server() { super(); } + + public static Server getInstance() { + return INSTANCE; + } } /** @@ -672,11 +702,22 @@ public static class Client extends PacketTypeEnum { private static final Sender SENDER = Sender.CLIENT; public static final PacketType CLIENT_INFORMATION = new PacketType(PROTOCOL, SENDER, 0x00, "ClientInformation"); - public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x01, "CustomPayload"); - public static final PacketType FINISH_CONFIGURATION = new PacketType(PROTOCOL, SENDER, 0x02, "FinishConfiguration"); - public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x03, "KeepAlive"); - public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x04, "Pong"); - public static final PacketType RESOURCE_PACK_ACK = new PacketType(PROTOCOL, SENDER, 0x05, "ResourcePack"); + public static final PacketType COOKIE_RESPONSE = new PacketType(PROTOCOL, SENDER, 0x01, "CookieResponse"); + public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x02, "CustomPayload"); + public static final PacketType FINISH_CONFIGURATION = new PacketType(PROTOCOL, SENDER, 0x03, "FinishConfiguration"); + public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x04, "KeepAlive"); + public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x05, "Pong"); + public static final PacketType RESOURCE_PACK_ACK = new PacketType(PROTOCOL, SENDER, 0x06, "ResourcePack"); + public static final PacketType SELECT_KNOWN_PACKS = new PacketType(PROTOCOL, SENDER, 0x07, "ServerboundSelectKnownPacks"); + + private static final Client INSTANCE = new Client(); + + // Prevent accidental construction + private Client() { super(); } + + public static Client getInstance() { + return INSTANCE; + } } } @@ -824,7 +865,9 @@ private static PacketTypeLookup getLookup() { addPacketTypes(Status.Client.getInstance()). addPacketTypes(Status.Server.getInstance()). addPacketTypes(Login.Client.getInstance()). - addPacketTypes(Login.Server.getInstance()); + addPacketTypes(Login.Server.getInstance()). + addPacketTypes(Configuration.Client.getInstance()). + addPacketTypes(Configuration.Server.getInstance()); } return LOOKUP; } @@ -931,6 +974,14 @@ public static PacketType findCurrent(Protocol protocol, Sender sender, String na } } + private static String formatSimpleClassName(Protocol protocol, Sender sender, String name) { + return "Packet" + protocol.getPacketName() + sender.getPacketName() + name; + } + + private static String formatSimpleMojangClassName(Protocol protocol, Sender sender, String name) { + return sender.getMojangName() + name + "Packet"; + } + private static String formatMojangClassName(Protocol protocol, Sender sender, String name) { return "net.minecraft.network.protocol." + protocol.getMojangName() + "." + sender.getMojangName() + name + "Packet"; @@ -1001,7 +1052,8 @@ public static PacketType fromID(Protocol protocol, Sender sender, int packetId, return type; } - static Consumer onDynamicCreate = x -> {}; + static BiConsumer onDynamicCreate = (type, className) -> {}; + static BiConsumer onIdMismatch = (type, newId) -> {}; /** * Retrieve a packet type from a protocol, sender, ID, and class for 1.8+ @@ -1019,7 +1071,7 @@ public static PacketType fromCurrent(Protocol protocol, Sender sender, int packe // Check the map first String className = packetClass.getName(); - PacketType type = find(map, className); + PacketType type = find(map, packetClass); if (type == null) { // Guess we don't support this packet :/ type = new PacketType(protocol, sender, packetId, PROTOCOL_VERSION, className); @@ -1027,14 +1079,17 @@ public static PacketType fromCurrent(Protocol protocol, Sender sender, int packe // Many may be scheduled, but only the first will be executed scheduleRegister(type, "Dynamic-" + UUID.randomUUID().toString()); - onDynamicCreate.accept(className); + onDynamicCreate.accept(type, className); + } else if (packetId != type.getCurrentId()) { + onIdMismatch.accept(type, packetId); } return type; } - private static PacketType find(Map map, String clazz) { - PacketType ret = map.get(clazz); + private static PacketType find(Map map, Class packetClass) { + String className = packetClass.getName(); + PacketType ret = map.get(className); if (ret != null) { return ret; } @@ -1044,7 +1099,7 @@ private static PacketType find(Map map, String clazz) { List aliases = check.getClassNames(); if (aliases.size() > 1) { for (String alias : aliases) { - if (alias.equals(clazz)) { + if (alias.equals(className) || alias.equals(packetClass.getSimpleName())) { // We have a match! return check; } @@ -1174,6 +1229,9 @@ public PacketType(Protocol protocol, Sender sender, int currentId, MinecraftVers } else { classNames.add(formatClassName(protocol, sender, classname)); classNames.add(formatMojangClassName(protocol, sender, classname)); + classNames.add(formatSimpleClassName(protocol, sender, classname)); + classNames.add(formatSimpleMojangClassName(protocol, sender, classname)); + classNames.add(classname); } } diff --git a/src/main/java/com/comphenix/protocol/PacketTypeLookup.java b/src/main/java/com/comphenix/protocol/PacketTypeLookup.java index e1f9b16bd..3bc330b32 100644 --- a/src/main/java/com/comphenix/protocol/PacketTypeLookup.java +++ b/src/main/java/com/comphenix/protocol/PacketTypeLookup.java @@ -17,6 +17,7 @@ * @author Kristian */ class PacketTypeLookup { + public static class ProtocolSenderLookup { // Unroll lookup for performance reasons public final IntegerMap HANDSHAKE_CLIENT = new IntegerMap<>(); @@ -27,6 +28,8 @@ public static class ProtocolSenderLookup { public final IntegerMap STATUS_SERVER = new IntegerMap<>(); public final IntegerMap LOGIN_CLIENT = new IntegerMap<>(); public final IntegerMap LOGIN_SERVER = new IntegerMap<>(); + public final IntegerMap CONFIGURATION_CLIENT = new IntegerMap<>(); + public final IntegerMap CONFIGURATION_SERVER = new IntegerMap<>(); /** * Retrieve the correct integer map for a specific protocol and sender. @@ -44,6 +47,8 @@ public IntegerMap getMap(Protocol protocol, Sender sender) { return sender == Sender.CLIENT ? STATUS_CLIENT : STATUS_SERVER; case LOGIN: return sender == Sender.CLIENT ? LOGIN_CLIENT : LOGIN_SERVER; + case CONFIGURATION: + return sender == Sender.CLIENT ? CONFIGURATION_CLIENT : CONFIGURATION_SERVER; default: throw new IllegalArgumentException("Unable to find protocol " + protocol); } @@ -87,11 +92,6 @@ public Map getMap(Protocol protocol, Sender sender) { } } - // Packet IDs from 1.6.4 and below - private final IntegerMap legacyLookup = new IntegerMap<>(); - private final IntegerMap serverLookup = new IntegerMap<>(); - private final IntegerMap clientLookup = new IntegerMap<>(); - // Packets for 1.7.2 private final ProtocolSenderLookup idLookup = new ProtocolSenderLookup(); @@ -123,9 +123,11 @@ public PacketTypeLookup addPacketTypes(Iterable types) { * Retrieve a packet type from a legacy (1.6.4 and below) packet ID. * @param packetId - the legacy packet ID. * @return The corresponding packet type, or NULL if not found. + * @deprecated no longer works and will always return null */ + @Deprecated public PacketType getFromLegacy(int packetId) { - return legacyLookup.get(packetId); + return null; } /** @@ -142,20 +144,11 @@ public Collection getFromName(String name) { * @param packetId - the legacy packet ID. * @param preference - which packet type to look for first. * @return The corresponding packet type, or NULL if not found. + * @deprecated no longer works and will always return null */ - public PacketType getFromLegacy(int packetId, Sender preference) { - if (preference == Sender.CLIENT) - return getFirst(packetId, clientLookup, serverLookup); - else - return getFirst(packetId, serverLookup, clientLookup); - } - - // Helper method for looking up in two sets - private T getFirst(int packetId, IntegerMap first, IntegerMap second) { - if (first.containsKey(packetId)) - return first.get(packetId); - else - return second.get(packetId); + @Deprecated + public PacketType getFromLegacy(int packetId, Sender preference) { + return null; } /** diff --git a/src/main/java/com/comphenix/protocol/events/PacketContainer.java b/src/main/java/com/comphenix/protocol/events/PacketContainer.java index db7d2af37..aebcb8cd4 100644 --- a/src/main/java/com/comphenix/protocol/events/PacketContainer.java +++ b/src/main/java/com/comphenix/protocol/events/PacketContainer.java @@ -34,6 +34,7 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.injector.StructureCache; +import com.comphenix.protocol.injector.packet.PacketRegistry; import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.ObjectWriter; import com.comphenix.protocol.reflect.StructureModifier; @@ -56,6 +57,7 @@ import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.Converters; +import com.comphenix.protocol.wrappers.WrappedStreamCodec; import com.google.common.collect.Sets; import io.netty.buffer.ByteBuf; import io.netty.util.ReferenceCountUtil; @@ -345,6 +347,11 @@ public static Object deserializeFromBuffer(PacketType packetType, Object buffer) } Function deserializer = PACKET_DESERIALIZER_METHODS.computeIfAbsent(packetType, type -> { + WrappedStreamCodec streamCodec = PacketRegistry.getStreamCodec(type.getPacketClass()); + if (streamCodec != null) { + return streamCodec::decode; + } + if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) { // best guess - a constructor which takes a buffer as the only argument ConstructorAccessor bufferConstructor = Accessors.getConstructorAccessorOrNull( @@ -392,7 +399,14 @@ public Object serializeToBuffer() { } Object targetBuffer = MinecraftReflection.createPacketDataSerializer(0); - MinecraftMethods.getPacketWriteByteBufMethod().invoke(handle, targetBuffer); + + WrappedStreamCodec streamCodec = PacketRegistry.getStreamCodec(type.getPacketClass()); + if (streamCodec != null) { + streamCodec.encode(targetBuffer, handle); + } else { + MinecraftMethods.getPacketWriteByteBufMethod().invoke(handle, targetBuffer); + } + return targetBuffer; } diff --git a/src/main/java/com/comphenix/protocol/injector/StructureCache.java b/src/main/java/com/comphenix/protocol/injector/StructureCache.java index 8817e01c7..1568d3568 100644 --- a/src/main/java/com/comphenix/protocol/injector/StructureCache.java +++ b/src/main/java/com/comphenix/protocol/injector/StructureCache.java @@ -20,22 +20,28 @@ import java.security.PublicKey; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.injector.packet.PacketRegistry; +import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.reflect.accessors.ConstructorAccessor; +import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.reflect.instances.DefaultInstances; import com.comphenix.protocol.utility.ByteBuddyFactory; import com.comphenix.protocol.utility.MinecraftMethods; import com.comphenix.protocol.utility.MinecraftReflection; +import com.comphenix.protocol.utility.MinecraftRegistryAccess; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.utility.ZeroBuffer; import com.comphenix.protocol.wrappers.WrappedChatComponent; +import com.comphenix.protocol.wrappers.WrappedStreamCodec; import com.google.common.base.Preconditions; + import io.netty.buffer.ByteBuf; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default; @@ -57,22 +63,47 @@ public class StructureCache { private static final Object TRICK_INIT_LOCK = new Object(); private static boolean TRICK_TRIED = false; - private static ConstructorAccessor TRICKED_DATA_SERIALIZER_BASE; - private static ConstructorAccessor TRICKED_DATA_SERIALIZER_JSON; + private static Supplier TRICKED_DATA_SERIALIZER_BASE; + private static Supplier TRICKED_DATA_SERIALIZER_JSON; public static Object newPacket(Class packetClass) { - Supplier packetConstructor = PACKET_INSTANCE_CREATORS.computeIfAbsent(packetClass, clazz -> { + Supplier packetConstructor = PACKET_INSTANCE_CREATORS.computeIfAbsent(packetClass, packetClassKey -> { + WrappedStreamCodec streamCodec = PacketRegistry.getStreamCodec(packetClassKey); + + // use the new stream codec for versions above 1.20.5 if possible + if (streamCodec != null && tryInitTrickDataSerializer()) { + try { + // first try with the base accessor + Object serializer = TRICKED_DATA_SERIALIZER_BASE.get(); + streamCodec.decode(serializer); // throwaway instance, for testing + + // method is working + return () -> streamCodec.decode(serializer); + } catch (Exception exception) { + try { + // try with the json accessor + Object serializer = TRICKED_DATA_SERIALIZER_JSON.get(); + streamCodec.decode(serializer); // throwaway instance, for testing + + // method is working + return () -> streamCodec.decode(serializer); + } catch (Exception ignored) { + // shrug, fall back to default behaviour + } + } + } + // prefer construction via PacketDataSerializer constructor on 1.17 and above - if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) { + if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) { ConstructorAccessor serializerAccessor = Accessors.getConstructorAccessorOrNull( - clazz, + packetClassKey, MinecraftReflection.getPacketDataSerializerClass()); if (serializerAccessor != null) { // check if the method is possible if (tryInitTrickDataSerializer()) { try { // first try with the base accessor - Object serializer = TRICKED_DATA_SERIALIZER_BASE.invoke(new ZeroBuffer()); + Object serializer = TRICKED_DATA_SERIALIZER_BASE.get(); serializerAccessor.invoke(serializer); // throwaway instance, for testing // method is working @@ -80,7 +111,7 @@ public static Object newPacket(Class packetClass) { } catch (Exception exception) { try { // try with the json accessor - Object serializer = TRICKED_DATA_SERIALIZER_JSON.invoke(new ZeroBuffer()); + Object serializer = TRICKED_DATA_SERIALIZER_JSON.get(); serializerAccessor.invoke(serializer); // throwaway instance, for testing // method is working @@ -95,8 +126,8 @@ public static Object newPacket(Class packetClass) { // try via DefaultInstances as fallback return () -> { - Object packetInstance = DefaultInstances.DEFAULT.create(clazz); - Objects.requireNonNull(packetInstance, "Unable to create packet instance for class " + clazz); + Object packetInstance = DefaultInstances.DEFAULT.create(packetClassKey); + Objects.requireNonNull(packetInstance, "Unable to create packet instance for class " + packetClassKey + " - " + tryInitTrickDataSerializer() + " - " + streamCodec); return packetInstance; }; }); @@ -156,16 +187,19 @@ public static StructureModifier getStructure(final PacketType packetType */ public static Object newNullDataSerializer() { tryInitTrickDataSerializer(); - return TRICKED_DATA_SERIALIZER_BASE.invoke(new ZeroBuffer()); + return TRICKED_DATA_SERIALIZER_BASE.get(); } static void initTrickDataSerializer() { + Optional> registryByteBuf = MinecraftReflection.getRegistryFriendlyByteBufClass(); + // create an empty instance of a nbt tag compound / text compound that we can re-use when needed Object textCompound = WrappedChatComponent.fromText("").getHandle(); Object compound = Accessors.getConstructorAccessor(MinecraftReflection.getNBTCompoundClass()).invoke(); + // base builder which intercepts a few methods DynamicType.Builder baseBuilder = ByteBuddyFactory.getInstance() - .createSubclass(MinecraftReflection.getPacketDataSerializerClass()) + .createSubclass(registryByteBuf.orElse(MinecraftReflection.getPacketDataSerializerClass())) .name(MinecraftMethods.class.getPackage().getName() + ".ProtocolLibTricksNmsDataSerializerBase") .method(ElementMatchers.takesArguments(MinecraftReflection.getNBTReadLimiterClass()) .and(ElementMatchers.returns(ElementMatchers.isSubTypeOf(MinecraftReflection.getNBTBaseClass())))) @@ -177,9 +211,19 @@ static void initTrickDataSerializer() { Class serializerBase = baseBuilder.make() .load(ByteBuddyFactory.getInstance().getClassLoader(), Default.INJECTION) .getLoaded(); - TRICKED_DATA_SERIALIZER_BASE = Accessors.getConstructorAccessor(serializerBase, ByteBuf.class); - // extended builder which intercepts the read string method as well + if (registryByteBuf.isPresent()) { + ConstructorAccessor accessor = Accessors.getConstructorAccessor(FuzzyReflection.fromClass(serializerBase, true).getConstructor(FuzzyMethodContract.newBuilder() + .parameterDerivedOf(ByteBuf.class) + .parameterDerivedOf(MinecraftReflection.getRegistryAccessClass()) + .build())); + TRICKED_DATA_SERIALIZER_BASE = () -> accessor.invoke(new ZeroBuffer(), MinecraftRegistryAccess.get()); + } else { + ConstructorAccessor accessor = Accessors.getConstructorAccessor(serializerBase, ByteBuf.class); + TRICKED_DATA_SERIALIZER_BASE = () -> accessor.invoke(new ZeroBuffer()); + } + + //xtended builder which intercepts the read string method as well Class withStringIntercept = baseBuilder .name(MinecraftMethods.class.getPackage().getName() + ".ProtocolLibTricksNmsDataSerializerJson") .method(ElementMatchers.returns(String.class).and(ElementMatchers.takesArguments(int.class))) @@ -187,7 +231,17 @@ static void initTrickDataSerializer() { .make() .load(ByteBuddyFactory.getInstance().getClassLoader(), Default.INJECTION) .getLoaded(); - TRICKED_DATA_SERIALIZER_JSON = Accessors.getConstructorAccessor(withStringIntercept, ByteBuf.class); + + if (registryByteBuf.isPresent()) { + ConstructorAccessor accessor = Accessors.getConstructorAccessor(FuzzyReflection.fromClass(withStringIntercept).getConstructor(FuzzyMethodContract.newBuilder() + .parameterDerivedOf(ByteBuf.class) + .parameterDerivedOf(MinecraftReflection.getRegistryAccessClass()) + .build())); + TRICKED_DATA_SERIALIZER_JSON = () -> accessor.invoke(new ZeroBuffer(), MinecraftRegistryAccess.get()); + } else { + ConstructorAccessor accessor = Accessors.getConstructorAccessor(withStringIntercept, ByteBuf.class); + TRICKED_DATA_SERIALIZER_JSON = () -> accessor.invoke(new ZeroBuffer()); + } } /** diff --git a/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java b/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java index 1b205e93d..f422efb1b 100644 --- a/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java +++ b/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java @@ -33,6 +33,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +import javax.annotation.Nullable; + import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType.Sender; import com.comphenix.protocol.ProtocolLogger; @@ -46,6 +48,7 @@ import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.WrappedStreamCodec; /** * Static packet registry in Minecraft. @@ -67,11 +70,12 @@ static void reset() { * * @author Kristian */ - protected static class Register { + private static class Register { // The main lookup table final Map>> typeToClass = new ConcurrentHashMap<>(); final Map, PacketType> classToType = new ConcurrentHashMap<>(); + final Map, WrappedStreamCodec> classToCodec = new ConcurrentHashMap<>(); final Map, PacketType>> protocolClassToType = new ConcurrentHashMap<>(); volatile Set serverPackets = new HashSet<>(); @@ -297,16 +301,27 @@ private static synchronized Register createRegisterV1_20_5() { final Map> packetTypeMap = new HashMap<>(); // List of all class containing PacketTypes - String[] packetTypesClassNames = new String[] { "common.CommonPacketTypes", - "configuration.ConfigurationPacketTypes", "cookie.CookiePacketTypes", "game.GamePacketTypes", - "handshake.HandshakePacketTypes", "login.LoginPacketTypes", "ping.PingPacketTypes", - "status.StatusPacketTypes", }; + String[] packetTypesClassNames = new String[] { + "common.CommonPacketTypes", + "configuration.ConfigurationPacketTypes", + "cookie.CookiePacketTypes", + "game.GamePacketTypes", + "handshake.HandshakePacketTypes", + "login.LoginPacketTypes", + "ping.PingPacketTypes", + "status.StatusPacketTypes" + }; Class packetTypeClass = MinecraftReflection.getMinecraftClass("network.protocol.PacketType"); for (String packetTypesClassName : packetTypesClassNames) { Class packetTypesClass = MinecraftReflection - .getMinecraftClass("network.protocol." + packetTypesClassName); + .getOptionalNMS("network.protocol." + packetTypesClassName) + .orElse(null); + if (packetTypesClass == null) { + ProtocolLogger.debug("Can't find PacketType class: {0}, will skip it", packetTypesClassName); + continue; + } // check every field for "static final PacketType" for (Field field : packetTypesClass.getDeclaredFields()) { @@ -336,16 +351,24 @@ private static synchronized Register createRegisterV1_20_5() { final Map, Integer>> serverMaps = new LinkedHashMap<>(); final Map, Integer>> clientMaps = new LinkedHashMap<>(); + // global registry instance + final Register result = new Register(); + // List of all class containing ProtocolInfos - String[] protocolClassNames = new String[] { "configuration.ConfigurationProtocols", "game.GameProtocols", - "handshake.HandshakeProtocols", "login.LoginProtocols", "status.StatusProtocols" }; + String[] protocolClassNames = new String[] { + "configuration.ConfigurationProtocols", + "game.GameProtocols", + "handshake.HandshakeProtocols", + "login.LoginProtocols", + "status.StatusProtocols" + }; Class protocolInfoClass = MinecraftReflection.getProtocolInfoClass(); - Class protocolInfoUnboundClass = MinecraftReflection.getMinecraftClass("network.ProtocolInfo$a"); - Class streamCodecClass = MinecraftReflection.getMinecraftClass("network.codec.StreamCodec"); - Class idDispatchCodecClass = MinecraftReflection.getMinecraftClass("network.codec.IdDispatchCodec"); - Class protocolDirectionClass = MinecraftReflection - .getMinecraftClass("network.protocol.EnumProtocolDirection"); + Class protocolInfoUnboundClass = MinecraftReflection.getProtocolInfoUnboundClass(); + Class streamCodecClass = MinecraftReflection.getStreamCodecClass(); + Class idCodecClass = MinecraftReflection.getMinecraftClass("network.codec.IdDispatchCodec"); + Class idCodecEntryClass = MinecraftReflection.getMinecraftClass("network.codec.IdDispatchCodec$Entry", "network.codec.IdDispatchCodec$b"); + Class protocolDirectionClass = MinecraftReflection.getPacketFlowClass(); Function emptyFunction = input -> null; @@ -363,11 +386,30 @@ private static synchronized Register createRegisterV1_20_5() { MethodAccessor bindAccessor = Accessors.getMethodAccessor(FuzzyReflection.fromClass(protocolInfoUnboundClass) .getMethodByReturnTypeAndParameters("bind", protocolInfoClass, new Class[] { Function.class })); - FieldAccessor toIdAccessor = Accessors.getFieldAccessor(FuzzyReflection.fromClass(idDispatchCodecClass, true) + FuzzyReflection idCodecReflection = FuzzyReflection.fromClass(idCodecClass, true); + + FieldAccessor byIdAccessor = Accessors.getFieldAccessor(idCodecReflection + .getField(FuzzyFieldContract.newBuilder().typeDerivedOf(List.class).build())); + + FieldAccessor toIdAccessor = Accessors.getFieldAccessor(idCodecReflection .getField(FuzzyFieldContract.newBuilder().typeDerivedOf(Map.class).build())); + FuzzyReflection idCodecEntryReflection = FuzzyReflection.fromClass(idCodecEntryClass, true); + + MethodAccessor idCodecEntryTypeAccessor = Accessors.getMethodAccessor(idCodecEntryReflection + .getMethodByReturnTypeAndParameters("type", Object.class, new Class[0])); + + MethodAccessor idCodecEntrySerializerAccessor = Accessors.getMethodAccessor(idCodecEntryReflection + .getMethodByReturnTypeAndParameters("serializer", streamCodecClass, new Class[0])); + for (String protocolClassName : protocolClassNames) { - Class protocolClass = MinecraftReflection.getMinecraftClass("network.protocol." + protocolClassName); + Class protocolClass = MinecraftReflection + .getOptionalNMS("network.protocol." + protocolClassName) + .orElse(null); + if (protocolClass == null) { + ProtocolLogger.debug("Can't find protocol class: {0}, will skip it", protocolClassName); + continue; + } for (Field field : protocolClass.getDeclaredFields()) { try { @@ -391,21 +433,35 @@ private static synchronized Register createRegisterV1_20_5() { // get codec and check if codec is instance of IdDispatchCodec // since that is the only support codec as of now Object codec = codecAccessor.invoke(protocolInfo); - if (!idDispatchCodecClass.isInstance(codec)) { + if (!idCodecClass.isInstance(codec)) { continue; } // retrieve packetTypeMap and convert it to packetIdMap Map, Integer> packetMap = new HashMap<>(); + List serializerList = (List) byIdAccessor.get(codec); Map packetTypeIdMap = (Map) toIdAccessor.get(codec); for (Map.Entry entry : packetTypeIdMap.entrySet()) { - Class packet = packetTypeMap.get(entry.getKey()); - if (packet == null) { + Class packetClass = packetTypeMap.get(entry.getKey()); + if (packetClass == null) { throw new RuntimeException("packetType missing packet " + entry.getKey()); } - packetMap.put(packet, entry.getValue()); + packetMap.put(packetClass, entry.getValue()); + } + + // retrieve packet codecs for packet construction and write methods + for (Object entry : serializerList) { + Object packetType = idCodecEntryTypeAccessor.invoke(entry); + + Class packetClass = packetTypeMap.get(packetType); + if (packetClass == null) { + throw new RuntimeException("packetType missing packet " + packetType); + } + + Object serializer = idCodecEntrySerializerAccessor.invoke(entry); + result.classToCodec.put(packetClass, new WrappedStreamCodec(serializer)); } // get EnumProtocol and Direction of protocol info @@ -424,8 +480,6 @@ private static synchronized Register createRegisterV1_20_5() { } } - Register result = new Register(); - for (Object protocol : protocols) { Enum enumProtocol = (Enum) protocol; PacketType.Protocol equivalent = PacketType.Protocol.fromVanilla(enumProtocol); @@ -506,6 +560,18 @@ static void initialize() { } } + /** + * Returns the wrapped stream codec to de-/serialize the given packet class + * + * @param packetClass - the packet class + * @return wrapped stream codec if existing, otherwise null + */ + @Nullable + public static WrappedStreamCodec getStreamCodec(Class packetClass) { + initialize(); + return REGISTER.classToCodec.get(packetClass); + } + /** * Determine if the given packet type is supported on the current server. * diff --git a/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java b/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java index ff6abd6f5..b484447a3 100644 --- a/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java +++ b/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java @@ -5,7 +5,9 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.List; +import java.util.Optional; import java.util.concurrent.Callable; +import java.util.function.Function; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; @@ -15,9 +17,9 @@ import com.comphenix.protocol.reflect.accessors.MethodAccessor; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; +import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; - import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.implementation.bind.annotation.Origin; @@ -47,9 +49,29 @@ public final class MinecraftMethods { // Decorated PacketSerializer to identify methods private volatile static ConstructorAccessor decoratedDataSerializerAccessor; + private volatile static Function friendlyBufBufConstructor; + private MinecraftMethods() { // sealed } + + public static Function getFriendlyBufBufConstructor() { + if (friendlyBufBufConstructor == null) { + Optional> registryByteBuf = MinecraftReflection.getRegistryFriendlyByteBufClass(); + + if (registryByteBuf.isPresent()) { + ConstructorAccessor accessor = Accessors.getConstructorAccessor(FuzzyReflection.fromClass(registryByteBuf.get()).getConstructor(FuzzyMethodContract.newBuilder() + .parameterDerivedOf(ByteBuf.class) + .parameterDerivedOf(MinecraftReflection.getRegistryAccessClass()) + .build())); + friendlyBufBufConstructor = (byteBuf) -> accessor.invoke(byteBuf, MinecraftRegistryAccess.get()); + } else { + ConstructorAccessor accessor = Accessors.getConstructorAccessor(MinecraftReflection.getPacketDataSerializerClass(), ByteBuf.class); + friendlyBufBufConstructor = (byteBuf) -> accessor.invoke(byteBuf); + } + } + return friendlyBufBufConstructor; + } /** * Retrieve the send packet method in PlayerConnection/NetServerHandler. @@ -145,6 +167,7 @@ public static MethodAccessor getNetworkManagerReadPacketMethod() { * Retrieve the Packet.read(PacketDataSerializer) method. * * @return The packet read method. + * @deprecated no longer works since 1.20.5 */ public static MethodAccessor getPacketReadByteBufMethod() { initializePacket(); @@ -157,6 +180,7 @@ public static MethodAccessor getPacketReadByteBufMethod() { * This only exists in version 1.7.2 and above. * * @return The packet write method. + * @deprecated no longer works since 1.20.5 */ public static MethodAccessor getPacketWriteByteBufMethod() { initializePacket(); @@ -195,6 +219,11 @@ public Object delegate(@SuperCall(nullIfImpossible = true) Callable zuper, @O * Initialize the two read() and write() methods. */ private static void initializePacket() { + // write and read methods are no longer part of the packet interface since 1.20.5 + if (MinecraftVersion.v1_20_5.atOrAbove()) { + throw new IllegalStateException("can't access packet read/write method after 1.20.5"); + } + // Initialize the methods if (packetReadByteBuf == null || packetWriteByteBuf == null) { // setups a decorated PacketDataSerializer which we can use to identity read/write methods in the packet class diff --git a/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java b/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java index da64a8d60..b18282a72 100644 --- a/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java +++ b/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java @@ -30,6 +30,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLogger; import com.comphenix.protocol.injector.BukkitUnwrapper; @@ -43,12 +49,9 @@ import com.comphenix.protocol.reflect.fuzzy.FuzzyMatchers; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.wrappers.EnumWrappers; + +import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Server; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; /** * Methods and constants specifically used in conjuction with reflecting Minecraft object. @@ -160,7 +163,7 @@ public static String getMinecraftPackage() { Matcher packageMatcher = PACKAGE_VERSION_MATCHER.matcher(CRAFTBUKKIT_PACKAGE); if (packageMatcher.matches()) { packageVersion = packageMatcher.group(1); - } else { + } else if (!MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) { // ignore version prefix since it's no longer needed MinecraftVersion version = new MinecraftVersion(craftServer); // Just assume R1 - it's probably fine (warn anyway) @@ -1500,9 +1503,7 @@ public static String getNetworkManagerName() { */ public static Object getPacketDataSerializer(Object buffer) { try { - // TODO: move this to MinecraftMethods, or at least, cache the constructor accessor - Class packetSerializer = getPacketDataSerializerClass(); - return packetSerializer.getConstructor(getByteBufClass()).newInstance(buffer); + return MinecraftMethods.getFriendlyBufBufConstructor().apply((ByteBuf) buffer); } catch (Exception e) { throw new RuntimeException("Cannot construct packet serializer.", e); } @@ -1721,12 +1722,32 @@ public static Class getHolderClass() { public static Class getCraftServer() { return getCraftBukkitClass("CraftServer"); } - + public static Class getHolderLookupProviderClass() { return getMinecraftClass("core.HolderLookup$a" /* Spigot Mappings */, "core.HolderLookup$Provider" /* Mojang Mappings */); } + public static Class getRegistryAccessClass() { + return getMinecraftClass("core.IRegistryCustom" /* Spigot Mappings */, "core.RegistryAccess" /* Mojang Mappings */); + } + public static Class getProtocolInfoClass() { return getMinecraftClass("network.ProtocolInfo"); } + + public static Class getProtocolInfoUnboundClass() { + return getMinecraftClass("network.ProtocolInfo$a" /* Spigot Mappings */, "network.ProtocolInfo$Unbound" /* Mojang Mappings */); + } + + public static Class getPacketFlowClass() { + return getMinecraftClass("network.protocol.EnumProtocolDirection" /* Spigot Mappings */, "network.protocol.PacketFlow" /* Mojang Mappings */); + } + + public static Class getStreamCodecClass() { + return getMinecraftClass("network.codec.StreamCodec"); + } + + public static Optional> getRegistryFriendlyByteBufClass() { + return getOptionalNMS("network.RegistryFriendlyByteBuf"); + } } diff --git a/src/main/java/com/comphenix/protocol/utility/MinecraftRegistryAccess.java b/src/main/java/com/comphenix/protocol/utility/MinecraftRegistryAccess.java index 5d1a01301..04c2079bf 100644 --- a/src/main/java/com/comphenix/protocol/utility/MinecraftRegistryAccess.java +++ b/src/main/java/com/comphenix/protocol/utility/MinecraftRegistryAccess.java @@ -34,7 +34,7 @@ public class MinecraftRegistryAccess { FuzzyReflection.fromClass(MinecraftReflection.getMinecraftServerClass(), false) .getMethod(FuzzyMethodContract.newBuilder() .banModifier(Modifier.STATIC) - .returnDerivedOf(MinecraftReflection.getHolderLookupProviderClass()) + .returnDerivedOf(MinecraftReflection.getRegistryAccessClass()) .build())); } } diff --git a/src/main/java/com/comphenix/protocol/utility/Util.java b/src/main/java/com/comphenix/protocol/utility/Util.java index 3f496d476..a73bdc633 100644 --- a/src/main/java/com/comphenix/protocol/utility/Util.java +++ b/src/main/java/com/comphenix/protocol/utility/Util.java @@ -23,7 +23,6 @@ public final class Util { private static final boolean SPIGOT = classExists("org.spigotmc.SpigotConfig"); private static final boolean FOLIA = classExists("io.papermc.paper.threadedregions.RegionizedServer"); - private static Class cachedBundleClass; public static boolean classExists(String className) { try { diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java index caf5114ea..d5e6a8e28 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java +++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java @@ -9,6 +9,7 @@ import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.reflect.accessors.ConstructorAccessor; import com.comphenix.protocol.reflect.accessors.MethodAccessor; +import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftRegistryAccess; import com.comphenix.protocol.utility.MinecraftVersion; @@ -35,24 +36,30 @@ public class WrappedChatComponent extends AbstractWrapper implements ClonableWra private static ConstructorAccessor CONSTRUCT_TEXT_COMPONENT = null; static { - FuzzyReflection fuzzy = FuzzyReflection.fromClass(SERIALIZER, true); + FuzzyReflection reflection = FuzzyReflection.fromClass(SERIALIZER, true); // Retrieve the correct methods if (MinecraftVersion.v1_20_5.atOrAbove()) { - SERIALIZE_COMPONENT = Accessors.getMethodAccessor(fuzzy.getMethodByReturnTypeAndParameters("serialize", /* a */ - String.class, new Class[] { COMPONENT, MinecraftReflection.getHolderLookupProviderClass() })); + SERIALIZE_COMPONENT = Accessors.getMethodAccessor(reflection.getMethod(FuzzyMethodContract.newBuilder() + .returnTypeExact(String.class) + .parameterDerivedOf(COMPONENT) + .parameterDerivedOf(MinecraftReflection.getHolderLookupProviderClass()) + .build())); } else { - SERIALIZE_COMPONENT = Accessors.getMethodAccessor(fuzzy.getMethodByReturnTypeAndParameters("serialize", /* a */ + SERIALIZE_COMPONENT = Accessors.getMethodAccessor(reflection.getMethodByReturnTypeAndParameters("serialize", /* a */ String.class, new Class[] { COMPONENT })); } - GSON = Accessors.getFieldAccessor(fuzzy.getFieldByType("gson", GSON_CLASS)).get(null); + GSON = Accessors.getFieldAccessor(reflection.getFieldByType("gson", GSON_CLASS)).get(null); if (MinecraftVersion.v1_20_5.atOrAbove()) { - DESERIALIZE = Accessors.getMethodAccessor(FuzzyReflection.fromClass(SERIALIZER, false) - .getMethodByReturnTypeAndParameters("fromJson", MUTABLE_COMPONENT_CLASS.get(), new Class[] { String.class, MinecraftReflection.getHolderLookupProviderClass() })); + DESERIALIZE = Accessors.getMethodAccessor(reflection.getMethod(FuzzyMethodContract.newBuilder() + .returnDerivedOf(COMPONENT) + .parameterExactType(String.class) + .parameterDerivedOf(MinecraftReflection.getHolderLookupProviderClass()) + .build())); } else if (MinecraftVersion.v1_20_4.atOrAbove()) { - DESERIALIZE = Accessors.getMethodAccessor(FuzzyReflection.fromClass(SERIALIZER, false) + DESERIALIZE = Accessors.getMethodAccessor(reflection .getMethodByReturnTypeAndParameters("fromJson", MUTABLE_COMPONENT_CLASS.get(), new Class[] { String.class })); } else { try { diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedLevelChunkData.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedLevelChunkData.java index 756bf2c08..bf81039c6 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/WrappedLevelChunkData.java +++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedLevelChunkData.java @@ -1,23 +1,24 @@ package com.comphenix.protocol.wrappers; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +import org.jetbrains.annotations.Nullable; + import com.comphenix.protocol.injector.StructureCache; import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.reflect.accessors.ConstructorAccessor; import com.comphenix.protocol.reflect.accessors.FieldAccessor; import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract; +import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; -import com.comphenix.protocol.utility.ZeroBuffer; import com.comphenix.protocol.wrappers.nbt.NbtCompound; import com.comphenix.protocol.wrappers.nbt.NbtFactory; import com.google.common.collect.Lists; -import org.jetbrains.annotations.Nullable; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.List; /** * Wrapper classes for ClientboundLevelChunkWithLightPacket @@ -45,8 +46,11 @@ public static final class ChunkData extends AbstractWrapper { static { FuzzyReflection reflection = FuzzyReflection.fromClass(HANDLE_TYPE, true); - LEVEL_CHUNK_PACKET_DATA_CONSTRUCTOR = Accessors.getConstructorAccessor(HANDLE_TYPE, - MinecraftReflection.getPacketDataSerializerClass(), int.class, int.class); + LEVEL_CHUNK_PACKET_DATA_CONSTRUCTOR = Accessors.getConstructorAccessor(reflection.getConstructor(FuzzyMethodContract.newBuilder() + .parameterDerivedOf(MinecraftReflection.getPacketDataSerializerClass()) + .parameterExactType(int.class) + .parameterExactType(int.class) + .build())); BLOCK_ENTITIES_DATA_ACCESSOR = Accessors.getFieldAccessor(reflection.getField(FuzzyFieldContract.newBuilder() .typeExact(List.class) .build())); @@ -160,8 +164,11 @@ public static class LightData extends AbstractWrapper { static { FuzzyReflection reflection = FuzzyReflection.fromClass(HANDLE_TYPE, true); - LIGHT_UPDATE_PACKET_DATA_CONSTRUCTOR = Accessors.getConstructorAccessor(HANDLE_TYPE, - MinecraftReflection.getPacketDataSerializerClass(), int.class, int.class); + LIGHT_UPDATE_PACKET_DATA_CONSTRUCTOR = Accessors.getConstructorAccessor(reflection.getConstructor(FuzzyMethodContract.newBuilder() + .parameterDerivedOf(MinecraftReflection.getPacketDataSerializerClass()) + .parameterExactType(int.class) + .parameterExactType(int.class) + .build())); BIT_SET_ACCESSORS = Accessors.getFieldAccessorArray(HANDLE_TYPE, BitSet.class, true); BYTE_ARRAY_LIST_ACCESSORS = Accessors.getFieldAccessorArray(HANDLE_TYPE, List.class, true); @@ -333,7 +340,7 @@ public static LightData fromValues(BitSet skyYMask, BitSet blockYMask, BitSet em */ public static LightData fromValues(BitSet skyYMask, BitSet blockYMask, BitSet emptySkyYMask, BitSet emptyBlockYMask, List skyUpdates, List blockUpdates) { - LightData data = new LightData(LIGHT_UPDATE_PACKET_DATA_CONSTRUCTOR.invoke(MinecraftReflection.getPacketDataSerializer(new ZeroBuffer()), 0, 0)); + LightData data = new LightData(LIGHT_UPDATE_PACKET_DATA_CONSTRUCTOR.invoke(StructureCache.newNullDataSerializer(), 0, 0)); data.setSkyYMask(skyYMask); data.setBlockYMask(blockYMask); diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedParticle.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedParticle.java index 4b8b15e1e..41efd1c75 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/WrappedParticle.java +++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedParticle.java @@ -217,8 +217,8 @@ private static Object getDustTransition(Object handle) { if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { StructureModifier modifier = new StructureModifier<>(handle.getClass()).withTarget(handle); - org.joml.Vector3f toRGB = (org.joml.Vector3f) modifier.withType(org.joml.Vector3f.class).read(0); - org.joml.Vector3f fromRGB = (org.joml.Vector3f) modifier.withType(org.joml.Vector3f.class).read(1); + org.joml.Vector3f toRGB = (org.joml.Vector3f) modifier.withType(org.joml.Vector3f.class).read(1); + org.joml.Vector3f fromRGB = (org.joml.Vector3f) modifier.withType(org.joml.Vector3f.class).read(0); size = (float) modifier.withType(float.class).read(0); fromR = (int) (fromRGB.x() * 255); diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedStreamCodec.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedStreamCodec.java new file mode 100644 index 000000000..5b498c8e3 --- /dev/null +++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedStreamCodec.java @@ -0,0 +1,41 @@ +package com.comphenix.protocol.wrappers; + +import com.comphenix.protocol.reflect.FuzzyReflection; +import com.comphenix.protocol.reflect.accessors.Accessors; +import com.comphenix.protocol.reflect.accessors.MethodAccessor; +import com.comphenix.protocol.utility.MinecraftReflection; + +/** + * Wrapper for StreamCodec class which is primarily used to de-/serialize + * packets since 1.20.5 + */ +public class WrappedStreamCodec extends AbstractWrapper { + + // use the de-/encoder interfaces to get the right method to avoid future errors + private static final Class DECODER_TYPE = MinecraftReflection.getMinecraftClass("network.codec.StreamDecoder"); + private static final Class ENCODER_TYPE = MinecraftReflection.getMinecraftClass("network.codec.StreamEncoder"); + + private static final MethodAccessor DECODE_ACCESSOR; + private static final MethodAccessor ENCODE_ACCESSOR; + + static { + DECODE_ACCESSOR = Accessors.getMethodAccessor(FuzzyReflection.fromClass(DECODER_TYPE) + .getMethodByReturnTypeAndParameters("decode", Object.class, new Class[] { Object.class })); + + ENCODE_ACCESSOR = Accessors.getMethodAccessor(FuzzyReflection.fromClass(ENCODER_TYPE) + .getMethodByReturnTypeAndParameters("encode", Void.TYPE, new Class[] { Object.class, Object.class })); + } + + public WrappedStreamCodec(Object handle) { + super(MinecraftReflection.getStreamCodecClass()); + setHandle(handle); + } + + public Object decode(Object buffer) { + return DECODE_ACCESSOR.invoke(handle, buffer); + } + + public void encode(Object buffer, Object value) { + ENCODE_ACCESSOR.invoke(handle, buffer, value); + } +} diff --git a/src/test/java/com/comphenix/protocol/BukkitInitialization.java b/src/test/java/com/comphenix/protocol/BukkitInitialization.java index 646d81c5b..3acfc21ae 100644 --- a/src/test/java/com/comphenix/protocol/BukkitInitialization.java +++ b/src/test/java/com/comphenix/protocol/BukkitInitialization.java @@ -134,12 +134,16 @@ private void initialize() { String serverVersion = CraftServer.class.getPackage().getImplementationVersion(); // Mock the server object - Server mockedServer = mock(Server.class); + CraftServer mockedServer = mock(CraftServer.class); + DedicatedServer mockedGameServer = mock(DedicatedServer.class); + + when(mockedGameServer.bc()/*registryAccess*/).thenReturn(registryCustom); when(mockedServer.getLogger()).thenReturn(java.util.logging.Logger.getLogger("Minecraft")); when(mockedServer.getName()).thenReturn("Mock Server"); when(mockedServer.getVersion()).thenReturn(serverVersion + " (MC: " + releaseTarget + ")"); when(mockedServer.getBukkitVersion()).thenReturn(Versioning.getBukkitVersion()); + when(mockedServer.getServer()).thenReturn(mockedGameServer); when(mockedServer.isPrimaryThread()).thenReturn(true); when(mockedServer.getItemFactory()).thenReturn(CraftItemFactory.instance()); diff --git a/src/test/java/com/comphenix/protocol/PacketTypeTest.java b/src/test/java/com/comphenix/protocol/PacketTypeTest.java index 5daa71561..66a676645 100644 --- a/src/test/java/com/comphenix/protocol/PacketTypeTest.java +++ b/src/test/java/com/comphenix/protocol/PacketTypeTest.java @@ -14,32 +14,35 @@ */ package com.comphenix.protocol; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + import com.comphenix.protocol.PacketType.Protocol; import com.comphenix.protocol.PacketType.Sender; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.injector.packet.PacketRegistry; import com.comphenix.protocol.utility.MinecraftReflection; -import com.comphenix.protocol.utility.MinecraftReflectionTestUtil; import com.comphenix.protocol.wrappers.WrappedChatComponent; -import net.minecraft.network.EnumProtocol; -import net.minecraft.network.protocol.EnumProtocolDirection; -import net.minecraft.network.protocol.login.PacketLoginInStart; -import org.apache.commons.lang.WordUtils; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import java.lang.reflect.Field; -import java.util.*; -import java.util.Map.Entry; -import static org.junit.jupiter.api.Assertions.*; +import net.minecraft.network.protocol.login.PacketLoginInStart; /** * @author dmulloy2 */ public class PacketTypeTest { + private static final Pattern PACKET_PATTERN = Pattern.compile("(?Serverbound|Clientbound)(?\\w+)Packet"); + @BeforeAll public static void beforeClass() { BukkitInitialization.initializeAll(); @@ -52,60 +55,41 @@ public static void beforeClass() { @AfterAll public static void afterClass() { - PacketType.onDynamicCreate = __ -> { + PacketType.onDynamicCreate = (x, y) -> { }; } - @SuppressWarnings("unchecked") - // @Test - // public static void main(String[] args) throws Exception { - public void generateNewPackets() throws Exception { - MinecraftReflectionTestUtil.init(); - - Set> allTypes = new HashSet<>(); - List> newTypes = new ArrayList<>(); - - EnumProtocol[] protocols = EnumProtocol.values(); - for (EnumProtocol protocol : protocols) { - System.out.println(WordUtils.capitalize(protocol.name().toLowerCase())); - - Field field = EnumProtocol.class.getDeclaredField("k"); - field.setAccessible(true); - - Map map = (Map) field.get(protocol); - for (Entry entry : map.entrySet()) { - Field mapField = entry.getValue().getClass().getDeclaredField("b"); - mapField.setAccessible(true); - - Map, Integer> reverseMap = (Map, Integer>) mapField.get(entry.getValue()); + public static void main(String[] args) throws Exception { +// public void generateNewPackets() throws Exception { + BukkitInitialization.initializeAll(); - Map> treeMap = new TreeMap<>(); - for (Entry, Integer> entry1 : reverseMap.entrySet()) { - treeMap.put(entry1.getValue(), entry1.getKey()); - } + PacketType.onDynamicCreate = (type, className) -> { + String packetTypeClassName = className; - System.out.println(" " + entry.getKey()); - for (Entry> entry1 : treeMap.entrySet()) { - System.out.println(generateNewType(entry1.getKey(), entry1.getValue())); - allTypes.add(entry1.getValue()); + Matcher matcher = PACKET_PATTERN.matcher(className); + if (matcher.find()) { + if (!matcher.group("sender").equals(type.getSender().getMojangName())) { + throw new RuntimeException(String.format("wrong packet flow, exepected: %s, got: %s", type.getSender().getMojangName(), matcher.group("sender"))); + } + packetTypeClassName = matcher.group("name"); + } - try { - PacketType.fromClass(entry1.getValue()); - } catch (Exception ex) { - newTypes.add(entry1.getValue()); - } - } - } - } + System.out.printf("%s, %s = new PacketType(PROTOCOL, SENDER, %s, \"%s\") %s\n", type.getProtocol(), type.getSender(), formatHex(type.getCurrentId()), packetTypeClassName, className); + }; - System.out.println("New types: " + newTypes); + PacketType.onIdMismatch = (type, newId) -> { + System.out.printf("%s, %s, %s %s MISMTACH %s\n", type.getProtocol(), type.getSender(), type.name(), formatHex(type.getCurrentId()), formatHex(newId)); + }; + + // initialize packet registry + PacketRegistry.getClientPacketTypes(); for (PacketType type : PacketType.values()) { if (type.isDeprecated()) { continue; } - if (!allTypes.contains(type.getPacketClass())) { + if (type.getPacketClass() == null) { System.out.println(type + " was removed"); } } @@ -286,60 +270,17 @@ public void testDeprecation() { } @Test - @SuppressWarnings("unchecked") - public void ensureTypesAreCorrect() throws Exception { - PacketType.onDynamicCreate = className -> { - throw new RuntimeException("Dynamically generated packet " + className); - }; - + public void ensureRegistryInitializes() throws Exception { try { - boolean fail = false; - - EnumProtocol[] protocols = EnumProtocol.values(); - for (EnumProtocol protocol : protocols) { - Field field = EnumProtocol.class.getDeclaredField("h"); - field.setAccessible(true); - - Map map = (Map) field.get(protocol); - for (Entry entry : map.entrySet()) { - Field holderField = entry.getValue().getClass().getDeclaredField("c"); - holderField.setAccessible(true); - - Object holder = holderField.get(entry.getValue()); - Field mapField = holder.getClass().getDeclaredField("b"); - mapField.setAccessible(true); - - Map, Integer> reverseMap = (Map, Integer>) mapField.get(holder); - - Map> treeMap = new TreeMap<>(); - for (Entry, Integer> entry1 : reverseMap.entrySet()) { - treeMap.put(entry1.getValue(), entry1.getKey()); - } - - for (Entry> entry1 : treeMap.entrySet()) { - try { - PacketType type = PacketType.fromClass(entry1.getValue()); - if (type.getCurrentId() != entry1.getKey()) { - throw new IllegalStateException( - "Packet ID for " + type + " is incorrect. Expected " + entry1.getKey() + ", but got " - + type.getCurrentId()); - } - } catch (Throwable ex) { - if (ex.getMessage().contains("BundleDelimiterPacket")) { - continue; - } - - ex.printStackTrace(); - fail = true; - } - } - } - } - - assertFalse(fail, "Packet type(s) were incorrect!"); - } finally { - PacketType.onDynamicCreate = __ -> { }; - } + PacketType.onDynamicCreate = (type, className) -> { + throw new RuntimeException("Dynamically generated packet " + className); + }; + + // try to initialize packet registry + PacketRegistry.getClientPacketTypes(); + } finally { + PacketType.onDynamicCreate = (x, y) -> { }; + } } @Test diff --git a/src/test/java/com/comphenix/protocol/utility/MinecraftMethodsTest.java b/src/test/java/com/comphenix/protocol/utility/MinecraftMethodsTest.java index 4d1966e36..6b94098da 100644 --- a/src/test/java/com/comphenix/protocol/utility/MinecraftMethodsTest.java +++ b/src/test/java/com/comphenix/protocol/utility/MinecraftMethodsTest.java @@ -31,8 +31,12 @@ public void initializePacket() throws NoSuchFieldException, IllegalAccessExcepti this.setNull("packetReadByteBuf"); this.setNull("packetWriteByteBuf"); - assertNotNull(MinecraftMethods.getPacketWriteByteBufMethod()); - // TODO it's now a constructor - // assertNotNull(MinecraftMethods.getPacketReadByteBufMethod()); + // the write and read method got replaced by the StreamCodec class and each + // packet now has it's own unique codec instance + if (!MinecraftVersion.v1_20_5.atOrAbove()) { + assertNotNull(MinecraftMethods.getPacketWriteByteBufMethod()); + // TODO it's now a constructor + // assertNotNull(MinecraftMethods.getPacketReadByteBufMethod()); + } } } diff --git a/src/test/java/com/comphenix/protocol/utility/MinecraftVersionTest.java b/src/test/java/com/comphenix/protocol/utility/MinecraftVersionTest.java index 0f68b48e8..59d4d20e5 100644 --- a/src/test/java/com/comphenix/protocol/utility/MinecraftVersionTest.java +++ b/src/test/java/com/comphenix/protocol/utility/MinecraftVersionTest.java @@ -48,7 +48,7 @@ void testComparison() { @Test void testCurrent() { - assertEquals(MinecraftVersion.v1_20_4, MinecraftVersion.getCurrentVersion()); + assertEquals(MinecraftVersion.v1_20_5, MinecraftVersion.getCurrentVersion()); } @Test