diff --git a/pom.xml b/pom.xml index 76d7dcc..812a81c 100644 --- a/pom.xml +++ b/pom.xml @@ -63,6 +63,10 @@ sonatype https://oss.sonatype.org/content/groups/public/ + + dmulloy2-repo + https://repo.dmulloy2.net/repository/public/ + @@ -72,5 +76,17 @@ 1.17.1-R0.1-SNAPSHOT provided + + com.comphenix.protocol + ProtocolLib + 4.7.0 + provided + + + io.netty + netty-all + 4.1.5.Final + provided + diff --git a/src/main/java/me/youhavetrouble/blockedit/BEPlayer.java b/src/main/java/me/youhavetrouble/blockedit/BEPlayer.java index c230d0f..cbc3581 100644 --- a/src/main/java/me/youhavetrouble/blockedit/BEPlayer.java +++ b/src/main/java/me/youhavetrouble/blockedit/BEPlayer.java @@ -1,5 +1,7 @@ package me.youhavetrouble.blockedit; +import me.youhavetrouble.blockedit.optionals.SelectionHighlight; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.util.BoundingBox; @@ -12,6 +14,15 @@ public class BEPlayer { private static final HashMap playerHashMap = new HashMap<>(); private BoundingBox selection; private Location selectionPoint1, selectionPoint2; + private final UUID playerUuid; + + public BEPlayer(Player player) { + this.playerUuid = player.getUniqueId(); + } + + public Player getPlayer() { + return Bukkit.getPlayer(playerUuid); + } public BoundingBox getSelection() { return selection; @@ -19,6 +30,7 @@ public class BEPlayer { public void resetSelection() { this.selection = null; + Bukkit.getScheduler().runTaskAsynchronously(BlockEdit.getPlugin(),() -> SelectionHighlight.sendStop(getPlayer())); } private void updateSelection() { @@ -34,6 +46,19 @@ public class BEPlayer { selection = null; return; } + + Bukkit.getScheduler().runTaskAsynchronously(BlockEdit.getPlugin(), () -> { + SelectionHighlight.sendStop(getPlayer()); + if (selectionPoint1.equals(selectionPoint2)) { + SelectionHighlight.highlightBlock(getPlayer(), selectionPoint1, "#ffffff", "Selection Points", 10000); + } else { + SelectionHighlight.highlightBlock(getPlayer(), selectionPoint1, "#ffffff", "Selection Point 1", 10000); + SelectionHighlight.highlightBlock(getPlayer(), selectionPoint2, "#ffffff", "Selection Point 2", 10000); + } + + }); + + selection = BoundingBox.of(selectionPoint1, selectionPoint2); // bounding boxes are dumb. selection.expand(0.5, 0.5, 0.5); @@ -75,7 +100,7 @@ public class BEPlayer { } protected static void addPlayer(Player player) { - playerHashMap.put(player.getUniqueId(), new BEPlayer()); + playerHashMap.put(player.getUniqueId(), new BEPlayer(player)); } protected static void removePlayer(Player player) { diff --git a/src/main/java/me/youhavetrouble/blockedit/optionals/SelectionHighlight.java b/src/main/java/me/youhavetrouble/blockedit/optionals/SelectionHighlight.java new file mode 100644 index 0000000..5fe695a --- /dev/null +++ b/src/main/java/me/youhavetrouble/blockedit/optionals/SelectionHighlight.java @@ -0,0 +1,84 @@ +package me.youhavetrouble.blockedit.optionals; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftReflection; +import com.comphenix.protocol.wrappers.MinecraftKey; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import me.youhavetrouble.blockedit.BlockEdit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.awt.*; +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.StandardCharsets; + + +/** + * Highlighting selection blocks thanks to https://github.com/ArtFect/BlockHighlight + */ +public class SelectionHighlight { + + public static void highlightBlock(Player player, Location location, String color, String text, int time) { + if (BlockEdit.getPlugin().getServer().getPluginManager().isPluginEnabled("ProtocolLib")) { + sendBlockHighlight(player, location, color, text, time); + } + } + + public static void sendStop(Player pl) { + sendPayload(pl, "debug/game_test_clear", Unpooled.wrappedBuffer(new byte[0])); + } + + private static void sendBlockHighlight(Player player, Location location, String hex, String text, int time) { + ByteBuf packet = Unpooled.buffer(); + packet.writeLong(blockPosToLong((int)location.getX(), (int)location.getY(), (int)location.getZ())); + int color = hex2Rgb(hex, 100).getRGB(); + packet.writeInt(color); + writeString(packet, text); + packet.writeInt(time); + sendPayload(player, "debug/game_test_add_marker", packet); + } + + private static long blockPosToLong(int x, int y, int z) { + return ((long) x & 67108863L) << 38 | (long) y & 4095L | ((long) z & 67108863L) << 12; + } + + private static void writeBytes(ByteBuf packet, int i) { + while ((i & -128) != 0) { + packet.writeByte(i & 127 | 128); + i >>>= 7; + } + packet.writeByte(i); + } + + private static void writeString(ByteBuf packet, String s) { + byte[] abyte = s.getBytes(StandardCharsets.UTF_8); + writeBytes(packet, abyte.length); + packet.writeBytes(abyte); + } + + private static void sendPayload(Player receiver, String channel, ByteBuf bytes) { + PacketContainer handle = new PacketContainer(PacketType.Play.Server.CUSTOM_PAYLOAD); + handle.getMinecraftKeys().write(0, new MinecraftKey(channel)); + + Object serializer = MinecraftReflection.getPacketDataSerializer(bytes); + handle.getModifier().withType(ByteBuf.class).write(0, serializer); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(receiver, handle); + } catch (InvocationTargetException e) { + throw new RuntimeException("Unable to send the packet", e); + } + } + + //https://stackoverflow.com/questions/4129666/how-to-convert-hex-to-rgb-using-java/4129692 + private static Color hex2Rgb(String colorStr, int transparency) { + return new Color( + Integer.valueOf(colorStr.substring(1, 3), 16), + Integer.valueOf(colorStr.substring(3, 5), 16), + Integer.valueOf(colorStr.substring(5, 7), 16), transparency); + } + +} diff --git a/src/main/java/me/youhavetrouble/blockedit/util/Selection.java b/src/main/java/me/youhavetrouble/blockedit/util/Selection.java index e731895..d534fcc 100644 --- a/src/main/java/me/youhavetrouble/blockedit/util/Selection.java +++ b/src/main/java/me/youhavetrouble/blockedit/util/Selection.java @@ -10,10 +10,13 @@ import java.util.UUID; public class Selection extends BoundingBox { private UUID worldUuid; + private Location selectionPoint1, selectionPoint2; public Selection(Location location1, Location location2, UUID worldUuid) { super(location1.getX(), location1.getY(), location1.getZ(), location2.getX(), location2.getY(), location2.getZ()); this.worldUuid = worldUuid; + this.selectionPoint1 = location1; + this.selectionPoint2 = location2; } public Selection(BoundingBox boundingBox, UUID worldUuid) { @@ -21,6 +24,14 @@ public class Selection extends BoundingBox { this.worldUuid = worldUuid; } + public Location getSelectionPoint1() { + return selectionPoint1; + } + + public Location getSelectionPoint2() { + return selectionPoint2; + } + public World getWorld() { return Bukkit.getWorld(worldUuid); } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9687e17..649b9d3 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,6 +5,8 @@ api-version: 1.17 authors: [ YouHaveTrouble ] description: Modern WorldEdit alternative website: youhavetrouble.me +softdepend: + - ProtocolLib commands: /wand: permission: blockedit.wand