Debugging Minecraft Plugins - acrawley/BasePluginLib GitHub Wiki

Debugging Minecraft Plugins

All of my plugins are set up to be easily debuggable from IntelliJ. Each provides a Maven profile called dev that deploys a copy of the plugin JAR to the server's plugins folder (specified by the spigot.plugindir variable).

Setting up IntelliJ

  • Run -> Edit Configurations
  • Click "Add new configuration" (green plus)
  • Choose "JAR application"
  • Name the configuration, e.g. "Spigot"
  • Check "Single instance only"
  • In the "Configuration" tab:
    • Set "Path to JAR" to the location of your Spigot JAR
    • Set "Working directory" to the Spigot server path
      • In the "Before launch" section:
        • Click "Add" (green plus)
        • Choose "Run Maven Goal"
        • In the "Select Maven Goal" dialog:
          • Click the "Select Maven Project" button (folder) and choose a project
          • Set "Command line" to -o install -P dev -D spigot.plugindir="/path/to/plugin/dir"
          • Click OK
        • Repeat for any other of my plugins you may be building
  • Click OK

Note that actually debugging (stopping at breakpoints, stepping, etc) can be difficult, as the client and server both contain timeouts that will cause a disconnection if much time is spent stopped in a debugger. This can be avoided by patching the client and server to remove the timeouts. Instructions are provided for the official Windows client and Spigot server.

Patching the server

  • Follow Spigot instructions to get set up to build (download BuildTools.jar, etc)
  • Run a build once to get all the sources synced
  • Open <BuildTools dir>\Spigot\Spigot-Server\src\main\java\net\minecraft\server\ServerConnection.java in your editor of choice
    • If this path changes, grep under Spigot for a .java file containing ReadTimeoutHandler
  • Remove the call to addLast on that line that adds the ReadTimeoutHandler, e.g.:
--- a/src/main/java/net/minecraft/server/ServerConnection.java
+++ b/src/main/java/net/minecraft/server/ServerConnection.java
@@ -91,7 +91,7 @@ public class ServerConnection {
                         ;
                     }

-                    channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyPingHandler(ServerConnection.this)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder(EnumProtocolDirection.SERVERBOUND)).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder(EnumProtocolDirection.CLIENTBOUND));
+                    channel.pipeline().addLast("legacy_query", new LegacyPingHandler(ServerConnection.this)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder(EnumProtocolDirection.SERVERBOUND)).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder(EnumProtocolDirection.CLIENTBOUND));
                     NetworkManager networkmanager = new NetworkManager(EnumProtocolDirection.SERVERBOUND);

                     ServerConnection.this.h.add(networkmanager);
  • cd Spigot
  • Rebuild just the server: ../apache-maven-3.2.5/bin/mvn package
  • Copy the new Spigot JAR from the Spigot-Server/target folder to your server folder

Patching the client

  • Download the appropriate version of MCP from http://www.modcoderpack.com/website/releases
    • NOTE: If no version of MCP is available for the version of Minecraft you want to debug, try these instructions
  • Unpack somewhere on your local box
  • Make sure you have the exact version of Minecraft installed that MCP expects - if MCP requires 1.10, having 1.10.2 installed won't work
  • Run MCP's decompile.bat and wait a few minutes while it does its work
  • Open <MCP DIR>\src\minecraft\net\minecraft\network\NetworkManager.java in your editor of choice
    • If this path is wrong, grep for ReadTimeoutHandler to figure out which file to edit. In 1.10, there is another hit in NetworkSystem.java related to allowing other players on your local network to join your game - this does not need to be changed to fix debugging, but it won't hurt anything.
  • Remove the call to addLast on that line that adds the ReadTimeoutHandler, e.g.:
--- a/orig/minecraft/net/minecraft/network/NetworkManager.java
+++ b/src/minecraft/net/minecraft/network/NetworkManager.java
@@ -370,7 +370,7 @@ public class NetworkManager extends SimpleChannelInboundHandler < Packet<? >>
                     ;
                 }

-                p_initChannel_1_.pipeline().addLast((String)"timeout", (ChannelHandler)(new ReadTimeoutHandler(30))).addLast((String)"splitter", (ChannelHandler)(new NettyVarint21FrameDecoder())).addLast((String)"decoder", (ChannelHandler)(new NettyPacketDecoder(EnumPacketDirection.CLIENTBOUND))).addLast((String)"prepender", (ChannelHandler)(new NettyVarint21FrameEncoder())).addLast((String)"encoder", (ChannelHandler)(new NettyPacketEncoder(EnumPacketDirection.SERVERBOUND))).addLast((String)"packet_handler", (ChannelHandler)networkmanager);
+                p_initChannel_1_.pipeline().addLast((String)"splitter", (ChannelHandler)(new NettyVarint21FrameDecoder())).addLast((String)"decoder", (ChannelHandler)(new NettyPacketDecoder(EnumPacketDirection.CLIENTBOUND))).addLast((String)"prepender", (ChannelHandler)(new NettyVarint21FrameEncoder())).addLast((String)"encoder", (ChannelHandler)(new NettyPacketEncoder(EnumPacketDirection.SERVERBOUND))).addLast((String)"packet_handler", (ChannelHandler)networkmanager);
             }
         })).channel(oclass)).connect(address, serverPort).syncUninterruptibly();
         return networkmanager;
  • Save and run recompile.bat
  • Run reobfuscate.bat
  • Browse to %APPDATA%\.minecraft\versions
  • Make a copy of the folder for the version edited (e.g. 1.10) and name it (e.g. 1.10-Debug)
  • Rename the .jar and .json in that folder to the same thing as the containing folder, e.g. 1.10-Debug.json and 1.10-Debug.jar
  • Open the .jar file in a ZIP program
    • Delete the META-INF folder
    • Copy all the .class files in MCP's reobf\minecraft folder to the root of the JAR, overwriting any existing files
  • Open the .json file in a text editor
    • Change the id field to the name of the containing folder (e.g. 1.10-Debug)
    • Delete the downloads section to prevent the launcher from replacing our edited JAR with a clean copy
  • Run the Minecraft Launcher
  • Click "New Profile"
    • Name the profile (e.g. "v1.10 - Debug")
    • In the "Use version" dropdown, select "release 1.10-Debug"
    • Click "Save Profile"
  • Select the new profile
  • Click "Play"

⚠️ **GitHub.com Fallback** ⚠️