Skip to content

Custom Packets

Vrekt edited this page May 11, 2023 · 2 revisions

Lunar supports the use of registering custom packets.

I will provide an example from my multiplayer game Oasis

In my game, I have a many custom packets, for this example I have two packets ServerPlayerEquippedItem and ServerPlayerSwungItem. Both are related to other players in the world either swinging or equipping a new item

First, I start by extending PlayerConnectionHandler into my own connection class

public class PlayerConnection extends PlayerConnectionHandler {}

Next, I register my packets.

registerPacket(ServerPlayerEquippedItem.ID, ServerPlayerEquippedItem::new, this::handlePlayerEquippedItem);
registerPacket(ServerPlayerSwungItem.ID, ServerPlayerSwungItem::new, this::handleSwingItem);

The constructor is as follows:

  • The packet ID
  • An PacketFactory<T> that will create a new packet
  • A consumer that will accept the newly created packet and handle it.

This is my full implementation:

public class PlayerConnection extends PlayerConnectionHandler {

    private final OasisPlayerSP player;

    public PlayerConnection(Channel channel, LunarProtocol protocol, OasisPlayerSP player) {
        super(channel, protocol);
        this.player = player;

        registerPacket(ServerSpawnEntity.ID, ServerSpawnEntity::new, this::handleSpawnEntity);
        registerPacket(ServerPlayerEquippedItem.ID, ServerPlayerEquippedItem::new, this::handlePlayerEquippedItem);
        registerPacket(ServerPlayerSwungItem.ID, ServerPlayerSwungItem::new, this::handleSwingItem);
    }

    private void handleSpawnEntity(ServerSpawnEntity packet) {
        switch (packet.getType()) {
            case INVALID:
                break;
            case TUTORIAL_COMBAT_DUMMY:
                final EntityNPCType type = EntityNPCType.typeOfServer(packet.getType());
                if (type != EntityNPCType.INVALID) {
                    player.getGameWorldIn().spawnEntityTypeAt(type, packet.getPosition());
                }
                break;
        }
    }

    private void handlePlayerEquippedItem(ServerPlayerEquippedItem packet) {
        if (player.getGameWorldIn().hasNetworkPlayer(packet.getEntityId())) {
            player.getGameWorldIn()
                    .getNetworkPlayer(packet.getEntityId())
                    .setEquippingItem(packet.getItemId());
        } else {
            Logging.warn(this, "No player by ID (equip)" + packet.getEntityId());
        }
    }

    private void handleSwingItem(ServerPlayerSwungItem packet) {
        if (player.getGameWorldIn().hasNetworkPlayer(packet.getEntityId())) {
            player.getGameWorldIn()
                    .getNetworkPlayer(packet.getEntityId())
                    .setSwingingItem(packet.getItemId());
        } else {
            Logging.warn(this, "No player by ID (swing)" + packet.getEntityId());
        }
    }

}