Fix type conversion not being instant, (causes issue when reading later on)

Introduce packet ID counting (so we can mark something for the next packet etc)
Move USE Item
Add patch to handle placement properly and not break items yay. (Requires a list of special items >.>)
(And lastplaceblock packet index)
This commit is contained in:
Myles 2016-03-24 15:45:16 +00:00
parent 9257298e17
commit 406500b0bd
7 changed files with 110 additions and 44 deletions

View File

@ -115,6 +115,16 @@ public class PacketWrapper {
* @param value The value of the type to write.
*/
public <T> void write(Type<T> type, T value) {
if (value != null) {
if (!type.getOutputClass().isAssignableFrom(value.getClass())) {
// attempt conversion
if (type instanceof TypeConverter) {
value = (T) ((TypeConverter) type).from(value);
} else {
System.out.println("Possible type mismatch: " + value.getClass().getName() + " -> " + type.getOutputClass());
}
}
}
packetValues.add(new Pair<Type, Object>(type, value));
}

View File

@ -19,6 +19,10 @@ public class UserConnection {
@Getter
@Setter
private Object lastPacket;
@Getter
private long sentPackets = 0L;
@Getter
private long receivedPackets = 0L;
public UserConnection(SocketChannel socketChannel) {
@ -82,4 +86,18 @@ public class UserConnection {
public void sendRawPacket(final ByteBuf packet) {
sendRawPacket(packet, false);
}
/**
* Used for incrementing the number of packets sent to the client
*/
public void incrementSent() {
this.sentPackets++;
}
/**
* Used for incrementing the number of packets received from the client
*/
public void incrementReceived() {
this.receivedPackets++;
}
}

View File

@ -30,6 +30,9 @@ public class ViaDecodeHandler extends ByteToMessageDecoder {
// use transformers
if (bytebuf.readableBytes() > 0) {
if (info.isActive()) {
// Increment received
info.incrementReceived();
// Handle ID
int id = Type.VAR_INT.read(bytebuf);
// Transform
ByteBuf newPacket = ctx.alloc().buffer();

View File

@ -41,6 +41,9 @@ public class ViaEncodeHandler extends MessageToByteEncoder {
throw new CancelException();
}
if (info.isActive()) {
// Increment sent
info.incrementSent();
// Handle ID
int id = Type.VAR_INT.read(bytebuf);
// Transform
ByteBuf oldPacket = bytebuf.copy();

View File

@ -373,48 +373,6 @@ public class PlayerPackets {
}
});
// Use Item Packet
protocol.registerIncoming(State.PLAY, -1, 0x1D, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int hand = wrapper.read(Type.VAR_INT);
// Wipe the input buffer
wrapper.clearInputBuffer();
// First set this packet ID to Block placement
wrapper.setId(0x08);
wrapper.write(Type.LONG, -1L);
wrapper.write(Type.BYTE, (byte) 255);
// Write item in hand
Item item = Item.getItem(Protocol1_9TO1_8.getHandItem(wrapper.user()));
// Blocking patch
if (item != null) {
if (Material.getMaterial(item.getId()).name().endsWith("SWORD")) {
if (hand == 0) {
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
if (!tracker.isBlocking()) {
tracker.setBlocking(true);
Item shield = new Item((short) 442, (byte) 1, (short) 0, null);
tracker.setSecondHand(shield);
}
wrapper.cancel();
}
}
}
wrapper.write(Type.ITEM, item);
wrapper.write(Type.BYTE, (byte) 0);
wrapper.write(Type.BYTE, (byte) 0);
wrapper.write(Type.BYTE, (byte) 0);
}
});
}
});
// Packet Plugin Message Incoming
protocol.registerIncoming(State.PLAY, 0x17, 0x09, new PacketRemapper() {
@Override

View File

@ -5,6 +5,7 @@ import org.spacehq.opennbt.tag.builtin.CompoundTag;
import org.spacehq.opennbt.tag.builtin.StringTag;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
@ -216,6 +217,61 @@ public class WorldPackets {
}
});
// Use Item Packet
protocol.registerIncoming(State.PLAY, -1, 0x1D, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
Long last = tracker.getLastPlaceBlock();
if(last != -1){
if((wrapper.user().getReceivedPackets() - last) < 5) {
wrapper.cancel();
}
tracker.setLastPlaceBlock(-1L);
}
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int hand = wrapper.read(Type.VAR_INT);
// Wipe the input buffer
wrapper.clearInputBuffer();
// First set this packet ID to Block placement
wrapper.setId(0x08);
wrapper.write(Type.LONG, -1L);
wrapper.write(Type.BYTE, (byte) 255);
// Write item in hand
Item item = Item.getItem(Protocol1_9TO1_8.getHandItem(wrapper.user()));
// Blocking patch
if (item != null) {
if (Material.getMaterial(item.getId()).name().endsWith("SWORD")) {
if (hand == 0) {
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
if (!tracker.isBlocking()) {
tracker.setBlocking(true);
Item shield = new Item((short) 442, (byte) 1, (short) 0, null);
tracker.setSecondHand(shield);
}
wrapper.cancel();
}
}
}
wrapper.write(Type.ITEM, item);
wrapper.write(Type.BYTE, (byte) 0);
wrapper.write(Type.BYTE, (byte) 0);
wrapper.write(Type.BYTE, (byte) 0);
}
});
}
});
// Block Placement Packet
protocol.registerIncoming(State.PLAY, 0x08, 0x1C, new PacketRemapper() {
@Override
@ -242,9 +298,25 @@ public class WorldPackets {
if (item != null) {
Material m = Material.getMaterial(item.getId());
if (m != null) {
if (!m.isBlock()) {
wrapper.cancel();
// Prevent special items from sending certain info
// Books
boolean special = m == Material.WRITTEN_BOOK;
// Buckets
special = special || m == Material.WATER_BUCKET || m == Material.LAVA_BUCKET || m == Material.BUCKET;
// Food
special = special || m.isEdible();
// Potions
special = special || m == Material.POTION || m == Material.GLASS_BOTTLE;
// Projectiles
special = special || m == Material.BOW;
special = special || m == Material.SNOW_BALL || m == Material.EGG || m == Material.EXP_BOTTLE || m == Material.ENDER_PEARL || m == Material.EYE_OF_ENDER;
// Don't send data if special
if (special) {
wrapper.set(Type.POSITION, 0, new Position(-1L, 255L, -1L));
wrapper.set(Type.BYTE, 0, (byte) -1);
}
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
tracker.setLastPlaceBlock(wrapper.user().getReceivedPackets());
}
}
}

View File

@ -34,6 +34,8 @@ public class EntityTracker extends StoredObject {
@Setter
private boolean autoTeam = false;
@Setter
private Long lastPlaceBlock = -1L;
@Setter
private int entityID;
private boolean teamExists = false;