Skip to content
main-- edited this page Mar 24, 2012 · 9 revisions

MCProxy

MCProxy is a nice tool that allows you to easily debug the minecraft-protocol. It's written in Java and can even load plugins! It's using the MCPackets-library.

Custom plugins

A simple example-plugin:

package example;

// imports

public class MyAwesomePlugin extends Plugin {
    public ProtocolVersionVerificationPlugin() {
        super("MyAwesomePlugin");
    }

    @PacketHandler(target = NetworkPartner.CLIENT, priority = -1)
    public void checkProtocolVersion(ChatPacket packet) throws CancelPacketException {
        String newMessage = packet.getMessage().replaceAll("bad", "good");
        if (!newMessage.equals(packet.getMessage())) { // avoid infinite chains
            // Note: Packets are immutable: you have to create new ones if you want to change them!
            this.getProxy().sendPacket(new ChatPacketImpl(newMessage), NetworkPartner.CLIENT);
            throw new CancelPacketException(); // to cancel packets either throw this or return false
        }
    }
}

Now you only need to add the pluginClass-file:

example.MyAwesomePlugin

Just pack it all into a JAR and your plugin is finished! It will replace "bad" with "good" in all chat-messages the server sends to the client.

The PacketHandlers

The @PacketHandler-annotations tells MCProxy that a method should be called when a certain packet is processed. You can specify the target-parameter if you want to handle only packets that are meant for the client/server. The priority-parameter controls the order in which PacketHandlers are executed. The lower the priority, the earlier the PacketHandler is called. The method is allowed to throw the CancelPacketException, it can return either void or a boolean and it has to be public. The name doesn't matter. It has to take one subclass of Packet and optionally a boolean indicating whether the packet is cancelled. By default, a PacketHandler is not called when the packet was cancelled. However, it is always called if it takes that parameter. But be careful not to uncancel packets:

@PacketHandler
public void checkProtocolVersion(Packet packet, boolean cancelled) {
    if (cancelled)
        System.out.println(String.format("Packet '%s' was CANCELLED!"));
}

The PacketHandler returns void so MCProxy expects it to throw the CancelPacketException if the packet should remain cancelled. However, that doesn't happen. This would be better:

@PacketHandler
public boolean checkProtocolVersion(Packet packet, boolean cancelled) {
    if (cancelled)
        System.out.println(String.format("Packet '%s' was CANCELLED!"));
    return !cancelled;
}

It's important that you negate the cancellation-state because the method returns whether the packet is allowed to pass instead of whether the packet is cancelled!

Default plugins

There are several default plugins:

ProtocolVersionVerificationPlugin

This plugin simply ensures that the MCPackets-version you're using matches the version of the client MCProxy is interacting with.

FreezePlugin

This plugin is really powerful. It has several commands. Just write them in chat on your client.

  • /proxy:freeze start client:ACTION server:ACTION: You can enter freeze-mode with this command. ACTION has to be either forward, discard or capture. Example: /proxy:freeze start client:forward server:capture would forward all packets from the client to the server and cache all packets from the server to the client.
  • /proxy:freeze flush [client|server]: Sends all cached packets to the client/server. If you don't write client/server, both caches will be flushed.
  • /proxy:freeze stop [noflush]: Leaves freeze-mode and automatically flushes all packets. Write noflush if you don't want that.

Maven

A plugin-archetype is available at http://repo.onarandombox.com/content/repositories/thirdparty/! Use it to create plugins much easier:

$ mvn archetype:generate -DarchetypeCatalog=http://repo.onarandombox.com/content/repositories/thirdparty/
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: http://repo.onarandombox.com/content/repositories/thirdparty/ -> tk.maincraft.util.mcproxy:PluginArchetype (-)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 1
Define value for property 'groupId': : com.example
Define value for property 'artifactId': : TestPlugin
Define value for property 'version':  1.0-SNAPSHOT: : 1.0
Define value for property 'package':  com.example: :
Confirm properties configuration:
groupId: com.example
artifactId: TestPlugin
version: 1.0
package: com.example
 Y: : Y
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: PluginArchetype:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: TestPlugin
[INFO] Parameter: version, Value: 1.0
[INFO] Parameter: package, Value: com.example
[INFO] Parameter: packageInPathFormat, Value: com/example
[INFO] Parameter: package, Value: com.example
[INFO] Parameter: version, Value: 1.0
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: TestPlugin
[INFO] project created from Archetype in dir: ~/archetype-testing/TestPlugin
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 40.270s
[INFO] Finished at: Sat Mar 24 18:13:41 CET 2012
[INFO] Final Memory: 13M/154M
[INFO] ------------------------------------------------------------------------

It automatically created everything:

TestPlugin
│───pom.xml
└───src
    └───main
        ├───java
        │   └───com
        │       └───example
        │           └───TestPlugin.java
        └───resources
            └───pluginClass