3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-12-26 00:00:28 +01:00

Handle changed block entities. Fixes banners,beds & flowerpots

Dieser Commit ist enthalten in:
Matsv 2018-01-06 15:23:49 +01:00
Ursprung ba70dae9ad
Commit 012aac97ee
13 geänderte Dateien mit 469 neuen und 33 gelöschten Zeilen

Datei anzeigen

@ -9,6 +9,8 @@ public interface ChunkSection {
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);
void writeBlocks(ByteBuf output) throws Exception;

Datei anzeigen

@ -3,7 +3,6 @@ package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks;
import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Getter;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
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);
}
/**
* 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) {
return getBlock(x, y, z) >> 4;
}

Datei anzeigen

@ -3,7 +3,7 @@ package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks;
import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
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.NibbleArray;
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);
}
@Override
public void setFlatBlock(int x, int y, int z, int type) {
throw new NotImplementedException();
}
public int getBlockId(int x, int y, int z) {
return getBlock(x, y, z) >> 4;
}

Datei anzeigen

@ -3,6 +3,7 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks;
import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
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.NibbleArray;
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);
}
@Override
public void setFlatBlock(int x, int y, int z, int type) {
throw new NotImplementedException();
}
public int getBlockId(int x, int y, int z) {
return getBlock(x, y, z) >> 4;
}

Datei anzeigen

@ -2,6 +2,7 @@ package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2;
import us.myles.ViaVersion.api.PacketWrapper;
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.remapper.PacketHandler;
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.InventoryPackets;
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.TabCompleteTracker;
@ -364,5 +367,11 @@ public class ProtocolSnapshotTo1_12_2 extends Protocol {
userConnection.put(new TabCompleteTracker(userConnection));
if (!userConnection.has(ClientWorld.class))
userConnection.put(new ClientWorld(userConnection));
userConnection.put(new BlockStorage(userConnection));
}
@Override
protected void register(ViaProviders providers) {
providers.register(BlockEntityProvider.class, new BlockEntityProvider());
}
}

Datei anzeigen

@ -94,7 +94,6 @@ public class EntityPackets {
int entityId = wrapper.get(Type.VAR_INT, 0);
Entity1_12Types.EntityType entType = Entity1_12Types.EntityType.PLAYER;
System.out.println("REGISTER PLAYER");
// Register Type ID
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_13.METADATA_LIST, 0), wrapper.user());

Datei anzeigen

@ -1,7 +1,11 @@
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.Via;
import us.myles.ViaVersion.api.data.UserConnection;
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.ChunkSection;
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_3to1_9_1_2.storage.ClientWorld;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.MappingData;
import java.util.List;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider;
import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage;
public class WorldPackets {
public static void register(Protocol protocol) {
// 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
protocol.registerOutgoing(State.PLAY, 0xB, 0xB, new PacketRemapper() {
@ -28,7 +58,10 @@ public class WorldPackets {
handler(new PacketHandler() {
@Override
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() {
@Override
public void registerMap() {
map(Type.INT);
map(Type.INT);
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
map(Type.INT); // 0 - Chunk X
map(Type.INT); // 1 - Chunk Z
map(Type.BLOCK_CHANGE_RECORD_ARRAY); // 2 - Records
handler(new PacketHandler() {
@Override
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
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
public void handle(PacketWrapper wrapper) throws Exception {
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);
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);
for (int i = 0; i < chunk.getSections().length; i++) {
ChunkSection section = chunk.getSections()[i];
if (section == null)
continue;
// TODO improve performance
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;
}
}

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -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();
}
}

Datei anzeigen

@ -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();
}
}

Datei anzeigen

@ -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;
}
}

Datei anzeigen

@ -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;
}
}

Datei anzeigen

@ -894,22 +894,22 @@
"2208": "minecraft:beacon",
"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]",
"2240": "minecraft:potted_cactus",
"2241": "minecraft:potted_cactus",
"2242": "minecraft:potted_cactus",
"2243": "minecraft:potted_cactus",
"2244": "minecraft:potted_cactus",
"2245": "minecraft:potted_cactus",
"2246": "minecraft:potted_cactus",
"2247": "minecraft:potted_cactus",
"2248": "minecraft:potted_cactus",
"2249": "minecraft:potted_cactus",
"2250": "minecraft:potted_cactus",
"2251": "minecraft:potted_cactus",
"2252": "minecraft:potted_cactus",
"2253": "minecraft:potted_cactus",
"2254": "minecraft:potted_cactus",
"2255": "minecraft:potted_cactus",
"2240": "minecraft:flower_pot",
"2241": "minecraft:flower_pot",
"2242": "minecraft:flower_pot",
"2243": "minecraft:flower_pot",
"2244": "minecraft:flower_pot",
"2245": "minecraft:flower_pot",
"2246": "minecraft:flower_pot",
"2247": "minecraft:flower_pot",
"2248": "minecraft:flower_pot",
"2249": "minecraft:flower_pot",
"2250": "minecraft:flower_pot",
"2251": "minecraft:flower_pot",
"2252": "minecraft:flower_pot",
"2253": "minecraft:flower_pot",
"2254": "minecraft:flower_pot",
"2255": "minecraft:flower_pot",
"2256": "minecraft:carrots[age=0]",
"2257": "minecraft:carrots[age=1]",
"2258": "minecraft:carrots[age=2]",
@ -2170,6 +2170,22 @@
"6720": "minecraft:lead",
"6736": "minecraft:name_tag",
"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",
"36112": "minecraft:music_disc_cat",
"36128": "minecraft:music_disc_blocks",