Skip to Content

Serverbound Packets

Overview

Players using Lunar Client may send packets to the server for specific Apollo modules, such as the PacketEnrichment Module and/or when the player is joining the server. This example demonstrates how to handle packets sent from the client that are related to Apollo.

Additionally, the Transfer Module expects a response packet from the client after the server sends a request. For an example of how to handle roundtrip packets, visit Packet Roundtrip Example

Integration

public class ApolloPacketReceiveProtoListener implements PluginMessageListener { public ApolloPacketReceiveProtoListener(ApolloExamplePlugin plugin) { Bukkit.getServer().getMessenger().registerIncomingPluginChannel(plugin, "lunar:apollo", this); } @Override public void onPluginMessageReceived(@NonNull String channel, @NonNull Player player, byte[] bytes) { try { Any any = Any.parseFrom(bytes); if (any.is(PlayerHandshakeMessage.class)) { this.onPlayerHandshake(any.unpack(PlayerHandshakeMessage.class)); } // Packet Enrichment Module if (any.is(PlayerAttackMessage.class)) { this.onPlayerAttack(any.unpack(PlayerAttackMessage.class)); } else if (any.is(PlayerChatOpenMessage.class)) { this.onPlayerChatOpen(any.unpack(PlayerChatOpenMessage.class)); } else if (any.is(PlayerChatCloseMessage.class)) { this.onPlayerChatClose(any.unpack(PlayerChatCloseMessage.class)); } else if (any.is(PlayerInventoryOpenMessage.class)) { this.onPlayerInventoryOpen(player, any.unpack(PlayerInventoryOpenMessage.class)); } else if (any.is(PlayerInventoryCloseMessage.class)) { this.onPlayerInventoryClose(player, any.unpack(PlayerInventoryCloseMessage.class)); } else if (any.is(PlayerUseItemMessage.class)) { this.onPlayerUseItem(any.unpack(PlayerUseItemMessage.class)); } else if (any.is(PlayerUseItemBucketMessage.class)) { this.onPlayerUseItemBucket(any.unpack(PlayerUseItemBucketMessage.class)); } } catch (InvalidProtocolBufferException e) { throw new RuntimeException(e); } } private void onPlayerHandshake(PlayerHandshakeMessage message) { EmbeddedCheckoutSupport checkoutSupport = message.getEmbeddedCheckoutSupport(); MinecraftVersion minecraftVersion = message.getMinecraftVersion(); LunarClientVersion lunarClientVersion = message.getLunarClientVersion(); String gitBranch = lunarClientVersion.getGitBranch(); String gitCommit = lunarClientVersion.getGitCommit(); String semVer = lunarClientVersion.getSemver(); List<ModMessage> installedMods = message.getInstalledModsList(); for (ModMessage mod : installedMods) { String modId = mod.getId(); String displayName = mod.getName(); String version = mod.getVersion(); ModMessage.Type type = mod.getType(); } } private void onPlayerAttack(PlayerAttackMessage message) { long instantiationTimeMs = ProtobufUtil.toJavaTimestamp(message.getPacketInfo().getInstantiationTime()); PlayerInfo targetInfo = message.getTargetInfo(); PlayerInfo attackerInfo = message.getAttackerInfo(); this.onPlayerInfo(targetInfo); this.onPlayerInfo(attackerInfo); } private void onPlayerChatOpen(PlayerChatOpenMessage message) { long instantiationTimeMs = ProtobufUtil.toJavaTimestamp(message.getPacketInfo().getInstantiationTime()); PlayerInfo playerInfo = message.getPlayerInfo(); this.onPlayerInfo(playerInfo); } private void onPlayerChatClose(PlayerChatCloseMessage message) { long instantiationTimeMs = ProtobufUtil.toJavaTimestamp(message.getPacketInfo().getInstantiationTime()); PlayerInfo playerInfo = message.getPlayerInfo(); this.onPlayerInfo(playerInfo); } private void onPlayerInventoryOpen(Player player, PlayerInventoryOpenMessage message) { long instantiationTimeMs = ProtobufUtil.toJavaTimestamp(message.getPacketInfo().getInstantiationTime()); PlayerInfo playerInfo = message.getPlayerInfo(); this.onPlayerInfo(playerInfo); InventoryExample example = ApolloExamplePlugin.getInstance().getInventoryExample(); if (example instanceof InventoryProtoExample) { ((InventoryProtoExample) example).handleInventoryOpen(player); } } private void onPlayerInventoryClose(Player player, PlayerInventoryCloseMessage message) { long instantiationTimeMs = ProtobufUtil.toJavaTimestamp(message.getPacketInfo().getInstantiationTime()); PlayerInfo playerInfo = message.getPlayerInfo(); this.onPlayerInfo(playerInfo); InventoryExample example = ApolloExamplePlugin.getInstance().getInventoryExample(); if (example instanceof InventoryProtoExample) { ((InventoryProtoExample) example).handleInventoryClose(player); } } private void onPlayerUseItem(PlayerUseItemMessage message) { long instantiationTimeMs = ProtobufUtil.toJavaTimestamp(message.getPacketInfo().getInstantiationTime()); PlayerInfo playerInfo = message.getPlayerInfo(); this.onPlayerInfo(playerInfo); boolean mainHand = message.getMainHand(); } private void onPlayerUseItemBucket(PlayerUseItemBucketMessage message) { long instantiationTimeMs = ProtobufUtil.toJavaTimestamp(message.getPacketInfo().getInstantiationTime()); PlayerInfo playerInfo = message.getPlayerInfo(); this.onPlayerInfo(playerInfo); RayTraceResult rayTraceResult = message.getRayTraceResult(); if (rayTraceResult.hasBlock()) { BlockHit blockHit = rayTraceResult.getBlock(); Location hitLocation = blockHit.getHitLocation(); BlockLocation blockLocation = blockHit.getBlockLocation(); Direction direction = blockHit.getDirection(); } else if (rayTraceResult.hasEntity()) { EntityHit entityHit = rayTraceResult.getEntity(); Location hitLocation = entityHit.getHitLocation(); EntityId entityId = entityHit.getEntityId(); } else { // Miss } } private void onPlayerInfo(PlayerInfo info) { UUID uuid = ProtobufUtil.toJavaUuid(info.getPlayerUuid()); org.bukkit.Location location = ProtobufUtil.toBukkitLocation(info.getLocation()); boolean sneaking = info.getSneaking(); boolean sprinting = info.getSprinting(); boolean jumping = info.getJumping(); float forwardSpeed = info.getForwardSpeed(); float strafeSpeed = info.getStrafeSpeed(); } }