forked from GeyserMC/Geyser
Fix block entities on older versions (#756)
* Fix block entities on older versions This commit solves two problems related to block entities on older versions: - Occasionally, tags would contain the ID under a StringTag with an empty value, and not the ID tag. - The block entity regex did not account for block entity tags that were already in a Bedrock-compatible format (BlockEntity) * Move BLOCK_ENTITY_TRANSLATIONS to BlockEntityTranslator
This commit is contained in:
parent
34b367bfc3
commit
7fcd8f2daf
3 changed files with 42 additions and 20 deletions
|
@ -46,6 +46,19 @@ public abstract class BlockEntityTranslator {
|
||||||
public static final Map<String, BlockEntityTranslator> BLOCK_ENTITY_TRANSLATORS = new HashMap<>();
|
public static final Map<String, BlockEntityTranslator> BLOCK_ENTITY_TRANSLATORS = new HashMap<>();
|
||||||
public static ObjectArrayList<RequiresBlockState> REQUIRES_BLOCK_STATE_LIST = new ObjectArrayList<>();
|
public static ObjectArrayList<RequiresBlockState> REQUIRES_BLOCK_STATE_LIST = new ObjectArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains a list of irregular block entity name translations that can't be fit into the regex
|
||||||
|
*/
|
||||||
|
public static final Map<String, String> BLOCK_ENTITY_TRANSLATIONS = new HashMap<String, String>() {
|
||||||
|
{
|
||||||
|
// Bedrock/Java differences
|
||||||
|
put("minecraft:enchanting_table", "EnchantTable");
|
||||||
|
put("minecraft:piston_head", "PistonArm");
|
||||||
|
put("minecraft:trapped_chest", "Chest");
|
||||||
|
// There are some legacy IDs sent but as far as I can tell they are not needed for things to work properly
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
protected BlockEntityTranslator() {
|
protected BlockEntityTranslator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,29 +12,24 @@ public class BlockEntityUtils {
|
||||||
|
|
||||||
public static String getBedrockBlockEntityId(String id) {
|
public static String getBedrockBlockEntityId(String id) {
|
||||||
// These are the only exceptions when it comes to block entity ids
|
// These are the only exceptions when it comes to block entity ids
|
||||||
if (id.contains("piston_head"))
|
if (BlockEntityTranslator.BLOCK_ENTITY_TRANSLATIONS.containsKey(id)) {
|
||||||
return "PistonArm";
|
return BlockEntityTranslator.BLOCK_ENTITY_TRANSLATIONS.get(id);
|
||||||
|
|
||||||
if (id.contains("trapped_chest"))
|
|
||||||
return "Chest";
|
|
||||||
|
|
||||||
if (id.contains("EnderChest"))
|
|
||||||
return "EnderChest";
|
|
||||||
|
|
||||||
if (id.contains("enchanting_table")) {
|
|
||||||
return "EnchantTable";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id = id.toLowerCase()
|
id = id.replace("minecraft:", "")
|
||||||
.replace("minecraft:", "")
|
|
||||||
.replace("_", " ");
|
.replace("_", " ");
|
||||||
String[] words = id.split(" ");
|
// Split at every space or capital letter - for the latter, some legacy Java block entity tags are the correct format already
|
||||||
|
String[] words;
|
||||||
|
if (!id.toUpperCase().equals(id)) { // Otherwise we get [S, K, U, L, L]
|
||||||
|
words = id.split("(?=[A-Z])| "); // Split at every space or note or before every capital letter
|
||||||
|
} else {
|
||||||
|
words = id.split(" ");
|
||||||
|
}
|
||||||
for (int i = 0; i < words.length; i++) {
|
for (int i = 0; i < words.length; i++) {
|
||||||
words[i] = words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase();
|
words[i] = words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
id = String.join(" ", words);
|
return String.join("", words);
|
||||||
return id.replace(" ", "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockEntityTranslator getBlockEntityTranslator(String name) {
|
public static BlockEntityTranslator getBlockEntityTranslator(String name) {
|
||||||
|
|
|
@ -30,6 +30,8 @@ import com.github.steveice10.mc.protocol.data.game.chunk.Column;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
|
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||||
import com.nukkitx.math.vector.Vector2i;
|
import com.nukkitx.math.vector.Vector2i;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.nbt.CompoundTagBuilder;
|
import com.nukkitx.nbt.CompoundTagBuilder;
|
||||||
|
@ -137,11 +139,23 @@ public class ChunkUtils {
|
||||||
while (i < blockEntities.length) {
|
while (i < blockEntities.length) {
|
||||||
CompoundTag tag = blockEntities[i];
|
CompoundTag tag = blockEntities[i];
|
||||||
String tagName;
|
String tagName;
|
||||||
if (!tag.contains("id")) {
|
if (tag.contains("id")) {
|
||||||
GeyserConnector.getInstance().getLogger().debug("Got tag with no id: " + tag.getValue());
|
|
||||||
tagName = "Empty";
|
|
||||||
} else {
|
|
||||||
tagName = (String) tag.get("id").getValue();
|
tagName = (String) tag.get("id").getValue();
|
||||||
|
} else {
|
||||||
|
tagName = "Empty";
|
||||||
|
// Sometimes legacy tags have their ID be a StringTag with empty value
|
||||||
|
for (Tag subTag : tag) {
|
||||||
|
if (subTag instanceof StringTag) {
|
||||||
|
StringTag stringTag = (StringTag) subTag;
|
||||||
|
if (stringTag.getValue().equals("")) {
|
||||||
|
tagName = stringTag.getName();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tagName.equals("Empty")) {
|
||||||
|
GeyserConnector.getInstance().getLogger().debug("Got tag with no id: " + tag.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String id = BlockEntityUtils.getBedrockBlockEntityId(tagName);
|
String id = BlockEntityUtils.getBedrockBlockEntityId(tagName);
|
||||||
|
|
Loading…
Reference in a new issue