Rewrite Spawner entity ID, fix #643

This commit is contained in:
Matsv 2017-05-14 16:02:04 +02:00
parent c92fcc9f9a
commit 667ad0d059
5 changed files with 223 additions and 18 deletions

View File

@ -6,7 +6,7 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import us.myles.ViaVersion.api.minecraft.item.Item; import us.myles.ViaVersion.api.minecraft.item.Item;
public class ItemRewriter { public class EntityIdRewriter {
private static BiMap<String, String> oldToNewNames = HashBiMap.create(); private static BiMap<String, String> oldToNewNames = HashBiMap.create();
static { static {
@ -87,20 +87,32 @@ public class ItemRewriter {
oldToNewNames.put("ZombieVillager", "minecraft:zombie_villager"); oldToNewNames.put("ZombieVillager", "minecraft:zombie_villager");
} }
public static void toClient(Item item) { public static void toClient(CompoundTag tag) {
if (hasEntityTag(item)) { if (tag.get("id") instanceof StringTag) {
CompoundTag entityTag = item.getTag().get("EntityTag"); StringTag id = tag.get("id");
if (entityTag.get("id") instanceof StringTag) {
StringTag id = entityTag.get("id");
if (oldToNewNames.containsKey(id.getValue())) { if (oldToNewNames.containsKey(id.getValue())) {
id.setValue(oldToNewNames.get(id.getValue())); id.setValue(oldToNewNames.get(id.getValue()));
} }
} }
} }
public static void toClientSpawner(CompoundTag tag) {
if (tag != null && tag.contains("SpawnData")) {
CompoundTag spawnData = tag.get("SpawnData");
if (spawnData != null && spawnData.contains("id"))
toClient(spawnData);
}
}
public static void toClientItem(Item item) {
if (hasEntityTag(item)) {
CompoundTag entityTag = item.getTag().get("EntityTag");
toClient(entityTag);
}
if (item != null && item.getAmount() <= 0) item.setAmount((byte) 1); if (item != null && item.getAmount() <= 0) item.setAmount((byte) 1);
} }
public static void toServer(Item item) { public static void toServerItem(Item item) {
if (hasEntityTag(item)) { if (hasEntityTag(item)) {
CompoundTag entityTag = item.getTag().get("EntityTag"); CompoundTag entityTag = item.getTag().get("EntityTag");
if (entityTag.get("id") instanceof StringTag) { if (entityTag.get("id") instanceof StringTag) {

View File

@ -1,10 +1,13 @@
package us.myles.ViaVersion.protocols.protocol1_11to1_10; package us.myles.ViaVersion.protocols.protocol1_11to1_10;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.Entity1_11Types; import us.myles.ViaVersion.api.entities.Entity1_11Types;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.protocol.Protocol; import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.remapper.PacketRemapper;
@ -15,6 +18,8 @@ import us.myles.ViaVersion.api.type.types.version.Types1_9;
import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_11to1_10.packets.InventoryPackets; import us.myles.ViaVersion.protocols.protocol1_11to1_10.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_11to1_10.storage.EntityTracker; import us.myles.ViaVersion.protocols.protocol1_11to1_10.storage.EntityTracker;
import us.myles.ViaVersion.protocols.protocol1_11to1_10.types.Chunk1_11Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_11To1_10 extends Protocol { public class Protocol1_11To1_10 extends Protocol {
private static final ValueTransformer<Float, Short> toOldByte = new ValueTransformer<Float, Short>(Type.UNSIGNED_BYTE) { private static final ValueTransformer<Float, Short> toOldByte = new ValueTransformer<Float, Short>(Type.UNSIGNED_BYTE) {
@ -243,6 +248,88 @@ public class Protocol1_11To1_10 extends Protocol {
} }
}); });
// Update Block Entity
registerOutgoing(State.PLAY, 0x09, 0x09, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Position
map(Type.UNSIGNED_BYTE); // 1 - Action
map(Type.NBT); // 2 - NBT data
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 1) {
CompoundTag tag = wrapper.get(Type.NBT, 0);
EntityIdRewriter.toClientSpawner(tag);
}
}
});
}
});
// Chunk Data
registerOutgoing(State.PLAY, 0x20, 0x20, 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_11Type type = new Chunk1_11Type(clientWorld);
Chunk chunk = wrapper.passthrough(type);
if (chunk.getBlockEntities() == null) return;
for (CompoundTag tag : chunk.getBlockEntities()) {
if (tag.contains("id") &&
((StringTag) tag.get("id")).getValue().equals("MobSpawner")) {
EntityIdRewriter.toClientSpawner(tag);
}
}
}
});
}
});
// Join (save dimension id)
registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() {
@Override
public void registerMap() {
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 {
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientChunks.setEnvironment(dimensionId);
}
});
}
});
// Respawn (save dimension id)
registerOutgoing(State.PLAY, 0x33, 0x33, 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);
}
});
}
});
/* /*
INCOMING PACKETS INCOMING PACKETS
*/ */
@ -314,5 +401,7 @@ public class Protocol1_11To1_10 extends Protocol {
@Override @Override
public void init(UserConnection userConnection) { public void init(UserConnection userConnection) {
userConnection.put(new EntityTracker(userConnection)); userConnection.put(new EntityTracker(userConnection));
if (!userConnection.has(ClientWorld.class))
userConnection.put(new ClientWorld(userConnection));
} }
} }

View File

@ -6,7 +6,7 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_11to1_10.ItemRewriter; import us.myles.ViaVersion.protocols.protocol1_11to1_10.EntityIdRewriter;
import us.myles.ViaVersion.protocols.protocol1_11to1_10.Protocol1_11To1_10; import us.myles.ViaVersion.protocols.protocol1_11to1_10.Protocol1_11To1_10;
public class InventoryPackets { public class InventoryPackets {
@ -27,7 +27,7 @@ public class InventoryPackets {
@Override @Override
public void handle(PacketWrapper wrapper) throws Exception { public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.ITEM, 0); Item stack = wrapper.get(Type.ITEM, 0);
ItemRewriter.toClient(stack); EntityIdRewriter.toClientItem(stack);
} }
}); });
} }
@ -45,7 +45,7 @@ public class InventoryPackets {
public void handle(PacketWrapper wrapper) throws Exception { public void handle(PacketWrapper wrapper) throws Exception {
Item[] stacks = wrapper.get(Type.ITEM_ARRAY, 0); Item[] stacks = wrapper.get(Type.ITEM_ARRAY, 0);
for (Item stack : stacks) for (Item stack : stacks)
ItemRewriter.toClient(stack); EntityIdRewriter.toClientItem(stack);
} }
}); });
} }
@ -63,7 +63,7 @@ public class InventoryPackets {
@Override @Override
public void handle(PacketWrapper wrapper) throws Exception { public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.ITEM, 0); Item stack = wrapper.get(Type.ITEM, 0);
ItemRewriter.toClient(stack); EntityIdRewriter.toClientItem(stack);
} }
}); });
} }
@ -83,12 +83,12 @@ public class InventoryPackets {
int size = wrapper.passthrough(Type.UNSIGNED_BYTE); int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
ItemRewriter.toClient(wrapper.passthrough(Type.ITEM)); // Input Item EntityIdRewriter.toClientItem(wrapper.passthrough(Type.ITEM)); // Input Item
ItemRewriter.toClient(wrapper.passthrough(Type.ITEM)); // Output Item EntityIdRewriter.toClientItem(wrapper.passthrough(Type.ITEM)); // Output Item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem) if (secondItem)
ItemRewriter.toClient(wrapper.passthrough(Type.ITEM)); // Second Item EntityIdRewriter.toClientItem(wrapper.passthrough(Type.ITEM)); // Second Item
wrapper.passthrough(Type.BOOLEAN); // Trade disabled wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses wrapper.passthrough(Type.INT); // Number of tools uses
@ -119,7 +119,7 @@ public class InventoryPackets {
@Override @Override
public void handle(PacketWrapper wrapper) throws Exception { public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0); Item item = wrapper.get(Type.ITEM, 0);
ItemRewriter.toServer(item); EntityIdRewriter.toServerItem(item);
} }
}); });
} }
@ -137,7 +137,7 @@ public class InventoryPackets {
@Override @Override
public void handle(PacketWrapper wrapper) throws Exception { public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0); Item item = wrapper.get(Type.ITEM, 0);
ItemRewriter.toServer(item); EntityIdRewriter.toServerItem(item);
} }
}); });
} }

View File

@ -0,0 +1,103 @@
package us.myles.ViaVersion.protocols.protocol1_11to1_10.types;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import us.myles.ViaVersion.api.minecraft.Environment;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.type.PartialType;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.Chunk1_9_3_4;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.ChunkSection1_9_3_4;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
public class Chunk1_11Type extends PartialType<Chunk, ClientWorld> {
public Chunk1_11Type(ClientWorld param) {
super(param, Chunk.class);
}
@Override
public Chunk read(ByteBuf input, ClientWorld world) throws Exception {
int chunkX = input.readInt();
int chunkZ = input.readInt();
boolean groundUp = input.readBoolean();
int primaryBitmask = Type.VAR_INT.read(input);
Type.VAR_INT.read(input);
BitSet usedSections = new BitSet(16);
ChunkSection1_9_3_4[] sections = new ChunkSection1_9_3_4[16];
// Calculate section count from bitmask
for (int i = 0; i < 16; i++) {
if ((primaryBitmask & (1 << i)) != 0) {
usedSections.set(i);
}
}
// Read sections
for (int i = 0; i < 16; i++) {
if (!usedSections.get(i)) continue; // Section not set
ChunkSection1_9_3_4 section = new ChunkSection1_9_3_4();
sections[i] = section;
section.readBlocks(input);
section.readBlockLight(input);
if (world.getEnvironment() == Environment.NORMAL) {
section.readSkyLight(input);
}
}
byte[] biomeData = groundUp ? new byte[256] : null;
if (groundUp) {
input.readBytes(biomeData);
}
List<CompoundTag> nbtData = Arrays.asList(Type.NBT_ARRAY.read(input));
return new Chunk1_9_3_4(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData);
}
@Override
public void write(ByteBuf output, ClientWorld world, Chunk chunk) throws Exception {
output.writeInt(chunk.getX());
output.writeInt(chunk.getZ());
output.writeBoolean(chunk.isGroundUp());
Type.VAR_INT.write(output, chunk.getBitmask());
ByteBuf buf = Unpooled.buffer();
for (int i = 0; i < 16; 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);
Type.VAR_INT.write(output, buf.readableBytes() + (chunk.isBiomeData() ? 256 : 0));
output.writeBytes(buf);
buf.release(); // release buffer
// Write biome data
if (chunk.isBiomeData()) {
output.writeBytes(chunk.getBiomeData());
}
// Write Block Entities
Type.NBT_ARRAY.write(output, chunk.getBlockEntities().toArray(new CompoundTag[0]));
}
@Override
public Class<? extends Type> getBaseClass() {
return BaseChunkType.class;
}
}

View File

@ -53,6 +53,7 @@ public class Protocol1_9_1_2TO1_9_3_4 extends Protocol {
} }
}); });
// Chunk Packet
registerOutgoing(State.PLAY, 0x20, 0x20, new PacketRemapper() { registerOutgoing(State.PLAY, 0x20, 0x20, new PacketRemapper() {
@Override @Override
public void registerMap() { public void registerMap() {