diff --git a/1_10_R1/pom.xml b/1_10_R1/pom.xml
index 4f6a3d5..342e536 100644
--- a/1_10_R1/pom.xml
+++ b/1_10_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_11_R1/pom.xml b/1_11_R1/pom.xml
index 392bbb4..e4a9847 100644
--- a/1_11_R1/pom.xml
+++ b/1_11_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_12_R1/pom.xml b/1_12_R1/pom.xml
index 1e4a990..cd878d3 100644
--- a/1_12_R1/pom.xml
+++ b/1_12_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_13_R1/pom.xml b/1_13_R1/pom.xml
index e52f4d5..dd6c058 100644
--- a/1_13_R1/pom.xml
+++ b/1_13_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_13_R2/pom.xml b/1_13_R2/pom.xml
index 176778f..1213f4e 100644
--- a/1_13_R2/pom.xml
+++ b/1_13_R2/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_14_R1/pom.xml b/1_14_R1/pom.xml
index fdde049..6ffb111 100644
--- a/1_14_R1/pom.xml
+++ b/1_14_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_15_R1/pom.xml b/1_15_R1/pom.xml
index 1a638e6..0f9b9ed 100644
--- a/1_15_R1/pom.xml
+++ b/1_15_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_16_R1/pom.xml b/1_16_R1/pom.xml
index feebefc..55cf616 100644
--- a/1_16_R1/pom.xml
+++ b/1_16_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_16_R2/pom.xml b/1_16_R2/pom.xml
index 100ca20..cda7458 100644
--- a/1_16_R2/pom.xml
+++ b/1_16_R2/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_16_R3/pom.xml b/1_16_R3/pom.xml
index 65f644c..ecdabdc 100644
--- a/1_16_R3/pom.xml
+++ b/1_16_R3/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_17_R1/pom.xml b/1_17_R1/pom.xml
index a410197..2543383 100644
--- a/1_17_R1/pom.xml
+++ b/1_17_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_18_R1/pom.xml b/1_18_R1/pom.xml
index 853b2ef..45fcd79 100644
--- a/1_18_R1/pom.xml
+++ b/1_18_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_18_R2/pom.xml b/1_18_R2/pom.xml
index 9e6b71e..c001a93 100644
--- a/1_18_R2/pom.xml
+++ b/1_18_R2/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_19_R1/pom.xml b/1_19_R1/pom.xml
index b164c70..a47012c 100644
--- a/1_19_R1/pom.xml
+++ b/1_19_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_19_R2/pom.xml b/1_19_R2/pom.xml
index 809d725..6534895 100644
--- a/1_19_R2/pom.xml
+++ b/1_19_R2/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_19_R3/pom.xml b/1_19_R3/pom.xml
index 65babbf..38f4fe0 100644
--- a/1_19_R3/pom.xml
+++ b/1_19_R3/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_20_R1/pom.xml b/1_20_R1/pom.xml
index 2edc4eb..b4d67ac 100644
--- a/1_20_R1/pom.xml
+++ b/1_20_R1/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_20_R2/pom.xml b/1_20_R2/pom.xml
index f52880b..2d243aa 100644
--- a/1_20_R2/pom.xml
+++ b/1_20_R2/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_20_R3/pom.xml b/1_20_R3/pom.xml
index f1ff076..55e67e3 100644
--- a/1_20_R3/pom.xml
+++ b/1_20_R3/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_20_R4/pom.xml b/1_20_R4/pom.xml
index 623d1a8..31c2a48 100644
--- a/1_20_R4/pom.xml
+++ b/1_20_R4/pom.xml
@@ -5,7 +5,7 @@
signgui-parent
de.rapha149.signgui
- 2.3.3
+ 2.3.4
4.0.0
diff --git a/1_21_R1/pom.xml b/1_21_R1/pom.xml
new file mode 100644
index 0000000..db680e7
--- /dev/null
+++ b/1_21_R1/pom.xml
@@ -0,0 +1,46 @@
+
+
+
+ signgui-parent
+ de.rapha149.signgui
+ 2.3.4
+
+ 4.0.0
+
+ signgui-1_21_R1
+
+
+ true
+
+
+
+
+ org.spigotmc
+ spigot
+ 1.21-R0.1-SNAPSHOT
+ provided
+
+
+ de.rapha149.signgui
+ signgui-wrapper
+ ${project.parent.version}
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 21
+
+
+
+
+
diff --git a/1_21_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_21_R1.java b/1_21_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_21_R1.java
new file mode 100644
index 0000000..25826d5
--- /dev/null
+++ b/1_21_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_21_R1.java
@@ -0,0 +1,165 @@
+package de.rapha149.signgui.version;
+
+import de.rapha149.signgui.SignEditor;
+import de.rapha149.signgui.SignGUIChannelHandler;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPipeline;
+import net.minecraft.core.BlockPosition;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.chat.IChatBaseComponent;
+import net.minecraft.network.protocol.Packet;
+import net.minecraft.network.protocol.game.PacketPlayInUpdateSign;
+import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor;
+import net.minecraft.server.level.EntityPlayer;
+import net.minecraft.server.network.PlayerConnection;
+import net.minecraft.server.network.ServerCommonPacketListenerImpl;
+import net.minecraft.world.item.EnumColor;
+import net.minecraft.world.level.World;
+import net.minecraft.world.level.block.entity.SignText;
+import net.minecraft.world.level.block.entity.TileEntitySign;
+import org.bukkit.DyeColor;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
+
+public class Wrapper1_21_R1 implements VersionWrapper {
+
+ private final Field NETWORK_MANAGER_FIELD;
+
+ {
+ Field networkManagerField = null;
+ for (Field field : ServerCommonPacketListenerImpl.class.getDeclaredFields()) {
+ if (field.getType() == NetworkManager.class) {
+ field.setAccessible(true);
+ networkManagerField = field;
+ break;
+ }
+ }
+
+ NETWORK_MANAGER_FIELD = networkManagerField;
+ }
+
+ @Override
+ public Material getDefaultType() {
+ return Material.OAK_SIGN;
+ }
+
+ @Override
+ public List getSignTypes() {
+ return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN,
+ Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN,
+ Material.CHERRY_SIGN, Material.MANGROVE_SIGN, Material.BAMBOO_SIGN
+ );
+ }
+
+ @Override
+ public void openSignEditor(Player player, String[] lines, Material type, DyeColor color, Location signLoc, BiConsumer onFinish) throws IllegalAccessException {
+ EntityPlayer p = ((CraftPlayer) player).getHandle();
+ PlayerConnection conn = p.c;
+
+ if (NETWORK_MANAGER_FIELD == null)
+ throw new IllegalStateException("Unable to find NetworkManager field in PlayerConnection class.");
+ if (!NETWORK_MANAGER_FIELD.canAccess(conn)) {
+ NETWORK_MANAGER_FIELD.setAccessible(true);
+ if (!NETWORK_MANAGER_FIELD.canAccess(conn))
+ throw new IllegalStateException("Unable to access NetworkManager field in PlayerConnection class.");
+ }
+
+ Location loc = signLoc != null ? signLoc : getDefaultLocation(player);
+ BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
+
+ TileEntitySign sign = new TileEntitySign(pos, null);
+ SignText signText = sign.a(true) // flag = front/back of sign
+ .a(EnumColor.valueOf(color.toString()));
+ for (int i = 0; i < lines.length; i++)
+ signText = signText.a(i, IChatBaseComponent.a(lines[i]));
+ sign.a(signText, true);
+
+ boolean schedule = false;
+ NetworkManager manager = (NetworkManager) NETWORK_MANAGER_FIELD.get(conn);
+ ChannelPipeline pipeline = manager.n.pipeline();
+ if (pipeline.names().contains("SignGUI")) {
+ ChannelHandler handler = pipeline.get("SignGUI");
+ if (handler instanceof SignGUIChannelHandler> signGUIHandler) {
+ signGUIHandler.close();
+ schedule = signGUIHandler.getBlockPosition().equals(pos);
+ }
+
+ if (pipeline.names().contains("SignGUI"))
+ pipeline.remove("SignGUI");
+ }
+
+ Runnable runnable = () -> {
+ player.sendBlockChange(loc, type.createBlockData());
+ sign.a(p.dO());
+ conn.b(sign.l());
+ sign.a((World) null);
+ conn.b(new PacketPlayOutOpenSignEditor(pos, true)); // flag = front/back of sign
+
+ SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline);
+ pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() {
+
+ @Override
+ public Object getBlockPosition() {
+ return pos;
+ }
+
+ @Override
+ public void close() {
+ closeSignEditor(player, signEditor);
+ }
+
+ @Override
+ protected void decode(ChannelHandlerContext chc, Packet> packet, List