From f2f59e4e3775dff8a24e01dbedca59634027e188 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sun, 28 Jun 2020 23:44:38 -0400 Subject: [PATCH 01/17] Fill in renamed villager trading values (villager trading UI now opens) --- .../translators/java/world/JavaTradeListTranslator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java index 7c80d104b58..d9d23f32351 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java @@ -70,9 +70,9 @@ public void translate(ServerTradeListPacket packet, GeyserSession session) { displayName = packet.isRegularVillager() ? "Villager" : "Wandering Trader"; } updateTradePacket.setDisplayName(displayName); - //updateTradePacket.setUnknownInt(0); //TODO -// updateTradePacket.setScreen2(true); -// updateTradePacket.setWilling(true); + updateTradePacket.setSize(0); + updateTradePacket.setNewTradingUi(true); + updateTradePacket.setUsingEconomyTrade(true); updateTradePacket.setPlayerUniqueEntityId(session.getPlayerEntity().getGeyserId()); updateTradePacket.setTraderUniqueEntityId(session.getPlayerEntity().getGeyserId()); CompoundTagBuilder builder = CompoundTagBuilder.builder(); From 70009c4bf96e20274454b207416b57eacf1bafc8 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 29 Jun 2020 13:50:16 +0100 Subject: [PATCH 02/17] Clean chat code and fix skins --- connector/pom.xml | 2 +- .../connector/utils/MessageUtils.java | 19 +++++++------------ .../geysermc/connector/utils/SkinUtils.java | 1 + 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index ddc62bf2a17..09171248ae4 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -105,7 +105,7 @@ com.github.GeyserMC MCProtocolLib - feature~1.16-1.12.1-1-g74ee57a-310 + feature~1.16-1.12.1-1-ge4798a3-318 compile diff --git a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java index 96775f24578..3a35782d4da 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -32,6 +32,7 @@ import com.github.steveice10.mc.protocol.data.message.TranslationMessage; import com.github.steveice10.mc.protocol.data.message.style.ChatColor; import com.github.steveice10.mc.protocol.data.message.style.ChatFormat; +import com.github.steveice10.mc.protocol.data.message.style.MessageStyle; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import net.kyori.text.Component; @@ -216,25 +217,19 @@ private static Message fixMessageStyle(Message message, Message parent) { if (parent == null) { return message; } - Message newMessage = message; + MessageStyle.Builder styleBuilder = message.getStyle().toBuilder(); // Copy color from parent - if (newMessage.getStyle().getColor() == ChatColor.NONE) { - JsonObject messageObject = MessageSerializer.toJsonObject(newMessage); - messageObject.addProperty("color", parent.getStyle().getColor()); - newMessage = MessageSerializer.fromJson(messageObject); + if (message.getStyle().getColor() == ChatColor.NONE) { + styleBuilder.color(parent.getStyle().getColor()); } // Copy formatting from parent - if (newMessage.getStyle().getFormats().size() == 0) { - JsonObject messageObject = MessageSerializer.toJsonObject(newMessage); - for(ChatFormat format : parent.getStyle().getFormats()) { - messageObject.addProperty(format.toString(), true); - } - newMessage = MessageSerializer.fromJson(messageObject); + if (message.getStyle().getFormats().size() == 0) { + styleBuilder.formats(parent.getStyle().getFormats()); } - return newMessage; + return message.toBuilder().style(styleBuilder.build()).build(); } public static String getBedrockMessage(Message message) { diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java index ae17ed20558..9e071247769 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -96,6 +96,7 @@ public static PlayerListPacket.Entry buildEntryManually(UUID uuid, String userna entry.setXuid(""); entry.setPlatformChatId(""); entry.setTeacher(false); + entry.setTrustedSkin(true); return entry; } From 91c33242c6f91122a915f67ac6f5ee5a06052b11 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 29 Jun 2020 14:40:06 +0100 Subject: [PATCH 03/17] Fix baby states and collisions of 1.16 mobs --- .../entity/living/animal/StriderEntity.java | 1 - .../entity/living/monster/HoglinEntity.java | 52 +++++++++++++++++++ .../entity/living/monster/ZoglinEntity.java | 36 +++++++++++++ .../connector/entity/type/EntityType.java | 10 ++-- 4 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java index 18bb8166e6f..abf6758a2e5 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java @@ -40,7 +40,6 @@ public StriderEntity(long entityId, long geyserId, EntityType entityType, Vector @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getId() == 18) { metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java new file mode 100644 index 00000000000..10faebc7835 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.entity.living.monster; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +public class HoglinEntity extends MonsterEntity { + + public HoglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + if (entityMetadata.getId() == 15) { + boolean isBaby = (boolean) entityMetadata.getValue(); + if (isBaby) { + metadata.put(EntityData.SCALE, .55f); + metadata.getFlags().setFlag(EntityFlag.BABY, true); + } + } + super.updateBedrockMetadata(entityMetadata, session); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java new file mode 100644 index 00000000000..b60a39521ed --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.entity.living.monster; + +import com.nukkitx.math.vector.Vector3f; +import org.geysermc.connector.entity.type.EntityType; + +public class ZoglinEntity extends HoglinEntity { + + public ZoglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java index 4ec3471c712..70c76038de6 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java +++ b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java @@ -68,7 +68,7 @@ public enum EntityType { CREEPER(CreeperEntity.class, 33, 1.7f, 0.6f, 0.6f, 1.62f), SKELETON(AbstractSkeletonEntity.class, 34, 1.8f, 0.6f, 0.6f, 1.62f), SPIDER(SpiderEntity.class, 35, 0.9f, 1.4f, 1.4f, 1f), - ZOMBIFIED_PIGLIN(MonsterEntity.class, 0, 1.8f, 0.6f, 0.6f, 1.62f, "minecraft:zombie_pigman"), + ZOMBIFIED_PIGLIN(ZombieEntity.class, 36, 1.95f, 0.6f, 0.6f, 1.62f, "minecraft:zombie_pigman"), SLIME(SlimeEntity.class, 37, 0.51f), ENDERMAN(EndermanEntity.class, 38, 2.9f, 0.6f), SILVERFISH(MonsterEntity.class, 39, 0.3f, 0.4f), @@ -151,10 +151,10 @@ public enum EntityType { PANDA(PandaEntity.class, 113, 1.25f, 1.125f, 1.825f), FOX(FoxEntity.class, 121, 0.5f, 1.25f), BEE(BeeEntity.class, 122, 0.6f, 0.6f), - STRIDER(StriderEntity.class, 0, 1.7f, 0.9f, 0f, 0f, "minecraft:strider"), //TODO - update entity metadata - HOGLIN(AnimalEntity.class, 0, 0.9f, 0.9f, 0f, 0f, "minecraft:hoglin"), //TODO - ZOGLIN(MonsterEntity.class, 0, 0.9f, 0.9f, 0f, 0f, "minecraft:zoglin"), //TODO - PIGLIN(MonsterEntity.class, 0, 1.9f, 0.6f, 0f, 0f, "minecraft:piglin"), //TODO + STRIDER(StriderEntity.class, 125, 1.7f, 0.9f, 0f, 0f, "minecraft:strider"), //TODO - update entity metadata + HOGLIN(HoglinEntity.class, 124, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:hoglin"), //TODO + ZOGLIN(ZoglinEntity.class, 126, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:zoglin"), //TODO + PIGLIN(ZombieEntity.class, 123, 1.95f, 0.6f, 0.6f, 0f, "minecraft:piglin"), //TODO /** * Item frames are handled differently since they are a block in Bedrock. From d394cc6280ca0a3c7e4e9cc9feee6d968a765554 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 29 Jun 2020 15:37:54 +0100 Subject: [PATCH 04/17] Update entity metadata --- .../entity/living/animal/StriderEntity.java | 3 +++ .../{HoglinEntity.java => PiglinEntity.java} | 11 +++++++++-- .../entity/living/monster/ZoglinEntity.java | 18 +++++++++++++++++- .../connector/entity/type/EntityType.java | 4 ++-- 4 files changed, 31 insertions(+), 5 deletions(-) rename connector/src/main/java/org/geysermc/connector/entity/living/monster/{HoglinEntity.java => PiglinEntity.java} (84%) diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java index abf6758a2e5..e3ef9b501bb 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java @@ -40,6 +40,9 @@ public StriderEntity(long entityId, long geyserId, EntityType entityType, Vector @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + if (entityMetadata.getId() == 17) { + metadata.getFlags().setFlag(EntityFlag.ALWAYS_SHOW_NAME, (boolean) entityMetadata.getValue()); + } if (entityMetadata.getId() == 18) { metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java similarity index 84% rename from connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java rename to connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java index 10faebc7835..78a420b8c40 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java @@ -32,9 +32,9 @@ import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; -public class HoglinEntity extends MonsterEntity { +public class PiglinEntity extends MonsterEntity { - public HoglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + public PiglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } @@ -47,6 +47,13 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s metadata.getFlags().setFlag(EntityFlag.BABY, true); } } + if (entityMetadata.getId() == 17) { + metadata.getFlags().setFlag(EntityFlag.CHARGING, (boolean) entityMetadata.getValue()); + } + if (entityMetadata.getId() == 18) { + metadata.getFlags().setFlag(EntityFlag.DANCING, (boolean) entityMetadata.getValue()); + } + super.updateBedrockMetadata(entityMetadata, session); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java index b60a39521ed..4ea842110b6 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java @@ -25,12 +25,28 @@ package org.geysermc.connector.entity.living.monster; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; -public class ZoglinEntity extends HoglinEntity { +public class ZoglinEntity extends MonsterEntity { public ZoglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + if (entityMetadata.getId() == 15) { + boolean isBaby = (boolean) entityMetadata.getValue(); + if (isBaby) { + metadata.put(EntityData.SCALE, .55f); + metadata.getFlags().setFlag(EntityFlag.BABY, true); + } + } + super.updateBedrockMetadata(entityMetadata, session); + } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java index 70c76038de6..1acf579f1b2 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java +++ b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java @@ -152,9 +152,9 @@ public enum EntityType { FOX(FoxEntity.class, 121, 0.5f, 1.25f), BEE(BeeEntity.class, 122, 0.6f, 0.6f), STRIDER(StriderEntity.class, 125, 1.7f, 0.9f, 0f, 0f, "minecraft:strider"), //TODO - update entity metadata - HOGLIN(HoglinEntity.class, 124, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:hoglin"), //TODO + HOGLIN(AnimalEntity.class, 124, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:hoglin"), //TODO ZOGLIN(ZoglinEntity.class, 126, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:zoglin"), //TODO - PIGLIN(ZombieEntity.class, 123, 1.95f, 0.6f, 0.6f, 0f, "minecraft:piglin"), //TODO + PIGLIN(PiglinEntity.class, 123, 1.95f, 0.6f, 0.6f, 0f, "minecraft:piglin"), //TODO /** * Item frames are handled differently since they are a block in Bedrock. From e77f2b5dbbbcbedcff3c96e416acaa07c000a5ca Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 29 Jun 2020 10:59:51 -0800 Subject: [PATCH 05/17] Drop long array nbt tag when translating to bedrock --- .../connector/network/translators/item/ItemTranslator.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index 6f11e94ac5e..aa75e1499fe 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -253,8 +253,10 @@ private Tag translateToBedrockNBT(com.github.steveice10.opennbt.tag.builtin.T } if (tag instanceof LongArrayTag) { - LongArrayTag longArrayTag = (LongArrayTag) tag; - return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue()); + //Long array tag does not exist in BE + //LongArrayTag longArrayTag = (LongArrayTag) tag; + //return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue()); + return null; } if (tag instanceof LongTag) { From ebc1f13e9b775bc103e36279d6d0e777c4f8e7ca Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 29 Jun 2020 16:03:54 -0400 Subject: [PATCH 06/17] Update dependencies ('item marked as non-null' error is fixed') --- connector/pom.xml | 2 +- connector/src/main/resources/mappings | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index 09171248ae4..b4816361f32 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -105,7 +105,7 @@ com.github.GeyserMC MCProtocolLib - feature~1.16-1.12.1-1-ge4798a3-318 + feature~1.16-1.12.1-1-g10bb8e2-319 compile diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 204c8f8dfdb..fdc65607994 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 204c8f8dfdb1e39b881986c4968aa2575fbb5400 +Subproject commit fdc65607994b924261f43170f4d4d563b14167d7 From fc4a87a9c902e7c63d4539930060788f1fbfcc74 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 29 Jun 2020 16:46:29 -0400 Subject: [PATCH 07/17] Fix blocks not updating --- .../src/main/java/org/geysermc/connector/utils/ChunkUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java index 9cab8605de5..5c426cb9b28 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -211,6 +211,7 @@ public static void updateBlock(GeyserSession session, int blockState, Vector3i p updateBlockPacket.setBlockPosition(position); updateBlockPacket.setRuntimeId(blockId); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); session.sendUpstreamPacket(updateBlockPacket); UpdateBlockPacket waterPacket = new UpdateBlockPacket(); From 4c89a8e30319631e2f3d0024b2b7739adc7886d2 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 29 Jun 2020 17:52:59 -0400 Subject: [PATCH 08/17] Return to using Protocol develop branch --- connector/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index b4816361f32..70ad0e26db6 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -31,9 +31,9 @@ compile - com.github.bundabrg.Protocol + com.nukkitx.protocol bedrock-v407 - feature~1.16-protocol-SNAPSHOT + 2.6.0-SNAPSHOT compile From 7710261b70d864429edcb887254f20be60ffc4ff Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 30 Jun 2020 00:52:32 +0100 Subject: [PATCH 09/17] Add Loadstone Compass tracking --- ...tionTrackingDBClientRequestTranslator.java | 82 ++++++++++++ .../translators/item/ItemRegistry.java | 3 + .../item/translators/CompassTranslator.java | 121 ++++++++++++++++++ .../connector/utils/LoadstoneTracker.java | 84 ++++++++++++ 4 files changed, 290 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/utils/LoadstoneTracker.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java new file mode 100644 index 00000000000..1ca467206e6 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + * + */ + +package org.geysermc.connector.network.translators.bedrock; + +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.IntTag; +import com.nukkitx.protocol.bedrock.packet.PositionTrackingDBClientRequestPacket; +import com.nukkitx.protocol.bedrock.packet.PositionTrackingDBServerBroadcastPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; +import org.geysermc.connector.utils.DimensionUtils; +import org.geysermc.connector.utils.LoadstoneTracker; + +import java.util.ArrayList; +import java.util.List; + +@Translator(packet = PositionTrackingDBClientRequestPacket.class) +public class BedrockPositionTrackingDBClientRequestTranslator extends PacketTranslator { + + @Override + public void translate(PositionTrackingDBClientRequestPacket packet, GeyserSession session) { + PositionTrackingDBServerBroadcastPacket broadcastPacket = new PositionTrackingDBServerBroadcastPacket(); + broadcastPacket.setTrackingId(packet.getTrackingId()); + + // Fetch the stored Loadstone + LoadstoneTracker.LoadstonePos pos = LoadstoneTracker.getPos(packet.getTrackingId()); + + // If we don't have data for that ID tell the client its not found + if (pos == null) { + broadcastPacket.setAction(PositionTrackingDBServerBroadcastPacket.Action.NOT_FOUND); + session.sendUpstreamPacket(broadcastPacket); + return; + } + + broadcastPacket.setAction(PositionTrackingDBServerBroadcastPacket.Action.UPDATE); + + // Build the nbt data for the update + CompoundTagBuilder builder = CompoundTagBuilder.builder(); + builder.intTag("dim", DimensionUtils.javaToBedrock(pos.getDimension())); + builder.stringTag("id", String.format("%08X", packet.getTrackingId())); + + builder.byteTag("version", (byte) 1); // Not sure what this is for + builder.byteTag("status", (byte) 0); // Not sure what this is for + + // Build the position for the update + List posList = new ArrayList<>(); + posList.add(new IntTag("", pos.getX())); + posList.add(new IntTag("", pos.getY())); + posList.add(new IntTag("", pos.getZ())); + + builder.listTag("pos", IntTag.class, posList); + + broadcastPacket.setTag(builder.buildRootTag()); + + session.sendUpstreamPacket(broadcastPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index db5bc1b34ba..2dbc945c3d9 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -133,6 +133,9 @@ public static void init() { itemIndex++; } + // Add the loadstonecompass since it doesn't exist on java but we need it for item conversion + ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestonecompass", itemIndex, 741, 0, false)); + /* Load creative items */ stream = FileUtils.getResource("bedrock/creative_items.json"); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java new file mode 100644 index 00000000000..675d42555c0 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.item.translators; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.opennbt.tag.builtin.*; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.connector.network.translators.ItemRemapper; +import org.geysermc.connector.network.translators.item.ItemEntry; +import org.geysermc.connector.network.translators.item.ItemRegistry; +import org.geysermc.connector.network.translators.item.ItemTranslator; +import org.geysermc.connector.utils.LoadstoneTracker; + +import java.util.List; +import java.util.stream.Collectors; + +@ItemRemapper +public class CompassTranslator extends ItemTranslator { + + private List appliedItems; + + public CompassTranslator() { + appliedItems = ItemRegistry.ITEM_ENTRIES.values().stream().filter(entry -> entry.getJavaIdentifier().endsWith("compass")).collect(Collectors.toList()); + } + + @Override + public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry); + + Tag lodestoneTag = itemStack.getNbt().get("LodestoneTracked"); + if (lodestoneTag instanceof ByteTag) { + // Get the fake lodestonecompass entry + itemEntry = ItemRegistry.getItemEntry("minecraft:lodestonecompass"); + + // Get the loadstone pos + CompoundTag loadstonePos = itemStack.getNbt().get("LodestonePos"); + if (loadstonePos != null) { + // Get all info needed for tracking + int x = ((IntTag) loadstonePos.get("X")).getValue(); + int y = ((IntTag) loadstonePos.get("Y")).getValue(); + int z = ((IntTag) loadstonePos.get("Z")).getValue(); + String dim = ((StringTag) itemStack.getNbt().get("LodestoneDimension")).getValue(); + + // Store the info + int trackID = LoadstoneTracker.store(x, y, z, dim); + + // Set the bedrock tracking id + itemStack.getNbt().put(new IntTag("trackingHandle", trackID)); + } else { + // The loadstone was removed just set the tracking id to 0 + itemStack.getNbt().put(new IntTag("trackingHandle", 0)); + } + } + + ItemData itemData = super.translateToBedrock(itemStack, itemEntry); + + return itemData; + } + + @Override + public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) { + boolean isLoadstone = false; + if (itemEntry.getJavaIdentifier().equals("minecraft:lodestonecompass")) { + // Revert the entry back to the compass + itemEntry = ItemRegistry.getItemEntry("minecraft:compass"); + + isLoadstone = true; + } + + ItemStack itemStack = super.translateToJava(itemData, itemEntry); + + if (isLoadstone) { + // Get the tracking id + int trackingID = ((IntTag) itemStack.getNbt().get("trackingHandle")).getValue(); + + // Fetch the tracking info from the id + LoadstoneTracker.LoadstonePos pos = LoadstoneTracker.getPos(trackingID); + if (pos != null) { + // Build the new NBT data for the fetched tracking info + itemStack.getNbt().put(new StringTag("LodestoneDimension", pos.getDimension())); + + CompoundTag posTag = new CompoundTag("LodestonePos"); + posTag.put(new IntTag("X", pos.getX())); + posTag.put(new IntTag("Y", pos.getY())); + posTag.put(new IntTag("Z", pos.getZ())); + + itemStack.getNbt().put(posTag); + } + } + + return itemStack; + } + + @Override + public List getAppliedItems() { + return appliedItems; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/LoadstoneTracker.java b/connector/src/main/java/org/geysermc/connector/utils/LoadstoneTracker.java new file mode 100644 index 00000000000..3bd547654a8 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/LoadstoneTracker.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + * + */ + +package org.geysermc.connector.utils; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +public class LoadstoneTracker { + + private static final Int2ObjectMap LOADSTONES = new Int2ObjectOpenHashMap<>(); + + /** + * Store the given coordinates and dimensions + * + * @param x The X position of the Loadstone + * @param y The Y position of the Loadstone + * @param z The Z position of the Loadstone + * @param dim The dimension containing of the Loadstone + * @return The id in the Map + */ + public static int store(int x, int y, int z, String dim) { + LoadstonePos pos = new LoadstonePos(x, y, z, dim); + + if (!LOADSTONES.containsValue(pos)) { + // Start at 1 as 0 seems to not work + LOADSTONES.put(LOADSTONES.size() + 1, pos); + } + + for (Int2ObjectMap.Entry loadstone : LOADSTONES.int2ObjectEntrySet()) { + if (loadstone.getValue().equals(pos)) { + return loadstone.getIntKey(); + } + } + + return 0; + } + + /** + * Get the loadstone data + * + * @param id The ID to get the data for + * @return The stored data + */ + public static LoadstonePos getPos(int id) { + return LOADSTONES.get(id); + } + + @Getter + @AllArgsConstructor + @EqualsAndHashCode + public static class LoadstonePos { + int x; + int y; + int z; + String dimension; + } +} \ No newline at end of file From 95144266d268e50e4cc80a06b14702d3a156394b Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 29 Jun 2020 16:34:07 -0800 Subject: [PATCH 10/17] Handle int tag for enchantment level --- .../item/translators/nbt/EnchantmentTranslator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java index 404d7824c87..b4846f5c6d8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java @@ -122,7 +122,7 @@ public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) { private CompoundTag remapEnchantment(CompoundTag tag) { Tag javaEnchLvl = tag.get("lvl"); - if (!(javaEnchLvl instanceof ShortTag)) + if (!(javaEnchLvl instanceof ShortTag || javaEnchLvl instanceof IntTag)) return null; Tag javaEnchId = tag.get("id"); @@ -137,7 +137,7 @@ private CompoundTag remapEnchantment(CompoundTag tag) { CompoundTag bedrockTag = new CompoundTag(""); bedrockTag.put(new ShortTag("id", (short) enchantment.ordinal())); - bedrockTag.put(new ShortTag("lvl", ((ShortTag) javaEnchLvl).getValue())); + bedrockTag.put(new ShortTag("lvl", ((Number) javaEnchLvl.getValue()).shortValue())); return bedrockTag; } From eb3bde15a76ea25414419593732d0896b41e56d4 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 29 Jun 2020 16:54:19 -0800 Subject: [PATCH 11/17] Fix stored enchantments accidentally being dropped --- .../translators/item/translators/nbt/EnchantmentTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java index b4846f5c6d8..6bd9cc77ed3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java @@ -114,7 +114,7 @@ public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) { itemTag.put(new ListTag("Enchantments", enchantments)); } if (!storedEnchantments.isEmpty()) { - itemTag.put(new ListTag("StoredEnchantments", enchantments)); + itemTag.put(new ListTag("StoredEnchantments", storedEnchantments)); } itemTag.remove("ench"); } From ba6adc988be440639d2d717517c884404bdf274e Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 29 Jun 2020 21:33:42 -0400 Subject: [PATCH 12/17] Strider mounting fixes; update mappings This commit refactors health visual logic to make it a global system for each living entity. --- .../connector/entity/LivingEntity.java | 38 +++++++++++++++++++ .../entity/living/animal/PigEntity.java | 35 +---------------- .../animal/horse/AbstractHorseEntity.java | 37 ------------------ .../JavaEntitySetPassengersTranslator.java | 6 +++ connector/src/main/resources/mappings | 2 +- 5 files changed, 47 insertions(+), 71 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java index 3d1a1456f98..32aa343588b 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java @@ -27,15 +27,23 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.AttributeData; import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket; import com.nukkitx.protocol.bedrock.packet.MobEquipmentPacket; +import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket; import lombok.Getter; import lombok.Setter; +import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.AttributeUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; @Getter @Setter @@ -98,4 +106,34 @@ public void updateEquipment(GeyserSession session) { session.sendUpstreamPacket(handPacket); session.sendUpstreamPacket(offHandPacket); } + + @Override + public void updateBedrockAttributes(GeyserSession session) { + if (!valid) return; + + float maxHealth = this.attributes.containsKey(AttributeType.MAX_HEALTH) ? this.attributes.get(AttributeType.MAX_HEALTH).getValue() : getDefaultMaxHealth(); + + List attributes = new ArrayList<>(); + for (Map.Entry entry : this.attributes.entrySet()) { + if (!entry.getValue().getType().isBedrockAttribute()) + continue; + + attributes.add(AttributeUtils.getBedrockAttribute(entry.getValue())); + } + // Add health attribute to properly show hearts when mounting + attributes.add(new AttributeData("minecraft:health", 0.0f, maxHealth, metadata.getFloat(EntityData.HEALTH, 20f), maxHealth)); + + UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket(); + updateAttributesPacket.setRuntimeEntityId(geyserId); + updateAttributesPacket.setAttributes(attributes); + session.sendUpstreamPacket(updateAttributesPacket); + } + + /** + * Used for the health visual when mounting an entity. + * @return the default maximum health for the entity. + */ + protected float getDefaultMaxHealth() { + return 20f; + } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PigEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PigEntity.java index 0a7c83e7528..9b9701f8a68 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PigEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PigEntity.java @@ -27,33 +27,18 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.AttributeData; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; -import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket; -import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.utils.AttributeUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; public class PigEntity extends AnimalEntity { - // For updating the pig heart visual easier - private float health = 20f; - public PigEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getId() == 8) { - health = (float) entityMetadata.getValue(); - updateBedrockAttributes(session); - } if (entityMetadata.getId() == 16) { metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); @@ -62,23 +47,7 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s } @Override - public void updateBedrockAttributes(GeyserSession session) { - if (!valid) return; - - float maxHealth = attributes.containsKey(AttributeType.MAX_HEALTH) ? attributes.get(AttributeType.MAX_HEALTH).getValue() : 20f; - - List attributesLocal = new ArrayList<>(); - for (Map.Entry entry : this.attributes.entrySet()) { - if (!entry.getValue().getType().isBedrockAttribute()) - continue; - - attributesLocal.add(AttributeUtils.getBedrockAttribute(entry.getValue())); - } - attributesLocal.add(new AttributeData("minecraft:health", 0.0f, maxHealth, health, maxHealth)); - - UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket(); - updateAttributesPacket.setRuntimeEntityId(geyserId); - updateAttributesPacket.setAttributes(attributesLocal); - session.sendUpstreamPacket(updateAttributesPacket); + protected float getDefaultMaxHealth() { + return 10f; } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/AbstractHorseEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/AbstractHorseEntity.java index 48586c78fd6..e08f9adf001 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/AbstractHorseEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/AbstractHorseEntity.java @@ -27,24 +27,13 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.AttributeData; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; -import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket; -import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.living.animal.AnimalEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.utils.AttributeUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; public class AbstractHorseEntity extends AnimalEntity { - // For updating the horse visual easier - private float health = 20f; - public AbstractHorseEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } @@ -52,11 +41,6 @@ public AbstractHorseEntity(long entityId, long geyserId, EntityType entityType, @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getId() == 8) { - health = (float) entityMetadata.getValue(); - updateBedrockAttributes(session); - } - if (entityMetadata.getId() == 16) { byte xd = (byte) entityMetadata.getValue(); metadata.getFlags().setFlag(EntityFlag.TAMED, (xd & 0x02) == 0x02); @@ -71,25 +55,4 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s super.updateBedrockMetadata(entityMetadata, session); } - - @Override - public void updateBedrockAttributes(GeyserSession session) { - if (!valid) return; - - float maxHealth = attributes.containsKey(AttributeType.MAX_HEALTH) ? attributes.get(AttributeType.MAX_HEALTH).getValue() : 20f; - - List attributesLocal = new ArrayList<>(); - for (Map.Entry entry : this.attributes.entrySet()) { - if (!entry.getValue().getType().isBedrockAttribute()) - continue; - - attributesLocal.add(AttributeUtils.getBedrockAttribute(entry.getValue())); - } - attributesLocal.add(new AttributeData("minecraft:health", 0.0f, maxHealth, health, maxHealth)); - - UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket(); - updateAttributesPacket.setRuntimeEntityId(geyserId); - updateAttributesPacket.setAttributes(attributesLocal); - session.sendUpstreamPacket(updateAttributesPacket); - } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java index 8eab10f5a13..ec3ca8318fd 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java @@ -140,8 +140,14 @@ private void updateOffset(Entity passenger, EntityType mountType, GeyserSession case ARMOR_STAND: yOffset = 1.3f; break; + case STRIDER: + yOffset = 2.8200102f; + break; } Vector3f offset = Vector3f.from(0f, yOffset, 0f); + if (mountType == EntityType.STRIDER) { + offset = offset.add(0f, 0f, -0.2f); + } // Without the X offset, more than one entity on a boat is stacked on top of each other if (rider && moreThanOneEntity) { offset = offset.add(Vector3f.from(0.2, 0, 0)); diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index fdc65607994..668156d559b 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit fdc65607994b924261f43170f4d4d563b14167d7 +Subproject commit 668156d559be2c0e081950194342da7fb68f1543 From a9bb8745f5bf305c71d873f294eeb2d9c4ab2fff Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 30 Jun 2020 13:20:03 +0100 Subject: [PATCH 13/17] Fix Zombified Piglin fire flicker --- .../org/geysermc/connector/entity/Entity.java | 2 +- .../entity/living/animal/StriderEntity.java | 2 + .../living/monster/ZombifiedPiglinEntity.java | 39 +++++++++++++++++++ .../connector/entity/type/EntityType.java | 2 +- .../translators/item/ItemRegistry.java | 5 ++- 5 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombifiedPiglinEntity.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java index 4d4d097f04a..6ae9c67174d 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -260,7 +260,7 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s case 0: if (entityMetadata.getType() == MetadataType.BYTE) { byte xd = (byte) entityMetadata.getValue(); - metadata.getFlags().setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01); + metadata.getFlags().setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !metadata.getFlags().getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02); metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08); metadata.getFlags().setFlag(EntityFlag.SWIMMING, ((xd & 0x10) == 0x10) && metadata.getFlags().getFlag(EntityFlag.SPRINTING)); // Otherwise swimming is enabled on older servers diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java index e3ef9b501bb..9d8a6220bdb 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java @@ -36,6 +36,8 @@ public class StriderEntity extends AnimalEntity { public StriderEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); + + metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true); } @Override diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombifiedPiglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombifiedPiglinEntity.java new file mode 100644 index 00000000000..01693170abf --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombifiedPiglinEntity.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.entity.living.monster; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.connector.entity.type.EntityType; + +public class ZombifiedPiglinEntity extends ZombieEntity { + + public ZombifiedPiglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + + metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java index 1acf579f1b2..6bc1a1b0bdc 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java +++ b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java @@ -68,7 +68,7 @@ public enum EntityType { CREEPER(CreeperEntity.class, 33, 1.7f, 0.6f, 0.6f, 1.62f), SKELETON(AbstractSkeletonEntity.class, 34, 1.8f, 0.6f, 0.6f, 1.62f), SPIDER(SpiderEntity.class, 35, 0.9f, 1.4f, 1.4f, 1f), - ZOMBIFIED_PIGLIN(ZombieEntity.class, 36, 1.95f, 0.6f, 0.6f, 1.62f, "minecraft:zombie_pigman"), + ZOMBIFIED_PIGLIN(ZombifiedPiglinEntity.class, 36, 1.95f, 0.6f, 0.6f, 1.62f, "minecraft:zombie_pigman"), SLIME(SlimeEntity.class, 37, 0.51f), ENDERMAN(EndermanEntity.class, 38, 2.9f, 0.6f), SILVERFISH(MonsterEntity.class, 39, 0.3f, 0.4f), diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index 2dbc945c3d9..aebf1979751 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -198,7 +198,10 @@ public static ItemEntry getItem(ItemData data) { } } - GeyserConnector.getInstance().getLogger().debug("Missing mapping for bedrock item " + data.getId() + ":" + data.getDamage()); + // This will hide the message when the player clicks with an empty hand + if (data.getId() != 0 && data.getDamage() != 0) { + GeyserConnector.getInstance().getLogger().debug("Missing mapping for bedrock item " + data.getId() + ":" + data.getDamage()); + } return ItemEntry.AIR; } From e7fae53552127521870856dd7096e4eb2374be03 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 30 Jun 2020 13:51:44 +0100 Subject: [PATCH 14/17] Fix Strider shaking --- .../connector/entity/living/animal/StriderEntity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java index 9d8a6220bdb..bb4daf545ff 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java @@ -38,12 +38,14 @@ public StriderEntity(long entityId, long geyserId, EntityType entityType, Vector super(entityId, geyserId, entityType, position, motion, rotation); metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true); + metadata.getFlags().setFlag(EntityFlag.BREATHING, true); } @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getId() == 17) { - metadata.getFlags().setFlag(EntityFlag.ALWAYS_SHOW_NAME, (boolean) entityMetadata.getValue()); + metadata.getFlags().setFlag(EntityFlag.BREATHING, !(boolean) entityMetadata.getValue()); + metadata.getFlags().setFlag(EntityFlag.SHAKING, (boolean) entityMetadata.getValue()); } if (entityMetadata.getId() == 18) { metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); From 4c2a8789afae978b79af3fa5a1e3324aab751029 Mon Sep 17 00:00:00 2001 From: D3ATHBRINGER13 <53559772+D3ATHBRINGER13@users.noreply.github.com> Date: Tue, 30 Jun 2020 16:22:39 +0100 Subject: [PATCH 15/17] Update Bedrock Version (#868) * Update Bedrock Version * Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5cf34473de1..a22a7a8d073 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here! -### Currently supporting Minecraft Bedrock v1.16.0 and Minecraft Java v1.16.1. +### Currently supporting Minecraft Bedrock v1.16.0/1 and Minecraft Java v1.16.1. ## Setting Up Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser. From c804a6edfb4ccc1348ec18868dfdba9d135961a2 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 30 Jun 2020 17:08:22 +0100 Subject: [PATCH 16/17] Fix respawning and death not being registered on the client --- .../translators/java/JavaRespawnTranslator.java | 5 ++--- .../java/entity/JavaEntityStatusTranslator.java | 14 ++++++++++++++ .../JavaPlayerPositionRotationTranslator.java | 12 ++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java index 288389fa646..6d03380821f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java @@ -25,9 +25,11 @@ package org.geysermc.connector.network.translators.java; +import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; +import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.network.session.GeyserSession; @@ -35,9 +37,6 @@ import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.DimensionUtils; -import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; -import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; - import java.util.concurrent.ThreadLocalRandom; @Translator(packet = ServerRespawnPacket.class) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityStatusTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityStatusTranslator.java index 98089ff277d..0af473ff763 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityStatusTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityStatusTranslator.java @@ -28,11 +28,14 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityStatusPacket; import com.nukkitx.protocol.bedrock.data.entity.EntityEventType; import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; +import java.util.concurrent.TimeUnit; + @Translator(packet = ServerEntityStatusPacket.class) public class JavaEntityStatusTranslator extends PacketTranslator { @@ -99,5 +102,16 @@ public void translate(ServerEntityStatusPacket packet, GeyserSession session) { } session.sendUpstreamPacket(entityEventPacket); + + // This fixes some death events not getting registered on the client such as drowning + if (entityEventPacket.getType() == EntityEventType.DEATH) { + GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> { + EntityEventPacket eventPacket2 = new EntityEventPacket(); + eventPacket2.setRuntimeEntityId(entityEventPacket.getRuntimeEntityId()); + eventPacket2.setType(entityEventPacket.getType()); + eventPacket2.setData(entityEventPacket.getData()); + session.sendUpstreamPacket(eventPacket2); + }, 1, TimeUnit.MILLISECONDS); + } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java index 8b0b8201487..fae289e12ae 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java @@ -34,6 +34,7 @@ import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.RespawnPacket; import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -42,6 +43,8 @@ import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.ChunkUtils; +import java.util.concurrent.TimeUnit; + @Translator(packet = ServerPlayerPositionRotationPacket.class) public class JavaPlayerPositionRotationTranslator extends PacketTranslator { @@ -71,6 +74,15 @@ public void translate(ServerPlayerPositionRotationPacket packet, GeyserSession s eventPacket.setData(0); session.sendUpstreamPacket(eventPacket); + // This will prevent the client getting stuck at the respawn screen + GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> { + EntityEventPacket eventPacket2 = new EntityEventPacket(); + eventPacket2.setRuntimeEntityId(entity.getGeyserId()); + eventPacket2.setType(EntityEventType.RESPAWN); + eventPacket2.setData(0); + session.sendUpstreamPacket(eventPacket2); + }, 1, TimeUnit.MILLISECONDS); + SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); entityDataPacket.getMetadata().putAll(entity.getMetadata()); From 81651cfac5daa77f7377e6e9b3f7de36fa24b43e Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Tue, 30 Jun 2020 20:39:21 -0400 Subject: [PATCH 17/17] Add support for 3D biomes; fix Nether biome display --- .../network/translators/BiomeTranslator.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java index c12cc51361d..6f858eb501d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java @@ -70,24 +70,27 @@ public static byte[] toBedrockBiome(int[] biomeData) { return bedrockData; } - for (int z = 0; z < 16; z += 4) { - for (int x = 0; x < 16; x += 4) { - byte biomeId = biomeID(biomeData, x, z); - fillArray(z, x, bedrockData, biomeId); - fillArray(z + 1, x, bedrockData, biomeId); - fillArray(z + 2, x, bedrockData, biomeId); - fillArray(z + 3, x, bedrockData, biomeId); + for (int y = 0; y < 16; y += 4) { + for (int z = 0; z < 16; z += 4) { + for (int x = 0; x < 16; x += 4) { + byte biomeId = biomeID(biomeData, x, y, z); + int offset = ((z + (y / 4)) << 4) | x; + Arrays.fill(bedrockData, offset, offset + 4, biomeId); + } } } return bedrockData; } - private static void fillArray(int z, int x, byte[] legacyBiomeData, int biomeId) { - int offset = (z << 4) | x; - Arrays.fill(legacyBiomeData, offset, offset + 4, (byte) biomeId); - } - - private static byte biomeID(int[] biomeData, int x, int z) { - return (byte) biomeData[((z >> 2) & 3) << 2 | ((x >> 2) & 3)]; + private static byte biomeID(int[] biomeData, int x, int y, int z) { + int biomeId = biomeData[((y >> 2) & 63) << 4 | ((z >> 2) & 3) << 2 | ((x >> 2) & 3)]; + if (biomeId == 0) { + biomeId = 42; // Ocean + } else if (biomeId >= 40 && biomeId <= 43) { // Java has multiple End dimensions that Bedrock doesn't recognize + biomeId = 9; + } else if (biomeId >= 170) { // Nether biomes. Dunno why it's like this :microjang: + biomeId = biomeId + 8; + } + return (byte) biomeId; } }