Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-08 17:20:24 +01:00
Intitial APIv2, this does not work. Type conversion is not implemented, as well as quite a few things, most things will probably change.
Dieser Commit ist enthalten in:
Ursprung
131517105e
Commit
7cff20f218
@ -60,6 +60,7 @@ public enum PacketType {
|
||||
PLAY_SPAWN_MOB(State.PLAY, Direction.OUTGOING, 0x0F, 0x03),
|
||||
PLAY_SPAWN_PAINTING(State.PLAY, Direction.OUTGOING, 0x10, 0x04),
|
||||
PLAY_SPAWN_PLAYER(State.PLAY, Direction.OUTGOING, 0x0C, 0x05),
|
||||
|
||||
PLAY_ANIMATION(State.PLAY, Direction.OUTGOING, 0x0B, 0x06),
|
||||
PLAY_STATS(State.PLAY, Direction.OUTGOING, 0x37, 0x07),
|
||||
PLAY_BLOCK_BREAK_ANIMATION(State.PLAY, Direction.OUTGOING, 0x25, 0x08),
|
||||
|
57
src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java
Normale Datei
57
src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java
Normale Datei
@ -0,0 +1,57 @@
|
||||
package us.myles.ViaVersion2.api;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.data.UserConnection;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
import us.myles.ViaVersion2.api.util.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketWrapper {
|
||||
private final ByteBuf inputBuffer;
|
||||
private final UserConnection userConnection;
|
||||
private List<Pair<Type, Object>> packetValues = new ArrayList<>();
|
||||
|
||||
public PacketWrapper(ByteBuf inputBuffer, UserConnection userConnection) {
|
||||
this.inputBuffer = inputBuffer;
|
||||
this.userConnection = userConnection;
|
||||
}
|
||||
|
||||
public <T> T get(Type<T> type, int index) {
|
||||
int currentIndex = 0;
|
||||
for (Pair<Type, Object> packetValue : packetValues) {
|
||||
if (packetValue.getKey() == type) { // Ref check
|
||||
if (currentIndex == index) {
|
||||
return (T) packetValue.getValue();
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index);
|
||||
}
|
||||
|
||||
public <T> T read(Type<T> type) {
|
||||
// We could in the future log input read values, but honestly for things like bulk maps, mem waste D:
|
||||
return type.read(inputBuffer);
|
||||
}
|
||||
|
||||
|
||||
public <T> void write(Type<T> type, T value) {
|
||||
packetValues.add(new Pair<Type, Object>(type, value));
|
||||
}
|
||||
|
||||
public void writeToBuffer(ByteBuf buffer) {
|
||||
for (Pair<Type, Object> packetValue : packetValues) {
|
||||
packetValue.getKey().write(buffer, packetValue.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void writeRemaining(ByteBuf output) {
|
||||
output.writeBytes(inputBuffer);
|
||||
}
|
||||
|
||||
public UserConnection user() {
|
||||
return this.userConnection;
|
||||
}
|
||||
}
|
4
src/main/java/us/myles/ViaVersion2/api/data/StoredObject.java
Normale Datei
4
src/main/java/us/myles/ViaVersion2/api/data/StoredObject.java
Normale Datei
@ -0,0 +1,4 @@
|
||||
package us.myles.ViaVersion2.api.data;
|
||||
|
||||
public class StoredObject {
|
||||
}
|
28
src/main/java/us/myles/ViaVersion2/api/data/UserConnection.java
Normale Datei
28
src/main/java/us/myles/ViaVersion2/api/data/UserConnection.java
Normale Datei
@ -0,0 +1,28 @@
|
||||
package us.myles.ViaVersion2.api.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class UserConnection {
|
||||
List<StoredObject> storedObjects = new ArrayList<>();
|
||||
|
||||
public <T extends StoredObject> T object(Class<T> objectClass) {
|
||||
for (StoredObject o : storedObjects) {
|
||||
if (o.getClass().equals(objectClass))
|
||||
return (T) o;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T extends StoredObject> boolean has(Class<T> objectClass) {
|
||||
for (StoredObject o : storedObjects) {
|
||||
if (o.getClass().equals(objectClass))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void add(StoredObject object) {
|
||||
storedObjects.add(object);
|
||||
}
|
||||
}
|
78
src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java
Normale Datei
78
src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java
Normale Datei
@ -0,0 +1,78 @@
|
||||
package us.myles.ViaVersion2.api.protocol;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
import us.myles.ViaVersion2.api.util.Pair;
|
||||
import us.myles.ViaVersion2.api.data.UserConnection;
|
||||
import us.myles.ViaVersion2.api.remapper.PacketRemapper;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class Protocol {
|
||||
public abstract void registerPackets();
|
||||
|
||||
public abstract void init(UserConnection userConnection);
|
||||
|
||||
public Map<Pair<State, Integer>, ProtocolPacket> incoming = new HashMap<>();
|
||||
public Map<Pair<State, Integer>, ProtocolPacket> outgoing = new HashMap<>();
|
||||
|
||||
public void registerIncoming(State state, int oldPacketID, int newPacketID) {
|
||||
registerIncoming(state, oldPacketID, newPacketID, null);
|
||||
}
|
||||
|
||||
public void registerIncoming(State state, int oldPacketID, int newPacketID, PacketRemapper packetRemapper) {
|
||||
ProtocolPacket protocolPacket = new ProtocolPacket(state, oldPacketID, newPacketID, packetRemapper);
|
||||
incoming.put(new Pair<>(state, newPacketID), protocolPacket);
|
||||
}
|
||||
|
||||
public void registerOutgoing(State state, int oldPacketID, int newPacketID) {
|
||||
registerOutgoing(state, oldPacketID, newPacketID, null);
|
||||
}
|
||||
|
||||
public void registerOutgoing(State state, int oldPacketID, int newPacketID, PacketRemapper packetRemapper) {
|
||||
ProtocolPacket protocolPacket = new ProtocolPacket(state, oldPacketID, newPacketID, packetRemapper);
|
||||
outgoing.put(new Pair<>(state, oldPacketID), protocolPacket);
|
||||
}
|
||||
|
||||
public void transform(Direction direction, State state, int packetID, PacketWrapper packetWrapper, ByteBuf output) {
|
||||
Pair<State, Integer> statePacket = new Pair<>(state, packetID);
|
||||
Map<Pair<State, Integer>, ProtocolPacket> packetMap = (direction == Direction.OUTGOING ? outgoing : incoming);
|
||||
ProtocolPacket protocolPacket;
|
||||
if (packetMap.containsKey(statePacket)) {
|
||||
protocolPacket = packetMap.get(statePacket);
|
||||
} else {
|
||||
System.out.println("Packet not found: " + packetID);
|
||||
// simply translate
|
||||
Type.VAR_INT.write(output, packetID);
|
||||
// pass through
|
||||
packetWrapper.writeRemaining(output);
|
||||
return;
|
||||
}
|
||||
// write packet id
|
||||
Type.VAR_INT.write(output, direction == Direction.OUTGOING ? protocolPacket.getNewID() : protocolPacket.getOldID());
|
||||
// remap
|
||||
if (protocolPacket.getRemapper() != null) {
|
||||
protocolPacket.getRemapper().remap(packetWrapper);
|
||||
// write to output
|
||||
packetWrapper.writeToBuffer(output);
|
||||
} else {
|
||||
// pass through
|
||||
packetWrapper.writeRemaining(output);
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
class ProtocolPacket {
|
||||
State state;
|
||||
int oldID;
|
||||
int newID;
|
||||
PacketRemapper remapper;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.protocol1_9to1_8;
|
||||
|
||||
import us.myles.ViaVersion2.api.data.UserConnection;
|
||||
import us.myles.ViaVersion2.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.packets.SpawnPackets;
|
||||
import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.EntityTracker;
|
||||
|
||||
public class Protocol1_9TO1_8 extends Protocol {
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
// Example PLAY_SPAWN_OBJECT(State.PLAY, Direction.OUTGOING, 0x0E, 0x00),
|
||||
SpawnPackets.register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(UserConnection userConnection) {
|
||||
// Entity tracker
|
||||
userConnection.add(new EntityTracker());
|
||||
}
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
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.storage.EntityTracker;
|
||||
import us.myles.ViaVersion2.api.remapper.PacketRemapper;
|
||||
import us.myles.ViaVersion2.api.remapper.ValueCreator;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class SpawnPackets {
|
||||
public static void register(Protocol protocol) {
|
||||
// Spawn Object Packet
|
||||
protocol.registerOutgoing(State.PLAY, 0x0E, 0x00, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.VAR_INT); // 0 - Entity ID
|
||||
// 1 - UUID
|
||||
create(new ValueCreator() {
|
||||
@Override
|
||||
public void write(PacketWrapper wrapper) {
|
||||
int entityID = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityTracker tracker = wrapper.user().object(EntityTracker.class);
|
||||
wrapper.write(Type.UUID, tracker.getEntityUUID(entityID));
|
||||
}
|
||||
});
|
||||
map(Type.BYTE); // 2 - Type
|
||||
|
||||
map(Type.INT, Type.DOUBLE); // 3 - X - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 4 - Y - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 5 - Z - Needs to be divide by 32
|
||||
|
||||
map(Type.BYTE); // 6 - Pitch
|
||||
map(Type.BYTE); // 7 - Yaw
|
||||
|
||||
map(Type.INT); // 8 - Data
|
||||
|
||||
// Create last 3 shorts
|
||||
create(new ValueCreator() {
|
||||
@Override
|
||||
public void write(PacketWrapper wrapper) {
|
||||
int data = wrapper.get(Type.INT, 3); // Data (4th Integer)
|
||||
|
||||
short vX = 0, vY = 0, vZ = 0;
|
||||
if (data > 0) {
|
||||
vX = wrapper.read(Type.SHORT);
|
||||
vY = wrapper.read(Type.SHORT);
|
||||
vZ = wrapper.read(Type.SHORT);
|
||||
}
|
||||
|
||||
wrapper.write(Type.SHORT, vX);
|
||||
wrapper.write(Type.SHORT, vY);
|
||||
wrapper.write(Type.SHORT, vZ);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// Spawn XP Packet
|
||||
protocol.registerOutgoing(State.PLAY, 0x11, 0x01, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.VAR_INT); // 0 - Entity ID
|
||||
|
||||
map(Type.INT, Type.DOUBLE); // 1 - X - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 2 - Y - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 3 - Z - Needs to be divide by 32
|
||||
|
||||
map(Type.INT); // 4 - Data
|
||||
}
|
||||
});
|
||||
|
||||
// Spawn Global Entity Packet
|
||||
protocol.registerOutgoing(State.PLAY, 0x2C, 0x02, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.VAR_INT); // 0 - Entity ID
|
||||
map(Type.BYTE); // 1 - Type
|
||||
|
||||
map(Type.INT, Type.DOUBLE); // 2 - X - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 3 - Y - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 4 - Z - Needs to be divide by 32
|
||||
}
|
||||
});
|
||||
|
||||
// Spawn Mob Packet
|
||||
protocol.registerOutgoing(State.PLAY, 0x0F, 0x03, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.VAR_INT); // 0 - Entity ID
|
||||
// 1 - UUID
|
||||
create(new ValueCreator() {
|
||||
@Override
|
||||
public void write(PacketWrapper wrapper) {
|
||||
int entityID = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityTracker tracker = wrapper.user().object(EntityTracker.class);
|
||||
wrapper.write(Type.UUID, tracker.getEntityUUID(entityID));
|
||||
}
|
||||
});
|
||||
map(Type.UNSIGNED_BYTE); // 2 - Type
|
||||
|
||||
map(Type.INT, Type.DOUBLE); // 3 - X - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 4 - Y - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 5 - Z - Needs to be divide by 32
|
||||
|
||||
map(Type.BYTE); // 6 - Yaw
|
||||
map(Type.BYTE); // 7 - Pitch
|
||||
map(Type.BYTE); // 8 - Head Pitch
|
||||
|
||||
map(Type.SHORT); // 9 - Velocity X
|
||||
map(Type.SHORT); // 10 - Velocity Y
|
||||
map(Type.SHORT); // 11 - Velocity Z
|
||||
|
||||
// TODO Read Metadata
|
||||
}
|
||||
});
|
||||
|
||||
// Spawn Painting Packet
|
||||
protocol.registerOutgoing(State.PLAY, 0x10, 0x04, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.VAR_INT); // 0 - Entity ID
|
||||
// 1 - UUID
|
||||
create(new ValueCreator() {
|
||||
@Override
|
||||
public void write(PacketWrapper wrapper) {
|
||||
int entityID = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityTracker tracker = wrapper.user().object(EntityTracker.class);
|
||||
wrapper.write(Type.UUID, tracker.getEntityUUID(entityID));
|
||||
}
|
||||
});
|
||||
map(Type.STRING); // 2 - Title
|
||||
|
||||
map(Type.POSITION); // 3 - Position
|
||||
|
||||
map(Type.BYTE); // 4 - Direction
|
||||
}
|
||||
});
|
||||
|
||||
// Spawn Player Packet
|
||||
protocol.registerOutgoing(State.PLAY, 0x0C, 0x05, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.VAR_INT); // 0 - Entity ID
|
||||
map(Type.UUID); // 1 - Player UUID
|
||||
|
||||
map(Type.INT, Type.DOUBLE); // 2 - X - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 3 - Y - Needs to be divide by 32
|
||||
map(Type.INT, Type.DOUBLE); // 4 - Z - Needs to be divide by 32
|
||||
|
||||
map(Type.BYTE); // 5 - Yaw
|
||||
map(Type.BYTE); // 6 - Pitch
|
||||
|
||||
map(Type.SHORT, Type.NOTHING); // Current Item is discontinued
|
||||
|
||||
// TODO Read Metadata
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package us.myles.ViaVersion2.api.protocol1_9to1_8.storage;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import us.myles.ViaVersion2.api.data.StoredObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
public class EntityTracker extends StoredObject{
|
||||
private final Map<Integer, UUID> uuidMap = new HashMap<>();
|
||||
private final Map<Integer, EntityType> clientEntityTypes = new HashMap<>();
|
||||
private final Map<Integer, Integer> vehicleMap = new HashMap<>();
|
||||
|
||||
public UUID getEntityUUID(int id) {
|
||||
if (uuidMap.containsKey(id)) {
|
||||
return uuidMap.get(id);
|
||||
} else {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
uuidMap.put(id, uuid);
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
}
|
46
src/main/java/us/myles/ViaVersion2/api/remapper/PacketRemapper.java
Normale Datei
46
src/main/java/us/myles/ViaVersion2/api/remapper/PacketRemapper.java
Normale Datei
@ -0,0 +1,46 @@
|
||||
package us.myles.ViaVersion2.api.remapper;
|
||||
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
import us.myles.ViaVersion2.api.util.Pair;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class PacketRemapper {
|
||||
private List<Pair<ValueReader, ValueTransformer>> valueRemappers = new ArrayList<>();
|
||||
|
||||
public PacketRemapper() {
|
||||
registerMap();
|
||||
}
|
||||
|
||||
public void map(Type type) {
|
||||
TypeRemapper remapper = new TypeRemapper(type);
|
||||
map(remapper, remapper);
|
||||
}
|
||||
|
||||
public void map(Type oldType, Type newType) {
|
||||
map(new TypeRemapper(oldType), new TypeRemapper(newType));
|
||||
}
|
||||
|
||||
public <T> void map(ValueReader<T> inputRemapper, ValueTransformer<T> outputRemapper) {
|
||||
valueRemappers.add(new Pair<ValueReader, ValueTransformer>(inputRemapper, outputRemapper));
|
||||
}
|
||||
|
||||
public void create(ValueCreator transformer) {
|
||||
map(new TypeRemapper(Type.NOTHING), transformer);
|
||||
}
|
||||
|
||||
public abstract void registerMap();
|
||||
|
||||
public void remap(PacketWrapper packetWrapper) {
|
||||
// Read all the current values
|
||||
for(Pair<ValueReader, ValueTransformer> valueRemapper : valueRemappers){
|
||||
Object object = valueRemapper.getKey().read(packetWrapper);
|
||||
// Convert object to write type :O!!!
|
||||
// TODO: Data converter lol
|
||||
valueRemapper.getValue().write(packetWrapper, object);
|
||||
}
|
||||
// If we had handlers we'd put them here
|
||||
}
|
||||
}
|
22
src/main/java/us/myles/ViaVersion2/api/remapper/TypeRemapper.java
Normale Datei
22
src/main/java/us/myles/ViaVersion2/api/remapper/TypeRemapper.java
Normale Datei
@ -0,0 +1,22 @@
|
||||
package us.myles.ViaVersion2.api.remapper;
|
||||
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class TypeRemapper<T> implements ValueReader<T>, ValueTransformer<T> {
|
||||
private final Type<T> type;
|
||||
|
||||
public TypeRemapper(Type<T> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(PacketWrapper wrapper) {
|
||||
return wrapper.read(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper output, T inputValue) {
|
||||
output.write(type, inputValue);
|
||||
}
|
||||
}
|
12
src/main/java/us/myles/ViaVersion2/api/remapper/ValueCreator.java
Normale Datei
12
src/main/java/us/myles/ViaVersion2/api/remapper/ValueCreator.java
Normale Datei
@ -0,0 +1,12 @@
|
||||
package us.myles.ViaVersion2.api.remapper;
|
||||
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
|
||||
public abstract class ValueCreator implements ValueTransformer{
|
||||
public abstract void write(PacketWrapper wrapper);
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper writer, Object inputValue) {
|
||||
write(writer);
|
||||
}
|
||||
}
|
8
src/main/java/us/myles/ViaVersion2/api/remapper/ValueReader.java
Normale Datei
8
src/main/java/us/myles/ViaVersion2/api/remapper/ValueReader.java
Normale Datei
@ -0,0 +1,8 @@
|
||||
package us.myles.ViaVersion2.api.remapper;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
|
||||
public interface ValueReader<T> {
|
||||
public T read(PacketWrapper wrapper);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package us.myles.ViaVersion2.api.remapper;
|
||||
|
||||
import us.myles.ViaVersion2.api.PacketWrapper;
|
||||
|
||||
public interface ValueTransformer<T> {
|
||||
public void write(PacketWrapper writer, T inputValue);
|
||||
}
|
7
src/main/java/us/myles/ViaVersion2/api/type/ByteBufReader.java
Normale Datei
7
src/main/java/us/myles/ViaVersion2/api/type/ByteBufReader.java
Normale Datei
@ -0,0 +1,7 @@
|
||||
package us.myles.ViaVersion2.api.type;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public interface ByteBufReader<T> {
|
||||
public T read(ByteBuf buffer);
|
||||
}
|
7
src/main/java/us/myles/ViaVersion2/api/type/ByteBufWriter.java
Normale Datei
7
src/main/java/us/myles/ViaVersion2/api/type/ByteBufWriter.java
Normale Datei
@ -0,0 +1,7 @@
|
||||
package us.myles.ViaVersion2.api.type;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public interface ByteBufWriter<T> {
|
||||
public void write(ByteBuf buffer, T object);
|
||||
}
|
63
src/main/java/us/myles/ViaVersion2/api/type/Type.java
Normale Datei
63
src/main/java/us/myles/ViaVersion2/api/type/Type.java
Normale Datei
@ -0,0 +1,63 @@
|
||||
package us.myles.ViaVersion2.api.type;
|
||||
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion2.api.type.types.*;
|
||||
import us.myles.ViaVersion2.api.util.Position;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
|
||||
/* Defined Types */
|
||||
public static final Type<Byte> BYTE = new ByteType();
|
||||
public static final Type<Byte[]> BYTE_ARRAY = new ArrayType<>(Type.BYTE);
|
||||
|
||||
public static final Type<Short> UNSIGNED_BYTE = new UnsignedByteType();
|
||||
public static final Type<Short[]> UNSIGNED_BYTE_ARRAY = new ArrayType<>(Type.UNSIGNED_BYTE);
|
||||
|
||||
public static final Type<Boolean> BOOLEAN = new BooleanType();
|
||||
public static final Type<Boolean[]> BOOLEAN_ARRAY = new ArrayType<>(Type.BOOLEAN);
|
||||
/* Number Types */
|
||||
public static final Type<Integer> INT = new IntType();
|
||||
public static final Type<Integer[]> INT_ARRAY = new ArrayType<>(Type.INT);
|
||||
|
||||
public static final Type<Double> DOUBLE = new DoubleType();
|
||||
public static final Type<Double[]> DOUBLE_ARRAY = new ArrayType<>(Type.DOUBLE);
|
||||
|
||||
public static final Type<Long> LONG = new LongType();
|
||||
public static final Type<Long[]> LONG_ARRAY = new ArrayType<>(Type.LONG);
|
||||
|
||||
public static final Type<Float> FLOAT = new FloatType();
|
||||
public static final Type<Float[]> FLOAT_ARRAY = new ArrayType<>(Type.FLOAT);
|
||||
|
||||
public static final Type<Short> SHORT = new ShortType();
|
||||
public static final Type<Short[]> SHORT_ARRAY = new ArrayType<>(Type.SHORT);
|
||||
/* Other Types */
|
||||
public static final Type<String> STRING = new StringType();
|
||||
public static final Type<String[]> STRING_ARRAY = new ArrayType<>(Type.STRING);
|
||||
|
||||
public static final Type<UUID> UUID = new UUIDType();
|
||||
public static final Type<UUID[]> UUID_ARRAY = new ArrayType<>(Type.UUID);
|
||||
/* Variable Types */
|
||||
public static final Type<Integer> VAR_INT = new VarIntType();
|
||||
public static final Type<Integer[]> VAR_INT_ARRAY = new ArrayType<>(Type.VAR_INT);
|
||||
/* Special Types */
|
||||
public static final Type<Void> NOTHING = new VoidType(); // This is purely used for remapping.
|
||||
/* MC Types */
|
||||
public static final Type<Position> POSITION = new PositionType(); // This is purely used for remapping.
|
||||
/* Actual Class */
|
||||
|
||||
private final Class<T> outputClass;
|
||||
private final String typeName;
|
||||
|
||||
public Type(Class<T> outputClass) {
|
||||
this(outputClass.getSimpleName(), outputClass);
|
||||
}
|
||||
|
||||
public Type(String typeName, Class<T> outputClass) {
|
||||
this.outputClass = outputClass;
|
||||
this.typeName = typeName;
|
||||
}
|
||||
}
|
65
src/main/java/us/myles/ViaVersion2/api/type/types/ArrayType.java
Normale Datei
65
src/main/java/us/myles/ViaVersion2/api/type/types/ArrayType.java
Normale Datei
@ -0,0 +1,65 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class ArrayType<T> extends Type<T[]> {
|
||||
private final Type<T> elementType;
|
||||
|
||||
public ArrayType(Type<T> type) {
|
||||
super(type.getTypeName() + " Array", (Class<T[]>) getArrayClass(type.getOutputClass()));
|
||||
this.elementType = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T[] read(ByteBuf buffer) {
|
||||
int amount = Type.VAR_INT.read(buffer);
|
||||
Object[] array = new Object[amount];
|
||||
for (int i = 0; i < amount; i++) {
|
||||
array[i] = elementType.read(buffer);
|
||||
}
|
||||
return (T[]) array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, T[] object) {
|
||||
Type.VAR_INT.write(buffer, object.length);
|
||||
for (T o : object) {
|
||||
elementType.write(buffer, o);
|
||||
}
|
||||
}
|
||||
|
||||
/* Taken from http://stackoverflow.com/questions/4901128/obtaining-the-array-class-of-a-component-type */
|
||||
public static Class<?> getArrayClass(Class<?> componentType) {
|
||||
ClassLoader classLoader = componentType.getClassLoader();
|
||||
String name;
|
||||
if (componentType.isArray()) {
|
||||
// just add a leading "["
|
||||
name = "[" + componentType.getName();
|
||||
} else if (componentType == boolean.class) {
|
||||
name = "[Z";
|
||||
} else if (componentType == byte.class) {
|
||||
name = "[B";
|
||||
} else if (componentType == char.class) {
|
||||
name = "[C";
|
||||
} else if (componentType == double.class) {
|
||||
name = "[D";
|
||||
} else if (componentType == float.class) {
|
||||
name = "[F";
|
||||
} else if (componentType == int.class) {
|
||||
name = "[I";
|
||||
} else if (componentType == long.class) {
|
||||
name = "[J";
|
||||
} else if (componentType == short.class) {
|
||||
name = "[S";
|
||||
} else {
|
||||
// must be an object non-array class
|
||||
name = "[L" + componentType.getName() + ";";
|
||||
}
|
||||
try {
|
||||
return classLoader != null ? classLoader.loadClass(name) : Class.forName(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null; // oh
|
||||
}
|
||||
}
|
||||
}
|
20
src/main/java/us/myles/ViaVersion2/api/type/types/BooleanType.java
Normale Datei
20
src/main/java/us/myles/ViaVersion2/api/type/types/BooleanType.java
Normale Datei
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class BooleanType extends Type<Boolean> {
|
||||
public BooleanType() {
|
||||
super(Boolean.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean read(ByteBuf buffer) {
|
||||
return buffer.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Boolean object) {
|
||||
buffer.writeBoolean(object);
|
||||
}
|
||||
}
|
20
src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java
Normale Datei
20
src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java
Normale Datei
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class ByteType extends Type<Byte> {
|
||||
public ByteType() {
|
||||
super(Byte.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte read(ByteBuf buffer) {
|
||||
return buffer.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Byte object) {
|
||||
buffer.writeByte(object);
|
||||
}
|
||||
}
|
20
src/main/java/us/myles/ViaVersion2/api/type/types/DoubleType.java
Normale Datei
20
src/main/java/us/myles/ViaVersion2/api/type/types/DoubleType.java
Normale Datei
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class DoubleType extends Type<Double> {
|
||||
public DoubleType() {
|
||||
super(Double.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double read(ByteBuf buffer) {
|
||||
return buffer.readDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Double object) {
|
||||
buffer.writeDouble(object);
|
||||
}
|
||||
}
|
20
src/main/java/us/myles/ViaVersion2/api/type/types/FloatType.java
Normale Datei
20
src/main/java/us/myles/ViaVersion2/api/type/types/FloatType.java
Normale Datei
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class FloatType extends Type<Float> {
|
||||
public FloatType() {
|
||||
super(Float.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float read(ByteBuf buffer) {
|
||||
return buffer.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Float object) {
|
||||
buffer.writeFloat(object);
|
||||
}
|
||||
}
|
20
src/main/java/us/myles/ViaVersion2/api/type/types/IntType.java
Normale Datei
20
src/main/java/us/myles/ViaVersion2/api/type/types/IntType.java
Normale Datei
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class IntType extends Type<Integer> {
|
||||
public IntType() {
|
||||
super(Integer.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer read(ByteBuf buffer) {
|
||||
return buffer.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Integer object) {
|
||||
buffer.writeInt(object);
|
||||
}
|
||||
}
|
20
src/main/java/us/myles/ViaVersion2/api/type/types/LongType.java
Normale Datei
20
src/main/java/us/myles/ViaVersion2/api/type/types/LongType.java
Normale Datei
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class LongType extends Type<Long> {
|
||||
public LongType() {
|
||||
super(Long.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long read(ByteBuf buffer) {
|
||||
return buffer.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Long object) {
|
||||
buffer.writeLong(object);
|
||||
}
|
||||
}
|
27
src/main/java/us/myles/ViaVersion2/api/type/types/PositionType.java
Normale Datei
27
src/main/java/us/myles/ViaVersion2/api/type/types/PositionType.java
Normale Datei
@ -0,0 +1,27 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
import us.myles.ViaVersion2.api.util.Position;
|
||||
|
||||
public class PositionType extends Type<Position> {
|
||||
public PositionType() {
|
||||
super(Position.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position read(ByteBuf buffer) {
|
||||
long val = buffer.readLong();
|
||||
long x = (val >> 38); // signed
|
||||
long y = (val >> 26) & 0xfff; // unsigned
|
||||
// this shifting madness is used to preserve sign
|
||||
long z = (val << 38) >> 38; // signed
|
||||
|
||||
return new Position(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Position object) {
|
||||
buffer.writeLong(((object.getX() & 0x3ffffff) << 38) | ((object.getY() & 0xfff) << 26) | (object.getZ() & 0x3ffffff));
|
||||
}
|
||||
}
|
20
src/main/java/us/myles/ViaVersion2/api/type/types/ShortType.java
Normale Datei
20
src/main/java/us/myles/ViaVersion2/api/type/types/ShortType.java
Normale Datei
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class ShortType extends Type<Short> {
|
||||
public ShortType() {
|
||||
super(Short.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short read(ByteBuf buffer) {
|
||||
return buffer.readShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Short object) {
|
||||
buffer.writeShort(object);
|
||||
}
|
||||
}
|
32
src/main/java/us/myles/ViaVersion2/api/type/types/StringType.java
Normale Datei
32
src/main/java/us/myles/ViaVersion2/api/type/types/StringType.java
Normale Datei
@ -0,0 +1,32 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class StringType extends Type<String> {
|
||||
public StringType() {
|
||||
super(String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String read(ByteBuf buffer) {
|
||||
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);
|
||||
|
||||
byte[] b = new byte[len];
|
||||
buffer.readBytes(b);
|
||||
|
||||
return new String(b, Charsets.UTF_8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, String object) {
|
||||
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);
|
||||
Type.VAR_INT.write(buffer, b.length);
|
||||
buffer.writeBytes(b);
|
||||
}
|
||||
}
|
23
src/main/java/us/myles/ViaVersion2/api/type/types/UUIDType.java
Normale Datei
23
src/main/java/us/myles/ViaVersion2/api/type/types/UUIDType.java
Normale Datei
@ -0,0 +1,23 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class UUIDType extends Type<UUID> {
|
||||
public UUIDType() {
|
||||
super(UUID.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID read(ByteBuf buffer) {
|
||||
return new UUID(buffer.readLong(), buffer.readLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, UUID object) {
|
||||
buffer.writeLong(object.getMostSignificantBits());
|
||||
buffer.writeLong(object.getLeastSignificantBits());
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class UnsignedByteType extends Type<Short> {
|
||||
public UnsignedByteType() {
|
||||
super(Short.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short read(ByteBuf buffer) {
|
||||
return buffer.readUnsignedByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Short object) {
|
||||
buffer.writeByte(object);
|
||||
}
|
||||
}
|
52
src/main/java/us/myles/ViaVersion2/api/type/types/VarIntType.java
Normale Datei
52
src/main/java/us/myles/ViaVersion2/api/type/types/VarIntType.java
Normale Datei
@ -0,0 +1,52 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class VarIntType extends Type<Integer>{
|
||||
|
||||
public VarIntType() {
|
||||
super("VarInt", Integer.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Integer object) {
|
||||
int part;
|
||||
while (true) {
|
||||
part = object & 0x7F;
|
||||
|
||||
object >>>= 7;
|
||||
if (object != 0) {
|
||||
part |= 0x80;
|
||||
}
|
||||
|
||||
buffer.writeByte(part);
|
||||
|
||||
if (object == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer read(ByteBuf buffer) {
|
||||
int out = 0;
|
||||
int bytes = 0;
|
||||
byte in;
|
||||
while (true) {
|
||||
in = buffer.readByte();
|
||||
|
||||
out |= (in & 0x7F) << (bytes++ * 7);
|
||||
|
||||
if (bytes > 5) { // 5 is maxBytes
|
||||
throw new RuntimeException("VarInt too big");
|
||||
}
|
||||
|
||||
if ((in & 0x80) != 0x80) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
20
src/main/java/us/myles/ViaVersion2/api/type/types/VoidType.java
Normale Datei
20
src/main/java/us/myles/ViaVersion2/api/type/types/VoidType.java
Normale Datei
@ -0,0 +1,20 @@
|
||||
package us.myles.ViaVersion2.api.type.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion2.api.type.Type;
|
||||
|
||||
public class VoidType extends Type<Void> {
|
||||
public VoidType() {
|
||||
super(Void.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void read(ByteBuf buffer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Void object) {
|
||||
|
||||
}
|
||||
}
|
16
src/main/java/us/myles/ViaVersion2/api/util/Pair.java
Normale Datei
16
src/main/java/us/myles/ViaVersion2/api/util/Pair.java
Normale Datei
@ -0,0 +1,16 @@
|
||||
package us.myles.ViaVersion2.api.util;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
public class Pair<X, Y> {
|
||||
private final X key;
|
||||
private final Y value;
|
||||
|
||||
public Pair(X key, Y value){
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
12
src/main/java/us/myles/ViaVersion2/api/util/Position.java
Normale Datei
12
src/main/java/us/myles/ViaVersion2/api/util/Position.java
Normale Datei
@ -0,0 +1,12 @@
|
||||
package us.myles.ViaVersion2.api.util;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public class Position {
|
||||
private Long x;
|
||||
private Long y;
|
||||
private Long z;
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren