Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-27 08:30:09 +01:00
Implement Partial Types (Types which require constructing with info), Implement Items, Implement NBT, add exceptions so they go down the tree!
Dieser Commit ist enthalten in:
Ursprung
55335944e3
Commit
0357d8e6aa
@ -1,10 +1,9 @@
|
||||
package us.myles.ViaVersion.chunks;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public class Chunk {
|
||||
private final int x;
|
||||
@ -21,7 +20,7 @@ public class Chunk {
|
||||
* @param x coord
|
||||
* @param z coord
|
||||
*/
|
||||
protected Chunk(int x, int z) {
|
||||
public Chunk(int x, int z) {
|
||||
this(x, z, true, 0, new ChunkSection[16], null);
|
||||
this.unloadPacket = true;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ public enum PacketType {
|
||||
PLAY_UNLOAD_CHUNK(State.PLAY, Direction.OUTGOING, -1, 0x1D),
|
||||
PLAY_CHANGE_GAME_STATE(State.PLAY, Direction.OUTGOING, 0x2B, 0x1E),
|
||||
PLAY_KEEP_ALIVE(State.PLAY, Direction.OUTGOING, 0x00, 0x1F), // Mapped
|
||||
PLAY_CHUNK_DATA(State.PLAY, Direction.OUTGOING, 0x21, 0x20), // TODO
|
||||
PLAY_CHUNK_DATA(State.PLAY, Direction.OUTGOING, 0x21, 0x20), // Mapped
|
||||
PLAY_EFFECT(State.PLAY, Direction.OUTGOING, 0x28, 0x21), // Mapped
|
||||
PLAY_PARTICLE(State.PLAY, Direction.OUTGOING, 0x2A, 0x22), // Mapped
|
||||
PLAY_JOIN_GAME(State.PLAY, Direction.OUTGOING, 0x01, 0x23), // Mapped
|
||||
|
@ -45,7 +45,7 @@ public class PacketWrapper {
|
||||
throw new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index);
|
||||
}
|
||||
|
||||
public <T> T read(Type<T> type) {
|
||||
public <T> T read(Type<T> type) throws Exception {
|
||||
System.out.println("Reading: " + type.getTypeName());
|
||||
// We could in the future log input read values, but honestly for things like bulk maps, mem waste D:
|
||||
return type.read(inputBuffer);
|
||||
@ -57,13 +57,13 @@ public class PacketWrapper {
|
||||
packetValues.add(new Pair<Type, Object>(type, value));
|
||||
}
|
||||
|
||||
public <T> T passthrough(Type<T> type) {
|
||||
public <T> T passthrough(Type<T> type) throws Exception {
|
||||
T value = read(type);
|
||||
write(type, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public void writeToBuffer(ByteBuf buffer) {
|
||||
public void writeToBuffer(ByteBuf buffer) throws Exception {
|
||||
for (Pair<Type, Object> packetValue : packetValues) {
|
||||
packetValue.getKey().write(buffer, packetValue.getValue());
|
||||
}
|
||||
|
@ -1,4 +1,14 @@
|
||||
package us.myles.ViaVersion2.api.item;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Item {
|
||||
private short id;
|
||||
private byte amount;
|
||||
private short data;
|
||||
private CompoundTag tag;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public abstract class Protocol {
|
||||
outgoing.put(new Pair<>(state, oldPacketID), protocolPacket);
|
||||
}
|
||||
|
||||
public void transform(Direction direction, State state, int packetID, PacketWrapper packetWrapper, ByteBuf output) {
|
||||
public void transform(Direction direction, State state, int packetID, PacketWrapper packetWrapper, ByteBuf output) throws Exception {
|
||||
Pair<State, Integer> statePacket = new Pair<>(state, packetID);
|
||||
Map<Pair<State, Integer>, ProtocolPacket> packetMap = (direction == Direction.OUTGOING ? outgoing : incoming);
|
||||
ProtocolPacket protocolPacket;
|
||||
|
@ -7,6 +7,7 @@ import us.myles.ViaVersion2.api.data.UserConnection;
|
||||
import us.myles.ViaVersion2.api.metadata.Metadata;
|
||||
import us.myles.ViaVersion2.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.packets.*;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.ClientChunks;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.EntityTracker;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.types.MetadataListType;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.types.MetadataType;
|
||||
@ -57,5 +58,7 @@ public class Protocol1_9TO1_8 extends Protocol {
|
||||
public void init(UserConnection userConnection) {
|
||||
// Entity tracker
|
||||
userConnection.put(new EntityTracker());
|
||||
// Chunk tracker
|
||||
userConnection.put(new ClientChunks());
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ public class EntityPackets {
|
||||
map(Type.VAR_INT); // 1 - Action Type
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) {
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
int type = wrapper.get(Type.VAR_INT, 1);
|
||||
if (type == 2) {
|
||||
wrapper.passthrough(Type.FLOAT); // 2 - X
|
||||
|
@ -49,7 +49,7 @@ public class PlayerPackets {
|
||||
// We only handle if the title or subtitle is set then just write through.
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) {
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
int action = wrapper.get(Type.VAR_INT, 0);
|
||||
if (action == 0 || action == 1) {
|
||||
Protocol1_9TO1_8.FIX_JSON.write(wrapper, wrapper.read(Type.STRING));
|
||||
@ -90,7 +90,7 @@ public class PlayerPackets {
|
||||
map(Type.BYTE);
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) {
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
byte mode = wrapper.get(Type.BYTE, 1);
|
||||
if (mode == 0 || mode == 2) {
|
||||
wrapper.passthrough(Type.STRING);
|
||||
@ -152,7 +152,7 @@ public class PlayerPackets {
|
||||
handler(new PacketHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) {
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
int action = wrapper.get(Type.VAR_INT, 0);
|
||||
int count = wrapper.get(Type.VAR_INT, 1);
|
||||
|
||||
|
@ -61,7 +61,7 @@ public class SpawnPackets {
|
||||
// Create last 3 shorts
|
||||
create(new ValueCreator() {
|
||||
@Override
|
||||
public void write(PacketWrapper wrapper) {
|
||||
public void write(PacketWrapper wrapper) throws Exception {
|
||||
int data = wrapper.get(Type.INT, 3); // Data (4th Integer)
|
||||
|
||||
short vX = 0, vY = 0, vZ = 0;
|
||||
|
@ -1,8 +1,12 @@
|
||||
package us.myles.ViaVersion2.api.protocol1_9to1_8.packets;
|
||||
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
import us.myles.ViaVersion2.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.ClientChunks;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.types.ChunkType;
|
||||
import us.myles.ViaVersion2.api.remapper.PacketHandler;
|
||||
import us.myles.ViaVersion2.api.remapper.PacketRemapper;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
@ -43,6 +47,20 @@ public class WorldPackets {
|
||||
}
|
||||
});
|
||||
|
||||
// Chunk Packet
|
||||
protocol.registerOutgoing(State.PLAY, 0x21, 0x20, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception{
|
||||
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
|
||||
wrapper.passthrough(new ChunkType(clientChunks));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/* Packets which do not have any field remapping or handlers */
|
||||
|
||||
protocol.registerOutgoing(State.PLAY, 0x25, 0x08); // Block Break Animation Packet
|
||||
@ -58,8 +76,6 @@ public class WorldPackets {
|
||||
protocol.registerOutgoing(State.PLAY, 0x03, 0x44); // Update Time Packet
|
||||
protocol.registerOutgoing(State.PLAY, 0x44, 0x35); // World Border Packet
|
||||
|
||||
// TODO: Chunk Data, Bulk Chunk :)
|
||||
|
||||
/* Incoming Packets */
|
||||
|
||||
// Sign Update Request Packet
|
||||
|
@ -0,0 +1,13 @@
|
||||
package us.myles.ViaVersion2.api.protocol1_9to1_8.storage;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion2.api.data.StoredObject;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
public class ClientChunks extends StoredObject {
|
||||
private final Set<Long> loadedChunks = Sets.newConcurrentHashSet();
|
||||
private final Set<Long> bulkChunks = Sets.newConcurrentHashSet();
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
package us.myles.ViaVersion2.api.protocol1_9to1_8.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.bukkit.Bukkit;
|
||||
import us.myles.ViaVersion.chunks.Chunk;
|
||||
import us.myles.ViaVersion.chunks.ChunkSection;
|
||||
import us.myles.ViaVersion.util.PacketUtil;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.ClientChunks;
|
||||
import us.myles.ViaVersion2.api.type.PartialType;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.util.BitSet;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ChunkType extends PartialType<Chunk, ClientChunks> {
|
||||
/**
|
||||
* Amount of sections in a chunk.
|
||||
*/
|
||||
private static final int SECTION_COUNT = 16;
|
||||
/**
|
||||
* size of each chunk section (16x16x16).
|
||||
*/
|
||||
private static final int SECTION_SIZE = 16;
|
||||
/**
|
||||
* Length of biome data.
|
||||
*/
|
||||
private static final int BIOME_DATA_LENGTH = 256;
|
||||
|
||||
public ChunkType(ClientChunks chunks) {
|
||||
super(chunks, Chunk.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk read(ByteBuf input, ClientChunks param) {
|
||||
int chunkX = input.readInt();
|
||||
int chunkZ = input.readInt();
|
||||
long chunkHash = toLong(chunkX, chunkZ);
|
||||
boolean groundUp = input.readByte() != 0;
|
||||
int bitmask = input.readUnsignedShort();
|
||||
int dataLength = PacketUtil.readVarInt(input);
|
||||
|
||||
// Data to be read
|
||||
BitSet usedSections = new BitSet(16);
|
||||
ChunkSection[] sections = new ChunkSection[16];
|
||||
byte[] biomeData = null;
|
||||
|
||||
// Calculate section count from bitmask
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((bitmask & (1 << i)) != 0) {
|
||||
usedSections.set(i);
|
||||
}
|
||||
}
|
||||
int sectionCount = usedSections.cardinality(); // the amount of sections set
|
||||
|
||||
// If the chunk is from a chunk bulk, it is never an unload packet
|
||||
// Other wise, if it has no data, it is :)
|
||||
boolean isBulkPacket = param.getBulkChunks().remove(chunkHash);
|
||||
if (sectionCount == 0 && groundUp && !isBulkPacket && param.getLoadedChunks().contains(chunkHash)) {
|
||||
// This is a chunk unload packet
|
||||
param.getLoadedChunks().remove(chunkHash);
|
||||
return new Chunk(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
int startIndex = input.readerIndex();
|
||||
param.getLoadedChunks().add(chunkHash); // mark chunk as loaded
|
||||
|
||||
// Read blocks
|
||||
for (int i = 0; i < SECTION_COUNT; i++) {
|
||||
if (!usedSections.get(i)) continue; // Section not set
|
||||
ChunkSection section = new ChunkSection();
|
||||
sections[i] = section;
|
||||
|
||||
// Read block data and convert to short buffer
|
||||
byte[] blockData = new byte[ChunkSection.SIZE * 2];
|
||||
input.readBytes(blockData);
|
||||
ShortBuffer blockBuf = ByteBuffer.wrap(blockData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
|
||||
|
||||
for (int j = 0; j < ChunkSection.SIZE; j++) {
|
||||
int mask = blockBuf.get();
|
||||
int type = mask >> 4;
|
||||
int data = mask & 0xF;
|
||||
section.setBlock(j, type, data);
|
||||
}
|
||||
}
|
||||
|
||||
// Read block light
|
||||
for (int i = 0; i < SECTION_COUNT; i++) {
|
||||
if (!usedSections.get(i)) continue; // Section not set, has no light
|
||||
byte[] blockLightArray = new byte[ChunkSection.LIGHT_LENGTH];
|
||||
input.readBytes(blockLightArray);
|
||||
sections[i].setBlockLight(blockLightArray);
|
||||
}
|
||||
|
||||
// Read sky light
|
||||
int bytesLeft = dataLength - (input.readerIndex() - startIndex);
|
||||
if (bytesLeft >= ChunkSection.LIGHT_LENGTH) {
|
||||
for (int i = 0; i < SECTION_COUNT; i++) {
|
||||
if (!usedSections.get(i)) continue; // Section not set, has no light
|
||||
byte[] skyLightArray = new byte[ChunkSection.LIGHT_LENGTH];
|
||||
input.readBytes(skyLightArray);
|
||||
sections[i].setSkyLight(skyLightArray);
|
||||
bytesLeft -= ChunkSection.LIGHT_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
// Read biome data
|
||||
if (bytesLeft >= BIOME_DATA_LENGTH) {
|
||||
biomeData = new byte[BIOME_DATA_LENGTH];
|
||||
input.readBytes(biomeData);
|
||||
bytesLeft -= BIOME_DATA_LENGTH;
|
||||
}
|
||||
|
||||
// Check remaining bytes
|
||||
if (bytesLeft > 0) {
|
||||
Bukkit.getLogger().log(Level.WARNING, bytesLeft + " Bytes left after reading chunk! (" + groundUp + ")");
|
||||
}
|
||||
|
||||
// Return chunk
|
||||
return new Chunk(chunkX, chunkZ, groundUp, bitmask, sections, biomeData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf output, ClientChunks param, Chunk chunk) {
|
||||
if(chunk.isUnloadPacket()) {
|
||||
output.clear();
|
||||
PacketUtil.writeVarInt(0x1D, output); // Unload packet ID
|
||||
}
|
||||
|
||||
// Write primary info
|
||||
output.writeInt(chunk.getX());
|
||||
output.writeInt(chunk.getZ());
|
||||
if(chunk.isUnloadPacket()) return;
|
||||
output.writeByte(chunk.isGroundUp() ? 0x01 : 0x00);
|
||||
PacketUtil.writeVarInt(chunk.getPrimaryBitmask(), output);
|
||||
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
for(int i = 0; i < SECTION_COUNT; i++) {
|
||||
ChunkSection section = chunk.getSections()[i];
|
||||
if(section == null) continue; // Section not set
|
||||
section.writeBlocks(buf);
|
||||
section.writeBlockLight(buf);
|
||||
if(!section.hasSkyLight()) continue; // No sky light, we're done here.
|
||||
section.writeSkyLight(buf);
|
||||
}
|
||||
buf.readerIndex(0);
|
||||
PacketUtil.writeVarInt(buf.readableBytes() + (chunk.hasBiomeData() ? 256 : 0), output);
|
||||
output.writeBytes(buf);
|
||||
buf.release(); // release buffer
|
||||
|
||||
// Write biome data
|
||||
if(chunk.hasBiomeData()) {
|
||||
output.writeBytes(chunk.getBiomeData());
|
||||
}
|
||||
}
|
||||
|
||||
private static long toLong(int msw, int lsw) {
|
||||
return ((long) msw << 32) + lsw - -2147483648L;
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ public class MetadataListType extends Type<List<Metadata>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Metadata> read(ByteBuf buffer) {
|
||||
public List<Metadata> read(ByteBuf buffer) throws Exception {
|
||||
List<Metadata> list = new ArrayList<>();
|
||||
Metadata m;
|
||||
do {
|
||||
@ -28,7 +28,7 @@ public class MetadataListType extends Type<List<Metadata>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, List<Metadata> object) {
|
||||
public void write(ByteBuf buffer, List<Metadata> object) throws Exception {
|
||||
for (Metadata m : object) {
|
||||
Protocol1_9TO1_8.METADATA.write(buffer, m);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ public class MetadataType extends Type<Metadata> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metadata read(ByteBuf buffer) {
|
||||
public Metadata read(ByteBuf buffer) throws Exception {
|
||||
byte item = buffer.readByte();
|
||||
if (item == 127) return null; // end of metadata
|
||||
MetadataTypes type = MetadataTypes.byId((item & 0xE0) >> 5);
|
||||
@ -22,7 +22,7 @@ public class MetadataType extends Type<Metadata> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Metadata object) {
|
||||
public void write(ByteBuf buffer, Metadata object) throws Exception {
|
||||
if (object == null) {
|
||||
buffer.writeByte(127);
|
||||
} else {
|
||||
|
@ -3,10 +3,10 @@ package us.myles.ViaVersion2.api.remapper;
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
|
||||
public abstract class PacketHandler implements ValueWriter {
|
||||
public abstract void handle(PacketWrapper wrapper);
|
||||
public abstract void handle(PacketWrapper wrapper) throws Exception;
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper writer, Object inputValue) {
|
||||
public void write(PacketWrapper writer, Object inputValue) throws Exception {
|
||||
handle(writer);
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public abstract class PacketRemapper {
|
||||
|
||||
public abstract void registerMap();
|
||||
|
||||
public void remap(PacketWrapper packetWrapper) {
|
||||
public void remap(PacketWrapper packetWrapper) throws Exception{
|
||||
// Read all the current values
|
||||
for (Pair<ValueReader, ValueWriter> valueRemapper : valueRemappers) {
|
||||
Object object = valueRemapper.getKey().read(packetWrapper);
|
||||
|
@ -11,7 +11,7 @@ public class TypeRemapper<T> implements ValueReader<T>, ValueWriter<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(PacketWrapper wrapper) {
|
||||
public T read(PacketWrapper wrapper) throws Exception {
|
||||
return wrapper.read(type);
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,10 @@ package us.myles.ViaVersion2.api.remapper;
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
|
||||
public abstract class ValueCreator implements ValueWriter {
|
||||
public abstract void write(PacketWrapper wrapper);
|
||||
public abstract void write(PacketWrapper wrapper) throws Exception;
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper writer, Object inputValue) {
|
||||
public void write(PacketWrapper writer, Object inputValue) throws Exception {
|
||||
write(writer);
|
||||
}
|
||||
}
|
||||
|
@ -4,5 +4,5 @@ import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
|
||||
public interface ValueReader<T> {
|
||||
public T read(PacketWrapper wrapper);
|
||||
public T read(PacketWrapper wrapper) throws Exception;
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ package us.myles.ViaVersion2.api.remapper;
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
|
||||
public interface ValueWriter<T> {
|
||||
public void write(PacketWrapper writer, T inputValue);
|
||||
public void write(PacketWrapper writer, T inputValue) throws Exception;
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ package us.myles.ViaVersion2.api.type;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public interface ByteBufReader<T> {
|
||||
public T read(ByteBuf buffer);
|
||||
public T read(ByteBuf buffer) throws Exception;
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ package us.myles.ViaVersion2.api.type;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public interface ByteBufWriter<T> {
|
||||
public void write(ByteBuf buffer, T object);
|
||||
public void write(ByteBuf buffer, T object) throws Exception;
|
||||
}
|
||||
|
26
src/main/java/us/myles/ViaVersion2/api/type/PartialType.java
Normale Datei
26
src/main/java/us/myles/ViaVersion2/api/type/PartialType.java
Normale Datei
@ -0,0 +1,26 @@
|
||||
package us.myles.ViaVersion2.api.type;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public abstract class PartialType<T, X> extends Type<T> {
|
||||
private final X param;
|
||||
|
||||
public PartialType(X param, Class<T> type) {
|
||||
super(type);
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
public abstract T read(ByteBuf buffer, X param);
|
||||
|
||||
public abstract void write(ByteBuf buffer, X param, T object);
|
||||
|
||||
@Override
|
||||
public T read(ByteBuf buffer) {
|
||||
return read(buffer, this.param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, T object) {
|
||||
write(buffer, this.param, object);
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ package us.myles.ViaVersion2.api.type;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.util.EulerAngle;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import us.myles.ViaVersion2.api.item.Item;
|
||||
import us.myles.ViaVersion2.api.type.types.*;
|
||||
import us.myles.ViaVersion2.api.type.types.minecraft.*;
|
||||
@ -57,7 +58,9 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
|
||||
public static final Type<Position> POSITION = new PositionType();
|
||||
public static final Type<EulerAngle> ROTATION = new EulerAngleType();
|
||||
public static final Type<Vector> VECTOR = new VectorType();
|
||||
public static final Type<Item> ITEM = new ItemType(); // TODO
|
||||
public static final Type<CompoundTag> NBT = new NBTType();
|
||||
|
||||
public static final Type<Item> ITEM = new ItemType();
|
||||
public static final Type<Item[]> ITEM_ARRAY = new ItemArrayType();
|
||||
/* Actual Class */
|
||||
|
||||
|
@ -12,7 +12,7 @@ public class ArrayType<T> extends Type<T[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T[] read(ByteBuf buffer) {
|
||||
public T[] read(ByteBuf buffer) throws Exception{
|
||||
int amount = Type.VAR_INT.read(buffer);
|
||||
Object[] array = new Object[amount];
|
||||
for (int i = 0; i < amount; i++) {
|
||||
@ -22,7 +22,7 @@ public class ArrayType<T> extends Type<T[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, T[] object) {
|
||||
public void write(ByteBuf buffer, T[] object) throws Exception{
|
||||
Type.VAR_INT.write(buffer, object.length);
|
||||
for (T o : object) {
|
||||
elementType.write(buffer, o);
|
||||
|
@ -11,7 +11,7 @@ public class StringType extends Type<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String read(ByteBuf buffer) {
|
||||
public String read(ByteBuf buffer) throws Exception {
|
||||
int len = Type.VAR_INT.read(buffer);
|
||||
Preconditions.checkArgument(len <= Short.MAX_VALUE, "Cannot receive string longer than Short.MAX_VALUE (got %s characters)", len);
|
||||
|
||||
@ -22,7 +22,7 @@ public class StringType extends Type<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, String object) {
|
||||
public void write(ByteBuf buffer, String object) throws Exception {
|
||||
Preconditions.checkArgument(object.length() <= Short.MAX_VALUE, "Cannot send string longer than Short.MAX_VALUE (got %s characters)", object.length());
|
||||
|
||||
byte[] b = object.getBytes(Charsets.UTF_8);
|
||||
|
@ -11,7 +11,7 @@ public class EulerAngleType extends Type<EulerAngle> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EulerAngle read(ByteBuf buffer) {
|
||||
public EulerAngle read(ByteBuf buffer) throws Exception {
|
||||
float x = Type.FLOAT.read(buffer);
|
||||
float y = Type.FLOAT.read(buffer);
|
||||
float z = Type.FLOAT.read(buffer);
|
||||
@ -20,7 +20,7 @@ public class EulerAngleType extends Type<EulerAngle> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, EulerAngle object) {
|
||||
public void write(ByteBuf buffer, EulerAngle object) throws Exception {
|
||||
Type.FLOAT.write(buffer, (float) object.getX());
|
||||
Type.FLOAT.write(buffer, (float) object.getY());
|
||||
Type.FLOAT.write(buffer, (float) object.getZ());
|
||||
|
@ -11,7 +11,7 @@ public class ItemArrayType extends Type<Item[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item[] read(ByteBuf buffer) {
|
||||
public Item[] read(ByteBuf buffer) throws Exception {
|
||||
int amount = Type.SHORT.read(buffer);
|
||||
Item[] array = new Item[amount];
|
||||
for (int i = 0; i < amount; i++) {
|
||||
@ -21,7 +21,7 @@ public class ItemArrayType extends Type<Item[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Item[] object) {
|
||||
public void write(ByteBuf buffer, Item[] object) throws Exception {
|
||||
Type.VAR_INT.write(buffer, object.length);
|
||||
for (Item o : object) {
|
||||
Type.ITEM.write(buffer, o);
|
||||
|
@ -4,19 +4,35 @@ import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.item.Item;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
// TODO: Implement this class
|
||||
public class ItemType extends Type<Item> {
|
||||
public ItemType() {
|
||||
super(Item.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item read(ByteBuf buffer) {
|
||||
public Item read(ByteBuf buffer) throws Exception {
|
||||
short id = buffer.readShort();
|
||||
if (id < 0) {
|
||||
return null;
|
||||
} else {
|
||||
Item item = new Item();
|
||||
item.setId(id);
|
||||
item.setAmount(buffer.readByte());
|
||||
item.setData(buffer.readShort());
|
||||
item.setTag(Type.NBT.read(buffer));
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Item object) {
|
||||
|
||||
public void write(ByteBuf buffer, Item object) throws Exception {
|
||||
if (object == null) {
|
||||
buffer.writeShort(-1);
|
||||
} else {
|
||||
buffer.writeShort(object.getId());
|
||||
buffer.writeByte(object.getAmount());
|
||||
buffer.writeShort(object.getData());
|
||||
Type.NBT.write(buffer, object.getTag());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
package us.myles.ViaVersion2.api.type.types.minecraft;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import org.spacehq.opennbt.NBTIO;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
public class NBTType extends Type<CompoundTag> {
|
||||
public NBTType() {
|
||||
super(CompoundTag.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag read(ByteBuf buffer) throws Exception {
|
||||
Preconditions.checkArgument(buffer.readableBytes() <= 2097152, "Cannot read NBT (got %s bytes)", buffer.readableBytes());
|
||||
|
||||
int readerIndex = buffer.readerIndex();
|
||||
byte b = buffer.readByte();
|
||||
if (b == 0) {
|
||||
return null;
|
||||
} else {
|
||||
buffer.readerIndex(readerIndex);
|
||||
ByteBufInputStream bytebufStream = new ByteBufInputStream(buffer);
|
||||
DataInputStream dataInputStream = new DataInputStream(bytebufStream);
|
||||
try {
|
||||
return (CompoundTag) NBTIO.readTag(dataInputStream);
|
||||
} finally {
|
||||
dataInputStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, CompoundTag object) throws Exception {
|
||||
if (object == null) {
|
||||
buffer.writeByte(0);
|
||||
} else {
|
||||
ByteBufOutputStream bytebufStream = new ByteBufOutputStream(buffer);
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(bytebufStream);
|
||||
|
||||
NBTIO.writeTag(dataOutputStream, object);
|
||||
|
||||
dataOutputStream.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ public class VectorType extends Type<Vector> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector read(ByteBuf buffer) {
|
||||
public Vector read(ByteBuf buffer) throws Exception {
|
||||
int x = Type.INT.read(buffer);
|
||||
int y = Type.INT.read(buffer);
|
||||
int z = Type.INT.read(buffer);
|
||||
@ -19,7 +19,7 @@ public class VectorType extends Type<Vector> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Vector object) {
|
||||
public void write(ByteBuf buffer, Vector object) throws Exception {
|
||||
Type.INT.write(buffer, object.getBlockX());
|
||||
Type.INT.write(buffer, object.getBlockY());
|
||||
Type.INT.write(buffer, object.getBlockZ());
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren