├── .github ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── config.yml │ ├── feature.yml │ └── implementing-the-api.yml └── workflows │ └── build.yml ├── .gitignore ├── 1_10_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_10_R1.java ├── 1_11_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_11_R1.java ├── 1_12_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_12_R1.java ├── 1_13_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_13_R1.java ├── 1_13_R2 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_13_R2.java ├── 1_14_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_14_R1.java ├── 1_15_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_15_R1.java ├── 1_16_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_16_R1.java ├── 1_16_R2 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_16_R2.java ├── 1_16_R3 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_16_R3.java ├── 1_17_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_17_R1.java ├── 1_18_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_18_R1.java ├── 1_18_R2 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_18_R2.java ├── 1_19_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_19_R1.java ├── 1_19_R2 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_19_R2.java ├── 1_19_R3 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_19_R3.java ├── 1_20_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_20_R1.java ├── 1_20_R2 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_20_R2.java ├── 1_20_R3 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_20_R3.java ├── 1_20_R4 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_20_R4.java ├── 1_21_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_21_R1.java ├── 1_21_R2 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_21_R2.java ├── 1_21_R3 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_21_R3.java ├── 1_21_R4 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_21_R4.java ├── 1_8_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_8_R1.java ├── 1_8_R2 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_8_R2.java ├── 1_8_R3 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_8_R3.java ├── 1_9_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_9_R1.java ├── 1_9_R2 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── Wrapper1_9_R2.java ├── LICENSE ├── Mojang1_20_R4 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── MojangWrapper1_20_R4.java ├── Mojang1_21_R1 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── MojangWrapper1_21_R1.java ├── Mojang1_21_R2 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── MojangWrapper1_21_R2.java ├── Mojang1_21_R3 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── MojangWrapper1_21_R3.java ├── Mojang1_21_R4 ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ └── version │ └── MojangWrapper1_21_R4.java ├── README.md ├── api ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── rapha149 │ └── signgui │ ├── SignGUI.java │ ├── SignGUIAction.java │ ├── SignGUIBuilder.java │ ├── SignGUIFinishHandler.java │ ├── SignGUIResult.java │ ├── exception │ ├── SignGUIException.java │ └── SignGUIVersionException.java │ └── version │ └── VersionMatcher.java ├── pom.xml └── wrapper ├── pom.xml └── src └── main └── java └── de └── rapha149 └── signgui ├── SignEditor.java ├── SignGUIChannelHandler.java └── version └── VersionWrapper.java /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a report to help improve the API 3 | title: "[Bug] " 4 | labels: ["bug"] 5 | 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: Thanks for taking the time to submit a bug report! Please fill out the fields below. 10 | - type: input 11 | attributes: 12 | label: API version 13 | placeholder: 2.3.3 14 | validations: 15 | required: true 16 | - type: input 17 | attributes: 18 | label: Server software and version 19 | description: e.g. Spigot, Paper, Mohist, ... 20 | placeholder: Spigot 1.16.5 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: Steps to reproduce 26 | description: How do you trigger this bug? Please walk us through it step by step. 27 | placeholder: | 28 | 1. 29 | 2. 30 | 3. 31 | ... 32 | render: bash 33 | validations: 34 | required: true 35 | - type: textarea 36 | attributes: 37 | label: Expected behaviour 38 | description: A clear and concise description of what you expected to happen. 39 | validations: 40 | required: true 41 | - type: textarea 42 | attributes: 43 | label: What is actually happening? 44 | description: Describe what is actually happening, i.e. what the bug is. Please add screenshots if applicable. 45 | validations: 46 | required: true 47 | - type: textarea 48 | attributes: 49 | label: Code snippets 50 | description: | 51 | If applicable, upload or paste code snippets to help explain your problem. For better formatting, please place your code inside a fenced code block like this: 52 | \`\`\`java 53 | // Code 54 | \`\`\` 55 | - type: textarea 56 | attributes: 57 | label: Any additional comments? 58 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Javadoc 4 | url: https://javadoc.io/doc/de.rapha149.signgui/signgui 5 | about: The Javadoc is the perfect place to retrieve information about our API. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for the API 3 | title: "[Feature] " 4 | labels: ["enhancement"] 5 | 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: Thanks for taking the time to submit a feature request! Please fill out the fields below. 10 | - type: textarea 11 | attributes: 12 | label: Is your feature request related to a problem? 13 | placeholder: Yes, I have this problem, that ... 14 | render: bash 15 | - type: textarea 16 | attributes: 17 | label: What solution would you like? 18 | description: A clear and concise description of what you want to happen. 19 | validations: 20 | required: true 21 | - type: textarea 22 | attributes: 23 | label: Describe alternatives you've considered 24 | validations: 25 | required: true 26 | - type: textarea 27 | attributes: 28 | label: Any additional comments? 29 | 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/implementing-the-api.yml: -------------------------------------------------------------------------------- 1 | name: I need help implementing the API 2 | description: Ask a question or describe a problem you have with using the API in your project 3 | title: "[Problem] " 4 | labels: ["problem"] 5 | 6 | body: 7 | - type: input 8 | attributes: 9 | label: API version 10 | placeholder: 2.3.3 11 | validations: 12 | required: true 13 | - type: input 14 | attributes: 15 | label: Server software and version 16 | description: e.g. Spigot, Paper, Mohist, ... 17 | placeholder: Spigot 1.16.5 18 | validations: 19 | required: true 20 | - type: textarea 21 | attributes: 22 | label: What are you trying to do? 23 | description: Describe what you want to achieve with the API in your project. 24 | validations: 25 | required: true 26 | - type: textarea 27 | attributes: 28 | label: What do you need help with? 29 | description: Describe what you struggle with and how you have tried to solve the problem. 30 | validations: 31 | required: true 32 | - type: textarea 33 | attributes: 34 | label: Code snippets 35 | description: | 36 | If applicable, upload or paste code snippets to help explain your problem. For better formatting, please place your code inside a fenced code block like this: 37 | \`\`\`java 38 | // Code 39 | \`\`\` 40 | validations: 41 | required: true 42 | - type: textarea 43 | attributes: 44 | label: Any additional comments? 45 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | release: 5 | types: [published] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v3 15 | - name: Set up JDK 16 | uses: actions/setup-java@v3 17 | with: 18 | java-version: '21' 19 | distribution: 'temurin' 20 | cache: maven 21 | server-id: central 22 | server-username: CENTRAL_USERNAME 23 | server-password: CENTRAL_TOKEN 24 | gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} 25 | gpg-passphrase: GPG_PASSPHRASE 26 | 27 | - name: Initialize Paper NMS 28 | run: for file in $(grep -l 'paper-nms' $(find -name 'pom.xml')); do mvn -B paper-nms:init --file "$file"; done 29 | 30 | - name: Build the dependencies of the api 31 | run: mvn -B install --file pom.xml -pl '!api' 32 | 33 | - name: Build and deploy the api 34 | working-directory: ./api 35 | run: mvn -B deploy --file pom.xml 36 | env: 37 | CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} 38 | CENTRAL_TOKEN: ${{ secrets.CENTRAL_TOKEN }} 39 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | target/ 4 | test/ 5 | dependency-reduced-pom.xml 6 | .mvn/ 7 | .flattened-pom.xml 8 | .paper-nms/ 9 | -------------------------------------------------------------------------------- /1_10_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_10_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.10.2-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_10_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_10_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_10_R1.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | @SuppressWarnings("deprecation") 21 | public class Wrapper1_10_R1 implements VersionWrapper { 22 | 23 | @Override 24 | public Material getDefaultType() { 25 | return Material.SIGN_POST; 26 | } 27 | 28 | @Override 29 | public List getSignTypes() { 30 | return Arrays.asList(Material.SIGN_POST); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.setPosition(pos); 42 | for (int i = 0; i < lines.length; i++) 43 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 44 | 45 | boolean schedule = false; 46 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 47 | if (pipeline.names().contains("SignGUI")) { 48 | ChannelHandler handler = pipeline.get("SignGUI"); 49 | if (handler instanceof SignGUIChannelHandler) { 50 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 51 | signGUIHandler.close(); 52 | schedule = signGUIHandler.getBlockPosition().equals(pos); 53 | } 54 | 55 | if (pipeline.names().contains("SignGUI")) 56 | pipeline.remove("SignGUI"); 57 | } 58 | 59 | Runnable runnable = () -> { 60 | player.sendBlockChange(loc, type, (byte) 0); 61 | conn.sendPacket(sign.getUpdatePacket()); 62 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 63 | 64 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 65 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 66 | 67 | @Override 68 | public Object getBlockPosition() { 69 | return pos; 70 | } 71 | 72 | @Override 73 | public void close() { 74 | closeSignEditor(player, signEditor); 75 | } 76 | 77 | @Override 78 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 79 | try { 80 | if (packet instanceof PacketPlayInUpdateSign) { 81 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 82 | if (updateSign.a().equals(pos)) 83 | onFinish.accept(signEditor, updateSign.b()); 84 | } 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | } 88 | 89 | out.add(packet); 90 | } 91 | }); 92 | }; 93 | 94 | if (schedule) 95 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 96 | else 97 | runnable.run(); 98 | } 99 | 100 | @Override 101 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 102 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 103 | for (int i = 0; i < lines.length; i++) 104 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 105 | 106 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 107 | conn.sendPacket(sign.getUpdatePacket()); 108 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 109 | } 110 | 111 | @Override 112 | public void closeSignEditor(Player player, SignEditor signEditor) { 113 | Location loc = signEditor.getLocation(); 114 | signEditor.getPipeline().remove("SignGUI"); 115 | player.sendBlockChange(loc, loc.getBlock().getType(), loc.getBlock().getData()); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /1_11_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_11_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.11-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_11_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_11_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_11_R1.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | @SuppressWarnings("deprecation") 21 | public class Wrapper1_11_R1 implements VersionWrapper { 22 | 23 | @Override 24 | public Material getDefaultType() { 25 | return Material.SIGN_POST; 26 | } 27 | 28 | @Override 29 | public List getSignTypes() { 30 | return Arrays.asList(Material.SIGN_POST); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.setPosition(pos); 42 | for (int i = 0; i < lines.length; i++) 43 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 44 | 45 | boolean schedule = false; 46 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 47 | if (pipeline.names().contains("SignGUI")) { 48 | ChannelHandler handler = pipeline.get("SignGUI"); 49 | if (handler instanceof SignGUIChannelHandler) { 50 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 51 | signGUIHandler.close(); 52 | schedule = signGUIHandler.getBlockPosition().equals(pos); 53 | } 54 | 55 | if (pipeline.names().contains("SignGUI")) 56 | pipeline.remove("SignGUI"); 57 | } 58 | 59 | Runnable runnable = () -> { 60 | player.sendBlockChange(loc, type, (byte) 0); 61 | conn.sendPacket(sign.getUpdatePacket()); 62 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 63 | 64 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 65 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 66 | 67 | @Override 68 | public Object getBlockPosition() { 69 | return pos; 70 | } 71 | 72 | @Override 73 | public void close() { 74 | closeSignEditor(player, signEditor); 75 | } 76 | 77 | @Override 78 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 79 | try { 80 | if (packet instanceof PacketPlayInUpdateSign) { 81 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 82 | if (updateSign.a().equals(pos)) 83 | onFinish.accept(signEditor, updateSign.b()); 84 | } 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | } 88 | 89 | out.add(packet); 90 | } 91 | }); 92 | }; 93 | 94 | if (schedule) 95 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 96 | else 97 | runnable.run(); 98 | } 99 | 100 | @Override 101 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 102 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 103 | for (int i = 0; i < lines.length; i++) 104 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 105 | 106 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 107 | conn.sendPacket(sign.getUpdatePacket()); 108 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 109 | } 110 | 111 | @Override 112 | public void closeSignEditor(Player player, SignEditor signEditor) { 113 | Location loc = signEditor.getLocation(); 114 | signEditor.getPipeline().remove("SignGUI"); 115 | player.sendBlockChange(loc, loc.getBlock().getType(), loc.getBlock().getData()); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /1_12_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_12_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.12-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_12_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_12_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_12_R1.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | @SuppressWarnings("deprecation") 21 | public class Wrapper1_12_R1 implements VersionWrapper { 22 | 23 | @Override 24 | public Material getDefaultType() { 25 | return Material.SIGN_POST; 26 | } 27 | 28 | @Override 29 | public List getSignTypes() { 30 | return Arrays.asList(Material.SIGN_POST); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.setPosition(pos); 42 | for (int i = 0; i < lines.length; i++) 43 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 44 | 45 | boolean schedule = false; 46 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 47 | if (pipeline.names().contains("SignGUI")) { 48 | ChannelHandler handler = pipeline.get("SignGUI"); 49 | if (handler instanceof SignGUIChannelHandler) { 50 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 51 | signGUIHandler.close(); 52 | schedule = signGUIHandler.getBlockPosition().equals(pos); 53 | } 54 | 55 | if (pipeline.names().contains("SignGUI")) 56 | pipeline.remove("SignGUI"); 57 | } 58 | 59 | Runnable runnable = () -> { 60 | player.sendBlockChange(loc, type, (byte) 0); 61 | conn.sendPacket(sign.getUpdatePacket()); 62 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 63 | 64 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 65 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 66 | 67 | @Override 68 | public Object getBlockPosition() { 69 | return pos; 70 | } 71 | 72 | @Override 73 | public void close() { 74 | closeSignEditor(player, signEditor); 75 | } 76 | 77 | @Override 78 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 79 | try { 80 | if (packet instanceof PacketPlayInUpdateSign) { 81 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 82 | if (updateSign.a().equals(pos)) 83 | onFinish.accept(signEditor, updateSign.b()); 84 | } 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | } 88 | 89 | out.add(packet); 90 | } 91 | }); 92 | }; 93 | 94 | if (schedule) 95 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 96 | else 97 | runnable.run(); 98 | } 99 | 100 | @Override 101 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 102 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 103 | for (int i = 0; i < lines.length; i++) 104 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 105 | 106 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 107 | conn.sendPacket(sign.getUpdatePacket()); 108 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 109 | } 110 | 111 | @Override 112 | public void closeSignEditor(Player player, SignEditor signEditor) { 113 | Location loc = signEditor.getLocation(); 114 | signEditor.getPipeline().remove("SignGUI"); 115 | player.sendBlockChange(loc, loc.getBlock().getType(), loc.getBlock().getData()); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /1_13_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_13_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.13-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_13_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_13_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_13_R1.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_13_R1.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | public class Wrapper1_13_R1 implements VersionWrapper { 21 | 22 | @Override 23 | public Material getDefaultType() { 24 | return Material.SIGN; 25 | } 26 | 27 | @Override 28 | public List getSignTypes() { 29 | return Arrays.asList(Material.SIGN); 30 | } 31 | 32 | @Override 33 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 34 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 35 | PlayerConnection conn = p.playerConnection; 36 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 37 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 38 | 39 | TileEntitySign sign = new TileEntitySign(); 40 | sign.setPosition(pos); 41 | for (int i = 0; i < lines.length; i++) 42 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 43 | 44 | boolean schedule = false; 45 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 46 | if (pipeline.names().contains("SignGUI")) { 47 | ChannelHandler handler = pipeline.get("SignGUI"); 48 | if (handler instanceof SignGUIChannelHandler) { 49 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 50 | signGUIHandler.close(); 51 | schedule = signGUIHandler.getBlockPosition().equals(pos); 52 | } 53 | 54 | if (pipeline.names().contains("SignGUI")) 55 | pipeline.remove("SignGUI"); 56 | } 57 | 58 | Runnable runnable = () -> { 59 | player.sendBlockChange(loc, type.createBlockData()); 60 | conn.sendPacket(sign.getUpdatePacket()); 61 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 62 | 63 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 64 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 65 | 66 | @Override 67 | public Object getBlockPosition() { 68 | return pos; 69 | } 70 | 71 | @Override 72 | public void close() { 73 | closeSignEditor(player, signEditor); 74 | } 75 | 76 | @Override 77 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 78 | try { 79 | if (packet instanceof PacketPlayInUpdateSign) { 80 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 81 | if (updateSign.b().equals(pos)) 82 | onFinish.accept(signEditor, updateSign.c()); 83 | } 84 | } catch (Exception e) { 85 | e.printStackTrace(); 86 | } 87 | 88 | out.add(packet); 89 | } 90 | }); 91 | }; 92 | 93 | if (schedule) 94 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 95 | else 96 | runnable.run(); 97 | } 98 | 99 | @Override 100 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 101 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 102 | for (int i = 0; i < lines.length; i++) 103 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 104 | 105 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 106 | conn.sendPacket(sign.getUpdatePacket()); 107 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 108 | } 109 | 110 | @Override 111 | public void closeSignEditor(Player player, SignEditor signEditor) { 112 | Location loc = signEditor.getLocation(); 113 | signEditor.getPipeline().remove("SignGUI"); 114 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /1_13_R2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_13_R2 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.13.1-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_13_R2/src/main/java/de/rapha149/signgui/version/Wrapper1_13_R2.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_13_R2.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | public class Wrapper1_13_R2 implements VersionWrapper { 21 | 22 | @Override 23 | public Material getDefaultType() { 24 | return Material.SIGN; 25 | } 26 | 27 | @Override 28 | public List getSignTypes() { 29 | return Arrays.asList(Material.SIGN); 30 | } 31 | 32 | @Override 33 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 34 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 35 | PlayerConnection conn = p.playerConnection; 36 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 37 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 38 | 39 | TileEntitySign sign = new TileEntitySign(); 40 | sign.setPosition(pos); 41 | for (int i = 0; i < lines.length; i++) 42 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 43 | 44 | boolean schedule = false; 45 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 46 | if (pipeline.names().contains("SignGUI")) { 47 | ChannelHandler handler = pipeline.get("SignGUI"); 48 | if (handler instanceof SignGUIChannelHandler) { 49 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 50 | signGUIHandler.close(); 51 | schedule = signGUIHandler.getBlockPosition().equals(pos); 52 | } 53 | 54 | if (pipeline.names().contains("SignGUI")) 55 | pipeline.remove("SignGUI"); 56 | } 57 | 58 | Runnable runnable = () -> { 59 | player.sendBlockChange(loc, type.createBlockData()); 60 | conn.sendPacket(sign.getUpdatePacket()); 61 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 62 | 63 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 64 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 65 | 66 | @Override 67 | public Object getBlockPosition() { 68 | return pos; 69 | } 70 | 71 | @Override 72 | public void close() { 73 | closeSignEditor(player, signEditor); 74 | } 75 | 76 | @Override 77 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 78 | try { 79 | if (packet instanceof PacketPlayInUpdateSign) { 80 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 81 | if (updateSign.b().equals(pos)) 82 | onFinish.accept(signEditor, updateSign.c()); 83 | } 84 | } catch (Exception e) { 85 | e.printStackTrace(); 86 | } 87 | 88 | out.add(packet); 89 | } 90 | }); 91 | }; 92 | 93 | if (schedule) 94 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 95 | else 96 | runnable.run(); 97 | } 98 | 99 | @Override 100 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 101 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 102 | for (int i = 0; i < lines.length; i++) 103 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 104 | 105 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 106 | conn.sendPacket(sign.getUpdatePacket()); 107 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 108 | } 109 | 110 | @Override 111 | public void closeSignEditor(Player player, SignEditor signEditor) { 112 | Location loc = signEditor.getLocation(); 113 | signEditor.getPipeline().remove("SignGUI"); 114 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /1_14_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_14_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.14-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_14_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_14_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_14_R1.*; 9 | import org.bukkit.Bukkit; 10 | import org.bukkit.DyeColor; 11 | import org.bukkit.Location; 12 | import org.bukkit.Material; 13 | import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; 14 | import org.bukkit.entity.Player; 15 | 16 | import java.lang.reflect.Field; 17 | import java.util.Arrays; 18 | import java.util.List; 19 | import java.util.concurrent.TimeUnit; 20 | import java.util.function.BiConsumer; 21 | import java.util.regex.Pattern; 22 | 23 | public class Wrapper1_14_R1 implements VersionWrapper { 24 | 25 | private final boolean IS_1_14_1 = Pattern.compile("1\\.14\\.\\d").matcher(Bukkit.getBukkitVersion()).find(); 26 | 27 | @Override 28 | public Material getDefaultType() { 29 | return Material.OAK_SIGN; 30 | } 31 | 32 | @Override 33 | public List getSignTypes() { 34 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 35 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN); 36 | } 37 | 38 | @Override 39 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) throws NoSuchFieldException, IllegalAccessException { 40 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 41 | PlayerConnection conn = p.playerConnection; 42 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 43 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 44 | 45 | TileEntitySign sign = new TileEntitySign(); 46 | sign.setPosition(pos); 47 | 48 | Field field = sign.getClass().getDeclaredField(IS_1_14_1 ? "color" : "l"); 49 | field.setAccessible(true); 50 | field.set(sign, EnumColor.valueOf(color.toString())); 51 | field.setAccessible(false); 52 | 53 | for (int i = 0; i < lines.length; i++) 54 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 55 | 56 | boolean schedule = false; 57 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 58 | if (pipeline.names().contains("SignGUI")) { 59 | ChannelHandler handler = pipeline.get("SignGUI"); 60 | if (handler instanceof SignGUIChannelHandler) { 61 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 62 | signGUIHandler.close(); 63 | schedule = signGUIHandler.getBlockPosition().equals(pos); 64 | } 65 | 66 | if (pipeline.names().contains("SignGUI")) 67 | pipeline.remove("SignGUI"); 68 | } 69 | 70 | Runnable runnable = () -> { 71 | player.sendBlockChange(loc, type.createBlockData()); 72 | conn.sendPacket(sign.getUpdatePacket()); 73 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 74 | 75 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 76 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 77 | 78 | @Override 79 | public Object getBlockPosition() { 80 | return pos; 81 | } 82 | 83 | @Override 84 | public void close() { 85 | closeSignEditor(player, signEditor); 86 | } 87 | 88 | @Override 89 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 90 | try { 91 | if (packet instanceof PacketPlayInUpdateSign) { 92 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 93 | if (updateSign.b().equals(pos)) 94 | onFinish.accept(signEditor, updateSign.c()); 95 | } 96 | } catch (Exception e) { 97 | e.printStackTrace(); 98 | } 99 | 100 | out.add(packet); 101 | } 102 | }); 103 | }; 104 | 105 | if (schedule) 106 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 107 | else 108 | runnable.run(); 109 | } 110 | 111 | @Override 112 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 113 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 114 | for (int i = 0; i < lines.length; i++) 115 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 116 | 117 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 118 | conn.sendPacket(sign.getUpdatePacket()); 119 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 120 | } 121 | 122 | @Override 123 | public void closeSignEditor(Player player, SignEditor signEditor) { 124 | Location loc = signEditor.getLocation(); 125 | signEditor.getPipeline().remove("SignGUI"); 126 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /1_15_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_15_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.15-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_15_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_15_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_15_R1.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | public class Wrapper1_15_R1 implements VersionWrapper { 21 | 22 | @Override 23 | public Material getDefaultType() { 24 | return Material.OAK_SIGN; 25 | } 26 | 27 | @Override 28 | public List getSignTypes() { 29 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 30 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.setPosition(pos); 42 | sign.setColor(EnumColor.valueOf(color.toString())); 43 | for (int i = 0; i < lines.length; i++) 44 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 45 | 46 | boolean schedule = false; 47 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 48 | if (pipeline.names().contains("SignGUI")) { 49 | ChannelHandler handler = pipeline.get("SignGUI"); 50 | if (handler instanceof SignGUIChannelHandler) { 51 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 52 | signGUIHandler.close(); 53 | schedule = signGUIHandler.getBlockPosition().equals(pos); 54 | } 55 | 56 | if (pipeline.names().contains("SignGUI")) 57 | pipeline.remove("SignGUI"); 58 | } 59 | 60 | Runnable runnable = () -> { 61 | player.sendBlockChange(loc, type.createBlockData()); 62 | conn.sendPacket(sign.getUpdatePacket()); 63 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 64 | 65 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 66 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 67 | 68 | @Override 69 | public Object getBlockPosition() { 70 | return pos; 71 | } 72 | 73 | @Override 74 | public void close() { 75 | closeSignEditor(player, signEditor); 76 | } 77 | 78 | @Override 79 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 80 | try { 81 | if (packet instanceof PacketPlayInUpdateSign) { 82 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 83 | if (updateSign.b().equals(pos)) 84 | onFinish.accept(signEditor, updateSign.c()); 85 | } 86 | } catch (Exception e) { 87 | e.printStackTrace(); 88 | } 89 | 90 | out.add(packet); 91 | } 92 | }); 93 | }; 94 | 95 | if (schedule) 96 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 97 | else 98 | runnable.run(); 99 | } 100 | 101 | @Override 102 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 103 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 104 | for (int i = 0; i < lines.length; i++) 105 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 106 | 107 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 108 | conn.sendPacket(sign.getUpdatePacket()); 109 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 110 | } 111 | 112 | @Override 113 | public void closeSignEditor(Player player, SignEditor signEditor) { 114 | Location loc = signEditor.getLocation(); 115 | signEditor.getPipeline().remove("SignGUI"); 116 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /1_16_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_16_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.16.1-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_16_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_16_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_16_R1.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | public class Wrapper1_16_R1 implements VersionWrapper { 21 | 22 | @Override 23 | public Material getDefaultType() { 24 | return Material.OAK_SIGN; 25 | } 26 | 27 | @Override 28 | public List getSignTypes() { 29 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 30 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.setPosition(pos); 42 | sign.setColor(EnumColor.valueOf(color.toString())); 43 | for (int i = 0; i < lines.length; i++) 44 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 45 | 46 | boolean schedule = false; 47 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 48 | if (pipeline.names().contains("SignGUI")) { 49 | ChannelHandler handler = pipeline.get("SignGUI"); 50 | if (handler instanceof SignGUIChannelHandler) { 51 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 52 | signGUIHandler.close(); 53 | schedule = signGUIHandler.getBlockPosition().equals(pos); 54 | } 55 | 56 | if (pipeline.names().contains("SignGUI")) 57 | pipeline.remove("SignGUI"); 58 | } 59 | 60 | Runnable runnable = () -> { 61 | player.sendBlockChange(loc, type.createBlockData()); 62 | conn.sendPacket(sign.getUpdatePacket()); 63 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 64 | 65 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 66 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 67 | 68 | @Override 69 | public Object getBlockPosition() { 70 | return pos; 71 | } 72 | 73 | @Override 74 | public void close() { 75 | closeSignEditor(player, signEditor); 76 | } 77 | 78 | @Override 79 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 80 | try { 81 | if (packet instanceof PacketPlayInUpdateSign) { 82 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 83 | if (updateSign.b().equals(pos)) 84 | onFinish.accept(signEditor, updateSign.c()); 85 | } 86 | } catch (Exception e) { 87 | e.printStackTrace(); 88 | } 89 | 90 | out.add(packet); 91 | } 92 | }); 93 | }; 94 | 95 | if (schedule) 96 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 97 | else 98 | runnable.run(); 99 | } 100 | 101 | @Override 102 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 103 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 104 | for (int i = 0; i < lines.length; i++) 105 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 106 | 107 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 108 | conn.sendPacket(sign.getUpdatePacket()); 109 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 110 | } 111 | 112 | @Override 113 | public void closeSignEditor(Player player, SignEditor signEditor) { 114 | Location loc = signEditor.getLocation(); 115 | signEditor.getPipeline().remove("SignGUI"); 116 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /1_16_R2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_16_R2 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.16.2-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_16_R2/src/main/java/de/rapha149/signgui/version/Wrapper1_16_R2.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_16_R2.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | public class Wrapper1_16_R2 implements VersionWrapper { 21 | 22 | @Override 23 | public Material getDefaultType() { 24 | return Material.OAK_SIGN; 25 | } 26 | 27 | @Override 28 | public List getSignTypes() { 29 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 30 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.setPosition(pos); 42 | sign.setColor(EnumColor.valueOf(color.toString())); 43 | for (int i = 0; i < lines.length; i++) 44 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 45 | 46 | boolean schedule = false; 47 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 48 | if (pipeline.names().contains("SignGUI")) { 49 | ChannelHandler handler = pipeline.get("SignGUI"); 50 | if (handler instanceof SignGUIChannelHandler) { 51 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 52 | signGUIHandler.close(); 53 | schedule = signGUIHandler.getBlockPosition().equals(pos); 54 | } 55 | 56 | if (pipeline.names().contains("SignGUI")) 57 | pipeline.remove("SignGUI"); 58 | } 59 | 60 | Runnable runnable = () -> { 61 | player.sendBlockChange(loc, type.createBlockData()); 62 | conn.sendPacket(sign.getUpdatePacket()); 63 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 64 | 65 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 66 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 67 | 68 | @Override 69 | public Object getBlockPosition() { 70 | return pos; 71 | } 72 | 73 | @Override 74 | public void close() { 75 | closeSignEditor(player, signEditor); 76 | } 77 | 78 | @Override 79 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 80 | try { 81 | if (packet instanceof PacketPlayInUpdateSign) { 82 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 83 | if (updateSign.b().equals(pos)) 84 | onFinish.accept(signEditor, updateSign.c()); 85 | } 86 | } catch (Exception e) { 87 | e.printStackTrace(); 88 | } 89 | 90 | out.add(packet); 91 | } 92 | }); 93 | }; 94 | 95 | if (schedule) 96 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 97 | else 98 | runnable.run(); 99 | } 100 | 101 | @Override 102 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 103 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 104 | for (int i = 0; i < lines.length; i++) 105 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 106 | 107 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 108 | conn.sendPacket(sign.getUpdatePacket()); 109 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 110 | } 111 | 112 | @Override 113 | public void closeSignEditor(Player player, SignEditor signEditor) { 114 | Location loc = signEditor.getLocation(); 115 | signEditor.getPipeline().remove("SignGUI"); 116 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /1_16_R3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_16_R3 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.16.4-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_16_R3/src/main/java/de/rapha149/signgui/version/Wrapper1_16_R3.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_16_R3.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | public class Wrapper1_16_R3 implements VersionWrapper { 21 | 22 | @Override 23 | public Material getDefaultType() { 24 | return Material.OAK_SIGN; 25 | } 26 | 27 | @Override 28 | public List getSignTypes() { 29 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 30 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.setPosition(pos); 42 | sign.setColor(EnumColor.valueOf(color.toString())); 43 | for (int i = 0; i < lines.length; i++) 44 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 45 | 46 | boolean schedule = false; 47 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 48 | if (pipeline.names().contains("SignGUI")) { 49 | ChannelHandler handler = pipeline.get("SignGUI"); 50 | if (handler instanceof SignGUIChannelHandler) { 51 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 52 | signGUIHandler.close(); 53 | schedule = signGUIHandler.getBlockPosition().equals(pos); 54 | } 55 | 56 | if (pipeline.names().contains("SignGUI")) 57 | pipeline.remove("SignGUI"); 58 | } 59 | 60 | Runnable runnable = () -> { 61 | player.sendBlockChange(loc, type.createBlockData()); 62 | conn.sendPacket(sign.getUpdatePacket()); 63 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 64 | 65 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 66 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 67 | 68 | @Override 69 | public Object getBlockPosition() { 70 | return pos; 71 | } 72 | 73 | @Override 74 | public void close() { 75 | closeSignEditor(player, signEditor); 76 | } 77 | 78 | @Override 79 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 80 | try { 81 | if (packet instanceof PacketPlayInUpdateSign) { 82 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 83 | if (updateSign.b().equals(pos)) 84 | onFinish.accept(signEditor, updateSign.c()); 85 | } 86 | } catch (Exception e) { 87 | e.printStackTrace(); 88 | } 89 | 90 | out.add(packet); 91 | } 92 | }); 93 | }; 94 | 95 | if (schedule) 96 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 97 | else 98 | runnable.run(); 99 | } 100 | 101 | @Override 102 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 103 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 104 | for (int i = 0; i < lines.length; i++) 105 | sign.a(i, new ChatComponentText(lines[i] != null ? lines[i] : "")); 106 | 107 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 108 | conn.sendPacket(sign.getUpdatePacket()); 109 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 110 | } 111 | 112 | @Override 113 | public void closeSignEditor(Player player, SignEditor signEditor) { 114 | Location loc = signEditor.getLocation(); 115 | signEditor.getPipeline().remove("SignGUI"); 116 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /1_17_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_17_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.17-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 16 41 | 16 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_17_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_17_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.chat.IChatBaseComponent; 10 | import net.minecraft.network.protocol.Packet; 11 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 12 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 13 | import net.minecraft.server.level.EntityPlayer; 14 | import net.minecraft.server.network.PlayerConnection; 15 | import net.minecraft.world.item.EnumColor; 16 | import net.minecraft.world.level.block.entity.TileEntitySign; 17 | import org.bukkit.DyeColor; 18 | import org.bukkit.Location; 19 | import org.bukkit.Material; 20 | import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; 21 | import org.bukkit.entity.Player; 22 | 23 | import java.util.Arrays; 24 | import java.util.List; 25 | import java.util.concurrent.TimeUnit; 26 | import java.util.function.BiConsumer; 27 | 28 | public class Wrapper1_17_R1 implements VersionWrapper { 29 | 30 | @Override 31 | public Material getDefaultType() { 32 | return Material.OAK_SIGN; 33 | } 34 | 35 | @Override 36 | public List getSignTypes() { 37 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 38 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN); 39 | } 40 | 41 | @Override 42 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 43 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 44 | PlayerConnection conn = p.b; 45 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 46 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 47 | 48 | TileEntitySign sign = new TileEntitySign(pos, null); 49 | sign.setColor(EnumColor.valueOf(color.toString())); 50 | sign.setHasGlowingText(glow); 51 | for (int i = 0; i < lines.length; i++) 52 | sign.a(i, IChatBaseComponent.a(lines[i])); 53 | 54 | boolean schedule = false; 55 | ChannelPipeline pipeline = conn.a.k.pipeline(); 56 | if (pipeline.names().contains("SignGUI")) { 57 | ChannelHandler handler = pipeline.get("SignGUI"); 58 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 59 | signGUIHandler.close(); 60 | schedule = signGUIHandler.getBlockPosition().equals(pos); 61 | } 62 | 63 | if (pipeline.names().contains("SignGUI")) 64 | pipeline.remove("SignGUI"); 65 | } 66 | 67 | Runnable runnable = () -> { 68 | player.sendBlockChange(loc, type.createBlockData()); 69 | conn.sendPacket(sign.getUpdatePacket()); 70 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 71 | 72 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 73 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 74 | 75 | @Override 76 | public Object getBlockPosition() { 77 | return pos; 78 | } 79 | 80 | @Override 81 | public void close() { 82 | closeSignEditor(player, signEditor); 83 | } 84 | 85 | @Override 86 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 87 | try { 88 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 89 | if (updateSign.b().equals(pos)) 90 | onFinish.accept(signEditor, updateSign.c()); 91 | } 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | 96 | out.add(packet); 97 | } 98 | }); 99 | }; 100 | 101 | if (schedule) 102 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 103 | else 104 | runnable.run(); 105 | } 106 | 107 | @Override 108 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 109 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 110 | for (int i = 0; i < lines.length; i++) 111 | sign.a(i, IChatBaseComponent.a(lines[i])); 112 | 113 | PlayerConnection conn = ((CraftPlayer) player).getHandle().b; 114 | conn.sendPacket(sign.getUpdatePacket()); 115 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 116 | } 117 | 118 | @Override 119 | public void closeSignEditor(Player player, SignEditor signEditor) { 120 | Location loc = signEditor.getLocation(); 121 | signEditor.getPipeline().remove("SignGUI"); 122 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /1_18_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_18_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.18-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 17 41 | 17 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_18_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_18_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.chat.IChatBaseComponent; 10 | import net.minecraft.network.protocol.Packet; 11 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 12 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 13 | import net.minecraft.server.level.EntityPlayer; 14 | import net.minecraft.server.network.PlayerConnection; 15 | import net.minecraft.world.item.EnumColor; 16 | import net.minecraft.world.level.block.entity.TileEntitySign; 17 | import org.bukkit.DyeColor; 18 | import org.bukkit.Location; 19 | import org.bukkit.Material; 20 | import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer; 21 | import org.bukkit.entity.Player; 22 | 23 | import java.util.Arrays; 24 | import java.util.List; 25 | import java.util.concurrent.TimeUnit; 26 | import java.util.function.BiConsumer; 27 | 28 | public class Wrapper1_18_R1 implements VersionWrapper { 29 | 30 | @Override 31 | public Material getDefaultType() { 32 | return Material.OAK_SIGN; 33 | } 34 | 35 | @Override 36 | public List getSignTypes() { 37 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 38 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN); 39 | } 40 | 41 | @Override 42 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 43 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 44 | PlayerConnection conn = p.b; 45 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 46 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 47 | 48 | TileEntitySign sign = new TileEntitySign(pos, null); 49 | sign.a(EnumColor.valueOf(color.toString())); 50 | sign.b(glow); 51 | for (int i = 0; i < lines.length; i++) 52 | sign.a(i, IChatBaseComponent.a(lines[i])); 53 | 54 | boolean schedule = false; 55 | ChannelPipeline pipeline = conn.a.k.pipeline(); 56 | if (pipeline.names().contains("SignGUI")) { 57 | ChannelHandler handler = pipeline.get("SignGUI"); 58 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 59 | signGUIHandler.close(); 60 | schedule = signGUIHandler.getBlockPosition().equals(pos); 61 | } 62 | 63 | if (pipeline.names().contains("SignGUI")) 64 | pipeline.remove("SignGUI"); 65 | } 66 | 67 | Runnable runnable = () -> { 68 | player.sendBlockChange(loc, type.createBlockData()); 69 | conn.a(sign.c()); 70 | conn.a(new PacketPlayOutOpenSignEditor(pos)); 71 | 72 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 73 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 74 | 75 | @Override 76 | public Object getBlockPosition() { 77 | return pos; 78 | } 79 | 80 | @Override 81 | public void close() { 82 | closeSignEditor(player, signEditor); 83 | } 84 | 85 | @Override 86 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 87 | try { 88 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 89 | if (updateSign.b().equals(pos)) 90 | onFinish.accept(signEditor, updateSign.c()); 91 | } 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | 96 | out.add(packet); 97 | } 98 | }); 99 | }; 100 | 101 | if (schedule) 102 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 103 | else 104 | runnable.run(); 105 | } 106 | 107 | @Override 108 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 109 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 110 | for (int i = 0; i < lines.length; i++) 111 | sign.a(i, IChatBaseComponent.a(lines[i])); 112 | 113 | PlayerConnection conn = ((CraftPlayer) player).getHandle().b; 114 | conn.a(sign.c()); 115 | conn.a(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 116 | } 117 | 118 | @Override 119 | public void closeSignEditor(Player player, SignEditor signEditor) { 120 | Location loc = signEditor.getLocation(); 121 | signEditor.getPipeline().remove("SignGUI"); 122 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /1_18_R2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_18_R2 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.18.2-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 17 41 | 17 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_18_R2/src/main/java/de/rapha149/signgui/version/Wrapper1_18_R2.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.chat.IChatBaseComponent; 10 | import net.minecraft.network.protocol.Packet; 11 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 12 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 13 | import net.minecraft.server.level.EntityPlayer; 14 | import net.minecraft.server.network.PlayerConnection; 15 | import net.minecraft.world.item.EnumColor; 16 | import net.minecraft.world.level.block.entity.TileEntitySign; 17 | import org.bukkit.DyeColor; 18 | import org.bukkit.Location; 19 | import org.bukkit.Material; 20 | import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; 21 | import org.bukkit.entity.Player; 22 | 23 | import java.util.Arrays; 24 | import java.util.List; 25 | import java.util.concurrent.TimeUnit; 26 | import java.util.function.BiConsumer; 27 | 28 | public class Wrapper1_18_R2 implements VersionWrapper { 29 | 30 | @Override 31 | public Material getDefaultType() { 32 | return Material.OAK_SIGN; 33 | } 34 | 35 | @Override 36 | public List getSignTypes() { 37 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 38 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN); 39 | } 40 | 41 | @Override 42 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 43 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 44 | PlayerConnection conn = p.b; 45 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 46 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 47 | 48 | TileEntitySign sign = new TileEntitySign(pos, null); 49 | sign.a(EnumColor.valueOf(color.toString())); 50 | sign.b(glow); 51 | for (int i = 0; i < lines.length; i++) 52 | sign.a(i, IChatBaseComponent.a(lines[i])); 53 | 54 | boolean schedule = false; 55 | ChannelPipeline pipeline = conn.a.m.pipeline(); 56 | if (pipeline.names().contains("SignGUI")) { 57 | ChannelHandler handler = pipeline.get("SignGUI"); 58 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 59 | signGUIHandler.close(); 60 | schedule = signGUIHandler.getBlockPosition().equals(pos); 61 | } 62 | 63 | if (pipeline.names().contains("SignGUI")) 64 | pipeline.remove("SignGUI"); 65 | } 66 | 67 | Runnable runnable = () -> { 68 | player.sendBlockChange(loc, type.createBlockData()); 69 | conn.a(sign.c()); 70 | conn.a(new PacketPlayOutOpenSignEditor(pos)); 71 | 72 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 73 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 74 | 75 | @Override 76 | public Object getBlockPosition() { 77 | return pos; 78 | } 79 | 80 | @Override 81 | public void close() { 82 | closeSignEditor(player, signEditor); 83 | } 84 | 85 | @Override 86 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 87 | try { 88 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 89 | if (updateSign.b().equals(pos)) 90 | onFinish.accept(signEditor, updateSign.c()); 91 | } 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | 96 | out.add(packet); 97 | } 98 | }); 99 | }; 100 | 101 | if (schedule) 102 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 103 | else 104 | runnable.run(); 105 | } 106 | 107 | @Override 108 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 109 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 110 | for (int i = 0; i < lines.length; i++) 111 | sign.a(i, IChatBaseComponent.a(lines[i])); 112 | 113 | PlayerConnection conn = ((CraftPlayer) player).getHandle().b; 114 | conn.a(sign.c()); 115 | conn.a(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 116 | } 117 | 118 | @Override 119 | public void closeSignEditor(Player player, SignEditor signEditor) { 120 | Location loc = signEditor.getLocation(); 121 | signEditor.getPipeline().remove("SignGUI"); 122 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /1_19_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_19_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.19-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 17 41 | 17 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_19_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_19_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.chat.IChatBaseComponent; 10 | import net.minecraft.network.protocol.Packet; 11 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 12 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 13 | import net.minecraft.server.level.EntityPlayer; 14 | import net.minecraft.server.network.PlayerConnection; 15 | import net.minecraft.world.item.EnumColor; 16 | import net.minecraft.world.level.block.entity.TileEntitySign; 17 | import org.bukkit.DyeColor; 18 | import org.bukkit.Location; 19 | import org.bukkit.Material; 20 | import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; 21 | import org.bukkit.entity.Player; 22 | 23 | import java.util.Arrays; 24 | import java.util.List; 25 | import java.util.concurrent.TimeUnit; 26 | import java.util.function.BiConsumer; 27 | 28 | public class Wrapper1_19_R1 implements VersionWrapper { 29 | 30 | @Override 31 | public Material getDefaultType() { 32 | return Material.OAK_SIGN; 33 | } 34 | 35 | @Override 36 | public List getSignTypes() { 37 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 38 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN); 39 | } 40 | 41 | @Override 42 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 43 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 44 | PlayerConnection conn = p.b; 45 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 46 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 47 | 48 | TileEntitySign sign = new TileEntitySign(pos, null); 49 | sign.a(EnumColor.valueOf(color.toString())); 50 | sign.b(glow); 51 | for (int i = 0; i < lines.length; i++) 52 | sign.a(i, IChatBaseComponent.a(lines[i])); 53 | 54 | boolean schedule = false; 55 | ChannelPipeline pipeline = conn.b.m.pipeline(); 56 | if (pipeline.names().contains("SignGUI")) { 57 | ChannelHandler handler = pipeline.get("SignGUI"); 58 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 59 | signGUIHandler.close(); 60 | schedule = signGUIHandler.getBlockPosition().equals(pos); 61 | } 62 | 63 | if (pipeline.names().contains("SignGUI")) 64 | pipeline.remove("SignGUI"); 65 | } 66 | 67 | Runnable runnable = () -> { 68 | player.sendBlockChange(loc, type.createBlockData()); 69 | conn.a(sign.c()); 70 | conn.a(new PacketPlayOutOpenSignEditor(pos)); 71 | 72 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 73 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 74 | 75 | @Override 76 | public Object getBlockPosition() { 77 | return pos; 78 | } 79 | 80 | @Override 81 | public void close() { 82 | closeSignEditor(player, signEditor); 83 | } 84 | 85 | @Override 86 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 87 | try { 88 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 89 | if (updateSign.b().equals(pos)) 90 | onFinish.accept(signEditor, updateSign.c()); 91 | } 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | 96 | out.add(packet); 97 | } 98 | }); 99 | }; 100 | 101 | if (schedule) 102 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 103 | else 104 | runnable.run(); 105 | } 106 | 107 | @Override 108 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 109 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 110 | for (int i = 0; i < lines.length; i++) 111 | sign.a(i, IChatBaseComponent.a(lines[i])); 112 | 113 | PlayerConnection conn = ((CraftPlayer) player).getHandle().b; 114 | conn.a(sign.c()); 115 | conn.a(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 116 | } 117 | 118 | @Override 119 | public void closeSignEditor(Player player, SignEditor signEditor) { 120 | Location loc = signEditor.getLocation(); 121 | signEditor.getPipeline().remove("SignGUI"); 122 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /1_19_R2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_19_R2 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.19.3-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 17 41 | 17 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_19_R2/src/main/java/de/rapha149/signgui/version/Wrapper1_19_R2.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.chat.IChatBaseComponent; 10 | import net.minecraft.network.protocol.Packet; 11 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 12 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 13 | import net.minecraft.server.level.EntityPlayer; 14 | import net.minecraft.server.network.PlayerConnection; 15 | import net.minecraft.world.item.EnumColor; 16 | import net.minecraft.world.level.block.entity.TileEntitySign; 17 | import org.bukkit.DyeColor; 18 | import org.bukkit.Location; 19 | import org.bukkit.Material; 20 | import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; 21 | import org.bukkit.entity.Player; 22 | 23 | import java.util.Arrays; 24 | import java.util.List; 25 | import java.util.concurrent.TimeUnit; 26 | import java.util.function.BiConsumer; 27 | 28 | public class Wrapper1_19_R2 implements VersionWrapper { 29 | 30 | @Override 31 | public Material getDefaultType() { 32 | return Material.OAK_SIGN; 33 | } 34 | 35 | @Override 36 | public List getSignTypes() { 37 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 38 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN); 39 | } 40 | 41 | @Override 42 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 43 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 44 | PlayerConnection conn = p.b; 45 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 46 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 47 | 48 | TileEntitySign sign = new TileEntitySign(pos, null); 49 | sign.a(EnumColor.valueOf(color.toString())); 50 | sign.b(glow); 51 | for (int i = 0; i < lines.length; i++) 52 | sign.a(i, IChatBaseComponent.a(lines[i])); 53 | 54 | boolean schedule = false; 55 | ChannelPipeline pipeline = conn.b.m.pipeline(); 56 | if (pipeline.names().contains("SignGUI")) { 57 | ChannelHandler handler = pipeline.get("SignGUI"); 58 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 59 | signGUIHandler.close(); 60 | schedule = signGUIHandler.getBlockPosition().equals(pos); 61 | } 62 | 63 | if (pipeline.names().contains("SignGUI")) 64 | pipeline.remove("SignGUI"); 65 | } 66 | 67 | Runnable runnable = () -> { 68 | player.sendBlockChange(loc, type.createBlockData()); 69 | conn.a(sign.f()); 70 | conn.a(new PacketPlayOutOpenSignEditor(pos)); 71 | 72 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 73 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 74 | 75 | @Override 76 | public Object getBlockPosition() { 77 | return pos; 78 | } 79 | 80 | @Override 81 | public void close() { 82 | closeSignEditor(player, signEditor); 83 | } 84 | 85 | @Override 86 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 87 | try { 88 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 89 | if (updateSign.b().equals(pos)) 90 | onFinish.accept(signEditor, updateSign.c()); 91 | } 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | 96 | out.add(packet); 97 | } 98 | }); 99 | }; 100 | 101 | if (schedule) 102 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 103 | else 104 | runnable.run(); 105 | } 106 | 107 | @Override 108 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 109 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 110 | for (int i = 0; i < lines.length; i++) 111 | sign.a(i, IChatBaseComponent.a(lines[i])); 112 | 113 | PlayerConnection conn = ((CraftPlayer) player).getHandle().b; 114 | conn.a(sign.f()); 115 | conn.a(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 116 | } 117 | 118 | @Override 119 | public void closeSignEditor(Player player, SignEditor signEditor) { 120 | Location loc = signEditor.getLocation(); 121 | signEditor.getPipeline().remove("SignGUI"); 122 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /1_19_R3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_19_R3 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.19.4-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 17 41 | 17 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_19_R3/src/main/java/de/rapha149/signgui/version/Wrapper1_19_R3.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.NetworkManager; 10 | import net.minecraft.network.chat.IChatBaseComponent; 11 | import net.minecraft.network.protocol.Packet; 12 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 13 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 14 | import net.minecraft.server.level.EntityPlayer; 15 | import net.minecraft.server.network.PlayerConnection; 16 | import net.minecraft.world.item.EnumColor; 17 | import net.minecraft.world.level.block.entity.TileEntitySign; 18 | import org.bukkit.DyeColor; 19 | import org.bukkit.Location; 20 | import org.bukkit.Material; 21 | import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; 22 | import org.bukkit.entity.Player; 23 | 24 | import java.lang.reflect.Field; 25 | import java.util.Arrays; 26 | import java.util.List; 27 | import java.util.concurrent.TimeUnit; 28 | import java.util.function.BiConsumer; 29 | 30 | public class Wrapper1_19_R3 implements VersionWrapper { 31 | 32 | private final Field NETWORK_MANAGER_FIELD; 33 | 34 | { 35 | Field networkManagerField = null; 36 | for (Field field : PlayerConnection.class.getDeclaredFields()) { 37 | if (field.getType() == NetworkManager.class) { 38 | field.setAccessible(true); 39 | networkManagerField = field; 40 | break; 41 | } 42 | } 43 | 44 | NETWORK_MANAGER_FIELD = networkManagerField; 45 | } 46 | 47 | @Override 48 | public Material getDefaultType() { 49 | return Material.OAK_SIGN; 50 | } 51 | 52 | @Override 53 | public List getSignTypes() { 54 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 55 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN); 56 | } 57 | 58 | @Override 59 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) throws IllegalAccessException { 60 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 61 | PlayerConnection conn = p.b; 62 | 63 | if (NETWORK_MANAGER_FIELD == null) 64 | throw new IllegalStateException("Unable to find NetworkManager field in PlayerConnection class."); 65 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) { 66 | NETWORK_MANAGER_FIELD.setAccessible(true); 67 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) 68 | throw new IllegalStateException("Unable to access NetworkManager field in PlayerConnection class."); 69 | } 70 | 71 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 72 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 73 | 74 | TileEntitySign sign = new TileEntitySign(pos, null); 75 | sign.a(EnumColor.valueOf(color.toString())); 76 | sign.b(glow); 77 | for (int i = 0; i < lines.length; i++) 78 | sign.a(i, IChatBaseComponent.a(lines[i])); 79 | 80 | boolean schedule = false; 81 | NetworkManager manager = (NetworkManager) NETWORK_MANAGER_FIELD.get(conn); 82 | ChannelPipeline pipeline = manager.m.pipeline(); 83 | if (pipeline.names().contains("SignGUI")) { 84 | ChannelHandler handler = pipeline.get("SignGUI"); 85 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 86 | signGUIHandler.close(); 87 | schedule = signGUIHandler.getBlockPosition().equals(pos); 88 | } 89 | 90 | if (pipeline.names().contains("SignGUI")) 91 | pipeline.remove("SignGUI"); 92 | } 93 | 94 | Runnable runnable = () -> { 95 | player.sendBlockChange(loc, type.createBlockData()); 96 | conn.a(sign.f()); 97 | conn.a(new PacketPlayOutOpenSignEditor(pos)); 98 | 99 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 100 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 101 | 102 | @Override 103 | public Object getBlockPosition() { 104 | return pos; 105 | } 106 | 107 | @Override 108 | public void close() { 109 | closeSignEditor(player, signEditor); 110 | } 111 | 112 | @Override 113 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 114 | try { 115 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 116 | if (updateSign.a().equals(pos)) 117 | onFinish.accept(signEditor, updateSign.c()); 118 | } 119 | } catch (Exception e) { 120 | e.printStackTrace(); 121 | } 122 | 123 | out.add(packet); 124 | } 125 | }); 126 | }; 127 | 128 | if (schedule) 129 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 130 | else 131 | runnable.run(); 132 | } 133 | 134 | @Override 135 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 136 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 137 | for (int i = 0; i < lines.length; i++) 138 | sign.a(i, IChatBaseComponent.a(lines[i])); 139 | 140 | PlayerConnection conn = ((CraftPlayer) player).getHandle().b; 141 | conn.a(sign.f()); 142 | conn.a(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 143 | } 144 | 145 | @Override 146 | public void closeSignEditor(Player player, SignEditor signEditor) { 147 | Location loc = signEditor.getLocation(); 148 | signEditor.getPipeline().remove("SignGUI"); 149 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /1_20_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_20_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.20-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 17 41 | 17 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_20_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_20_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.NetworkManager; 10 | import net.minecraft.network.chat.IChatBaseComponent; 11 | import net.minecraft.network.protocol.Packet; 12 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 13 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 14 | import net.minecraft.server.level.EntityPlayer; 15 | import net.minecraft.server.network.PlayerConnection; 16 | import net.minecraft.world.item.EnumColor; 17 | import net.minecraft.world.level.block.entity.SignText; 18 | import net.minecraft.world.level.block.entity.TileEntitySign; 19 | import org.bukkit.DyeColor; 20 | import org.bukkit.Location; 21 | import org.bukkit.Material; 22 | import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; 23 | import org.bukkit.entity.Player; 24 | 25 | import java.lang.reflect.Field; 26 | import java.util.Arrays; 27 | import java.util.List; 28 | import java.util.concurrent.TimeUnit; 29 | import java.util.function.BiConsumer; 30 | 31 | public class Wrapper1_20_R1 implements VersionWrapper { 32 | 33 | private final Field NETWORK_MANAGER_FIELD; 34 | 35 | { 36 | Field networkManagerField = null; 37 | for (Field field : PlayerConnection.class.getDeclaredFields()) { 38 | if (field.getType() == NetworkManager.class) { 39 | field.setAccessible(true); 40 | networkManagerField = field; 41 | break; 42 | } 43 | } 44 | 45 | NETWORK_MANAGER_FIELD = networkManagerField; 46 | } 47 | 48 | @Override 49 | public Material getDefaultType() { 50 | return Material.OAK_SIGN; 51 | } 52 | 53 | @Override 54 | public List getSignTypes() { 55 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 56 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN, 57 | Material.CHERRY_SIGN, Material.MANGROVE_SIGN, Material.BAMBOO_SIGN 58 | ); 59 | } 60 | 61 | @Override 62 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) throws IllegalAccessException { 63 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 64 | PlayerConnection conn = p.c; 65 | 66 | if (NETWORK_MANAGER_FIELD == null) 67 | throw new IllegalStateException("Unable to find NetworkManager field in PlayerConnection class."); 68 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) { 69 | NETWORK_MANAGER_FIELD.setAccessible(true); 70 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) 71 | throw new IllegalStateException("Unable to access NetworkManager field in PlayerConnection class."); 72 | } 73 | 74 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 75 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 76 | 77 | TileEntitySign sign = new TileEntitySign(pos, null); 78 | SignText signText = sign.a(true) // flag = front/back of sign 79 | .a(EnumColor.valueOf(color.toString())) 80 | .a(glow); 81 | for (int i = 0; i < lines.length; i++) 82 | signText = signText.a(i, IChatBaseComponent.a(lines[i])); 83 | sign.a(signText, true); 84 | 85 | boolean schedule = false; 86 | NetworkManager manager = (NetworkManager) NETWORK_MANAGER_FIELD.get(conn); 87 | ChannelPipeline pipeline = manager.m.pipeline(); 88 | if (pipeline.names().contains("SignGUI")) { 89 | ChannelHandler handler = pipeline.get("SignGUI"); 90 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 91 | signGUIHandler.close(); 92 | schedule = signGUIHandler.getBlockPosition().equals(pos); 93 | } 94 | 95 | if (pipeline.names().contains("SignGUI")) 96 | pipeline.remove("SignGUI"); 97 | } 98 | 99 | Runnable runnable = () -> { 100 | player.sendBlockChange(loc, type.createBlockData()); 101 | conn.a(sign.j()); 102 | conn.a(new PacketPlayOutOpenSignEditor(pos, true)); // flag = front/back of sign 103 | 104 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 105 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 106 | 107 | @Override 108 | public Object getBlockPosition() { 109 | return pos; 110 | } 111 | 112 | @Override 113 | public void close() { 114 | closeSignEditor(player, signEditor); 115 | } 116 | 117 | @Override 118 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 119 | try { 120 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 121 | if (updateSign.a().equals(pos)) 122 | onFinish.accept(signEditor, updateSign.d()); 123 | } 124 | } catch (Exception e) { 125 | e.printStackTrace(); 126 | } 127 | 128 | out.add(packet); 129 | } 130 | }); 131 | }; 132 | 133 | if (schedule) 134 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 135 | else 136 | runnable.run(); 137 | } 138 | 139 | @Override 140 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 141 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 142 | 143 | SignText newSignText = sign.a(true); 144 | for (int i = 0; i < lines.length; i++) 145 | newSignText = newSignText.a(i, IChatBaseComponent.a(lines[i])); 146 | sign.a(newSignText, true); 147 | 148 | PlayerConnection conn = ((CraftPlayer) player).getHandle().c; 149 | conn.a(sign.j()); 150 | conn.a(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition(), true)); 151 | } 152 | 153 | @Override 154 | public void closeSignEditor(Player player, SignEditor signEditor) { 155 | Location loc = signEditor.getLocation(); 156 | signEditor.getPipeline().remove("SignGUI"); 157 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /1_20_R2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_20_R2 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.20.2-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 17 41 | 17 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_20_R2/src/main/java/de/rapha149/signgui/version/Wrapper1_20_R2.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.NetworkManager; 10 | import net.minecraft.network.chat.IChatBaseComponent; 11 | import net.minecraft.network.protocol.Packet; 12 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 13 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 14 | import net.minecraft.server.level.EntityPlayer; 15 | import net.minecraft.server.network.PlayerConnection; 16 | import net.minecraft.server.network.ServerCommonPacketListenerImpl; 17 | import net.minecraft.world.item.EnumColor; 18 | import net.minecraft.world.level.block.entity.SignText; 19 | import net.minecraft.world.level.block.entity.TileEntitySign; 20 | import org.bukkit.DyeColor; 21 | import org.bukkit.Location; 22 | import org.bukkit.Material; 23 | import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; 24 | import org.bukkit.entity.Player; 25 | 26 | import java.lang.reflect.Field; 27 | import java.util.Arrays; 28 | import java.util.List; 29 | import java.util.concurrent.TimeUnit; 30 | import java.util.function.BiConsumer; 31 | 32 | public class Wrapper1_20_R2 implements VersionWrapper { 33 | 34 | private final Field NETWORK_MANAGER_FIELD; 35 | 36 | { 37 | Field networkManagerField = null; 38 | for (Field field : ServerCommonPacketListenerImpl.class.getDeclaredFields()) { 39 | if (field.getType() == NetworkManager.class) { 40 | field.setAccessible(true); 41 | networkManagerField = field; 42 | break; 43 | } 44 | } 45 | 46 | NETWORK_MANAGER_FIELD = networkManagerField; 47 | } 48 | 49 | @Override 50 | public Material getDefaultType() { 51 | return Material.OAK_SIGN; 52 | } 53 | 54 | @Override 55 | public List getSignTypes() { 56 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 57 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN, 58 | Material.CHERRY_SIGN, Material.MANGROVE_SIGN, Material.BAMBOO_SIGN 59 | ); 60 | } 61 | 62 | @Override 63 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) throws IllegalAccessException { 64 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 65 | PlayerConnection conn = p.c; 66 | 67 | if (NETWORK_MANAGER_FIELD == null) 68 | throw new IllegalStateException("Unable to find NetworkManager field in PlayerConnection class."); 69 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) { 70 | NETWORK_MANAGER_FIELD.setAccessible(true); 71 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) 72 | throw new IllegalStateException("Unable to access NetworkManager field in PlayerConnection class."); 73 | } 74 | 75 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 76 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 77 | 78 | TileEntitySign sign = new TileEntitySign(pos, null); 79 | SignText signText = sign.a(true) // flag = front/back of sign 80 | .a(EnumColor.valueOf(color.toString())) 81 | .a(glow); 82 | for (int i = 0; i < lines.length; i++) 83 | signText = signText.a(i, IChatBaseComponent.a(lines[i])); 84 | sign.a(signText, true); 85 | 86 | boolean schedule = false; 87 | NetworkManager manager = (NetworkManager) NETWORK_MANAGER_FIELD.get(conn); 88 | ChannelPipeline pipeline = manager.n.pipeline(); 89 | if (pipeline.names().contains("SignGUI")) { 90 | ChannelHandler handler = pipeline.get("SignGUI"); 91 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 92 | signGUIHandler.close(); 93 | schedule = signGUIHandler.getBlockPosition().equals(pos); 94 | } 95 | 96 | if (pipeline.names().contains("SignGUI")) 97 | pipeline.remove("SignGUI"); 98 | } 99 | 100 | Runnable runnable = () -> { 101 | player.sendBlockChange(loc, type.createBlockData()); 102 | conn.b(sign.j()); 103 | conn.b(new PacketPlayOutOpenSignEditor(pos, true)); // flag = front/back of sign 104 | 105 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 106 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 107 | 108 | @Override 109 | public Object getBlockPosition() { 110 | return pos; 111 | } 112 | 113 | @Override 114 | public void close() { 115 | closeSignEditor(player, signEditor); 116 | } 117 | 118 | @Override 119 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 120 | try { 121 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 122 | if (updateSign.a().equals(pos)) 123 | onFinish.accept(signEditor, updateSign.e()); 124 | } 125 | } catch (Exception e) { 126 | e.printStackTrace(); 127 | } 128 | 129 | out.add(packet); 130 | } 131 | }); 132 | }; 133 | 134 | if (schedule) 135 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 136 | else 137 | runnable.run(); 138 | } 139 | 140 | @Override 141 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 142 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 143 | 144 | SignText newSignText = sign.a(true); 145 | for (int i = 0; i < lines.length; i++) 146 | newSignText = newSignText.a(i, IChatBaseComponent.a(lines[i])); 147 | sign.a(newSignText, true); 148 | 149 | PlayerConnection conn = ((CraftPlayer) player).getHandle().c; 150 | conn.b(sign.j()); 151 | conn.b(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition(), true)); 152 | } 153 | 154 | @Override 155 | public void closeSignEditor(Player player, SignEditor signEditor) { 156 | Location loc = signEditor.getLocation(); 157 | signEditor.getPipeline().remove("SignGUI"); 158 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /1_20_R3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_20_R3 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.20.3-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 17 41 | 17 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_20_R3/src/main/java/de/rapha149/signgui/version/Wrapper1_20_R3.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.NetworkManager; 10 | import net.minecraft.network.chat.IChatBaseComponent; 11 | import net.minecraft.network.protocol.Packet; 12 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 13 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 14 | import net.minecraft.server.level.EntityPlayer; 15 | import net.minecraft.server.network.PlayerConnection; 16 | import net.minecraft.server.network.ServerCommonPacketListenerImpl; 17 | import net.minecraft.world.item.EnumColor; 18 | import net.minecraft.world.level.block.entity.SignText; 19 | import net.minecraft.world.level.block.entity.TileEntitySign; 20 | import org.bukkit.DyeColor; 21 | import org.bukkit.Location; 22 | import org.bukkit.Material; 23 | import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; 24 | import org.bukkit.entity.Player; 25 | 26 | import java.lang.reflect.Field; 27 | import java.util.Arrays; 28 | import java.util.List; 29 | import java.util.concurrent.TimeUnit; 30 | import java.util.function.BiConsumer; 31 | 32 | public class Wrapper1_20_R3 implements VersionWrapper { 33 | 34 | private final Field NETWORK_MANAGER_FIELD; 35 | 36 | { 37 | Field networkManagerField = null; 38 | for (Field field : ServerCommonPacketListenerImpl.class.getDeclaredFields()) { 39 | if (field.getType() == NetworkManager.class) { 40 | field.setAccessible(true); 41 | networkManagerField = field; 42 | break; 43 | } 44 | } 45 | 46 | NETWORK_MANAGER_FIELD = networkManagerField; 47 | } 48 | 49 | @Override 50 | public Material getDefaultType() { 51 | return Material.OAK_SIGN; 52 | } 53 | 54 | @Override 55 | public List getSignTypes() { 56 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 57 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN, 58 | Material.CHERRY_SIGN, Material.MANGROVE_SIGN, Material.BAMBOO_SIGN 59 | ); 60 | } 61 | 62 | @Override 63 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) throws IllegalAccessException { 64 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 65 | PlayerConnection conn = p.c; 66 | 67 | if (NETWORK_MANAGER_FIELD == null) 68 | throw new IllegalStateException("Unable to find NetworkManager field in PlayerConnection class."); 69 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) { 70 | NETWORK_MANAGER_FIELD.setAccessible(true); 71 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) 72 | throw new IllegalStateException("Unable to access NetworkManager field in PlayerConnection class."); 73 | } 74 | 75 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 76 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 77 | 78 | TileEntitySign sign = new TileEntitySign(pos, null); 79 | SignText signText = sign.a(true) // flag = front/back of sign 80 | .a(EnumColor.valueOf(color.toString())) 81 | .a(glow); 82 | for (int i = 0; i < lines.length; i++) 83 | signText = signText.a(i, IChatBaseComponent.a(lines[i])); 84 | sign.a(signText, true); 85 | 86 | boolean schedule = false; 87 | NetworkManager manager = (NetworkManager) NETWORK_MANAGER_FIELD.get(conn); 88 | ChannelPipeline pipeline = manager.n.pipeline(); 89 | if (pipeline.names().contains("SignGUI")) { 90 | ChannelHandler handler = pipeline.get("SignGUI"); 91 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 92 | signGUIHandler.close(); 93 | schedule = signGUIHandler.getBlockPosition().equals(pos); 94 | } 95 | 96 | if (pipeline.names().contains("SignGUI")) 97 | pipeline.remove("SignGUI"); 98 | } 99 | 100 | Runnable runnable = () -> { 101 | player.sendBlockChange(loc, type.createBlockData()); 102 | conn.b(sign.j()); 103 | conn.b(new PacketPlayOutOpenSignEditor(pos, true)); // flag = front/back of sign 104 | 105 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 106 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 107 | 108 | @Override 109 | public Object getBlockPosition() { 110 | return pos; 111 | } 112 | 113 | @Override 114 | public void close() { 115 | closeSignEditor(player, signEditor); 116 | } 117 | 118 | @Override 119 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 120 | try { 121 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 122 | if (updateSign.a().equals(pos)) 123 | onFinish.accept(signEditor, updateSign.e()); 124 | } 125 | } catch (Exception e) { 126 | e.printStackTrace(); 127 | } 128 | 129 | out.add(packet); 130 | } 131 | }); 132 | }; 133 | 134 | if (schedule) 135 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 136 | else 137 | runnable.run(); 138 | } 139 | 140 | @Override 141 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 142 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 143 | 144 | SignText newSignText = sign.a(true); 145 | for (int i = 0; i < lines.length; i++) 146 | newSignText = newSignText.a(i, IChatBaseComponent.a(lines[i])); 147 | sign.a(newSignText, true); 148 | 149 | PlayerConnection conn = ((CraftPlayer) player).getHandle().c; 150 | conn.b(sign.j()); 151 | conn.b(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition(), true)); 152 | } 153 | 154 | @Override 155 | public void closeSignEditor(Player player, SignEditor signEditor) { 156 | Location loc = signEditor.getLocation(); 157 | signEditor.getPipeline().remove("SignGUI"); 158 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /1_20_R4/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_20_R4 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.20.5-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 21 41 | 21 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_20_R4/src/main/java/de/rapha149/signgui/version/Wrapper1_20_R4.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.core.BlockPosition; 9 | import net.minecraft.network.NetworkManager; 10 | import net.minecraft.network.chat.IChatBaseComponent; 11 | import net.minecraft.network.protocol.Packet; 12 | import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; 13 | import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor; 14 | import net.minecraft.server.level.EntityPlayer; 15 | import net.minecraft.server.network.PlayerConnection; 16 | import net.minecraft.server.network.ServerCommonPacketListenerImpl; 17 | import net.minecraft.world.item.EnumColor; 18 | import net.minecraft.world.level.World; 19 | import net.minecraft.world.level.block.entity.SignText; 20 | import net.minecraft.world.level.block.entity.TileEntitySign; 21 | import org.bukkit.DyeColor; 22 | import org.bukkit.Location; 23 | import org.bukkit.Material; 24 | import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer; 25 | import org.bukkit.entity.Player; 26 | 27 | import java.lang.reflect.Field; 28 | import java.util.Arrays; 29 | import java.util.List; 30 | import java.util.concurrent.TimeUnit; 31 | import java.util.function.BiConsumer; 32 | 33 | public class Wrapper1_20_R4 implements VersionWrapper { 34 | 35 | private final Field NETWORK_MANAGER_FIELD; 36 | 37 | { 38 | Field networkManagerField = null; 39 | for (Field field : ServerCommonPacketListenerImpl.class.getDeclaredFields()) { 40 | if (field.getType() == NetworkManager.class) { 41 | field.setAccessible(true); 42 | networkManagerField = field; 43 | break; 44 | } 45 | } 46 | 47 | NETWORK_MANAGER_FIELD = networkManagerField; 48 | } 49 | 50 | @Override 51 | public Material getDefaultType() { 52 | return Material.OAK_SIGN; 53 | } 54 | 55 | @Override 56 | public List getSignTypes() { 57 | return Arrays.asList(Material.OAK_SIGN, Material.BIRCH_SIGN, Material.SPRUCE_SIGN, Material.JUNGLE_SIGN, 58 | Material.ACACIA_SIGN, Material.DARK_OAK_SIGN, Material.CRIMSON_SIGN, Material.WARPED_SIGN, 59 | Material.CHERRY_SIGN, Material.MANGROVE_SIGN, Material.BAMBOO_SIGN 60 | ); 61 | } 62 | 63 | @Override 64 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) throws IllegalAccessException { 65 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 66 | PlayerConnection conn = p.c; 67 | 68 | if (NETWORK_MANAGER_FIELD == null) 69 | throw new IllegalStateException("Unable to find NetworkManager field in PlayerConnection class."); 70 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) { 71 | NETWORK_MANAGER_FIELD.setAccessible(true); 72 | if (!NETWORK_MANAGER_FIELD.canAccess(conn)) 73 | throw new IllegalStateException("Unable to access NetworkManager field in PlayerConnection class."); 74 | } 75 | 76 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 77 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 78 | 79 | TileEntitySign sign = new TileEntitySign(pos, null); 80 | SignText signText = sign.a(true) // flag = front/back of sign 81 | .a(EnumColor.valueOf(color.toString())) 82 | .a(glow); 83 | for (int i = 0; i < lines.length; i++) 84 | signText = signText.a(i, IChatBaseComponent.a(lines[i])); 85 | sign.a(signText, true); 86 | 87 | boolean schedule = false; 88 | NetworkManager manager = (NetworkManager) NETWORK_MANAGER_FIELD.get(conn); 89 | ChannelPipeline pipeline = manager.n.pipeline(); 90 | if (pipeline.names().contains("SignGUI")) { 91 | ChannelHandler handler = pipeline.get("SignGUI"); 92 | if (handler instanceof SignGUIChannelHandler signGUIHandler) { 93 | signGUIHandler.close(); 94 | schedule = signGUIHandler.getBlockPosition().equals(pos); 95 | } 96 | 97 | if (pipeline.names().contains("SignGUI")) 98 | pipeline.remove("SignGUI"); 99 | } 100 | 101 | Runnable runnable = () -> { 102 | player.sendBlockChange(loc, type.createBlockData()); 103 | sign.a(p.dP()); 104 | conn.b(sign.l()); 105 | sign.a((World) null); 106 | conn.b(new PacketPlayOutOpenSignEditor(pos, true)); // flag = front/back of sign 107 | 108 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 109 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 110 | 111 | @Override 112 | public Object getBlockPosition() { 113 | return pos; 114 | } 115 | 116 | @Override 117 | public void close() { 118 | closeSignEditor(player, signEditor); 119 | } 120 | 121 | @Override 122 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 123 | try { 124 | if (packet instanceof PacketPlayInUpdateSign updateSign) { 125 | if (updateSign.b().equals(pos)) 126 | onFinish.accept(signEditor, updateSign.f()); 127 | } 128 | } catch (Exception e) { 129 | e.printStackTrace(); 130 | } 131 | 132 | out.add(packet); 133 | } 134 | }); 135 | }; 136 | 137 | if (schedule) 138 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 139 | else 140 | runnable.run(); 141 | } 142 | 143 | @Override 144 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 145 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 146 | 147 | SignText newSignText = sign.a(true); 148 | for (int i = 0; i < lines.length; i++) 149 | newSignText = newSignText.a(i, IChatBaseComponent.a(lines[i])); 150 | sign.a(newSignText, true); 151 | 152 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 153 | PlayerConnection conn = p.c; 154 | sign.a(p.dP()); 155 | conn.b(sign.l()); 156 | sign.a((World) null); 157 | conn.b(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition(), true)); 158 | } 159 | 160 | @Override 161 | public void closeSignEditor(Player player, SignEditor signEditor) { 162 | Location loc = signEditor.getLocation(); 163 | signEditor.getPipeline().remove("SignGUI"); 164 | player.sendBlockChange(loc, loc.getBlock().getBlockData()); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /1_21_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_21_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.21.1-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 21 41 | 21 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_21_R2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_21_R2 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.21.3-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 21 41 | 21 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_21_R3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_21_R3 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.21.4-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 21 41 | 21 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_21_R4/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_21_R4 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.21.5-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.8.1 39 | 40 | 21 41 | 21 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /1_8_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_8_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.8-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_8_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_8_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.Channel; 6 | import io.netty.channel.ChannelHandler; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.channel.ChannelPipeline; 9 | import net.minecraft.server.v1_8_R1.*; 10 | import org.bukkit.DyeColor; 11 | import org.bukkit.Location; 12 | import org.bukkit.Material; 13 | import org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer; 14 | import org.bukkit.entity.Player; 15 | 16 | import java.lang.reflect.Field; 17 | import java.util.Arrays; 18 | import java.util.List; 19 | import java.util.concurrent.TimeUnit; 20 | import java.util.function.BiConsumer; 21 | 22 | @SuppressWarnings("deprecation") 23 | public class Wrapper1_8_R1 implements VersionWrapper { 24 | 25 | @Override 26 | public Material getDefaultType() { 27 | return Material.SIGN_POST; 28 | } 29 | 30 | @Override 31 | public List getSignTypes() { 32 | return Arrays.asList(Material.SIGN_POST); 33 | } 34 | 35 | @Override 36 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) throws NoSuchFieldException, IllegalAccessException { 37 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 38 | PlayerConnection conn = p.playerConnection; 39 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 40 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 41 | 42 | TileEntitySign sign = new TileEntitySign(); 43 | sign.a(pos); 44 | for (int i = 0; i < lines.length; i++) 45 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 46 | 47 | Field field = conn.networkManager.getClass().getDeclaredField("i"); 48 | field.setAccessible(true); 49 | ChannelPipeline pipeline = ((Channel) field.get(conn.networkManager)).pipeline(); 50 | field.setAccessible(false); 51 | 52 | boolean schedule = false; 53 | if (pipeline.names().contains("SignGUI")) { 54 | ChannelHandler handler = pipeline.get("SignGUI"); 55 | if (handler instanceof SignGUIChannelHandler) { 56 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 57 | signGUIHandler.close(); 58 | schedule = signGUIHandler.getBlockPosition().equals(pos); 59 | } 60 | 61 | if (pipeline.names().contains("SignGUI")) 62 | pipeline.remove("SignGUI"); 63 | } 64 | 65 | Runnable runnable = () -> { 66 | player.sendBlockChange(loc, type, (byte) 0); 67 | conn.sendPacket(sign.getUpdatePacket()); 68 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 69 | 70 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 71 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler() { 72 | 73 | @Override 74 | public Object getBlockPosition() { 75 | return pos; 76 | } 77 | 78 | @Override 79 | public void close() { 80 | closeSignEditor(player, signEditor); 81 | } 82 | 83 | @Override 84 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 85 | try { 86 | if (packet instanceof PacketPlayInUpdateSign) { 87 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 88 | if (updateSign.a().equals(pos)) 89 | onFinish.accept(signEditor, Arrays.stream(updateSign.b()).map(IChatBaseComponent::getText).toArray(String[]::new)); 90 | } 91 | } catch (Exception e) { 92 | e.printStackTrace(); 93 | } 94 | 95 | out.add(packet); 96 | } 97 | }); 98 | }; 99 | 100 | if (schedule) 101 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 102 | else 103 | runnable.run(); 104 | } 105 | 106 | @Override 107 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 108 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 109 | for (int i = 0; i < lines.length; i++) 110 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 111 | 112 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 113 | conn.sendPacket(sign.getUpdatePacket()); 114 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 115 | } 116 | 117 | @Override 118 | public void closeSignEditor(Player player, SignEditor signEditor) { 119 | Location loc = signEditor.getLocation(); 120 | signEditor.getPipeline().remove("SignGUI"); 121 | player.sendBlockChange(loc, loc.getBlock().getType(), loc.getBlock().getData()); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /1_8_R2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_8_R2 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.8.3-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_8_R2/src/main/java/de/rapha149/signgui/version/Wrapper1_8_R2.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_8_R2.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_8_R2.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | @SuppressWarnings("deprecation") 21 | public class Wrapper1_8_R2 implements VersionWrapper { 22 | 23 | @Override 24 | public Material getDefaultType() { 25 | return Material.SIGN_POST; 26 | } 27 | 28 | @Override 29 | public List getSignTypes() { 30 | return Arrays.asList(Material.SIGN_POST); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.a(pos); 42 | for (int i = 0; i < lines.length; i++) 43 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 44 | 45 | boolean schedule = false; 46 | ChannelPipeline pipeline = conn.networkManager.k.pipeline(); 47 | if (pipeline.names().contains("SignGUI")) { 48 | ChannelHandler handler = pipeline.get("SignGUI"); 49 | if (handler instanceof SignGUIChannelHandler) { 50 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 51 | signGUIHandler.close(); 52 | schedule = signGUIHandler.getBlockPosition().equals(pos); 53 | } 54 | 55 | if (pipeline.names().contains("SignGUI")) 56 | pipeline.remove("SignGUI"); 57 | } 58 | 59 | Runnable runnable = () -> { 60 | player.sendBlockChange(loc, type, (byte) 0); 61 | conn.sendPacket(sign.getUpdatePacket()); 62 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 63 | 64 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 65 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 66 | 67 | @Override 68 | public Object getBlockPosition() { 69 | return pos; 70 | } 71 | 72 | @Override 73 | public void close() { 74 | closeSignEditor(player, signEditor); 75 | } 76 | 77 | @Override 78 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 79 | try { 80 | if (packet instanceof PacketPlayInUpdateSign) { 81 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 82 | if (updateSign.a().equals(pos)) 83 | onFinish.accept(signEditor, Arrays.stream(updateSign.b()).map(IChatBaseComponent::getText).toArray(String[]::new)); 84 | } 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | } 88 | 89 | out.add(packet); 90 | } 91 | }); 92 | }; 93 | 94 | if (schedule) 95 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 96 | else 97 | runnable.run(); 98 | } 99 | 100 | @Override 101 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 102 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 103 | for (int i = 0; i < lines.length; i++) 104 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 105 | 106 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 107 | conn.sendPacket(sign.getUpdatePacket()); 108 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 109 | } 110 | 111 | @Override 112 | public void closeSignEditor(Player player, SignEditor signEditor) { 113 | Location loc = signEditor.getLocation(); 114 | signEditor.getPipeline().remove("SignGUI"); 115 | player.sendBlockChange(loc, loc.getBlock().getType(), loc.getBlock().getData()); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /1_8_R3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_8_R3 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.8.8-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_8_R3/src/main/java/de/rapha149/signgui/version/Wrapper1_8_R3.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_8_R3.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | @SuppressWarnings("deprecation") 21 | public class Wrapper1_8_R3 implements VersionWrapper { 22 | 23 | @Override 24 | public Material getDefaultType() { 25 | return Material.SIGN_POST; 26 | } 27 | 28 | @Override 29 | public List getSignTypes() { 30 | return Arrays.asList(Material.SIGN_POST); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.a(pos); 42 | for (int i = 0; i < lines.length; i++) 43 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 44 | 45 | boolean schedule = false; 46 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 47 | if (pipeline.names().contains("SignGUI")) { 48 | ChannelHandler handler = pipeline.get("SignGUI"); 49 | if (handler instanceof SignGUIChannelHandler) { 50 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 51 | signGUIHandler.close(); 52 | schedule = signGUIHandler.getBlockPosition().equals(pos); 53 | } 54 | 55 | if (pipeline.names().contains("SignGUI")) 56 | pipeline.remove("SignGUI"); 57 | } 58 | 59 | Runnable runnable = () -> { 60 | player.sendBlockChange(loc, type, (byte) 0); 61 | conn.sendPacket(sign.getUpdatePacket()); 62 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 63 | 64 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 65 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 66 | 67 | @Override 68 | public Object getBlockPosition() { 69 | return pos; 70 | } 71 | 72 | @Override 73 | public void close() { 74 | closeSignEditor(player, signEditor); 75 | } 76 | 77 | @Override 78 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 79 | try { 80 | if (packet instanceof PacketPlayInUpdateSign) { 81 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 82 | if (updateSign.a().equals(pos)) 83 | onFinish.accept(signEditor, Arrays.stream(updateSign.b()).map(IChatBaseComponent::getText).toArray(String[]::new)); 84 | } 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | } 88 | 89 | out.add(packet); 90 | } 91 | }); 92 | }; 93 | 94 | if (schedule) 95 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 96 | else 97 | runnable.run(); 98 | } 99 | 100 | @Override 101 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 102 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 103 | for (int i = 0; i < lines.length; i++) 104 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 105 | 106 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 107 | conn.sendPacket(sign.getUpdatePacket()); 108 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 109 | } 110 | 111 | @Override 112 | public void closeSignEditor(Player player, SignEditor signEditor) { 113 | Location loc = signEditor.getLocation(); 114 | signEditor.getPipeline().remove("SignGUI"); 115 | player.sendBlockChange(loc, loc.getBlock().getType(), loc.getBlock().getData()); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /1_9_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_9_R1 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.9-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_9_R1/src/main/java/de/rapha149/signgui/version/Wrapper1_9_R1.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_9_R1.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | @SuppressWarnings("deprecation") 21 | public class Wrapper1_9_R1 implements VersionWrapper { 22 | 23 | @Override 24 | public Material getDefaultType() { 25 | return Material.SIGN_POST; 26 | } 27 | 28 | @Override 29 | public List getSignTypes() { 30 | return Arrays.asList(Material.SIGN_POST); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.a(pos); 42 | for (int i = 0; i < lines.length; i++) 43 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 44 | 45 | boolean schedule = false; 46 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 47 | if (pipeline.names().contains("SignGUI")) { 48 | ChannelHandler handler = pipeline.get("SignGUI"); 49 | if (handler instanceof SignGUIChannelHandler) { 50 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 51 | signGUIHandler.close(); 52 | schedule = signGUIHandler.getBlockPosition().equals(pos); 53 | } 54 | 55 | if (pipeline.names().contains("SignGUI")) 56 | pipeline.remove("SignGUI"); 57 | } 58 | 59 | Runnable runnable = () -> { 60 | player.sendBlockChange(loc, type, (byte) 0); 61 | conn.sendPacket(sign.getUpdatePacket()); 62 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 63 | 64 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 65 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 66 | 67 | @Override 68 | public Object getBlockPosition() { 69 | return pos; 70 | } 71 | 72 | @Override 73 | public void close() { 74 | closeSignEditor(player, signEditor); 75 | } 76 | 77 | @Override 78 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 79 | try { 80 | if (packet instanceof PacketPlayInUpdateSign) { 81 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 82 | if (updateSign.a().equals(pos)) 83 | onFinish.accept(signEditor, updateSign.b()); 84 | } 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | } 88 | 89 | out.add(packet); 90 | } 91 | }); 92 | }; 93 | 94 | if (schedule) 95 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 96 | else 97 | runnable.run(); 98 | } 99 | 100 | @Override 101 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 102 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 103 | for (int i = 0; i < lines.length; i++) 104 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 105 | 106 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 107 | conn.sendPacket(sign.getUpdatePacket()); 108 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 109 | } 110 | 111 | @Override 112 | public void closeSignEditor(Player player, SignEditor signEditor) { 113 | Location loc = signEditor.getLocation(); 114 | signEditor.getPipeline().remove("SignGUI"); 115 | player.sendBlockChange(loc, loc.getBlock().getType(), loc.getBlock().getData()); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /1_9_R2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | de.rapha149.signgui 8 | 2.5.2 9 | 10 | 4.0.0 11 | 12 | signgui-1_9_R2 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | org.spigotmc 21 | spigot 22 | 1.9.4-R0.1-SNAPSHOT 23 | provided 24 | 25 | 26 | de.rapha149.signgui 27 | signgui-wrapper 28 | ${project.parent.version} 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /1_9_R2/src/main/java/de/rapha149/signgui/version/Wrapper1_9_R2.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import de.rapha149.signgui.SignGUIChannelHandler; 5 | import io.netty.channel.ChannelHandler; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelPipeline; 8 | import net.minecraft.server.v1_9_R2.*; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer; 13 | import org.bukkit.entity.Player; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.function.BiConsumer; 19 | 20 | @SuppressWarnings("deprecation") 21 | public class Wrapper1_9_R2 implements VersionWrapper { 22 | 23 | @Override 24 | public Material getDefaultType() { 25 | return Material.SIGN_POST; 26 | } 27 | 28 | @Override 29 | public List getSignTypes() { 30 | return Arrays.asList(Material.SIGN_POST); 31 | } 32 | 33 | @Override 34 | public void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) { 35 | EntityPlayer p = ((CraftPlayer) player).getHandle(); 36 | PlayerConnection conn = p.playerConnection; 37 | Location loc = signLoc != null ? signLoc : getDefaultLocation(player); 38 | BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); 39 | 40 | TileEntitySign sign = new TileEntitySign(); 41 | sign.a(pos); 42 | for (int i = 0; i < lines.length; i++) 43 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 44 | 45 | boolean schedule = false; 46 | ChannelPipeline pipeline = conn.networkManager.channel.pipeline(); 47 | if (pipeline.names().contains("SignGUI")) { 48 | ChannelHandler handler = pipeline.get("SignGUI"); 49 | if (handler instanceof SignGUIChannelHandler) { 50 | SignGUIChannelHandler signGUIHandler = (SignGUIChannelHandler) handler; 51 | signGUIHandler.close(); 52 | schedule = signGUIHandler.getBlockPosition().equals(pos); 53 | } 54 | 55 | if (pipeline.names().contains("SignGUI")) 56 | pipeline.remove("SignGUI"); 57 | } 58 | 59 | Runnable runnable = () -> { 60 | player.sendBlockChange(loc, type, (byte) 0); 61 | conn.sendPacket(sign.getUpdatePacket()); 62 | conn.sendPacket(new PacketPlayOutOpenSignEditor(pos)); 63 | 64 | SignEditor signEditor = new SignEditor(sign, loc, pos, pipeline); 65 | pipeline.addAfter("decoder", "SignGUI", new SignGUIChannelHandler>() { 66 | 67 | @Override 68 | public Object getBlockPosition() { 69 | return pos; 70 | } 71 | 72 | @Override 73 | public void close() { 74 | closeSignEditor(player, signEditor); 75 | } 76 | 77 | @Override 78 | protected void decode(ChannelHandlerContext chc, Packet packet, List out) { 79 | try { 80 | if (packet instanceof PacketPlayInUpdateSign) { 81 | PacketPlayInUpdateSign updateSign = (PacketPlayInUpdateSign) packet; 82 | if (updateSign.a().equals(pos)) 83 | onFinish.accept(signEditor, updateSign.b()); 84 | } 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | } 88 | 89 | out.add(packet); 90 | } 91 | }); 92 | }; 93 | 94 | if (schedule) 95 | SCHEDULER.schedule(runnable, 200, TimeUnit.MILLISECONDS); 96 | else 97 | runnable.run(); 98 | } 99 | 100 | @Override 101 | public void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 102 | TileEntitySign sign = (TileEntitySign) signEditor.getSign(); 103 | for (int i = 0; i < lines.length; i++) 104 | sign.lines[i] = new ChatComponentText(lines[i] != null ? lines[i] : ""); 105 | 106 | PlayerConnection conn = ((CraftPlayer) player).getHandle().playerConnection; 107 | conn.sendPacket(sign.getUpdatePacket()); 108 | conn.sendPacket(new PacketPlayOutOpenSignEditor((BlockPosition) signEditor.getBlockPosition())); 109 | } 110 | 111 | @Override 112 | public void closeSignEditor(Player player, SignEditor signEditor) { 113 | Location loc = signEditor.getLocation(); 114 | signEditor.getPipeline().remove("SignGUI"); 115 | player.sendBlockChange(loc, loc.getBlock().getType(), loc.getBlock().getData()); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Rapha149 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Mojang1_20_R4/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | 2.5.2 8 | de.rapha149.signgui 9 | 10 | 4.0.0 11 | 12 | signgui-1_20_R4-mojang 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | 21 | ca.bkaw 22 | paper-nms 23 | 1.20.6-SNAPSHOT 24 | provided 25 | 26 | 27 | de.rapha149.signgui 28 | signgui-wrapper 29 | ${project.parent.version} 30 | provided 31 | 32 | 33 | 34 | 35 | 36 | bytecode.space 37 | https://repo.bytecode.space/repository/maven-public/ 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-compiler-plugin 46 | 3.8.1 47 | 48 | 21 49 | 21 50 | 51 | 52 | 53 | ca.bkaw 54 | paper-nms-maven-plugin 55 | 1.4.7 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Mojang1_21_R1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | 2.5.2 8 | de.rapha149.signgui 9 | 10 | 4.0.0 11 | 12 | signgui-1_21_R1-mojang 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | 21 | ca.bkaw 22 | paper-nms 23 | 1.21.1-SNAPSHOT 24 | provided 25 | 26 | 27 | de.rapha149.signgui 28 | signgui-wrapper 29 | ${project.parent.version} 30 | provided 31 | 32 | 33 | 34 | 35 | 36 | bytecode.space 37 | https://repo.bytecode.space/repository/maven-public/ 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-compiler-plugin 46 | 3.8.1 47 | 48 | 21 49 | 21 50 | 51 | 52 | 53 | ca.bkaw 54 | paper-nms-maven-plugin 55 | 1.4.7 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Mojang1_21_R2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | 2.5.2 8 | de.rapha149.signgui 9 | 10 | 4.0.0 11 | 12 | signgui-1_21_R2-mojang 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | 21 | ca.bkaw 22 | paper-nms 23 | 1.21.3-SNAPSHOT 24 | provided 25 | 26 | 27 | de.rapha149.signgui 28 | signgui-wrapper 29 | ${project.parent.version} 30 | provided 31 | 32 | 33 | 34 | 35 | 36 | bytecode.space 37 | https://repo.bytecode.space/repository/maven-public/ 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-compiler-plugin 46 | 3.8.1 47 | 48 | 21 49 | 21 50 | 51 | 52 | 53 | ca.bkaw 54 | paper-nms-maven-plugin 55 | 1.4.7 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Mojang1_21_R3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | 2.5.2 8 | de.rapha149.signgui 9 | 10 | 4.0.0 11 | 12 | signgui-1_21_R3-mojang 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | 21 | ca.bkaw 22 | paper-nms 23 | 1.21.4-SNAPSHOT 24 | provided 25 | 26 | 27 | de.rapha149.signgui 28 | signgui-wrapper 29 | ${project.parent.version} 30 | provided 31 | 32 | 33 | 34 | 35 | 36 | bytecode.space 37 | https://repo.bytecode.space/repository/maven-public/ 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-compiler-plugin 46 | 3.8.1 47 | 48 | 21 49 | 21 50 | 51 | 52 | 53 | ca.bkaw 54 | paper-nms-maven-plugin 55 | 1.4.7 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Mojang1_21_R4/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | signgui-parent 7 | 2.5.2 8 | de.rapha149.signgui 9 | 10 | 4.0.0 11 | 12 | signgui-1_21_R4-mojang 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | 21 | ca.bkaw 22 | paper-nms 23 | 1.21.5-SNAPSHOT 24 | provided 25 | 26 | 27 | de.rapha149.signgui 28 | signgui-wrapper 29 | ${project.parent.version} 30 | provided 31 | 32 | 33 | 34 | 35 | 36 | bytecode.space 37 | https://repo.bytecode.space/repository/maven-public/ 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-compiler-plugin 46 | 3.8.1 47 | 48 | 21 49 | 21 50 | 51 | 52 | 53 | ca.bkaw 54 | paper-nms-maven-plugin 55 | 1.4.7 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /api/src/main/java/de/rapha149/signgui/SignGUI.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui; 2 | 3 | import de.rapha149.signgui.SignGUIAction.SignGUIActionInfo; 4 | import de.rapha149.signgui.exception.SignGUIException; 5 | import de.rapha149.signgui.exception.SignGUIVersionException; 6 | import de.rapha149.signgui.version.VersionMatcher; 7 | import org.apache.commons.lang.Validate; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.entity.Player; 13 | import org.bukkit.plugin.java.JavaPlugin; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * The base class of this api. Use {@link SignGUI#builder()} to get a new instance. 19 | */ 20 | public class SignGUI { 21 | 22 | /** 23 | * Constructs a new SignGUIBuilder. 24 | * 25 | * @return The new {@link SignGUIBuilder} instance 26 | * @throws SignGUIVersionException If the server version is not supported by this api. 27 | */ 28 | public static SignGUIBuilder builder() throws SignGUIVersionException { 29 | return new SignGUIBuilder(VersionMatcher.getWrapper()); 30 | } 31 | 32 | private final String[] lines; 33 | private final Object[] adventureLines; 34 | private final Material type; 35 | private final DyeColor color; 36 | private final boolean glow; 37 | private final Location signLoc; 38 | private final SignGUIFinishHandler handler; 39 | private final boolean callHandlerSynchronously; 40 | private final JavaPlugin plugin; 41 | 42 | /** 43 | * Constructs a new SignGUI. Use {@link SignGUI#builder()} to get a new instance. 44 | */ 45 | SignGUI(String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, SignGUIFinishHandler handler, boolean callHandlerSynchronously, JavaPlugin plugin) { 46 | this.lines = lines; 47 | this.adventureLines = adventureLines; 48 | this.type = type; 49 | this.color = color; 50 | this.glow = glow; 51 | this.signLoc = signLoc; 52 | this.handler = handler; 53 | this.callHandlerSynchronously = callHandlerSynchronously; 54 | this.plugin = plugin; 55 | } 56 | 57 | /** 58 | * Opens the sign gui for the player. 59 | *

60 | * Note: if there already is a sign gui open for the player, it will be closed and the {@link SignGUIFinishHandler} will not be called. 61 | * It is recommended to avoid opening a sign gui for a player that already has one open. 62 | * 63 | * @param player The player to open the gui for. 64 | * @throws de.rapha149.signgui.exception.SignGUIException If an error occurs while opening the gui. 65 | */ 66 | public void open(Player player) throws SignGUIException { 67 | Validate.notNull(player, "The player cannot be null"); 68 | 69 | try { 70 | VersionMatcher.getWrapper().openSignEditor(player, lines, adventureLines, type, color, glow, signLoc, (signEditor, resultLines) -> { 71 | Runnable runnable = () -> { 72 | Runnable close = () -> { 73 | try { 74 | VersionMatcher.getWrapper().closeSignEditor(player, signEditor); 75 | } catch (SignGUIVersionException e) { 76 | throw new SignGUIException("Failed to close sign editor", e); 77 | } 78 | }; 79 | List actions = handler.onFinish(player, new SignGUIResult(resultLines)); 80 | 81 | if (actions == null || actions.isEmpty()) { 82 | close.run(); 83 | return; 84 | } 85 | 86 | boolean keepOpen = false; 87 | for (SignGUIAction action : actions) { 88 | SignGUIActionInfo info = action.getInfo(); 89 | for (SignGUIAction otherAction : actions) { 90 | if (action == otherAction) 91 | continue; 92 | 93 | SignGUIActionInfo otherInfo = otherAction.getInfo(); 94 | if (info.isConflicting(otherInfo)) { 95 | close.run(); 96 | throw new IllegalArgumentException("The actions " + info.getName() + " and " + otherInfo.getName() + " are conflicting"); 97 | } 98 | } 99 | 100 | if (info.isKeepOpen()) 101 | keepOpen = true; 102 | } 103 | 104 | if (!keepOpen) 105 | close.run(); 106 | for (SignGUIAction action : actions) 107 | action.execute(this, signEditor, player); 108 | }; 109 | 110 | if (callHandlerSynchronously) 111 | Bukkit.getScheduler().runTask(plugin, runnable); 112 | else 113 | runnable.run(); 114 | }); 115 | } catch (Exception e) { 116 | throw new SignGUIException("Failed to open sign gui", e); 117 | } 118 | } 119 | 120 | /** 121 | * Sets the lines that are shown on the sign. 122 | * This is called when {@link SignGUIAction#displayNewLines(String...)} is returned as an action after the player has finished editing. 123 | * 124 | * @param lines The lines, must be exactly 4. 125 | * @param adventureLines The lines using Adventure components (1.20.5+). Must be exactly 4. May be null. 126 | * @throws java.lang.IllegalArgumentException If lines is null or not exactly 4 lines. 127 | * @throws SignGUIException If an error occurs while setting the lines. 128 | */ 129 | void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines) { 130 | Validate.notNull(lines, "The lines cannot be null"); 131 | Validate.isTrue(lines.length == 4, "The lines must have a length of 4"); 132 | if (adventureLines != null) 133 | Validate.isTrue(adventureLines.length == 4, "The adventure lines must null or have a length of 4"); 134 | 135 | try { 136 | VersionMatcher.getWrapper().displayNewLines(player, signEditor, lines, adventureLines); 137 | } catch (Exception e) { 138 | throw new SignGUIException("Failed to display new lines", e); 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /api/src/main/java/de/rapha149/signgui/SignGUIFinishHandler.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * A functional interface used for handling the result of the sign editing. 9 | */ 10 | @FunctionalInterface 11 | public interface SignGUIFinishHandler { 12 | 13 | /** 14 | * Called when the player finished editing the sign. 15 | * Return a list of actions that should be executed after the editing is finished. The actions are executed in the order they are in the list. 16 | * If {@link SignGUIAction#displayNewLines(String...)} is not included, the sign gui will be closed. 17 | * If you just want to close the sign gui, return an empty list or null. 18 | * 19 | * @param player The player who edited the sign. 20 | * @param result The result of the editing. 21 | * @return The list of actions. 22 | */ 23 | List onFinish(Player player, SignGUIResult result); 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/de/rapha149/signgui/SignGUIResult.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui; 2 | 3 | import org.bukkit.ChatColor; 4 | 5 | /** 6 | * The result of the sign editing. 7 | */ 8 | public class SignGUIResult { 9 | 10 | private final String[] lines; 11 | 12 | SignGUIResult(String[] lines) { 13 | this.lines = lines; 14 | } 15 | 16 | /** 17 | * @return The lines of the sign when the player finished editing. 18 | */ 19 | public String[] getLines() { 20 | return lines; 21 | } 22 | 23 | /** 24 | * Used for getting a specific line of the sign. 25 | * @param index The index of the desired line. 26 | * @return The line at the given index. 27 | */ 28 | public String getLine(int index) { 29 | return lines[index]; 30 | } 31 | 32 | /** 33 | * Used for getting the lines of the sign without color codes. 34 | * Calls {@link org.bukkit.ChatColor#stripColor(String)} on each line. 35 | * This method only strips color codes with § (not with {@literal &} for example). 36 | * 37 | * @return The lines of the sign without color codes. 38 | */ 39 | public String[] getLinesWithoutColor() { 40 | String[] linesWithoutColor = new String[lines.length]; 41 | for (int i = 0; i < lines.length; i++) 42 | linesWithoutColor[i] = ChatColor.stripColor(lines[i]); 43 | return linesWithoutColor; 44 | } 45 | 46 | /** 47 | * Used for getting a specific line of the sign without color codes. 48 | * Calls {@link org.bukkit.ChatColor#stripColor(String)} on the line. 49 | * This method only strips color codes with § (not with {@literal &} for example). 50 | * 51 | * @param index The index of the desired line. 52 | * @return The line at the given index without color codes. 53 | */ 54 | public String getLineWithoutColor(int index) { 55 | return ChatColor.stripColor(lines[index]); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /api/src/main/java/de/rapha149/signgui/exception/SignGUIException.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.exception; 2 | 3 | /** 4 | * An exception thrown when an error occurs while using this api. 5 | */ 6 | public class SignGUIException extends RuntimeException { 7 | 8 | /** 9 | * {@inheritDoc} 10 | */ 11 | public SignGUIException() { 12 | } 13 | 14 | /** 15 | * {@inheritDoc} 16 | */ 17 | public SignGUIException(String message) { 18 | super(message); 19 | } 20 | 21 | /** 22 | * {@inheritDoc} 23 | */ 24 | public SignGUIException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | 28 | /** 29 | * {@inheritDoc} 30 | */ 31 | public SignGUIException(Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | public SignGUIException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 39 | super(message, cause, enableSuppression, writableStackTrace); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /api/src/main/java/de/rapha149/signgui/exception/SignGUIVersionException.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.exception; 2 | 3 | /** 4 | * An exception thrown when the server version is not supported by this api or an error occured during initialization. 5 | */ 6 | public class SignGUIVersionException extends Exception { 7 | 8 | /** 9 | * {@inheritDoc} 10 | */ 11 | public SignGUIVersionException() { 12 | } 13 | 14 | /** 15 | * {@inheritDoc} 16 | */ 17 | public SignGUIVersionException(String message) { 18 | super(message); 19 | } 20 | 21 | /** 22 | * {@inheritDoc} 23 | */ 24 | public SignGUIVersionException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | 28 | /** 29 | * {@inheritDoc} 30 | */ 31 | public SignGUIVersionException(Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | public SignGUIVersionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 39 | super(message, cause, enableSuppression, writableStackTrace); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /api/src/main/java/de/rapha149/signgui/version/VersionMatcher.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.exception.SignGUIVersionException; 4 | import org.bukkit.Bukkit; 5 | 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.util.Collections; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * A utility class to get the version wrapper for the server version. 13 | */ 14 | public class VersionMatcher { 15 | 16 | private static final Map VERSIONS; 17 | private static final String NEWEST_VERSION = "1_21_R4"; 18 | 19 | private static boolean initialized; 20 | private static VersionWrapper wrapper; 21 | 22 | static { 23 | Map versions = new HashMap<>(); 24 | versions.put("1.20.5", "1_20_R4"); 25 | versions.put("1.20.6", "1_20_R4"); 26 | versions.put("1.21.1", "1_21_R1"); 27 | versions.put("1.21.3", "1_21_R2"); 28 | versions.put("1.21.4", "1_21_R3"); 29 | versions.put("1.21.5", "1_21_R4"); 30 | VERSIONS = Collections.unmodifiableMap(versions); 31 | } 32 | 33 | /** 34 | * Returns the appropriate version wrapper for the current server version. 35 | * If this method is called for the first time, the wrapper is initialized beforehand. 36 | * 37 | * @return The {@link VersionWrapper} instance 38 | * @throws SignGUIVersionException If the server version is not supported by this api or an error occured during initialization. 39 | */ 40 | public static VersionWrapper getWrapper() throws SignGUIVersionException { 41 | if (!initialized) { 42 | initialized = true; 43 | return wrapper = initWrapper(); 44 | } else if (wrapper == null) { 45 | throw new SignGUIVersionException("The previous attempt to initialize the version wrapper failed. " + 46 | "This could be because this server version is not supported or " + 47 | "because an error occured during initialization."); 48 | } else { 49 | return wrapper; 50 | } 51 | } 52 | 53 | /** 54 | * Internal method to initialize the version wrapper. 55 | */ 56 | private static VersionWrapper initWrapper() throws SignGUIVersionException { 57 | String craftBukkitPackage = Bukkit.getServer().getClass().getPackage().getName(); 58 | String version = craftBukkitPackage.contains(".v") ? craftBukkitPackage.split("\\.")[3].substring(1) : 59 | VERSIONS.getOrDefault(Bukkit.getBukkitVersion().split("-")[0], NEWEST_VERSION); 60 | 61 | final String className; 62 | if (useMojangMappings(version)) { 63 | className = VersionWrapper.class.getPackage().getName() + ".MojangWrapper" + version; 64 | } else { 65 | className = VersionWrapper.class.getPackage().getName() + ".Wrapper" + version; 66 | } 67 | 68 | try { 69 | return (VersionWrapper) Class.forName(className).getDeclaredConstructor().newInstance(); 70 | } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | 71 | InvocationTargetException exception) { 72 | throw new SignGUIVersionException("Failed to load support for server version " + version, exception); 73 | } catch (ClassNotFoundException exception) { 74 | throw new SignGUIVersionException("SignGUI does not support the server version \"" + version + "\"", exception); 75 | } 76 | } 77 | 78 | private static boolean useMojangMappings(String version) { 79 | try { 80 | Class.forName("com.destroystokyo.paper.ParticleBuilder"); 81 | } catch (ClassNotFoundException ignored) { 82 | return false; 83 | } 84 | 85 | final String[] versionNumbers = version.replace("R", "").split("_"); 86 | int major = Integer.parseInt(versionNumbers[1]); 87 | int minor = versionNumbers.length > 2 ? Integer.parseInt(versionNumbers[2]) : 0; 88 | if (major == 20 && minor == 4) 89 | return true; // 1.20.5/6 90 | return major > 20; // >= 1.21 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | de.rapha149.signgui 8 | signgui-parent 9 | pom 10 | 2.5.2 11 | 12 | 13 | api 14 | wrapper 15 | 1_8_R1 16 | 1_8_R2 17 | 1_8_R3 18 | 1_9_R1 19 | 1_9_R2 20 | 1_10_R1 21 | 1_11_R1 22 | 1_12_R1 23 | 1_13_R1 24 | 1_13_R2 25 | 1_14_R1 26 | 1_15_R1 27 | 1_16_R1 28 | 1_16_R2 29 | 1_16_R3 30 | 1_17_R1 31 | 1_18_R1 32 | 1_18_R2 33 | 1_19_R1 34 | 1_19_R2 35 | 1_19_R3 36 | 1_20_R1 37 | 1_20_R2 38 | 1_20_R3 39 | 1_20_R4 40 | Mojang1_20_R4 41 | 1_21_R1 42 | Mojang1_21_R1 43 | 1_21_R2 44 | Mojang1_21_R2 45 | 1_21_R3 46 | Mojang1_21_R3 47 | 1_21_R4 48 | Mojang1_21_R4 49 | 50 | 51 | 52 | UTF-8 53 | 54 | 55 | 56 | 57 | nms-repo 58 | https://repo.codemc.org/repository/nms/ 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.apache.maven.plugins 67 | maven-compiler-plugin 68 | 3.8.1 69 | 70 | 1.8 71 | 1.8 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | org.apache.maven.plugins 80 | maven-source-plugin 81 | 3.3.0 82 | 83 | 84 | attach-sources 85 | 86 | jar 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /wrapper/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | signgui-parent 9 | de.rapha149.signgui 10 | 2.5.2 11 | 12 | 13 | signgui-wrapper 14 | 15 | 16 | true 17 | 18 | 19 | 20 | 21 | org.spigotmc 22 | spigot 23 | 1.17-R0.1-SNAPSHOT 24 | provided 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-javadoc-plugin 33 | 3.2.0 34 | 35 | 8 36 | 37 | 38 | 39 | attach-javadocs 40 | 41 | jar 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /wrapper/src/main/java/de/rapha149/signgui/SignEditor.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui; 2 | 3 | import io.netty.channel.ChannelPipeline; 4 | import org.bukkit.Location; 5 | 6 | public class SignEditor { 7 | 8 | private final Object sign; 9 | private final Location location; 10 | private final Object blockPosition; 11 | private final ChannelPipeline pipeline; 12 | 13 | public SignEditor(Object sign, Location location, Object blockPosition, ChannelPipeline pipeline) { 14 | this.sign = sign; 15 | this.location = location; 16 | this.blockPosition = blockPosition; 17 | this.pipeline = pipeline; 18 | } 19 | 20 | public Object getSign() { 21 | return sign; 22 | } 23 | 24 | public Location getLocation() { 25 | return location; 26 | } 27 | 28 | public Object getBlockPosition() { 29 | return blockPosition; 30 | } 31 | 32 | public ChannelPipeline getPipeline() { 33 | return pipeline; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /wrapper/src/main/java/de/rapha149/signgui/SignGUIChannelHandler.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui; 2 | 3 | import io.netty.handler.codec.MessageToMessageDecoder; 4 | 5 | public abstract class SignGUIChannelHandler extends MessageToMessageDecoder { 6 | 7 | public abstract Object getBlockPosition(); 8 | 9 | public abstract void close(); 10 | } 11 | -------------------------------------------------------------------------------- /wrapper/src/main/java/de/rapha149/signgui/version/VersionWrapper.java: -------------------------------------------------------------------------------- 1 | package de.rapha149.signgui.version; 2 | 3 | import de.rapha149.signgui.SignEditor; 4 | import org.bukkit.DyeColor; 5 | import org.bukkit.Location; 6 | import org.bukkit.Material; 7 | import org.bukkit.entity.Player; 8 | 9 | import java.util.List; 10 | import java.util.concurrent.Executors; 11 | import java.util.concurrent.ScheduledExecutorService; 12 | import java.util.function.BiConsumer; 13 | 14 | /** 15 | * Interface for version wrappers 16 | */ 17 | public interface VersionWrapper { 18 | 19 | ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(0); 20 | 21 | /** 22 | * @return The default type for the sign. Different between some versions. 23 | */ 24 | Material getDefaultType(); 25 | 26 | /** 27 | * @return A list of available sign types. Different between some versions. 28 | */ 29 | List getSignTypes(); 30 | 31 | /** 32 | * Called when a sign gui should be opened. 33 | * 34 | * @param player The player to whom the sign is to be shown. 35 | * @param lines The lines that are shown. 36 | * @param type The type of the sign. 37 | * @param color The color of the sign (1.14+) 38 | * @param glow If the sign's text should glow (1.17+) 39 | * @param signLoc The location where the sign should be placed. Can be null for default. 40 | * @param onFinish The {@link java.util.function.BiConsumer} which is called when the player finished editing the sign. 41 | */ 42 | void openSignEditor(Player player, String[] lines, Object[] adventureLines, Material type, DyeColor color, boolean glow, Location signLoc, BiConsumer onFinish) throws Exception; 43 | 44 | /** 45 | * Called when the lines of a sign should be updated. 46 | * 47 | * @param player The player to whom the sign was shown to. 48 | * @param signEditor The sign editor. 49 | * @param lines The new lines. 50 | */ 51 | void displayNewLines(Player player, SignEditor signEditor, String[] lines, Object[] adventureLines); 52 | 53 | /** 54 | * Called when the sign editor should be closed. 55 | * 56 | * @param player The player to whom the sign was shown to. 57 | * @param signEditor The sign editor. 58 | */ 59 | void closeSignEditor(Player player, SignEditor signEditor); 60 | 61 | /** 62 | * Get the default location where the sign should be placed for the player. 63 | * 64 | * @param player The player. 65 | * @return The location of the sign. 66 | */ 67 | default Location getDefaultLocation(Player player) { 68 | Location loc = player.getEyeLocation(); 69 | return loc.clone().add(loc.getDirection().multiply(-3)); 70 | } 71 | } 72 | --------------------------------------------------------------------------------