Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-26 16:12:42 +01:00
Handle changed block entities. Fixes banners,beds & flowerpots
Dieser Commit ist enthalten in:
Ursprung
ba70dae9ad
Commit
012aac97ee
@ -9,6 +9,8 @@ public interface ChunkSection {
|
|||||||
|
|
||||||
void setBlock(int x, int y, int z, int type, int data);
|
void setBlock(int x, int y, int z, int type, int data);
|
||||||
|
|
||||||
|
void setFlatBlock(int x, int y, int z, int type);
|
||||||
|
|
||||||
int getBlockId(int x, int y, int z);
|
int getBlockId(int x, int y, int z);
|
||||||
|
|
||||||
void writeBlocks(ByteBuf output) throws Exception;
|
void writeBlocks(ByteBuf output) throws Exception;
|
||||||
|
@ -3,7 +3,6 @@ package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import lombok.Getter;
|
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
|
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
|
||||||
import us.myles.ViaVersion.api.type.Type;
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
@ -46,6 +45,25 @@ public class ChunkSection1_9_3_4 implements ChunkSection {
|
|||||||
setBlock(index(x, y, z), type, data);
|
setBlock(index(x, y, z), type, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a flat block in the chunks
|
||||||
|
*
|
||||||
|
* @param x Block X
|
||||||
|
* @param y Block Y
|
||||||
|
* @param z Block Z
|
||||||
|
* @param type The type of the block
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setFlatBlock(int x, int y, int z, int type) {
|
||||||
|
int index = palette.indexOf(type);
|
||||||
|
if (index == -1) {
|
||||||
|
index = palette.size();
|
||||||
|
palette.add(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks[index(x, y, z)] = index;
|
||||||
|
}
|
||||||
|
|
||||||
public int getBlockId(int x, int y, int z) {
|
public int getBlockId(int x, int y, int z) {
|
||||||
return getBlock(x, y, z) >> 4;
|
return getBlock(x, y, z) >> 4;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import lombok.Getter;
|
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
|
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
|
||||||
import us.myles.ViaVersion.api.type.Type;
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
@ -46,6 +46,11 @@ public class ChunkSection1_9_1_2 implements ChunkSection {
|
|||||||
setBlock(index(x, y, z), type, data);
|
setBlock(index(x, y, z), type, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlatBlock(int x, int y, int z, int type) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public int getBlockId(int x, int y, int z) {
|
public int getBlockId(int x, int y, int z) {
|
||||||
return getBlock(x, y, z) >> 4;
|
return getBlock(x, y, z) >> 4;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
|
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
|
||||||
import us.myles.ViaVersion.api.type.Type;
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
@ -46,6 +47,11 @@ public class ChunkSection1_9to1_8 implements ChunkSection {
|
|||||||
setBlock(index(x, y, z), type, data);
|
setBlock(index(x, y, z), type, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlatBlock(int x, int y, int z, int type) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public int getBlockId(int x, int y, int z) {
|
public int getBlockId(int x, int y, int z) {
|
||||||
return getBlock(x, y, z) >> 4;
|
return getBlock(x, y, z) >> 4;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2;
|
|||||||
|
|
||||||
import us.myles.ViaVersion.api.PacketWrapper;
|
import us.myles.ViaVersion.api.PacketWrapper;
|
||||||
import us.myles.ViaVersion.api.data.UserConnection;
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.api.platform.providers.ViaProviders;
|
||||||
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;
|
||||||
@ -13,6 +14,8 @@ 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.EntityPackets;
|
||||||
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets.InventoryPackets;
|
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.packets.WorldPackets;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage;
|
||||||
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.EntityTracker;
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.EntityTracker;
|
||||||
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.TabCompleteTracker;
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.TabCompleteTracker;
|
||||||
|
|
||||||
@ -364,5 +367,11 @@ public class ProtocolSnapshotTo1_12_2 extends Protocol {
|
|||||||
userConnection.put(new TabCompleteTracker(userConnection));
|
userConnection.put(new TabCompleteTracker(userConnection));
|
||||||
if (!userConnection.has(ClientWorld.class))
|
if (!userConnection.has(ClientWorld.class))
|
||||||
userConnection.put(new ClientWorld(userConnection));
|
userConnection.put(new ClientWorld(userConnection));
|
||||||
|
userConnection.put(new BlockStorage(userConnection));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void register(ViaProviders providers) {
|
||||||
|
providers.register(BlockEntityProvider.class, new BlockEntityProvider());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,6 @@ public class EntityPackets {
|
|||||||
int entityId = wrapper.get(Type.VAR_INT, 0);
|
int entityId = wrapper.get(Type.VAR_INT, 0);
|
||||||
|
|
||||||
Entity1_12Types.EntityType entType = Entity1_12Types.EntityType.PLAYER;
|
Entity1_12Types.EntityType entType = Entity1_12Types.EntityType.PLAYER;
|
||||||
System.out.println("REGISTER PLAYER");
|
|
||||||
// Register Type ID
|
// Register Type ID
|
||||||
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
|
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
|
||||||
MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_13.METADATA_LIST, 0), wrapper.user());
|
MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_13.METADATA_LIST, 0), wrapper.user());
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets;
|
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import us.myles.ViaVersion.api.PacketWrapper;
|
import us.myles.ViaVersion.api.PacketWrapper;
|
||||||
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
|
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
|
||||||
|
import us.myles.ViaVersion.api.minecraft.Position;
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
|
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||||
@ -12,12 +16,38 @@ 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_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.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||||
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.MappingData;
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.MappingData;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider;
|
||||||
import java.util.List;
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage;
|
||||||
|
|
||||||
public class WorldPackets {
|
public class WorldPackets {
|
||||||
public static void register(Protocol protocol) {
|
public static void register(Protocol protocol) {
|
||||||
// Outgoing packets
|
// Outgoing packets
|
||||||
|
// Update Block Entity
|
||||||
|
protocol.registerOutgoing(State.PLAY, 0x09, 0x09, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.POSITION); // 0 - Location
|
||||||
|
map(Type.UNSIGNED_BYTE); // 1 - Action
|
||||||
|
map(Type.NBT); // 2 - NBT data
|
||||||
|
|
||||||
|
handler(new PacketHandler() {
|
||||||
|
@Override
|
||||||
|
public void handle(PacketWrapper wrapper) throws Exception {
|
||||||
|
Position position = wrapper.get(Type.POSITION, 0);
|
||||||
|
CompoundTag tag = wrapper.get(Type.NBT, 0);
|
||||||
|
|
||||||
|
BlockEntityProvider provider = Via.getManager().getProviders().get(BlockEntityProvider.class);
|
||||||
|
int newId = provider.transform(wrapper.user(), position, tag, true);
|
||||||
|
|
||||||
|
if (newId != -1) {
|
||||||
|
BlockStorage storage = wrapper.user().get(BlockStorage.class);
|
||||||
|
if (storage.contains(position))
|
||||||
|
storage.get(position).setReplacement(newId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Block Change
|
// Block Change
|
||||||
protocol.registerOutgoing(State.PLAY, 0xB, 0xB, new PacketRemapper() {
|
protocol.registerOutgoing(State.PLAY, 0xB, 0xB, new PacketRemapper() {
|
||||||
@ -28,7 +58,10 @@ public class WorldPackets {
|
|||||||
handler(new PacketHandler() {
|
handler(new PacketHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(PacketWrapper wrapper) throws Exception {
|
public void handle(PacketWrapper wrapper) throws Exception {
|
||||||
wrapper.set(Type.VAR_INT, 0, toNewId(wrapper.get(Type.VAR_INT, 0)));
|
Position position = wrapper.get(Type.POSITION, 0);
|
||||||
|
int newId = toNewId(wrapper.get(Type.VAR_INT, 0));
|
||||||
|
|
||||||
|
wrapper.set(Type.VAR_INT, 0, checkStorage(wrapper.user(), position, newId));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -38,15 +71,24 @@ public class WorldPackets {
|
|||||||
protocol.registerOutgoing(State.PLAY, 0x10, 0xF, new PacketRemapper() {
|
protocol.registerOutgoing(State.PLAY, 0x10, 0xF, new PacketRemapper() {
|
||||||
@Override
|
@Override
|
||||||
public void registerMap() {
|
public void registerMap() {
|
||||||
map(Type.INT);
|
map(Type.INT); // 0 - Chunk X
|
||||||
map(Type.INT);
|
map(Type.INT); // 1 - Chunk Z
|
||||||
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
|
map(Type.BLOCK_CHANGE_RECORD_ARRAY); // 2 - Records
|
||||||
handler(new PacketHandler() {
|
handler(new PacketHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(PacketWrapper wrapper) throws Exception {
|
public void handle(PacketWrapper wrapper) throws Exception {
|
||||||
|
BlockStorage storage = wrapper.user().get(BlockStorage.class);
|
||||||
|
int chunkX = wrapper.get(Type.INT, 0);
|
||||||
|
int chunkZ = wrapper.get(Type.INT, 0);
|
||||||
// Convert ids
|
// Convert ids
|
||||||
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
|
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
|
||||||
record.setBlockId(toNewId(record.getBlockId()));
|
int newBlock = toNewId(record.getBlockId());
|
||||||
|
Position position = new Position(
|
||||||
|
(long) (record.getHorizontal() >> 4 & 15) + (chunkX * 16),
|
||||||
|
(long) record.getY(),
|
||||||
|
(long) ((record.getHorizontal() & 15) + (chunkZ * 16)));
|
||||||
|
|
||||||
|
record.setBlockId(checkStorage(wrapper.user(), position, newBlock));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -64,17 +106,52 @@ public class WorldPackets {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(PacketWrapper wrapper) throws Exception {
|
public void handle(PacketWrapper wrapper) throws Exception {
|
||||||
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
|
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
|
||||||
|
BlockStorage storage = wrapper.user().get(BlockStorage.class);
|
||||||
|
|
||||||
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld);
|
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld);
|
||||||
Chunk chunk = wrapper.passthrough(type);
|
Chunk chunk = wrapper.passthrough(type);
|
||||||
|
|
||||||
// Remap palette ids
|
for (int i = 0; i < chunk.getSections().length; i++) {
|
||||||
for (ChunkSection section : chunk.getSections()) {
|
ChunkSection section = chunk.getSections()[i];
|
||||||
if (section == null) continue;
|
if (section == null)
|
||||||
List<Integer> palette = section.getPalette();
|
continue;
|
||||||
for (int i = 0; i < palette.size(); i++) {
|
|
||||||
int newId = toNewId(palette.get(i));
|
// TODO improve performance
|
||||||
palette.set(i, newId);
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int y = 0; y < 16; y++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
int block = section.getBlock(x, y, z);
|
||||||
|
|
||||||
|
int newId = toNewId(block);
|
||||||
|
section.setFlatBlock(x, y, z, newId);
|
||||||
|
|
||||||
|
if (storage.isWelcome(newId)) {
|
||||||
|
storage.store(new Position(
|
||||||
|
(long) (x + (chunk.getX() << 4)),
|
||||||
|
(long) (y + (i << 4)),
|
||||||
|
(long) (z + (chunk.getZ() << 4))
|
||||||
|
), newId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rewrite BlockEntities to normal blocks
|
||||||
|
BlockEntityProvider provider = Via.getManager().getProviders().get(BlockEntityProvider.class);
|
||||||
|
for (CompoundTag tag : chunk.getBlockEntities()) {
|
||||||
|
int newId = provider.transform(wrapper.user(), null, tag, false);
|
||||||
|
if (newId != -1) {
|
||||||
|
int x = (int) tag.get("x").getValue() & 0xF;
|
||||||
|
int y = (int) tag.get("y").getValue();
|
||||||
|
int z = (int) tag.get("z").getValue() & 0xF;
|
||||||
|
|
||||||
|
Position position = new Position((long) x, (long) y, (long) z);
|
||||||
|
// Store the replacement blocks for blockupdates
|
||||||
|
if (storage.contains(position))
|
||||||
|
storage.get(position).setReplacement(newId);
|
||||||
|
|
||||||
|
chunk.getSections()[y >> 4].setFlatBlock(x, y, z, newId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,4 +188,23 @@ public class WorldPackets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int checkStorage(UserConnection user, Position position, int newId) {
|
||||||
|
BlockStorage storage = user.get(BlockStorage.class);
|
||||||
|
if (storage.contains(position)) {
|
||||||
|
BlockStorage.ReplacementData data = storage.get(position);
|
||||||
|
|
||||||
|
if (data.getOriginal() == newId) {
|
||||||
|
if (data.getReplacement() != -1) {
|
||||||
|
return data.getReplacement();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
storage.remove(position);
|
||||||
|
// Check if the new id has to be stored
|
||||||
|
if (storage.isWelcome(newId))
|
||||||
|
storage.store(position, newId);
|
||||||
|
}
|
||||||
|
} else if (storage.isWelcome(newId))
|
||||||
|
storage.store(position, newId);
|
||||||
|
return newId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import us.myles.ViaVersion.api.PacketWrapper;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.api.minecraft.Position;
|
||||||
|
import us.myles.ViaVersion.api.platform.providers.Provider;
|
||||||
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.ProtocolSnapshotTo1_12_2;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities.BannerHandler;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities.BedHandler;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities.FlowerPotHandler;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class BlockEntityProvider implements Provider {
|
||||||
|
private final Map<String, BlockEntityHandler> handlers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public BlockEntityProvider() {
|
||||||
|
handlers.put("minecraft:flower_pot", new FlowerPotHandler());
|
||||||
|
handlers.put("minecraft:bed", new BedHandler());
|
||||||
|
handlers.put("minecraft:banner", new BannerHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms the BlockEntities to blocks!
|
||||||
|
*
|
||||||
|
* @param user UserConnection instance
|
||||||
|
* @param position Block Position - WARNING: Position is null when called from a chunk
|
||||||
|
* @param tag BlockEntity NBT
|
||||||
|
* @param sendUpdate send a block change update
|
||||||
|
* @return new block id
|
||||||
|
* @throws Exception Gotta throw that exception
|
||||||
|
*/
|
||||||
|
public int transform(UserConnection user, Position position, CompoundTag tag, boolean sendUpdate) throws Exception {
|
||||||
|
if (!tag.contains("id"))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
String id = (String) tag.get("id").getValue();
|
||||||
|
|
||||||
|
if (!handlers.containsKey(id)) {
|
||||||
|
System.out.println("Unhandled BlockEntity " + id + " full tag: " + tag);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int newBlock = handlers.get(id).transform(user, tag);
|
||||||
|
|
||||||
|
if (sendUpdate && newBlock != -1)
|
||||||
|
sendBlockChange(user, position, newBlock);
|
||||||
|
|
||||||
|
return newBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface BlockEntityHandler {
|
||||||
|
int transform(UserConnection user, CompoundTag tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendBlockChange(UserConnection user, Position position, int blockId) throws Exception {
|
||||||
|
PacketWrapper wrapper = new PacketWrapper(0x0B, null, user);
|
||||||
|
wrapper.write(Type.POSITION, position);
|
||||||
|
wrapper.write(Type.VAR_INT, blockId);
|
||||||
|
|
||||||
|
wrapper.send(ProtocolSnapshotTo1_12_2.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.api.minecraft.Position;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage;
|
||||||
|
|
||||||
|
public class BannerHandler implements BlockEntityProvider.BlockEntityHandler {
|
||||||
|
private final int WALL_BANNER_START = 5633; // 4 each
|
||||||
|
private final int WALL_BANNER_STOP = 5696;
|
||||||
|
|
||||||
|
private final int BANNER_START = 5377; // 16 each
|
||||||
|
private final int BANNER_STOP = 5632;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int transform(UserConnection user, CompoundTag tag) {
|
||||||
|
BlockStorage storage = user.get(BlockStorage.class);
|
||||||
|
Position position = new Position(getLong(tag.get("x")), getLong(tag.get("y")), getLong(tag.get("z")));
|
||||||
|
|
||||||
|
if (!storage.contains(position)) {
|
||||||
|
System.out.println("Received an banner color update packet, but there is no banner! O_o " + tag);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blockId = storage.get(position).getOriginal();
|
||||||
|
|
||||||
|
int color = (int) tag.get("Base").getValue();
|
||||||
|
// Standing banner
|
||||||
|
if (blockId >= BANNER_START && blockId <= BANNER_STOP)
|
||||||
|
blockId += ((15 - color) * 16);
|
||||||
|
// Wall banner
|
||||||
|
else if (blockId >= WALL_BANNER_START && blockId <= WALL_BANNER_STOP)
|
||||||
|
blockId += ((15 - color) * 4);
|
||||||
|
else
|
||||||
|
System.out.println("Why does this block have the banner block entity? :(" + tag);
|
||||||
|
|
||||||
|
return blockId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getLong(Tag tag) {
|
||||||
|
return ((Integer) tag.getValue()).longValue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.api.minecraft.Position;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage;
|
||||||
|
|
||||||
|
public class BedHandler implements BlockEntityProvider.BlockEntityHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int transform(UserConnection user, CompoundTag tag) {
|
||||||
|
BlockStorage storage = user.get(BlockStorage.class);
|
||||||
|
Position position = new Position(getLong(tag.get("x")), getLong(tag.get("y")), getLong(tag.get("z")));
|
||||||
|
|
||||||
|
if (!storage.contains(position)) {
|
||||||
|
System.out.println("Received an bed color update packet, but there is no bed! O_o " + tag);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RED_BED + FIRST_BED
|
||||||
|
int blockId = storage.get(position).getOriginal() - 896 + 672;
|
||||||
|
|
||||||
|
int color = (int) tag.get("color").getValue();
|
||||||
|
blockId += (color * 16);
|
||||||
|
|
||||||
|
return blockId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getLong(Tag tag) {
|
||||||
|
return ((Integer) tag.getValue()).longValue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import us.myles.ViaVersion.api.Pair;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class FlowerPotHandler implements BlockEntityProvider.BlockEntityHandler {
|
||||||
|
private static final Map<Pair<String, Integer>, Integer> flowers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
register("minecraft:air", 0, 4466);
|
||||||
|
register("minecraft:sapling", 0, 4467);
|
||||||
|
register("minecraft:sapling", 1, 4468);
|
||||||
|
register("minecraft:sapling", 2, 4469);
|
||||||
|
register("minecraft:sapling", 3, 4470);
|
||||||
|
register("minecraft:sapling", 4, 4471);
|
||||||
|
register("minecraft:sapling", 5, 4472);
|
||||||
|
register("minecraft:tallgrass", 2, 4473);
|
||||||
|
register("minecraft:yellow_flower", 0, 4474);
|
||||||
|
register("minecraft:red_flower", 0, 4475);
|
||||||
|
register("minecraft:red_flower", 1, 4476);
|
||||||
|
register("minecraft:red_flower", 2, 4477);
|
||||||
|
register("minecraft:red_flower", 3, 4478);
|
||||||
|
register("minecraft:red_flower", 4, 4479);
|
||||||
|
register("minecraft:red_flower", 5, 4480);
|
||||||
|
register("minecraft:red_flower", 6, 4481);
|
||||||
|
register("minecraft:red_flower", 7, 4482);
|
||||||
|
register("minecraft:red_flower", 8, 4483);
|
||||||
|
register("minecraft:red_mushroom", 0, 4484);
|
||||||
|
register("minecraft:brown_mushroom", 0, 4485);
|
||||||
|
register("minecraft:deadbush", 0, 4486);
|
||||||
|
register("minecraft:cactus", 0, 4487);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register(String identifier, int blockData, int newId) {
|
||||||
|
flowers.put(new Pair<>(identifier, blockData), newId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int transform(UserConnection user, CompoundTag tag) {
|
||||||
|
String item = (String) tag.get("Item").getValue();
|
||||||
|
int data = (int) tag.get("Data").getValue();
|
||||||
|
|
||||||
|
Pair<String, Integer> pair = new Pair<>(item, data);
|
||||||
|
|
||||||
|
if (flowers.containsKey(pair)) {
|
||||||
|
return flowers.get(pair);
|
||||||
|
} else {
|
||||||
|
System.out.println("Could not find flowerpot content " + item + " for " + tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import us.myles.ViaVersion.api.data.StoredObject;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.api.minecraft.Position;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
public class BlockStorage extends StoredObject {
|
||||||
|
// This BlockStorage is very exclusive (;
|
||||||
|
private static final List<Integer> whitelist = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
// Flower pots
|
||||||
|
whitelist.add(4466);
|
||||||
|
|
||||||
|
// Add those red beds
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
whitelist.add(896 + i);
|
||||||
|
|
||||||
|
// Add the white banners
|
||||||
|
for (int i = 0; i < 20; i++)
|
||||||
|
whitelist.add(5377 + i);
|
||||||
|
|
||||||
|
// Add the whhite wall banners
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
whitelist.add(5633 + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Position, ReplacementData> blocks = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public BlockStorage(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new BlockStorage(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void store(Position position, int block) {
|
||||||
|
store(position, block, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void store(Position position, int block, int replacementId) {
|
||||||
|
if (!whitelist.contains(block))
|
||||||
|
return;
|
||||||
|
|
||||||
|
blocks.put(position, new ReplacementData(block, replacementId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWelcome(int block) {
|
||||||
|
return whitelist.contains(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Position position) {
|
||||||
|
return blocks.containsKey(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReplacementData get(Position position) {
|
||||||
|
return blocks.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReplacementData remove(Position position) {
|
||||||
|
return blocks.remove(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ReplacementData {
|
||||||
|
private int original;
|
||||||
|
private int replacement;
|
||||||
|
}
|
||||||
|
}
|
@ -894,22 +894,22 @@
|
|||||||
"2208": "minecraft:beacon",
|
"2208": "minecraft:beacon",
|
||||||
"2224": "minecraft:cobblestone_wall[east=false,north=false,south=false,up=false,west=false]",
|
"2224": "minecraft:cobblestone_wall[east=false,north=false,south=false,up=false,west=false]",
|
||||||
"2225": "minecraft:mossy_cobblestone_wall[east=false,north=false,south=false,up=false,west=false]",
|
"2225": "minecraft:mossy_cobblestone_wall[east=false,north=false,south=false,up=false,west=false]",
|
||||||
"2240": "minecraft:potted_cactus",
|
"2240": "minecraft:flower_pot",
|
||||||
"2241": "minecraft:potted_cactus",
|
"2241": "minecraft:flower_pot",
|
||||||
"2242": "minecraft:potted_cactus",
|
"2242": "minecraft:flower_pot",
|
||||||
"2243": "minecraft:potted_cactus",
|
"2243": "minecraft:flower_pot",
|
||||||
"2244": "minecraft:potted_cactus",
|
"2244": "minecraft:flower_pot",
|
||||||
"2245": "minecraft:potted_cactus",
|
"2245": "minecraft:flower_pot",
|
||||||
"2246": "minecraft:potted_cactus",
|
"2246": "minecraft:flower_pot",
|
||||||
"2247": "minecraft:potted_cactus",
|
"2247": "minecraft:flower_pot",
|
||||||
"2248": "minecraft:potted_cactus",
|
"2248": "minecraft:flower_pot",
|
||||||
"2249": "minecraft:potted_cactus",
|
"2249": "minecraft:flower_pot",
|
||||||
"2250": "minecraft:potted_cactus",
|
"2250": "minecraft:flower_pot",
|
||||||
"2251": "minecraft:potted_cactus",
|
"2251": "minecraft:flower_pot",
|
||||||
"2252": "minecraft:potted_cactus",
|
"2252": "minecraft:flower_pot",
|
||||||
"2253": "minecraft:potted_cactus",
|
"2253": "minecraft:flower_pot",
|
||||||
"2254": "minecraft:potted_cactus",
|
"2254": "minecraft:flower_pot",
|
||||||
"2255": "minecraft:potted_cactus",
|
"2255": "minecraft:flower_pot",
|
||||||
"2256": "minecraft:carrots[age=0]",
|
"2256": "minecraft:carrots[age=0]",
|
||||||
"2257": "minecraft:carrots[age=1]",
|
"2257": "minecraft:carrots[age=1]",
|
||||||
"2258": "minecraft:carrots[age=2]",
|
"2258": "minecraft:carrots[age=2]",
|
||||||
@ -2170,6 +2170,22 @@
|
|||||||
"6720": "minecraft:lead",
|
"6720": "minecraft:lead",
|
||||||
"6736": "minecraft:name_tag",
|
"6736": "minecraft:name_tag",
|
||||||
"6752": "minecraft:command_block_minecart",
|
"6752": "minecraft:command_block_minecart",
|
||||||
|
"6800": "minecraft:black_banner",
|
||||||
|
"6801": "minecraft:red_banner",
|
||||||
|
"6802": "minecraft:green_banner",
|
||||||
|
"6803": "minecraft:brown_banner",
|
||||||
|
"6804": "minecraft:blue_banner",
|
||||||
|
"6805": "minecraft:purple_banner",
|
||||||
|
"6806": "minecraft:cyan_banner",
|
||||||
|
"6807": "minecraft:light_gray_banner",
|
||||||
|
"6808": "minecraft:gray_banner",
|
||||||
|
"6809": "minecraft:pink_banner",
|
||||||
|
"6810": "minecraft:lime_banner",
|
||||||
|
"6811": "minecraft:yellow_banner",
|
||||||
|
"6812": "minecraft:light_blue_banner",
|
||||||
|
"6813": "minecraft:magenta_banner",
|
||||||
|
"6814": "minecraft:orange_banner",
|
||||||
|
"6815": "minecraft:white_banner",
|
||||||
"36096": "minecraft:music_disc_13",
|
"36096": "minecraft:music_disc_13",
|
||||||
"36112": "minecraft:music_disc_cat",
|
"36112": "minecraft:music_disc_cat",
|
||||||
"36128": "minecraft:music_disc_blocks",
|
"36128": "minecraft:music_disc_blocks",
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren