Code Monkey home page Code Monkey logo

protocollib's Introduction

ProtocolLib Travis Status

Certain tasks are impossible to perform with the standard Bukkit API, and may require working with and even modify Minecraft directly. A common technique is to modify incoming and outgoing packets, or inject custom packets into the stream. This is quite cumbersome to do, however, and most implementations will break as soon as a new version of Minecraft has been released, mostly due to obfuscation.

Critically, different plugins that use this approach may hook into the same classes, with unpredictable outcomes. More than often this causes plugins to crash, but it may also lead to more subtle bugs.

Currently maintained by dmulloy2 on behalf of Spigot.

Resources

Compilation

ProtocolLib is built with Maven and requires Spigot and SpigotAPI, which can be found here.

A new API

ProtocolLib attempts to solve this problem by providing a event API, much like Bukkit, that allows plugins to monitor, modify, or cancel packets sent and received. But, more importantly, the API also hides all the gritty, obfuscated classes with a simple index based read/write system. You no longer have to reference CraftBukkit!

Using ProtocolLib

To use this library, first add ProtocolLib.jar to your Java build path. Then, add ProtocolLib as a dependency or soft dependency to your plugin.yml file like any other plugin:

depend: [ProtocolLib]

You can also add ProtocolLib as a Maven dependency:

<repositories>
  <repository>
    <id>dmulloy2-repo</id>
    <url>http://repo.dmulloy2.net/nexus/repository/public/</url>
  </repository>
  ...
</repositories>

<dependencies>
  <dependency>
    <groupId>com.comphenix.protocol</groupId>
    <artifactId>ProtocolLib-API</artifactId>
    <version>4.4.0</version>
  </dependency>
</dependencies>

Or use the maven dependency with gradle:

repositories {
    maven { url "http://repo.dmulloy2.net/nexus/repository/public/" }
}

dependencies {
    compileOnly group: "com.comphenix.protocol", name: "ProtocolLib", version: "4.4.0";
}

Then get a reference to ProtocolManager in onLoad() or onEnable() and you're good to go.

private ProtocolManager protocolManager;

public void onLoad() {
    protocolManager = ProtocolLibrary.getProtocolManager();
}

To listen for packets sent by the server to a client, add a server-side listener:

// Disable all sound effects
protocolManager.addPacketListener(
  new PacketAdapter(this, ListenerPriority.NORMAL, 
          PacketType.Play.Server.NAMED_SOUND_EFFECT) {
    @Override
    public void onPacketSending(PacketEvent event) {
        // Item packets (id: 0x29)
        if (event.getPacketType() == 
                PacketType.Play.Server.NAMED_SOUND_EFFECT) {
            event.setCancelled(true);
        }
    }
});

It's also possible to read and modify the content of these packets. For instance, you can create a global censor by listening for Packet3Chat events:

// Censor
protocolManager.addPacketListener(new PacketAdapter(this,
        ListenerPriority.NORMAL, 
        PacketType.Play.Client.CHAT) {
    @Override
    public void onPacketReceiving(PacketEvent event) {
        if (event.getPacketType() == PacketType.Play.Client.CHAT) {
            PacketContainer packet = event.getPacket();
            String message = packet.getStrings().read(0);

            if (message.contains("shit")
                    || message.contains("damn")) {
                event.setCancelled(true);
                event.getPlayer().sendMessage("Bad manners!");
            }
        }
    }
});

Sending packets

Normally, you might have to do something ugly like the following:

Packet60Explosion fakeExplosion = new Packet60Explosion();
	
fakeExplosion.a = player.getLocation().getX();
fakeExplosion.b = player.getLocation().getY();
fakeExplosion.c = player.getLocation().getZ();
fakeExplosion.d = 3.0F;
fakeExplosion.e = new ArrayList<Object>();

((CraftPlayer) player).getHandle().netServerHandler.sendPacket(fakeExplosion);

But with ProtocolLib, you can turn that into something more manageable. Notice that you don't have to create an ArrayList with this version:

PacketContainer fakeExplosion = new PacketContainer(PacketType.Play.Server.EXPLOSION);
fakeExplosion.getDoubles().
    write(0, player.getLocation().getX()).
    write(1, player.getLocation().getY()).
    write(2, player.getLocation().getZ());
fakeExplosion.getFloat().write(0, 3.0F);

try {
    protocolManager.sendServerPacket(player, fakeExplosion);
} catch (InvocationTargetException e) {
    throw new RuntimeException(
        "Cannot send packet " + fakeExplosion, e);
}

Compatibility

One of the main goals of this project was to achieve maximum compatibility with CraftBukkit. And the end result is quite flexible. Aside from netty package changes, it should be resilient against future changes. It's likely that I won't have to update ProtocolLib for anything but bug fixes and new features.

How is this possible? It all comes down to reflection in the end. Essentially, no name is hard coded - every field, method and class is deduced by looking at field types, package names or parameter types. It's remarkably consistent across different versions.

protocollib's People

Contributors

aadnk avatar dmulloy2 avatar glen3b avatar devil-boy avatar stephan-gh avatar felixklauke avatar 0x277f avatar sheigutn avatar zeruska avatar dadus33 avatar ttaylorr avatar techcable avatar yukon avatar ds58 avatar diffblue-assistant avatar games647 avatar nuclearsteven avatar johni0702 avatar mbax avatar 502647092 avatar minidigger avatar matrixtunnel avatar markhughes avatar darkseraphim avatar yawkat avatar sgdc3 avatar emiel45 avatar derflash avatar alvin-lb avatar

Stargazers

Ruby Hale avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.