// Path: src/main/java/net/techcable/spudcompat/ProtocolVersion.java
// @RequiredArgsConstructor
// public enum ProtocolVersion {
//     v1_7_10(5),
//     v1_8(47);
// 
//     public boolean isBefore(ProtocolVersion other) {
//         return this.getId() < other.getId();
//     }
// 
//     private final int versionNumber;
// 
//     public int getId() {
//         return versionNumber;
//     }
// 
//     public static final int MAX_ID;
//     private static final ProtocolVersion[] BY_ID;
// 
//     static {
//         int maxId = 0;
//         for (ProtocolVersion version : values()) {
//             if (version.getId() > maxId) {
//                 maxId = version.getId();
//             }
//         }
//         MAX_ID = maxId;
//         BY_ID = new ProtocolVersion[MAX_ID + 1];
//         for (ProtocolVersion version : values()) {
//             int id = version.getId();
//             if (BY_ID[id] != null) throw new AssertionError("Already a version with id: " + id);
//             BY_ID[id] = version;
//         }
//     }
// 
//     public static ProtocolVersion getById(int id) {
//         if (id < 0) {
//             throw new IllegalArgumentException("Negative id: " + id);
//         } else if (id < BY_ID.length) {
//             return BY_ID[id];
//         } else {
//             return null;
//         }
//     }
// }
// 
// Path: src/main/java/net/techcable/spudcompat/protocol/Packet.java
// public interface Packet {
//     public PacketType getType();
// 
//     public void write(ByteBuf buf, ProtocolVersion version, ProtocolState state, ProtocolDirection direction);
// 
//     public default RawPacket toRaw(ByteBufAllocator allocator, ProtocolVersion version, ProtocolState state, ProtocolDirection direction) {
//         ByteBuf buf = allocator.buffer();
//         write(buf, version, state, direction);
//         RawPacket raw = RawPacket.fromBuffer(buf, state, direction);
//         buf.release();
//         assert buf.refCnt() != 0;
//         assert raw.getType() == this.getType();
//         return raw;
//     }
// }
// 
// Path: src/main/java/net/techcable/spudcompat/protocol/PlayerConnection.java
// public interface PlayerConnection {
// 
//     public default boolean isSupportedVersion() {
//         return ProtocolVersion.getById(getVersionId()) != null;
//     }
// 
//     public default ProtocolVersion getVersion() {
//         int id = getVersionId();
//         ProtocolVersion version = ProtocolVersion.getById(id);
//         if (version != null) {
//             return version;
//         } else {
//             throw new IllegalStateException("Unsupported version: " + id);
//         }
//     }
// 
//     public ProtocolState getState();
// 
//     public int getVersionId();
// 
//     public void sendPacket(RawPacket rawPacket);
// 
//     public Channel getChannel();
// 
//     public Server getServer();
// }
// 
// Path: src/main/java/net/techcable/spudcompat/protocol/ProtocolDirection.java
// public enum ProtocolDirection {
//     CLIENTBOUND(ProtocolConstants.Direction.TO_CLIENT),
//     SERVERBOUND(ProtocolConstants.Direction.TO_SERVER);
// 
//     private ProtocolDirection(ProtocolConstants.Direction bungee) {
//         this.bungee = checkNotNull(bungee, "Null bungee direction");
//     }
// 
//     private final ProtocolConstants.Direction bungee;
// 
//     public ProtocolConstants.Direction asBungee() {
//         return bungee;
//     }
// }
// 
// Path: src/main/java/net/techcable/spudcompat/protocol/ProtocolState.java
// @RequiredArgsConstructor
// public enum ProtocolState {
//     HANDSHAKE(Protocol.HANDSHAKE),
//     LOGIN(Protocol.LOGIN),
//     PLAY(Protocol.GAME),
//     STATUS(Protocol.STATUS);
// 
//     private final Protocol bungee;
// 
//     public Protocol toBungee() {
//         return bungee;
//     }
// }


import lombok.*;
import net.techcable.spudcompat.ProtocolVersion;
import net.techcable.spudcompat.protocol.Packet;
import net.techcable.spudcompat.protocol.PlayerConnection;
import net.techcable.spudcompat.protocol.ProtocolDirection;
import net.techcable.spudcompat.protocol.ProtocolState;
import static com.google.common.base.Preconditions.checkNotNull;
package net.techcable.spudcompat.protocol.injector;




public interface PacketListener {

    public default Result onRawSend(PlayerConnection connection, RawPacket packet) {
        return Result.IGNORED;
    }

    public default Result onRawReceive(PlayerConnection connection, RawPacket packet) {
        return Result.IGNORED;
    }

    public Result onSend(PlayerConnection connection, Packet definedPacket);

    public Result onReceive(PlayerConnection connection, Packet definedPacket);

    @Getter
    @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
    public static class Result {
        private final boolean canceled;
        private final RawPacket result;
// Path: src/main/java/net/techcable/spudcompat/ProtocolVersion.java
// @RequiredArgsConstructor
// public enum ProtocolVersion {
//     v1_7_10(5),
//     v1_8(47);
// 
//     public boolean isBefore(ProtocolVersion other) {
//         return this.getId() < other.getId();
//     }
// 
//     private final int versionNumber;
// 
//     public int getId() {
//         return versionNumber;
//     }
// 
//     public static final int MAX_ID;
//     private static final ProtocolVersion[] BY_ID;
// 
//     static {
//         int maxId = 0;
//         for (ProtocolVersion version : values()) {
//             if (version.getId() > maxId) {
//                 maxId = version.getId();
//             }
//         }
//         MAX_ID = maxId;
//         BY_ID = new ProtocolVersion[MAX_ID + 1];
//         for (ProtocolVersion version : values()) {
//             int id = version.getId();
//             if (BY_ID[id] != null) throw new AssertionError("Already a version with id: " + id);
//             BY_ID[id] = version;
//         }
//     }
// 
//     public static ProtocolVersion getById(int id) {
//         if (id < 0) {
//             throw new IllegalArgumentException("Negative id: " + id);
//         } else if (id < BY_ID.length) {
//             return BY_ID[id];
//         } else {
//             return null;
//         }
//     }
// }
// 
// Path: src/main/java/net/techcable/spudcompat/protocol/Packet.java
// public interface Packet {
//     public PacketType getType();
// 
//     public void write(ByteBuf buf, ProtocolVersion version, ProtocolState state, ProtocolDirection direction);
// 
//     public default RawPacket toRaw(ByteBufAllocator allocator, ProtocolVersion version, ProtocolState state, ProtocolDirection direction) {
//         ByteBuf buf = allocator.buffer();
//         write(buf, version, state, direction);
//         RawPacket raw = RawPacket.fromBuffer(buf, state, direction);
//         buf.release();
//         assert buf.refCnt() != 0;
//         assert raw.getType() == this.getType();
//         return raw;
//     }
// }
// 
// Path: src/main/java/net/techcable/spudcompat/protocol/PlayerConnection.java
// public interface PlayerConnection {
// 
//     public default boolean isSupportedVersion() {
//         return ProtocolVersion.getById(getVersionId()) != null;
//     }
// 
//     public default ProtocolVersion getVersion() {
//         int id = getVersionId();
//         ProtocolVersion version = ProtocolVersion.getById(id);
//         if (version != null) {
//             return version;
//         } else {
//             throw new IllegalStateException("Unsupported version: " + id);
//         }
//     }
// 
//     public ProtocolState getState();
// 
//     public int getVersionId();
// 
//     public void sendPacket(RawPacket rawPacket);
// 
//     public Channel getChannel();
// 
//     public Server getServer();
// }
// 
// Path: src/main/java/net/techcable/spudcompat/protocol/ProtocolDirection.java
// public enum ProtocolDirection {
//     CLIENTBOUND(ProtocolConstants.Direction.TO_CLIENT),
//     SERVERBOUND(ProtocolConstants.Direction.TO_SERVER);
// 
//     private ProtocolDirection(ProtocolConstants.Direction bungee) {
//         this.bungee = checkNotNull(bungee, "Null bungee direction");
//     }
// 
//     private final ProtocolConstants.Direction bungee;
// 
//     public ProtocolConstants.Direction asBungee() {
//         return bungee;
//     }
// }
// 
// Path: src/main/java/net/techcable/spudcompat/protocol/ProtocolState.java
// @RequiredArgsConstructor
// public enum ProtocolState {
//     HANDSHAKE(Protocol.HANDSHAKE),
//     LOGIN(Protocol.LOGIN),
//     PLAY(Protocol.GAME),
//     STATUS(Protocol.STATUS);
// 
//     private final Protocol bungee;
// 
//     public Protocol toBungee() {
//         return bungee;
//     }
// }


// Path: src/main/java/net/techcable/spudcompat/protocol/injector/PacketListener.java
import lombok.*;
import net.techcable.spudcompat.ProtocolVersion;
import net.techcable.spudcompat.protocol.Packet;
import net.techcable.spudcompat.protocol.PlayerConnection;
import net.techcable.spudcompat.protocol.ProtocolDirection;
import net.techcable.spudcompat.protocol.ProtocolState;
import static com.google.common.base.Preconditions.checkNotNull;

package net.techcable.spudcompat.protocol.injector;




public interface PacketListener {

    public default Result onRawSend(PlayerConnection connection, RawPacket packet) {
        return Result.IGNORED;
    }

    public default Result onRawReceive(PlayerConnection connection, RawPacket packet) {
        return Result.IGNORED;
    }

    public Result onSend(PlayerConnection connection, Packet definedPacket);

    public Result onReceive(PlayerConnection connection, Packet definedPacket);

    @Getter
    @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
    public static class Result {
        private final boolean canceled;
        private final RawPacket result;
        private final ProtocolVersion version;