From 70e28604b81e3b76d62e1434cb1047c3a0c66c22 Mon Sep 17 00:00:00 2001 From: David Choo Date: Thu, 15 Apr 2021 15:31:03 -0400 Subject: [PATCH 1/5] Fix various horse bugs (#2115) * Fix horse health display * Fix horses warping back when damaged * Fix horse jumping animation * Fix horses not taking damage while standing on magma * Allow mules and donkeys to jump --- .../animal/horse/AbstractHorseEntity.java | 13 ++++- .../network/session/GeyserSession.java | 6 +++ .../BedrockMoveEntityAbsoluteTranslator.java | 2 + .../bedrock/BedrockPlayerInputTranslator.java | 45 ++++++++++++++++++ .../player/BedrockRiderJumpTranslator.java | 47 +++++++++++++++++++ .../entity/JavaEntityVelocityTranslator.java | 7 +++ 6 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/player/BedrockRiderJumpTranslator.java 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 41073246e..1fe8d4362 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 @@ -32,6 +32,7 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityEventType; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; +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; @@ -44,6 +45,10 @@ public class AbstractHorseEntity extends AnimalEntity { // Specifies the size of the entity's inventory. Required to place slots in the entity. metadata.put(EntityData.CONTAINER_BASE_SIZE, 2); + // Add dummy health attribute since LivingEntity updates the attribute for us + attributes.put(AttributeType.HEALTH, AttributeType.HEALTH.getAttribute(20, 20)); + // Add horse jump strength attribute to allow donkeys and mules to jump + attributes.put(AttributeType.HORSE_JUMP_STRENGTH, AttributeType.HORSE_JUMP_STRENGTH.getAttribute(0.5f, 2)); } @Override @@ -85,9 +90,15 @@ public class AbstractHorseEntity extends AnimalEntity { } // Needed to control horses - metadata.getFlags().setFlag(EntityFlag.CAN_POWER_JUMP, true); + boolean canPowerJump = entityType != EntityType.LLAMA && entityType != EntityType.TRADER_LLAMA; + metadata.getFlags().setFlag(EntityFlag.CAN_POWER_JUMP, canPowerJump); metadata.getFlags().setFlag(EntityFlag.WASD_CONTROLLED, true); super.updateBedrockMetadata(entityMetadata, session); + + if (entityMetadata.getId() == 8) { + // Update the health attribute + updateBedrockAttributes(session); + } } } 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 fe632c224..e521673e2 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 @@ -355,6 +355,12 @@ public class GeyserSession implements CommandSender { @Setter private long lastMovementTimestamp = System.currentTimeMillis(); + /** + * Used to send a ClientVehicleMovePacket for every PlayerInputPacket after idling on a boat/horse for more than 100ms + */ + @Setter + private long lastVehicleMoveTimestamp = System.currentTimeMillis(); + /** * Controls whether the daylight cycle gamerule has been sent to the client, so the sun/moon remain motionless. */ diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMoveEntityAbsoluteTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMoveEntityAbsoluteTranslator.java index f0b5a1752..b053a204c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMoveEntityAbsoluteTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMoveEntityAbsoluteTranslator.java @@ -41,6 +41,8 @@ public class BedrockMoveEntityAbsoluteTranslator extends PacketTranslator 0) { + sendMovement = true; + } + } + } + if (sendMovement) { + long timeSinceVehicleMove = System.currentTimeMillis() - session.getLastVehicleMoveTimestamp(); + if (timeSinceVehicleMove >= 100) { + Vector3f vehiclePosition = vehicle.getPosition(); + Vector3f vehicleRotation = vehicle.getRotation(); + + if (vehicle instanceof BoatEntity) { + // Remove some Y position to prevents boats flying up + vehiclePosition = vehiclePosition.down(EntityType.BOAT.getOffset()); + } + + ClientVehicleMovePacket clientVehicleMovePacket = new ClientVehicleMovePacket( + vehiclePosition.getX(), vehiclePosition.getY(), vehiclePosition.getZ(), + vehicleRotation.getX() - 90, vehicleRotation.getY() + ); + session.sendDownstreamPacket(clientVehicleMovePacket); + } + } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/player/BedrockRiderJumpTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/player/BedrockRiderJumpTranslator.java new file mode 100644 index 000000000..5d375daee --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/player/BedrockRiderJumpTranslator.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019-2021 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.entity.player; + +import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; +import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket; +import com.nukkitx.protocol.bedrock.packet.RiderJumpPacket; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.entity.living.animal.horse.AbstractHorseEntity; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; + +@Translator(packet = RiderJumpPacket.class) +public class BedrockRiderJumpTranslator extends PacketTranslator { + @Override + public void translate(RiderJumpPacket packet, GeyserSession session) { + Entity vehicle = session.getRidingVehicleEntity(); + if (vehicle instanceof AbstractHorseEntity) { + ClientPlayerStatePacket playerStatePacket = new ClientPlayerStatePacket((int) vehicle.getEntityId(), PlayerState.START_HORSE_JUMP, packet.getJumpStrength()); + session.sendDownstreamPacket(playerStatePacket); + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityVelocityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityVelocityTranslator.java index 1a236f551..1c628503a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityVelocityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityVelocityTranslator.java @@ -26,6 +26,7 @@ package org.geysermc.connector.network.translators.java.entity; import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.entity.living.animal.horse.AbstractHorseEntity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -47,6 +48,12 @@ public class JavaEntityVelocityTranslator extends PacketTranslator Date: Fri, 16 Apr 2021 11:28:15 -0400 Subject: [PATCH 2/5] Fall back to the loopback address when resolving autoconfigured remote (#2090) This way, if it errors, you're not stuck with 'unknown host: auto' when actually connecting. --- .../src/main/java/org/geysermc/connector/GeyserConnector.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index ae6dbbe1d..03bf7538c 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -160,12 +160,13 @@ public class GeyserConnector { if (config.isDebugMode()) { ex.printStackTrace(); } + config.getRemote().setAddress(InetAddress.getLoopbackAddress().getHostAddress()); } } String remoteAddress = config.getRemote().getAddress(); - int remotePort = config.getRemote().getPort(); // Filters whether it is not an IP address or localhost, because otherwise it is not possible to find out an SRV entry. if (!remoteAddress.matches(IP_REGEX) && !remoteAddress.equalsIgnoreCase("localhost")) { + int remotePort; try { // Searches for a server address and a port from a SRV record of the specified host name InitialDirContext ctx = new InitialDirContext(); From beb7e54b7a8e65b937a0da3083cf214f2d55424d Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 16 Apr 2021 11:30:17 -0400 Subject: [PATCH 3/5] Fix llama carpet decoration (#2125) --- .../entity/living/animal/horse/LlamaEntity.java | 15 ++++++--------- .../network/translators/item/ItemRegistry.java | 11 +++++++++++ .../translators/world/block/BlockTranslator.java | 3 --- 3 files changed, 17 insertions(+), 12 deletions(-) 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 d575f9521..48e321932 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 @@ -32,7 +32,7 @@ import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.network.translators.item.ItemRegistry; public class LlamaEntity extends ChestedHorseEntity { @@ -52,16 +52,13 @@ public class LlamaEntity extends ChestedHorseEntity { if (entityMetadata.getId() == 20) { // Bedrock treats llama decoration as armor MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket(); - equipmentPacket.setRuntimeEntityId(getGeyserId()); + equipmentPacket.setRuntimeEntityId(geyserId); // -1 means no armor - if ((int) entityMetadata.getValue() != -1) { - // The damage value is the dye color that Java sends us + int carpetIndex = (int) entityMetadata.getValue(); + if (carpetIndex > -1 && carpetIndex <= 15) { + // The damage value is the dye color that Java sends us, for pre-1.16.220 // The item is always going to be a carpet - equipmentPacket.setChestplate(ItemData.builder() - .id(BlockTranslator.CARPET) - .damage((int) entityMetadata.getValue()) - .count(1) - .build()); + equipmentPacket.setChestplate(ItemRegistry.CARPETS.get(carpetIndex)); } else { equipmentPacket.setChestplate(ItemData.AIR); } 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 c56ba249f..7550bc818 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 @@ -92,6 +92,10 @@ public class ItemRegistry { * Bucket item entries (excluding the milk bucket), used in BedrockInventoryTransactionTranslator.java */ public static final IntSet BUCKETS = new IntArraySet(); + /** + * Carpet item data, used in LlamaEntity.java + */ + public static final List CARPETS = new ArrayList<>(16); /** * Crossbow item entry, used in PillagerEntity.java */ @@ -452,6 +456,13 @@ public class ItemRegistry { BOATS.add(entry.getValue().get("bedrock_id").intValue()); } else if (entry.getKey().contains("bucket") && !entry.getKey().contains("milk")) { BUCKETS.add(entry.getValue().get("bedrock_id").intValue()); + } else if (entry.getKey().contains("_carpet")) { + // This should be the numerical order Java sends as an integer value for llamas + CARPETS.add(ItemData.builder() + .id(itemEntry.getBedrockId()) + .damage(itemEntry.getBedrockData()) + .count(1) + .blockRuntimeId(itemEntry.getBedrockBlockId()).build()); } itemNames.add(entry.getKey()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java index 36707eff1..1a2624a6f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java @@ -74,9 +74,6 @@ public abstract class BlockTranslator { private final Object2IntMap itemFrames = new Object2IntOpenHashMap<>(); private final Map flowerPotBlocks = new HashMap<>(); - // Bedrock carpet ID, used in LlamaEntity.java for decoration - public static final int CARPET = 171; - public static final Int2DoubleMap JAVA_RUNTIME_ID_TO_HARDNESS = new Int2DoubleOpenHashMap(); public static final Int2BooleanMap JAVA_RUNTIME_ID_TO_CAN_HARVEST_WITH_HAND = new Int2BooleanOpenHashMap(); public static final Int2ObjectMap JAVA_RUNTIME_ID_TO_TOOL_TYPE = new Int2ObjectOpenHashMap<>(); From 852d5b050dde8e3aedf6eef80891640d916f39b8 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 16 Apr 2021 11:42:03 -0400 Subject: [PATCH 4/5] Fix item enchanting pre-1.14 (#2127) If the server spams the window property update packet, then the network ID assigned for each enchanting slot will update too quickly, essentially disabling enchanting. This commit remedies this by only updating the network ID of each slot if a property changed. --- .../inventory/GeyserEnchantOption.java | 35 +++++++++++++++++-- .../EnchantingInventoryTranslator.java | 22 +++++++----- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/inventory/GeyserEnchantOption.java b/connector/src/main/java/org/geysermc/connector/inventory/GeyserEnchantOption.java index e9ad81a6a..68f65f9af 100644 --- a/connector/src/main/java/org/geysermc/connector/inventory/GeyserEnchantOption.java +++ b/connector/src/main/java/org/geysermc/connector/inventory/GeyserEnchantOption.java @@ -28,7 +28,6 @@ package org.geysermc.connector.inventory; import com.nukkitx.protocol.bedrock.data.inventory.EnchantData; import com.nukkitx.protocol.bedrock.data.inventory.EnchantOptionData; import lombok.Getter; -import lombok.Setter; import org.geysermc.connector.network.session.GeyserSession; import java.util.Arrays; @@ -38,7 +37,6 @@ import java.util.List; /** * A mutable "wrapper" around {@link EnchantOptionData} */ -@Setter public class GeyserEnchantOption { private static final List EMPTY = Collections.emptyList(); /** @@ -57,6 +55,12 @@ public class GeyserEnchantOption { @Getter private final int javaIndex; + /** + * Whether the enchantment details have actually changed. + * Used to mitigate weird packet spamming pre-1.14, causing the net ID to always update. + */ + private boolean hasChanged; + private int xpCost = 0; private int javaEnchantIndex = -1; private int bedrockEnchantIndex = -1; @@ -67,8 +71,35 @@ public class GeyserEnchantOption { } public EnchantOptionData build(GeyserSession session) { + this.hasChanged = false; return new EnchantOptionData(xpCost, javaIndex + 16, EMPTY, enchantLevel == -1 ? EMPTY : Collections.singletonList(new EnchantData(bedrockEnchantIndex, enchantLevel)), EMPTY, javaEnchantIndex == -1 ? "unknown" : ENCHANT_NAMES.get(javaEnchantIndex), enchantLevel == -1 ? 0 : session.getNextItemNetId()); } + + public boolean hasChanged() { + return hasChanged; + } + + public void setXpCost(int xpCost) { + if (this.xpCost != xpCost) { + hasChanged = true; + this.xpCost = xpCost; + } + } + + public void setEnchantIndex(int javaEnchantIndex, int bedrockEnchantIndex) { + if (this.javaEnchantIndex != javaEnchantIndex) { + hasChanged = true; + this.javaEnchantIndex = javaEnchantIndex; + this.bedrockEnchantIndex = bedrockEnchantIndex; + } + } + + public void setEnchantLevel(int enchantLevel) { + if (this.enchantLevel != enchantLevel) { + hasChanged = true; + this.enchantLevel = enchantLevel; + } + } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/EnchantingInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/EnchantingInventoryTranslator.java index 03f8bb104..6e03c7df3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/EnchantingInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/EnchantingInventoryTranslator.java @@ -34,6 +34,7 @@ import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.StackRequ import com.nukkitx.protocol.bedrock.packet.ItemStackResponsePacket; import com.nukkitx.protocol.bedrock.packet.PlayerEnchantOptionsPacket; import org.geysermc.connector.inventory.EnchantingContainer; +import org.geysermc.connector.inventory.GeyserEnchantOption; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.PlayerInventory; import org.geysermc.connector.network.session.GeyserSession; @@ -67,18 +68,20 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla case 6: // Enchantment type slotToUpdate = key - 4; - int index = value; - if (index != -1) { - Enchantment enchantment = Enchantment.getByJavaIdentifier("minecraft:" + JavaEnchantment.values()[index].name().toLowerCase()); + // "value" here is the Java enchant ordinal, so that does not need to be changed + // The Bedrock index might need changed, so let's look it up and see. + int bedrockIndex = value; + if (bedrockIndex != -1) { + Enchantment enchantment = Enchantment.getByJavaIdentifier("minecraft:" + JavaEnchantment.values()[bedrockIndex].name().toLowerCase()); if (enchantment != null) { // Convert the Java enchantment index to Bedrock's - index = enchantment.ordinal(); + bedrockIndex = enchantment.ordinal(); } else { - index = -1; + // There is no Bedrock enchantment equivalent + bedrockIndex = -1; } } - enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].setJavaEnchantIndex(value); - enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].setBedrockEnchantIndex(index); + enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].setEnchantIndex(value, bedrockIndex); break; case 7: case 8: @@ -91,8 +94,9 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla default: return; } - if (shouldUpdate) { - enchantingInventory.getEnchantOptions()[slotToUpdate] = enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].build(session); + GeyserEnchantOption enchantOption = enchantingInventory.getGeyserEnchantOptions()[slotToUpdate]; + if (shouldUpdate && enchantOption.hasChanged()) { + enchantingInventory.getEnchantOptions()[slotToUpdate] = enchantOption.build(session); PlayerEnchantOptionsPacket packet = new PlayerEnchantOptionsPacket(); packet.getOptions().addAll(Arrays.asList(enchantingInventory.getEnchantOptions())); session.sendUpstreamPacket(packet); From bb41c0f9eef7c47de8edcd62ae76c6d71cb61a26 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 19 Apr 2021 22:18:18 -0400 Subject: [PATCH 5/5] Add an option for setting Bedrock compression level (#2128) --- .../connector/configuration/GeyserConfiguration.java | 2 ++ .../configuration/GeyserJacksonConfiguration.java | 7 +++++++ .../connector/network/ConnectorServerEventHandler.java | 1 + connector/src/main/resources/config.yml | 3 +++ 4 files changed, 13 insertions(+) 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 652ec1339..b6af30fed 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java @@ -111,6 +111,8 @@ public interface GeyserConfiguration { String getServerName(); + int getCompressionLevel(); + boolean isEnableProxyProtocol(); List getProxyProtocolWhitelistedIPs(); 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 e9adfe12b..f8b652e53 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java @@ -147,6 +147,13 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration @JsonProperty("server-name") private String serverName = GeyserConnector.NAME; + @JsonProperty("compression-level") + private int compressionLevel = 6; + + public int getCompressionLevel() { + return Math.max(-1, Math.min(compressionLevel, 9)); + } + @JsonProperty("enable-proxy-protocol") private boolean enableProxyProtocol = false; diff --git a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java index bd5030a8b..554ae9504 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -159,6 +159,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { @Override public void onSessionCreation(BedrockServerSession bedrockServerSession) { bedrockServerSession.setLogging(true); + bedrockServerSession.setCompressionLevel(connector.getConfig().getBedrock().getCompressionLevel()); bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserSession(connector, bedrockServerSession))); // Set the packet codec to default just in case we need to send disconnect packets. bedrockServerSession.setPacketCodec(BedrockProtocol.DEFAULT_BEDROCK_CODEC); diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index 6ccddd401..c81bfc675 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -23,6 +23,9 @@ bedrock: motd2: "Another Geyser server." # The Server Name that will be sent to Minecraft: Bedrock Edition clients. This is visible in both the pause menu and the settings menu. server-name: "Geyser" + # How much to compress network traffic to the Bedrock client. The higher the number, the more CPU usage used, but + # the smaller the bandwidth used. Does not have any effect below -1 or above 9. Set to -1 to disable. + compression-level: 6 # Whether to enable PROXY protocol or not for clients. You DO NOT WANT this feature unless you run UDP reverse proxy # in front of your Geyser instance. enable-proxy-protocol: false