[WIP] 17w49a Basic block + item support (inventory transactions are broken / some issues with wrong block)

This will be fully implemented over the coming weeks. Please don't report missing features etc.
This commit is contained in:
Myles 2017-12-11 23:39:34 +00:00
parent 54540fb8ef
commit 19eb478067
33 changed files with 10598 additions and 138 deletions

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>1.4.0-17w45b</version>
<version>1.4.0-17w49b</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>1.4.0-17w45b</version>
<version>1.4.0-17w49b</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -37,7 +37,7 @@
<dependency>
<groupId>us.myles</groupId>
<artifactId>viaversion-common</artifactId>
<version>1.4.0-17w45b</version>
<version>1.4.0-17w49b</version>
</dependency>
</dependencies>
</project>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>1.4.0-17w45b</version>
<version>1.4.0-17w49b</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -0,0 +1,12 @@
package us.myles.ViaVersion.api.minecraft;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class BlockChangeRecord {
private short horizontal;
private short y;
private int blockId;
}

View File

@ -2,6 +2,8 @@ package us.myles.ViaVersion.api.minecraft.chunks;
import io.netty.buffer.ByteBuf;
import java.util.List;
public interface ChunkSection {
int getBlock(int x, int y, int z);
@ -16,4 +18,6 @@ public interface ChunkSection {
boolean hasSkyLight();
void writeSkyLight(ByteBuf output) throws Exception;
List<Integer> getPalette();
}

View File

@ -0,0 +1,34 @@
package us.myles.ViaVersion.api.minecraft.metadata.types;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.type.Type;
@RequiredArgsConstructor
@Getter
public enum MetaType1_13 implements MetaType {
Byte(0, Type.BYTE),
VarInt(1, Type.VAR_INT),
Float(2, Type.FLOAT),
String(3, Type.STRING),
Chat(4, Type.STRING),
Slot(5, Type.FLAT_ITEM),
Boolean(6, Type.BOOLEAN),
Vector3F(7, Type.ROTATION),
Position(8, Type.POSITION),
OptPosition(9, Type.OPTIONAL_POSITION),
Direction(10, Type.VAR_INT),
OptUUID(11, Type.OPTIONAL_UUID),
BlockID(12, Type.VAR_INT),
NBTTag(13, Type.NBT),
Discontinued(99, null);
private final int typeID;
private final Type type;
public static MetaType1_13 byId(int id) {
return values()[id];
}
}

View File

@ -62,7 +62,7 @@ public class ProtocolVersion {
register(v1_12 = new ProtocolVersion(335, "1.12"));
register(v1_12_1 = new ProtocolVersion(338, "1.12.1"));
register(v1_12_2 = new ProtocolVersion(340, "1.12.2"));
register(v1_13 = new ProtocolVersion(344, "17w45b"));
register(v1_13 = new ProtocolVersion(350, "17w49b"));
register(unknown = new ProtocolVersion(-1, "UNKNOWN"));
}

View File

@ -3,6 +3,7 @@ package us.myles.ViaVersion.api.type;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import lombok.Getter;
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
import us.myles.ViaVersion.api.minecraft.EulerAngle;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.minecraft.Vector;
@ -66,6 +67,14 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final Type<Item> ITEM = new ItemType();
public static final Type<Item[]> ITEM_ARRAY = new ItemArrayType();
public static final Type<BlockChangeRecord> BLOCK_CHANGE_RECORD = new BlockChangeRecordType();
public static final Type<BlockChangeRecord[]> BLOCK_CHANGE_RECORD_ARRAY = new ArrayType<>(Type.BLOCK_CHANGE_RECORD);
/* 1.13 Flat Item (no data) */
public static final Type<Item> FLAT_ITEM = new FlatItemType();
public static final Type<Item[]> FLAT_ITEM_ARRAY = new FlatItemArrayType();
/* Actual Class */
private final Class<? super T> outputClass;

View File

@ -0,0 +1,19 @@
package us.myles.ViaVersion.api.type.types.minecraft;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.type.Type;
public abstract class BaseItemArrayType extends Type<Item[]> {
public BaseItemArrayType() {
super(Item[].class);
}
public BaseItemArrayType(String typeName) {
super(typeName, Item[].class);
}
@Override
public Class<? extends Type> getBaseClass() {
return BaseItemArrayType.class;
}
}

View File

@ -0,0 +1,20 @@
package us.myles.ViaVersion.api.type.types.minecraft;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.type.Type;
public abstract class BaseItemType extends Type<Item> {
public BaseItemType() {
super(Item.class);
}
public BaseItemType(String typeName) {
super(typeName, Item.class);
}
@Override
public Class<? extends Type> getBaseClass() {
return BaseItemType.class;
}
}

View File

@ -0,0 +1,27 @@
package us.myles.ViaVersion.api.type.types.minecraft;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
import us.myles.ViaVersion.api.type.Type;
public class BlockChangeRecordType extends Type<BlockChangeRecord> {
public BlockChangeRecordType() {
super(BlockChangeRecord.class);
}
@Override
public BlockChangeRecord read(ByteBuf buffer) throws Exception {
short horizontal = Type.UNSIGNED_BYTE.read(buffer);
short y = Type.UNSIGNED_BYTE.read(buffer);
int blockId = Type.VAR_INT.read(buffer);
return new BlockChangeRecord(horizontal, y, blockId);
}
@Override
public void write(ByteBuf buffer, BlockChangeRecord object) throws Exception {
Type.UNSIGNED_BYTE.write(buffer, object.getHorizontal());
Type.UNSIGNED_BYTE.write(buffer, object.getY());
Type.VAR_INT.write(buffer, object.getBlockId());
}
}

View File

@ -0,0 +1,30 @@
package us.myles.ViaVersion.api.type.types.minecraft;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.type.Type;
public class FlatItemArrayType extends BaseItemArrayType {
public FlatItemArrayType() {
super("Flat Item Array");
}
@Override
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++) {
array[i] = Type.FLAT_ITEM.read(buffer);
}
return array;
}
@Override
public void write(ByteBuf buffer, Item[] object) throws Exception {
Type.SHORT.write(buffer, (short) object.length);
for (Item o : object) {
Type.FLAT_ITEM.write(buffer, o);
}
}
}

View File

@ -0,0 +1,36 @@
package us.myles.ViaVersion.api.type.types.minecraft;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.type.Type;
public class FlatItemType extends BaseItemType {
public FlatItemType() {
super("FlatItem");
}
@Override
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.setTag(Type.NBT.read(buffer));
return item;
}
}
@Override
public void write(ByteBuf buffer, Item object) throws Exception {
if (object == null) {
buffer.writeShort(-1);
} else {
buffer.writeShort(object.getId());
buffer.writeByte(object.getAmount());
Type.NBT.write(buffer, object.getTag());
}
}
}

View File

@ -4,10 +4,10 @@ import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.type.Type;
public class ItemArrayType extends Type<Item[]> {
public class ItemArrayType extends BaseItemArrayType {
public ItemArrayType() {
super("Item Array", Item[].class);
super("Item Array");
}
@Override

View File

@ -4,9 +4,9 @@ import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.type.Type;
public class ItemType extends Type<Item> {
public class ItemType extends BaseItemType {
public ItemType() {
super(Item.class);
super("Item");
}
@Override

View File

@ -0,0 +1,29 @@
package us.myles.ViaVersion.api.type.types.version;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13;
import us.myles.ViaVersion.api.type.types.minecraft.MetaTypeTemplate;
public class Metadata1_13Type extends MetaTypeTemplate {
@Override
public Metadata read(ByteBuf buffer) throws Exception {
short index = buffer.readUnsignedByte();
if (index == 0xff) return null; //End of metadata
MetaType1_13 type = MetaType1_13.byId(buffer.readByte());
return new Metadata(index, type, type.getType().read(buffer));
}
@Override
public void write(ByteBuf buffer, Metadata object) throws Exception {
if (object == null) {
buffer.writeByte(255);
} else {
buffer.writeByte(object.getId());
buffer.writeByte(object.getMetaType().getTypeID());
object.getMetaType().getType().write(buffer, object.getValue());
}
}
}

View File

@ -0,0 +1,32 @@
package us.myles.ViaVersion.api.type.types.version;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.type.types.minecraft.MetaListTypeTemplate;
import java.util.ArrayList;
import java.util.List;
public class MetadataList1_13Type extends MetaListTypeTemplate {
@Override
public List<Metadata> read(ByteBuf buffer) throws Exception {
List<Metadata> list = new ArrayList<>();
Metadata meta;
do {
meta = Types1_13.METADATA.read(buffer);
if (meta != null)
list.add(meta);
} while (meta != null);
return list;
}
@Override
public void write(ByteBuf buffer, List<Metadata> object) throws Exception {
for (Metadata m : object)
Types1_13.METADATA.write(buffer, m);
// Write end of list
Types1_13.METADATA.write(buffer, null);
}
}

View File

@ -0,0 +1,18 @@
package us.myles.ViaVersion.api.type.types.version;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.type.Type;
import java.util.List;
public class Types1_13 {
/**
* Metadata list type for 1.13
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_13Type();
/**
* Metadata type for 1.13
*/
public static final Type<Metadata> METADATA = new Metadata1_13Type();
}

View File

@ -22,7 +22,6 @@ public class ChunkSection1_9_3_4 implements ChunkSection {
/**
* Length of the block data array.
*/
@Getter
private final List<Integer> palette = Lists.newArrayList();
private final int[] blocks;
private final NibbleArray blockLight;
@ -112,7 +111,7 @@ public class ChunkSection1_9_3_4 implements ChunkSection {
public void readBlocks(ByteBuf input) throws Exception {
palette.clear();
// Reaad bits per block
// Read bits per block
int bitsPerBlock = input.readUnsignedByte();
long maxEntryValue = (1L << bitsPerBlock) - 1;
@ -294,4 +293,9 @@ public class ChunkSection1_9_3_4 implements ChunkSection {
buf.release();
return bitCount;
}
@Override
public List<Integer> getPalette() {
return palette;
}
}

View File

@ -22,7 +22,6 @@ public class ChunkSection1_9_1_2 implements ChunkSection {
/**
* Length of the block data array.
*/
@Getter
private final List<Integer> palette = Lists.newArrayList();
private final int[] blocks;
private final NibbleArray blockLight;
@ -250,6 +249,11 @@ public class ChunkSection1_9_1_2 implements ChunkSection {
output.writeBytes(skyLight.getHandle());
}
@Override
public List<Integer> getPalette() {
return palette;
}
/**
* Check if sky light is present
*

View File

@ -155,6 +155,11 @@ public class ChunkSection1_9to1_8 implements ChunkSection {
output.writeBytes(skyLight.getHandle());
}
@Override
public List<Integer> getPalette() {
return palette;
}
/**
* Check if sky light is present
*

View File

@ -0,0 +1,64 @@
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import us.myles.ViaVersion.util.GsonUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class MappingData {
public static Map<Integer, Integer> oldToNewBlocks = new HashMap<>();
public static Map<Integer, Integer> oldToNewItems = new HashMap<>();
public static void init() {
JsonObject mapping1_12 = loadData("mapping-1.12.json");
JsonObject mapping1_13 = loadData("mapping-1.13.json");
// TODO: Remove how verbose this is
System.out.println("Loading block mapping...");
mapIdentifiers(oldToNewBlocks, mapping1_12.getAsJsonObject("blocks"), mapping1_13.getAsJsonObject("blocks"));
System.out.println("Loading item mapping...");
mapIdentifiers(oldToNewItems, mapping1_12.getAsJsonObject("items"), mapping1_13.getAsJsonObject("items"));
}
private static void mapIdentifiers(Map<Integer, Integer> output, JsonObject oldIdentifiers, JsonObject newIdentifiers) {
for (Map.Entry<String, JsonElement> entry : oldIdentifiers.entrySet()) {
Map.Entry<String, JsonElement> value = findValue(newIdentifiers, entry.getValue().getAsString());
if (value == null) {
System.out.println("No key for " + entry.getValue() + " :( ");
continue;
}
output.put(Integer.parseInt(entry.getKey()), Integer.parseInt(value.getKey()));
}
}
private static Map.Entry<String, JsonElement> findValue(JsonObject object, String needle) {
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
String value = entry.getValue().getAsString();
if (value.equals(needle)) {
return entry;
}
}
return null;
}
public static JsonObject loadData(String name) {
InputStream stream = MappingData.class.getClassLoader().getResourceAsStream("assets/viaversion/data/" + name);
InputStreamReader reader = new InputStreamReader(stream);
try {
JsonObject jsonObject = GsonUtil.getGson().fromJson(reader, JsonObject.class);
return jsonObject;
} finally {
try {
reader.close();
} catch (IOException ignored) {
// Ignored
}
}
}
}

View File

@ -3,21 +3,31 @@ package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.Entity1_12Types;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets.InventoryPackets;
import java.util.ArrayList;
import java.util.List;
public class MetadataRewriter {
public static void handleMetadata(int entityId, Entity1_12Types.EntityType type, List<Metadata> metadatas, UserConnection connection) {
// metadatas.clear();
for (Metadata metadata : new ArrayList<>(metadatas)) {
// 1.13 changed item to flat item (no data)
if (metadata.getMetaType().getType() == Type.ITEM) {
metadata.setMetaType(MetaType1_13.Slot);
InventoryPackets.toClient((Item) metadata.getValue());
}
// Handle other changes
try {
if (type.is(Entity1_12Types.EntityType.AREA_EFFECT_CLOUD)) {
if (metadata.getId() == 10 || metadata.getId() == 11) {
// TODO: AreaEffectCloud has lost 2 integers and gained "ef"
// Will be implemented when more info is known
metadata.setId(13);
metadatas.remove(metadata); // Remove
}
}
} catch (Exception e) {

View File

@ -1,86 +1,40 @@
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2;
import com.google.common.base.Optional;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.Entity1_12Types;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_12;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets.EntityPackets;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets.WorldPackets;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.EntityTracker;
// Development of 1.13 support!
public class ProtocolSnapshotTo1_12_2 extends Protocol {
static {
MappingData.init();
}
@Override
protected void registerPackets() {
// Register grouped packet changes
EntityPackets.register(this);
WorldPackets.register(this);
InventoryPackets.register(this);
// Outgoing packets
// Spawn Object
registerOutgoing(State.PLAY, 0x00, 0x00, new PacketRemapper() {
// Statistics
registerOutgoing(State.PLAY, 0x7, 0x7, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.BYTE); // 2 - Type
// TODO: This packet has changed
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
byte type = wrapper.get(Type.BYTE, 0);
Entity1_12Types.EntityType entType = Entity1_12Types.getTypeFromId(type, true);
// Register Type ID
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
}
});
}
});
// Spawn mob packet
registerOutgoing(State.PLAY, 0x03, 0x03, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.UUID); // 1 - Entity UUID
map(Type.VAR_INT); // 2 - Entity Type
map(Type.DOUBLE); // 3 - X
map(Type.DOUBLE); // 4 - Y
map(Type.DOUBLE); // 5 - Z
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
map(Types1_12.METADATA_LIST); // 12 - Metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
// Change Type :)
int type = wrapper.get(Type.VAR_INT, 1);
Entity1_12Types.EntityType entType = Entity1_12Types.getTypeFromId(type, false);
// Register Type ID
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_12.METADATA_LIST, 0), wrapper.user());
}
});
}
});
registerOutgoing(State.PLAY, 0xF, 0xE);
// 0xE Tab complete was removed
registerOutgoing(State.PLAY, 0xE, 0xE, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
@ -89,90 +43,202 @@ public class ProtocolSnapshotTo1_12_2 extends Protocol {
});
}
});
registerOutgoing(State.PLAY, 0x10, 0xF);
// New packet 0x10, empty packet, possible placeholder for new command system?
// Destroy entities
registerOutgoing(State.PLAY, 0x32, 0x32, new PacketRemapper() {
registerOutgoing(State.PLAY, 0xF, 0xE);
// Tab-Complete
registerOutgoing(State.PLAY, 0xE, 0x10, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY); // 0 - Entity IDS
// TODO: This packet has changed
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0))
wrapper.user().get(EntityTracker.class).removeEntity(entity);
wrapper.cancel();
}
});
}
});
// Metadata packet
registerOutgoing(State.PLAY, 0x3c, 0x3c, new PacketRemapper() {
// New packet 0x11, declare commands
registerOutgoing(State.PLAY, 0x11, 0x12);
registerOutgoing(State.PLAY, 0x12, 0x13);
registerOutgoing(State.PLAY, 0x13, 0x14);
registerOutgoing(State.PLAY, 0x15, 0x16);
registerOutgoing(State.PLAY, 0x17, 0x18);
registerOutgoing(State.PLAY, 0x1A, 0x1B);
registerOutgoing(State.PLAY, 0x1B, 0x1C);
registerOutgoing(State.PLAY, 0x1C, 0x1D);
registerOutgoing(State.PLAY, 0x1D, 0x1E);
registerOutgoing(State.PLAY, 0x1E, 0x1F);
registerOutgoing(State.PLAY, 0x1F, 0x20);
registerOutgoing(State.PLAY, 0x21, 0x22);
// Join (save dimension id)
registerOutgoing(State.PLAY, 0x23, 0x24, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Types1_12.METADATA_LIST); // 1 - Metadata list
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
Optional<Entity1_12Types.EntityType> type = wrapper.user().get(EntityTracker.class).get(entityId);
if (!type.isPresent())
return;
MetadataRewriter.handleMetadata(entityId, type.get(), wrapper.get(Types1_12.METADATA_LIST, 0), wrapper.user());
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientChunks.setEnvironment(dimensionId);
}
});
}
});
// 0x49 - New packet, options 0-4 followed by enum / string (possibly new command system?)
registerOutgoing(State.PLAY, 0x49, 0x4A);
registerOutgoing(State.PLAY, 0x4A, 0x4B);
registerOutgoing(State.PLAY, 0x4B, 0x4C);
registerOutgoing(State.PLAY, 0x4C, 0x4D);
registerOutgoing(State.PLAY, 0x4D, 0x4E);
registerOutgoing(State.PLAY, 0x4E, 0x4F);
registerOutgoing(State.PLAY, 0x4F, 0x50);
registerOutgoing(State.PLAY, 0x24, 0x25);
registerOutgoing(State.PLAY, 0x25, 0x26);
registerOutgoing(State.PLAY, 0x26, 0x27);
registerOutgoing(State.PLAY, 0x27, 0x28);
registerOutgoing(State.PLAY, 0x28, 0x29);
registerOutgoing(State.PLAY, 0x29, 0x2A);
registerOutgoing(State.PLAY, 0x2A, 0x2B);
// Craft Recipe Response
registerOutgoing(State.PLAY, 0x2B, 0x2C, new PacketRemapper() {
@Override
public void registerMap() {
// TODO: This packet has changed
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.cancel();
}
});
}
});
registerOutgoing(State.PLAY, 0x2C, 0x2D);
registerOutgoing(State.PLAY, 0x2D, 0x2E);
registerOutgoing(State.PLAY, 0x2E, 0x2F);
registerOutgoing(State.PLAY, 0x2F, 0x30);
registerOutgoing(State.PLAY, 0x30, 0x31);
// Unlock Recipes
registerOutgoing(State.PLAY, 0x31, 0x32, new PacketRemapper() {
@Override
public void registerMap() {
// TODO: This packet has changed
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.cancel();
}
});
}
});
registerOutgoing(State.PLAY, 0x33, 0x34);
registerOutgoing(State.PLAY, 0x34, 0x35);
// Respawn (save dimension id)
registerOutgoing(State.PLAY, 0x35, 0x36, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Dimension ID
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 0);
clientWorld.setEnvironment(dimensionId);
}
});
}
});
registerOutgoing(State.PLAY, 0x36, 0x37);
registerOutgoing(State.PLAY, 0x37, 0x38);
registerOutgoing(State.PLAY, 0x38, 0x39);
registerOutgoing(State.PLAY, 0x39, 0x3A);
registerOutgoing(State.PLAY, 0x3A, 0x3B);
registerOutgoing(State.PLAY, 0x3B, 0x3C);
registerOutgoing(State.PLAY, 0x3D, 0x3E);
registerOutgoing(State.PLAY, 0x3E, 0x3F);
registerOutgoing(State.PLAY, 0x40, 0x41);
registerOutgoing(State.PLAY, 0x41, 0x42);
// Scoreboard Objective
registerOutgoing(State.PLAY, 0x42, 0x43, new PacketRemapper() {
@Override
public void registerMap() {
// TODO: This packet has changed
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.cancel();
}
});
}
});
registerOutgoing(State.PLAY, 0x43, 0x44);
registerOutgoing(State.PLAY, 0x44, 0x45);
registerOutgoing(State.PLAY, 0x45, 0x46);
registerOutgoing(State.PLAY, 0x46, 0x47);
registerOutgoing(State.PLAY, 0x47, 0x48);
registerOutgoing(State.PLAY, 0x48, 0x49);
// New packet 0x4A - Stop sound (TODO: Migrate from Plugin Messages)
registerOutgoing(State.PLAY, 0x49, 0x4B);
registerOutgoing(State.PLAY, 0x4A, 0x4C);
registerOutgoing(State.PLAY, 0x4B, 0x4D);
registerOutgoing(State.PLAY, 0x4C, 0x4E);
registerOutgoing(State.PLAY, 0x4D, 0x4F);
registerOutgoing(State.PLAY, 0x4E, 0x50);
registerOutgoing(State.PLAY, 0x4F, 0x51);
// New packet 0x52 - Declare Recipes
// New packet 0x53 - Tags
// Incoming packets
registerIncoming(State.PLAY, 0x2, 0x1);
// 0x1 Tab complete was removed
registerIncoming(State.PLAY, 0x3, 0x2);
registerIncoming(State.PLAY, 0x4, 0x3);
registerIncoming(State.PLAY, 0x5, 0x4);
registerIncoming(State.PLAY, 0x6, 0x5);
registerIncoming(State.PLAY, 0x7, 0x6);
registerIncoming(State.PLAY, 0x8, 0x7);
registerIncoming(State.PLAY, 0x9, 0x8);
registerIncoming(State.PLAY, 0xA, 0x9);
registerIncoming(State.PLAY, 0xB, 0xA);
registerIncoming(State.PLAY, 0xC, 0xB);
registerIncoming(State.PLAY, 0xD, 0xC);
registerIncoming(State.PLAY, 0xE, 0xD);
registerIncoming(State.PLAY, 0xF, 0xE);
registerIncoming(State.PLAY, 0x10, 0xF);
registerIncoming(State.PLAY, 0x11, 0x10);
registerIncoming(State.PLAY, 0x12, 0x11);
registerIncoming(State.PLAY, 0x13, 0x12);
registerIncoming(State.PLAY, 0x14, 0x13);
registerIncoming(State.PLAY, 0x15, 0x14);
registerIncoming(State.PLAY, 0x16, 0x15);
registerIncoming(State.PLAY, 0x17, 0x16);
registerIncoming(State.PLAY, 0x18, 0x17);
registerIncoming(State.PLAY, 0x19, 0x18);
registerIncoming(State.PLAY, 0x1A, 0x19);
registerIncoming(State.PLAY, 0x1B, 0x1A);
registerIncoming(State.PLAY, 0x1C, 0x1B);
registerIncoming(State.PLAY, 0x1D, 0x1C);
registerIncoming(State.PLAY, 0x1E, 0x1D);
registerIncoming(State.PLAY, 0x1F, 0x1E);
registerIncoming(State.PLAY, 0x20, 0x1F);
// Tab-Complete
registerIncoming(State.PLAY, 0x1, 0x4, new PacketRemapper() {
@Override
public void registerMap() {
// TODO: This packet has changed
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.cancel();
}
});
}
});
// Craft Recipe Request
registerIncoming(State.PLAY, 0x12, 0x12, new PacketRemapper() {
@Override
public void registerMap() {
// TODO: This packet has changed
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.cancel();
}
});
}
});
}
@Override
public void init(UserConnection userConnection) {
userConnection.put(new EntityTracker(userConnection));
if (!userConnection.has(ClientWorld.class))
userConnection.put(new ClientWorld(userConnection));
}
}

View File

@ -0,0 +1,114 @@
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets;
import com.google.common.base.Optional;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.entities.Entity1_12Types;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_12;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.MetadataRewriter;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.EntityTracker;
public class EntityPackets {
public static void register(Protocol protocol) {
// Outgoing packets
// Spawn Object
protocol.registerOutgoing(State.PLAY, 0x0, 0x0, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.BYTE); // 2 - Type
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
byte type = wrapper.get(Type.BYTE, 0);
Entity1_12Types.EntityType entType = Entity1_12Types.getTypeFromId(type, true);
// Register Type ID
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
}
});
}
});
// Spawn mob packet
protocol.registerOutgoing(State.PLAY, 0x3, 0x3, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.UUID); // 1 - Entity UUID
map(Type.VAR_INT); // 2 - Entity Type
map(Type.DOUBLE); // 3 - X
map(Type.DOUBLE); // 4 - Y
map(Type.DOUBLE); // 5 - Z
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
map(Types1_12.METADATA_LIST); // 12 - Metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
int type = wrapper.get(Type.VAR_INT, 1);
Entity1_12Types.EntityType entType = Entity1_12Types.getTypeFromId(type, false);
// Register Type ID
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_12.METADATA_LIST, 0), wrapper.user());
}
});
}
});
// Destroy entities
protocol.registerOutgoing(State.PLAY, 0x32, 0x33, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY); // 0 - Entity IDS
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0))
wrapper.user().get(EntityTracker.class).removeEntity(entity);
}
});
}
});
// Metadata packet
protocol.registerOutgoing(State.PLAY, 0x3C, 0x3D, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Types1_12.METADATA_LIST); // 1 - Metadata list
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
Optional<Entity1_12Types.EntityType> type = wrapper.user().get(EntityTracker.class).get(entityId);
if (!type.isPresent())
return;
MetadataRewriter.handleMetadata(entityId, type.get(), wrapper.get(Types1_12.METADATA_LIST, 0), wrapper.user());
}
});
}
});
}
}

View File

@ -0,0 +1,164 @@
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.MappingData;
public class InventoryPackets {
public static void register(Protocol protocol) {
/*
Outgoing packets
*/
// Set slot packet
protocol.registerOutgoing(State.PLAY, 0x16, 0x17, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.FLAT_ITEM); // 2 - Slot Value
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.FLAT_ITEM, 0);
toClient(stack);
}
});
}
});
// Window items packet
protocol.registerOutgoing(State.PLAY, 0x14, 0x15, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.FLAT_ITEM_ARRAY); // 1 - Window Values
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item[] stacks = wrapper.get(Type.FLAT_ITEM_ARRAY, 0);
for (Item stack : stacks)
toClient(stack);
}
});
}
});
// Plugin message Packet -> Trading
protocol.registerOutgoing(State.PLAY, 0x18, 0x19, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Channel
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// TODO: StopSound?
if (wrapper.get(Type.STRING, 0).equalsIgnoreCase("MC|TrList")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
toClient(wrapper.passthrough(Type.FLAT_ITEM)); // Input Item
toClient(wrapper.passthrough(Type.FLAT_ITEM)); // Output Item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem)
toClient(wrapper.passthrough(Type.FLAT_ITEM)); // Second Item
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses
wrapper.passthrough(Type.INT); // Maximum number of trade uses
}
}
}
});
}
});
// Entity Equipment Packet
protocol.registerOutgoing(State.PLAY, 0x3F, 0x40, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.VAR_INT); // 1 - Slot ID
map(Type.FLAT_ITEM); // 2 - Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.FLAT_ITEM, 0);
toClient(stack);
}
});
}
});
/*
Incoming packets
*/
// Click window packet
protocol.registerIncoming(State.PLAY, 0x07, 0x07, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot
map(Type.BYTE); // 2 - Button
map(Type.SHORT); // 3 - Action number
map(Type.VAR_INT); // 4 - Mode
map(Type.FLAT_ITEM); // 5 - Clicked Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.FLAT_ITEM, 0);
// EntityIdRewriter.toServerItem(item);
}
});
}
}
);
// Creative Inventory Action
protocol.registerIncoming(State.PLAY, 0x1B, 0x1B, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.SHORT); // 0 - Slot
map(Type.FLAT_ITEM); // 1 - Clicked Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0);
// EntityIdRewriter.toServerItem(item);
}
});
}
}
);
}
public static void toClient(Item item) {
if (item == null) return;
int rawId = (item.getId() << 4 | item.getData() & 0xF);
if (!MappingData.oldToNewItems.containsKey(rawId)) {
if (MappingData.oldToNewItems.containsKey(item.getId() << 4)) {
rawId = item.getId() << 4;
} else {
rawId = 0;
}
}
item.setId(MappingData.oldToNewItems.get(rawId).shortValue());
item.setData((short) 0);
}
}

View File

@ -0,0 +1,130 @@
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.MappingData;
import java.util.List;
public class WorldPackets {
public static void register(Protocol protocol) {
// Outgoing packets
protocol.registerOutgoing(State.PLAY, 0x9, 0x9, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) {
wrapper.cancel();
}
});
}
});
// Block Change
protocol.registerOutgoing(State.PLAY, 0xB, 0xB, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION);
map(Type.VAR_INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.VAR_INT, 0, toNewId(wrapper.get(Type.VAR_INT, 0)));
}
});
}
});
// Multi Block Change
protocol.registerOutgoing(State.PLAY, 0x10, 0xF, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT);
map(Type.INT);
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// Convert ids
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
record.setBlockId(toNewId(record.getBlockId()));
}
}
});
}
});
// Named Sound Effect
protocol.registerOutgoing(State.PLAY, 0x19, 0x1A, new PacketRemapper() {
@Override
public void registerMap() {
// TODO: This packet has changed
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.cancel();
}
});
}
});
// Chunk Data
protocol.registerOutgoing(State.PLAY, 0x20, 0x21, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld);
Chunk chunk = wrapper.passthrough(type);
// Remap palette ids
for (ChunkSection section : chunk.getSections()) {
if (section == null) continue;
List<Integer> palette = section.getPalette();
for (int i = 0; i < palette.size(); i++) {
int newId = toNewId(palette.get(i));
palette.set(i, newId);
}
}
}
});
}
});
// Particle
protocol.registerOutgoing(State.PLAY, 0x22, 0x23, new PacketRemapper() {
@Override
public void registerMap() {
// TODO: This packet has changed
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.cancel();
}
});
}
});
}
private static int toNewId(int oldId) {
if (MappingData.oldToNewBlocks.containsKey(oldId)) {
return MappingData.oldToNewBlocks.get(oldId);
} else {
System.out.println("Missing block " + oldId);
// Default stone
return 1;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>1.4.0-17w45b</version>
<version>1.4.0-17w49b</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>viaversion-jar</name>

View File

@ -6,7 +6,7 @@
<groupId>us.myles</groupId>
<artifactId>viaversion-parent</artifactId>
<version>1.4.0-17w45b</version>
<version>1.4.0-17w49b</version>
<packaging>pom</packaging>
<name>viaversion-parent</name>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>1.4.0-17w45b</version>
<version>1.4.0-17w49b</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>1.4.0-17w45b</version>
<version>1.4.0-17w49b</version>
</parent>
<modelVersion>4.0.0</modelVersion>