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:
Camotoy 2020-06-10 19:02:29 -04:00 committed by GitHub
parent 34b367bfc3
commit 7fcd8f2daf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 20 deletions

View file

@ -46,6 +46,19 @@ public abstract class BlockEntityTranslator {
public static final Map<String, BlockEntityTranslator> BLOCK_ENTITY_TRANSLATORS = new HashMap<>();
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() {
}

View file

@ -12,29 +12,24 @@ public class BlockEntityUtils {
public static String getBedrockBlockEntityId(String id) {
// These are the only exceptions when it comes to block entity ids
if (id.contains("piston_head"))
return "PistonArm";
if (id.contains("trapped_chest"))
return "Chest";
if (id.contains("EnderChest"))
return "EnderChest";
if (id.contains("enchanting_table")) {
return "EnchantTable";
if (BlockEntityTranslator.BLOCK_ENTITY_TRANSLATIONS.containsKey(id)) {
return BlockEntityTranslator.BLOCK_ENTITY_TRANSLATIONS.get(id);
}
id = id.toLowerCase()
.replace("minecraft:", "")
id = id.replace("minecraft:", "")
.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++) {
words[i] = words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase();
}
id = String.join(" ", words);
return id.replace(" ", "");
return String.join("", words);
}
public static BlockEntityTranslator getBlockEntityTranslator(String name) {

View file

@ -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.world.block.BlockState;
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.Vector3i;
import com.nukkitx.nbt.CompoundTagBuilder;
@ -137,11 +139,23 @@ public class ChunkUtils {
while (i < blockEntities.length) {
CompoundTag tag = blockEntities[i];
String tagName;
if (!tag.contains("id")) {
GeyserConnector.getInstance().getLogger().debug("Got tag with no id: " + tag.getValue());
tagName = "Empty";
} else {
if (tag.contains("id")) {
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);