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