From 7cd941e5d6094d9d00f54ecf88b3f1a3001baa2a Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Apr 2020 15:48:21 +0200 Subject: [PATCH 1/3] Fix BossBars --- .../network/session/cache/BossBar.java | 104 ++++++++++++++++++ .../network/session/cache/EntityCache.java | 26 +++-- .../bedrock/BedrockActionTranslator.java | 1 + .../java/JavaBossBarTranslator.java | 61 ++-------- 4 files changed, 130 insertions(+), 62 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java 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 new file mode 100644 index 000000000..8ff2c9459 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java @@ -0,0 +1,104 @@ +package org.geysermc.connector.network.session.cache; + +import com.github.steveice10.mc.protocol.data.message.Message; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; +import com.nukkitx.protocol.bedrock.packet.BossEventPacket; +import com.nukkitx.protocol.bedrock.packet.RemoveEntityPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.MessageUtils; + +public class BossBar { + + private GeyserSession session; + + private long entityId; + private Message title; + private float health; + private int color; + private int overlay; + private int darkenSky; + + public BossBar(GeyserSession session, Message title, float health, int color, int overlay, int darkenSky) { + this.session = session; + this.entityId = session.getEntityCache().getNextEntityId().incrementAndGet(); + this.title = title; + this.health = health; + this.color = color; + this.overlay = overlay; + this.darkenSky = darkenSky; + } + + public void addBossBar() { + addBossEntity(); + updateBossBar(); + } + + public void updateBossBar() { + BossEventPacket bossEventPacket = new BossEventPacket(); + bossEventPacket.setBossUniqueEntityId(entityId); + bossEventPacket.setAction(BossEventPacket.Action.SHOW); + bossEventPacket.setTitle(MessageUtils.getTranslatedBedrockMessage(title, session.getClientData().getLanguageCode())); + bossEventPacket.setHealthPercentage(health); + bossEventPacket.setColor(color); //ignored by client + bossEventPacket.setOverlay(overlay); + bossEventPacket.setDarkenSky(darkenSky); + + session.getUpstream().sendPacket(bossEventPacket); + } + + public void updateTitle(Message title) { + this.title = title; + BossEventPacket bossEventPacket = new BossEventPacket(); + bossEventPacket.setBossUniqueEntityId(entityId); + bossEventPacket.setAction(BossEventPacket.Action.TITLE); + bossEventPacket.setTitle(MessageUtils.getTranslatedBedrockMessage(title, session.getClientData().getLanguageCode())); + + session.getUpstream().sendPacket(bossEventPacket); + } + + public void updateHealth(float health) { + this.health = health; + BossEventPacket bossEventPacket = new BossEventPacket(); + bossEventPacket.setBossUniqueEntityId(entityId); + bossEventPacket.setAction(BossEventPacket.Action.HEALTH_PERCENTAGE); + bossEventPacket.setHealthPercentage(health); + + session.getUpstream().sendPacket(bossEventPacket); + } + + public void removeBossBar() { + BossEventPacket bossEventPacket = new BossEventPacket(); + bossEventPacket.setBossUniqueEntityId(entityId); + bossEventPacket.setAction(BossEventPacket.Action.HIDE); + + session.getUpstream().sendPacket(bossEventPacket); + removeBossEntity(); + } + + /** + * Bedrock still needs an entity to display the BossBar.
+ * Just like 1.8 but it doesn't care about which entity + */ + private void addBossEntity() { + AddEntityPacket addEntityPacket = new AddEntityPacket(); + addEntityPacket.setUniqueEntityId(entityId); + addEntityPacket.setRuntimeEntityId(entityId); + addEntityPacket.setIdentifier("minecraft:creeper"); + addEntityPacket.setEntityType(33); + addEntityPacket.setPosition(session.getPlayerEntity().getPosition()); + addEntityPacket.setRotation(Vector3f.ZERO); + addEntityPacket.setMotion(Vector3f.ZERO); + addEntityPacket.getMetadata().put(EntityData.SCALE, 0.01F); // scale = 0 doesn't work? + + session.getUpstream().sendPacket(addEntityPacket); + } + + private void removeBossEntity() { + RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket(); + removeEntityPacket.setUniqueEntityId(entityId); + + session.getUpstream().sendPacket(removeEntityPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java index f32ee2a5c..f0b394fd5 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java @@ -48,7 +48,7 @@ public class EntityCache { private Long2ObjectMap entities = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>()); private Long2LongMap entityIdTranslations = Long2LongMaps.synchronize(new Long2LongOpenHashMap()); private Map playerEntities = Collections.synchronizedMap(new HashMap<>()); - private Object2LongMap bossbars = new Object2LongOpenHashMap<>(); + private Map bossBars = Collections.synchronizedMap(new HashMap<>()); @Getter private AtomicLong nextEntityId = new AtomicLong(2L); @@ -116,24 +116,30 @@ public class EntityCache { playerEntities.remove(uuid); } - public long addBossBar(UUID uuid) { - long entityId = getNextEntityId().incrementAndGet(); - bossbars.put(uuid, entityId); - return entityId; + public void addBossBar(UUID uuid, BossBar bossBar) { + bossBars.put(uuid, bossBar); + bossBar.addBossBar(); } - public long getBossBar(UUID uuid) { - return bossbars.containsKey(uuid) ? bossbars.get(uuid) : -1; + public BossBar getBossBar(UUID uuid) { + return bossBars.get(uuid); } - public long removeBossBar(UUID uuid) { - return bossbars.remove(uuid); + public void removeBossBar(UUID uuid) { + BossBar bossBar = bossBars.remove(uuid); + if (bossBar != null) { + bossBar.removeBossBar(); + } + } + + public void updateBossBars() { + bossBars.values().forEach(BossBar::updateBossBar); } public void clear() { entities = null; entityIdTranslations = null; playerEntities = null; - bossbars = null; + bossBars = null; } } 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 206f42d1f..7ab713893 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 @@ -123,6 +123,7 @@ public class BedrockActionTranslator extends PacketTranslator { @Override public void translate(ServerBossBarPacket packet, GeyserSession session) { - BossEventPacket bossEventPacket = new BossEventPacket(); - bossEventPacket.setBossUniqueEntityId(session.getEntityCache().getBossBar(packet.getUuid())); - + BossBar bossBar = session.getEntityCache().getBossBar(packet.getUuid()); switch (packet.getAction()) { case ADD: - long entityId = session.getEntityCache().addBossBar(packet.getUuid()); - addBossEntity(session, entityId); - - bossEventPacket.setAction(BossEventPacket.Action.SHOW); - bossEventPacket.setBossUniqueEntityId(entityId); - bossEventPacket.setTitle(MessageUtils.getTranslatedBedrockMessage(packet.getTitle(), session.getClientData().getLanguageCode())); - bossEventPacket.setHealthPercentage(packet.getHealth()); - bossEventPacket.setColor(0); //ignored by client - bossEventPacket.setOverlay(1); - bossEventPacket.setDarkenSky(0); + bossBar = new BossBar(session, packet.getTitle(), packet.getHealth(), Color.RED.getRGB(), 1, 0); + session.getEntityCache().addBossBar(packet.getUuid(), bossBar); break; case UPDATE_TITLE: - bossEventPacket.setAction(BossEventPacket.Action.TITLE); - bossEventPacket.setTitle(MessageUtils.getTranslatedBedrockMessage(packet.getTitle(), session.getClientData().getLanguageCode())); + if (bossBar != null) bossBar.updateTitle(packet.getTitle()); break; case UPDATE_HEALTH: - bossEventPacket.setAction(BossEventPacket.Action.HEALTH_PERCENTAGE); - bossEventPacket.setHealthPercentage(packet.getHealth()); + if (bossBar != null) bossBar.updateHealth(packet.getHealth()); break; case REMOVE: - bossEventPacket.setAction(BossEventPacket.Action.HIDE); - removeBossEntity(session, session.getEntityCache().removeBossBar(packet.getUuid())); + session.getEntityCache().removeBossBar(packet.getUuid()); break; case UPDATE_STYLE: case UPDATE_FLAGS: //todo return; } - - session.getUpstream().sendPacket(bossEventPacket); - } - - /** - * Bedrock still needs an entity to display the BossBar.
- * Just like 1.8 but it doesn't care about which entity - */ - private void addBossEntity(GeyserSession session, long entityId) { - AddEntityPacket addEntityPacket = new AddEntityPacket(); - addEntityPacket.setUniqueEntityId(entityId); - addEntityPacket.setRuntimeEntityId(entityId); - addEntityPacket.setIdentifier("minecraft:creeper"); - addEntityPacket.setEntityType(33); - addEntityPacket.setPosition(session.getPlayerEntity().getPosition()); - addEntityPacket.setRotation(Vector3f.ZERO); - addEntityPacket.setMotion(Vector3f.ZERO); - addEntityPacket.getMetadata().put(EntityData.SCALE, 0.01F); // scale = 0 doesn't work? - - session.getUpstream().sendPacket(addEntityPacket); - } - - private void removeBossEntity(GeyserSession session, long entityId) { - RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket(); - removeEntityPacket.setUniqueEntityId(entityId); - - session.getUpstream().sendPacket(removeEntityPacket); } } From de9c9b3dfafe63a86278ea33ab51fb1b54772fad Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Apr 2020 15:49:28 +0200 Subject: [PATCH 2/3] reset color --- .../network/translators/java/JavaBossBarTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 288d71516..375384d77 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 @@ -41,7 +41,7 @@ public class JavaBossBarTranslator extends PacketTranslator BossBar bossBar = session.getEntityCache().getBossBar(packet.getUuid()); switch (packet.getAction()) { case ADD: - bossBar = new BossBar(session, packet.getTitle(), packet.getHealth(), Color.RED.getRGB(), 1, 0); + bossBar = new BossBar(session, packet.getTitle(), packet.getHealth(), 0, 1, 0); session.getEntityCache().addBossBar(packet.getUuid(), bossBar); break; case UPDATE_TITLE: From 88a12385933d5611448506656fa3e6bb69a0ce14 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Apr 2020 21:37:14 +0200 Subject: [PATCH 3/3] add licence header --- .../network/session/cache/BossBar.java | 37 ++++++++++++++----- .../java/JavaBossBarTranslator.java | 3 +- 2 files changed, 29 insertions(+), 11 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 8ff2c9459..abb9016a2 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 @@ -1,3 +1,28 @@ +/* + * 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.session.cache; import com.github.steveice10.mc.protocol.data.message.Message; @@ -6,9 +31,11 @@ import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; import com.nukkitx.protocol.bedrock.packet.BossEventPacket; import com.nukkitx.protocol.bedrock.packet.RemoveEntityPacket; +import lombok.AllArgsConstructor; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.MessageUtils; +@AllArgsConstructor public class BossBar { private GeyserSession session; @@ -20,16 +47,6 @@ public class BossBar { private int overlay; private int darkenSky; - public BossBar(GeyserSession session, Message title, float health, int color, int overlay, int darkenSky) { - this.session = session; - this.entityId = session.getEntityCache().getNextEntityId().incrementAndGet(); - this.title = title; - this.health = health; - this.color = color; - this.overlay = overlay; - this.darkenSky = darkenSky; - } - public void addBossBar() { addBossEntity(); updateBossBar(); 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 375384d77..2c32ef6fe 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 @@ -41,7 +41,8 @@ public class JavaBossBarTranslator extends PacketTranslator BossBar bossBar = session.getEntityCache().getBossBar(packet.getUuid()); switch (packet.getAction()) { case ADD: - bossBar = new BossBar(session, packet.getTitle(), packet.getHealth(), 0, 1, 0); + long entityId = session.getEntityCache().getNextEntityId().incrementAndGet(); + bossBar = new BossBar(session, entityId, packet.getTitle(), packet.getHealth(), 0, 1, 0); session.getEntityCache().addBossBar(packet.getUuid(), bossBar); break; case UPDATE_TITLE: