From 2f42a4c6308a5b736d0a40425642ea896c1205d0 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 31 Mar 2021 14:06:05 -0400 Subject: [PATCH 1/5] Add furnace minecart item translation (#2003) Conveniently enough, the minecart furnace icon still exists in the vanilla Bedrock Edition game (thanks to Kastle for this discovery). With this and the translation string still being present, we can add the item into the game with only minor issues. --- .../configuration/GeyserConfiguration.java | 2 + .../GeyserJacksonConfiguration.java | 3 + .../network/UpstreamPacketHandler.java | 7 ++ .../network/session/GeyserSession.java | 6 ++ .../translators/item/ItemRegistry.java | 73 ++++++++++++++++++- connector/src/main/resources/config.yml | 6 ++ 6 files changed, 95 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java index 6052bd283..0d879c401 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java @@ -81,6 +81,8 @@ public interface GeyserConfiguration { Path getFloodgateKeyPath(); + boolean isAddNonBedrockItems(); + boolean isAboveBedrockNetherBuilding(); boolean isCacheChunks(); diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java index 70aa3ff5d..cdc0ad239 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java @@ -115,6 +115,9 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration @JsonProperty("allow-custom-skulls") private boolean allowCustomSkulls = true; + @JsonProperty("add-non-bedrock-items") + private boolean addNonBedrockItems = true; + @JsonProperty("above-bedrock-nether-building") private boolean aboveBedrockNetherBuilding = false; diff --git a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java index c85bb773b..a30de4d07 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -27,6 +27,7 @@ package org.geysermc.connector.network; import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; +import com.nukkitx.protocol.bedrock.data.ExperimentData; import com.nukkitx.protocol.bedrock.data.ResourcePackType; import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.v428.Bedrock_v428; @@ -36,6 +37,7 @@ import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.cache.AdvancementsCache; import org.geysermc.connector.network.translators.PacketTranslatorRegistry; +import org.geysermc.connector.network.translators.item.ItemRegistry; import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_100; import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210; import org.geysermc.connector.utils.*; @@ -133,6 +135,11 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { stackPacket.getResourcePacks().add(new ResourcePackStackPacket.Entry(header.getUuid().toString(), header.getVersionString(), "")); } + if (ItemRegistry.FURNACE_MINECART_DATA != null) { + // Allow custom items to work + stackPacket.getExperiments().add(new ExperimentData("data_driven_items", true)); + } + session.sendUpstreamPacket(stackPacket); break; diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index de6fb94b5..436b6db11 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -464,6 +464,12 @@ public class GeyserSession implements CommandSender { // Set the hardcoded shield ID to the ID we just defined in StartGamePacket upstream.getSession().getHardcodedBlockingId().set(ItemRegistry.SHIELD.getBedrockId()); + if (ItemRegistry.FURNACE_MINECART_DATA != null) { + ItemComponentPacket componentPacket = new ItemComponentPacket(); + componentPacket.getItems().add(ItemRegistry.FURNACE_MINECART_DATA); + upstream.sendPacket(componentPacket); + } + ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false); BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket(); 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 c865a162a..be190f6ff 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 @@ -28,14 +28,19 @@ package org.geysermc.connector.network.translators.item; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.google.common.collect.ImmutableSet; import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; +import com.nukkitx.nbt.NbtType; import com.nukkitx.nbt.NbtUtils; +import com.nukkitx.protocol.bedrock.data.inventory.ComponentItemData; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; @@ -55,8 +60,7 @@ public class ItemRegistry { /** * A list of all identifiers that only exist on Java. Used to prevent creative items from becoming these unintentionally. */ - private static final List JAVA_ONLY_ITEMS = Arrays.asList("minecraft:spectral_arrow", "minecraft:debug_stick", - "minecraft:knowledge_book", "minecraft:tipped_arrow", "minecraft:furnace_minecart"); + private static final Set JAVA_ONLY_ITEMS; public static final ItemData[] CREATIVE_ITEMS; @@ -107,6 +111,11 @@ public class ItemRegistry { public static int BARRIER_INDEX = 0; + /** + * Stores the properties and data of the "custom" furnace minecart item. + */ + public static final ComponentItemData FURNACE_MINECART_DATA; + public static void init() { // no-op } @@ -150,9 +159,16 @@ public class ItemRegistry { } int itemIndex = 0; + int javaFurnaceMinecartId = 0; + boolean usingFurnaceMinecart = GeyserConnector.getInstance().getConfig().isAddNonBedrockItems(); Iterator> iterator = items.fields(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); + if (usingFurnaceMinecart && entry.getKey().equals("minecraft:furnace_minecart")) { + javaFurnaceMinecartId = itemIndex; + itemIndex++; + continue; + } int bedrockId = entry.getValue().get("bedrock_id").intValue(); String bedrockIdentifier = bedrockIdToIdentifier.get(bedrockId); if (bedrockIdentifier == null) { @@ -224,6 +240,9 @@ public class ItemRegistry { itemIndex++; } + itemNames.add("minecraft:furnace_minecart"); + itemNames.add("minecraft:spectral_arrow"); + if (lodestoneCompassId == 0) { throw new RuntimeException("Lodestone compass not found in item palette!"); } @@ -248,9 +267,59 @@ public class ItemRegistry { ItemData item = getBedrockItemFromJson(itemNode); creativeItems.add(ItemData.fromNet(netId++, item.getId(), item.getDamage(), item.getCount(), item.getTag())); } + + if (usingFurnaceMinecart) { + // Add the furnace minecart as an item + int furnaceMinecartId = ITEMS.size() + 1; + + ITEMS.add(new StartGamePacket.ItemEntry("geysermc:furnace_minecart", (short) furnaceMinecartId, true)); + ITEM_ENTRIES.put(javaFurnaceMinecartId, new ItemEntry("minecraft:furnace_minecart", "geysermc:furnace_minecart", javaFurnaceMinecartId, + furnaceMinecartId, 0, false, 1)); + creativeItems.add(ItemData.fromNet(netId, furnaceMinecartId, (short) 0, 1, null)); + + NbtMapBuilder builder = NbtMap.builder(); + builder.putString("name", "geysermc:furnace_minecart") + .putInt("id", furnaceMinecartId); + + NbtMapBuilder componentBuilder = NbtMap.builder(); + // Conveniently, as of 1.16.200, the furnace minecart has a texture AND translation string already. + componentBuilder.putCompound("minecraft:icon", NbtMap.builder().putString("texture", "minecart_furnace").build()); + componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", "item.minecartFurnace.name").build()); + + // Indicate that the arm animation should play on rails + List useOnTag = Collections.singletonList(NbtMap.builder().putString("tags", "q.any_tag('rail')").build()); + componentBuilder.putCompound("minecraft:entity_placer", NbtMap.builder() + .putList("dispense_on", NbtType.COMPOUND, useOnTag) + .putString("entity", "minecraft:minecart") + .putList("use_on", NbtType.COMPOUND, useOnTag) + .build()); + + NbtMapBuilder itemProperties = NbtMap.builder(); + // We always want to allow offhand usage when we can - matches Java Edition + itemProperties.putBoolean("allow_off_hand", true); + itemProperties.putBoolean("hand_equipped", false); + itemProperties.putInt("max_stack_size", 1); + itemProperties.putString("creative_group", "itemGroup.name.minecart"); + itemProperties.putInt("creative_category", 4); // 4 - "Items" + + componentBuilder.putCompound("item_properties", itemProperties.build()); + builder.putCompound("components", componentBuilder.build()); + FURNACE_MINECART_DATA = new ComponentItemData("geysermc:furnace_minecart", builder.build()); + } else { + FURNACE_MINECART_DATA = null; + } + CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]); ITEM_NAMES = itemNames.toArray(new String[0]); + + Set javaOnlyItems = new ObjectOpenHashSet<>(); + Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick", + "minecraft:knowledge_book", "minecraft:tipped_arrow"); + if (!usingFurnaceMinecart) { + javaOnlyItems.add("minecraft:furnace_minecart"); + } + JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems); } /** diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index ce202a3c1..847eded1a 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -139,6 +139,12 @@ cache-images: 0 # Allows custom skulls to be displayed. Keeping them enabled may cause a performance decrease on older/weaker devices. allow-custom-skulls: true +# Whether to add (at this time, only) the furnace minecart as a separate item in the game, which normally does not exist in Bedrock Edition. +# This should only need to be disabled if using a proxy that does not use the "transfer packet" style of server switching. +# If this is disabled, furnace minecart items will be mapped to hopper minecart items. +# This option requires a restart of Geyser in order to change its setting. +add-non-bedrock-items: true + # Bedrock prevents building and displaying blocks above Y127 in the Nether - # enabling this config option works around that by changing the Nether dimension ID # to the End ID. The main downside to this is that the sky will resemble that of From aa5c3c30e13f01ffd7a4418c298bcf7ba4a1ac9d Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 31 Mar 2021 14:15:55 -0400 Subject: [PATCH 2/5] Minor touchups (#2011) --- .../connector/network/session/GeyserSession.java | 10 ++++------ .../java/world/JavaPlayEffectTranslator.java | 8 +++----- .../org/geysermc/connector/utils/FireworkColor.java | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 436b6db11..ab01963eb 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -490,11 +490,10 @@ public class GeyserSession implements CommandSender { UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); attributesPacket.setRuntimeEntityId(getPlayerEntity().getGeyserId()); - List attributes = new ArrayList<>(); // Default move speed // Bedrock clients move very fast by default until they get an attribute packet correcting the speed - attributes.add(new AttributeData("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f)); - attributesPacket.setAttributes(attributes); + attributesPacket.setAttributes(Collections.singletonList( + new AttributeData("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f))); upstream.sendPacket(attributesPacket); GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket(); @@ -709,7 +708,7 @@ public class GeyserSession implements CommandSender { // Let the user know there locale may take some time to download // as it has to be extracted from a JAR - if (locale.toLowerCase().equals("en_us") && !LocaleUtils.LOCALE_MAPPINGS.containsKey("en_us")) { + if (locale.equalsIgnoreCase("en_us") && !LocaleUtils.LOCALE_MAPPINGS.containsKey("en_us")) { // This should probably be left hardcoded as it will only show for en_us clients sendMessage("Loading your locale (en_us); if this isn't already downloaded, this may take some time"); } @@ -1163,7 +1162,7 @@ public class GeyserSession implements CommandSender { noClip = gameMode == GameMode.SPECTATOR; worldImmutable = gameMode == GameMode.ADVENTURE || gameMode == GameMode.SPECTATOR; - Set flags = new HashSet<>(); + Set flags = adventureSettingsPacket.getSettings(); if (canFly) { flags.add(AdventureSetting.MAY_FLY); } @@ -1182,7 +1181,6 @@ public class GeyserSession implements CommandSender { flags.add(AdventureSetting.AUTO_JUMP); - adventureSettingsPacket.getSettings().addAll(flags); sendUpstreamPacket(adventureSettingsPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayEffectTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayEffectTranslator.java index f7285af2e..7f15213ca 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayEffectTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayEffectTranslator.java @@ -39,10 +39,10 @@ import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.effect.Effect; import org.geysermc.connector.network.translators.effect.EffectRegistry; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.utils.LocaleUtils; -import java.util.ArrayList; -import java.util.List; +import java.util.Collections; import java.util.Locale; @Translator(packet = ServerPlayEffectPacket.class) @@ -74,10 +74,8 @@ public class JavaPlayEffectTranslator extends PacketTranslator params = new ArrayList<>(); String recordString = "%item." + soundEvent.name().toLowerCase(Locale.ROOT) + ".desc"; - params.add(LocaleUtils.getLocaleString(recordString, session.getLocale())); - textPacket.setParameters(params); + textPacket.setParameters(Collections.singletonList(LocaleUtils.getLocaleString(recordString, session.getLocale()))); session.sendUpstreamPacket(textPacket); } return; diff --git a/connector/src/main/java/org/geysermc/connector/utils/FireworkColor.java b/connector/src/main/java/org/geysermc/connector/utils/FireworkColor.java index 36eda6adc..8846e477c 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/FireworkColor.java +++ b/connector/src/main/java/org/geysermc/connector/utils/FireworkColor.java @@ -69,9 +69,9 @@ public enum FireworkColor { private static final FireworkColor[] VALUES = values(); @Getter - private byte bedrockID; + private final byte bedrockID; @Getter - private int javaID; + private final int javaID; FireworkColor(byte bedrockID, int javaID) { this.bedrockID = bedrockID; From fb18a6493a0f5935176b85611081374503e1b825 Mon Sep 17 00:00:00 2001 From: ImDaBigBoss <67973871+ImDaBigBoss@users.noreply.github.com> Date: Thu, 1 Apr 2021 06:06:01 +0200 Subject: [PATCH 3/5] Add an option for actionbar hit cooldown (#2006) Co-authored-by: Camotoy <20743703+Camotoy@users.noreply.github.com> --- .../geysermc/connector/GeyserConnector.java | 2 +- .../configuration/GeyserConfiguration.java | 2 +- .../GeyserJacksonConfiguration.java | 2 +- .../connector/utils/CooldownUtils.java | 50 ++++++++++++++++--- connector/src/main/resources/config.yml | 3 +- connector/src/main/resources/mappings | 2 +- 6 files changed, 50 insertions(+), 11 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 26b07583b..ae6dbbe1d 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -187,7 +187,7 @@ public class GeyserConnector { defaultAuthType = AuthType.getByName(config.getRemote().getAuthType()); - CooldownUtils.setShowCooldown(config.isShowCooldown()); + CooldownUtils.setShowCooldown(config.getShowCooldown()); DimensionUtils.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether SkullBlockEntityTranslator.ALLOW_CUSTOM_SKULLS = config.isAllowCustomSkulls(); diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java index 0d879c401..652ec1339 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java @@ -73,7 +73,7 @@ public interface GeyserConfiguration { boolean isAllowThirdPartyEars(); - boolean isShowCooldown(); + String getShowCooldown(); boolean isShowCoordinates(); diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java index cdc0ad239..e9adfe12b 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java @@ -95,7 +95,7 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration private boolean allowThirdPartyCapes = true; @JsonProperty("show-cooldown") - private boolean showCooldown = true; + private String showCooldown = "title"; @JsonProperty("show-coordinates") private boolean showCoordinates = true; diff --git a/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java index 816b718aa..0b5c2bdd3 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java @@ -26,6 +26,7 @@ package org.geysermc.connector.utils; import com.nukkitx.protocol.bedrock.packet.SetTitlePacket; +import lombok.Getter; import org.geysermc.connector.network.session.GeyserSession; import java.util.concurrent.TimeUnit; @@ -35,10 +36,10 @@ import java.util.concurrent.TimeUnit; * Much of the work here is from the wonderful folks from ViaRewind: https://github.com/ViaVersion/ViaRewind */ public class CooldownUtils { - private static boolean SHOW_COOLDOWN; + private static CooldownType SHOW_COOLDOWN; - public static void setShowCooldown(boolean showCooldown) { - SHOW_COOLDOWN = showCooldown; + public static void setShowCooldown(String showCooldown) { + SHOW_COOLDOWN = CooldownType.getByName(showCooldown); } /** @@ -46,7 +47,7 @@ public class CooldownUtils { * @param session GeyserSession */ public static void sendCooldown(GeyserSession session) { - if (!SHOW_COOLDOWN) return; + if (SHOW_COOLDOWN == CooldownType.DISABLED) return; if (session.getAttackSpeed() == 0.0 || session.getAttackSpeed() > 20) return; // 0.0 usually happens on login and causes issues with visuals; anything above 20 means a plugin like OldCombatMechanics is being used // Needs to be sent or no subtitle packet is recognized by the client SetTitlePacket titlePacket = new SetTitlePacket(); @@ -67,7 +68,11 @@ public class CooldownUtils { if (session.isClosed()) return; // Don't run scheduled tasks if the client left if (lastHitTime != session.getLastHitTime()) return; // Means another cooldown has started so there's no need to continue this one SetTitlePacket titlePacket = new SetTitlePacket(); - titlePacket.setType(SetTitlePacket.Type.SUBTITLE); + if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) { + titlePacket.setType(SetTitlePacket.Type.ACTIONBAR); + } else { + titlePacket.setType(SetTitlePacket.Type.SUBTITLE); + } titlePacket.setText(getTitle(session)); titlePacket.setFadeInTime(0); titlePacket.setFadeOutTime(5); @@ -77,7 +82,11 @@ public class CooldownUtils { session.getConnector().getGeneralThreadPool().schedule(() -> computeCooldown(session, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50 } else { SetTitlePacket removeTitlePacket = new SetTitlePacket(); - removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE); + if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) { + removeTitlePacket.setType(SetTitlePacket.Type.ACTIONBAR); + } else { + removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE); + } removeTitlePacket.setText(" "); session.sendUpstreamPacket(removeTitlePacket); } @@ -114,4 +123,33 @@ public class CooldownUtils { } return builder.toString(); } + + @Getter + public enum CooldownType { + TITLE, + ACTIONBAR, + DISABLED; + + public static final CooldownType[] VALUES = values(); + + /** + * Convert the CooldownType string (from config) to the enum, TITLE on fail + * + * @param name CooldownType string + * + * @return The converted CooldownType + */ + public static CooldownType getByName(String name) { + if (name.equalsIgnoreCase("true")) { // Backwards config compatibility + return CooldownType.TITLE; + } + + for (CooldownType type : VALUES) { + if (type.name().equalsIgnoreCase(name)) { + return type; + } + } + return DISABLED; + } + } } diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index 847eded1a..6ccddd401 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -112,7 +112,8 @@ allow-third-party-capes: true allow-third-party-ears: false # Allow a fake cooldown indicator to be sent. Bedrock players do not see a cooldown as they still use 1.8 combat -show-cooldown: true +# Can be title, actionbar or false +show-cooldown: title # Controls if coordinates are shown to players. show-coordinates: true diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 216e90086..2ce794e21 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 216e9008678a761b3885808f4f3d43000404381b +Subproject commit 2ce794e21a0212865059e7551db893c28843620a From 8f6785e48f788284ff4adb73388124fe078c507d Mon Sep 17 00:00:00 2001 From: Konicai <71294714+Konicai@users.noreply.github.com> Date: Fri, 2 Apr 2021 13:36:30 -0400 Subject: [PATCH 4/5] Restrictions to commands players can send on Geyser Standalone (#2099) - players cannot create a dump - if the version command is sent by a player, it will not check for new updates --- .../geysermc/connector/command/defaults/DumpCommand.java | 7 +++++++ .../geysermc/connector/command/defaults/StopCommand.java | 2 ++ .../connector/command/defaults/VersionCommand.java | 9 +++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java index 97d09f7e0..05f32ae2b 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java @@ -27,6 +27,7 @@ package org.geysermc.connector.command.defaults; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import org.geysermc.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; @@ -56,6 +57,12 @@ public class DumpCommand extends GeyserCommand { @Override public void execute(GeyserSession session, CommandSender sender, String[] args) { + // Only allow the console to create dumps on Geyser Standalone + if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) { + sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale())); + return; + } + boolean showSensitive = false; boolean offlineDump = false; if (args.length >= 1) { diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java index b00e44b72..8ceeb9990 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java @@ -30,6 +30,7 @@ import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; import java.util.Collections; @@ -47,6 +48,7 @@ public class StopCommand extends GeyserCommand { @Override public void execute(GeyserSession session, CommandSender sender, String[] args) { if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) { + sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale())); return; } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java index 226a770a6..21a891c0e 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java @@ -27,6 +27,7 @@ package org.geysermc.connector.command.defaults; import com.github.steveice10.mc.protocol.MinecraftConstants; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; +import org.geysermc.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; @@ -45,8 +46,12 @@ import java.util.Properties; public class VersionCommand extends GeyserCommand { + private final GeyserConnector connector; + public VersionCommand(GeyserConnector connector, String name, String description, String permission) { super(name, description, permission); + + this.connector = connector; } @Override @@ -61,9 +66,9 @@ public class VersionCommand extends GeyserCommand { sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.version", sender.getLocale(), GeyserConnector.NAME, GeyserConnector.VERSION, GeyserConnector.MINECRAFT_VERSION, bedrockVersions)); - // Disable update checking in dev mode + // Disable update checking in dev mode and for players in Geyser Standalone //noinspection ConstantConditions - changes in production - if (!GeyserConnector.VERSION.equals("DEV")) { + if (!GeyserConnector.VERSION.equals("DEV") && !(!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE)) { sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.checking", sender.getLocale())); try { Properties gitProp = new Properties(); From 86b2901f0281d8373a3d921513d2efef91b1894f Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 6 Apr 2021 00:14:06 -0400 Subject: [PATCH 5/5] 1.16.220 support (#2105) This update does not break compatibility with any other currently supported version of Bedrock. Co-authored-by: Redned --- README.md | 2 +- bootstrap/bungeecord/pom.xml | 4 +- bootstrap/pom.xml | 2 +- bootstrap/spigot/pom.xml | 4 +- bootstrap/sponge/pom.xml | 4 +- bootstrap/standalone/pom.xml | 4 +- bootstrap/velocity/pom.xml | 4 +- common/pom.xml | 2 +- connector/pom.xml | 8 +- .../connector/entity/ItemFrameEntity.java | 2 +- .../living/animal/horse/LlamaEntity.java | 9 +- .../connector/inventory/GeyserItemStack.java | 1 + .../connector/network/BedrockProtocol.java | 2 + .../network/translators/item/ItemEntry.java | 15 +++- .../translators/item/ItemRegistry.java | 87 ++++++++++++------- .../translators/item/ItemTranslator.java | 29 ++++--- .../network/translators/item/Potion.java | 2 +- .../translators/item/RecipeRegistry.java | 6 +- .../translators/item/TippedArrowPotion.java | 2 +- .../translators/item/ToolItemEntry.java | 5 +- .../item/translators/BannerTranslator.java | 16 ++-- .../item/translators/CompassTranslator.java | 6 +- .../item/translators/PotionTranslator.java | 8 +- .../translators/TippedArrowTranslator.java | 8 +- .../translators/nbt/CrossbowTranslator.java | 2 +- .../java/JavaDeclareCommandsTranslator.java | 28 +++--- .../java/JavaDeclareRecipesTranslator.java | 10 ++- .../world/JavaSpawnParticleTranslator.java | 2 +- .../java/world/JavaTradeListTranslator.java | 2 +- .../connector/utils/InventoryUtils.java | 5 +- connector/src/main/resources/mappings | 2 +- pom.xml | 2 +- 32 files changed, 175 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index a21a1b6c9..4a522f21f 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,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.100 - v1.16.210 and Minecraft Java v1.16.4 - v1.16.5. +### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.220 and Minecraft Java v1.16.4 - v1.16.5. ## Setting Up Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser. diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml index 10855aed4..a62faa33a 100644 --- a/bootstrap/bungeecord/pom.xml +++ b/bootstrap/bungeecord/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-bungeecord @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml index 4b61a65c3..b06fc59cf 100644 --- a/bootstrap/pom.xml +++ b/bootstrap/pom.xml @@ -6,7 +6,7 @@ org.geysermc geyser-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-parent pom diff --git a/bootstrap/spigot/pom.xml b/bootstrap/spigot/pom.xml index d1cba8aea..12c8292e9 100644 --- a/bootstrap/spigot/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-spigot @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/bootstrap/sponge/pom.xml b/bootstrap/sponge/pom.xml index 97c4ac8a4..93ae3ab6b 100644 --- a/bootstrap/sponge/pom.xml +++ b/bootstrap/sponge/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-sponge @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/bootstrap/standalone/pom.xml b/bootstrap/standalone/pom.xml index 831239f66..122991357 100644 --- a/bootstrap/standalone/pom.xml +++ b/bootstrap/standalone/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-standalone @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/bootstrap/velocity/pom.xml b/bootstrap/velocity/pom.xml index 58eee1f77..bcc62ed4c 100644 --- a/bootstrap/velocity/pom.xml +++ b/bootstrap/velocity/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT bootstrap-velocity @@ -14,7 +14,7 @@ org.geysermc connector - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile diff --git a/common/pom.xml b/common/pom.xml index 32c4b1876..e40e40c55 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -6,7 +6,7 @@ org.geysermc geyser-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT common diff --git a/connector/pom.xml b/connector/pom.xml index 6f2cdab4e..90ee8a5c9 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -6,7 +6,7 @@ org.geysermc geyser-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT connector @@ -20,7 +20,7 @@ org.geysermc common - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT compile @@ -31,8 +31,8 @@ com.github.CloudburstMC.Protocol - bedrock-v428 - 42da92f + bedrock-v431 + f8ecf54 compile diff --git a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java index a898ea389..e10ad0afd 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java @@ -107,7 +107,7 @@ public class ItemFrameEntity extends Entity { if (itemData.getTag() != null) { builder.put("tag", itemData.getTag().toBuilder().build()); } - builder.putShort("Damage", itemData.getDamage()); + builder.putShort("Damage", (short) itemData.getDamage()); builder.putString("Name", itemEntry.getBedrockIdentifier()); NbtMapBuilder tag = getDefaultTag().toBuilder(); tag.put("Item", builder.build()); diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java index 5fdde5272..d575f9521 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java @@ -56,9 +56,12 @@ public class LlamaEntity extends ChestedHorseEntity { // -1 means no armor if ((int) entityMetadata.getValue() != -1) { // The damage value is the dye color that Java sends us - // Always going to be a carpet so we can hardcode 171 in BlockTranslator - // The int then short conversion is required or we get a ClassCastException - equipmentPacket.setChestplate(ItemData.of(BlockTranslator.CARPET, (short) ((int) entityMetadata.getValue()), 1)); + // The item is always going to be a carpet + equipmentPacket.setChestplate(ItemData.builder() + .id(BlockTranslator.CARPET) + .damage((int) entityMetadata.getValue()) + .count(1) + .build()); } else { equipmentPacket.setChestplate(ItemData.AIR); } diff --git a/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java b/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java index b4e91c1d6..1cfd425d9 100644 --- a/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java +++ b/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java @@ -101,6 +101,7 @@ public class GeyserItemStack { public ItemData getItemData(GeyserSession session) { ItemData itemData = ItemTranslator.translateToBedrock(session, getItemStack()); itemData.setNetId(getNetId()); + itemData.setUsingNetId(true); // Seems silly - this should probably be on the protocol level return itemData; } diff --git a/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java b/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java index 3b5af7f99..2d29ddd88 100644 --- a/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java +++ b/connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java @@ -29,6 +29,7 @@ import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.v419.Bedrock_v419; import com.nukkitx.protocol.bedrock.v422.Bedrock_v422; import com.nukkitx.protocol.bedrock.v428.Bedrock_v428; +import com.nukkitx.protocol.bedrock.v431.Bedrock_v431; import java.util.ArrayList; import java.util.List; @@ -55,6 +56,7 @@ public class BedrockProtocol { .minecraftVersion("1.16.200/1.16.201") .build()); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC); + SUPPORTED_BEDROCK_CODECS.add(Bedrock_v431.V431_CODEC); } /** diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java index 278d708f9..3d92e823c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java @@ -28,23 +28,32 @@ package org.geysermc.connector.network.translators.item; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; +import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210; @Getter @AllArgsConstructor @ToString public class ItemEntry { - public static ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0, false, 64); + public static ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0, + BlockTranslator1_16_210.INSTANCE.getBedrockAirId(), 64); private final String javaIdentifier; private final String bedrockIdentifier; private final int javaId; private final int bedrockId; private final int bedrockData; - - private final boolean block; + /** + * The Bedrock block runtime ID to render this item with. The specific state *does* matter in how this item is rendered. + * Required since 1.16.220. + */ + private final int bedrockBlockId; private final int stackSize; + public boolean isBlock() { + return bedrockBlockId != -1; + } + @Override public boolean equals(Object obj) { return obj == this || (obj instanceof ItemEntry && ((ItemEntry) obj).getBedrockId() == this.getBedrockId() && ((ItemEntry) obj).getJavaIdentifier().equals(this.getJavaIdentifier())); 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 be190f6ff..4690fb700 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 @@ -42,6 +42,7 @@ import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; @@ -176,54 +177,64 @@ public class ItemRegistry { } JsonNode stackSizeNode = entry.getValue().get("stack_size"); int stackSize = stackSizeNode == null ? 64 : stackSizeNode.intValue(); + + int bedrockBlockId = -1; + JsonNode blockRuntimeIdNode = entry.getValue().get("blockRuntimeId"); + if (blockRuntimeIdNode != null) { + bedrockBlockId = BlockTranslator1_16_210.INSTANCE.getBedrockBlockId(blockRuntimeIdNode.intValue()); + } + + ItemEntry itemEntry; if (entry.getValue().has("tool_type")) { if (entry.getValue().has("tool_tier")) { - ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( + itemEntry = new ToolItemEntry( entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, entry.getValue().get("bedrock_data").intValue(), entry.getValue().get("tool_type").textValue(), entry.getValue().get("tool_tier").textValue(), - entry.getValue().get("is_block").booleanValue(), - stackSize)); + bedrockBlockId, + stackSize); } else { - ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( + itemEntry = new ToolItemEntry( entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, entry.getValue().get("bedrock_data").intValue(), entry.getValue().get("tool_type").textValue(), - "", entry.getValue().get("is_block").booleanValue(), - stackSize)); + "", bedrockBlockId, + stackSize); } } else { - ITEM_ENTRIES.put(itemIndex, new ItemEntry( + itemEntry = new ItemEntry( entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, entry.getValue().get("bedrock_data").intValue(), - entry.getValue().get("is_block").booleanValue(), - stackSize)); + bedrockBlockId, + stackSize); } + ITEM_ENTRIES.put(itemIndex, itemEntry); + switch (entry.getKey()) { case "minecraft:barrier": BARRIER_INDEX = itemIndex; break; case "minecraft:bamboo": - BAMBOO = ITEM_ENTRIES.get(itemIndex); + BAMBOO = itemEntry; break; case "minecraft:egg": - EGG = ITEM_ENTRIES.get(itemIndex); + EGG = itemEntry; break; case "minecraft:gold_ingot": - GOLD = ITEM_ENTRIES.get(itemIndex); + GOLD = itemEntry; break; case "minecraft:shield": - SHIELD = ITEM_ENTRIES.get(itemIndex); + SHIELD = itemEntry; break; case "minecraft:milk_bucket": - MILK_BUCKET = ITEM_ENTRIES.get(itemIndex); + MILK_BUCKET = itemEntry; break; case "minecraft:wheat": - WHEAT = ITEM_ENTRIES.get(itemIndex); + WHEAT = itemEntry; break; case "minecraft:writable_book": - WRITABLE_BOOK = ITEM_ENTRIES.get(itemIndex); + WRITABLE_BOOK = itemEntry; break; default: break; @@ -249,7 +260,7 @@ public class ItemRegistry { // Add the loadstone compass since it doesn't exist on java but we need it for item conversion ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestone_compass", "minecraft:lodestone_compass", itemIndex, - lodestoneCompassId, 0, false, 1)); + lodestoneCompassId, 0, -1, 1)); /* Load creative items */ stream = FileUtils.getResource("bedrock/creative_items.json"); @@ -261,11 +272,24 @@ public class ItemRegistry { throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e); } + Set javaOnlyItems = new ObjectOpenHashSet<>(); + Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick", + "minecraft:knowledge_book", "minecraft:tipped_arrow"); + if (!usingFurnaceMinecart) { + javaOnlyItems.add("minecraft:furnace_minecart"); + } + JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems); + int netId = 1; List creativeItems = new ArrayList<>(); for (JsonNode itemNode : creativeItemEntries) { - ItemData item = getBedrockItemFromJson(itemNode); - creativeItems.add(ItemData.fromNet(netId++, item.getId(), item.getDamage(), item.getCount(), item.getTag())); + ItemData.Builder item = getBedrockItemFromJson(itemNode); + int bedrockRuntimeId = 0; + ItemEntry itemEntry = getItem(item.build()); // please + if (itemEntry.isBlock()) { + bedrockRuntimeId = itemEntry.getBedrockBlockId(); + } + creativeItems.add(item.netId(netId++).blockRuntimeId(bedrockRuntimeId).build()); } if (usingFurnaceMinecart) { @@ -274,8 +298,11 @@ public class ItemRegistry { ITEMS.add(new StartGamePacket.ItemEntry("geysermc:furnace_minecart", (short) furnaceMinecartId, true)); ITEM_ENTRIES.put(javaFurnaceMinecartId, new ItemEntry("minecraft:furnace_minecart", "geysermc:furnace_minecart", javaFurnaceMinecartId, - furnaceMinecartId, 0, false, 1)); - creativeItems.add(ItemData.fromNet(netId, furnaceMinecartId, (short) 0, 1, null)); + furnaceMinecartId, 0, -1, 1)); + creativeItems.add(ItemData.builder() + .netId(netId) + .id(furnaceMinecartId) + .count(1).build()); NbtMapBuilder builder = NbtMap.builder(); builder.putString("name", "geysermc:furnace_minecart") @@ -312,14 +339,6 @@ public class ItemRegistry { CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]); ITEM_NAMES = itemNames.toArray(new String[0]); - - Set javaOnlyItems = new ObjectOpenHashSet<>(); - Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick", - "minecraft:knowledge_book", "minecraft:tipped_arrow"); - if (!usingFurnaceMinecart) { - javaOnlyItems.add("minecraft:furnace_minecart"); - } - JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems); } /** @@ -376,11 +395,11 @@ public class ItemRegistry { } /** - * Gets a Bedrock {@link ItemData} from a {@link JsonNode} + * Gets a Bedrock {@link com.nukkitx.protocol.bedrock.data.inventory.ItemData.Builder} from a {@link JsonNode} * @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data * @return */ - public static ItemData getBedrockItemFromJson(JsonNode itemNode) { + public static ItemData.Builder getBedrockItemFromJson(JsonNode itemNode) { int count = 1; short damage = 0; NbtMap tag = null; @@ -399,6 +418,10 @@ public class ItemRegistry { e.printStackTrace(); } } - return ItemData.of(itemNode.get("id").asInt(), damage, count, tag); + return ItemData.builder() + .id(itemNode.get("id").asInt()) + .damage(damage) + .count(count) + .tag(tag); } } 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 f1ae98faf..2cd1aad94 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 @@ -149,12 +149,15 @@ public abstract class ItemTranslator { translateDisplayProperties(session, nbt); - ItemData itemData; + ItemData.Builder builder; ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId()); if (itemStackTranslator != null) { - itemData = itemStackTranslator.translateToBedrock(itemStack, bedrockItem); + builder = itemStackTranslator.translateToBedrock(itemStack, bedrockItem); } else { - itemData = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem); + builder = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem); + } + if (bedrockItem.isBlock()) { + builder.blockRuntimeId(bedrockItem.getBedrockBlockId()); } if (nbt != null) { @@ -165,10 +168,11 @@ public abstract class ItemTranslator { String[] canPlace = new String[0]; canBreak = getCanModify(session, canDestroy, canBreak); canPlace = getCanModify(session, canPlaceOn, canPlace); - itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), itemData.getTag(), canPlace, canBreak); + builder.canBreak(canBreak); + builder.canPlace(canPlace); } - return itemData; + return builder.build(); } /** @@ -202,14 +206,19 @@ public abstract class ItemTranslator { } }; - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (itemStack == null) { - return ItemData.AIR; + // Return, essentially, air + return ItemData.builder(); } - if (itemStack.getNbt() == null) { - return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount()); + ItemData.Builder builder = ItemData.builder() + .id(itemEntry.getBedrockId()) + .damage(itemEntry.getBedrockData()) + .count(itemStack.getAmount()); + if (itemStack.getNbt() != null) { + builder.tag(this.translateNbtToBedrock(itemStack.getNbt())); } - return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount(), this.translateNbtToBedrock(itemStack.getNbt())); + return builder; } public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java index d81e059e9..4e710c550 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java @@ -91,7 +91,7 @@ public enum Potion { return null; } - public static Potion getByBedrockId(short bedrockId) { + public static Potion getByBedrockId(int bedrockId) { for (Potion potion : Potion.values()) { if (potion.bedrockId == bedrockId) { return potion; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java index 110014bf5..b570df8a1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/RecipeRegistry.java @@ -272,7 +272,11 @@ public class RecipeRegistry { e.printStackTrace(); } } - return ItemData.of(itemEntry.getBedrockId(), damage, count, tag); + return ItemData.builder() + .id(itemEntry.getBedrockId()) + .damage(damage) + .count(count) + .tag(tag).build(); } public static void init() { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/TippedArrowPotion.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/TippedArrowPotion.java index 0125dae05..5aac09790 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/TippedArrowPotion.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/TippedArrowPotion.java @@ -100,7 +100,7 @@ public enum TippedArrowPotion { return null; } - public static TippedArrowPotion getByBedrockId(short bedrockId) { + public static TippedArrowPotion getByBedrockId(int bedrockId) { for (TippedArrowPotion potion : TippedArrowPotion.values()) { if (potion.bedrockId == bedrockId) { return potion; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java index ba1753a35..2e93811c0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java @@ -32,8 +32,9 @@ public class ToolItemEntry extends ItemEntry { private final String toolType; private final String toolTier; - public ToolItemEntry(String javaIdentifier, String bedrockIdentifier, int javaId, int bedrockId, int bedrockData, String toolType, String toolTier, boolean isBlock, int stackSize) { - super(javaIdentifier, bedrockIdentifier, javaId, bedrockId, bedrockData, isBlock, stackSize); + public ToolItemEntry(String javaIdentifier, String bedrockIdentifier, int javaId, int bedrockId, int bedrockData, + String toolType, String toolTier, int bedrockBlockId, int stackSize) { + super(javaIdentifier, bedrockIdentifier, javaId, bedrockId, bedrockData, bedrockBlockId, stackSize); this.toolType = toolType; this.toolTier = toolTier; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java index a96c47f6a..b127e1928 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java @@ -153,30 +153,30 @@ public class BannerTranslator extends ItemTranslator { } @Override - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (itemStack.getNbt() == null) { return super.translateToBedrock(itemStack, itemEntry); } - ItemData itemData = super.translateToBedrock(itemStack, itemEntry); + ItemData.Builder builder = super.translateToBedrock(itemStack, itemEntry); CompoundTag blockEntityTag = itemStack.getNbt().get("BlockEntityTag"); if (blockEntityTag != null && blockEntityTag.contains("Patterns")) { ListTag patterns = blockEntityTag.get("Patterns"); - NbtMapBuilder builder = itemData.getTag().toBuilder(); + NbtMapBuilder nbtBuilder = builder.build().getTag().toBuilder(); //TODO fix ugly hack if (patterns.equals(OMINOUS_BANNER_PATTERN)) { // Remove the current patterns and set the ominous banner type - builder.remove("Patterns"); - builder.putInt("Type", 1); + nbtBuilder.remove("Patterns"); + nbtBuilder.putInt("Type", 1); } else { - builder.put("Patterns", convertBannerPattern(patterns)); + nbtBuilder.put("Patterns", convertBannerPattern(patterns)); } - itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.build()); + builder.tag(nbtBuilder.build()); } - return itemData; + return builder; } @Override 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 index 9e3bf7d46..08c7426fe 100644 --- 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 @@ -47,7 +47,7 @@ public class CompassTranslator extends ItemTranslator { } @Override - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry); Tag lodestoneTag = itemStack.getNbt().get("LodestoneTracked"); @@ -75,9 +75,7 @@ public class CompassTranslator extends ItemTranslator { } } - ItemData itemData = super.translateToBedrock(itemStack, itemEntry); - - return itemData; + return super.translateToBedrock(itemStack, itemEntry); } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java index 20a36c9e2..9f41472fe 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java @@ -49,13 +49,17 @@ public class PotionTranslator extends ItemTranslator { } @Override - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry); Tag potionTag = itemStack.getNbt().get("Potion"); if (potionTag instanceof StringTag) { Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (potion != null) { - return ItemData.of(itemEntry.getBedrockId(), potion.getBedrockId(), itemStack.getAmount(), translateNbtToBedrock(itemStack.getNbt())); + return ItemData.builder() + .id(itemEntry.getBedrockId()) + .damage(potion.getBedrockId()) + .count(itemStack.getAmount()) + .tag(translateNbtToBedrock(itemStack.getNbt())); } GeyserConnector.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue()); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/TippedArrowTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/TippedArrowTranslator.java index dd151dcd8..8b64732c4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/TippedArrowTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/TippedArrowTranslator.java @@ -52,7 +52,7 @@ public class TippedArrowTranslator extends ItemTranslator { } @Override - public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { if (!itemEntry.getJavaIdentifier().equals("minecraft:tipped_arrow") || itemStack.getNbt() == null) { // We're only concerned about minecraft:arrow when translating Bedrock -> Java return super.translateToBedrock(itemStack, itemEntry); @@ -61,7 +61,11 @@ public class TippedArrowTranslator extends ItemTranslator { if (potionTag instanceof StringTag) { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (tippedArrowPotion != null) { - return ItemData.of(itemEntry.getBedrockId(), tippedArrowPotion.getBedrockId(), itemStack.getAmount(), translateNbtToBedrock(itemStack.getNbt())); + return ItemData.builder() + .id(itemEntry.getBedrockId()) + .damage(tippedArrowPotion.getBedrockId()) + .count(itemStack.getAmount()) + .tag(translateNbtToBedrock(itemStack.getNbt())); } GeyserConnector.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue()); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java index 2af803807..ae52e4221 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java @@ -55,7 +55,7 @@ public class CrossbowTranslator extends NbtItemStackTranslator { newProjectile.put(new ByteTag("Count", (byte) itemData.getCount())); newProjectile.put(new StringTag("Name", projectileEntry.getBedrockIdentifier())); - newProjectile.put(new ShortTag("Damage", itemData.getDamage())); + newProjectile.put(new ShortTag("Damage", (short) itemData.getDamage())); itemTag.put(newProjectile); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java index 7de101811..942bc7fdc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java @@ -30,8 +30,8 @@ import com.github.steveice10.mc.protocol.data.game.command.CommandParser; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket; import com.nukkitx.protocol.bedrock.data.command.CommandData; import com.nukkitx.protocol.bedrock.data.command.CommandEnumData; +import com.nukkitx.protocol.bedrock.data.command.CommandParam; import com.nukkitx.protocol.bedrock.data.command.CommandParamData; -import com.nukkitx.protocol.bedrock.data.command.CommandParamType; import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -200,47 +200,47 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator=", "==", etc - return CommandParamType.OPERATOR; + return CommandParam.OPERATOR; case BLOCK_STATE: return BlockTranslator.getAllBlockIdentifiers(); @@ -261,7 +261,7 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java index bf78d52c6..693bf94f3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java @@ -69,7 +69,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator4.0.0 org.geysermc geyser-parent - 1.2.0-SNAPSHOT + 1.2.1-SNAPSHOT pom Geyser Allows for players from Minecraft Bedrock Edition to join Minecraft Java Edition servers.