diff --git a/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/ActionBarVisualization.java b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/ActionBarVisualization.java new file mode 100644 index 000000000..10ea7e32b --- /dev/null +++ b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/ActionBarVisualization.java @@ -0,0 +1,33 @@ +package com.viaversion.viarewind.protocol.protocol1_8to1_9.cooldown; + +import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.libs.gson.JsonPrimitive; +import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8; + +public class ActionBarVisualization implements CooldownVisualization { + private final UserConnection user; + + public ActionBarVisualization(UserConnection user) { + this.user = user; + } + + @Override + public void show(double progress) throws Exception { + sendActionBar(CooldownVisualization.buildProgressText("■", progress)); + } + + @Override + public void hide() throws Exception { + sendActionBar("§r"); + } + + private void sendActionBar(String bar) throws Exception { + PacketWrapper actionBarPacket = PacketWrapper.create(ClientboundPackets1_8.CHAT_MESSAGE, user); + actionBarPacket.write(Type.COMPONENT, new JsonPrimitive(bar)); + actionBarPacket.write(Type.BYTE, (byte) 2); // Position - above hotbar + actionBarPacket.scheduleSend(Protocol1_8To1_9.class); + } +} diff --git a/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/BossBarVisualization.java b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/BossBarVisualization.java new file mode 100644 index 000000000..1947f8c30 --- /dev/null +++ b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/BossBarVisualization.java @@ -0,0 +1,50 @@ +package com.viaversion.viarewind.protocol.protocol1_8to1_9.cooldown; + +import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.libs.gson.JsonPrimitive; +import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9; +import java.util.UUID; + +public class BossBarVisualization implements CooldownVisualization { + private final UserConnection user; + private UUID bossUUID; + + public BossBarVisualization(UserConnection user) { + this.user = user; + } + + @Override + public void show(double progress) throws Exception { + PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_9.BOSSBAR, user); + if (bossUUID == null) { + bossUUID = UUID.randomUUID(); + wrapper.write(Type.UUID, bossUUID); + wrapper.write(Type.VAR_INT, 0); // Action - add + wrapper.write(Type.COMPONENT, new JsonPrimitive(" ")); // Title + wrapper.write(Type.FLOAT, (float) progress); // Health + wrapper.write(Type.VAR_INT, 0); // Color + wrapper.write(Type.VAR_INT, 0); // Division + wrapper.write(Type.UNSIGNED_BYTE, (short) 0); // Flags + } else { + wrapper.write(Type.UUID, bossUUID); + wrapper.write(Type.VAR_INT, 2); // Action - update health + wrapper.write(Type.FLOAT, (float) progress); // Health + } + wrapper.scheduleSend(Protocol1_8To1_9.class, false); + } + + @Override + public void hide() throws Exception { + if (bossUUID == null) { + return; + } + PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_9.BOSSBAR, null, user); + wrapper.write(Type.UUID, bossUUID); + wrapper.write(Type.VAR_INT, 1); // Action - remove + wrapper.scheduleSend(Protocol1_8To1_9.class, false); + bossUUID = null; + } +} diff --git a/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/CooldownVisualization.java b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/CooldownVisualization.java new file mode 100644 index 000000000..49615bdcd --- /dev/null +++ b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/CooldownVisualization.java @@ -0,0 +1,54 @@ +package com.viaversion.viarewind.protocol.protocol1_8to1_9.cooldown; + +import com.viaversion.viarewind.ViaRewind; +import com.viaversion.viarewind.api.ViaRewindConfig.CooldownIndicator; +import com.viaversion.viaversion.api.connection.UserConnection; + +public interface CooldownVisualization { + void show(double progress) throws Exception; + + void hide() throws Exception; + + + int MAX_PROGRESS_TEXT_LENGTH = 10; + + static String buildProgressText(String symbol, double cooldown) { + int green = (int) Math.floor(((double) MAX_PROGRESS_TEXT_LENGTH) * cooldown); + int grey = MAX_PROGRESS_TEXT_LENGTH - green; + StringBuilder builder = new StringBuilder("§8"); + while (green-- > 0) builder.append(symbol); + builder.append("§7"); + while (grey-- > 0) builder.append(symbol); + return builder.toString(); + } + + interface Factory { + CooldownVisualization create(UserConnection user); + + static Factory fromConfiguration() { + try { + return fromIndicator(ViaRewind.getConfig().getCooldownIndicator()); + } catch (IllegalArgumentException e) { + ViaRewind.getPlatform().getLogger().warning("Invalid cooldown-indicator setting"); + return DISABLED; + } + } + + static Factory fromIndicator(CooldownIndicator indicator) { + switch (indicator) { + case TITLE: + return TitleCooldownVisualization::new; + case BOSS_BAR: + return BossBarVisualization::new; + case ACTION_BAR: + return ActionBarVisualization::new; + case DISABLED: + return DISABLED; + default: + throw new IllegalArgumentException("Unexpected: " + indicator); + } + } + + Factory DISABLED = user -> new DisabledCooldownVisualization(); + } +} diff --git a/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/DisabledCooldownVisualization.java b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/DisabledCooldownVisualization.java new file mode 100644 index 000000000..d1e9d7868 --- /dev/null +++ b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/DisabledCooldownVisualization.java @@ -0,0 +1,13 @@ +package com.viaversion.viarewind.protocol.protocol1_8to1_9.cooldown; + +public class DisabledCooldownVisualization implements CooldownVisualization { + @Override + public void show(double progress) { + + } + + @Override + public void hide() { + + } +} diff --git a/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/TitleCooldownVisualization.java b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/TitleCooldownVisualization.java new file mode 100644 index 000000000..f1c35f5fd --- /dev/null +++ b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/cooldown/TitleCooldownVisualization.java @@ -0,0 +1,59 @@ +package com.viaversion.viarewind.protocol.protocol1_8to1_9.cooldown; + +import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.libs.gson.JsonPrimitive; +import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8; +import java.util.function.Consumer; + +public class TitleCooldownVisualization implements CooldownVisualization { + private final UserConnection user; + + public TitleCooldownVisualization(UserConnection user) { + this.user = user; + } + + @Override + public void show(double progress) throws Exception { + String text = CooldownVisualization.buildProgressText("˙", progress); + sendTitle("", text, 0, 2, 5); + } + + @Override + public void hide() throws Exception { + sendTitlePacket(ACTION_HIDE, wrapper -> {}); + } + + private static final int ACTION_SET_TITLE = 0; + private static final int ACTION_SET_SUBTITLE = 1; + private static final int ACTION_SET_TIMES_AND_DISPLAY = 2; + private static final int ACTION_HIDE = 3; + + private void sendTitle(String titleText, String subTitleText, int fadeIn, int stay, int fadeOut) throws Exception { + sendTitlePacket( + ACTION_SET_TITLE, + packet -> packet.write(Type.COMPONENT, new JsonPrimitive(titleText)) + ); + sendTitlePacket( + ACTION_SET_SUBTITLE, + packet -> packet.write(Type.COMPONENT, new JsonPrimitive(subTitleText)) + ); + sendTitlePacket( + ACTION_SET_TIMES_AND_DISPLAY, + packet -> { + packet.write(Type.INT, fadeIn); + packet.write(Type.INT, stay); + packet.write(Type.INT, fadeOut); + } + ); + } + + private void sendTitlePacket(int action, Consumer writer) throws Exception { + PacketWrapper titlePacket = PacketWrapper.create(ClientboundPackets1_8.TITLE, user); + titlePacket.write(Type.VAR_INT, action); + writer.accept(titlePacket); + titlePacket.scheduleSend(Protocol1_8To1_9.class); + } +} diff --git a/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/storage/Cooldown.java b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/storage/Cooldown.java index 8a940f39b..75dac068c 100644 --- a/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/storage/Cooldown.java +++ b/common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/storage/Cooldown.java @@ -19,146 +19,59 @@ package com.viaversion.viarewind.protocol.protocol1_8to1_9.storage; import com.viaversion.viarewind.ViaRewind; -import com.viaversion.viarewind.api.ViaRewindConfig; -import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9; -import com.viaversion.viarewind.utils.PacketUtil; +import com.viaversion.viarewind.protocol.protocol1_8to1_9.cooldown.CooldownVisualization; +import com.viaversion.viarewind.protocol.protocol1_8to1_9.cooldown.CooldownVisualization.Factory; import com.viaversion.viarewind.utils.Tickable; import com.viaversion.viaversion.api.connection.StoredObject; import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; -import com.viaversion.viaversion.api.type.Type; -import com.viaversion.viaversion.libs.gson.JsonPrimitive; -import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8; -import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9; import com.viaversion.viaversion.util.Pair; import java.util.ArrayList; -import java.util.UUID; +import java.util.Objects; +import java.util.logging.Level; public class Cooldown extends StoredObject implements Tickable { private double attackSpeed = 4.0; private long lastHit = 0; - private final ViaRewindConfig.CooldownIndicator cooldownIndicator; - private UUID bossUUID; - private boolean lastSend; + private CooldownVisualization.Factory visualizationFactory = CooldownVisualization.Factory.fromConfiguration(); + private CooldownVisualization current; public Cooldown(final UserConnection user) { super(user); - - ViaRewindConfig.CooldownIndicator indicator; - try { - indicator = ViaRewind.getConfig().getCooldownIndicator(); - } catch (IllegalArgumentException e) { - ViaRewind.getPlatform().getLogger().warning("Invalid cooldown-indicator setting"); - indicator = ViaRewindConfig.CooldownIndicator.DISABLED; - } - - this.cooldownIndicator = indicator; } @Override public void tick() { if (!hasCooldown()) { - if (lastSend) { - hide(); - lastSend = false; - } + endCurrentVisualization(); return; } - BlockPlaceDestroyTracker tracker = getUser().get(BlockPlaceDestroyTracker.class); if (tracker.isMining()) { lastHit = 0; - if (lastSend) { - hide(); - lastSend = false; - } + endCurrentVisualization(); return; } - - showCooldown(); - lastSend = true; - } - - private void showCooldown() { - if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.TITLE) { - sendTitle("", getTitle(), 0, 2, 5); - } else if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.ACTION_BAR) { - sendActionBar(getTitle()); - } else if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.BOSS_BAR) { - sendBossBar((float) getCooldown()); + if (current == null) { + current = visualizationFactory.create(getUser()); } - } - - private void hide() { - if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.ACTION_BAR) { - sendActionBar("§r"); - } else if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.TITLE) { - hideTitle(); - } else if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.BOSS_BAR) { - hideBossBar(); + try { + current.show(getCooldown()); + } catch (Exception exception) { + ViaRewind.getPlatform().getLogger().log(Level.WARNING, "Unable to show cooldown visualization", exception); } } - private void hideBossBar() { - if (bossUUID == null) return; - PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_9.BOSSBAR, null, getUser()); - wrapper.write(Type.UUID, bossUUID); - wrapper.write(Type.VAR_INT, 1); - PacketUtil.sendPacket(wrapper, Protocol1_8To1_9.class, false, true); - bossUUID = null; - } - - private void sendBossBar(float cooldown) { - PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_9.BOSSBAR, getUser()); - if (bossUUID == null) { - bossUUID = UUID.randomUUID(); - wrapper.write(Type.UUID, bossUUID); - wrapper.write(Type.VAR_INT, 0); - wrapper.write(Type.COMPONENT, new JsonPrimitive(" ")); - wrapper.write(Type.FLOAT, cooldown); - wrapper.write(Type.VAR_INT, 0); - wrapper.write(Type.VAR_INT, 0); - wrapper.write(Type.UNSIGNED_BYTE, (short) 0); - } else { - wrapper.write(Type.UUID, bossUUID); - wrapper.write(Type.VAR_INT, 2); - wrapper.write(Type.FLOAT, cooldown); + private void endCurrentVisualization() { + if (current != null) { + try { + current.hide(); + } catch (Exception exception) { + ViaRewind.getPlatform().getLogger().log(Level.WARNING, "Unable to hide cooldown visualization", exception); + } + current = null; } - PacketUtil.sendPacket(wrapper, Protocol1_8To1_9.class, false, true); - } - - private void hideTitle() { - PacketWrapper hide = PacketWrapper.create(ClientboundPackets1_8.TITLE, null, getUser()); - hide.write(Type.VAR_INT, 3); - PacketUtil.sendPacket(hide, Protocol1_8To1_9.class); - } - - private void sendTitle(String title, String subTitle, int fadeIn, int stay, int fadeOut) { - PacketWrapper timePacket = PacketWrapper.create(ClientboundPackets1_8.TITLE, null, getUser()); - timePacket.write(Type.VAR_INT, 2); - timePacket.write(Type.INT, fadeIn); - timePacket.write(Type.INT, stay); - timePacket.write(Type.INT, fadeOut); - PacketWrapper titlePacket = PacketWrapper.create(ClientboundPackets1_8.TITLE, getUser()); - titlePacket.write(Type.VAR_INT, 0); - titlePacket.write(Type.COMPONENT, new JsonPrimitive(title)); - PacketWrapper subtitlePacket = PacketWrapper.create(ClientboundPackets1_8.TITLE, getUser()); - subtitlePacket.write(Type.VAR_INT, 1); - subtitlePacket.write(Type.COMPONENT, new JsonPrimitive(subTitle)); - - PacketUtil.sendPacket(titlePacket, Protocol1_8To1_9.class); - PacketUtil.sendPacket(subtitlePacket, Protocol1_8To1_9.class); - PacketUtil.sendPacket(timePacket, Protocol1_8To1_9.class); - } - - private void sendActionBar(String bar) { - PacketWrapper actionBarPacket = PacketWrapper.create(ClientboundPackets1_8.CHAT_MESSAGE, getUser()); - actionBarPacket.write(Type.COMPONENT, new JsonPrimitive(bar)); - actionBarPacket.write(Type.BYTE, (byte) 2); - - PacketUtil.sendPacket(actionBarPacket, Protocol1_8To1_9.class); } public boolean hasCooldown() { @@ -177,21 +90,6 @@ private double restrain(double x, double a, double b) { return Math.min(x, b); } - private final static int max = 10; - - private String getTitle() { - String symbol = cooldownIndicator == ViaRewindConfig.CooldownIndicator.ACTION_BAR ? "■" : "˙"; - - double cooldown = getCooldown(); - int green = (int) Math.floor(((double) max) * cooldown); - int grey = max - green; - StringBuilder builder = new StringBuilder("§8"); - while (green-- > 0) builder.append(symbol); - builder.append("§7"); - while (grey-- > 0) builder.append(symbol); - return builder.toString(); - } - public double getAttackSpeed() { return attackSpeed; } @@ -229,4 +127,8 @@ public void hit() { public void setLastHit(long lastHit) { this.lastHit = lastHit; } + + public void setVisualizationFactory(Factory visualizationFactory) { + this.visualizationFactory = Objects.requireNonNull(visualizationFactory, "visualizationFactory"); + } } diff --git a/gradle.properties b/gradle.properties index 04143e0f7..2f9c11ee5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ maven_version=3.0.4-SNAPSHOT maven_group=com.viaversion # libraries -viaversion_version=4.9.0-23w43a-SNAPSHOT +viaversion_version=4.9.0-23w44a-SNAPSHOT netty_version=4.0.20.Final guava_version=17.0 @@ -15,4 +15,4 @@ guava_version=17.0 mcVersions=1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9, 1.8.8 mcVersionRange=1.8-1.20.2 waterfallVersion=1.20 -velocityVersion=3.2 \ No newline at end of file +velocityVersion=3.2