From 50c4c0b2d8bb35bbe5de74681c9d19ac82692594 Mon Sep 17 00:00:00 2001 From: Luke <32024335+lukeeey@users.noreply.github.com> Date: Tue, 5 May 2020 14:10:27 +0100 Subject: [PATCH 001/581] Initial world border --- .../network/session/GeyserSession.java | 15 +++ .../java/world/JavaWorldBorderTranslator.java | 78 ++++++++++++ .../geysermc/connector/world/WorldBorder.java | 116 ++++++++++++++++++ 3 files changed, 209 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaWorldBorderTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/world/WorldBorder.java 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 51cc0923..88fba8b0 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 @@ -66,6 +66,7 @@ import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.utils.LocaleUtils; import org.geysermc.connector.utils.Toolbox; +import org.geysermc.connector.world.WorldBorder; import org.geysermc.floodgate.util.BedrockData; import org.geysermc.floodgate.util.EncryptionUtil; @@ -156,6 +157,9 @@ public class GeyserSession implements CommandSender { @Setter private int craftSlot = 0; + @Setter + private WorldBorder worldBorder; // Im just going to shove this here until i move some stuff around + public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { this.connector = connector; this.upstream = new UpstreamSession(bedrockServerSession); @@ -392,6 +396,17 @@ public class GeyserSession implements CommandSender { upstream.sendPacket(textPacket); } + public void sendActionBar(String text) { + SetTitlePacket setTitlePacket = new SetTitlePacket(); + setTitlePacket.setType(SetTitlePacket.Type.SET_ACTIONBAR_MESSAGE); + setTitlePacket.setText(text); + setTitlePacket.setFadeInTime(0); + setTitlePacket.setStayTime(0); + setTitlePacket.setFadeOutTime(0); + + upstream.sendPacket(setTitlePacket); + } + @Override public boolean isConsole() { return false; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaWorldBorderTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaWorldBorderTranslator.java new file mode 100644 index 00000000..6795e78f --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaWorldBorderTranslator.java @@ -0,0 +1,78 @@ +/* + * 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.java.world; + +import com.github.steveice10.mc.protocol.data.game.world.WorldBorderAction; +import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerWorldBorderPacket; +import com.nukkitx.math.vector.Vector2f; +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.world.WorldBorder; + +@Translator(packet = ServerWorldBorderPacket.class) +public class JavaWorldBorderTranslator extends PacketTranslator { + + @Override + public void translate(ServerWorldBorderPacket packet, GeyserSession session) { + WorldBorder worldBorder = session.getWorldBorder(); + + if(packet.getAction() != WorldBorderAction.INITIALIZE && worldBorder == null) { + return; + } + + switch(packet.getAction()) { + case INITIALIZE: + // should be getCenterZ() + worldBorder = new WorldBorder(Vector2f.from(packet.getCenterX(), packet.getCenterY()), packet.getRadius(), packet.getOldRadius(), packet.getNewRadius(), + packet.getSpeed(), packet.getWarningTime(), packet.getWarningTime()); + + session.setWorldBorder(worldBorder); + break; + case SET_SIZE: + worldBorder.setRadius(packet.getRadius()); + break; + case LERP_SIZE: + worldBorder.setOldRadius(packet.getOldRadius()); + worldBorder.setNewRadius(packet.getNewRadius()); + worldBorder.setSpeed(packet.getSpeed()); + break; + case SET_CENTER: + // should be getCenterZ() + worldBorder.setCenter(Vector2f.from(packet.getCenterX(), packet.getCenterY())); + break; + case SET_WARNING_TIME: + worldBorder.setWarningTime(packet.getWarningTime()); + return; + case SET_WARNING_BLOCKS: + worldBorder.setWarningBlocks(packet.getWarningBlocks()); + return; + } + + worldBorder.update(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/world/WorldBorder.java b/connector/src/main/java/org/geysermc/connector/world/WorldBorder.java new file mode 100644 index 00000000..f7ea173b --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/world/WorldBorder.java @@ -0,0 +1,116 @@ +/* + * 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.world; + +import com.nukkitx.math.vector.Vector2f; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.packet.TextPacket; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.geysermc.common.ChatColor; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.entity.PlayerEntity; +import org.geysermc.connector.network.session.GeyserSession; + +@Getter +@Setter +@RequiredArgsConstructor +public class WorldBorder { + private @NonNull Vector2f center; + private @NonNull double radius; + private @NonNull double oldRadius; + private @NonNull double newRadius; + private @NonNull long speed; + private @NonNull int warningTime; + private @NonNull int warningBlocks; + + private double minX; + private double minZ; + private double maxX; + private double maxZ; + + public void onTick(GeyserSession session) { + PlayerEntity player = session.getPlayerEntity(); + if(isNearEdge(player)) { + session.sendActionBar(ChatColor.BOLD + "" + ChatColor.RED + "You are near the world border (" + (int) getDistanceToEdge(player) + " blocks)"); + } + } + + /** + * Updates the min and max positions of the world border. + * This should be called every time there is a modifcation to either the center coordinates or the radius. + */ + public void update() { + this.minX = Math.max(center.getX() - newRadius / 2.0D, -newRadius); + this.minZ = Math.max(center.getY() - newRadius / 2.0D, -newRadius); + this.maxX = Math.min(center.getX() + newRadius / 2.0D, newRadius); + this.maxZ = Math.min(center.getY() + newRadius / 2.0D, newRadius); + } + + /** + * Checks if an entity is within the warning distance to the edge of the world border. + * https://wiki.vg/Protocol#World_Border + */ + public boolean isNearEdge(Entity entity) { + double distance = Math.max(Math.min(speed * 1000 * warningTime, Math.abs(newRadius - oldRadius)), warningBlocks); + + float entityDistance = (float) getDistanceToEdge(entity); + + if ((double) entityDistance < distance) { + return true; + } + return false; + } + + /** + * Checks if an entity is inside the world border. + * + * This method needs to be improved as it doesn't account for when the world border + * is currently changing size, it only accounts for the target size. + * + * Something similar to the method above should work. + */ + public boolean isInsideBorder(Entity entity) { + return entity.getPosition().getX() > minX && entity.getPosition().getX() < maxX && entity.getPosition().getZ() > minZ && entity.getPosition().getZ() < maxZ; + } + + /** + * Calculates how close the entity is to the edge of the world border. + */ + public double getDistanceToEdge(Entity entity) { + Vector3f pos = entity.getPosition(); + + double minPosZ = pos.getZ() - minZ; + double maxPosZ = maxZ - pos.getZ(); + double minPosX = pos.getX() - minX; + double maxPosX = maxX - pos.getX(); + + return Math.min(Math.min(Math.min(minPosX, maxPosX), minPosZ), maxPosZ); + } +} \ No newline at end of file From 96a7770c22cfc1db21cc2f840f511e543177710a Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 5 May 2020 16:48:01 +0100 Subject: [PATCH 002/581] Fixed entity bugs introduced by 6642f1e and added fishing lines (#483) * Fixed entity bugs introduced by 6642f1e * Fixed fishing line not displaying * Clean extra line and added todo --- .../connector/entity/EnderCrystalEntity.java | 1 - .../geysermc/connector/entity/ExpOrbEntity.java | 4 ---- .../connector/entity/FishingHookEntity.java | 14 ++++++++++++-- .../living/animal/TropicalFishEntity.java | 1 - .../living/animal/horse/TraderLlamaEntity.java | 8 ++++++++ .../entity/spawn/JavaSpawnObjectTranslator.java | 17 +++++++++++------ 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/EnderCrystalEntity.java b/connector/src/main/java/org/geysermc/connector/entity/EnderCrystalEntity.java index 31f7b8ed..727df90c 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/EnderCrystalEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/EnderCrystalEntity.java @@ -31,7 +31,6 @@ import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.EntityFlag; -import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/ExpOrbEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ExpOrbEntity.java index 2fd06c23..bfd3e1ca 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ExpOrbEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ExpOrbEntity.java @@ -27,13 +27,9 @@ package org.geysermc.connector.entity; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - public class ExpOrbEntity extends Entity { private int amount; diff --git a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java index e82a42a2..abd52292 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java @@ -25,13 +25,23 @@ package org.geysermc.connector.entity; +import com.github.steveice10.mc.protocol.data.game.entity.type.object.ProjectileData; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; +import com.nukkitx.protocol.bedrock.data.EntityData; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; public class FishingHookEntity extends Entity { - public FishingHookEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + public FishingHookEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, ProjectileData data) { super(entityId, geyserId, entityType, position, motion, rotation); + + // TODO: Find a better way to do this + for (GeyserSession session : GeyserConnector.getInstance().getPlayers().values()) { + if (session.getPlayerEntity().getEntityId() == data.getOwnerId()) { + this.metadata.put(EntityData.OWNER_EID, session.getPlayerEntity().getGeyserId()); + return; + } + } } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/TropicalFishEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/TropicalFishEntity.java index d5e9a687..a8866d7e 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/TropicalFishEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/TropicalFishEntity.java @@ -28,7 +28,6 @@ package org.geysermc.connector.entity.living.animal; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; import lombok.AllArgsConstructor; import lombok.Getter; import org.geysermc.connector.entity.living.AbstractFishEntity; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java index 08a71836..b9505509 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java @@ -26,11 +26,19 @@ package org.geysermc.connector.entity.living.animal.horse; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.EntityData; import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; public class TraderLlamaEntity extends LlamaEntity { public TraderLlamaEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } + + @Override + public void spawnEntity(GeyserSession session) { + this.metadata.put(EntityData.MARK_VARIANT, 1); + super.spawnEntity(session); + } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java index d544e24b..419f1e46 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java @@ -25,13 +25,15 @@ package org.geysermc.connector.network.translators.java.entity.spawn; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - import com.github.steveice10.mc.protocol.data.game.entity.type.object.FallingBlockData; import com.github.steveice10.mc.protocol.data.game.entity.type.object.HangingDirection; +import com.github.steveice10.mc.protocol.data.game.entity.type.object.ObjectType; +import com.github.steveice10.mc.protocol.data.game.entity.type.object.ProjectileData; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnObjectPacket; +import com.nukkitx.math.vector.Vector3f; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.FallingBlockEntity; +import org.geysermc.connector.entity.FishingHookEntity; import org.geysermc.connector.entity.ItemFrameEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -39,9 +41,8 @@ import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.EntityUtils; -import com.github.steveice10.mc.protocol.data.game.entity.type.object.ObjectType; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnObjectPacket; -import com.nukkitx.math.vector.Vector3f; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; @Translator(packet = ServerSpawnObjectPacket.class) public class JavaSpawnObjectTranslator extends PacketTranslator { @@ -69,6 +70,10 @@ public class JavaSpawnObjectTranslator extends PacketTranslator entityConstructor = entityClass.getConstructor(long.class, long.class, EntityType.class, Vector3f.class, Vector3f.class, Vector3f.class); From 7195d20fae8dbfb1d165e3cdb0d4dbca4cc3d3d7 Mon Sep 17 00:00:00 2001 From: Luke <32024335+lukeeey@users.noreply.github.com> Date: Tue, 5 May 2020 16:51:43 +0100 Subject: [PATCH 003/581] Implement helper methods for sending packets (#487) * Implement helper methods for sending packets, fixes an NPE when chatting before connecting to the remote server * Change method names * Add a space between doc comment lines * Add debug messages --- .../command/defaults/OffhandCommand.java | 2 +- .../org/geysermc/connector/entity/Entity.java | 16 +++---- .../geysermc/connector/entity/ItemEntity.java | 2 +- .../connector/entity/ItemFrameEntity.java | 6 +-- .../connector/entity/LivingEntity.java | 6 +-- .../connector/entity/PaintingEntity.java | 2 +- .../connector/entity/PlayerEntity.java | 10 ++-- .../living/animal/horse/LlamaEntity.java | 2 +- .../living/monster/EnderDragonEntity.java | 4 +- .../network/UpstreamPacketHandler.java | 6 +-- .../network/session/GeyserSession.java | 46 ++++++++++++++++++- .../network/session/cache/BossBar.java | 12 ++--- .../network/session/cache/WindowCache.java | 4 +- .../bedrock/BedrockActionTranslator.java | 26 +++++------ .../bedrock/BedrockAnimateTranslator.java | 2 +- .../BedrockBlockEntityDataTranslator.java | 2 +- .../BedrockCommandRequestTranslator.java | 2 +- .../BedrockContainerCloseTranslator.java | 2 +- .../bedrock/BedrockEntityEventTranslator.java | 2 +- .../bedrock/BedrockInteractTranslator.java | 4 +- ...BedrockInventoryTransactionTranslator.java | 22 ++++----- .../BedrockItemFrameDropItemTranslator.java | 2 +- .../BedrockLevelSoundEventTranslator.java | 2 +- .../BedrockMobEquipmentTranslator.java | 2 +- .../bedrock/BedrockMovePlayerTranslator.java | 8 ++-- .../bedrock/BedrockRespawnTranslator.java | 4 +- .../bedrock/BedrockShowCreditsTranslator.java | 2 +- .../bedrock/BedrockTextTranslator.java | 2 +- .../inventory/AnvilInventoryTranslator.java | 4 +- .../inventory/BrewingInventoryTranslator.java | 4 +- .../CraftingInventoryTranslator.java | 2 +- .../DoubleChestInventoryTranslator.java | 14 +++--- .../inventory/FurnaceInventoryTranslator.java | 2 +- .../inventory/PlayerInventoryTranslator.java | 17 ++++--- .../inventory/action/ClickPlan.java | 4 +- .../action/InventoryActionDataTranslator.java | 12 ++--- .../holder/BlockInventoryHolder.java | 8 ++-- .../updater/ChestInventoryUpdater.java | 4 +- .../updater/ContainerInventoryUpdater.java | 4 +- .../updater/CursorInventoryUpdater.java | 4 +- .../inventory/updater/InventoryUpdater.java | 4 +- .../translators/java/JavaChatTranslator.java | 2 +- .../java/JavaDeclareRecipesTranslator.java | 2 +- .../java/JavaDifficultyTranslator.java | 2 +- .../java/JavaJoinGameTranslator.java | 10 ++-- .../JavaLoginPluginMessageTranslator.java | 2 +- .../java/JavaPluginMessageTranslator.java | 2 +- .../java/JavaRespawnTranslator.java | 4 +- .../JavaServerDeclareCommandsTranslator.java | 2 +- .../translators/java/JavaTitleTranslator.java | 2 +- .../entity/JavaEntityAnimationTranslator.java | 2 +- .../entity/JavaEntityEffectTranslator.java | 2 +- .../entity/JavaEntityHeadLookTranslator.java | 4 +- .../JavaEntityRemoveEffectTranslator.java | 2 +- .../entity/JavaEntityRotationTranslator.java | 4 +- .../entity/JavaEntityStatusTranslator.java | 2 +- .../entity/JavaEntityVelocityTranslator.java | 2 +- .../player/JavaPlayerAbilitiesTranslator.java | 4 +- .../player/JavaPlayerActionAckTranslator.java | 6 +-- .../JavaPlayerChangeHeldItemTranslator.java | 2 +- .../player/JavaPlayerHealthTranslator.java | 2 +- .../player/JavaPlayerListEntryTranslator.java | 2 +- .../JavaPlayerPositionRotationTranslator.java | 12 ++--- .../player/JavaPlayerStopSoundTranslator.java | 2 +- .../window/JavaCloseWindowTranslator.java | 2 +- .../JavaConfirmTransactionTranslator.java | 5 +- .../java/window/JavaOpenWindowTranslator.java | 4 +- .../java/world/JavaBlockChangeTranslator.java | 2 +- .../java/world/JavaBlockValueTranslator.java | 14 +++--- .../java/world/JavaChunkDataTranslator.java | 2 +- .../java/world/JavaCollectItemTranslator.java | 2 +- .../java/world/JavaExplosionTranslator.java | 5 +- .../world/JavaNotifyClientTranslator.java | 14 +++--- .../world/JavaPlayBuiltinSoundTranslator.java | 4 +- .../java/world/JavaPlayEffectTranslator.java | 12 ++--- .../world/JavaPlayerPlaySoundTranslator.java | 2 +- .../world/JavaSpawnParticleTranslator.java | 12 ++--- .../world/JavaSpawnPositionTranslator.java | 2 +- .../java/world/JavaUpdateTimeTranslator.java | 4 +- .../block/BucketSoundInteractionHandler.java | 2 +- .../block/ComparatorSoundInteractHandler.java | 2 +- .../block/DoorSoundInteractionHandler.java | 2 +- .../FlintAndSteelInteractionHandler.java | 2 +- .../block/GrassPathInteractionHandler.java | 2 +- .../sound/block/HoeInteractionHandler.java | 2 +- .../block/LeverSoundInteractionHandler.java | 2 +- .../MilkCowSoundInteractionHandler.java | 2 +- .../FlowerPotBlockEntityTranslator.java | 2 +- .../NoteblockBlockEntityTranslator.java | 2 +- .../connector/scoreboard/Scoreboard.java | 12 ++--- .../connector/utils/BlockEntityUtils.java | 2 +- .../geysermc/connector/utils/ChunkUtils.java | 10 ++-- .../connector/utils/DimensionUtils.java | 4 +- .../connector/utils/InventoryUtils.java | 2 +- .../connector/utils/LoginEncryptionUtils.java | 4 +- .../geysermc/connector/utils/SkinUtils.java | 4 +- 96 files changed, 270 insertions(+), 235 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java index d181d07e..5392baed 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java @@ -55,7 +55,7 @@ public class OffhandCommand extends GeyserCommand { GeyserSession session = (GeyserSession) sender; ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0), BlockFace.DOWN); - session.getDownstream().getSession().send(releaseItemPacket); + session.sendDownstreamPacket(releaseItemPacket); } } } 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 7e8a190d..186c0ae8 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -119,7 +119,7 @@ public class Entity { addEntityPacket.getMetadata().putAll(metadata); valid = true; - session.getUpstream().sendPacket(addEntityPacket); + session.sendUpstreamPacket(addEntityPacket); session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); } @@ -135,7 +135,7 @@ public class Entity { RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket(); removeEntityPacket.setUniqueEntityId(geyserId); - session.getUpstream().sendPacket(removeEntityPacket); + session.sendUpstreamPacket(removeEntityPacket); valid = false; return true; @@ -156,7 +156,7 @@ public class Entity { moveEntityPacket.setOnGround(isOnGround); moveEntityPacket.setTeleported(false); - session.getUpstream().sendPacket(moveEntityPacket); + session.sendUpstreamPacket(moveEntityPacket); } public void moveAbsolute(GeyserSession session, Vector3f position, float yaw, float pitch, boolean isOnGround, boolean teleported) { @@ -174,7 +174,7 @@ public class Entity { moveEntityPacket.setOnGround(isOnGround); moveEntityPacket.setTeleported(teleported); - session.getUpstream().sendPacket(moveEntityPacket); + session.sendUpstreamPacket(moveEntityPacket); } public void updateBedrockAttributes(GeyserSession session) { @@ -191,7 +191,7 @@ public class Entity { UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket(); updateAttributesPacket.setRuntimeEntityId(geyserId); updateAttributesPacket.setAttributes(attributes); - session.getUpstream().sendPacket(updateAttributesPacket); + session.sendUpstreamPacket(updateAttributesPacket); } public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { @@ -218,13 +218,13 @@ public class Entity { else { useItemPacket = new ClientPlayerUseItemPacket(Hand.OFF_HAND); } - session.getDownstream().getSession().send(useItemPacket); + session.sendDownstreamPacket(useItemPacket); } } else if (session.getPlayerEntity().getEntityId() == entityId && !metadata.getFlags().getFlag(EntityFlag.SNEAKING) && metadata.getFlags().getFlag(EntityFlag.BLOCKING)) { metadata.getFlags().setFlag(EntityFlag.BLOCKING, false); metadata.getFlags().setFlag(EntityFlag.DISABLE_BLOCKING, true); ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0,0,0), BlockFace.DOWN); - session.getDownstream().getSession().send(releaseItemPacket); + session.sendDownstreamPacket(releaseItemPacket); } // metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20); if ((xd & 0x20) == 0x20) @@ -265,7 +265,7 @@ public class Entity { SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entityDataPacket.setRuntimeEntityId(geyserId); entityDataPacket.getMetadata().putAll(metadata); - session.getUpstream().sendPacket(entityDataPacket); + session.sendUpstreamPacket(entityDataPacket); } /** diff --git a/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java index a28b563b..b321213e 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java @@ -50,7 +50,7 @@ public class ItemEntity extends Entity { itemPacket.setFromFishing(false); itemPacket.getMetadata().putAll(metadata); itemPacket.setItemInHand(Translators.getItemTranslator().translateToBedrock(session, (ItemStack) entityMetadata.getValue())); - session.getUpstream().sendPacket(itemPacket); + session.sendUpstreamPacket(itemPacket); } super.updateBedrockMetadata(entityMetadata, session); 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 d49f6e17..16942898 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java @@ -149,7 +149,7 @@ public class ItemFrameEntity extends Entity { updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NONE); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); - session.getUpstream().sendPacket(updateBlockPacket); + session.sendUpstreamPacket(updateBlockPacket); session.getItemFrameCache().remove(position, entityId); valid = false; return true; @@ -179,7 +179,7 @@ public class ItemFrameEntity extends Entity { updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NONE); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); - session.getUpstream().sendPacket(updateBlockPacket); + session.sendUpstreamPacket(updateBlockPacket); BlockEntityDataPacket blockEntityDataPacket = new BlockEntityDataPacket(); blockEntityDataPacket.setBlockPosition(bedrockPosition); @@ -189,7 +189,7 @@ public class ItemFrameEntity extends Entity { blockEntityDataPacket.setData(getDefaultTag()); } - session.getUpstream().sendPacket(blockEntityDataPacket); + session.sendUpstreamPacket(blockEntityDataPacket); }, 500, TimeUnit.MILLISECONDS); } 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 40b30f70..f5aa4a54 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java @@ -96,8 +96,8 @@ public class LivingEntity extends Entity { offHandPacket.setInventorySlot(0); offHandPacket.setContainerId(ContainerId.OFFHAND); - session.getUpstream().sendPacket(armorEquipmentPacket); - session.getUpstream().sendPacket(handPacket); - session.getUpstream().sendPacket(offHandPacket); + session.sendUpstreamPacket(armorEquipmentPacket); + session.sendUpstreamPacket(handPacket); + session.sendUpstreamPacket(offHandPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java index 87ff9a35..56e07733 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java @@ -55,7 +55,7 @@ public class PaintingEntity extends Entity { addPaintingPacket.setName(paintingName.getBedrockName()); addPaintingPacket.setPosition(fixOffset(true)); addPaintingPacket.setDirection(direction); - session.getUpstream().sendPacket(addPaintingPacket); + session.sendUpstreamPacket(addPaintingPacket); valid = true; diff --git a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java index d4732168..82e91f55 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java @@ -94,7 +94,7 @@ public class PlayerEntity extends LivingEntity { addPlayerPacket.getMetadata().putAll(metadata); valid = true; - session.getUpstream().sendPacket(addPlayerPacket); + session.sendUpstreamPacket(addPlayerPacket); updateEquipment(session); updateBedrockAttributes(session); @@ -108,7 +108,7 @@ public class PlayerEntity extends LivingEntity { PlayerListPacket playerList = new PlayerListPacket(); playerList.setAction(PlayerListPacket.Action.ADD); playerList.getEntries().add(SkinUtils.buildDefaultEntry(profile, geyserId)); - session.getUpstream().sendPacket(playerList); + session.sendUpstreamPacket(playerList); } } @@ -124,7 +124,7 @@ public class PlayerEntity extends LivingEntity { PlayerListPacket playerList = new PlayerListPacket(); playerList.setAction(PlayerListPacket.Action.REMOVE); playerList.getEntries().add(new PlayerListPacket.Entry(uuid)); - session.getUpstream().sendPacket(playerList); + session.sendUpstreamPacket(playerList); }); } } @@ -145,7 +145,7 @@ public class PlayerEntity extends LivingEntity { movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.UNKNOWN); } - session.getUpstream().sendPacket(movePlayerPacket); + session.sendUpstreamPacket(movePlayerPacket); } @Override @@ -159,7 +159,7 @@ public class PlayerEntity extends LivingEntity { movePlayerPacket.setRotation(getBedrockRotation()); movePlayerPacket.setOnGround(isOnGround); movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL); - session.getUpstream().sendPacket(movePlayerPacket); + session.sendUpstreamPacket(movePlayerPacket); } @Override 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 c2dad7a5..d4d7b726 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 @@ -65,7 +65,7 @@ public class LlamaEntity extends ChestedHorseEntity { equipmentPacket.setHelmet(ItemData.AIR); equipmentPacket.setLeggings(ItemData.AIR); - session.getUpstream().sendPacket(equipmentPacket); + session.sendUpstreamPacket(equipmentPacket); } // Color of the llama if (entityMetadata.getId() == 21) { diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/EnderDragonEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/EnderDragonEntity.java index b0737738..394be544 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/EnderDragonEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/EnderDragonEntity.java @@ -53,7 +53,7 @@ public class EnderDragonEntity extends InsentientEntity { entityEventPacket.setType(EntityEventType.DRAGON_FLAMING); entityEventPacket.setRuntimeEntityId(geyserId); entityEventPacket.setData(0); - session.getUpstream().sendPacket(entityEventPacket); + session.sendUpstreamPacket(entityEventPacket); case 6: case 7: metadata.getFlags().setFlag(EntityFlag.SITTING, true); @@ -79,7 +79,7 @@ public class EnderDragonEntity extends InsentientEntity { addEntityPacket.getAttributes().add(new Attribute("minecraft:health", 0.0f, 200f, 200f, 200f)); valid = true; - session.getUpstream().sendPacket(addEntityPacket); + session.sendUpstreamPacket(addEntityPacket); session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); } 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 2839237e..dfc3112b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -58,10 +58,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { PlayStatusPacket playStatus = new PlayStatusPacket(); playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS); - session.getUpstream().sendPacket(playStatus); + session.sendUpstreamPacket(playStatus); ResourcePacksInfoPacket resourcePacksInfo = new ResourcePacksInfoPacket(); - session.getUpstream().sendPacket(resourcePacksInfo); + session.sendUpstreamPacket(resourcePacksInfo); return true; } @@ -77,7 +77,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { stack.setExperimental(false); stack.setForcedToAccept(false); stack.setGameVersion("*"); - session.getUpstream().sendPacket(stack); + session.sendUpstreamPacket(stack); break; default: session.disconnect("disconnectionScreen.resourcePack"); 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 51cc0923..9068456c 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 @@ -29,6 +29,7 @@ import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.exception.request.InvalidCredentialsException; import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.protocol.MinecraftProtocol; +import com.github.steveice10.mc.protocol.data.SubProtocol; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; @@ -41,6 +42,7 @@ import com.github.steveice10.packetlib.tcp.TcpSessionFactory; import com.nukkitx.math.GenericMath; import com.nukkitx.math.TrigMath; import com.nukkitx.math.vector.*; +import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.data.ContainerId; import com.nukkitx.protocol.bedrock.data.GamePublishSetting; @@ -156,6 +158,8 @@ public class GeyserSession implements CommandSender { @Setter private int craftSlot = 0; + private MinecraftProtocol protocol; + public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { this.connector = connector; this.upstream = new UpstreamSession(bedrockServerSession); @@ -227,7 +231,6 @@ public class GeyserSession implements CommandSender { // new thread so clients don't timeout new Thread(() -> { try { - MinecraftProtocol protocol; if (password != null && !password.isEmpty()) { protocol = new MinecraftProtocol(username, password); } else { @@ -481,8 +484,47 @@ public class GeyserSession implements CommandSender { int teleportId = teleportCache.getTeleportConfirmId(); teleportCache = null; ClientTeleportConfirmPacket teleportConfirmPacket = new ClientTeleportConfirmPacket(teleportId); - getDownstream().getSession().send(teleportConfirmPacket); + sendDownstreamPacket(teleportConfirmPacket); } return true; } + + /** + * Queue a packet to be sent to player. + * + * @param packet the bedrock packet from the NukkitX protocol lib + */ + public void sendUpstreamPacket(BedrockPacket packet) { + if (upstream != null && !upstream.isClosed()) { + upstream.sendPacket(packet); + } else { + connector.getLogger().debug("Tried to send upstream packet " + packet.getClass().getSimpleName() + " but the session was null"); + } + } + + /** + * Send a packet immediately to the player. + * + * @param packet the bedrock packet from the NukkitX protocol lib + */ + public void sendUpstreamPacketImmediately(BedrockPacket packet) { + if (upstream != null && !upstream.isClosed()) { + upstream.sendPacketImmediately(packet); + } else { + connector.getLogger().debug("Tried to send upstream packet " + packet.getClass().getSimpleName() + " immediately but the session was null"); + } + } + + /** + * Send a packet to the remote server. + * + * @param packet the java edition packet from MCProtocolLib + */ + public void sendDownstreamPacket(Packet packet) { + if (downstream != null && downstream.getSession() != null && protocol.getSubProtocol().equals(SubProtocol.GAME)) { + downstream.getSession().send(packet); + } else { + connector.getLogger().debug("Tried to send downstream packet " + packet.getClass().getSimpleName() + " before connected to the server"); + } + } } diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java index abb9016a..1fde179d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java @@ -62,7 +62,7 @@ public class BossBar { bossEventPacket.setOverlay(overlay); bossEventPacket.setDarkenSky(darkenSky); - session.getUpstream().sendPacket(bossEventPacket); + session.sendUpstreamPacket(bossEventPacket); } public void updateTitle(Message title) { @@ -72,7 +72,7 @@ public class BossBar { bossEventPacket.setAction(BossEventPacket.Action.TITLE); bossEventPacket.setTitle(MessageUtils.getTranslatedBedrockMessage(title, session.getClientData().getLanguageCode())); - session.getUpstream().sendPacket(bossEventPacket); + session.sendUpstreamPacket(bossEventPacket); } public void updateHealth(float health) { @@ -82,7 +82,7 @@ public class BossBar { bossEventPacket.setAction(BossEventPacket.Action.HEALTH_PERCENTAGE); bossEventPacket.setHealthPercentage(health); - session.getUpstream().sendPacket(bossEventPacket); + session.sendUpstreamPacket(bossEventPacket); } public void removeBossBar() { @@ -90,7 +90,7 @@ public class BossBar { bossEventPacket.setBossUniqueEntityId(entityId); bossEventPacket.setAction(BossEventPacket.Action.HIDE); - session.getUpstream().sendPacket(bossEventPacket); + session.sendUpstreamPacket(bossEventPacket); removeBossEntity(); } @@ -109,13 +109,13 @@ public class BossBar { addEntityPacket.setMotion(Vector3f.ZERO); addEntityPacket.getMetadata().put(EntityData.SCALE, 0.01F); // scale = 0 doesn't work? - session.getUpstream().sendPacket(addEntityPacket); + session.sendUpstreamPacket(addEntityPacket); } private void removeBossEntity() { RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket(); removeEntityPacket.setUniqueEntityId(entityId); - session.getUpstream().sendPacket(removeEntityPacket); + session.sendUpstreamPacket(removeEntityPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java index 1d10e4db..15b9a770 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java @@ -66,7 +66,7 @@ public class WindowCache { formRequestPacket.setFormId(id); formRequestPacket.setFormData(windows.get(id).getJSONData()); - session.getUpstream().sendPacket(formRequestPacket); + session.sendUpstreamPacket(formRequestPacket); } public void showWindow(FormWindow window, int id) { @@ -74,7 +74,7 @@ public class WindowCache { formRequestPacket.setFormId(id); formRequestPacket.setFormData(window.getJSONData()); - session.getUpstream().sendPacket(formRequestPacket); + session.sendUpstreamPacket(formRequestPacket); addWindow(window, id); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java index d7248aa3..2c44e4fd 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java @@ -64,44 +64,44 @@ public class BedrockActionTranslator extends PacketTranslator { case SWING_ARM: // Delay so entity damage can be processed first session.getConnector().getGeneralThreadPool().schedule(() -> - session.getDownstream().getSession().send(new ClientPlayerSwingArmPacket(Hand.MAIN_HAND)), + session.sendDownstreamPacket(new ClientPlayerSwingArmPacket(Hand.MAIN_HAND)), 25, TimeUnit.MILLISECONDS ); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockEntityDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockEntityDataTranslator.java index dc076a91..9fe62bb4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockEntityDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockEntityDataTranslator.java @@ -79,7 +79,7 @@ public class BedrockBlockEntityDataTranslator extends PacketTranslator } ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), InteractAction.INTERACT, Hand.MAIN_HAND); - session.getDownstream().getSession().send(interactPacket); + session.sendDownstreamPacket(interactPacket); break; case DAMAGE: ClientPlayerInteractEntityPacket attackPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), InteractAction.ATTACK, Hand.MAIN_HAND); - session.getDownstream().getSession().send(attackPacket); + session.sendDownstreamPacket(attackPacket); break; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java index ed928959..71ba20e4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java @@ -84,8 +84,8 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator { respawnPacket.setRuntimeEntityId(0); respawnPacket.setPosition(Vector3f.ZERO); respawnPacket.setState(RespawnPacket.State.SERVER_SEARCHING); - session.getUpstream().sendPacket(respawnPacket); + session.sendUpstreamPacket(respawnPacket); ClientRequestPacket javaRespawnPacket = new ClientRequestPacket(ClientRequest.RESPAWN); - session.getDownstream().getSession().send(javaRespawnPacket); + session.sendDownstreamPacket(javaRespawnPacket); } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockShowCreditsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockShowCreditsTranslator.java index 161397b6..4f0af78c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockShowCreditsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockShowCreditsTranslator.java @@ -40,7 +40,7 @@ public class BedrockShowCreditsTranslator extends PacketTranslator { } ClientChatPacket chatPacket = new ClientChatPacket(message); - session.getDownstream().getSession().send(chatPacket); + session.sendDownstreamPacket(chatPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java index 8df72d36..f301d2b5 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java @@ -108,7 +108,7 @@ public class AnvilInventoryTranslator extends BlockInventoryTranslator { rename = ""; } ClientRenameItemPacket renameItemPacket = new ClientRenameItemPacket(rename); - session.getDownstream().getSession().send(renameItemPacket); + session.sendDownstreamPacket(renameItemPacket); } if (anvilResult != null) { //client will send another packet to grab anvil output @@ -138,7 +138,7 @@ public class AnvilInventoryTranslator extends BlockInventoryTranslator { rename = ""; } ClientRenameItemPacket renameItemPacket = new ClientRenameItemPacket(rename); - session.getDownstream().getSession().send(renameItemPacket); + session.sendDownstreamPacket(renameItemPacket); } } super.updateSlot(session, inventory, slot); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BrewingInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BrewingInventoryTranslator.java index bd143698..acda7c91 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BrewingInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BrewingInventoryTranslator.java @@ -44,7 +44,7 @@ public class BrewingInventoryTranslator extends BlockInventoryTranslator { dataPacket.setWindowId((byte) inventory.getId()); dataPacket.setProperty(ContainerSetDataPacket.BREWING_STAND_FUEL_TOTAL); dataPacket.setValue(20); - session.getUpstream().sendPacket(dataPacket); + session.sendUpstreamPacket(dataPacket); } @Override @@ -62,7 +62,7 @@ public class BrewingInventoryTranslator extends BlockInventoryTranslator { return; } dataPacket.setValue(value); - session.getUpstream().sendPacket(dataPacket); + session.sendUpstreamPacket(dataPacket); } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java index 92a1d90e..3f887001 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java @@ -59,7 +59,7 @@ public class CraftingInventoryTranslator extends BaseInventoryTranslator { containerOpenPacket.setType((byte) ContainerType.WORKBENCH.id()); containerOpenPacket.setBlockPosition(inventory.getHolderPosition()); containerOpenPacket.setUniqueEntityId(inventory.getHolderId()); - session.getUpstream().sendPacket(containerOpenPacket); + session.sendUpstreamPacket(containerOpenPacket); } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/DoubleChestInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/DoubleChestInventoryTranslator.java index 720280b4..8c5b2cf2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/DoubleChestInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/DoubleChestInventoryTranslator.java @@ -60,7 +60,7 @@ public class DoubleChestInventoryTranslator extends BaseInventoryTranslator { blockPacket.setBlockPosition(position); blockPacket.setRuntimeId(blockId); blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); - session.getUpstream().sendPacket(blockPacket); + session.sendUpstreamPacket(blockPacket); CompoundTag tag = CompoundTag.builder() .stringTag("id", "Chest") @@ -73,14 +73,14 @@ public class DoubleChestInventoryTranslator extends BaseInventoryTranslator { BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag); dataPacket.setBlockPosition(position); - session.getUpstream().sendPacket(dataPacket); + session.sendUpstreamPacket(dataPacket); blockPacket = new UpdateBlockPacket(); blockPacket.setDataLayer(0); blockPacket.setBlockPosition(pairPosition); blockPacket.setRuntimeId(blockId); blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); - session.getUpstream().sendPacket(blockPacket); + session.sendUpstreamPacket(blockPacket); tag = CompoundTag.builder() .stringTag("id", "Chest") @@ -93,7 +93,7 @@ public class DoubleChestInventoryTranslator extends BaseInventoryTranslator { dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag); dataPacket.setBlockPosition(pairPosition); - session.getUpstream().sendPacket(dataPacket); + session.sendUpstreamPacket(dataPacket); inventory.setHolderPosition(position); } @@ -105,7 +105,7 @@ public class DoubleChestInventoryTranslator extends BaseInventoryTranslator { containerOpenPacket.setType((byte) ContainerType.CONTAINER.id()); containerOpenPacket.setBlockPosition(inventory.getHolderPosition()); containerOpenPacket.setUniqueEntityId(inventory.getHolderId()); - session.getUpstream().sendPacket(containerOpenPacket); + session.sendUpstreamPacket(containerOpenPacket); } @Override @@ -117,7 +117,7 @@ public class DoubleChestInventoryTranslator extends BaseInventoryTranslator { blockPacket.setDataLayer(0); blockPacket.setBlockPosition(holderPos); blockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(realBlock)); - session.getUpstream().sendPacket(blockPacket); + session.sendUpstreamPacket(blockPacket); holderPos = holderPos.add(Vector3i.UNIT_X); pos = new Position(holderPos.getX(), holderPos.getY(), holderPos.getZ()); @@ -126,7 +126,7 @@ public class DoubleChestInventoryTranslator extends BaseInventoryTranslator { blockPacket.setDataLayer(0); blockPacket.setBlockPosition(holderPos); blockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(realBlock)); - session.getUpstream().sendPacket(blockPacket); + session.sendUpstreamPacket(blockPacket); } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/FurnaceInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/FurnaceInventoryTranslator.java index 9b45201e..5c6de0e8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/FurnaceInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/FurnaceInventoryTranslator.java @@ -58,7 +58,7 @@ public class FurnaceInventoryTranslator extends BlockInventoryTranslator { return; } dataPacket.setValue(value); - session.getUpstream().sendPacket(dataPacket); + session.sendUpstreamPacket(dataPacket); } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java index 668612c5..b711bddc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java @@ -34,7 +34,6 @@ import com.nukkitx.protocol.bedrock.data.InventorySource; import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; -import it.unimi.dsi.fastutil.longs.LongArraySet; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.Translators; @@ -66,7 +65,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { contents[i - 36] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)); } inventoryContentPacket.setContents(contents); - session.getUpstream().sendPacket(inventoryContentPacket); + session.sendUpstreamPacket(inventoryContentPacket); // Armor InventoryContentPacket armorContentPacket = new InventoryContentPacket(); @@ -76,13 +75,13 @@ public class PlayerInventoryTranslator extends InventoryTranslator { contents[i - 5] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)); } armorContentPacket.setContents(contents); - session.getUpstream().sendPacket(armorContentPacket); + session.sendUpstreamPacket(armorContentPacket); // Offhand InventoryContentPacket offhandPacket = new InventoryContentPacket(); offhandPacket.setContainerId(ContainerId.OFFHAND); offhandPacket.setContents(new ItemData[]{Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(45))}); - session.getUpstream().sendPacket(offhandPacket); + session.sendUpstreamPacket(offhandPacket); } /** @@ -103,7 +102,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i))); } - session.getUpstream().sendPacket(slotPacket); + session.sendUpstreamPacket(slotPacket); } } @@ -126,12 +125,12 @@ public class PlayerInventoryTranslator extends InventoryTranslator { slotPacket.setSlot(slot + 27); } slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(slot))); - session.getUpstream().sendPacket(slotPacket); + session.sendUpstreamPacket(slotPacket); } else if (slot == 45) { InventoryContentPacket offhandPacket = new InventoryContentPacket(); offhandPacket.setContainerId(ContainerId.OFFHAND); offhandPacket.setContents(new ItemData[]{Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(slot))}); - session.getUpstream().sendPacket(offhandPacket); + session.sendUpstreamPacket(offhandPacket); } } @@ -204,7 +203,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { javaItem = Translators.getItemTranslator().translateToJava(session, action.getToItem()); } ClientCreativeInventoryActionPacket creativePacket = new ClientCreativeInventoryActionPacket(javaSlot, javaItem); - session.getDownstream().getSession().send(creativePacket); + session.sendDownstreamPacket(creativePacket); inventory.setItem(javaSlot, javaItem); break; case ContainerId.CURSOR: @@ -217,7 +216,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { && action.getSource().getFlag() == InventorySource.Flag.DROP_ITEM) { javaItem = Translators.getItemTranslator().translateToJava(session, action.getToItem()); ClientCreativeInventoryActionPacket creativeDropPacket = new ClientCreativeInventoryActionPacket(-1, javaItem); - session.getDownstream().getSession().send(creativeDropPacket); + session.sendDownstreamPacket(creativeDropPacket); } break; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/ClickPlan.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/ClickPlan.java index cdc42f96..a9c1eddc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/ClickPlan.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/ClickPlan.java @@ -104,8 +104,8 @@ class ClickPlan { break; } } - session.getDownstream().getSession().send(clickPacket); - session.getDownstream().getSession().send(new ClientConfirmTransactionPacket(inventory.getId(), actionId, true)); + session.sendDownstreamPacket(clickPacket); + session.sendDownstreamPacket(new ClientConfirmTransactionPacket(inventory.getId(), actionId, true)); } /*if (refresh) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java index 370d4177..0c267775 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java @@ -94,7 +94,7 @@ public class InventoryActionDataTranslator { ClientPlayerActionPacket actionPacket = new ClientPlayerActionPacket( sourceAction.getToItem().getCount() == 0 ? PlayerAction.DROP_ITEM_STACK : PlayerAction.DROP_ITEM, new Position(0, 0, 0), BlockFace.DOWN); - session.getDownstream().getSession().send(actionPacket); + session.sendDownstreamPacket(actionPacket); ItemStack item = session.getInventory().getItem(heldSlot); if (item != null) { session.getInventory().setItem(heldSlot, new ItemStack(item.getId(), item.getAmount() - 1, item.getNbt())); @@ -110,14 +110,14 @@ public class InventoryActionDataTranslator { inventory.getTransactionId().getAndIncrement(), javaSlot, null, WindowAction.DROP_ITEM, DropItemParam.DROP_SELECTED_STACK); - session.getDownstream().getSession().send(dropPacket); + session.sendDownstreamPacket(dropPacket); } else { for (int i = 0; i < dropAmount; i++) { ClientWindowActionPacket dropPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(), javaSlot, null, WindowAction.DROP_ITEM, DropItemParam.DROP_FROM_SELECTED); - session.getDownstream().getSession().send(dropPacket); + session.sendDownstreamPacket(dropPacket); } } ItemStack item = session.getInventory().getItem(javaSlot); @@ -129,7 +129,7 @@ public class InventoryActionDataTranslator { ClientWindowActionPacket dropPacket = new ClientWindowActionPacket(inventory.getId(), inventory.getTransactionId().getAndIncrement(), -999, null, WindowAction.CLICK_ITEM, dropAmount > 1 ? ClickItemParam.LEFT_CLICK : ClickItemParam.RIGHT_CLICK); - session.getDownstream().getSession().send(dropPacket); + session.sendDownstreamPacket(dropPacket); ItemStack cursor = session.getInventory().getCursor(); if (cursor != null) { session.getInventory().setCursor(new ItemStack(cursor.getId(), dropAmount > 1 ? 0 : cursor.getAmount() - 1, cursor.getNbt())); @@ -180,7 +180,7 @@ public class InventoryActionDataTranslator { inventory.getTransactionId().getAndIncrement(), javaSlot, InventoryUtils.REFRESH_ITEM, WindowAction.SHIFT_CLICK_ITEM, ShiftClickItemParam.LEFT_CLICK); - session.getDownstream().getSession().send(shiftClickPacket); + session.sendDownstreamPacket(shiftClickPacket); translator.updateInventory(session, inventory); return; } @@ -266,7 +266,7 @@ public class InventoryActionDataTranslator { inventory.getTransactionId().getAndIncrement(), fromSlot, InventoryUtils.REFRESH_ITEM, WindowAction.SHIFT_CLICK_ITEM, ShiftClickItemParam.LEFT_CLICK); - session.getDownstream().getSession().send(shiftClickPacket); + session.sendDownstreamPacket(shiftClickPacket); translator.updateInventory(session, inventory); return; } else if (translator.getSlotType(fromSlot) == SlotType.OUTPUT) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java index a6e5b2dd..67ce2ce1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java @@ -54,7 +54,7 @@ public class BlockInventoryHolder extends InventoryHolder { blockPacket.setBlockPosition(position); blockPacket.setRuntimeId(blockId); blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); - session.getUpstream().sendPacket(blockPacket); + session.sendUpstreamPacket(blockPacket); inventory.setHolderPosition(position); CompoundTag tag = CompoundTag.builder() @@ -65,7 +65,7 @@ public class BlockInventoryHolder extends InventoryHolder { BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag); dataPacket.setBlockPosition(position); - session.getUpstream().sendPacket(dataPacket); + session.sendUpstreamPacket(dataPacket); } @Override @@ -75,7 +75,7 @@ public class BlockInventoryHolder extends InventoryHolder { containerOpenPacket.setType((byte) containerType.id()); containerOpenPacket.setBlockPosition(inventory.getHolderPosition()); containerOpenPacket.setUniqueEntityId(inventory.getHolderId()); - session.getUpstream().sendPacket(containerOpenPacket); + session.sendUpstreamPacket(containerOpenPacket); } @Override @@ -87,6 +87,6 @@ public class BlockInventoryHolder extends InventoryHolder { blockPacket.setDataLayer(0); blockPacket.setBlockPosition(holderPos); blockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(realBlock)); - session.getUpstream().sendPacket(blockPacket); + session.sendUpstreamPacket(blockPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java index e8e0fc45..8318081d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java @@ -54,7 +54,7 @@ public class ChestInventoryUpdater extends InventoryUpdater { InventoryContentPacket contentPacket = new InventoryContentPacket(); contentPacket.setContainerId(inventory.getId()); contentPacket.setContents(bedrockItems); - session.getUpstream().sendPacket(contentPacket); + session.sendUpstreamPacket(contentPacket); } @Override @@ -66,7 +66,7 @@ public class ChestInventoryUpdater extends InventoryUpdater { slotPacket.setContainerId(inventory.getId()); slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot)); slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot))); - session.getUpstream().sendPacket(slotPacket); + session.sendUpstreamPacket(slotPacket); return true; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ContainerInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ContainerInventoryUpdater.java index d187ffd9..d25705e2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ContainerInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ContainerInventoryUpdater.java @@ -46,7 +46,7 @@ public class ContainerInventoryUpdater extends InventoryUpdater { InventoryContentPacket contentPacket = new InventoryContentPacket(); contentPacket.setContainerId(inventory.getId()); contentPacket.setContents(bedrockItems); - session.getUpstream().sendPacket(contentPacket); + session.sendUpstreamPacket(contentPacket); } @Override @@ -58,7 +58,7 @@ public class ContainerInventoryUpdater extends InventoryUpdater { slotPacket.setContainerId(inventory.getId()); slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot)); slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot))); - session.getUpstream().sendPacket(slotPacket); + session.sendUpstreamPacket(slotPacket); return true; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/CursorInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/CursorInventoryUpdater.java index e3dc1864..6a93ecd3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/CursorInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/CursorInventoryUpdater.java @@ -45,7 +45,7 @@ public class CursorInventoryUpdater extends InventoryUpdater { slotPacket.setContainerId(ContainerId.CURSOR); slotPacket.setSlot(bedrockSlot); slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i))); - session.getUpstream().sendPacket(slotPacket); + session.sendUpstreamPacket(slotPacket); } } @@ -58,7 +58,7 @@ public class CursorInventoryUpdater extends InventoryUpdater { slotPacket.setContainerId(ContainerId.CURSOR); slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot)); slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot))); - session.getUpstream().sendPacket(slotPacket); + session.sendUpstreamPacket(slotPacket); return true; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/InventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/InventoryUpdater.java index 2f139e27..ebca038a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/InventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/InventoryUpdater.java @@ -44,7 +44,7 @@ public abstract class InventoryUpdater { InventoryContentPacket contentPacket = new InventoryContentPacket(); contentPacket.setContainerId(ContainerId.INVENTORY); contentPacket.setContents(bedrockItems); - session.getUpstream().sendPacket(contentPacket); + session.sendUpstreamPacket(contentPacket); } public boolean updateSlot(InventoryTranslator translator, GeyserSession session, Inventory inventory, int javaSlot) { @@ -53,7 +53,7 @@ public abstract class InventoryUpdater { slotPacket.setContainerId(ContainerId.INVENTORY); slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot)); slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot))); - session.getUpstream().sendPacket(slotPacket); + session.sendUpstreamPacket(slotPacket); return true; } return false; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java index a527866c..53ce6811 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java @@ -76,6 +76,6 @@ public class JavaChatTranslator extends PacketTranslator { textPacket.setMessage(MessageUtils.getTranslatedBedrockMessage(packet.getMessage(), locale, false)); } - session.getUpstream().sendPacket(textPacket); + session.sendUpstreamPacket(textPacket); } } 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 c78493a3..b6a25e54 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 @@ -90,7 +90,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator skinParts = Arrays.asList(SkinPart.values()); ClientSettingsPacket clientSettingsPacket = new ClientSettingsPacket(locale, (byte) session.getRenderDistance(), ChatVisibility.FULL, true, skinParts, Hand.MAIN_HAND); - session.getDownstream().getSession().send(clientSettingsPacket); + session.sendDownstreamPacket(clientSettingsPacket); if (DimensionUtils.javaToBedrock(packet.getDimension()) != entity.getDimension()) { DimensionUtils.switchDimension(session, packet.getDimension()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaLoginPluginMessageTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaLoginPluginMessageTranslator.java index 1ce17fe9..f2a2bf02 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaLoginPluginMessageTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaLoginPluginMessageTranslator.java @@ -12,7 +12,7 @@ public class JavaLoginPluginMessageTranslator extends PacketTranslator SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); playerGameTypePacket.setGamemode(packet.getGamemode().ordinal()); - session.getUpstream().sendPacket(playerGameTypePacket); + session.sendUpstreamPacket(playerGameTypePacket); session.setGameMode(packet.getGamemode()); LevelEventPacket stopRainPacket = new LevelEventPacket(); stopRainPacket.setType(LevelEventType.STOP_RAIN); stopRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000); stopRainPacket.setPosition(Vector3f.ZERO); - session.getUpstream().sendPacket(stopRainPacket); + session.sendUpstreamPacket(stopRainPacket); if (entity.getDimension() != DimensionUtils.javaToBedrock(packet.getDimension())) { DimensionUtils.switchDimension(session, packet.getDimension()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java index 0e329669..6f16f8b4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -100,7 +100,7 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator { break; } - session.getUpstream().sendPacket(titlePacket); + session.sendUpstreamPacket(titlePacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAnimationTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAnimationTranslator.java index 9d8853e7..4f2fe022 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAnimationTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAnimationTranslator.java @@ -62,6 +62,6 @@ public class JavaEntityAnimationTranslator extends PacketTranslator playerFlags = new ObjectOpenHashSet<>(); playerFlags.add(AdventureSettingsPacket.Flag.AUTO_JUMP); @@ -73,6 +73,6 @@ public class JavaPlayerAbilitiesTranslator extends PacketTranslator " + stopSoundPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaCloseWindowTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaCloseWindowTranslator.java index 8162b82a..7360cbb2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaCloseWindowTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaCloseWindowTranslator.java @@ -39,7 +39,7 @@ public class JavaCloseWindowTranslator extends PacketTranslator { @@ -41,7 +38,7 @@ public class JavaConfirmTransactionTranslator extends PacketTranslator 0 ? 1 : 0); - session.getUpstream().sendPacket(blockEventPacket); + session.sendUpstreamPacket(blockEventPacket); } if (packet.getValue() instanceof EndGatewayValue) { blockEventPacket.setEventType(1); - session.getUpstream().sendPacket(blockEventPacket); + session.sendUpstreamPacket(blockEventPacket); } if (packet.getValue() instanceof NoteBlockValue) { NoteblockBlockEntityTranslator.translate(session, packet.getPosition()); @@ -77,15 +77,15 @@ public class JavaBlockValueTranslator extends PacketTranslator extendPiston(session, position, (progress >= 1.0f) ? 1.0f : progress + 0.5f, progress), @@ -121,7 +121,7 @@ public class JavaBlockValueTranslator extends PacketTranslator retractPiston(session, position, (progress <= 0.0f) ? 0.0f : progress - 0.5f, progress), diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java index 9e2d2ae7..2af7bb5b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java @@ -98,7 +98,7 @@ public class JavaChunkDataTranslator extends PacketTranslator blockEntityEntry : chunkData.getLoadBlockEntitiesLater().object2IntEntrySet()) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaCollectItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaCollectItemTranslator.java index b4287b08..31379bd2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaCollectItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaCollectItemTranslator.java @@ -50,6 +50,6 @@ public class JavaCollectItemTranslator extends PacketTranslator playerFlags = new ObjectOpenHashSet<>(); @@ -89,14 +89,14 @@ public class JavaNotifyClientTranslator extends PacketTranslator " + soundPacket.toString()); } } 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 e22db97e..8e76d7d8 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 @@ -90,12 +90,12 @@ public class JavaPlayEffectTranslator extends PacketTranslator " + playSoundPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java index 1f9bcba3..d6da1c81 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java @@ -52,7 +52,7 @@ public class JavaSpawnParticleTranslator extends PacketTranslator("dodaylightcycle", doCycle)); - session.getUpstream().sendPacket(gameRulesChangedPacket); + session.sendUpstreamPacket(gameRulesChangedPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/BucketSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/BucketSoundInteractionHandler.java index 00269cc7..031782c1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/BucketSoundInteractionHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/BucketSoundInteractionHandler.java @@ -67,7 +67,7 @@ public class BucketSoundInteractionHandler implements BlockSoundInteractionHandl } if (soundEvent != null) { soundEventPacket.setSound(soundEvent); - session.getUpstream().sendPacket(soundEventPacket); + session.sendUpstreamPacket(soundEventPacket); } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java index 260ad814..4b74a678 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java @@ -43,6 +43,6 @@ public class ComparatorSoundInteractHandler implements BlockSoundInteractionHand levelEventPacket.setPosition(position); levelEventPacket.setType(LevelEventType.REDSTONE_TRIGGER); levelEventPacket.setData(powered ? 500 : 550); - session.getUpstream().sendPacket(levelEventPacket); + session.sendUpstreamPacket(levelEventPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java index b8e2854d..39a07c3a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java @@ -42,6 +42,6 @@ public class DoorSoundInteractionHandler implements BlockSoundInteractionHandler levelEventPacket.setType(LevelEventType.SOUND_DOOR); levelEventPacket.setPosition(position); levelEventPacket.setData(0); - session.getUpstream().sendPacket(levelEventPacket); + session.sendUpstreamPacket(levelEventPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/FlintAndSteelInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/FlintAndSteelInteractionHandler.java index b28133b3..290aa7bd 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/FlintAndSteelInteractionHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/FlintAndSteelInteractionHandler.java @@ -45,6 +45,6 @@ public class FlintAndSteelInteractionHandler implements BlockSoundInteractionHan levelSoundEventPacket.setIdentifier(":"); levelSoundEventPacket.setSound(SoundEvent.IGNITE); levelSoundEventPacket.setExtraData(-1); - session.getUpstream().sendPacket(levelSoundEventPacket); + session.sendUpstreamPacket(levelSoundEventPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/GrassPathInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/GrassPathInteractionHandler.java index e2957103..e5445e9d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/GrassPathInteractionHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/GrassPathInteractionHandler.java @@ -46,6 +46,6 @@ public class GrassPathInteractionHandler implements BlockSoundInteractionHandler levelSoundEventPacket.setIdentifier(":"); levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON); levelSoundEventPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaBlockState(identifier))); - session.getUpstream().sendPacket(levelSoundEventPacket); + session.sendUpstreamPacket(levelSoundEventPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/HoeInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/HoeInteractionHandler.java index c9d4299b..17d346ae 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/HoeInteractionHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/HoeInteractionHandler.java @@ -46,6 +46,6 @@ public class HoeInteractionHandler implements BlockSoundInteractionHandler { levelSoundEventPacket.setIdentifier(":"); levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON); levelSoundEventPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaBlockState(identifier))); - session.getUpstream().sendPacket(levelSoundEventPacket); + session.sendUpstreamPacket(levelSoundEventPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java index cfbe7727..fb39d4ac 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java @@ -43,6 +43,6 @@ public class LeverSoundInteractionHandler implements BlockSoundInteractionHandle levelEventPacket.setPosition(position); levelEventPacket.setType(LevelEventType.REDSTONE_TRIGGER); levelEventPacket.setData(powered ? 600 : 500); - session.getUpstream().sendPacket(levelEventPacket); + session.sendUpstreamPacket(levelEventPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/entity/MilkCowSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/entity/MilkCowSoundInteractionHandler.java index d4046eea..42e2e601 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/entity/MilkCowSoundInteractionHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/entity/MilkCowSoundInteractionHandler.java @@ -50,6 +50,6 @@ public class MilkCowSoundInteractionHandler implements EntitySoundInteractionHan levelSoundEventPacket.setIdentifier(":"); levelSoundEventPacket.setSound(SoundEvent.MILK); levelSoundEventPacket.setExtraData(-1); - session.getUpstream().sendPacket(levelSoundEventPacket); + session.sendUpstreamPacket(levelSoundEventPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/FlowerPotBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/FlowerPotBlockEntityTranslator.java index 6861a953..c4748c82 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/FlowerPotBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/FlowerPotBlockEntityTranslator.java @@ -53,7 +53,7 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, R updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NONE); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); - session.getUpstream().sendPacket(updateBlockPacket); + session.sendUpstreamPacket(updateBlockPacket); } /** diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java index c538f09e..168015f6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java @@ -50,7 +50,7 @@ public class NoteblockBlockEntityTranslator implements RequiresBlockState { blockEventPacket.setBlockPosition(Vector3i.from(position.getX(), position.getY(), position.getZ())); blockEventPacket.setEventType(0); blockEventPacket.setEventData(BlockStateValues.getNoteblockPitch(blockState)); - session.getUpstream().sendPacket(blockEventPacket); + session.sendUpstreamPacket(blockEventPacket); ChunkUtils.CACHED_BLOCK_ENTITIES.remove(position); } diff --git a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java index 03ccb2fd..59d9b25f 100644 --- a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java +++ b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java @@ -187,7 +187,7 @@ public class Scoreboard { if (objective.getUpdateType() == REMOVE || update) { RemoveObjectivePacket removeObjectivePacket = new RemoveObjectivePacket(); removeObjectivePacket.setObjectiveId(objective.getObjectiveName()); - session.getUpstream().sendPacket(removeObjectivePacket); + session.sendUpstreamPacket(removeObjectivePacket); if (objective.getUpdateType() == REMOVE) { objectives.remove(objective.getObjectiveName()); // now we can deregister } @@ -199,7 +199,7 @@ public class Scoreboard { displayObjectivePacket.setCriteria("dummy"); displayObjectivePacket.setDisplaySlot(objective.getDisplaySlot()); displayObjectivePacket.setSortOrder(1); // ?? - session.getUpstream().sendPacket(displayObjectivePacket); + session.sendUpstreamPacket(displayObjectivePacket); } objective.setUpdateType(NOTHING); } @@ -208,21 +208,21 @@ public class Scoreboard { SetScorePacket setScorePacket = new SetScorePacket(); setScorePacket.setAction(SetScorePacket.Action.REMOVE); setScorePacket.setInfos(removeScores); - session.getUpstream().sendPacket(setScorePacket); + session.sendUpstreamPacket(setScorePacket); } if (!addScores.isEmpty()) { SetScorePacket setScorePacket = new SetScorePacket(); setScorePacket.setAction(SetScorePacket.Action.SET); setScorePacket.setInfos(addScores); - session.getUpstream().sendPacket(setScorePacket); + session.sendUpstreamPacket(setScorePacket); } } public void despawnObjective(Objective objective) { RemoveObjectivePacket removeObjectivePacket = new RemoveObjectivePacket(); removeObjectivePacket.setObjectiveId(objective.getObjectiveName()); - session.getUpstream().sendPacket(removeObjectivePacket); + session.sendUpstreamPacket(removeObjectivePacket); objectives.remove(objective.getDisplayName()); List toRemove = new ArrayList<>(); @@ -238,7 +238,7 @@ public class Scoreboard { SetScorePacket setScorePacket = new SetScorePacket(); setScorePacket.setAction(SetScorePacket.Action.REMOVE); setScorePacket.setInfos(toRemove); - session.getUpstream().sendPacket(setScorePacket); + session.sendUpstreamPacket(setScorePacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java index b0794e20..c595eee4 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -49,6 +49,6 @@ public class BlockEntityUtils { BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket(); blockEntityPacket.setBlockPosition(position); blockEntityPacket.setData(blockEntity); - session.getUpstream().sendPacket(blockEntityPacket); + session.sendUpstreamPacket(blockEntityPacket); } } 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 fcc596eb..7afb8e6a 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -156,7 +156,7 @@ public class ChunkUtils { NetworkChunkPublisherUpdatePacket chunkPublisherUpdatePacket = new NetworkChunkPublisherUpdatePacket(); chunkPublisherUpdatePacket.setPosition(position); chunkPublisherUpdatePacket.setRadius(session.getRenderDistance() << 4); - session.getUpstream().sendPacket(chunkPublisherUpdatePacket); + session.sendUpstreamPacket(chunkPublisherUpdatePacket); session.setLastChunkPosition(newChunkPos); } @@ -188,7 +188,7 @@ public class ChunkUtils { updateBlockPacket.setBlockPosition(position); updateBlockPacket.setRuntimeId(blockId); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); - session.getUpstream().sendPacket(updateBlockPacket); + session.sendUpstreamPacket(updateBlockPacket); UpdateBlockPacket waterPacket = new UpdateBlockPacket(); waterPacket.setDataLayer(1); @@ -198,7 +198,7 @@ public class ChunkUtils { } else { waterPacket.setRuntimeId(0); } - session.getUpstream().sendPacket(waterPacket); + session.sendUpstreamPacket(waterPacket); // Since Java stores bed colors/skull information as part of the namespaced ID and Bedrock stores it as a tag // This is the only place I could find that interacts with the Java block state and block updates @@ -228,7 +228,7 @@ public class ChunkUtils { data.setSubChunksLength(0); data.setData(Translators.EMPTY_LEVEL_CHUNK_DATA); data.setCachingEnabled(false); - session.getUpstream().sendPacket(data); + session.sendUpstreamPacket(data); if (forceUpdate) { Vector3i pos = Vector3i.from(chunkX + x << 4, 80, chunkZ + z << 4); @@ -236,7 +236,7 @@ public class ChunkUtils { blockPacket.setBlockPosition(pos); blockPacket.setDataLayer(0); blockPacket.setRuntimeId(1); - session.getUpstream().sendPacket(blockPacket); + session.sendUpstreamPacket(blockPacket); } } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java b/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java index 6dd182a7..2c3933e2 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java @@ -49,7 +49,7 @@ public class DimensionUtils { changeDimensionPacket.setDimension(bedrockDimension); changeDimensionPacket.setRespawn(true); changeDimensionPacket.setPosition(pos.toFloat()); - session.getUpstream().sendPacket(changeDimensionPacket); + session.sendUpstreamPacket(changeDimensionPacket); player.setDimension(bedrockDimension); player.setPosition(pos.toFloat()); session.setSpawned(false); @@ -59,7 +59,7 @@ public class DimensionUtils { StopSoundPacket stopSoundPacket = new StopSoundPacket(); stopSoundPacket.setStoppingAllSound(true); stopSoundPacket.setSoundName(""); - session.getUpstream().sendPacket(stopSoundPacket); + session.sendUpstreamPacket(stopSoundPacket); } /** diff --git a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java index 3717b432..60938119 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -84,7 +84,7 @@ public class InventoryUtils { cursorPacket.setContainerId(ContainerId.CURSOR); cursorPacket.setSlot(0); cursorPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, session.getInventory().getCursor())); - session.getUpstream().sendPacket(cursorPacket); + session.sendUpstreamPacket(cursorPacket); } public static boolean canStack(ItemStack item1, ItemStack item2) { diff --git a/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java b/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java index 300294a2..7f6c4760 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java @@ -35,8 +35,6 @@ import com.nukkitx.protocol.bedrock.packet.LoginPacket; import com.nukkitx.protocol.bedrock.packet.ServerToClientHandshakePacket; import com.nukkitx.protocol.bedrock.util.EncryptionUtils; -import net.minidev.json.JSONObject; - import org.geysermc.common.window.CustomFormBuilder; import org.geysermc.common.window.CustomFormWindow; import org.geysermc.common.window.FormWindow; @@ -152,7 +150,7 @@ public class LoginEncryptionUtils { ServerToClientHandshakePacket packet = new ServerToClientHandshakePacket(); packet.setJwt(EncryptionUtils.createHandshakeJwt(serverKeyPair, token).serialize()); - session.getUpstream().sendPacketImmediately(packet); + session.sendUpstreamPacketImmediately(packet); } private static int AUTH_FORM_ID = 1336; 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 9ce025e7..db88f2fa 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -177,12 +177,12 @@ public class SkinUtils { PlayerListPacket playerRemovePacket = new PlayerListPacket(); playerRemovePacket.setAction(PlayerListPacket.Action.REMOVE); playerRemovePacket.getEntries().add(updatedEntry); - session.getUpstream().sendPacket(playerRemovePacket); + session.sendUpstreamPacket(playerRemovePacket); PlayerListPacket playerAddPacket = new PlayerListPacket(); playerAddPacket.setAction(PlayerListPacket.Action.ADD); playerAddPacket.getEntries().add(updatedEntry); - session.getUpstream().sendPacket(playerAddPacket); + session.sendUpstreamPacket(playerAddPacket); } } } catch (Exception e) { From 48147c2ce3b41010ce1bd6f6a24378963ee75396 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Tue, 5 May 2020 13:53:25 -0400 Subject: [PATCH 004/581] Fix Floodgate players causing errors on Bukkit. (#490) Co-authored-by: Tim203 --- .../geysermc/connector/network/session/GeyserSession.java | 8 ++++++++ 1 file changed, 8 insertions(+) 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 9068456c..cf74f923 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 @@ -35,6 +35,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTelepo import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket; +import com.github.steveice10.mc.protocol.packet.login.server.LoginSuccessPacket; import com.github.steveice10.packetlib.Client; import com.github.steveice10.packetlib.event.session.*; import com.github.steveice10.packetlib.packet.Packet; @@ -332,6 +333,13 @@ public class GeyserSession implements CommandSender { lastDimPacket = null; } + // Required, or else Floodgate players break with Bukkit chunk caching + if (event.getPacket() instanceof LoginSuccessPacket) { + GameProfile profile = ((LoginSuccessPacket) event.getPacket()).getProfile(); + playerEntity.setUsername(profile.getName()); + playerEntity.setUuid(profile.getId()); + } + Registry.JAVA.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this); } } From 425df396cb4922e1d14df1042d3ea4d7005abd63 Mon Sep 17 00:00:00 2001 From: Chase MacDonnell Date: Wed, 6 May 2020 17:02:52 -0400 Subject: [PATCH 005/581] Don't load floodgate if it isn't needed (velocity) (#499) Co-authored-by: Chase M <1860157-chasemacdonnell@users.noreply.gitlab.com> --- .../geysermc/platform/velocity/GeyserVelocityConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java index ff99f8ab..b9b3b379 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java @@ -79,7 +79,7 @@ public class GeyserVelocityConfiguration implements GeyserConfiguration { public void loadFloodgate(GeyserVelocityPlugin plugin, ProxyServer proxyServer, File dataFolder) { Optional floodgate = proxyServer.getPluginManager().getPlugin("floodgate"); - floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(dataFolder.toString(), floodgateKeyFile.isEmpty() ? floodgateKeyFile : "public-key.pem"), floodgate.get(), Paths.get("plugins/floodgate/")); + floodgate.ifPresent(it -> floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(dataFolder.toString(), floodgateKeyFile.isEmpty() ? floodgateKeyFile : "public-key.pem"), it, Paths.get("plugins/floodgate/"))); } @Override From 4c1dae67140296440312a9c3afa38ab4d03aca4b Mon Sep 17 00:00:00 2001 From: Luke <32024335+lukeeey@users.noreply.github.com> Date: Wed, 6 May 2020 22:05:03 +0100 Subject: [PATCH 006/581] Add unusable inventory space message (#492) * Add unusable inventory space message * Remove unused imports * Fixed barrier pickup (#1) Co-authored-by: rtm516 --- .../inventory/PlayerInventoryTranslator.java | 4 +++- .../updater/ChestInventoryUpdater.java | 6 +++++- .../connector/utils/InventoryUtils.java | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java index b711bddc..5beea2a2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java @@ -44,6 +44,8 @@ import org.geysermc.connector.utils.Toolbox; import java.util.List; public class PlayerInventoryTranslator extends InventoryTranslator { + private static final ItemData UNUSUABLE_CRAFTING_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock( + "The creative crafting grid is\nunavailable in Java Edition"); public PlayerInventoryTranslator() { super(46); @@ -97,7 +99,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { slotPacket.setSlot(i + 27); if (session.getGameMode() == GameMode.CREATIVE) { - slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, new ItemStack(Toolbox.BARRIER_INDEX))); + slotPacket.setItem(UNUSUABLE_CRAFTING_SPACE_BLOCK); }else{ slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i))); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java index 8318081d..e9541bd1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java @@ -33,9 +33,13 @@ import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.inventory.InventoryTranslator; +import org.geysermc.connector.utils.InventoryUtils; @AllArgsConstructor public class ChestInventoryUpdater extends InventoryUpdater { + private static final ItemData UNUSUABLE_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock( + "This slot does not exist in the inventory\non Java Edition, as there is less\nrows than possible in Bedrock"); + private final int paddedSize; @Override @@ -47,7 +51,7 @@ public class ChestInventoryUpdater extends InventoryUpdater { if (i <= translator.size) { bedrockItems[i] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)); } else { - bedrockItems[i] = ItemData.AIR; + bedrockItems[i] = UNUSUABLE_SPACE_BLOCK; } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java index 60938119..c0311b64 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -27,9 +27,12 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.StringTag; import com.nukkitx.protocol.bedrock.data.ContainerId; import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; +import org.geysermc.common.ChatColor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; @@ -37,6 +40,7 @@ import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.inventory.DoubleChestInventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator; +import java.util.Collections; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -98,4 +102,19 @@ public class InventoryUtils { return false; return item1.equals(item2, false, true, true); } + + /** + * Returns a barrier block with custom name and lore to explain why + * part of the inventory is unusable. + */ + public static ItemData createUnusableSpaceBlock(String description) { + CompoundTagBuilder root = CompoundTagBuilder.builder(); + CompoundTagBuilder display = CompoundTagBuilder.builder(); + + display.stringTag("Name", ChatColor.RESET + "Unusable inventory space"); + display.listTag("Lore", StringTag.class, Collections.singletonList(new StringTag("", ChatColor.RESET + ChatColor.DARK_PURPLE + description))); + + root.tag(display.build("display")); + return ItemData.of(Toolbox.ITEM_ENTRIES.get(Toolbox.BARRIER_INDEX).getBedrockId(), (short) 0, 1, root.buildRootTag()); + } } From 5ae95433e52dc68bd28620f226965e7868ab9921 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Wed, 6 May 2020 22:50:01 +0100 Subject: [PATCH 007/581] Bedrock to Bedrock legacy skin support (#276) * Added legacy skin support for bedrock to bedrock clients * Added bedrock to bedrock cape handling * Added bedrock geometry support * Bedrock skins now work in all auth modes * Tonne of debug info * Added fix to prevent customised skins from being loaded * Added skin size to bedrock client data * Cleaned debugging code * Made bedrock cape take priority over third party * Cut the customised skin image in half to hopefully get it to map * Removed hacky conversion attempt * Fixed bedrock skin caching on load and 1.14.60 support * Cleaned up debug messages * Added linked player ignore --- .../network/session/GeyserSession.java | 10 +++- .../session/auth/BedrockClientData.java | 4 ++ .../connector/utils/SkinProvider.java | 39 ++++++++++++++ .../geysermc/connector/utils/SkinUtils.java | 53 ++++++++++++++++--- 4 files changed, 98 insertions(+), 8 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 cf74f923..759a0f3b 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 @@ -31,10 +31,10 @@ import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.SubProtocol; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; -import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket; +import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; +import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; import com.github.steveice10.mc.protocol.packet.login.server.LoginSuccessPacket; import com.github.steveice10.packetlib.Client; import com.github.steveice10.packetlib.event.session.*; @@ -68,6 +68,7 @@ import org.geysermc.connector.network.translators.Registry; import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.utils.LocaleUtils; +import org.geysermc.connector.utils.SkinUtils; import org.geysermc.connector.utils.Toolbox; import org.geysermc.floodgate.util.BedrockData; import org.geysermc.floodgate.util.EncryptionUtil; @@ -338,6 +339,11 @@ public class GeyserSession implements CommandSender { GameProfile profile = ((LoginSuccessPacket) event.getPacket()).getProfile(); playerEntity.setUsername(profile.getName()); playerEntity.setUuid(profile.getId()); + + // Check if they are not using a linked account + if (!playerEntity.getUuid().toString().startsWith("00000000-0000-0000")) { + SkinUtils.handleBedrockSkin(playerEntity, clientData); + } } Registry.JAVA.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this); diff --git a/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java b/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java index 8fc56acd..4ef0fe79 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java @@ -24,6 +24,10 @@ public class BedrockClientData { private String skinId; @JsonProperty(value = "SkinData") private String skinData; + @JsonProperty(value = "SkinImageHeight") + private int skinImageHeight; + @JsonProperty(value = "SkinImageWidth") + private int skinImageWidth; @JsonProperty(value = "CapeId") private String capeId; @JsonProperty(value = "CapeData") diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java index 7c2b7fc0..15cccf22 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java @@ -58,6 +58,9 @@ public class SkinProvider { private static Map cachedCapes = new ConcurrentHashMap<>(); private static Map> requestedCapes = new ConcurrentHashMap<>(); + public static final SkinGeometry EMPTY_GEOMETRY = SkinProvider.SkinGeometry.getLegacy("geometry.humanoid"); + private static Map cachedGeometry = new ConcurrentHashMap<>(); + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final int CACHE_INTERVAL = 8 * 60 * 1000; // 8 minutes @@ -164,6 +167,31 @@ public class SkinProvider { return CompletableFuture.completedFuture(officialCape); } + public static CompletableFuture requestBedrockCape(UUID playerID, boolean newThread) { + Cape bedrockCape = cachedCapes.getOrDefault(playerID.toString() + ".Bedrock", EMPTY_CAPE); + return CompletableFuture.completedFuture(bedrockCape); + } + + public static CompletableFuture requestBedrockGeometry(SkinGeometry currentGeometry, UUID playerID, boolean newThread) { + SkinGeometry bedrockGeometry = cachedGeometry.getOrDefault(playerID, currentGeometry); + return CompletableFuture.completedFuture(bedrockGeometry); + } + + public static void storeBedrockSkin(UUID playerID, String skinID, byte[] skinData) { + Skin skin = new Skin(playerID, skinID, skinData, System.currentTimeMillis(), true); + cachedSkins.put(playerID, skin); + } + + public static void storeBedrockCape(UUID playerID, byte[] capeData) { + Cape cape = new Cape(playerID.toString() + ".Bedrock", playerID.toString(), capeData, System.currentTimeMillis(), false); + cachedCapes.put(playerID.toString() + ".Bedrock", cape); + } + + public static void storeBedrockGeometry(UUID playerID, byte[] geometryName, byte[] geometryData) { + SkinGeometry geometry = new SkinGeometry(new String(geometryName), new String(geometryData)); + cachedGeometry.put(playerID, geometry); + } + private static Skin supplySkin(UUID uuid, String textureUrl) { byte[] skin = EMPTY_SKIN.getSkinData(); try { @@ -285,6 +313,17 @@ public class SkinProvider { private boolean failed; } + @AllArgsConstructor + @Getter + public static class SkinGeometry { + private String geometryName; + private String geometryData; + + public static SkinGeometry getLegacy(String name) { + return new SkinProvider.SkinGeometry("{\"geometry\" :{\"default\" :\"" + name + "\"}}", ""); + } + } + /* * Sorted by 'priority' */ 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 db88f2fa..1d0ee216 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -39,6 +39,7 @@ import org.geysermc.common.AuthType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.session.auth.BedrockClientData; import java.nio.charset.StandardCharsets; import java.util.Base64; @@ -52,6 +53,8 @@ public class SkinUtils { GameProfileData data = GameProfileData.from(profile); SkinProvider.Cape cape = SkinProvider.getCachedCape(data.getCapeUrl()); + SkinProvider.SkinGeometry geometry = SkinProvider.SkinGeometry.getLegacy("geometry.humanoid.custom" + (data.isAlex() ? "Slim" : "")); + return buildEntryManually( profile.getId(), profile.getName(), @@ -60,8 +63,8 @@ public class SkinUtils { SkinProvider.getCachedSkin(profile.getId()).getSkinData(), cape.getCapeId(), cape.getCapeData(), - getLegacySkinGeometry("geometry.humanoid.custom" + (data.isAlex() ? "Slim" : "")), - "" + geometry.getGeometryName(), + geometry.getGeometryData() ); } @@ -74,8 +77,8 @@ public class SkinUtils { SkinProvider.STEVE_SKIN, SkinProvider.EMPTY_CAPE.getCapeId(), SkinProvider.EMPTY_CAPE.getCapeData(), - getLegacySkinGeometry("geometry.humanoid"), - "" + SkinProvider.EMPTY_GEOMETRY.getGeometryName(), + SkinProvider.EMPTY_GEOMETRY.getGeometryData() ); } @@ -151,6 +154,12 @@ public class SkinUtils { SkinProvider.Skin skin = skinAndCape.getSkin(); SkinProvider.Cape cape = skinAndCape.getCape(); + if (cape.isFailed()) { + cape = SkinProvider.getOrDefault(SkinProvider.requestBedrockCape( + entity.getUuid(), false + ), SkinProvider.EMPTY_CAPE, 3); + } + if (cape.isFailed() && SkinProvider.ALLOW_THIRD_PARTY_CAPES) { cape = SkinProvider.getOrDefault(SkinProvider.requestUnofficialCape( cape, entity.getUuid(), @@ -158,6 +167,11 @@ public class SkinUtils { ), SkinProvider.EMPTY_CAPE, SkinProvider.CapeProvider.VALUES.length * 3); } + SkinProvider.SkinGeometry geometry = SkinProvider.SkinGeometry.getLegacy("geometry.humanoid.custom" + (data.isAlex() ? "Slim" : "")); + geometry = SkinProvider.getOrDefault(SkinProvider.requestBedrockGeometry( + geometry, entity.getUuid(), false + ), geometry, 3); + if (entity.getLastSkinUpdate() < skin.getRequestedOn()) { entity.setLastSkinUpdate(skin.getRequestedOn()); @@ -170,8 +184,8 @@ public class SkinUtils { skin.getSkinData(), cape.getCapeId(), cape.getCapeData(), - getLegacySkinGeometry("geometry.humanoid.custom" + (data.isAlex() ? "Slim" : "")), - "" + geometry.getGeometryName(), + geometry.getGeometryData() ); PlayerListPacket playerRemovePacket = new PlayerListPacket(); @@ -194,6 +208,33 @@ public class SkinUtils { }); } + public static void handleBedrockSkin(PlayerEntity playerEntity, BedrockClientData clientData) { + GameProfileData data = GameProfileData.from(playerEntity.getProfile()); + + GeyserConnector.getInstance().getLogger().info("Registering bedrock skin for " + playerEntity.getUsername() + " (" + playerEntity.getUuid() + ")"); + + try { + byte[] skinBytes = com.github.steveice10.mc.auth.util.Base64.decode(clientData.getSkinData().getBytes("UTF-8")); + byte[] capeBytes = clientData.getCapeData(); + + byte[] geometryNameBytes = com.github.steveice10.mc.auth.util.Base64.decode(clientData.getGeometryName().getBytes("UTF-8")); + byte[] geometryBytes = com.github.steveice10.mc.auth.util.Base64.decode(clientData.getGeometryData().getBytes("UTF-8")); + + if (skinBytes.length <= (128 * 128 * 4)) { + SkinProvider.storeBedrockSkin(playerEntity.getUuid(), data.getSkinUrl(), skinBytes); + } else { + GeyserConnector.getInstance().getLogger().info("Unable to load bedrock skin for '" + playerEntity.getUsername() + "' as they are using a customised skin"); + GeyserConnector.getInstance().getLogger().debug("The size of '" + playerEntity.getUsername() + "' skin is: " + clientData.getSkinImageWidth() + "x" + clientData.getSkinImageHeight()); + } + SkinProvider.storeBedrockGeometry(playerEntity.getUuid(), geometryNameBytes, geometryBytes); + if (!clientData.getCapeId().equals("")) { + SkinProvider.storeBedrockCape(playerEntity.getUuid(), capeBytes); + } + } catch (Exception e) { + throw new AssertionError("Failed to cache skin for bedrock user (" + playerEntity.getUsername() + "): ", e); + } + } + /** * Create a basic geometry json for the given name * From f11bae0bf078a4ee0f8308d6fcc0b421e95cb37c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Wed, 6 May 2020 17:52:57 -0400 Subject: [PATCH 008/581] Fix signs (#439) * Fix signs on everything except Paper * Fix sign line placement * Update shulker box block entity Co-authored-by: James Harrison --- .../world/JavaUpdateTileEntityTranslator.java | 11 -- .../entity/BannerBlockEntityTranslator.java | 2 +- .../entity/BedBlockEntityTranslator.java | 2 +- .../world/block/entity/BlockEntity.java | 6 - .../entity/CampfireBlockEntityTranslator.java | 2 +- .../entity/EmptyBlockEntityTranslator.java | 2 +- .../EndGatewayBlockEntityTranslator.java | 2 +- .../ShulkerBoxBlockEntityTranslator.java | 2 +- .../entity/SignBlockEntityTranslator.java | 26 ++-- .../entity/SkullBlockEntityTranslator.java | 142 +++++++++--------- .../geysermc/connector/utils/ChunkUtils.java | 13 +- 11 files changed, 95 insertions(+), 115 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java index 5c55efed..362d67d0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java @@ -30,19 +30,13 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdate 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.network.translators.world.block.entity.BlockEntity; import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator; import org.geysermc.connector.utils.BlockEntityUtils; import org.geysermc.connector.utils.ChunkUtils; -import java.util.concurrent.TimeUnit; - @Translator(packet = ServerUpdateTileEntityPacket.class) public class JavaUpdateTileEntityTranslator extends PacketTranslator { - // This should be modified if sign text is not showing up - private static final int DELAY = 500; - @Override public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) { String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name()); @@ -52,11 +46,6 @@ public class JavaUpdateTileEntityTranslator extends PacketTranslator - BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(id, packet.getNbt(), null), packet.getPosition()), - DELAY, TimeUnit.MILLISECONDS); } else { BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(id, packet.getNbt(), null), packet.getPosition()); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java index 2034b3d5..eefd8402 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java @@ -37,7 +37,7 @@ import org.geysermc.connector.network.translators.world.block.BlockStateValues; import java.util.ArrayList; import java.util.List; -@BlockEntity(name = "Banner", delay = false, regex = "banner") +@BlockEntity(name = "Banner", regex = "banner") public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java index 543828e8..5f0b1cc0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java @@ -35,7 +35,7 @@ import org.geysermc.connector.network.translators.world.block.BlockStateValues; import java.util.ArrayList; import java.util.List; -@BlockEntity(name = "Bed", delay = false, regex = "bed") +@BlockEntity(name = "Bed", regex = "bed") public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntity.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntity.java index d08ab561..11bfe0ea 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntity.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntity.java @@ -31,12 +31,6 @@ import java.lang.annotation.RetentionPolicy; @Retention(value = RetentionPolicy.RUNTIME) public @interface BlockEntity { - /** - * Whether to delay the sending of the block entity - * @return the delay for when sending the block entity - */ - boolean delay(); - /** * The block entity name * @return the name of the block entity diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java index d91e47c2..eac87b04 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java @@ -38,7 +38,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; -@BlockEntity(name = "Campfire", delay = false, regex = "campfire") +@BlockEntity(name = "Campfire", regex = "campfire") public class CampfireBlockEntityTranslator extends BlockEntityTranslator { @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java index f95cb89e..d1068277 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java @@ -32,7 +32,7 @@ import com.nukkitx.nbt.tag.Tag; import java.util.ArrayList; import java.util.List; -@BlockEntity(name = "Empty", delay = false, regex = "") +@BlockEntity(name = "Empty", regex = "") public class EmptyBlockEntityTranslator extends BlockEntityTranslator { @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java index 10de9d32..4cd2eaa9 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java @@ -36,7 +36,7 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; -@BlockEntity(name = "EndGateway", delay = true, regex = "end_gateway") +@BlockEntity(name = "EndGateway", regex = "end_gateway") public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java index b0b8fa3d..373b963e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java @@ -36,7 +36,7 @@ import org.geysermc.connector.network.translators.world.block.BlockStateValues; import java.util.ArrayList; import java.util.List; -@BlockEntity(name = "ShulkerBox", delay = false, regex = "shulker_box") +@BlockEntity(name = "ShulkerBox", regex = "shulker_box") public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator { @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java index 0dde3307..6c170462 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java @@ -31,29 +31,35 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.StringTag; import com.nukkitx.nbt.tag.Tag; +import io.netty.util.internal.StringUtil; import org.geysermc.connector.utils.MessageUtils; import java.util.ArrayList; import java.util.List; -@BlockEntity(name = "Sign", delay = true, regex = "sign") +@BlockEntity(name = "Sign", regex = "sign") public class SignBlockEntityTranslator extends BlockEntityTranslator { @Override public List> translateTag(CompoundTag tag, BlockState blockState) { List> tags = new ArrayList<>(); - String line1 = getOrDefault(tag.getValue().get("Text1"), ""); - String line2 = getOrDefault(tag.getValue().get("Text2"), ""); - String line3 = getOrDefault(tag.getValue().get("Text3"), ""); - String line4 = getOrDefault(tag.getValue().get("Text4"), ""); + StringBuilder signText = new StringBuilder(); + for(int i = 0; i < 4; i++) { + int currentLine = i+1; + String signLine = getOrDefault(tag.getValue().get("Text" + currentLine), ""); + signLine = MessageUtils.getBedrockMessage(Message.fromString(signLine)); - tags.add(new StringTag("Text", MessageUtils.getBedrockMessage(Message.fromString(line1)) - + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line2)) - + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line3)) - + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line4)) - )); + //Java allows up to 16+ characters on certain symbols. + if(signLine.length() >= 15 && (signLine.contains("-") || signLine.contains("="))) { + signLine = signLine.substring(0, 14); + } + signText.append(signLine); + signText.append("\n"); + } + + tags.add(new StringTag("Text", MessageUtils.getBedrockMessage(Message.fromString(signText.toString())))); return tags; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java index 7e73c846..9393f7bb 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java @@ -1,71 +1,71 @@ -/* - * 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.world.block.entity; - -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.ByteTag; -import com.nukkitx.nbt.tag.CompoundTag; -import com.nukkitx.nbt.tag.FloatTag; -import com.nukkitx.nbt.tag.Tag; -import org.geysermc.connector.network.translators.world.block.BlockStateValues; - -import java.util.ArrayList; -import java.util.List; - -@BlockEntity(name = "Skull", delay = false, regex = "skull") -public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { - - @Override - public boolean isBlock(BlockState blockState) { - return BlockStateValues.getSkullVariant(blockState) != -1; - } - - @Override - public List> translateTag(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag, BlockState blockState) { - List> tags = new ArrayList<>(); - byte skullVariant = BlockStateValues.getSkullVariant(blockState); - float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f; - // Just in case... - if (skullVariant == -1) skullVariant = 0; - tags.add(new FloatTag("Rotation", rotation)); - tags.add(new ByteTag("SkullType", skullVariant)); - return tags; - } - - @Override - public com.github.steveice10.opennbt.tag.builtin.CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { - return null; - } - - @Override - public CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); - tagBuilder.floatTag("Rotation", 0); - tagBuilder.byteTag("SkullType", (byte) 0); - return tagBuilder.buildRootTag(); - } -} +/* + * 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.world.block.entity; + +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.ByteTag; +import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.tag.FloatTag; +import com.nukkitx.nbt.tag.Tag; +import org.geysermc.connector.network.translators.world.block.BlockStateValues; + +import java.util.ArrayList; +import java.util.List; + +@BlockEntity(name = "Skull", regex = "skull") +public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { + + @Override + public boolean isBlock(BlockState blockState) { + return BlockStateValues.getSkullVariant(blockState) != -1; + } + + @Override + public List> translateTag(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag, BlockState blockState) { + List> tags = new ArrayList<>(); + byte skullVariant = BlockStateValues.getSkullVariant(blockState); + float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f; + // Just in case... + if (skullVariant == -1) skullVariant = 0; + tags.add(new FloatTag("Rotation", rotation)); + tags.add(new ByteTag("SkullType", skullVariant)); + return tags; + } + + @Override + public com.github.steveice10.opennbt.tag.builtin.CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + return null; + } + + @Override + public CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); + tagBuilder.floatTag("Rotation", 0); + tagBuilder.byteTag("SkullType", (byte) 0); + return tagBuilder.buildRootTag(); + } +} 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 7afb8e6a..41d0dc2d 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -89,21 +89,12 @@ public class ChunkUtils { // Check to see if the name is in BlockTranslator.getBlockEntityString, and therefore must be handled differently if (BlockTranslator.getBlockEntityString(blockState) != null) { - // Get the block entity translator - BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(BlockTranslator.getBlockEntityString(blockState)); Position pos = new ChunkPosition(column.getX(), column.getZ()).getBlock(x, (chunkY << 4) + y, z); blockEntityPositions.put(pos, blockState); - // If there is a delay required for the block, allow it. - if (blockEntityTranslator.getClass().getAnnotation(BlockEntity.class).delay()) { - chunkData.loadBlockEntitiesLater.put(blockEntityTranslator.getDefaultBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockTranslator.getBlockEntityString(blockState)), - pos.getX(), pos.getY(), pos.getZ()), blockState.getId()); - } else { - section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), id); - } - } else { - section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), id); } + section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), id); + // Check if block is piston or flower - only block entities in Bedrock if (BlockStateValues.getFlowerPotValues().containsKey(blockState.getId()) || BlockStateValues.getPistonValues().containsKey(blockState.getId())) { From 2355c503c929f792634c78cb26f7b9c2528a656f Mon Sep 17 00:00:00 2001 From: James Harrison Date: Fri, 8 May 2020 03:49:44 +0100 Subject: [PATCH 009/581] Enderchest and Invisible Players fix. (#506) * Fix EnderChests not showing on legacy servers (Hypixel) Fix NPCs/Players sometimes being invisible * Remove unused import * Fix standard --- .../java/entity/player/JavaPlayerListEntryTranslator.java | 3 ++- .../java/org/geysermc/connector/utils/BlockEntityUtils.java | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerListEntryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerListEntryTranslator.java index 5fff40b1..2f71d683 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerListEntryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerListEntryTranslator.java @@ -63,8 +63,9 @@ public class JavaPlayerListEntryTranslator extends PacketTranslator Date: Thu, 7 May 2020 22:57:08 -0500 Subject: [PATCH 010/581] Add slime and magma cube size support --- .../connector/entity/living/SlimeEntity.java | 48 +++++++++++++++++++ .../connector/entity/type/EntityType.java | 4 +- 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/SlimeEntity.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/SlimeEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/SlimeEntity.java new file mode 100644 index 00000000..26106f0a --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/SlimeEntity.java @@ -0,0 +1,48 @@ +/* + * 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; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.EntityData; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +public class SlimeEntity extends InsentientEntity { + + public SlimeEntity(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) { + this.metadata.put(EntityData.SCALE, 0.10f + (int) entityMetadata.getValue()); + } + 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 98d836d2..1173796f 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,12 +68,12 @@ public enum EntityType { SKELETON(AbstractSkeletonEntity.class, 34, 1.8f, 0.6f, 0.6f, 1.62f), SPIDER(SpiderEntity.class, 35, 0.9f, 1.4f, 1.4f, 1f), ZOMBIE_PIGMAN(MonsterEntity.class, 36, 1.8f, 0.6f, 0.6f, 1.62f), - SLIME(InsentientEntity.class, 37, 0.51f), + SLIME(SlimeEntity.class, 37, 0.51f), ENDERMAN(EndermanEntity.class, 38, 2.9f, 0.6f), SILVERFISH(MonsterEntity.class, 39, 0.3f, 0.4f), CAVE_SPIDER(MonsterEntity.class, 40, 0.5f, 0.7f), GHAST(FlyingEntity.class, 41, 4.0f), - MAGMA_CUBE(InsentientEntity.class, 42, 0.51f), + MAGMA_CUBE(SlimeEntity.class, 42, 0.51f), BLAZE(BlazeEntity.class, 43, 1.8f, 0.6f), ZOMBIE_VILLAGER(ZombieEntity.class, 44, 1.8f, 0.6f, 0.6f, 1.62f), WITCH(RaidParticipantEntity.class, 45, 1.8f, 0.6f, 0.6f, 1.62f), From e58ffdd3c039a6c0d7e155535f2ed9e0d4effbd6 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Fri, 8 May 2020 00:18:05 -0500 Subject: [PATCH 011/581] Add support for block break animations from java players to bedrock --- .../world/JavaBlockBreakAnimTranslator.java | 95 +++++++++++++++++++ .../geysermc/connector/utils/BlockUtils.java | 8 +- 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockBreakAnimTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockBreakAnimTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockBreakAnimTranslator.java new file mode 100644 index 00000000..27bc34c9 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockBreakAnimTranslator.java @@ -0,0 +1,95 @@ +/* + * 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.java.world; + +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerBlockBreakAnimPacket; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; +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.network.translators.item.ItemEntry; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.utils.BlockUtils; + +@Translator(packet = ServerBlockBreakAnimPacket.class) +public class JavaBlockBreakAnimTranslator extends PacketTranslator { + + @Override + public void translate(ServerBlockBreakAnimPacket packet, GeyserSession session) { + BlockState state = session.getConnector().getWorldManager().getBlockAt(session, packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ()); + int breakTime = (int) (65535 / Math.ceil(BlockUtils.getBreakTime(BlockTranslator.JAVA_RUNTIME_ID_TO_HARDNESS.get(state.getId()), state.getId(), ItemEntry.AIR, new CompoundTag(""), null) * 20)); + LevelEventPacket levelEventPacket = new LevelEventPacket(); + levelEventPacket.setPosition(Vector3f.from( + packet.getPosition().getX(), + packet.getPosition().getY(), + packet.getPosition().getZ() + )); + levelEventPacket.setType(LevelEventType.BLOCK_START_BREAK); + + switch (packet.getStage()) { + case STAGE_1: + levelEventPacket.setData(breakTime); + break; + case STAGE_2: + levelEventPacket.setData(breakTime * 2); + break; + case STAGE_3: + levelEventPacket.setData(breakTime * 3); + break; + case STAGE_4: + levelEventPacket.setData(breakTime * 4); + break; + case STAGE_5: + levelEventPacket.setData(breakTime * 5); + break; + case STAGE_6: + levelEventPacket.setData(breakTime * 6); + break; + case STAGE_7: + levelEventPacket.setData(breakTime * 7); + break; + case STAGE_8: + levelEventPacket.setData(breakTime * 8); + break; + case STAGE_9: + levelEventPacket.setData(breakTime * 9); + break; + case STAGE_10: + levelEventPacket.setData(breakTime * 10); + break; + case RESET: + levelEventPacket.setType(LevelEventType.BLOCK_STOP_BREAK); + levelEventPacket.setData(0); + break; + } + session.sendUpstreamPacket(levelEventPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java index 3a9ecb86..deddce58 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java @@ -114,9 +114,13 @@ public class BlockUtils { correctTool = correctTool(blockToolType, toolType); } int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency"); - int hasteLevel = player.getEffectCache().getEffectLevel(Effect.FASTER_DIG); - int miningFatigueLevel = player.getEffectCache().getEffectLevel(Effect.SLOWER_DIG); + int hasteLevel = 0; + int miningFatigueLevel = 0; + if (player != null) { + hasteLevel = player.getEffectCache().getEffectLevel(Effect.FASTER_DIG); + miningFatigueLevel = player.getEffectCache().getEffectLevel(Effect.SLOWER_DIG); + } // TODO implement these checks and material check if possible //boolean insideOfWaterWithoutAquaAffinity = player.isInsideOfWater() && // Optional.ofNullable(player.getInventory().getHelmet().getEnchantment(Enchantment.ID_WATER_WORKER)) From 7b3893ff78d4e484386436e361f0d545a967997d Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 9 May 2020 04:58:29 +0100 Subject: [PATCH 012/581] Fixed empty listen IPs breaking automatic config (#519) --- .../java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java | 2 +- .../org/geysermc/platform/bungeecord/GeyserBungeePlugin.java | 2 +- .../java/org/geysermc/platform/sponge/GeyserSpongePlugin.java | 2 +- .../org/geysermc/platform/velocity/GeyserVelocityPlugin.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java index d6bd31ac..579e8b16 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java @@ -59,7 +59,7 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { // Don't change the ip if its listening on all interfaces // By default this should be 127.0.0.1 but may need to be changed in some circumstances - if (!Bukkit.getIp().equals("0.0.0.0")) { + if (!Bukkit.getIp().equals("0.0.0.0") && !Bukkit.getIp().equals("")) { getConfig().set("remote.address", Bukkit.getIp()); } diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java index bfd0cf49..488854c9 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java @@ -91,7 +91,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { // Don't change the ip if its listening on all interfaces // By default this should be 127.0.0.1 but may need to be changed in some circumstances - if (!javaAddr.getHostString().equals("0.0.0.0")) { + if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) { configuration.set("remote.address", javaAddr.getHostString()); } diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java index 01d71f1c..0c323a5e 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java @@ -97,7 +97,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap { // Don't change the ip if its listening on all interfaces // By default this should be 127.0.0.1 but may need to be changed in some circumstances - if (!javaAddr.getHostString().equals("0.0.0.0")) { + if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) { serverIP.setValue("127.0.0.1"); } diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java index bd892413..0269d933 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java @@ -83,7 +83,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { // Don't change the ip if its listening on all interfaces // By default this should be 127.0.0.1 but may need to be changed in some circumstances - if (!javaAddr.getHostString().equals("0.0.0.0")) { + if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) { geyserConfig.getRemote().setAddress(javaAddr.getHostString()); } From d4291888b3f22b19bc309a6ca1e3bd98473c99d1 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Sat, 9 May 2020 22:37:18 -0400 Subject: [PATCH 013/581] Fallback to ViaVersion to convert block state (#515) * Fallback to ViaVersion to convert block state * Use ViaVersion 3.0.0-SNAPSHOT * Detect versions better; change logic for getting blocks --- bootstrap/bukkit/pom.xml | 6 +++ .../platform/bukkit/GeyserBukkitPlugin.java | 54 ++++++++++++++++++- .../world/GeyserBukkitWorldManager.java | 25 +++++++++ .../bukkit/src/main/resources/plugin.yml | 1 + pom.xml | 4 ++ 5 files changed, 89 insertions(+), 1 deletion(-) diff --git a/bootstrap/bukkit/pom.xml b/bootstrap/bukkit/pom.xml index 94fab83b..1f831d67 100644 --- a/bootstrap/bukkit/pom.xml +++ b/bootstrap/bukkit/pom.xml @@ -23,6 +23,12 @@ 1.14-R0.1-SNAPSHOT provided + + us.myles + viaversion + 3.0.0-SNAPSHOT + provided + ${outputName}-Bukkit diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java index 579e8b16..3f2b9cad 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java @@ -35,6 +35,7 @@ import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.platform.bukkit.command.GeyserBukkitCommandExecutor; import org.geysermc.platform.bukkit.command.GeyserBukkitCommandManager; import org.geysermc.platform.bukkit.world.GeyserBukkitWorldManager; +import us.myles.ViaVersion.api.Via; import java.util.UUID; @@ -73,7 +74,24 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { this.connector = GeyserConnector.start(PlatformType.BUKKIT, this); this.geyserCommandManager = new GeyserBukkitCommandManager(this, connector); - this.geyserWorldManager = new GeyserBukkitWorldManager(); + + boolean isViaVersion = false; + // Used to determine if Block.getBlockData() is present. + boolean isLegacy = !isCompatible(Bukkit.getServer().getVersion(), "1.13.0"); + if (isLegacy) + geyserLogger.debug("Legacy version of Minecraft (1.12.2 or older) detected."); + + if (Bukkit.getPluginManager().getPlugin("ViaVersion") != null) { + // TODO: Update when ViaVersion updates + // API changes between 2.2.3 and 3.0.0-SNAPSHOT require this check + if (!Via.getAPI().getVersion().equals("3.0.0-SNAPSHOT") && isLegacy) { + geyserLogger.info("ViaVersion detected but not ViaVersion-ABSTRACTION. Please update your ViaVersion plugin for compatibility with Geyser."); + } else { + isViaVersion = true; + } + } + + this.geyserWorldManager = new GeyserBukkitWorldManager(isLegacy, isViaVersion); this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector)); } @@ -102,4 +120,38 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { public WorldManager getWorldManager() { return this.geyserWorldManager; } + + public boolean isCompatible(String version, String whichVersion) { + int[] currentVersion = parseVersion(version); + int[] otherVersion = parseVersion(whichVersion); + int length = Math.max(currentVersion.length, otherVersion.length); + for (int index = 0; index < length; index = index + 1) { + int self = (index < currentVersion.length) ? currentVersion[index] : 0; + int other = (index < otherVersion.length) ? otherVersion[index] : 0; + + if (self != other) { + return (self - other) > 0; + } + } + return true; + } + + private int[] parseVersion(String versionParam) { + versionParam = (versionParam == null) ? "" : versionParam; + if (versionParam.contains("(MC: ")) { + versionParam = versionParam.split("\\(MC: ")[1]; + versionParam = versionParam.split("\\)")[0]; + } + String[] stringArray = versionParam.split("[_.-]"); + int[] temp = new int[stringArray.length]; + for (int index = 0; index <= (stringArray.length - 1); index = index + 1) { + String t = stringArray[index].replaceAll("\\D", ""); + try { + temp[index] = Integer.parseInt(t); + } catch(NumberFormatException ex) { + temp[index] = 0; + } + } + return temp; + } } diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java index 07fc3136..44a520e8 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java @@ -28,18 +28,43 @@ package org.geysermc.platform.bukkit.world; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import lombok.AllArgsConstructor; import org.bukkit.Bukkit; +import org.bukkit.block.Block; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.Protocol1_13_1To1_13; +import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data.MappingData; +@AllArgsConstructor public class GeyserBukkitWorldManager extends WorldManager { + private final boolean isLegacy; + // You need ViaVersion to connect to an older server with Geyser. + // However, we still check for ViaVersion in case there's some other way that gets Geyser on a pre-1.13 Bukkit server + private final boolean isViaVersion; + @Override + @SuppressWarnings("deprecation") public BlockState getBlockAt(GeyserSession session, int x, int y, int z) { if (session.getPlayerEntity() == null) { return BlockTranslator.AIR; } + if (isLegacy) { + if (isViaVersion) { + Block block = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z); + // Black magic that gets the old block state ID + int oldBlockId = (block.getType().getId() << 4) | (block.getData() & 0xF); + // Convert block state from old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 + int thirteenBlockId = us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData.blockMappings.getNewId(oldBlockId); + int thirteenPointOneBlockId = Protocol1_13_1To1_13.getNewBlockStateId(thirteenBlockId); + int fourteenBlockId = us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.blockStateMappings.getNewId(thirteenPointOneBlockId); + return new BlockState(MappingData.blockStateMappings.getNewId(fourteenBlockId)); + } else { + return BlockTranslator.AIR; + } + } return BlockTranslator.getJavaIdBlockMap().get(Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z).getBlockData().getAsString()); } } diff --git a/bootstrap/bukkit/src/main/resources/plugin.yml b/bootstrap/bukkit/src/main/resources/plugin.yml index 8e002eb2..7e32f0e1 100644 --- a/bootstrap/bukkit/src/main/resources/plugin.yml +++ b/bootstrap/bukkit/src/main/resources/plugin.yml @@ -3,6 +3,7 @@ name: ${outputName}-Bukkit author: ${project.organization.name} website: ${project.organization.url} version: ${project.version} +softdepend: ["ViaVersion"] commands: geyser: description: The main command for Geyser. diff --git a/pom.xml b/pom.xml index fc1ead33..a82d6217 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,10 @@ true + + viaversion-repo + https://repo.viaversion.com + From 34d48177959fea4d53677431fe8e737420166abd Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Sun, 10 May 2020 15:26:00 -0400 Subject: [PATCH 014/581] Add visual support for double chests (#523) * Add visual support for double chests * Update mappings submodule --- .../world/block/BlockStateValues.java | 19 +++ .../world/block/DoubleChestValue.java | 52 +++++++++ .../DoubleChestBlockEntityTranslator.java | 108 ++++++++++++++++++ connector/src/main/resources/mappings | 2 +- 4 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/world/block/DoubleChestValue.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/DoubleChestBlockEntityTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java index de08b7e8..070a0592 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java @@ -47,6 +47,7 @@ public class BlockStateValues { private static final Object2IntMap BANNER_COLORS = new Object2IntOpenHashMap<>(); private static final Object2ByteMap BED_COLORS = new Object2ByteOpenHashMap<>(); + private static final Int2ObjectMap DOUBLE_CHEST_VALUES = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap FLOWER_POT_VALUES = new Int2ObjectOpenHashMap<>(); private static final Map FLOWER_POT_BLOCKS = new HashMap<>(); private static final Object2IntMap NOTEBLOCK_PITCHES = new Object2IntOpenHashMap<>(); @@ -74,6 +75,15 @@ public class BlockStateValues { return; } + if (entry.getValue().get("double_chest_position") != null) { + boolean isX = (entry.getValue().get("x") != null); + boolean isDirectionPositive = ((entry.getValue().get("x") != null && entry.getValue().get("x").asBoolean()) || + (entry.getValue().get("z") != null && entry.getValue().get("z").asBoolean())); + boolean isLeft = (entry.getValue().get("double_chest_position").asText().contains("left")); + DOUBLE_CHEST_VALUES.put(javaBlockState.getId(), new DoubleChestValue(isX, isDirectionPositive, isLeft)); + return; + } + if (entry.getKey().contains("potted_")) { FLOWER_POT_VALUES.put(javaBlockState.getId(), entry.getKey().replace("potted_", "")); return; @@ -136,6 +146,15 @@ public class BlockStateValues { return -1; } + /** + * All double chest values are part of the block state in Java and part of the block entity tag in Bedrock. + * This gives the DoubleChestValue that can be calculated into the final tag. + * @return The map of all DoubleChestValues. + */ + public static Int2ObjectMap getDoubleChestValues() { + return DOUBLE_CHEST_VALUES; + } + /** * Get the Int2ObjectMap of flower pot block states to containing plant * @return Int2ObjectMap of flower pot values diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/DoubleChestValue.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/DoubleChestValue.java new file mode 100644 index 00000000..5bd21724 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/DoubleChestValue.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.network.translators.world.block; + +import lombok.AllArgsConstructor; + +/** + * This stores all values of double chests that are part of the Java block state. + */ +@AllArgsConstructor +public class DoubleChestValue { + + /** + * If true, then chest is facing east/west; if false, south/north + */ + public boolean isFacingEast; + + /** + * If true, direction is positive (east/south); if false, direction is negative (west/north) + */ + public boolean isDirectionPositive; + + /** + * If true, chest is the left of a pair; if false, chest is the right of a pair. + */ + public boolean isLeft; + +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/DoubleChestBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/DoubleChestBlockEntityTranslator.java new file mode 100644 index 00000000..f5599832 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/DoubleChestBlockEntityTranslator.java @@ -0,0 +1,108 @@ +/* + * 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.world.block.entity; + +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.ByteTag; +import com.nukkitx.nbt.tag.IntTag; +import com.nukkitx.nbt.tag.Tag; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.world.block.BlockStateValues; +import org.geysermc.connector.network.translators.world.block.DoubleChestValue; +import org.geysermc.connector.utils.BlockEntityUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockOnlyBlockEntity + */ +@BlockEntity(name = "Chest", regex = "chest") +public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity, RequiresBlockState { + + @Override + public boolean isBlock(BlockState blockState) { + return BlockStateValues.getDoubleChestValues().containsKey(blockState.getId()); + } + + @Override + public void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { + CompoundTag javaTag = getConstantJavaTag("chest", position.getX(), position.getY(), position.getZ()); + CompoundTagBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId("chest"), position.getX(), position.getY(), position.getZ()).toBuilder(); + translateTag(javaTag, blockState).forEach(tagBuilder::tag); + BlockEntityUtils.updateBlockEntity(session, tagBuilder.buildRootTag(), position); + } + + @Override + public List> translateTag(CompoundTag tag, BlockState blockState) { + List> tags = new ArrayList<>(); + if (blockState != null && BlockStateValues.getDoubleChestValues().containsKey(blockState.getId())) { + DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState.getId()); + if (chestValues != null) { + int x = (int) tag.getValue().get("x").getValue(); + int z = (int) tag.getValue().get("z").getValue(); + // Calculate the position of the other chest based on the Java block state + if (chestValues.isFacingEast) { + if (chestValues.isDirectionPositive) { + // East + z = z + (chestValues.isLeft ? 1 : -1); + } else { + // West + z = z + (chestValues.isLeft ? -1 : 1); + } + } else { + if (chestValues.isDirectionPositive) { + // South + x = x + (chestValues.isLeft ? -1 : 1); + } else { + // North + x = x + (chestValues.isLeft ? 1 : -1); + } + } + tags.add(new IntTag("pairx", x)); + tags.add(new IntTag("pairz", z)); + if (!chestValues.isLeft) { + tags.add(new ByteTag("pairlead", (byte) 1)); + } + } + } + return tags; + } + + @Override + public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + return null; + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return null; + } +} diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 5b3a9ad1..a7963d0a 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 5b3a9ad1d2ef76105fb318e63126a096844b3195 +Subproject commit a7963d0a0236b1c47eea21718ac50706139d90cc From 6192237cc986a9fcbae3350efe92936836b14ef5 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Sun, 10 May 2020 15:38:39 -0400 Subject: [PATCH 015/581] Add parrots on player shoulders (#530) * Add parrots on player shoulders Parrots on player shoulders are a separate entity in Bedrock, but part of the player metadata in Java. This commit creates a parrot entity from the NBT data given by the player's entity data. * Remove unused import * Nullify parrot after despawning * Remove debug code --- .../connector/entity/PlayerEntity.java | 62 ++++++++++++++++++- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java index 82e91f55..a5d2d9a8 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java @@ -28,13 +28,13 @@ package org.geysermc.connector.entity; import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.message.TextMessage; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.CommandPermission; import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.EntityLink; import com.nukkitx.protocol.bedrock.data.PlayerPermission; -import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket; -import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; -import com.nukkitx.protocol.bedrock.packet.PlayerListPacket; +import com.nukkitx.protocol.bedrock.packet.*; import lombok.Getter; import lombok.Setter; @@ -48,6 +48,7 @@ import org.geysermc.connector.network.session.cache.EntityEffectCache; import org.geysermc.connector.utils.SkinUtils; import java.util.UUID; +import java.util.concurrent.TimeUnit; @Getter @Setter public class PlayerEntity extends LivingEntity { @@ -58,6 +59,9 @@ public class PlayerEntity extends LivingEntity { private boolean playerList = true; private final EntityEffectCache effectCache; + private Entity leftParrot; + private Entity rightParrot; + public PlayerEntity(GameProfile gameProfile, long entityId, long geyserId, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, EntityType.PLAYER, position, motion, rotation); @@ -146,6 +150,12 @@ public class PlayerEntity extends LivingEntity { } session.sendUpstreamPacket(movePlayerPacket); + if (leftParrot != null) { + leftParrot.moveAbsolute(session, position, rotation, true, teleported); + } + if (rightParrot != null) { + rightParrot.moveAbsolute(session, position, rotation, true, teleported); + } } @Override @@ -160,6 +170,12 @@ public class PlayerEntity extends LivingEntity { movePlayerPacket.setOnGround(isOnGround); movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL); session.sendUpstreamPacket(movePlayerPacket); + if (leftParrot != null) { + leftParrot.moveRelative(session, relX, relY, relZ, rotation, true); + } + if (rightParrot != null) { + rightParrot.moveRelative(session, relX, relY, relZ, rotation, true); + } } @Override @@ -188,5 +204,45 @@ public class PlayerEntity extends LivingEntity { metadata.put(EntityData.NAMETAG, team.getPrefix() + MessageUtils.toChatColor(team.getColor()) + username + team.getSuffix()); } } + + // Parrot occupying shoulder + if (entityMetadata.getId() == 18 || entityMetadata.getId() == 19) { + CompoundTag tag = (CompoundTag) entityMetadata.getValue(); + if (tag != null && !tag.isEmpty()) { + // The parrot is a separate entity in Bedrock, but part of the player entity in Java + Entity parrot = new Entity(0, session.getEntityCache().getNextEntityId().incrementAndGet(), + EntityType.PARROT, position, motion, rotation); + parrot.spawnEntity(session); + parrot.getMetadata().put(EntityData.VARIANT, tag.get("Variant").getValue()); + // Different position whether the parrot is left or right + float offset = (entityMetadata.getId() == 18) ? 0.4f : -0.4f; + parrot.getMetadata().put(EntityData.RIDER_SEAT_POSITION, Vector3f.from(offset, -0.22, -0.1)); + parrot.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, 1); + parrot.updateBedrockMetadata(session); + SetEntityLinkPacket linkPacket = new SetEntityLinkPacket(); + EntityLink.Type type = (entityMetadata.getId() == 18) ? EntityLink.Type.RIDER : EntityLink.Type.PASSENGER; + linkPacket.setEntityLink(new EntityLink(geyserId, parrot.getGeyserId(), type, false)); + // Delay, or else spawned-in players won't get the link + // TODO: Find a better solution. This problem also exists with item frames + session.getConnector().getGeneralThreadPool().schedule(() -> session.sendUpstreamPacket(linkPacket), 500, TimeUnit.MILLISECONDS); + if (entityMetadata.getId() == 18) { + leftParrot = parrot; + } else { + rightParrot = parrot; + } + } else { + Entity parrot = (entityMetadata.getId() == 18 ? leftParrot : rightParrot); + if (parrot != null) { + SetEntityLinkPacket linkPacket = new SetEntityLinkPacket(); + linkPacket.setEntityLink(new EntityLink(parrot.getGeyserId(), geyserId, EntityLink.Type.REMOVE, false)); + parrot.despawnEntity(session); + if (entityMetadata.getId() == 18) { + leftParrot = null; + } else { + rightParrot = null; + } + } + } + } } } From d2a18f8fd59ee0e6dd715acfcb39b13e16bb40f8 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 10 May 2020 14:47:40 -0500 Subject: [PATCH 016/581] Remove dangling entity link packet in PlayerEntity for parrots --- .../main/java/org/geysermc/connector/entity/PlayerEntity.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java index a5d2d9a8..43891a7e 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java @@ -233,8 +233,6 @@ public class PlayerEntity extends LivingEntity { } else { Entity parrot = (entityMetadata.getId() == 18 ? leftParrot : rightParrot); if (parrot != null) { - SetEntityLinkPacket linkPacket = new SetEntityLinkPacket(); - linkPacket.setEntityLink(new EntityLink(parrot.getGeyserId(), geyserId, EntityLink.Type.REMOVE, false)); parrot.despawnEntity(session); if (entityMetadata.getId() == 18) { leftParrot = null; From cf6309886498c6a11a650c1e81b8c38878f6277f Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 10 May 2020 15:03:12 -0500 Subject: [PATCH 017/581] Add Windows Phone in DeviceOS (Fixes #520) --- common/src/main/java/org/geysermc/floodgate/util/DeviceOS.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/org/geysermc/floodgate/util/DeviceOS.java b/common/src/main/java/org/geysermc/floodgate/util/DeviceOS.java index bd8e4002..93d3c121 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/DeviceOS.java +++ b/common/src/main/java/org/geysermc/floodgate/util/DeviceOS.java @@ -43,7 +43,8 @@ public enum DeviceOS { ORBIS("PS4"), NX("Switch"), SWITCH("Switch"), - XBOX_ONE("Xbox One"); + XBOX_ONE("Xbox One"), + WIN_PHONE("Windows Phone"); private static final DeviceOS[] VALUES = values(); From 720ae3c92dbcf7355f9ed7e7dd66b8e049571462 Mon Sep 17 00:00:00 2001 From: Heath123 Date: Sun, 10 May 2020 21:05:51 +0100 Subject: [PATCH 018/581] Add survival-style block pick support (#526) * Add survival-style block pick support * Add BedrockBlockPickRequestPacketTranslator.java * Remove unnecessary println * Edit styling and add null check * Fix compile error * Remove nesting and unnecessary check * Further reduce nesting * Change 1-line statements and add missing comment * Fix creating translator * Fix imports --- ...drockBlockPickRequestPacketTranslator.java | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestPacketTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestPacketTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestPacketTranslator.java new file mode 100644 index 00000000..288b99d3 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestPacketTranslator.java @@ -0,0 +1,104 @@ +/* + * 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.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientMoveItemToHotbarPacket; +import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.protocol.bedrock.packet.BlockPickRequestPacket; +import com.nukkitx.protocol.bedrock.packet.PlayerHotbarPacket; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.inventory.Inventory; +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.network.translators.item.ItemEntry; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.network.translators.item.ItemTranslator; +import org.geysermc.connector.network.translators.Translators; + +@Translator(packet = BlockPickRequestPacket.class) +public class BedrockBlockPickRequestPacketTranslator extends PacketTranslator { + + @Override + public void translate(BlockPickRequestPacket packet, GeyserSession session) { + Vector3i vector = packet.getBlockPosition(); + BlockState blockToPick = session.getConnector().getWorldManager().getBlockAt(session, vector.getX(), vector.getY(), vector.getZ()); + + // Block is air - chunk caching is probably off + if (blockToPick.getId() == 0) { + return; + } + + // Get the inventory to choose a slot to pick + Inventory inventory = session.getInventoryCache().getOpenInventory(); + if (inventory == null) { + inventory = session.getInventory(); + } + + String targetIdentifier = BlockTranslator.getJavaIdBlockMap().inverse().get(blockToPick).split("\\[")[0]; + ItemTranslator itemTranslator = Translators.getItemTranslator(); + + // Check hotbar for item + for (int i = 36; i < 45; i++) { + if (inventory.getItem(i) == null) { + continue; + } + ItemEntry item = itemTranslator.getItem(inventory.getItem(i)); + // If this isn't the item we're looking for + if (!item.getJavaIdentifier().equals(targetIdentifier)) { + continue; + } + + PlayerHotbarPacket hotbarPacket = new PlayerHotbarPacket(); + hotbarPacket.setContainerId(0); + // Java inventory slot to hotbar slot ID + hotbarPacket.setSelectedHotbarSlot(i - 36); + hotbarPacket.setSelectHotbarSlot(true); + session.sendUpstreamPacket(hotbarPacket); + session.getInventory().setHeldItemSlot(i - 36); + // Don't check inventory if item was in hotbar + return; + } + + // Check inventory for item + for (int i = 9; i < 36; i++) { + if (inventory.getItem(i) == null) { + continue; + } + ItemEntry item = itemTranslator.getItem(inventory.getItem(i)); + // If this isn't the item we're looking for + if (!item.getJavaIdentifier().equals(targetIdentifier)) { + continue; + } + + ClientMoveItemToHotbarPacket packetToSend = new ClientMoveItemToHotbarPacket(i); // https://wiki.vg/Protocol#Pick_Item + session.sendDownstreamPacket(packetToSend); + return; + } + } +} From 64bfad2af94ef40bf73c6d27652a76f654c2b81e Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Sun, 10 May 2020 16:25:28 -0400 Subject: [PATCH 019/581] Use Bukkit methods to send block sound (#522) --- .../platform/bukkit/GeyserBukkitPlugin.java | 4 ++ .../world/GeyserBukkitBlockPlaceListener.java | 63 +++++++++++++++++++ .../java/world/JavaBlockChangeTranslator.java | 3 +- 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java index 3f2b9cad..9ab02583 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java @@ -34,6 +34,7 @@ import org.geysermc.connector.command.CommandManager; import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.platform.bukkit.command.GeyserBukkitCommandExecutor; import org.geysermc.platform.bukkit.command.GeyserBukkitCommandManager; +import org.geysermc.platform.bukkit.world.GeyserBukkitBlockPlaceListener; import org.geysermc.platform.bukkit.world.GeyserBukkitWorldManager; import us.myles.ViaVersion.api.Via; @@ -44,6 +45,7 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { private GeyserBukkitCommandManager geyserCommandManager; private GeyserBukkitConfiguration geyserConfig; private GeyserBukkitLogger geyserLogger; + private GeyserBukkitBlockPlaceListener blockPlaceListener; private GeyserBukkitWorldManager geyserWorldManager; private GeyserConnector connector; @@ -92,6 +94,8 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { } this.geyserWorldManager = new GeyserBukkitWorldManager(isLegacy, isViaVersion); + this.blockPlaceListener = new GeyserBukkitBlockPlaceListener(connector); + Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this); this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector)); } diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java new file mode 100644 index 00000000..d4b57145 --- /dev/null +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java @@ -0,0 +1,63 @@ +/* + * 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.platform.bukkit.world; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.SoundEvent; +import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +import lombok.AllArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; + +@AllArgsConstructor +public class GeyserBukkitBlockPlaceListener implements Listener { + + private final GeyserConnector connector; + + @EventHandler + public void place(final BlockPlaceEvent event) { + for (GeyserSession session : connector.getPlayers().values()) { + if (event.getPlayer() == Bukkit.getPlayer(session.getPlayerEntity().getUsername())) { + LevelSoundEventPacket placeBlockSoundPacket = new LevelSoundEventPacket(); + placeBlockSoundPacket.setSound(SoundEvent.PLACE); + placeBlockSoundPacket.setPosition(Vector3f.from(event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ())); + placeBlockSoundPacket.setBabySound(false); + placeBlockSoundPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaIdBlockMap().get(event.getBlockPlaced().getBlockData().getAsString()))); + placeBlockSoundPacket.setIdentifier(":"); + session.sendUpstreamPacket(placeBlockSoundPacket); + session.setLastBlockPlacePosition(null); + session.setLastBlockPlacedId(null); + } + } + } + +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java index 0fa58ef8..2eb04a8a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java @@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.common.PlatformType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -46,7 +47,7 @@ public class JavaBlockChangeTranslator extends PacketTranslator Date: Mon, 11 May 2020 06:09:16 +0100 Subject: [PATCH 020/581] Various entity fixes (#529) * Fixed invisible entities nametags being displayed * Fixed most entity collision boxes * Fixed area effect cloud not displaying * Fixed armour stand size and marker * Fix baby collision boxes * Fixed squid animation (rotation still broken) * Fix Guardian beam for local player * Fixed armour stand invisibility * Fixed Wither boss data * Fixed fishing line attach to entities --- .../entity/AreaEffectCloudEntity.java | 61 +++++++++++++ .../org/geysermc/connector/entity/Entity.java | 40 +++++---- .../connector/entity/FishingHookEntity.java | 17 ++++ .../entity/living/AbstractFishEntity.java | 10 --- .../entity/living/AgeableEntity.java | 3 + .../entity/living/ArmorStandEntity.java | 25 +++++- .../connector/entity/living/SquidEntity.java | 36 ++++++++ .../connector/entity/living/WaterEntity.java | 3 + .../entity/living/monster/GuardianEntity.java | 4 + .../entity/living/monster/WitherEntity.java | 89 +++++++++++++++++++ .../connector/entity/type/EntityType.java | 52 +++++------ 11 files changed, 287 insertions(+), 53 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/AreaEffectCloudEntity.java create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/SquidEntity.java create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/AreaEffectCloudEntity.java b/connector/src/main/java/org/geysermc/connector/entity/AreaEffectCloudEntity.java new file mode 100644 index 00000000..2808b093 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/AreaEffectCloudEntity.java @@ -0,0 +1,61 @@ +/* + * 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; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.github.steveice10.mc.protocol.data.game.world.particle.Particle; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.EntityData; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.EffectUtils; + +public class AreaEffectCloudEntity extends Entity { + + public AreaEffectCloudEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + + // Without this the cloud doesn't appear, + metadata.put(EntityData.AREA_EFFECT_CLOUD_DURATION, 600); + + // This disabled client side shrink of the cloud + metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS_PER_TICK, 0.0f); + } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + if (entityMetadata.getId() == 7) { + metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, (float) entityMetadata.getValue()); + metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue()); + } else if (entityMetadata.getId() == 10) { + Particle particle = (Particle) entityMetadata.getValue(); + metadata.put(EntityData.AREA_EFFECT_CLOUD_PARTICLE_ID, EffectUtils.getParticleString(particle.getType())); + } else if (entityMetadata.getId() == 8) { + metadata.put(EntityData.POTION_COLOR, entityMetadata.getValue()); + } + super.updateBedrockMetadata(entityMetadata, session); + } +} 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 186c0ae8..d911ff7a 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -35,24 +35,28 @@ import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.*; +import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.EntityDataMap; +import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.EntityFlags; import com.nukkitx.protocol.bedrock.packet.*; - import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; - import lombok.Getter; import lombok.Setter; - import org.geysermc.connector.entity.attribute.Attribute; import org.geysermc.connector.entity.attribute.AttributeType; +import org.geysermc.connector.entity.living.ArmorStandEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.utils.AttributeUtils; import org.geysermc.connector.utils.MessageUtils; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @Getter @Setter @@ -205,6 +209,16 @@ public class Entity { metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10); metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); + metadata.put(EntityData.SCALE, scale); + + if ((xd & 0x20) == 0x20) { + if (this.is(ArmorStandEntity.class)) { + metadata.put(EntityData.SCALE, 0.0f); + } else { + metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true); + } + } + // Shield code if (session.getPlayerEntity().getEntityId() == entityId && metadata.getFlags().getFlag(EntityFlag.SNEAKING)) { if ((session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) || @@ -221,16 +235,11 @@ public class Entity { session.sendDownstreamPacket(useItemPacket); } } else if (session.getPlayerEntity().getEntityId() == entityId && !metadata.getFlags().getFlag(EntityFlag.SNEAKING) && metadata.getFlags().getFlag(EntityFlag.BLOCKING)) { - metadata.getFlags().setFlag(EntityFlag.BLOCKING, false); - metadata.getFlags().setFlag(EntityFlag.DISABLE_BLOCKING, true); - ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0,0,0), BlockFace.DOWN); - session.sendDownstreamPacket(releaseItemPacket); - } - // metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20); - if ((xd & 0x20) == 0x20) - metadata.put(EntityData.SCALE, 0.0f); - else - metadata.put(EntityData.SCALE, scale); + metadata.getFlags().setFlag(EntityFlag.BLOCKING, false); + metadata.getFlags().setFlag(EntityFlag.DISABLE_BLOCKING, true); + ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0, 0, 0), BlockFace.DOWN); + session.sendDownstreamPacket(releaseItemPacket); + } } break; case 2: // custom name @@ -270,6 +279,7 @@ public class Entity { /** * x = Pitch, y = HeadYaw, z = Yaw + * * @return the bedrock rotation */ public Vector3f getBedrockRotation() { diff --git a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java index abd52292..8d8d5ef2 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java @@ -25,6 +25,7 @@ package org.geysermc.connector.entity; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.type.object.ProjectileData; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; @@ -44,4 +45,20 @@ public class FishingHookEntity extends Entity { } } } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + if (entityMetadata.getId() == 7) { + Entity entity = session.getEntityCache().getEntityByJavaId((Integer) entityMetadata.getValue() - 1); + if (entity == null && session.getPlayerEntity().getEntityId() == (Integer) entityMetadata.getValue() - 1) { + entity = session.getPlayerEntity(); + } + + if (entity != null) { + metadata.put(EntityData.TARGET_EID, entity.getGeyserId()); + } + } + + super.updateBedrockMetadata(entityMetadata, session); + } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java index 54443825..de5fa1b5 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java @@ -25,28 +25,18 @@ package org.geysermc.connector.entity.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.EntityFlag; import org.geysermc.connector.entity.type.EntityType; -import org.geysermc.connector.network.session.GeyserSession; public class AbstractFishEntity extends WaterEntity { public AbstractFishEntity(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) { metadata.getFlags().setFlag(EntityFlag.CAN_SWIM, true); metadata.getFlags().setFlag(EntityFlag.BREATHING, true); metadata.getFlags().setFlag(EntityFlag.CAN_CLIMB, false); metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, false); - - metadata.put(EntityData.AIR, (short) 400); - - super.updateBedrockMetadata(entityMetadata, session); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java index 634f0674..b90983f7 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java @@ -44,6 +44,9 @@ public class AgeableEntity extends CreatureEntity { boolean isBaby = (boolean) entityMetadata.getValue(); metadata.put(EntityData.SCALE, isBaby ? .55f : 1f); metadata.getFlags().setFlag(EntityFlag.BABY, isBaby); + + metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight() * (isBaby ? 0.55f : 1f)); + metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth() * (isBaby ? 0.55f : 1f)); } super.updateBedrockMetadata(entityMetadata, session); diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java index 1beb8ab8..3c05933f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java @@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadat import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.LivingEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -43,8 +44,28 @@ public class ArmorStandEntity extends LivingEntity { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getType() == MetadataType.BYTE) { byte xd = (byte) entityMetadata.getValue(); - if ((xd & 0x01) == 0x01 && (metadata.get(EntityData.SCALE) != null && !metadata.get(EntityData.SCALE).equals(0.0f))) { - metadata.put(EntityData.SCALE, .55f); + + // isSmall + if ((xd & 0x01) == 0x01) { + GeyserConnector.getInstance().getLogger().debug("S: " + metadata.get(EntityData.SCALE)); + + if (metadata.get(EntityData.SCALE) == null || (metadata.get(EntityData.SCALE) != null && !metadata.get(EntityData.SCALE).equals(0.55f))) { + metadata.put(EntityData.SCALE, 0.55f); + } + + if (metadata.get(EntityData.BOUNDING_BOX_WIDTH) != null && metadata.get(EntityData.BOUNDING_BOX_WIDTH).equals(0.5f)) { + metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.25f); + metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.9875f); + } + } else if (metadata.get(EntityData.BOUNDING_BOX_WIDTH) != null && metadata.get(EntityData.BOUNDING_BOX_WIDTH).equals(0.25f)) { + metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth()); + metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight()); + } + + // setMarker + if ((xd & 0x10) == 0x10 && (metadata.get(EntityData.BOUNDING_BOX_WIDTH) != null && !metadata.get(EntityData.BOUNDING_BOX_WIDTH).equals(0.0f))) { + metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.0f); + metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.0f); } } super.updateBedrockMetadata(entityMetadata, session); diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/SquidEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/SquidEntity.java new file mode 100644 index 00000000..81c0eeef --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/SquidEntity.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; + +import com.nukkitx.math.vector.Vector3f; +import org.geysermc.connector.entity.type.EntityType; + +public class SquidEntity extends WaterEntity { + + public SquidEntity(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/living/WaterEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java index dc83847a..69afd975 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java @@ -26,11 +26,14 @@ package org.geysermc.connector.entity.living; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.EntityData; import org.geysermc.connector.entity.type.EntityType; public class WaterEntity extends CreatureEntity { public WaterEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); + + metadata.put(EntityData.AIR, (short) 400); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java index 682b02b2..3abbebba 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java @@ -42,6 +42,10 @@ public class GuardianEntity extends MonsterEntity { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getId() == 16) { Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue()); + if (entity == null && session.getPlayerEntity().getEntityId() == (Integer) entityMetadata.getValue()) { + entity = session.getPlayerEntity(); + } + if (entity != null) { metadata.put(EntityData.TARGET_EID, entity.getGeyserId()); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java new file mode 100644 index 00000000..062f4388 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java @@ -0,0 +1,89 @@ +/* + * 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.EntityData; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.entity.attribute.Attribute; +import org.geysermc.connector.entity.attribute.AttributeType; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +public class WitherEntity extends MonsterEntity { + + public WitherEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + + // After WITHER_AERIAL_ATTACK gets fixed in NukkitX/Protocol this can be uncommented + // It hides the withers shield + //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 1); + } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + long targetID = -1; + + if (entityMetadata.getId() >= 15 && entityMetadata.getId() <= 17) { + Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue()); + if (entity == null && session.getPlayerEntity().getEntityId() == (Integer) entityMetadata.getValue()) { + entity = session.getPlayerEntity(); + } + + if (entity != null) { + targetID = entity.getGeyserId(); + } + } + + if (entityMetadata.getId() == 15) { + metadata.put(EntityData.WITHER_TARGET_1, targetID); + } else if (entityMetadata.getId() == 16) { + metadata.put(EntityData.WITHER_TARGET_2, targetID); + } else if (entityMetadata.getId() == 17) { + metadata.put(EntityData.WITHER_TARGET_3, targetID); + } else if (entityMetadata.getId() == 18) { + metadata.put(EntityData.WITHER_INVULNERABLE_TICKS, (int) entityMetadata.getValue()); + + // Show the shield for the first few seconds of spawning (like Java) + if ((int) entityMetadata.getValue() >= 175) { + //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 0); + } else { + //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 1); + } + } + + // If less than 50% health show shield + Attribute health = attributes.get(AttributeType.HEALTH); + if ((health.getValue() <= health.getMaximum() / 2) || health.getMaximum() == 300f) { + //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 0); + } else { + //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 1); + } + + 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 1173796f..5ab4eb1a 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 @@ -47,7 +47,7 @@ public enum EntityType { WOLF(WolfEntity.class, 14, 0.85f, 0.6f), VILLAGER(VillagerEntity.class, 15, 1.8f, 0.6f, 0.6f, 1.62f, "minecraft:villager_v2"), MOOSHROOM(AnimalEntity.class, 16, 1.4f, 0.9f), - SQUID(WaterEntity.class, 17, 0.8f), + SQUID(SquidEntity.class, 17, 0.8f), RABBIT(RabbitEntity.class, 18, 0.5f, 0.4f), BAT(AmbientEntity.class, 19, 0.9f, 0.5f), IRON_GOLEM(GolemEntity.class, 20, 2.7f, 1.4f), @@ -83,7 +83,7 @@ public enum EntityType { GUARDIAN(GuardianEntity.class, 49, 0.85f), ELDER_GUARDIAN(GuardianEntity.class, 50, 1.9975f), NPC(PlayerEntity.class, 51, 1.8f, 0.6f, 0.6f, 1.62f), - WITHER(MonsterEntity.class, 52, 3.5f, 0.9f), + WITHER(WitherEntity.class, 52, 3.5f, 0.9f), ENDER_DRAGON(EnderDragonEntity.class, 53, 4f, 13f), SHULKER(ShulkerEntity.class, 54, 1f, 1f), ENDERMITE(MonsterEntity.class, 55, 0.3f, 0.4f), @@ -94,7 +94,7 @@ public enum EntityType { PHANTOM(FlyingEntity.class, 58, 0.5f, 0.9f, 0.9f, 0.6f), RAVAGER(RaidParticipantEntity.class, 59, 1.9f, 1.2f), - ARMOR_STAND(ArmorStandEntity.class, 61, 0f), + ARMOR_STAND(ArmorStandEntity.class, 61, 1.975f, 0.5f), TRIPOD_CAMERA(Entity.class, 62, 0f), PLAYER(PlayerEntity.class, 63, 1.8f, 0.6f, 0.6f, 1.62f), ITEM(ItemEntity.class, 64, 0.25f, 0.25f), @@ -103,41 +103,41 @@ public enum EntityType { MOVING_BLOCK(Entity.class, 67, 0f), EXPERIENCE_BOTTLE(ThrowableEntity.class, 68, 0.25f, 0.25f, 0f, 0f, "minecraft:xp_bottle"), EXPERIENCE_ORB(ExpOrbEntity.class, 69, 0f, 0f, 0f, 0f, "minecraft:xp_orb"), - EYE_OF_ENDER(Entity.class, 70, 0f), + EYE_OF_ENDER(Entity.class, 70, 0.25f), END_CRYSTAL(EnderCrystalEntity.class, 71, 0f, 0f, 0f, 0f, "minecraft:ender_crystal"), - FIREWORK_ROCKET(Entity.class, 72, 0f), + FIREWORK_ROCKET(Entity.class, 72, 0.25f), TRIDENT(ArrowEntity.class, 73, 0f), TURTLE(AnimalEntity.class, 74, 0.4f, 1.2f), CAT(CatEntity.class, 75, 0.35f, 0.3f), - SHULKER_BULLET(Entity.class, 76, 0f), + SHULKER_BULLET(Entity.class, 76, 0.3125f), FISHING_BOBBER(FishingHookEntity.class, 77, 0f, 0f, 0f, 0f, "minecraft:fishing_hook"), CHALKBOARD(Entity.class, 78, 0f), - DRAGON_FIREBALL(ItemedFireballEntity.class, 79, 0f), + DRAGON_FIREBALL(ItemedFireballEntity.class, 79, 1.0f), ARROW(ArrowEntity.class, 80, 0.25f, 0.25f), - SNOWBALL(ThrowableEntity.class, 81, 0f), - EGG(ThrowableEntity.class, 82, 0f), + SNOWBALL(ThrowableEntity.class, 81, 0.25f), + EGG(ThrowableEntity.class, 82, 0.25f), PAINTING(PaintingEntity.class, 83, 0f), - MINECART(MinecartEntity.class, 84, 0f), - FIREBALL(ItemedFireballEntity.class, 85, 0f), - POTION(ThrowableEntity.class, 86, 0f), - ENDER_PEARL(ThrowableEntity.class, 87, 0f), - LEASH_KNOT(Entity.class, 88, 0f), - WITHER_SKULL(Entity.class, 89, 0f), + MINECART(MinecartEntity.class, 84, 0.7f, 0.98f), + FIREBALL(ItemedFireballEntity.class, 85, 1.0f), + POTION(ThrowableEntity.class, 86, 0.25f), + ENDER_PEARL(ThrowableEntity.class, 87, 0.25f), + LEASH_KNOT(Entity.class, 88, 0.5f, 0.375f), + WITHER_SKULL(Entity.class, 89, 0.3125f), BOAT(Entity.class, 90, 0.7f, 1.6f, 1.6f, 0.35f), WITHER_SKULL_DANGEROUS(Entity.class, 91, 0f), LIGHTNING_BOLT(Entity.class, 93, 0f), - SMALL_FIREBALL(ItemedFireballEntity.class, 94, 0f), - AREA_EFFECT_CLOUD(Entity.class, 95, 0f), - HOPPER_MINECART(MinecartEntity.class, 96, 0f), - TNT_MINECART(MinecartEntity.class, 97, 0f), - CHEST_MINECART(MinecartEntity.class, 98, 0f), + SMALL_FIREBALL(ItemedFireballEntity.class, 94, 0.3125f), + AREA_EFFECT_CLOUD(AreaEffectCloudEntity.class, 95, 0.5f, 1.0f), + HOPPER_MINECART(MinecartEntity.class, 96, 0.7f, 0.98f), + TNT_MINECART(MinecartEntity.class, 97, 0.7f, 0.98f), + CHEST_MINECART(MinecartEntity.class, 98, 0.7f, 0.98f), - COMMAND_BLOCK_MINECART(MinecartEntity.class, 100, 0f), + COMMAND_BLOCK_MINECART(MinecartEntity.class, 100, 0.7f, 0.98f), LINGERING_POTION(ThrowableEntity.class, 101, 0f), - LLAMA_SPIT(Entity.class, 102, 0f), - EVOKER_FANGS(Entity.class, 103, 0f), - EVOKER(SpellcasterIllagerEntity.class, 104, 0f), - VEX(MonsterEntity.class, 105, 0f), + LLAMA_SPIT(Entity.class, 102, 0.25f), + EVOKER_FANGS(Entity.class, 103, 0.8f, 0.5f), + EVOKER(SpellcasterIllagerEntity.class, 104, 1.95f, 0.5f), + VEX(MonsterEntity.class, 105, 0.8f, 0.4f), ICE_BOMB(Entity.class, 106, 0f), BALLOON(Entity.class, 107, 0f), //TODO PUFFERFISH(PufferFishEntity.class, 108, 0.7f, 0.7f), @@ -163,7 +163,7 @@ public enum EntityType { private String identifier; EntityType(Class entityClass, int type, float height) { - this(entityClass, type, height, 0f); + this(entityClass, type, height, height); } EntityType(Class entityClass, int type, float height, float width) { From 324bc67c97935832927a03949208885fc8a37503 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 11 May 2020 20:56:50 +0100 Subject: [PATCH 021/581] Fixed small armour stands not respecting invisibility (#533) --- .../src/main/java/org/geysermc/connector/entity/Entity.java | 2 -- .../geysermc/connector/entity/living/ArmorStandEntity.java | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) 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 d911ff7a..ae3679fe 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -209,8 +209,6 @@ public class Entity { metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10); metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); - metadata.put(EntityData.SCALE, scale); - if ((xd & 0x20) == 0x20) { if (this.is(ArmorStandEntity.class)) { metadata.put(EntityData.SCALE, 0.0f); diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java index 3c05933f..8d3c8f8f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java @@ -29,7 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadat import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; -import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.LivingEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -47,9 +46,7 @@ public class ArmorStandEntity extends LivingEntity { // isSmall if ((xd & 0x01) == 0x01) { - GeyserConnector.getInstance().getLogger().debug("S: " + metadata.get(EntityData.SCALE)); - - if (metadata.get(EntityData.SCALE) == null || (metadata.get(EntityData.SCALE) != null && !metadata.get(EntityData.SCALE).equals(0.55f))) { + if (metadata.getFloat(EntityData.SCALE) != 0.55f && metadata.getFloat(EntityData.SCALE) != 0.0f) { metadata.put(EntityData.SCALE, 0.55f); } From c84c0f23cb583b65970593ee1b870134bda3a049 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 12 May 2020 05:44:30 +0100 Subject: [PATCH 022/581] Fixed invisible flag not getting set back (#535) * Fixed invisible flag not getting set back * Fixed indentation --- .../src/main/java/org/geysermc/connector/entity/Entity.java | 2 ++ 1 file changed, 2 insertions(+) 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 ae3679fe..2fe830af 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -215,6 +215,8 @@ public class Entity { } else { metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true); } + } else { + metadata.getFlags().setFlag(EntityFlag.INVISIBLE, false); } // Shield code From 0c60af66b2a6503fc762af2ab215fb8219826e3b Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 12 May 2020 05:45:16 +0100 Subject: [PATCH 023/581] Fixed customised skins causing strange display (#534) * Fixed customised skins causing strange display * Cleaned up floodgate player checking * Fixed cape scale Co-authored-by: James Harrison --- .../connector/network/session/GeyserSession.java | 2 +- .../network/session/auth/BedrockClientData.java | 15 +++++++++++++++ .../geysermc/connector/utils/SkinProvider.java | 4 +++- .../org/geysermc/connector/utils/SkinUtils.java | 7 ++++--- 4 files changed, 23 insertions(+), 5 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 759a0f3b..fa9960f2 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 @@ -341,7 +341,7 @@ public class GeyserSession implements CommandSender { playerEntity.setUuid(profile.getId()); // Check if they are not using a linked account - if (!playerEntity.getUuid().toString().startsWith("00000000-0000-0000")) { + if (connector.getAuthType() == AuthType.OFFLINE || playerEntity.getUuid().getMostSignificantBits() == 0) { SkinUtils.handleBedrockSkin(playerEntity, clientData); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java b/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java index 4ef0fe79..6aeebbaa 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java @@ -32,12 +32,18 @@ public class BedrockClientData { private String capeId; @JsonProperty(value = "CapeData") private byte[] capeData; + @JsonProperty(value = "CapeImageHeight") + private int capeImageHeight; + @JsonProperty(value = "CapeImageWidth") + private int capeImageWidth; @JsonProperty(value = "CapeOnClassicSkin") private boolean capeOnClassicSkin; @JsonProperty(value = "SkinResourcePatch") private String geometryName; @JsonProperty(value = "SkinGeometryData") private String geometryData; + @JsonProperty(value = "PersonaSkin") + private boolean personaSkin; @JsonProperty(value = "PremiumSkin") private boolean premiumSkin; @@ -64,6 +70,15 @@ public class BedrockClientData { @JsonProperty(value = "ClientRandomId") private long clientRandomId; + @JsonProperty(value = "ArmSize") + private String armSize; + @JsonProperty(value = "SkinAnimationData") + private String skinAnimationData; + @JsonProperty(value = "SkinColor") + private String skinColor; + @JsonProperty(value = "ThirdPartyNameOnly") + private boolean thirdPartyNameOnly; + public enum UIProfile { @JsonEnumDefaultValue CLASSIC, diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java index 15cccf22..469ae758 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java @@ -223,7 +223,9 @@ public class SkinProvider { // if the requested image is an cape if (provider != null) { - image = image.getWidth() > 64 ? scale(image) : image; + while(image.getWidth() > 64) { + image = scale(image); + } BufferedImage newImage = new BufferedImage(64, 32, BufferedImage.TYPE_INT_RGB); Graphics g = newImage.createGraphics(); g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null); 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 1d0ee216..8e68d3e1 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -220,13 +220,14 @@ public class SkinUtils { byte[] geometryNameBytes = com.github.steveice10.mc.auth.util.Base64.decode(clientData.getGeometryName().getBytes("UTF-8")); byte[] geometryBytes = com.github.steveice10.mc.auth.util.Base64.decode(clientData.getGeometryData().getBytes("UTF-8")); - if (skinBytes.length <= (128 * 128 * 4)) { + if (skinBytes.length <= (128 * 128 * 4) && !clientData.isPersonaSkin()) { SkinProvider.storeBedrockSkin(playerEntity.getUuid(), data.getSkinUrl(), skinBytes); + SkinProvider.storeBedrockGeometry(playerEntity.getUuid(), geometryNameBytes, geometryBytes); } else { - GeyserConnector.getInstance().getLogger().info("Unable to load bedrock skin for '" + playerEntity.getUsername() + "' as they are using a customised skin"); + GeyserConnector.getInstance().getLogger().info("Unable to load bedrock skin for '" + playerEntity.getUsername() + "' as they are likely using a customised skin"); GeyserConnector.getInstance().getLogger().debug("The size of '" + playerEntity.getUsername() + "' skin is: " + clientData.getSkinImageWidth() + "x" + clientData.getSkinImageHeight()); } - SkinProvider.storeBedrockGeometry(playerEntity.getUuid(), geometryNameBytes, geometryBytes); + if (!clientData.getCapeId().equals("")) { SkinProvider.storeBedrockCape(playerEntity.getUuid(), capeBytes); } From d63d0def5ad30d8547d98cc90f162f0784fa673b Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Tue, 12 May 2020 15:59:28 -0400 Subject: [PATCH 024/581] Break for loop in GeyserBukkitBlockPlaceListener when a player is found (#538) No need to keep searching when a player is found. --- .../platform/bukkit/world/GeyserBukkitBlockPlaceListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java index d4b57145..877e6646 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java @@ -56,6 +56,7 @@ public class GeyserBukkitBlockPlaceListener implements Listener { session.sendUpstreamPacket(placeBlockSoundPacket); session.setLastBlockPlacePosition(null); session.setLastBlockPlacedId(null); + break; } } } From 46b005443555517248bab1ea21c7d8ae78d23ed0 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Wed, 13 May 2020 03:31:42 +0100 Subject: [PATCH 025/581] Fixed guardian beam getting stuck on players (#540) * Fixed guardian beam getting stuck on players * Fixed formatting --- .../connector/entity/living/monster/GuardianEntity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java index 3abbebba..821faa85 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java @@ -48,6 +48,8 @@ public class GuardianEntity extends MonsterEntity { if (entity != null) { metadata.put(EntityData.TARGET_EID, entity.getGeyserId()); + } else { + metadata.put(EntityData.TARGET_EID, (long) 0); } } From 9673e1e4aa3432ade3d288765f22e6482fbb05db Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Wed, 13 May 2020 17:07:41 -0400 Subject: [PATCH 026/581] Use ViaVersion for block placing sounds (#551) GeyserBukkitBlockPlaceListener previous assumed that getBlockData() was available. This separates the ViaVersion code from getBlockAt to make it accessible elsewhere. --- .../platform/bukkit/GeyserBukkitPlugin.java | 2 +- .../world/GeyserBukkitBlockPlaceListener.java | 11 ++++++- .../world/GeyserBukkitWorldManager.java | 32 +++++++++++-------- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java index 9ab02583..dda804b7 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java @@ -94,7 +94,7 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { } this.geyserWorldManager = new GeyserBukkitWorldManager(isLegacy, isViaVersion); - this.blockPlaceListener = new GeyserBukkitBlockPlaceListener(connector); + this.blockPlaceListener = new GeyserBukkitBlockPlaceListener(connector, isLegacy, isViaVersion); Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this); this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector)); diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java index 877e6646..76d1564e 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java @@ -42,6 +42,8 @@ import org.geysermc.connector.network.translators.world.block.BlockTranslator; public class GeyserBukkitBlockPlaceListener implements Listener { private final GeyserConnector connector; + private final boolean isLegacy; + private final boolean isViaVersion; @EventHandler public void place(final BlockPlaceEvent event) { @@ -51,7 +53,14 @@ public class GeyserBukkitBlockPlaceListener implements Listener { placeBlockSoundPacket.setSound(SoundEvent.PLACE); placeBlockSoundPacket.setPosition(Vector3f.from(event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ())); placeBlockSoundPacket.setBabySound(false); - placeBlockSoundPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaIdBlockMap().get(event.getBlockPlaced().getBlockData().getAsString()))); + String javaBlockId; + if (isLegacy) { + javaBlockId = BlockTranslator.getJavaIdBlockMap().inverse().get(GeyserBukkitWorldManager.getLegacyBlock(session, + event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ(), isViaVersion)); + } else { + javaBlockId = event.getBlockPlaced().getBlockData().getAsString(); + } + placeBlockSoundPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaIdBlockMap().get(javaBlockId))); placeBlockSoundPacket.setIdentifier(":"); session.sendUpstreamPacket(placeBlockSoundPacket); session.setLastBlockPlacePosition(null); diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java index 44a520e8..fbdf2a47 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java @@ -29,11 +29,13 @@ package org.geysermc.platform.bukkit.world; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import lombok.AllArgsConstructor; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.platform.bukkit.GeyserBukkitPlugin; import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.Protocol1_13_1To1_13; import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data.MappingData; @@ -46,25 +48,29 @@ public class GeyserBukkitWorldManager extends WorldManager { private final boolean isViaVersion; @Override - @SuppressWarnings("deprecation") public BlockState getBlockAt(GeyserSession session, int x, int y, int z) { if (session.getPlayerEntity() == null) { return BlockTranslator.AIR; } if (isLegacy) { - if (isViaVersion) { - Block block = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z); - // Black magic that gets the old block state ID - int oldBlockId = (block.getType().getId() << 4) | (block.getData() & 0xF); - // Convert block state from old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 - int thirteenBlockId = us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData.blockMappings.getNewId(oldBlockId); - int thirteenPointOneBlockId = Protocol1_13_1To1_13.getNewBlockStateId(thirteenBlockId); - int fourteenBlockId = us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.blockStateMappings.getNewId(thirteenPointOneBlockId); - return new BlockState(MappingData.blockStateMappings.getNewId(fourteenBlockId)); - } else { - return BlockTranslator.AIR; - } + return getLegacyBlock(session, x, y, z, isViaVersion); } return BlockTranslator.getJavaIdBlockMap().get(Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z).getBlockData().getAsString()); } + + @SuppressWarnings("deprecation") + public static BlockState getLegacyBlock(GeyserSession session, int x, int y, int z, boolean isViaVersion) { + if (isViaVersion) { + Block block = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z); + // Black magic that gets the old block state ID + int oldBlockId = (block.getType().getId() << 4) | (block.getData() & 0xF); + // Convert block state from old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 + int thirteenBlockId = us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData.blockMappings.getNewId(oldBlockId); + int thirteenPointOneBlockId = Protocol1_13_1To1_13.getNewBlockStateId(thirteenBlockId); + int fourteenBlockId = us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.blockStateMappings.getNewId(thirteenPointOneBlockId); + return new BlockState(MappingData.blockStateMappings.getNewId(fourteenBlockId)); + } else { + return BlockTranslator.AIR; + } + } } From 6aadfb3a63532085e299d5614bff871bc5c64d57 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Wed, 13 May 2020 22:08:14 +0100 Subject: [PATCH 027/581] Fixed wither shield (#544) --- .../entity/living/monster/WitherEntity.java | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java index 062f4388..005d0db3 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java @@ -29,8 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadat import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.entity.attribute.Attribute; -import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -39,14 +37,12 @@ public class WitherEntity extends MonsterEntity { public WitherEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); - // After WITHER_AERIAL_ATTACK gets fixed in NukkitX/Protocol this can be uncommented - // It hides the withers shield - //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 1); + metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 1); } @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - long targetID = -1; + long targetID = 0; if (entityMetadata.getId() >= 15 && entityMetadata.getId() <= 17) { Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue()); @@ -69,21 +65,13 @@ public class WitherEntity extends MonsterEntity { metadata.put(EntityData.WITHER_INVULNERABLE_TICKS, (int) entityMetadata.getValue()); // Show the shield for the first few seconds of spawning (like Java) - if ((int) entityMetadata.getValue() >= 175) { - //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 0); + if ((int) entityMetadata.getValue() >= 165) { + metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 0); } else { - //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 1); + metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 1); } } - // If less than 50% health show shield - Attribute health = attributes.get(AttributeType.HEALTH); - if ((health.getValue() <= health.getMaximum() / 2) || health.getMaximum() == 300f) { - //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 0); - } else { - //metadata.put(EntityData.WITHER_AERIAL_ATTACK, (short) 1); - } - super.updateBedrockMetadata(entityMetadata, session); } } From 278f59103e8977b97078623103b39c853a6a1eef Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Wed, 13 May 2020 17:08:32 -0400 Subject: [PATCH 028/581] Replace illusioners with pillagers (#550) Illusioners do not exist in Bedrock edition; this commit replaces them with pillagers so they can be somewhat replicated. --- .../org/geysermc/connector/entity/type/EntityType.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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 5ab4eb1a..c77baf0e 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,7 +152,12 @@ public enum EntityType { /** * Item frames are handled differently since they are a block in Bedrock. */ - ITEM_FRAME(ItemFrameEntity.class, 0, 0, 0); + ITEM_FRAME(ItemFrameEntity.class, 0, 0, 0), + + /** + * Not an entity in Bedrock, so we replace it with a Pillager + */ + ILLUSIONER(AbstractIllagerEntity.class, 114, 1.8f, 0.6f, 0.6f, 1.62f, "minecraft:pillager"); private Class entityClass; private final int type; From d5c14921e93972a380a6cadf55f40326577c5264 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Wed, 13 May 2020 17:08:52 -0400 Subject: [PATCH 029/581] Add message when playing record (#549) It appears that the record message is client-sided in Java Edition, so this sends a message whenever a record is played in-world. --- .../java/world/JavaPlayEffectTranslator.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) 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 8e76d7d8..3afb79bd 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 @@ -33,6 +33,7 @@ import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +import com.nukkitx.protocol.bedrock.packet.TextPacket; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -40,6 +41,10 @@ import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.effect.Effect; import org.geysermc.connector.utils.EffectUtils; +import org.geysermc.connector.utils.LocaleUtils; + +import java.util.ArrayList; +import java.util.List; @Translator(packet = ServerPlayEffectPacket.class) public class JavaPlayEffectTranslator extends PacketTranslator { @@ -125,6 +130,22 @@ public class JavaPlayEffectTranslator extends PacketTranslator params = new ArrayList<>(); + // Couldn't figure out how to set this to Bedrock translation so it just uses the Java translation + String recordString = "item.minecraft." + EffectUtils.RECORDS.get(recordEffectData.getRecordId()).name().toLowerCase().replace("record_", "music_disc_") + ".desc"; + params.add(LocaleUtils.getLocaleString(recordString, session.getClientData().getLanguageCode())); + textPacket.setParameters(params); + session.sendUpstreamPacket(textPacket); + } } else { soundEvent.setSound(SoundEvent.valueOf(geyserEffect.getBedrockName())); } From c6527fa723038bdf433c5399cf92f4a27fecf825 Mon Sep 17 00:00:00 2001 From: Redned Date: Wed, 13 May 2020 17:53:13 -0500 Subject: [PATCH 030/581] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 713e77b7..874c79f3 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,14 @@ Geyser is a bridge between Minecraft: Bedrock Edition and Minecraft: Java Edition, closing the gap from those wanting to play true cross-platform. +Geyser is an open collaboration project by [CubeCraft Games](https://cubecraft.net). + ## What is Geyser? Geyser is a proxy, bridging the gap between Minecraft: Bedrock Edition and Minecraft: Java Edition servers. The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible. **Please note, this project is still a work in progress and should not be used on production. Expect bugs!** +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.14.6(0) and Minecraft Java v1.15.2. ## Setting Up From d4995acec694009fb512a7a9d6d5a106208f7f17 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Thu, 14 May 2020 12:30:33 -0400 Subject: [PATCH 031/581] Add support for absorption (golden hearts) (#553) Absorption is an attribute in Bedrock and an entity metadata value in Java. This commit sends an attribute update packet when the metadata value is updated. --- .../connector/entity/PlayerEntity.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java index 43891a7e..98b6b7da 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java @@ -26,14 +26,12 @@ package org.geysermc.connector.entity; import com.github.steveice10.mc.auth.data.GameProfile; +import com.github.steveice10.mc.protocol.data.game.entity.Effect; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.CommandPermission; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityLink; -import com.nukkitx.protocol.bedrock.data.PlayerPermission; +import com.nukkitx.protocol.bedrock.data.*; import com.nukkitx.protocol.bedrock.packet.*; import lombok.Getter; @@ -47,6 +45,8 @@ import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.network.session.cache.EntityEffectCache; import org.geysermc.connector.utils.SkinUtils; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -205,6 +205,17 @@ public class PlayerEntity extends LivingEntity { } } + // Extra hearts - is not metadata but an attribute on Bedrock + if (entityMetadata.getId() == 14) { + UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); + attributesPacket.setRuntimeEntityId(geyserId); + List attributes = new ArrayList<>(); + // Setting to a higher maximum since plugins/datapacks can probably extend the Bedrock soft limit + attributes.add(new Attribute("minecraft:absorption", 0.0f, 1024f, (float) entityMetadata.getValue(), 0.0f)); + attributesPacket.setAttributes(attributes); + session.sendUpstreamPacket(attributesPacket); + } + // Parrot occupying shoulder if (entityMetadata.getId() == 18 || entityMetadata.getId() == 19) { CompoundTag tag = (CompoundTag) entityMetadata.getValue(); From 919af5203d27289af3f0e7549d2e5982958cdabf Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 15 May 2020 01:41:42 +0100 Subject: [PATCH 032/581] Fix banner items loosing patterns in inventory (#560) --- .../item/translators/BannerTranslator.java | 93 +++++++++++++++++++ .../entity/BannerBlockEntityTranslator.java | 39 ++------ .../geysermc/connector/utils/ItemUtils.java | 79 ++++++++++++++++ 3 files changed, 179 insertions(+), 32 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java 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 new file mode 100644 index 00000000..00ee7c0d --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java @@ -0,0 +1,93 @@ +/* + * 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.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.protocol.bedrock.data.ItemData; +import org.geysermc.connector.network.translators.ItemRemapper; +import org.geysermc.connector.network.translators.ItemStackTranslator; +import org.geysermc.connector.network.translators.item.ItemEntry; +import org.geysermc.connector.utils.ItemUtils; +import org.geysermc.connector.utils.Toolbox; + +import java.util.List; +import java.util.stream.Collectors; + +@ItemRemapper +public class BannerTranslator extends ItemStackTranslator { + + private List appliedItems; + + public BannerTranslator() { + appliedItems = Toolbox.ITEM_ENTRIES.values().stream().filter(entry -> entry.getJavaIdentifier().endsWith("banner")).collect(Collectors.toList()); + } + + @Override + public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry); + + ItemData itemData = super.translateToBedrock(itemStack, itemEntry); + + CompoundTag blockEntityTag = itemStack.getNbt().get("BlockEntityTag"); + if (blockEntityTag.contains("Patterns")) { + ListTag patterns = blockEntityTag.get("Patterns"); + + CompoundTagBuilder builder = itemData.getTag().toBuilder(); + builder.tag(ItemUtils.convertBannerPattern(patterns)); + + itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.buildRootTag()); + } + + return itemData; + } + + @Override + public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) { + if (itemData.getTag() == null) return super.translateToJava(itemData, itemEntry); + + ItemStack itemStack = super.translateToJava(itemData, itemEntry); + + com.nukkitx.nbt.tag.CompoundTag nbtTag = itemData.getTag(); + if (nbtTag.contains("Patterns")) { + com.nukkitx.nbt.tag.ListTag patterns = (com.nukkitx.nbt.tag.ListTag) nbtTag.get("Patterns"); + + CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); + blockEntityTag.put(ItemUtils.convertBannerPattern(patterns)); + + itemStack.getNbt().put(blockEntityTag); + } + + return itemStack; + } + + @Override + public List getAppliedItems() { + return appliedItems; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java index eefd8402..41f83bad 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java @@ -33,6 +33,7 @@ import com.nukkitx.nbt.tag.IntTag; import com.nukkitx.nbt.tag.StringTag; import com.nukkitx.nbt.tag.Tag; import org.geysermc.connector.network.translators.world.block.BlockStateValues; +import org.geysermc.connector.utils.ItemUtils; import java.util.ArrayList; import java.util.List; @@ -48,26 +49,21 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implement @Override public List> translateTag(CompoundTag tag, BlockState blockState) { List> tags = new ArrayList<>(); + int bannerColor = BlockStateValues.getBannerColor(blockState); if (bannerColor != -1) { tags.add(new IntTag("Base", 15 - bannerColor)); } - ListTag patterns = tag.get("Patterns"); - List tagsList = new ArrayList<>(); + if (tag.contains("Patterns")) { - for (com.github.steveice10.opennbt.tag.builtin.Tag patternTag : patterns.getValue()) { - com.nukkitx.nbt.tag.CompoundTag newPatternTag = getPattern((CompoundTag) patternTag); - if (newPatternTag != null) { - tagsList.add(newPatternTag); - } - } - com.nukkitx.nbt.tag.ListTag bedrockPatterns = - new com.nukkitx.nbt.tag.ListTag<>("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, tagsList); - tags.add(bedrockPatterns); + ListTag patterns = tag.get("Patterns"); + tags.add(ItemUtils.convertBannerPattern(patterns)); } + if (tag.contains("CustomName")) { tags.add(new StringTag("CustomName", (String) tag.get("CustomName").getValue())); } + return tags; } @@ -84,25 +80,4 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implement tagBuilder.listTag("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, new ArrayList<>()); return tagBuilder.buildRootTag(); } - - /** - * Convert the Java edition pattern nbt to Bedrock edition, null if the pattern doesn't exist - * - * @param pattern Java edition pattern nbt - * @return The Bedrock edition format pattern nbt - */ - protected com.nukkitx.nbt.tag.CompoundTag getPattern(CompoundTag pattern) { - String patternName = (String) pattern.get("Pattern").getValue(); - - // Return null if its the globe pattern as it doesn't exist on bedrock - if (patternName.equals("glb")) { - return null; - } - - return CompoundTagBuilder.builder() - .intTag("Color", 15 - (int) pattern.get("Color").getValue()) - .stringTag("Pattern", (String) pattern.get("Pattern").getValue()) - .stringTag("Pattern", patternName) - .buildRootTag(); - } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java index bb3cf0ed..d3fe48d9 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java @@ -26,6 +26,12 @@ package org.geysermc.connector.utils; import com.github.steveice10.opennbt.tag.builtin.*; +import com.nukkitx.nbt.CompoundTagBuilder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class ItemUtils { @@ -44,4 +50,77 @@ public class ItemUtils { } return 0; } + + /** + * Convert a list of patterns from Java nbt to Bedrock nbt + * + * @param patterns The patterns to convert + * @return The new converted patterns + */ + public static com.nukkitx.nbt.tag.ListTag convertBannerPattern(ListTag patterns) { + List tagsList = new ArrayList<>(); + for (com.github.steveice10.opennbt.tag.builtin.Tag patternTag : patterns.getValue()) { + com.nukkitx.nbt.tag.CompoundTag newPatternTag = getBedrockBannerPattern((CompoundTag) patternTag); + if (newPatternTag != null) { + tagsList.add(newPatternTag); + } + } + + return new com.nukkitx.nbt.tag.ListTag<>("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, tagsList); + } + + /** + * Convert the Java edition banner pattern nbt to Bedrock edition, null if the pattern doesn't exist + * + * @param pattern Java edition pattern nbt + * @return The Bedrock edition format pattern nbt + */ + public static com.nukkitx.nbt.tag.CompoundTag getBedrockBannerPattern(CompoundTag pattern) { + String patternName = (String) pattern.get("Pattern").getValue(); + + // Return null if its the globe pattern as it doesn't exist on bedrock + if (patternName.equals("glb")) { + return null; + } + + return CompoundTagBuilder.builder() + .intTag("Color", 15 - (int) pattern.get("Color").getValue()) + .stringTag("Pattern", (String) pattern.get("Pattern").getValue()) + .stringTag("Pattern", patternName) + .buildRootTag(); + } + + /** + * Convert a list of patterns from Bedrock nbt to Java nbt + * + * @param patterns The patterns to convert + * @return The new converted patterns + */ + public static ListTag convertBannerPattern(com.nukkitx.nbt.tag.ListTag patterns) { + List tagsList = new ArrayList<>(); + for (Object patternTag : patterns.getValue()) { + CompoundTag newPatternTag = getJavaBannerPattern((com.nukkitx.nbt.tag.CompoundTag) patternTag); + if (newPatternTag != null) { + tagsList.add(newPatternTag); + } + } + + return new ListTag("Patterns", tagsList); + } + + /** + * Convert the Bedrock edition banner pattern nbt to Java edition + * + * @param pattern Bedorck edition pattern nbt + * @return The Java edition format pattern nbt + */ + public static CompoundTag getJavaBannerPattern(com.nukkitx.nbt.tag.CompoundTag pattern) { + String patternName = (String) pattern.get("Pattern").getValue(); + + Map tags = new HashMap<>(); + tags.put("Color", new IntTag("Color", 15 - pattern.getInt("Color"))); + tags.put("Pattern", new StringTag("Pattern", pattern.getString("Pattern"))); + + return new CompoundTag("", tags); + } } From 2830756a55e5dbe14c906d05600d2933624a9407 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 15 May 2020 17:08:44 +0100 Subject: [PATCH 033/581] Fixed unusable space being off by 1 (#561) --- .../translators/inventory/updater/ChestInventoryUpdater.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java index e9541bd1..6656cc83 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java @@ -48,7 +48,7 @@ public class ChestInventoryUpdater extends InventoryUpdater { ItemData[] bedrockItems = new ItemData[paddedSize]; for (int i = 0; i < bedrockItems.length; i++) { - if (i <= translator.size) { + if (i < translator.size) { bedrockItems[i] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)); } else { bedrockItems[i] = UNUSUABLE_SPACE_BLOCK; From 1b260c16d7cbe6731d5f378fc0f15fee79c4b71a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Fri, 15 May 2020 13:50:34 -0400 Subject: [PATCH 034/581] Leash fixes (#567) * Leash fixes - Adds visuals for leash string by translating ServerEntityAttachPacket - Updates position offset for lead knots, making them properly appear on fences * Add basic description of JavaEntityAttachTranslator --- .../connector/entity/LeashKnotEntity.java | 39 +++++++++ .../connector/entity/type/EntityType.java | 2 +- .../entity/JavaEntityAttachTranslator.java | 81 +++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/LeashKnotEntity.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAttachTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/LeashKnotEntity.java b/connector/src/main/java/org/geysermc/connector/entity/LeashKnotEntity.java new file mode 100644 index 00000000..0bec07b0 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/LeashKnotEntity.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; + +import com.nukkitx.math.vector.Vector3f; +import org.geysermc.connector.entity.type.EntityType; + +public class LeashKnotEntity extends Entity { + + public LeashKnotEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + // Position is incorrect by default + super(entityId, geyserId, entityType, position.add(0.5f, 0.25f, 0.5f), 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 c77baf0e..ed231d8c 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 @@ -121,7 +121,7 @@ public enum EntityType { FIREBALL(ItemedFireballEntity.class, 85, 1.0f), POTION(ThrowableEntity.class, 86, 0.25f), ENDER_PEARL(ThrowableEntity.class, 87, 0.25f), - LEASH_KNOT(Entity.class, 88, 0.5f, 0.375f), + LEASH_KNOT(LeashKnotEntity.class, 88, 0.5f, 0.375f), WITHER_SKULL(Entity.class, 89, 0.3125f), BOAT(Entity.class, 90, 0.7f, 1.6f, 1.6f, 0.35f), WITHER_SKULL_DANGEROUS(Entity.class, 91, 0f), diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAttachTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAttachTranslator.java new file mode 100644 index 00000000..6e53df27 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAttachTranslator.java @@ -0,0 +1,81 @@ +/* + * 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.java.entity; + +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityAttachPacket; +import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.EntityEventType; +import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; +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; + +/** + * Called when a leash is attached, removed or updated from an entity + */ +@Translator(packet = ServerEntityAttachPacket.class) +public class JavaEntityAttachTranslator extends PacketTranslator { + + @Override + public void translate(ServerEntityAttachPacket packet, GeyserSession session) { + + Entity holderId; + if (packet.getEntityId() == session.getPlayerEntity().getEntityId()) { + holderId = session.getPlayerEntity(); + } else { + holderId = session.getEntityCache().getEntityByJavaId(packet.getEntityId()); + if (holderId == null) { + return; + } + } + + Entity attachedToId; + if (packet.getAttachedToId() == session.getPlayerEntity().getEntityId()) { + attachedToId = session.getPlayerEntity(); + } else { + attachedToId = session.getEntityCache().getEntityByJavaId(packet.getAttachedToId()); + if ((attachedToId == null || packet.getAttachedToId() == 0)) { + // Is not being leashed + holderId.getMetadata().getFlags().setFlag(EntityFlag.LEASHED, false); + holderId.getMetadata().put(EntityData.LEAD_HOLDER_EID, 0); + holderId.updateBedrockMetadata(session); + EntityEventPacket eventPacket = new EntityEventPacket(); + eventPacket.setRuntimeEntityId(holderId.getGeyserId()); + eventPacket.setType(EntityEventType.REMOVE_LEASH); + eventPacket.setData(0); + session.sendUpstreamPacket(eventPacket); + return; + } + } + + holderId.getMetadata().getFlags().setFlag(EntityFlag.LEASHED, true); + holderId.getMetadata().put(EntityData.LEAD_HOLDER_EID, attachedToId.getGeyserId()); + holderId.updateBedrockMetadata(session); + } +} From b4ecb88d4942fa75d9d2fc1221e34695ef15c9b2 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Fri, 15 May 2020 16:29:54 -0400 Subject: [PATCH 035/581] Add air bubble UI support (#569) This commit translates entity metadata ID 1 into the AIR entity metadata. --- .../main/java/org/geysermc/connector/entity/Entity.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 2fe830af..d0c1920f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -98,7 +98,7 @@ public class Entity { metadata.put(EntityData.SCALE, 1f); metadata.put(EntityData.COLOR, 0); - metadata.put(EntityData.MAX_AIR, (short) 400); + metadata.put(EntityData.MAX_AIR, (short) 300); metadata.put(EntityData.AIR, (short) 0); metadata.put(EntityData.LEAD_HOLDER_EID, -1L); metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight()); @@ -242,6 +242,13 @@ public class Entity { } } break; + case 1: // Air/bubbles + if ((int) entityMetadata.getValue() == 300) { + metadata.put(EntityData.AIR, (short) 0); // Otherwise the bubble counter remains in the UI + } else { + metadata.put(EntityData.AIR, (short) (int) entityMetadata.getValue()); + } + break; case 2: // custom name TextMessage name = (TextMessage) entityMetadata.getValue(); if (name != null) From 30e38b3a2f30ebd61dbd70e6cb9e1b5769eb41c4 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sat, 16 May 2020 23:52:39 -0500 Subject: [PATCH 036/581] Add basic villager trading support (incomplete) This commit implements basic functionality for villager trading. This is still incomplete and is buggy in areas such as with villager trades that have more than one input and trade inputs and outputs containing NBT. Co-authored-by: DoctorMacc --- .../living/merchant/VillagerEntity.java | 7 + .../network/session/GeyserSession.java | 10 ++ .../network/translators/Translators.java | 1 + ...BedrockInventoryTransactionTranslator.java | 5 + .../MerchantInventoryTranslator.java | 170 ++++++++++++++++++ .../translators/item/ItemTranslator.java | 45 +++++ .../java/world/JavaTradeListTranslator.java | 115 ++++++++++++ 7 files changed, 353 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/inventory/MerchantInventoryTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/merchant/VillagerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/merchant/VillagerEntity.java index 895f8cc1..adb362e0 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/merchant/VillagerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/merchant/VillagerEntity.java @@ -27,10 +27,13 @@ package org.geysermc.connector.entity.living.merchant; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData; +import com.github.steveice10.mc.protocol.data.game.window.VillagerTrade; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import lombok.Getter; +import lombok.Setter; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -66,6 +69,10 @@ public class VillagerEntity extends AbstractMerchantEntity { VILLAGER_REGIONS.put(6, 6); } + @Getter + @Setter + private VillagerTrade[] villagerTrades; + public VillagerEntity(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/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index fa9960f2..ea34bef6 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 @@ -30,6 +30,7 @@ import com.github.steveice10.mc.auth.exception.request.InvalidCredentialsExcepti import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.SubProtocol; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket; @@ -149,9 +150,18 @@ public class GeyserSession implements CommandSender { @Setter private boolean interacting; + @Setter + private long lastInteractedVillagerEid; + @Setter private Vector3i lastInteractionPosition; + @Setter + private ItemStack firstTradeSlot; + + @Setter + private ItemStack secondTradeSlot; + @Setter private boolean switchingDimension = false; private boolean manyDimPackets = false; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java b/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java index 03042e3a..376d0f43 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java @@ -159,6 +159,7 @@ public class Translators { inventoryTranslators.put(WindowType.ANVIL, new AnvilInventoryTranslator()); inventoryTranslators.put(WindowType.CRAFTING, new CraftingInventoryTranslator()); inventoryTranslators.put(WindowType.GRINDSTONE, new GrindstoneInventoryTranslator()); + inventoryTranslators.put(WindowType.MERCHANT, new MerchantInventoryTranslator()); //inventoryTranslators.put(WindowType.ENCHANTMENT, new EnchantmentInventoryTranslator()); //TODO InventoryTranslator furnace = new FurnaceInventoryTranslator(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java index 71ba20e4..20b19432 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java @@ -44,6 +44,7 @@ import com.nukkitx.protocol.bedrock.packet.InventoryTransactionPacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.ItemFrameEntity; +import org.geysermc.connector.entity.living.merchant.VillagerEntity; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -187,6 +188,10 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator actions) { + InventoryActionData result = null; + + VillagerEntity villager = (VillagerEntity) session.getEntityCache().getEntityByGeyserId(session.getLastInteractedVillagerEid()); + if (villager == null) { + session.getConnector().getLogger().debug("Could not find villager with entity id: " + session.getLastInteractedVillagerEid()); + return; + } + + // We need to store the trade slot data in the session itself as data + // needs to persist beyond this translateActions method since the client + // sends multiple packets for this + for (InventoryActionData data : actions) { + if (data.getSlot() == 4 && session.getFirstTradeSlot() == null && data.getSource().getContainerId() == ContainerId.CURSOR) { + session.setFirstTradeSlot(Translators.getItemTranslator().translateToJava(session, data.getToItem())); + } + + if (data.getSlot() == 5 && session.getSecondTradeSlot() == null && data.getToItem() != null && data.getSource().getContainerId() == ContainerId.CURSOR) { + session.setSecondTradeSlot(Translators.getItemTranslator().translateToJava(session, data.getToItem())); + } + if (data.getSlot() == 50 && result == null) { + result = data; + } + } + + if (result == null || session.getFirstTradeSlot() == null) { + super.translateActions(session, inventory, actions); + return; + } + + ItemStack resultSlot = Translators.getItemTranslator().translateToJava(session, result.getToItem()); + for (int i = 0; i < villager.getVillagerTrades().length; i++) { + VillagerTrade trade = villager.getVillagerTrades()[i]; + if (!Translators.getItemTranslator().equals(session.getFirstTradeSlot(), trade.getFirstInput(), true, true, false) || !Translators.getItemTranslator().equals(resultSlot, trade.getOutput(), true, false, false)) { + continue; + } + + if (session.getSecondTradeSlot() != null && trade.getSecondInput() != null && !Translators.getItemTranslator().equals(session.getSecondTradeSlot(), trade.getSecondInput(), true, false, false)) { + continue; + } + + ClientSelectTradePacket selectTradePacket = new ClientSelectTradePacket(i); + session.sendDownstreamPacket(selectTradePacket); + + ClientWindowActionPacket tradeAction = new ClientWindowActionPacket( + inventory.getId(), + inventory.getTransactionId().getAndIncrement(), + this.bedrockSlotToJava(result), + null, + WindowAction.CLICK_ITEM, + ClickItemParam.LEFT_CLICK + ); + session.sendDownstreamPacket(tradeAction); + break; + + } + + super.translateActions(session, inventory, actions); + } +} 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 f59b82ba..28c5345a 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 @@ -160,6 +160,51 @@ public class ItemTranslator { .stream().filter(itemEntry -> itemEntry.getJavaIdentifier().equals(key)).findFirst().orElse(null)); } + /** + * Checks if an {@link ItemStack} is equal to another item stack + * + * @param itemStack the item stack to check + * @param equalsItemStack the item stack to check if equal to + * @param checkAmount if the amount should be taken into account + * @param trueIfAmountIsGreater if this should return true if the amount of the + * first item stack is greater than that of the second + * @param checkNbt if NBT data should be checked + * @return if an item stack is equal to another item stack + */ + public boolean equals(ItemStack itemStack, ItemStack equalsItemStack, boolean checkAmount, boolean trueIfAmountIsGreater, boolean checkNbt) { + if (itemStack.getId() != equalsItemStack.getId()) { + return false; + } + if (checkAmount) { + if (trueIfAmountIsGreater) { + if (itemStack.getAmount() < equalsItemStack.getAmount()) { + return false; + } + } else { + if (itemStack.getAmount() != equalsItemStack.getAmount()) { + return false; + } + } + } + + if (!checkNbt) { + return true; + } + if ((itemStack.getNbt() == null || itemStack.getNbt().isEmpty()) && (equalsItemStack.getNbt() != null && !equalsItemStack.getNbt().isEmpty())) { + return false; + } + + if ((itemStack.getNbt() != null && !itemStack.getNbt().isEmpty() && (equalsItemStack.getNbt() == null || !equalsItemStack.getNbt().isEmpty()))) { + return false; + } + + if (itemStack.getNbt() != null && equalsItemStack.getNbt() != null) { + return itemStack.getNbt().equals(equalsItemStack.getNbt()); + } + + return true; + } + private static final ItemStackTranslator DEFAULT_TRANSLATOR = new ItemStackTranslator() { @Override public List getAppliedItems() { 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 new file mode 100644 index 00000000..b156ef83 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java @@ -0,0 +1,115 @@ +/* + * 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.java.world; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.window.VillagerTrade; +import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerTradeListPacket; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.protocol.bedrock.data.ContainerType; +import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.packet.UpdateTradePacket; +import org.geysermc.connector.entity.living.merchant.VillagerEntity; +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.network.translators.Translators; +import org.geysermc.connector.network.translators.item.ItemEntry; + +import java.util.ArrayList; +import java.util.List; + +@Translator(packet = ServerTradeListPacket.class) +public class JavaTradeListTranslator extends PacketTranslator { + + @Override + public void translate(ServerTradeListPacket packet, GeyserSession session) { + VillagerEntity villager = (VillagerEntity) session.getEntityCache().getEntityByGeyserId(session.getLastInteractedVillagerEid()); + if (villager == null) { + session.getConnector().getLogger().debug("Could not find villager with entity id: " + session.getLastInteractedVillagerEid()); + return; + } + villager.setVillagerTrades(packet.getTrades()); + villager.getMetadata().put(EntityData.TRADE_XP, packet.getExperience()); + villager.getMetadata().put(EntityData.TRADE_TIER, packet.getVillagerLevel() - 1); + villager.updateBedrockMetadata(session); + + UpdateTradePacket updateTradePacket = new UpdateTradePacket(); + updateTradePacket.setTradeTier(packet.getVillagerLevel() + 1); + updateTradePacket.setWindowId((short) packet.getWindowId()); + updateTradePacket.setWindowType((short) ContainerType.TRADING.id()); + updateTradePacket.setDisplayName("Villager"); + updateTradePacket.setUnknownInt(0); + updateTradePacket.setScreen2(true); + updateTradePacket.setWilling(true); + updateTradePacket.setPlayerUniqueEntityId(session.getPlayerEntity().getGeyserId()); + updateTradePacket.setTraderUniqueEntityId(session.getLastInteractedVillagerEid()); + CompoundTagBuilder builder = CompoundTagBuilder.builder(); + List tags = new ArrayList<>(); + for (VillagerTrade trade : packet.getTrades()) { + CompoundTagBuilder recipe = CompoundTagBuilder.builder(); + recipe.intTag("maxUses", trade.getMaxUses()); + recipe.intTag("traderExp", packet.getExperience()); + recipe.floatTag("priceMultiplierA", trade.getPriceMultiplier()); + recipe.tag(getItemTag(session, trade.getOutput(), "sell")); + recipe.floatTag("priceMultiplierB", 0.0f); + recipe.intTag("buyCountB", 0); + recipe.intTag("buyCountA", trade.getOutput().getAmount()); + recipe.intTag("demand", trade.getDemand()); + recipe.intTag("tier", packet.getVillagerLevel() - 1); + recipe.tag(getItemTag(session, trade.getFirstInput(), "buyA")); + if (trade.getSecondInput() != null) { + recipe.tag(getItemTag(session, trade.getSecondInput(), "buyB")); + } + recipe.intTag("uses", trade.getNumUses()); + recipe.byteTag("rewardExp", (byte) trade.getXp()); + tags.add(recipe.buildRootTag()); + } + builder.listTag("Recipes", CompoundTag.class, tags); + List expTags = new ArrayList<>(); + expTags.add(CompoundTagBuilder.builder().intTag("0", 0).buildRootTag()); + expTags.add(CompoundTagBuilder.builder().intTag("1", 10).buildRootTag()); + expTags.add(CompoundTagBuilder.builder().intTag("2", 60).buildRootTag()); + expTags.add(CompoundTagBuilder.builder().intTag("3", 160).buildRootTag()); + expTags.add(CompoundTagBuilder.builder().intTag("4", 310).buildRootTag()); + builder.listTag("TierExpRequirements", CompoundTag.class, expTags); + updateTradePacket.setOffers(builder.buildRootTag()); + session.sendUpstreamPacket(updateTradePacket); + } + + private CompoundTag getItemTag(GeyserSession session, ItemStack stack, String name) { + ItemData itemData = Translators.getItemTranslator().translateToBedrock(session, stack); + ItemEntry itemEntry = Translators.getItemTranslator().getItem(stack); + CompoundTagBuilder builder = CompoundTagBuilder.builder(); + builder.byteTag("Count", (byte) itemData.getCount()); + builder.shortTag("Damage", itemData.getDamage()); + builder.stringTag("Name", itemEntry.getJavaIdentifier()); + return builder.build(name); + } +} From 3220532083982f2357c9c8c35cd2e6046c712208 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 17 May 2020 05:57:18 +0100 Subject: [PATCH 037/581] Fixed fishing rod lines not connecting to other players (#580) --- .../geysermc/connector/entity/FishingHookEntity.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java index 8d8d5ef2..808e1667 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java @@ -37,10 +37,14 @@ public class FishingHookEntity extends Entity { public FishingHookEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, ProjectileData data) { super(entityId, geyserId, entityType, position, motion, rotation); - // TODO: Find a better way to do this for (GeyserSession session : GeyserConnector.getInstance().getPlayers().values()) { - if (session.getPlayerEntity().getEntityId() == data.getOwnerId()) { - this.metadata.put(EntityData.OWNER_EID, session.getPlayerEntity().getGeyserId()); + Entity entity = session.getEntityCache().getEntityByJavaId(data.getOwnerId()); + if (entity == null && session.getPlayerEntity().getEntityId() == data.getOwnerId()) { + entity = session.getPlayerEntity(); + } + + if (entity != null) { + this.metadata.put(EntityData.OWNER_EID, entity.getGeyserId()); return; } } From 563cde2adece3cc99702160bb5249ee45aa18268 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Sun, 17 May 2020 00:57:34 -0400 Subject: [PATCH 038/581] Switch to client's translation for jukebox song name. (#573) Just for consistency with the other part of the code. --- .../translators/java/world/JavaPlayEffectTranslator.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 3afb79bd..79a2c920 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 @@ -140,8 +140,7 @@ public class JavaPlayEffectTranslator extends PacketTranslator params = new ArrayList<>(); - // Couldn't figure out how to set this to Bedrock translation so it just uses the Java translation - String recordString = "item.minecraft." + EffectUtils.RECORDS.get(recordEffectData.getRecordId()).name().toLowerCase().replace("record_", "music_disc_") + ".desc"; + String recordString = "%item." + EffectUtils.RECORDS.get(recordEffectData.getRecordId()).name().toLowerCase() + ".desc"; params.add(LocaleUtils.getLocaleString(recordString, session.getClientData().getLanguageCode())); textPacket.setParameters(params); session.sendUpstreamPacket(textPacket); From 95b7055c10dfdce25c226b7ad5209407e75f3414 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 17 May 2020 05:58:00 +0100 Subject: [PATCH 039/581] Added map icons (#572) * Added map icons * Cleaned up and moved to enum --- .../translators/nbt/MapItemTranslator.java | 2 + .../java/world/JavaMapDataTranslator.java | 14 +++ .../connector/utils/BedrockMapIcon.java | 118 ++++++++++++++++++ .../geysermc/connector/utils/MapColor.java | 26 ++++ 4 files changed, 160 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/utils/BedrockMapIcon.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/MapItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/MapItemTranslator.java index cdf272ec..7e6bc729 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/MapItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/MapItemTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt; +import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -42,6 +43,7 @@ public class MapItemTranslator extends NbtItemStackTranslator { if (mapId != null) { itemTag.put(new StringTag("map_uuid", mapId.getValue().toString())); itemTag.put(new IntTag("map_name_index", mapId.getValue())); + itemTag.put(new ByteTag("map_display_players", (byte) 1)); itemTag.remove("map"); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java index 78681f8f..c8be3a56 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java @@ -26,11 +26,15 @@ package org.geysermc.connector.network.translators.java.world; import com.github.steveice10.mc.protocol.data.game.world.map.MapData; +import com.github.steveice10.mc.protocol.data.game.world.map.MapIcon; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerMapDataPacket; +import com.nukkitx.protocol.bedrock.data.MapDecoration; +import com.nukkitx.protocol.bedrock.data.MapTrackedObject; import com.nukkitx.protocol.bedrock.packet.ClientboundMapItemDataPacket; 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.BedrockMapIcon; import org.geysermc.connector.utils.MapColor; @Translator(packet = ServerMapDataPacket.class) @@ -62,6 +66,16 @@ public class JavaMapDataTranslator extends PacketTranslator mapItemDataPacket.setColors(colors); } + // Bedrock needs an entity id to display an icon + int id = 0; + for (MapIcon icon : packet.getIcons()) { + BedrockMapIcon bedrockMapIcon = BedrockMapIcon.fromType(icon.getIconType()); + + mapItemDataPacket.getTrackedObjects().add(new MapTrackedObject(id)); + mapItemDataPacket.getDecorations().add(new MapDecoration(bedrockMapIcon.getIconID(), icon.getIconRotation(), icon.getCenterX(), icon.getCenterZ(), "", bedrockMapIcon.toARGB())); + id++; + } + session.getUpstream().getSession().sendPacket(mapItemDataPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/BedrockMapIcon.java b/connector/src/main/java/org/geysermc/connector/utils/BedrockMapIcon.java new file mode 100644 index 00000000..f3ee956b --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/BedrockMapIcon.java @@ -0,0 +1,118 @@ +/* + * 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 com.github.steveice10.mc.protocol.data.game.world.map.MapIconType; +import lombok.Getter; + +public enum BedrockMapIcon { + ICON_WHITE_ARROW(MapIconType.WHITE_ARROW, 0), + ICON_ITEM_FRAME(MapIconType.GREEN_ARROW, 7), + ICON_RED_ARROW(MapIconType.RED_ARROW, 2), + ICON_BLUE_ARROW(MapIconType.BLUE_ARROW, 3), + ICON_TREASURE_MARKER(MapIconType.TREASURE_MARKER, 4), + ICON_RED_POINTER(MapIconType.RED_POINTER, 5), + ICON_WHITE_CIRCLE(MapIconType.WHITE_CIRCLE, 6), + ICON_SMALL_WHITE_CIRCLE(MapIconType.SMALL_WHITE_CIRCLE, 13), + ICON_MANSION(MapIconType.MANSION, 14), + ICON_TEMPLE(MapIconType.TEMPLE, 15), + ICON_WHITE_BANNER(MapIconType.WHITE_BANNER, 13, 255, 255, 255), + ICON_ORANGE_BANNER(MapIconType.ORANGE_BANNER, 13, 249, 128, 29), + ICON_MAGENTA_BANNER(MapIconType.MAGENTA_BANNER, 13, 199, 78, 189), + ICON_LIGHT_BLUE_BANNER(MapIconType.LIGHT_BLUE_BANNER, 13, 58, 179, 218), + ICON_YELLOW_BANNER(MapIconType.YELLOW_BANNER, 13, 254, 216, 61), + ICON_LIME_BANNER(MapIconType.LIME_BANNER, 13, 128, 199, 31), + ICON_PINK_BANNER(MapIconType.PINK_BANNER, 13, 243, 139, 170), + ICON_GRAY_BANNER(MapIconType.GRAY_BANNER, 13, 71, 79, 82), + ICON_LIGHT_GRAY_BANNER(MapIconType.LIGHT_GRAY_BANNER, 13, 157, 157, 151), + ICON_CYAN_BANNER(MapIconType.CYAN_BANNER, 13, 22, 156, 156), + ICON_PURPLE_BANNER(MapIconType.PURPLE_BANNER, 13, 137, 50, 184), + ICON_BLUE_BANNER(MapIconType.BLUE_BANNER, 13, 60, 68, 170), + ICON_BROWN_BANNER(MapIconType.BROWN_BANNER, 13, 131, 84, 50), + ICON_GREEN_BANNER(MapIconType.GREEN_BANNER, 13, 94, 124, 22), + ICON_RED_BANNER(MapIconType.RED_BANNER, 13, 176, 46, 38), + ICON_BLACK_BANNER(MapIconType.BLACK_BANNER, 13, 29, 29, 33); + + private static final BedrockMapIcon[] VALUES = values(); + + private MapIconType iconType; + + @Getter + private int iconID; + + private int red; + private int green; + private int blue; + + BedrockMapIcon(MapIconType iconType, int iconID) { + this.iconType = iconType; + this.iconID = iconID; + + this.red = 255; + this.green = 255; + this.blue = 255; + } + + BedrockMapIcon(MapIconType iconType, int iconID, int red, int green, int blue) { + this.iconType = iconType; + this.iconID = iconID; + + this.red = red; + this.green = green; + this.blue = blue; + } + + /** + * Get the BedrockMapIcon for the Java MapIconType + * + * @param iconType A MapIconType + * @return The mapping for a BedrockMapIcon + */ + public static BedrockMapIcon fromType(MapIconType iconType) { + for (BedrockMapIcon icon : VALUES) { + if (icon.iconType.equals(iconType)) { + return icon; + } + } + + return null; + } + + /** + * Get the ARGB value of a BedrockMapIcon + * + * @return ARGB as an int + */ + public int toARGB() { + int alpha = 255; + + return ((alpha & 0xFF) << 24) | + ((red & 0xFF) << 16) | + ((green & 0xFF) << 8) | + ((blue & 0xFF) << 0); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/MapColor.java b/connector/src/main/java/org/geysermc/connector/utils/MapColor.java index b011edc7..4328d758 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MapColor.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MapColor.java @@ -1,3 +1,29 @@ +/* + * 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; public enum MapColor { From 57717795a378120a9cd26495badad1e05c3b4cab Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Sun, 17 May 2020 00:59:03 -0400 Subject: [PATCH 040/581] Add enchantment table book on chunk load (#568) Java's block entity ID is enchantment_table whereas Bedrock's is EnchantTable; this commit adds an exception to the block entity regex as such. --- .../java/org/geysermc/connector/utils/BlockEntityUtils.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java index 9423a4f8..da32b12b 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -22,6 +22,10 @@ public class BlockEntityUtils { if (id.contains("EnderChest")) return "EnderChest"; + if (id.contains("enchanting_table")) { + return "EnchantTable"; + } + id = id.toLowerCase() .replace("minecraft:", "") .replace("_", " "); From b0d0c168d2b9837f484863fb8aa24498c5741af7 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 17 May 2020 01:06:07 -0500 Subject: [PATCH 041/581] Fix bossbar causing players to be unable to break blocks or interact in small areas (Closes #537) --- .../geysermc/connector/network/session/cache/BossBar.java | 7 +++++-- .../network/translators/java/JavaBossBarTranslator.java | 2 -- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java index 1fde179d..267f3cb1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java @@ -104,10 +104,13 @@ public class BossBar { addEntityPacket.setRuntimeEntityId(entityId); addEntityPacket.setIdentifier("minecraft:creeper"); addEntityPacket.setEntityType(33); - addEntityPacket.setPosition(session.getPlayerEntity().getPosition()); + addEntityPacket.setPosition(session.getPlayerEntity().getPosition().sub(0D, -10D, 0D)); addEntityPacket.setRotation(Vector3f.ZERO); addEntityPacket.setMotion(Vector3f.ZERO); - addEntityPacket.getMetadata().put(EntityData.SCALE, 0.01F); // scale = 0 doesn't work? + addEntityPacket.getMetadata() + .putFloat(EntityData.SCALE, 0F) + .putFloat(EntityData.BOUNDING_BOX_WIDTH, 0F) + .putFloat(EntityData.BOUNDING_BOX_HEIGHT, 0F); session.sendUpstreamPacket(addEntityPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaBossBarTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaBossBarTranslator.java index 2c32ef6f..3da76a22 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaBossBarTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaBossBarTranslator.java @@ -32,8 +32,6 @@ import org.geysermc.connector.network.translators.Translator; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerBossBarPacket; -import java.awt.*; - @Translator(packet = ServerBossBarPacket.class) public class JavaBossBarTranslator extends PacketTranslator { @Override From 43ee7d602765c2ef0f75f3ad467efd23b1162531 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 17 May 2020 07:26:13 +0100 Subject: [PATCH 042/581] Fixed creepers, giants and eye of ender (#578) --- .../entity/living/monster/CreeperEntity.java | 4 +- .../entity/living/monster/GiantEntity.java | 39 +++++++++++++++++++ .../connector/entity/type/EntityType.java | 3 +- 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/monster/GiantEntity.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/CreeperEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/CreeperEntity.java index e99e1a63..9b5c3822 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/CreeperEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/CreeperEntity.java @@ -39,8 +39,8 @@ public class CreeperEntity extends MonsterEntity { @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getId() == 15 && (int) entityMetadata.getValue() > 0) { - metadata.getFlags().setFlag(EntityFlag.IGNITED, true); + if (entityMetadata.getId() == 15) { + metadata.getFlags().setFlag(EntityFlag.IGNITED, (int) entityMetadata.getValue() == 1); } if (entityMetadata.getId() == 16) { metadata.getFlags().setFlag(EntityFlag.POWERED, (boolean) entityMetadata.getValue()); diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GiantEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GiantEntity.java new file mode 100644 index 00000000..b9dc9e66 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GiantEntity.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.EntityData; +import org.geysermc.connector.entity.type.EntityType; + +public class GiantEntity extends MonsterEntity { + + public GiantEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + + metadata.put(EntityData.SCALE, 6f); + } +} 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 ed231d8c..d08c5e33 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 @@ -64,6 +64,7 @@ public enum EntityType { PARROT(ParrotEntity.class, 30, 0.9f, 0.5f), DOLPHIN(WaterEntity.class, 31, 0.6f, 0.9f), ZOMBIE(ZombieEntity.class, 32, 1.8f, 0.6f, 0.6f, 1.62f), + GIANT(GiantEntity.class, 32, 1.8f, 0.6f, 0.6f, 1.62f, "minecraft:zombie"), 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), @@ -103,7 +104,7 @@ public enum EntityType { MOVING_BLOCK(Entity.class, 67, 0f), EXPERIENCE_BOTTLE(ThrowableEntity.class, 68, 0.25f, 0.25f, 0f, 0f, "minecraft:xp_bottle"), EXPERIENCE_ORB(ExpOrbEntity.class, 69, 0f, 0f, 0f, 0f, "minecraft:xp_orb"), - EYE_OF_ENDER(Entity.class, 70, 0.25f), + EYE_OF_ENDER(Entity.class, 70, 0.25f, 0.25f, 0f, 0f, "minecraft:eye_of_ender_signal"), END_CRYSTAL(EnderCrystalEntity.class, 71, 0f, 0f, 0f, 0f, "minecraft:ender_crystal"), FIREWORK_ROCKET(Entity.class, 72, 0.25f), TRIDENT(ArrowEntity.class, 73, 0f), From 405ffb2666203bb2c6f17eed3f151881bd27cbf1 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 18 May 2020 05:35:01 +0100 Subject: [PATCH 043/581] Added mob spawner block entity data (#587) --- .../connector/entity/type/EntityType.java | 12 ++ .../entity/SpawnerBlockEntityTranslator.java | 105 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SpawnerBlockEntityTranslator.java 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 d08c5e33..ad3ac105 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 @@ -160,6 +160,8 @@ public enum EntityType { */ ILLUSIONER(AbstractIllagerEntity.class, 114, 1.8f, 0.6f, 0.6f, 1.62f, "minecraft:pillager"); + private static final EntityType[] VALUES = values(); + private Class entityClass; private final int type; private final float height; @@ -195,4 +197,14 @@ public enum EntityType { this.offset = offset + 0.00001f; this.identifier = identifier; } + + public static EntityType getFromIdentifier(String identifier) { + for (EntityType type : VALUES) { + if (type.identifier.equals(identifier)) { + return type; + } + } + + return null; + } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SpawnerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SpawnerBlockEntityTranslator.java new file mode 100644 index 00000000..100dbddd --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SpawnerBlockEntityTranslator.java @@ -0,0 +1,105 @@ +/* + * 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.world.block.entity; + +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.*; +import org.geysermc.connector.entity.type.EntityType; + +import java.util.ArrayList; +import java.util.List; + +@BlockEntity(name = "MobSpawner", regex = "mob_spawner") +public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { + + @Override + public List> translateTag(CompoundTag tag, BlockState blockState) { + List> tags = new ArrayList<>(); + + if (tag.get("MaxNearbyEntities") != null) { + tags.add(new ShortTag("MaxNearbyEntities", (short) tag.get("MaxNearbyEntities").getValue())); + } + + if (tag.get("RequiredPlayerRange") != null) { + tags.add(new ShortTag("RequiredPlayerRange", (short) tag.get("RequiredPlayerRange").getValue())); + } + + if (tag.get("SpawnCount") != null) { + tags.add(new ShortTag("SpawnCount", (short) tag.get("SpawnCount").getValue())); + } + + if (tag.get("MaxSpawnDelay") != null) { + tags.add(new ShortTag("MaxSpawnDelay", (short) tag.get("MaxSpawnDelay").getValue())); + } + + if (tag.get("Delay") != null) { + tags.add(new ShortTag("Delay", (short) tag.get("Delay").getValue())); + } + + if (tag.get("SpawnRange") != null) { + tags.add(new ShortTag("SpawnRange", (short) tag.get("SpawnRange").getValue())); + } + + if (tag.get("MinSpawnDelay") != null) { + tags.add(new ShortTag("MinSpawnDelay", (short) tag.get("MinSpawnDelay").getValue())); + } + + if (tag.get("SpawnData") != null) { + CompoundTag spawnData = tag.get("SpawnData"); + String entityID = (String) spawnData.get("id").getValue(); + tags.add(new StringTag("EntityIdentifier", entityID)); + + EntityType type = EntityType.getFromIdentifier(entityID); + if (type != null) { + tags.add(new FloatTag("DisplayEntityWidth", type.getWidth())); + tags.add(new FloatTag("DisplayEntityHeight", type.getHeight())); + tags.add(new FloatTag("DisplayEntityScale", 1.0f)); + } + } + + tags.add(new StringTag("id", "MobSpawner")); + tags.add(new ByteTag("isMovable", (byte) 1)); + + return tags; + } + + @Override + public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + return null; + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); + tagBuilder.byteTag("isMovable", (byte) 1) + .stringTag("id", "MobSpawner"); + + return tagBuilder.buildRootTag(); + } +} From 31d3d2e289c9a9bca6826b333acc86788ea4de0b Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Mon, 18 May 2020 00:35:26 -0400 Subject: [PATCH 044/581] Add some elder guardian properties (#586) - Adds the ELDER flag to all elder guardians, so they look like elder guardians and not giant regular guardians. - Translates AFFECTED_BY_ELDER_GUARDIAN in JavaNotifyClientTranslator to add the elder guardian curse event. --- .../living/monster/ElderGuardianEntity.java | 41 +++++++++++++++++++ .../connector/entity/type/EntityType.java | 2 +- .../world/JavaNotifyClientTranslator.java | 11 +++-- 3 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/monster/ElderGuardianEntity.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ElderGuardianEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ElderGuardianEntity.java new file mode 100644 index 00000000..fedd7980 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ElderGuardianEntity.java @@ -0,0 +1,41 @@ +/* + * 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.EntityFlag; +import org.geysermc.connector.entity.type.EntityType; + +public class ElderGuardianEntity extends GuardianEntity { + + public ElderGuardianEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + // Otherwise it just looks like a normal guardian but bigger + metadata.getFlags().setFlag(EntityFlag.ELDER, 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 ad3ac105..f2b66280 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 @@ -82,7 +82,7 @@ public enum EntityType { HUSK(ZombieEntity.class, 47, 1.8f, 0.6f, 0.6f, 1.62f), WITHER_SKELETON(AbstractSkeletonEntity.class, 48, 2.4f, 0.7f), GUARDIAN(GuardianEntity.class, 49, 0.85f), - ELDER_GUARDIAN(GuardianEntity.class, 50, 1.9975f), + ELDER_GUARDIAN(ElderGuardianEntity.class, 50, 1.9975f), NPC(PlayerEntity.class, 51, 1.8f, 0.6f, 0.6f, 1.62f), WITHER(WitherEntity.class, 52, 3.5f, 0.9f), ENDER_DRAGON(EnderDragonEntity.class, 53, 4f, 13f), diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java index 0db343b2..de1066c0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java @@ -31,10 +31,7 @@ import com.github.steveice10.mc.protocol.data.game.world.notify.EnterCreditsValu import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityDataMap; -import com.nukkitx.protocol.bedrock.data.EntityFlag; -import com.nukkitx.protocol.bedrock.data.LevelEventType; -import com.nukkitx.protocol.bedrock.data.PlayerPermission; +import com.nukkitx.protocol.bedrock.data.*; import com.nukkitx.protocol.bedrock.packet.*; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.geysermc.connector.entity.Entity; @@ -124,6 +121,12 @@ public class JavaNotifyClientTranslator extends PacketTranslator Date: Mon, 18 May 2020 10:46:35 -0400 Subject: [PATCH 045/581] Add firework boost for elytras (#552) * Add firework boost for elytras! * Change how to detect player glide * Add comments explaining code * Remove unused ID --- .../connector/entity/FireworkEntity.java | 64 +++++++++++++++++++ .../connector/entity/type/EntityType.java | 2 +- 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java new file mode 100644 index 00000000..25128d48 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java @@ -0,0 +1,64 @@ +/* + * 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; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +import java.util.OptionalInt; + +public class FireworkEntity extends Entity { + + public FireworkEntity(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 && !entityMetadata.getValue().equals(OptionalInt.empty()) && ((OptionalInt) entityMetadata.getValue()).getAsInt() == session.getPlayerEntity().getEntityId()) { + //Checks if the firework has an entity ID (used when a player is gliding) and checks to make sure the player that is gliding is the one getting sent the packet or else every player near the gliding player will boost too. + PlayerEntity entity = session.getPlayerEntity(); + float yaw = entity.getRotation().getX(); + float pitch = entity.getRotation().getY(); + //Uses math from NukkitX + entity.setMotion(Vector3f.from( + -Math.sin(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)) * 2, + -Math.sin(Math.toRadians(pitch)) * 2, + Math.cos(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)) * 2)); + //Need to update the EntityMotionPacket or else the player won't boost + SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket(); + entityMotionPacket.setRuntimeEntityId(entity.getGeyserId()); + entityMotionPacket.setMotion(entity.getMotion()); + + session.sendUpstreamPacket(entityMotionPacket); + } + super.updateBedrockMetadata(entityMetadata, session); + } +} \ No newline at end of file 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 f2b66280..6cfda74a 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 @@ -106,7 +106,7 @@ public enum EntityType { EXPERIENCE_ORB(ExpOrbEntity.class, 69, 0f, 0f, 0f, 0f, "minecraft:xp_orb"), EYE_OF_ENDER(Entity.class, 70, 0.25f, 0.25f, 0f, 0f, "minecraft:eye_of_ender_signal"), END_CRYSTAL(EnderCrystalEntity.class, 71, 0f, 0f, 0f, 0f, "minecraft:ender_crystal"), - FIREWORK_ROCKET(Entity.class, 72, 0.25f), + FIREWORK_ROCKET(FireworkEntity.class, 72, 0.25f), TRIDENT(ArrowEntity.class, 73, 0f), TURTLE(AnimalEntity.class, 74, 0.4f, 1.2f), CAT(CatEntity.class, 75, 0.35f, 0.3f), From fd36930502d45302b64a1658ef1b435ddb77dae1 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Mon, 18 May 2020 23:26:27 -0400 Subject: [PATCH 046/581] Add entity event for drowning. (#588) This commit translates Java's LIVING_DROWN entity status to Bedrock's HURT_ANIMATION. --- .../translators/java/entity/JavaEntityStatusTranslator.java | 2 ++ 1 file changed, 2 insertions(+) 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 06d06695..3032785a 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 @@ -49,6 +49,8 @@ public class JavaEntityStatusTranslator extends PacketTranslator Date: Tue, 19 May 2020 04:27:35 +0100 Subject: [PATCH 047/581] Added a docker container IP warning (#584) * Added a docker container IP warning * Corrected messages * Moved to normal java file read instead of starting cat * Fixed capitalisation on method name --- .../geysermc/connector/GeyserConnector.java | 5 ++ .../geysermc/connector/utils/DockerCheck.java | 58 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 72995293..58307682 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -40,6 +40,7 @@ import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.thread.PingPassthroughThread; +import org.geysermc.connector.utils.DockerCheck; import org.geysermc.connector.utils.Toolbox; import java.net.InetSocketAddress; @@ -102,6 +103,10 @@ public class GeyserConnector { Toolbox.init(); Translators.start(); + if (platformType != PlatformType.STANDALONE) { + DockerCheck.check(bootstrap); + } + remoteServer = new RemoteServer(config.getRemote().getAddress(), config.getRemote().getPort()); authType = AuthType.getByName(config.getRemote().getAuthType()); diff --git a/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java b/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java new file mode 100644 index 00000000..0a5a2278 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java @@ -0,0 +1,58 @@ +/* + * 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 org.geysermc.connector.bootstrap.GeyserBootstrap; + +import java.net.InetAddress; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class DockerCheck { + public static void check(GeyserBootstrap bootstrap) { + try { + String OS = System.getProperty("os.name").toLowerCase(); + String ipAddress = InetAddress.getLocalHost().getHostAddress(); + + // Check if the user is already using the recommended IP + if (ipAddress.equals(bootstrap.getGeyserConfig().getRemote().getAddress())) { + return; + } + + if (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0) { + bootstrap.getGeyserLogger().debug("We are on a Unix system, checking for Docker..."); + + String output = new String(Files.readAllBytes(Paths.get("/proc/1/cgroup"))); + + if (output.contains("docker")) { + bootstrap.getGeyserLogger().warning("You are most likely in a Docker container, this may cause connection issues from Geyser to the Java server"); + bootstrap.getGeyserLogger().warning("We recommended using the following IP as the remote address: " + ipAddress); + } + } + } catch (Exception e) { } // Ignore any errors, inc ip failed to fetch, process could not run or access denied + } +} From e2d46c3d490f62d0c5b6a8518e0f962dc7505c77 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 18 May 2020 21:15:29 -0800 Subject: [PATCH 048/581] Work on villager trading --- .../network/session/GeyserSession.java | 6 -- .../bedrock/BedrockEntityEventTranslator.java | 22 ++++++ .../MerchantInventoryTranslator.java | 75 +++---------------- .../java/world/JavaTradeListTranslator.java | 54 +++++++++---- 4 files changed, 72 insertions(+), 85 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 ea34bef6..1bf506e7 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 @@ -156,12 +156,6 @@ public class GeyserSession implements CommandSender { @Setter private Vector3i lastInteractionPosition; - @Setter - private ItemStack firstTradeSlot; - - @Setter - private ItemStack secondTradeSlot; - @Setter private boolean switchingDimension = false; private boolean manyDimPackets = false; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockEntityEventTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockEntityEventTranslator.java index f97dc3c6..c7d1ae67 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockEntityEventTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockEntityEventTranslator.java @@ -26,7 +26,12 @@ package org.geysermc.connector.network.translators.bedrock; +import com.github.steveice10.mc.protocol.data.game.window.VillagerTrade; +import com.github.steveice10.mc.protocol.data.game.window.WindowType; +import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientSelectTradePacket; import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; +import org.geysermc.connector.entity.living.merchant.VillagerEntity; +import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -41,6 +46,23 @@ public class BedrockEntityEventTranslator extends PacketTranslator 0 && packet.getData() < villager.getVillagerTrades().length) { + VillagerTrade trade = villager.getVillagerTrades()[packet.getData()]; + openInventory.setItem(2, trade.getOutput()); + } + } + return; } session.getConnector().getLogger().debug("Did not translate incoming EntityEventPacket: " + packet.toString()); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/MerchantInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/MerchantInventoryTranslator.java index 5d1ce122..7e3f24bd 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/MerchantInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/MerchantInventoryTranslator.java @@ -26,18 +26,11 @@ package org.geysermc.connector.network.translators.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; -import com.github.steveice10.mc.protocol.data.game.window.ClickItemParam; -import com.github.steveice10.mc.protocol.data.game.window.VillagerTrade; -import com.github.steveice10.mc.protocol.data.game.window.WindowAction; -import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientSelectTradePacket; -import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientWindowActionPacket; import com.nukkitx.protocol.bedrock.data.ContainerId; import com.nukkitx.protocol.bedrock.data.InventoryActionData; -import org.geysermc.connector.entity.living.merchant.VillagerEntity; +import com.nukkitx.protocol.bedrock.data.InventorySource; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.inventory.updater.CursorInventoryUpdater; import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater; @@ -80,6 +73,14 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator { return super.bedrockSlotToJava(action); } + @Override + public SlotType getSlotType(int javaSlot) { + if (javaSlot == 2) { + return SlotType.OUTPUT; + } + return SlotType.NORMAL; + } + @Override public void prepareInventory(GeyserSession session, Inventory inventory) { @@ -93,8 +94,6 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator { @Override public void closeInventory(GeyserSession session, Inventory inventory) { session.setLastInteractedVillagerEid(-1); - session.setFirstTradeSlot(null); - session.setSecondTradeSlot(null); } @Override @@ -109,60 +108,10 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator { @Override public void translateActions(GeyserSession session, Inventory inventory, List actions) { - InventoryActionData result = null; - - VillagerEntity villager = (VillagerEntity) session.getEntityCache().getEntityByGeyserId(session.getLastInteractedVillagerEid()); - if (villager == null) { - session.getConnector().getLogger().debug("Could not find villager with entity id: " + session.getLastInteractedVillagerEid()); - return; - } - - // We need to store the trade slot data in the session itself as data - // needs to persist beyond this translateActions method since the client - // sends multiple packets for this - for (InventoryActionData data : actions) { - if (data.getSlot() == 4 && session.getFirstTradeSlot() == null && data.getSource().getContainerId() == ContainerId.CURSOR) { - session.setFirstTradeSlot(Translators.getItemTranslator().translateToJava(session, data.getToItem())); + for (InventoryActionData action : actions) { + if (action.getSource().getType() == InventorySource.Type.NON_IMPLEMENTED_TODO) { + return; } - - if (data.getSlot() == 5 && session.getSecondTradeSlot() == null && data.getToItem() != null && data.getSource().getContainerId() == ContainerId.CURSOR) { - session.setSecondTradeSlot(Translators.getItemTranslator().translateToJava(session, data.getToItem())); - } - if (data.getSlot() == 50 && result == null) { - result = data; - } - } - - if (result == null || session.getFirstTradeSlot() == null) { - super.translateActions(session, inventory, actions); - return; - } - - ItemStack resultSlot = Translators.getItemTranslator().translateToJava(session, result.getToItem()); - for (int i = 0; i < villager.getVillagerTrades().length; i++) { - VillagerTrade trade = villager.getVillagerTrades()[i]; - if (!Translators.getItemTranslator().equals(session.getFirstTradeSlot(), trade.getFirstInput(), true, true, false) || !Translators.getItemTranslator().equals(resultSlot, trade.getOutput(), true, false, false)) { - continue; - } - - if (session.getSecondTradeSlot() != null && trade.getSecondInput() != null && !Translators.getItemTranslator().equals(session.getSecondTradeSlot(), trade.getSecondInput(), true, false, false)) { - continue; - } - - ClientSelectTradePacket selectTradePacket = new ClientSelectTradePacket(i); - session.sendDownstreamPacket(selectTradePacket); - - ClientWindowActionPacket tradeAction = new ClientWindowActionPacket( - inventory.getId(), - inventory.getTransactionId().getAndIncrement(), - this.bedrockSlotToJava(result), - null, - WindowAction.CLICK_ITEM, - ClickItemParam.LEFT_CLICK - ); - session.sendDownstreamPacket(tradeAction); - break; - } super.translateActions(session, inventory, actions); 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 b156ef83..7ba20d1a 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 @@ -56,12 +56,13 @@ public class JavaTradeListTranslator extends PacketTranslator