Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package example;
- import java.lang.reflect.Field;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import java.util.NoSuchElementException;
- import java.util.concurrent.Callable;
- import net.minecraft.server.v1_7_R4.MinecraftServer;
- import net.minecraft.server.v1_7_R4.NetworkManager;
- import net.minecraft.server.v1_7_R4.Packet;
- import net.minecraft.server.v1_7_R4.ServerConnection;
- import net.minecraft.util.io.netty.channel.Channel;
- import net.minecraft.util.io.netty.channel.ChannelDuplexHandler;
- import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
- import net.minecraft.util.io.netty.channel.ChannelPromise;
- import org.bukkit.craftbukkit.v1_7_R4.CraftServer;
- import org.bukkit.event.EventHandler;
- import org.bukkit.event.Listener;
- import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
- import org.bukkit.event.server.ServerListPingEvent;
- import org.bukkit.plugin.Plugin;
- public class PacketProtocol {
- /*
- * Class made by BigTeddy98.
- *
- * PacketProtocol is a simple class to intercept packets.
- *
- * 1. No warranty is given or implied. 2. All damage is your own
- * responsibility. 3. If you want to use this in your plugins, a credit
- * would we appreciated.
- */
- private Plugin plugin;
- private List<PacketListener> packetListeners = Collections
- .synchronizedList(new ArrayList<PacketListener>());
- // injected channels, stored so we can remove our handler on disable
- private List<NetworkManager> injectedNetworkManagers = Collections
- .synchronizedList(new ArrayList<NetworkManager>());
- private List<NetworkManager> list;
- // some reflection
- private Field m;
- private Field getConsole;
- private Field getServerConnection;
- private Field getF;
- public PacketProtocol(Plugin plugin) throws Exception {
- this.plugin = plugin;
- // set up our little bit of reflection
- this.m = NetworkManager.class.getDeclaredField("m");
- this.m.setAccessible(true);
- this.getConsole = CraftServer.class.getDeclaredField("console");
- this.getConsole.setAccessible(true);
- this.getServerConnection = MinecraftServer.class.getDeclaredField("p");
- this.getServerConnection.setAccessible(true);
- this.getF = ServerConnection.class.getDeclaredField("f");
- this.getF.setAccessible(true);
- // call initialize
- this.initialize();
- }
- // calling this method onDisable is very IMPORTANT, without calling this
- // method this class won't work correctly.
- public void disable() {
- // loop through all channels and remove our handler
- for (NetworkManager netManager : injectedNetworkManagers) {
- try {
- Channel channel = (Channel) this.m.get(netManager);
- removeHandler(channel, plugin.getName(), false);
- } catch (NoSuchElementException e) {
- // something changed, no problem
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- // used to thread safe remove our handler
- private void removeHandler(final Channel channel, final String name,
- final boolean b) throws NoSuchElementException {
- channel.eventLoop().submit(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- channel.pipeline().remove(name);
- if (b) {
- channel.pipeline().addBefore("packet_handler",
- plugin.getName(), new DuplexHandler());
- }
- return null;
- }
- });
- }
- // register out listeners
- @SuppressWarnings("unchecked")
- private void initialize() throws IllegalArgumentException,
- IllegalAccessException {
- // get the NMS minecraftserver
- MinecraftServer server = (MinecraftServer) getConsole
- .get(PacketProtocol.this.plugin.getServer());
- // get the serverconnection
- ServerConnection connection = (ServerConnection) PacketProtocol.this.getServerConnection
- .get(server);
- // get a list of all waiting connections
- Object obj = getF.get(connection);
- this.list = Collections.synchronizedList((List<NetworkManager>) obj);
- this.plugin.getServer().getPluginManager()
- .registerEvents(new Listener() {
- @EventHandler
- private void onPing(ServerListPingEvent event)
- throws IllegalArgumentException,
- IllegalAccessException {
- injectConnections();
- }
- @EventHandler
- private void onLogin(AsyncPlayerPreLoginEvent event)
- throws IllegalArgumentException,
- IllegalAccessException {
- injectConnections();
- }
- }, this.plugin);
- }
- private synchronized void injectConnections()
- throws IllegalArgumentException, IllegalAccessException {
- // inject them all, to intercept our packets
- for (NetworkManager manager : list) {
- // inject connection
- injectConnection(manager);
- }
- }
- // method for injecting ping connections
- private void injectConnection(final NetworkManager manager)
- throws IllegalArgumentException, IllegalAccessException {
- // get channel using reflection
- // check if it already has been injected
- if (this.injectedNetworkManagers.contains(manager)) {
- return;
- }
- // store it for later
- this.injectedNetworkManagers.add(manager);
- final Channel channel = (Channel) this.m.get(manager);
- if (channel.pipeline().context("packet_handler") == null) {
- return;
- }
- try {
- // add the packet_handler
- channel.pipeline().addBefore("packet_handler", plugin.getName(),
- new DuplexHandler());
- } catch (IllegalArgumentException e) {
- // handler already registered
- System.out.println("reinjecting");
- removeHandler(channel, plugin.getName(), true);
- }
- }
- // used to register your packet listeners
- public void registerListener(PacketListener listener) {
- this.packetListeners.add(listener);
- }
- private class DuplexHandler extends ChannelDuplexHandler {
- // this method comes from the netty thread
- @Override
- public void write(ChannelHandlerContext ctx, Object msg,
- ChannelPromise promise) throws Exception {
- // loop and call
- Packet packet = (Packet) msg;
- for (PacketListener listener : packetListeners) {
- try {
- Packet newPacket = listener.onOutgoingPacket(packet);
- if (newPacket == null) {
- return;
- } else {
- packet = newPacket;
- }
- } catch (Exception e) {
- }
- }
- // write it if it hasn't been cancelled
- super.write(ctx, packet, promise);
- }
- // this method comes from the netty thread
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg)
- throws Exception {
- // loop and call
- Packet packet = (Packet) msg;
- for (PacketListener listener : packetListeners) {
- try {
- Packet newPacket = listener.onIncomingPacket(packet);
- if (newPacket == null) {
- return;
- } else {
- packet = newPacket;
- }
- } catch (Exception e) {
- }
- }
- // write it if it hasn't been cancelled
- super.channelRead(ctx, packet);
- }
- }
- public interface PacketListener {
- // PAY ATTENTION, these methods are being called from another thread!
- public Packet onIncomingPacket(Packet packet);
- // PAY ATTENTION, these methods are being called from another thread!
- public Packet onOutgoingPacket(Packet packet);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement