package com.gmail.woodyc40.common.protocol.impl;
import com.esotericsoftware.reflectasm.FieldAccess;
import com.gmail.woodyc40.common.protocol.ByteAppender;
import com.gmail.woodyc40.common.protocol.Packet;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.tridentsdk.server.TridentServer;
import net.tridentsdk.server.netty.packet.PacketData;
import net.tridentsdk.server.netty.packet.PacketDirection;
import net.tridentsdk.server.netty.protocol.Protocol;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Implements {@link com.gmail.woodyc40.common.protocol.Packet}
*
* @author Pierre C
*/
public class PacketImpl implements Packet {
/** The Trident packet */
private final net.tridentsdk.server.netty.packet.Packet packet;
/** The field getter and setter */
private final FieldAccess access;
/** The write index */
private final AtomicInteger writeIdx = new AtomicInteger();
/** The read index */
private final AtomicInteger readIdx = new AtomicInteger();
/**
* Constructs a new packet wrapper with the data provided
*
* @param data the data
*/
private PacketImpl(PacketData data) {
this.packet = TridentServer
.instance()
.protocol()
.getPacket(data.getId(), Protocol.ClientStage.PLAY, PacketDirection.IN);
this.access = FieldAccess.get(packet.getClass());
this.packet.decode(data.getData());
data.getData().resetReaderIndex();
}
/**
* Constructs a new packet wrapper with the packet provided
*
* @param packet the packet
*/
PacketImpl(net.tridentsdk.server.netty.packet.Packet packet) {
this.packet = packet;
this.access = FieldAccess.get(packet.getClass());
}
/**
* Constructs a new packet wrapper with the data provided
*
* @param msg the data
* @return the new packet wrapper
*/
public static PacketImpl in(Object msg) {
return new PacketImpl((PacketData) msg);
}
/**
* Constructs a new packet wrapper with the packet provided
*
* @param msg the packet
* @return the new packet wrapper
*/
public static PacketImpl out(Object msg) {
return new PacketImpl((net.tridentsdk.server.netty.packet.Packet) msg);
}
@Override public void write(int idx, Object o) {
access.set(packet, idx, o);
}
@Override public void write(Object o) {
access.set(packet, writeIdx.getAndIncrement(), o);
}
@Override public int writeIndex() {
return writeIdx.get();
}
@Override public void setWriteIndex(int index) {
writeIdx.set(id());
}
@Override public Object read(int idx) {
return access.get(packet, idx);
}
@Override public Object read() {
return access.get(packet, readIdx.getAndIncrement());
}
@Override public int readIndex() {
return readIdx.get();
}
@Override public void setReadIndex(int index) {
readIdx.set(index);
}
@Override public int id() {
return this.packet.id();
}
@Override public void encode(ByteAppender appender) {
appender.segment();
ByteBuf b = Unpooled.directBuffer();
this.packet.encode(b);
appender.append(b);
b.release();
}
@Override public void decode(ByteBuf buf) {
packet.decode(buf);
}
@Override public Object asTridentForm() {
return this.packet;
}
}