Provide backwards compatibility with 1.7.10 and earlier

Also update the version to 3.6.4 since this was such a massive change
This commit is contained in:
Dan Mulloy 2015-06-18 21:07:32 -04:00
parent 9ce277cd76
commit 325b91fb1f
36 changed files with 1046 additions and 346 deletions

View File

@ -4,7 +4,6 @@ jdk:
- oraclejdk7
- openjdk6
script: mvn clean install -U
before_install: cd ProtocolLib
install: true
notifications:
email:

View File

@ -0,0 +1,273 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>ShadedNetty</artifactId>
<version>3.6.4-SNAPSHOT</version>
<name>ShadedNetty</name>
<description>Provides read/write access to the Minecraft protocol.</description>
<url>http://www.spigotmc.org/resources/protocollib.1997/</url>
<packaging>jar</packaging>
<parent>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib-Parent</artifactId>
<version>3</version>
<relativePath>../../</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>cp1252</project.build.sourceEncoding>
<project.build.number></project.build.number>
</properties>
<build>
<defaultGoal>clean install</defaultGoal>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>net.sf</pattern>
<shadedPattern>com.comphenix.net.sf</shadedPattern>
</relocation>
</relocations>
<artifactSet>
<excludes>
<exclude>org.spigotmc:spigot</exclude>
<exclude>org.spigotmc:spigot-api</exclude>
<exclude>junit:junit</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
<finalName>ProtocolLib</finalName>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<threshold>High</threshold>
<effort>Default</effort>
</configuration>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>jenkins</id>
<activation>
<property>
<name>env.BUILD_NUMBER</name>
</property>
</activation>
<properties>
<project.build.number>-b${env.BUILD_NUMBER}</project.build.number>
</properties>
</profile>
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<scm>
<connection>scm:git:git://github.com/dmulloy2/ProtocolLib.git</connection>
<developerConnection>scm:git:git@github.com:dmulloy2/ProtocolLib.git</developerConnection>
<url>https://github.com/dmulloy2/ProtocolLib</url>
</scm>
<licenses>
<license>
<name>GNU GENERAL PUBLIC LICENSE - Version 2, June 1991</name>
<url>http://www.gnu.org/licenses/gpl-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>dmulloy2</id>
<name>Dan Mulloy</name>
<url>http://shadowvolt.com/</url>
<roles>
<role>developer</role>
<role>maintainer</role>
</roles>
</developer>
<developer>
<id>aadnk</id>
<name>Kristian S. Stangeland</name>
<email>kr_stang@hotmail.com</email>
<url>http://comphenix.net/</url>
<roles>
<role>former author</role>
</roles>
<timezone>1</timezone>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.2.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.comphenix.executors</groupId>
<artifactId>BukkitExecutors</artifactId>
<version>1.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.7.10-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.7.10-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.5</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,79 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.guava;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
import net.minecraft.util.com.google.common.io.ByteStreams;
import net.minecraft.util.com.google.common.io.InputSupplier;
import com.comphenix.protocol.PacketType;
import com.google.common.collect.DiscreteDomains;
import com.google.common.collect.Range;
import com.google.common.collect.Ranges;
/**
* @author dmulloy2
*/
public class Guava10 implements GuavaCompat {
@Override
public <C extends Comparable<C>> Range<C> closedRange(C lower, C upper) {
return Ranges.closed(lower, upper);
}
@Override
public <C extends Comparable<C>> Range<C> singletonRange(C value) {
return Ranges.singleton(value);
}
@Override
public Set<Integer> toSet(Range<Integer> range) {
return range.asSet(DiscreteDomains.integers());
}
@Override
@SuppressWarnings("unchecked")
public DataInputStream addHeader(final DataInputStream input, final PacketType type) {
InputSupplier<InputStream> header = new InputSupplier<InputStream>() {
@Override
public InputStream getInput() throws IOException {
byte[] data = new byte[] { (byte) type.getLegacyId() };
return new ByteArrayInputStream(data);
}
};
InputSupplier<InputStream> data = new InputSupplier<InputStream>() {
@Override
public InputStream getInput() throws IOException {
return input;
}
};
// Combine them into a single stream
try {
return new DataInputStream(ByteStreams.join(header, data).getInput());
} catch (IOException e) {
throw new RuntimeException("Cannot add header.", e);
}
}
}

View File

@ -1,8 +1,20 @@
package com.comphenix.protocol.injector.netty;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import java.util.Collection;
import java.util.Iterator;
@ -10,10 +22,13 @@ import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.Callable;
import com.google.common.collect.Lists;
// Hopefully, CB won't version these as well
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelFuture;
import net.minecraft.util.io.netty.channel.ChannelHandler;
class BootstrapList implements List<Object> {
import com.google.common.collect.Lists;
public class ShadedBootstrapList implements List<Object> {
private List<Object> delegate;
private ChannelHandler handler;
@ -22,7 +37,7 @@ class BootstrapList implements List<Object> {
* @param delegate - the delegate.
* @param handler - the channel handler to add.
*/
public BootstrapList(List<Object> delegate, ChannelHandler handler) {
public ShadedBootstrapList(List<Object> delegate, ChannelHandler handler) {
this.delegate = delegate;
this.handler = handler;

View File

@ -0,0 +1,76 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/package com.comphenix.protocol.compat.netty.shaded;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import net.minecraft.util.io.netty.buffer.ByteBuf;
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
/**
* @author dmulloy2
*/
public class ShadedByteBuf implements WrappedByteBuf {
private final ByteBuf handle;
public ShadedByteBuf(ByteBuf handle) {
this.handle = handle;
}
@Override
public Object getHandle() {
return handle;
}
@Override
public void writeBytes(ObjectInputStream input, int id) throws IOException {
handle.writeBytes(input, id);
}
@Override
public int readableBytes() {
return handle.readableBytes();
}
@Override
public void readBytes(ObjectOutputStream output, int readableBytes) throws IOException {
handle.readBytes(output, readableBytes);
}
@Override
public void readBytes(byte[] data) {
handle.readBytes(data);
}
@Override
public void writeByte(byte b) {
handle.writeByte(b);
}
@Override
public void writeByte(int i) {
handle.writeByte(i);
}
@Override
public void writeBytes(byte[] bytes) {
handle.writeBytes(bytes);
}
}

View File

@ -1,8 +1,20 @@
package com.comphenix.protocol.utility;
import io.netty.buffer.AbstractByteBuf;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@ -16,9 +28,15 @@ import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.channels.WritableByteChannel;
import net.minecraft.util.io.netty.buffer.AbstractByteBuf;
import net.minecraft.util.io.netty.buffer.ByteBuf;
import net.minecraft.util.io.netty.buffer.ByteBufAllocator;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.google.common.io.ByteStreams;
import com.google.common.io.LimitInputStream;
/**
* Construct a ByteBuf around an input stream and an output stream.
@ -27,7 +45,7 @@ import com.google.common.io.ByteStreams;
* all indexing in the byte buffer.
* @author Kristian
*/
class ByteBufAdapter extends AbstractByteBuf {
public class ShadedByteBufAdapter extends AbstractByteBuf {
private DataInputStream input;
private DataOutputStream output;
@ -37,7 +55,7 @@ class ByteBufAdapter extends AbstractByteBuf {
private static final int CAPACITY = Short.MAX_VALUE;
private ByteBufAdapter(DataInputStream input, DataOutputStream output) {
private ShadedByteBufAdapter(DataInputStream input, DataOutputStream output) {
// Just pick a figure
super(CAPACITY);
this.input = input;
@ -68,7 +86,7 @@ class ByteBufAdapter extends AbstractByteBuf {
* @return A packet serializer with a wrapped byte buf adapter.
*/
public static ByteBuf packetReader(DataInputStream input) {
return MinecraftReflection.getPacketDataSerializer(new ByteBufAdapter(input, null));
return (ByteBuf) MinecraftReflection.getPacketDataSerializer(new ShadedByteBufAdapter(input, null));
}
/**
@ -77,7 +95,7 @@ class ByteBufAdapter extends AbstractByteBuf {
* @return A packet serializer with a wrapped byte buf adapter.
*/
public static ByteBuf packetWriter(DataOutputStream output) {
return MinecraftReflection.getPacketDataSerializer(new ByteBufAdapter(null, output));
return (ByteBuf) MinecraftReflection.getPacketDataSerializer(new ShadedByteBufAdapter(null, output));
}
@Override
@ -249,13 +267,13 @@ class ByteBufAdapter extends AbstractByteBuf {
@Override
public ByteBuf getBytes(int index, OutputStream dst, int length) throws IOException {
ByteStreams.copy(ByteStreams.limit(input, length), dst);
ByteStreams.copy(new LimitInputStream(input, length), dst);
return this;
}
@Override
public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
byte[] data = ByteStreams.toByteArray(ByteStreams.limit(input, length));
byte[] data = ByteStreams.toByteArray(new LimitInputStream(input, length));
out.write(ByteBuffer.wrap(data));
return data.length;
@ -298,7 +316,7 @@ class ByteBufAdapter extends AbstractByteBuf {
@Override
public int setBytes(int index, InputStream in, int length) throws IOException {
InputStream limit = ByteStreams.limit(in, length);
LimitInputStream limit = new LimitInputStream(in, length);
ByteStreams.copy(limit, output);
return length - limit.available();
}

View File

@ -0,0 +1,38 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import net.minecraft.util.io.netty.channel.Channel;
import com.comphenix.protocol.compat.netty.WrappedChannel;
/**
* @author dmulloy2
*/
public class ShadedChannel implements WrappedChannel {
private final Channel channel;
public ShadedChannel(Channel channel) {
this.channel = channel;
}
@Override
public void writeAndFlush(Object packet) {
channel.writeAndFlush(packet);
}
}

View File

@ -1,18 +1,20 @@
package com.comphenix.protocol.injector.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.ChannelPromise;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.internal.TypeParameterMatcher;
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
@ -27,6 +29,19 @@ import java.util.NoSuchElementException;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import net.minecraft.util.io.netty.buffer.ByteBuf;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelHandler;
import net.minecraft.util.io.netty.channel.ChannelHandlerAdapter;
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
import net.minecraft.util.io.netty.channel.ChannelInboundHandlerAdapter;
import net.minecraft.util.io.netty.channel.ChannelPipeline;
import net.minecraft.util.io.netty.channel.ChannelPromise;
import net.minecraft.util.io.netty.channel.socket.SocketChannel;
import net.minecraft.util.io.netty.handler.codec.ByteToMessageDecoder;
import net.minecraft.util.io.netty.handler.codec.MessageToByteEncoder;
import net.minecraft.util.io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.util.io.netty.util.internal.TypeParameterMatcher;
import net.sf.cglib.proxy.Factory;
import org.bukkit.Bukkit;
@ -35,12 +50,18 @@ import org.bukkit.entity.Player;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.compat.netty.ChannelInjector;
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
import com.comphenix.protocol.compat.netty.WrappedChannel;
import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.error.ReportType;
import com.comphenix.protocol.events.ConnectionSide;
import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.injector.NetworkProcessor;
import com.comphenix.protocol.injector.netty.ChannelListener;
import com.comphenix.protocol.injector.netty.NettyNetworkMarker;
import com.comphenix.protocol.injector.netty.WirePacket;
import com.comphenix.protocol.injector.server.SocketInjector;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.VolatileField;
@ -59,7 +80,7 @@ import com.google.common.collect.MapMaker;
* Represents a channel injector.
* @author Kristian
*/
class ChannelInjector extends ByteToMessageDecoder implements Injector {
public class ShadedChannelInjector extends ByteToMessageDecoder implements ChannelInjector {
public static final ReportType REPORT_CANNOT_INTERCEPT_SERVER_PACKET = new ReportType("Unable to intercept a written server packet.");
public static final ReportType REPORT_CANNOT_INTERCEPT_CLIENT_PACKET = new ReportType("Unable to intercept a read client packet.");
public static final ReportType REPORT_CANNOT_EXECUTE_IN_CHANNEL_THREAD = new ReportType("Cannot execute code in channel thread.");
@ -69,7 +90,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
/**
* Indicates that a packet has bypassed packet listeners.
*/
private static final PacketEvent BYPASSED_PACKET = new PacketEvent(ChannelInjector.class);
private static final PacketEvent BYPASSED_PACKET = new PacketEvent(ShadedChannelInjector.class);
// The login packet
private static Class<?> PACKET_LOGIN_CLIENT = null;
@ -87,7 +108,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
private static MethodAccessor PROTOCOL_VERSION;
// The factory that created this injector
private InjectionFactory factory;
private ShadedInjectionFactory factory;
// The player, or temporary player
private Player player;
@ -151,7 +172,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
* @param channelListener - a listener.
* @param factory - the factory that created this injector
*/
public ChannelInjector(Player player, Object networkManager, Channel channel, ChannelListener channelListener, InjectionFactory factory) {
public ShadedChannelInjector(Player player, Object networkManager, Channel channel, ChannelListener channelListener, ShadedInjectionFactory factory) {
this.player = Preconditions.checkNotNull(player, "player cannot be NULL");
this.networkManager = Preconditions.checkNotNull(networkManager, "networkMananger cannot be NULL");
this.originalChannel = Preconditions.checkNotNull(channel, "channel cannot be NULL");
@ -210,7 +231,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
}
// Don't inject the same channel twice
if (findChannelHandler(originalChannel, ChannelInjector.class) != null) {
if (findChannelHandler(originalChannel, ShadedChannelInjector.class) != null) {
return false;
}
@ -237,16 +258,16 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
protected void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) throws Exception {
if (packet instanceof WirePacket) {
// Special case for wire format
ChannelInjector.this.encodeWirePacket((WirePacket) packet, output);
ShadedChannelInjector.this.encodeWirePacket((WirePacket) packet, new ShadedByteBuf(output));
} else {
ChannelInjector.this.encode(ctx, packet, output);
ShadedChannelInjector.this.encode(ctx, packet, output);
}
}
@Override
public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception {
super.write(ctx, packet, promise);
ChannelInjector.this.finalWrite(ctx, packet, promise);
ShadedChannelInjector.this.finalWrite(ctx, packet, promise);
}
};
@ -256,7 +277,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// Execute context first
ctx.fireChannelRead(msg);
ChannelInjector.this.finishRead(ctx, msg);
ShadedChannelInjector.this.finishRead(ctx, msg);
}
};
@ -280,9 +301,9 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
originalChannel.pipeline().addLast("protocol_lib_exception_handler", exceptionHandler);
// Intercept all write methods
channelField.setValue(new ChannelProxy(originalChannel, MinecraftReflection.getPacketClass()) {
channelField.setValue(new ShadedChannelProxy(originalChannel, MinecraftReflection.getPacketClass()) {
// Compatibility with Spigot 1.8
private final PipelineProxy pipelineProxy = new PipelineProxy(originalChannel.pipeline(), this) {
private final ShadedPipelineProxy pipelineProxy = new ShadedPipelineProxy(originalChannel.pipeline(), this) {
@Override
public ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler) {
// Correct the position of the decoder
@ -351,7 +372,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
NetworkMarker marker = getMarker(original);
if (marker != null) {
PacketEvent result = new PacketEvent(ChannelInjector.class);
PacketEvent result = new PacketEvent(ShadedChannelInjector.class);
result.setNetworkMarker(marker);
return result;
} else {
@ -392,7 +413,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
* @return The resulting message/packet.
*/
private PacketEvent processSending(Object message) {
return channelListener.onPacketSending(ChannelInjector.this, message, getMarker(message));
return channelListener.onPacketSending(ShadedChannelInjector.this, message, getMarker(message));
}
/**
@ -413,7 +434,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
super.exceptionCaught(ctx, cause);
}
protected void encodeWirePacket(WirePacket packet, ByteBuf output) throws Exception {
protected void encodeWirePacket(WirePacket packet, WrappedByteBuf output) throws Exception {
packet.writeId(output);
packet.writeBytes(output);
}
@ -841,7 +862,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
try {
command.run();
} catch (Exception e) {
ProtocolLibrary.getErrorReporter().reportDetailed(ChannelInjector.this,
ProtocolLibrary.getErrorReporter().reportDetailed(ShadedChannelInjector.this,
Report.newBuilder(REPORT_CANNOT_EXECUTE_IN_CHANNEL_THREAD).error(e).build());
}
}
@ -867,16 +888,16 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
* Represents a socket injector that foreards to the current channel injector.
* @author Kristian
*/
static class ChannelSocketInjector implements SocketInjector {
private final ChannelInjector injector;
public static class ChannelSocketInjector implements SocketInjector {
private final ShadedChannelInjector injector;
public ChannelSocketInjector(ChannelInjector injector) {
public ChannelSocketInjector(ShadedChannelInjector injector) {
this.injector = Preconditions.checkNotNull(injector, "injector cannot be NULL");
}
@Override
public Socket getSocket() throws IllegalAccessException {
return NettySocketAdaptor.adapt((SocketChannel) injector.originalChannel);
return ShadedSocketAdapter.adapt((SocketChannel) injector.originalChannel);
}
@Override
@ -914,12 +935,13 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
injector.setPlayer(updatedPlayer);
}
public ChannelInjector getChannelInjector() {
public ShadedChannelInjector getChannelInjector() {
return injector;
}
}
public Channel getChannel() {
return originalChannel;
@Override
public WrappedChannel getChannel() {
return new ShadedChannel(originalChannel);
}
}

View File

@ -1,27 +1,43 @@
package com.comphenix.protocol.injector.netty;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelConfig;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelMetadata;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.ChannelProgressivePromise;
import io.netty.channel.ChannelPromise;
import io.netty.channel.EventLoop;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import java.lang.reflect.Field;
import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.Callable;
import net.minecraft.util.io.netty.buffer.ByteBufAllocator;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelConfig;
import net.minecraft.util.io.netty.channel.ChannelFuture;
import net.minecraft.util.io.netty.channel.ChannelMetadata;
import net.minecraft.util.io.netty.channel.ChannelPipeline;
import net.minecraft.util.io.netty.channel.ChannelProgressivePromise;
import net.minecraft.util.io.netty.channel.ChannelPromise;
import net.minecraft.util.io.netty.channel.EventLoop;
import net.minecraft.util.io.netty.util.Attribute;
import net.minecraft.util.io.netty.util.AttributeKey;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.google.common.collect.Maps;
abstract class ChannelProxy implements Channel {
public abstract class ShadedChannelProxy implements Channel {
// Mark that a certain object does not contain a message field
private static final FieldAccessor MARK_NO_MESSAGE = new FieldAccessor() {
@Override
@ -40,9 +56,9 @@ abstract class ChannelProxy implements Channel {
protected Class<?> messageClass;
// Event loop proxy
private transient EventLoopProxy loopProxy;
private transient ShadedEventLoopProxy loopProxy;
public ChannelProxy(Channel delegate, Class<?> messageClass) {
public ShadedChannelProxy(Channel delegate, Class<?> messageClass) {
this.delegate = delegate;
this.messageClass = messageClass;
}
@ -96,7 +112,7 @@ abstract class ChannelProxy implements Channel {
@Override
public EventLoop eventLoop() {
if (loopProxy == null) {
loopProxy = new EventLoopProxy() {
loopProxy = new ShadedEventLoopProxy() {
@Override
protected EventLoop getDelegate() {
return delegate.eventLoop();
@ -119,7 +135,7 @@ abstract class ChannelProxy implements Channel {
if (accessor != null) {
Callable<T> result = onMessageScheduled(callable, accessor);;
return result != null ? result : EventLoopProxy.<T>getEmptyCallable();
return result != null ? result : ShadedEventLoopProxy.<T>getEmptyCallable();
}
return callable;
}

View File

@ -1,29 +1,45 @@
package com.comphenix.protocol.injector.netty;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelPromise;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.ProgressivePromise;
import io.netty.util.concurrent.Promise;
import io.netty.util.concurrent.ScheduledFuture;
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelFuture;
import net.minecraft.util.io.netty.channel.ChannelPromise;
import net.minecraft.util.io.netty.channel.EventLoop;
import net.minecraft.util.io.netty.channel.EventLoopGroup;
import net.minecraft.util.io.netty.util.concurrent.EventExecutor;
import net.minecraft.util.io.netty.util.concurrent.Future;
import net.minecraft.util.io.netty.util.concurrent.ProgressivePromise;
import net.minecraft.util.io.netty.util.concurrent.Promise;
import net.minecraft.util.io.netty.util.concurrent.ScheduledFuture;
/**
* An event loop proxy.
* @author Kristian.
*/
abstract class EventLoopProxy implements EventLoop {
abstract class ShadedEventLoopProxy implements EventLoop {
private static final Runnable EMPTY_RUNNABLE = new Runnable() {
@Override
public void run() {
@ -80,17 +96,17 @@ abstract class EventLoopProxy implements EventLoop {
}
@Override
public <T> io.netty.util.concurrent.Future<T> submit(Callable<T> action) {
public <T> Future<T> submit(Callable<T> action) {
return getDelegate().submit(schedulingCallable(action));
}
@Override
public <T> io.netty.util.concurrent.Future<T> submit(Runnable action, T arg1) {
public <T> Future<T> submit(Runnable action, T arg1) {
return getDelegate().submit(schedulingRunnable(action), arg1);
}
@Override
public io.netty.util.concurrent.Future<?> submit(Runnable action) {
public Future<?> submit(Runnable action) {
return getDelegate().submit(schedulingRunnable(action));
}
@ -141,13 +157,13 @@ abstract class EventLoopProxy implements EventLoop {
}
@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
public <T> List<java.util.concurrent.Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
return getDelegate().invokeAll(tasks);
}
@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout,
public <T> List<java.util.concurrent.Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout,
TimeUnit unit) throws InterruptedException {
return getDelegate().invokeAll(tasks, timeout, unit);
}
@ -175,7 +191,7 @@ abstract class EventLoopProxy implements EventLoop {
}
@Override
public <V> io.netty.util.concurrent.Future<V> newFailedFuture(Throwable arg0) {
public <V> Future<V> newFailedFuture(Throwable arg0) {
return getDelegate().newFailedFuture(arg0);
}
@ -195,7 +211,7 @@ abstract class EventLoopProxy implements EventLoop {
}
@Override
public <V> io.netty.util.concurrent.Future<V> newSucceededFuture(V arg0) {
public <V> Future<V> newSucceededFuture(V arg0) {
return getDelegate().newSucceededFuture(arg0);
}
@ -215,17 +231,17 @@ abstract class EventLoopProxy implements EventLoop {
}
@Override
public io.netty.util.concurrent.Future<?> shutdownGracefully() {
public Future<?> shutdownGracefully() {
return getDelegate().shutdownGracefully();
}
@Override
public io.netty.util.concurrent.Future<?> shutdownGracefully(long arg0, long arg1, TimeUnit arg2) {
public Future<?> shutdownGracefully(long arg0, long arg1, TimeUnit arg2) {
return getDelegate().shutdownGracefully(arg0, arg1, arg2);
}
@Override
public io.netty.util.concurrent.Future<?> terminationFuture() {
public Future<?> terminationFuture() {
return getDelegate().terminationFuture();
}

View File

@ -1,16 +1,35 @@
package com.comphenix.protocol.injector.netty;
import io.netty.channel.Channel;
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nonnull;
import net.minecraft.util.io.netty.channel.Channel;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.injector.netty.ChannelInjector.ChannelSocketInjector;
import com.comphenix.protocol.compat.netty.shaded.ShadedChannelInjector.ChannelSocketInjector;
import com.comphenix.protocol.injector.netty.ChannelListener;
import com.comphenix.protocol.injector.netty.ClosedInjector;
import com.comphenix.protocol.injector.netty.Injector;
import com.comphenix.protocol.injector.server.SocketInjector;
import com.comphenix.protocol.injector.server.TemporaryPlayerFactory;
import com.comphenix.protocol.reflect.FuzzyReflection;
@ -24,7 +43,7 @@ import com.google.common.collect.MapMaker;
* Note that the factory will return {@link ClosedInjector} when the factory is closed.
* @author Kristian
*/
class InjectionFactory {
public class ShadedInjectionFactory {
// This should work as long as the injectors are, uh, injected
private final ConcurrentMap<Player, Injector> playerLookup = new MapMaker().weakKeys().weakValues().makeMap();
private final ConcurrentMap<String, Injector> nameLookup = new MapMaker().weakValues().makeMap();
@ -35,7 +54,7 @@ class InjectionFactory {
// The current plugin
private final Plugin plugin;
public InjectionFactory(Plugin plugin) {
public ShadedInjectionFactory(Plugin plugin) {
this.plugin = plugin;
}
@ -74,14 +93,14 @@ class InjectionFactory {
Channel channel = FuzzyReflection.getFieldValue(networkManager, Channel.class, true);
// See if a channel has already been created
injector = (ChannelInjector) ChannelInjector.findChannelHandler(channel, ChannelInjector.class);
injector = (ShadedChannelInjector) ShadedChannelInjector.findChannelHandler(channel, ShadedChannelInjector.class);
if (injector != null) {
// Update the player instance
playerLookup.remove(injector.getPlayer());
injector.setPlayer(player);
} else {
injector = new ChannelInjector(player, networkManager, channel, listener, this);
injector = new ShadedChannelInjector(player, networkManager, channel, listener, this);
}
// Cache injector and return
@ -125,7 +144,7 @@ class InjectionFactory {
Object networkManager = findNetworkManager(channel);
Player temporaryPlayer = playerFactory.createTemporaryPlayer(Bukkit.getServer());
ChannelInjector injector = new ChannelInjector(temporaryPlayer, networkManager, channel, listener, this);
ShadedChannelInjector injector = new ShadedChannelInjector(temporaryPlayer, networkManager, channel, listener, this);
// Initialize temporary player
TemporaryPlayerFactory.setInjectorInPlayer(temporaryPlayer, new ChannelSocketInjector(injector));
@ -170,7 +189,7 @@ class InjectionFactory {
* @param player - the temporary player, or normal Bukkit player.
* @return The associated injector, or NULL if this is a Bukkit player.
*/
private ChannelInjector getTemporaryInjector(Player player) {
private ShadedChannelInjector getTemporaryInjector(Player player) {
SocketInjector injector = TemporaryPlayerFactory.getInjectorFromPlayer(player);
if (injector != null) {
@ -186,7 +205,7 @@ class InjectionFactory {
*/
private Object findNetworkManager(Channel channel) {
// Find the network manager
Object networkManager = ChannelInjector.findChannelHandler(channel, MinecraftReflection.getNetworkManagerClass());
Object networkManager = ShadedChannelInjector.findChannelHandler(channel, MinecraftReflection.getNetworkManagerClass());
if (networkManager != null)
return networkManager;

View File

@ -0,0 +1,103 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/package com.comphenix.protocol.compat.netty.shaded;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import net.minecraft.util.io.netty.buffer.ByteBuf;
import net.minecraft.util.io.netty.buffer.Unpooled;
import net.minecraft.util.io.netty.buffer.UnpooledByteBufAllocator;
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
import net.minecraft.util.io.netty.handler.codec.base64.Base64;
import net.minecraft.util.io.netty.util.concurrent.GenericFutureListener;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.compat.netty.NettyCompat;
import com.comphenix.protocol.compat.netty.ProtocolInjector;
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.injector.ListenerInvoker;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.WrappedServerPing.CompressedImage;
import com.google.common.base.Charsets;
/**
* @author dmulloy2
*/
public class ShadedNetty implements NettyCompat {
@Override
public WrappedByteBuf createPacketBuffer() {
return getPacketDataSerializer(allocateUnpooled());
}
private WrappedByteBuf getPacketDataSerializer(WrappedByteBuf buffer) {
Class<?> packetSerializer = MinecraftReflection.getPacketDataSerializerClass();
try {
return new ShadedByteBuf((ByteBuf) packetSerializer.getConstructor(MinecraftReflection.getByteBufClass())
.newInstance(buffer.getHandle()));
} catch (Exception e) {
throw new RuntimeException("Cannot construct packet serializer.", e);
}
}
@Override
public WrappedByteBuf allocateUnpooled() {
return new ShadedByteBuf(UnpooledByteBufAllocator.DEFAULT.buffer());
}
@Override
public Class<?> getGenericFutureListenerArray() {
return GenericFutureListener[].class;
}
@Override
public Class<?> getChannelHandlerContext() {
return ChannelHandlerContext.class;
}
@Override
public String toEncodedText(CompressedImage image) {
final ByteBuf buffer = Unpooled.wrappedBuffer(image.getDataCopy());
String computed = "data:" + image.getMime() + ";base64," +
Base64.encode(buffer).toString(Charsets.UTF_8);
return computed;
}
@Override
public WrappedByteBuf decode(byte[] encoded) {
return new ShadedByteBuf(Base64.decode(Unpooled.wrappedBuffer(encoded)));
}
@Override
public ProtocolInjector getProtocolInjector(Plugin plugin, ListenerInvoker invoker, ErrorReporter reporter) {
return new ShadedProtocolInjector(plugin, invoker, reporter);
}
@Override
public WrappedByteBuf packetReader(DataInputStream input) {
return new ShadedByteBuf(ShadedByteBufAdapter.packetReader(input));
}
@Override
public WrappedByteBuf packetWriter(DataOutputStream output) {
return new ShadedByteBuf(ShadedByteBufAdapter.packetWriter(output));
}
}

View File

@ -1,12 +1,20 @@
package com.comphenix.protocol.injector.netty;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.ChannelPromise;
import io.netty.util.concurrent.EventExecutorGroup;
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import java.net.SocketAddress;
import java.util.Iterator;
@ -14,15 +22,23 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelFuture;
import net.minecraft.util.io.netty.channel.ChannelHandler;
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
import net.minecraft.util.io.netty.channel.ChannelPipeline;
import net.minecraft.util.io.netty.channel.ChannelPromise;
import net.minecraft.util.io.netty.util.concurrent.EventExecutorGroup;
/**
* A pipeline proxy.
* @author Kristian
*/
public class PipelineProxy implements ChannelPipeline {
public class ShadedPipelineProxy implements ChannelPipeline {
protected final ChannelPipeline pipeline;
protected final Channel channel;
public PipelineProxy(ChannelPipeline pipeline, Channel channel) {
public ShadedPipelineProxy(ChannelPipeline pipeline, Channel channel) {
this.pipeline = pipeline;
this.channel = channel;
}

View File

@ -1,12 +1,20 @@
package com.comphenix.protocol.injector.netty;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import java.io.InputStream;
import java.lang.reflect.Field;
@ -16,10 +24,21 @@ import java.net.InetSocketAddress;
import java.util.List;
import java.util.Set;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelFuture;
import net.minecraft.util.io.netty.channel.ChannelHandler;
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
import net.minecraft.util.io.netty.channel.ChannelInboundHandler;
import net.minecraft.util.io.netty.channel.ChannelInboundHandlerAdapter;
import net.minecraft.util.io.netty.channel.ChannelInitializer;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.compat.netty.ChannelInjector;
import com.comphenix.protocol.compat.netty.ProtocolInjector;
import com.comphenix.protocol.compat.netty.WrappedChannel;
import com.comphenix.protocol.concurrency.PacketTypeSet;
import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.error.Report;
@ -30,6 +49,9 @@ import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.injector.ListenerInvoker;
import com.comphenix.protocol.injector.netty.ChannelListener;
import com.comphenix.protocol.injector.netty.Injector;
import com.comphenix.protocol.injector.netty.NettyNetworkMarker;
import com.comphenix.protocol.injector.packet.PacketInjector;
import com.comphenix.protocol.injector.packet.PacketRegistry;
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
@ -41,8 +63,7 @@ import com.comphenix.protocol.reflect.VolatileField;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.google.common.collect.Lists;
public class NettyProtocolInjector implements ChannelListener {
public class ShadedProtocolInjector implements ProtocolInjector {
public static final ReportType REPORT_CANNOT_INJECT_INCOMING_CHANNEL = new ReportType("Unable to inject incoming channel %s.");
private volatile boolean injected;
@ -53,7 +74,7 @@ public class NettyProtocolInjector implements ChannelListener {
private List<VolatileField> bootstrapFields = Lists.newArrayList();
// The channel injector factory
private InjectionFactory injectionFactory;
private ShadedInjectionFactory injectionFactory;
// List of network managers
private volatile List<Object> networkManagers;
@ -73,8 +94,8 @@ public class NettyProtocolInjector implements ChannelListener {
private ErrorReporter reporter;
private boolean debug;
public NettyProtocolInjector(Plugin plugin, ListenerInvoker invoker, ErrorReporter reporter) {
this.injectionFactory = new InjectionFactory(plugin);
public ShadedProtocolInjector(Plugin plugin, ListenerInvoker invoker, ErrorReporter reporter) {
this.injectionFactory = new ShadedInjectionFactory(plugin);
this.invoker = invoker;
this.reporter = reporter;
}
@ -88,6 +109,7 @@ public class NettyProtocolInjector implements ChannelListener {
* Set whether or not the debug mode is enabled.
* @param debug - TRUE if it is, FALSE otherwise.
*/
@Override
public void setDebug(boolean debug) {
this.debug = debug;
}
@ -95,7 +117,8 @@ public class NettyProtocolInjector implements ChannelListener {
/**
* Inject into the spigot connection class.
*/
@SuppressWarnings("unchecked")
@Override
@SuppressWarnings("unchecked")
public synchronized void inject() {
if (injected)
throw new IllegalStateException("Cannot inject twice.");
@ -128,10 +151,10 @@ public class NettyProtocolInjector implements ChannelListener {
try {
// This can take a while, so we need to stop the main thread from interfering
synchronized (networkManagers) {
injectionFactory.fromChannel(channel, NettyProtocolInjector.this, playerFactory).inject();
injectionFactory.fromChannel(channel, ShadedProtocolInjector.this, playerFactory).inject();
}
} catch (Exception e) {
reporter.reportDetailed(NettyProtocolInjector.this, Report.newBuilder(REPORT_CANNOT_INJECT_INCOMING_CHANNEL).
reporter.reportDetailed(ShadedProtocolInjector.this, Report.newBuilder(REPORT_CANNOT_INJECT_INCOMING_CHANNEL).
messageParam(channel).error(e));
}
}
@ -174,7 +197,7 @@ public class NettyProtocolInjector implements ChannelListener {
}
// Synchronize with each list before we attempt to replace them.
field.setValue(new BootstrapList(list, connectionHandler));
field.setValue(new ShadedBootstrapList(list, connectionHandler));
}
injected = true;
@ -227,7 +250,8 @@ public class NettyProtocolInjector implements ChannelListener {
/**
* Clean up any remaning injections.
*/
public synchronized void close() {
@Override
public synchronized void close() {
if (!closed) {
closed = true;
@ -235,8 +259,8 @@ public class NettyProtocolInjector implements ChannelListener {
Object value = field.getValue();
// Undo the processed channels, if any
if (value instanceof BootstrapList) {
((BootstrapList) value).close();
if (value instanceof ShadedBootstrapList) {
((ShadedBootstrapList) value).close();
}
field.revertValue();
}
@ -304,9 +328,10 @@ public class NettyProtocolInjector implements ChannelListener {
}
// Server side
@Override
public PlayerInjectionHandler getPlayerInjector() {
return new AbstractPlayerHandler(sendingFilters) {
private ChannelListener listener = NettyProtocolInjector.this;
private ChannelListener listener = ShadedProtocolInjector.this;
@Override
public int getProtocolVersion(Player player) {
@ -377,7 +402,7 @@ public class NettyProtocolInjector implements ChannelListener {
}
@Override
public Channel getChannel(Player player) {
public WrappedChannel getChannel(Player player) {
Injector injector = injectionFactory.fromPlayer(player, listener);
if (injector instanceof ChannelInjector) {
return ((ChannelInjector) injector).getChannel();
@ -393,12 +418,13 @@ public class NettyProtocolInjector implements ChannelListener {
* @return The packet injector.
*/
// Client side
@Override
public PacketInjector getPacketInjector() {
return new AbstractPacketInjector(reveivedFilters) {
@Override
public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) {
NetworkMarker marker = buffered != null ? new NettyNetworkMarker(ConnectionSide.CLIENT_SIDE, buffered) : null;
injectionFactory.fromPlayer(client, NettyProtocolInjector.this).
injectionFactory.fromPlayer(client, ShadedProtocolInjector.this).
saveMarker(packet.getHandle(), marker);
return packetReceived(packet, client, marker);
}

View File

@ -1,8 +1,20 @@
package com.comphenix.protocol.injector.netty;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.SocketChannel;
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.compat.netty.shaded;
import java.io.IOException;
import java.io.InputStream;
@ -12,6 +24,10 @@ import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelOption;
import net.minecraft.util.io.netty.channel.socket.SocketChannel;
/**
* This class wraps a Netty {@link Channel} in a {@link Socket}. It overrides
* all methods in {@link Socket} to ensure that calls are not mistakingly made
@ -20,15 +36,15 @@ import java.net.SocketException;
* {@link UnsupportedOperationException}.
*/
// Thanks MD5. :)
class NettySocketAdaptor extends Socket {
public class ShadedSocketAdapter extends Socket {
private final SocketChannel ch;
private NettySocketAdaptor(SocketChannel ch) {
private ShadedSocketAdapter(SocketChannel ch) {
this.ch = ch;
}
public static NettySocketAdaptor adapt(SocketChannel ch) {
return new NettySocketAdaptor(ch);
public static ShadedSocketAdapter adapt(SocketChannel ch) {
return new ShadedSocketAdapter(ch);
}
@Override
@ -54,7 +70,7 @@ class NettySocketAdaptor extends Socket {
@Override
public boolean equals(Object obj) {
return obj instanceof NettySocketAdaptor && ch.equals(((NettySocketAdaptor) obj).ch);
return obj instanceof ShadedSocketAdapter && ch.equals(((ShadedSocketAdapter) obj).ch);
}
@Override

View File

@ -1,47 +1,26 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>3.6.3-SNAPSHOT</version>
<version>3.6.4-SNAPSHOT</version>
<name>ProtocolLib</name>
<description>Provides read/write access to the Minecraft protocol.</description>
<url>http://www.spigotmc.org/resources/protocollib.1997/</url>
<packaging>jar</packaging>
<parent>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib-Parent</artifactId>
<version>3</version>
<relativePath>../</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>cp1252</project.build.sourceEncoding>
<project.build.number></project.build.number>
<jarName>ProtocolLib</jarName>
</properties>
<distributionManagement>
<repository>
<id>dmulloy2-releases</id>
<url>http://repo.dmulloy2.net/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>dmulloy2-snapshots</id>
<url>http://repo.dmulloy2.net/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>dmulloy2-repo</id>
<url>http://repo.dmulloy2.net/content/groups/public/</url>
</repository>
<repository>
<id>md_5-repo</id>
<url>http://repo.md-5.net/content/groups/public/</url>
</repository>
</repositories>
<build>
<defaultGoal>clean install</defaultGoal>
<sourceDirectory>src/main/java</sourceDirectory>
@ -107,7 +86,7 @@
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
<finalName>${jarName}</finalName>
<finalName>ProtocolLib</finalName>
</configuration>
</plugin>
@ -284,15 +263,5 @@
<version>1.5</version>
<scope>test</scope>
</dependency>
<!--<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>17.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.26.Final</version>
</dependency>-->
</dependencies>
</project>

View File

@ -8,15 +8,14 @@ import java.util.Set;
import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.compat.guava.Guava;
import com.comphenix.protocol.events.ConnectionSide;
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
class PacketTypeParser {
public final static Range<Integer> DEFAULT_MAX_RANGE = Range.closed(0, 255);
public final static Range<Integer> DEFAULT_MAX_RANGE = Guava.closedRange(0, 255);
private Sender side = null;
private Protocol protocol = null;
@ -72,7 +71,7 @@ class PacketTypeParser {
}
for (Range<Integer> range : ranges) {
for (Integer id : ContiguousSet.create(range, DiscreteDomain.integers())) {
for (Integer id : Guava.toSet(range)) {
// Deprecated packets
if (protocol == null) {
if (PacketType.hasLegacy(id)) {

View File

@ -697,4 +697,8 @@ public class ProtocolLibrary extends JavaPlugin {
public static void log(String message, Object... args) {
log(Level.INFO, message, args);
}
public static Logger getStaticLogger() {
return logger;
}
}

View File

@ -23,8 +23,7 @@ import java.util.Arrays;
import java.util.Deque;
import java.util.List;
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.comphenix.protocol.compat.guava.Guava;
import com.google.common.collect.Range;
/**
@ -68,7 +67,7 @@ class RangeParser {
throw new IllegalArgumentException("Cannot form a range without a upper limit.");
// This is a proper range
range = Range.closed(Integer.parseInt(current), Integer.parseInt(tokens.get(i + 2)));
range = Guava.closedRange(Integer.parseInt(current), Integer.parseInt(tokens.get(i + 2)));
ranges.add(range);
// Skip the two next tokens
@ -76,7 +75,7 @@ class RangeParser {
} else {
// Just a single number
range = Range.singleton(Integer.parseInt(current));
range = Guava.singleton(Integer.parseInt(current));
ranges.add(range);
}
@ -102,7 +101,7 @@ class RangeParser {
// Set every ID
for (Range<Integer> range : ranges) {
for (int id : ContiguousSet.create(range, DiscreteDomain.integers())) {
for (int id : Guava.toSet(range)) {
set[id] = true;
}
}
@ -115,7 +114,7 @@ class RangeParser {
}
} else {
if (start >= 0) {
result.add(Range.closed(start, i - 1));
result.add(Guava.closedRange(start, i - 1));
start = -1;
}
}

View File

@ -23,6 +23,7 @@ import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
import com.comphenix.protocol.compat.guava.Guava;
import com.google.common.base.Objects;
import com.google.common.collect.Range;
@ -67,7 +68,7 @@ public abstract class AbstractIntervalTree<TKey extends Comparable<TKey>, TValue
@Override
public Range<TKey> getKey() {
return Range.closed(left.key, right.key);
return Guava.closedRange(left.key, right.key);
}
@Override

View File

@ -17,9 +17,6 @@
package com.comphenix.protocol.events;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.UnpooledByteBufAllocator;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
@ -50,6 +47,8 @@ import org.bukkit.util.Vector;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.compat.netty.Netty;
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
import com.comphenix.protocol.injector.StructureCache;
import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.FuzzyReflection;
@ -102,7 +101,6 @@ import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mojang.authlib.GameProfile;
/**
* Represents a Minecraft packet indirectly.
@ -606,7 +604,7 @@ public class PacketContainer implements Serializable {
public StructureModifier<WrappedGameProfile> getGameProfiles() {
// Convert to and from the Bukkit wrapper
return structureModifier.<WrappedGameProfile>withType(
GameProfile.class, BukkitConverters.getWrappedGameProfileConverter());
MinecraftReflection.getGameProfileClass(), BukkitConverters.getWrappedGameProfileConverter());
}
/**
@ -930,12 +928,11 @@ public class PacketContainer implements Serializable {
try {
if (MinecraftReflection.isUsingNetty()) {
ByteBuf buffer = createPacketBuffer();
MinecraftMethods.getPacketWriteByteBufMethod().invoke(handle, buffer);
WrappedByteBuf buffer = createPacketBuffer();
MinecraftMethods.getPacketWriteByteBufMethod().invoke(handle, buffer.getHandle());
output.writeInt(buffer.readableBytes());
buffer.readBytes(output, buffer.readableBytes());
} else {
// Call the write-method
output.writeInt(-1);
@ -968,10 +965,10 @@ public class PacketContainer implements Serializable {
// Call the read method
try {
if (MinecraftReflection.isUsingNetty()) {
ByteBuf buffer = createPacketBuffer();
WrappedByteBuf buffer = createPacketBuffer();
buffer.writeBytes(input, input.readInt());
MinecraftMethods.getPacketReadByteBufMethod().invoke(handle, buffer);
MinecraftMethods.getPacketReadByteBufMethod().invoke(handle, buffer.getHandle());
} else {
if (input.readInt() != -1)
throw new IllegalArgumentException("Cannot load a packet from 1.7.2 in 1.6.4.");
@ -996,8 +993,8 @@ public class PacketContainer implements Serializable {
* Construct a new packet data serializer.
* @return The packet data serializer.
*/
private ByteBuf createPacketBuffer() {
return MinecraftReflection.getPacketDataSerializer(UnpooledByteBufAllocator.DEFAULT.buffer());
private WrappedByteBuf createPacketBuffer() {
return Netty.createPacketBuffer();
}
// ---- Metadata

View File

@ -17,8 +17,6 @@
package com.comphenix.protocol.injector;
import io.netty.channel.Channel;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
@ -56,6 +54,9 @@ import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.async.AsyncFilterManager;
import com.comphenix.protocol.async.AsyncMarker;
import com.comphenix.protocol.compat.netty.Netty;
import com.comphenix.protocol.compat.netty.ProtocolInjector;
import com.comphenix.protocol.compat.netty.WrappedChannel;
import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.error.ReportType;
@ -68,7 +69,6 @@ import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.injector.netty.NettyProtocolInjector;
import com.comphenix.protocol.injector.netty.WirePacket;
import com.comphenix.protocol.injector.packet.InterceptWritePacket;
import com.comphenix.protocol.injector.packet.PacketInjector;
@ -205,7 +205,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
private SpigotPacketInjector spigotInjector;
// Netty injector (for 1.7.2)
private NettyProtocolInjector nettyInjector;
private ProtocolInjector nettyInjector;
// Plugin verifier
private PluginVerifier pluginVerifier;
@ -273,7 +273,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
// Use the correct injection type
if (MinecraftReflection.isUsingNetty()) {
this.nettyInjector = new NettyProtocolInjector(builder.getLibrary(), this, reporter);
this.nettyInjector = Netty.getProtocolInjector(builder.getLibrary(), this, reporter);
this.playerInjection = nettyInjector.getPlayerInjector();
this.packetInjector = nettyInjector.getPacketInjector();
@ -845,7 +845,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
@Override
public void sendWirePacket(Player receiver, WirePacket packet) throws InvocationTargetException {
Channel channel = playerInjection.getChannel(receiver);
WrappedChannel channel = playerInjection.getChannel(receiver);
if (channel == null) {
throw new InvocationTargetException(new NullPointerException(), "Failed to obtain channel for " + receiver.getName());
}

View File

@ -4,12 +4,11 @@ import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketEvent;
/**
* Represents a listener for received or sent packets.
* @author Kristian
*/
interface ChannelListener {
public interface ChannelListener {
/**
* Invoked when a packet is being sent to the client.
* <p>

View File

@ -9,7 +9,7 @@ import com.comphenix.protocol.events.NetworkMarker;
* Represents a closed injector.
* @author Kristian
*/
class ClosedInjector implements Injector {
public class ClosedInjector implements Injector {
private Player player;
/**

View File

@ -9,7 +9,7 @@ import com.comphenix.protocol.events.NetworkMarker;
* Represents an injected client connection.
* @author Kristian
*/
interface Injector {
public interface Injector {
/**
* Retrieve the current protocol version of the player.
* @return Protocol version.

View File

@ -10,7 +10,7 @@ import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.ConnectionSide;
import com.comphenix.protocol.events.NetworkMarker;
class NettyNetworkMarker extends NetworkMarker {
public class NettyNetworkMarker extends NetworkMarker {
public NettyNetworkMarker(@Nonnull ConnectionSide side, byte[] inputBuffer) {
super(side, inputBuffer, null);
}

View File

@ -16,7 +16,7 @@
*/
package com.comphenix.protocol.injector.netty;
import io.netty.buffer.ByteBuf;
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
/**
* @author dmulloy2
@ -39,7 +39,7 @@ public class WirePacket {
return bytes;
}
public void writeId(ByteBuf output) {
public void writeId(WrappedByteBuf output) {
int i = id;
while ((i & -128) != 0) {
output.writeByte(i & 127 | 128);
@ -49,7 +49,7 @@ public class WirePacket {
output.writeByte(i);
}
public void writeBytes(ByteBuf output) {
public void writeBytes(WrappedByteBuf output) {
output.writeBytes(bytes);
}
}

View File

@ -1,17 +1,15 @@
package com.comphenix.protocol.injector.packet;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import javax.annotation.Nonnull;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.compat.guava.Guava;
import com.comphenix.protocol.events.ConnectionSide;
import com.comphenix.protocol.events.NetworkMarker;
import com.google.common.io.ByteSource;
import com.google.common.primitives.Bytes;
/**
@ -40,26 +38,6 @@ public class LegacyNetworkMarker extends NetworkMarker {
@Override
protected DataInputStream addHeader(final DataInputStream input, final PacketType type) {
ByteSource header = new ByteSource() {
@Override
public InputStream openStream() throws IOException {
byte[] data = new byte[] { (byte) type.getLegacyId() };
return new ByteArrayInputStream(data);
}
};
ByteSource data = new ByteSource() {
@Override
public InputStream openStream() throws IOException {
return input;
}
};
// Combine them into a single stream
try {
return new DataInputStream(ByteSource.concat(header, data).openStream());
} catch (IOException e) {
throw new RuntimeException("Cannot add header.", e);
}
return Guava.addHeader(input, type);
}
}
}

View File

@ -1,7 +1,5 @@
package com.comphenix.protocol.injector.player;
import io.netty.channel.Channel;
import java.io.DataInputStream;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
@ -11,6 +9,7 @@ import java.util.Set;
import org.bukkit.entity.Player;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.compat.netty.WrappedChannel;
import com.comphenix.protocol.events.ListenerOptions;
import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketContainer;
@ -201,5 +200,5 @@ public interface PlayerInjectionHandler {
*/
public abstract boolean hasMainThreadListener(PacketType type);
public abstract Channel getChannel(Player player);
public abstract WrappedChannel getChannel(Player player);
}

View File

@ -17,8 +17,6 @@
package com.comphenix.protocol.injector.player;
import io.netty.channel.Channel;
import java.io.DataInputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
@ -39,6 +37,7 @@ import org.bukkit.entity.Player;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.Packets;
import com.comphenix.protocol.compat.netty.WrappedChannel;
import com.comphenix.protocol.concurrency.BlockingHashMap;
import com.comphenix.protocol.concurrency.IntegerSet;
import com.comphenix.protocol.error.ErrorReporter;
@ -757,7 +756,7 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler {
}
@Override
public Channel getChannel(Player player) {
public WrappedChannel getChannel(Player player) {
throw new UnsupportedOperationException();
}
}

View File

@ -1,7 +1,5 @@
package com.comphenix.protocol.injector.spigot;
import io.netty.channel.Channel;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.InetSocketAddress;
@ -9,6 +7,7 @@ import java.net.InetSocketAddress;
import org.bukkit.entity.Player;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.compat.netty.WrappedChannel;
import com.comphenix.protocol.concurrency.PacketTypeSet;
import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketContainer;
@ -86,7 +85,7 @@ class DummyPlayerHandler extends AbstractPlayerHandler {
}
@Override
public Channel getChannel(Player player) {
public WrappedChannel getChannel(Player player) {
throw new UnsupportedOperationException();
}
}

View File

@ -1,10 +1,5 @@
package com.comphenix.protocol.utility;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.GenericFutureListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
@ -15,6 +10,7 @@ import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.compat.netty.Netty;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.FuzzyReflection;
@ -98,7 +94,7 @@ public class MinecraftMethods {
public static Method getNetworkManagerHandleMethod() {
if (networkManagerHandle == null) {
networkManagerHandle = FuzzyReflection.fromClass(MinecraftReflection.getNetworkManagerClass(), true).
getMethodByParameters("handle", MinecraftReflection.getPacketClass(), GenericFutureListener[].class);
getMethodByParameters("handle", MinecraftReflection.getPacketClass(), Netty.getGenericFutureListenerArray());
networkManagerHandle.setAccessible(true);
}
return networkManagerHandle;
@ -113,7 +109,7 @@ public class MinecraftMethods {
public static Method getNetworkManagerReadPacketMethod() {
if (networkManagerPacketRead == null) {
networkManagerPacketRead = FuzzyReflection.fromClass(MinecraftReflection.getNetworkManagerClass(), true).
getMethodByParameters("packetRead", ChannelHandlerContext.class, MinecraftReflection.getPacketClass());
getMethodByParameters("packetRead", Netty.getChannelHandlerContext(), MinecraftReflection.getPacketClass());
networkManagerPacketRead.setAccessible(true);
}
return networkManagerPacketRead;
@ -177,8 +173,8 @@ public class MinecraftMethods {
// Create our proxy object
Object javaProxy = enhancer.create(
new Class<?>[] { ByteBuf.class },
new Object[] { UnpooledByteBufAllocator.DEFAULT.buffer() }
new Class<?>[] { MinecraftReflection.getByteBufClass() },
new Object[] { Netty.allocateUnpooled().getHandle() }
);
Object lookPacket = new PacketContainer(PacketType.Play.Client.CLOSE_WINDOW).getHandle();

View File

@ -17,8 +17,6 @@
package com.comphenix.protocol.utility;
import io.netty.buffer.ByteBuf;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.lang.reflect.Array;
@ -69,7 +67,6 @@ import com.comphenix.protocol.wrappers.nbt.NbtFactory;
import com.comphenix.protocol.wrappers.nbt.NbtType;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile;
/**
* Methods and constants specifically used in conjuction with reflecting Minecraft object.
@ -571,6 +568,7 @@ public class MinecraftReflection {
/**
* Retrieve the GameProfile class in 1.7.2 and later.
*
* @return The game profile class.
* @throws IllegalStateException If we are running 1.6.4 or earlier.
*/
@ -579,14 +577,18 @@ public class MinecraftReflection {
throw new IllegalStateException("GameProfile does not exist in version 1.6.4 and earlier.");
try {
return GameProfile.class;
return getClass("com.mojang.authlib.GameProfile");
} catch (Throwable ex) {
FuzzyReflection reflection = FuzzyReflection.fromClass(PacketType.Login.Client.START.getPacketClass(), true);
FuzzyFieldContract contract = FuzzyFieldContract.newBuilder()
.banModifier(Modifier.STATIC)
.typeMatches(FuzzyMatchers.matchRegex("(.*)(GameProfile)", 1))
.build();
return reflection.getField(contract).getType();
try {
return getClass("net.minecraft.util.com.mojang.authlib.GameProfile");
} catch (Throwable ex1) {
FuzzyReflection reflection = FuzzyReflection.fromClass(PacketType.Login.Client.START.getPacketClass(), true);
FuzzyFieldContract contract = FuzzyFieldContract.newBuilder()
.banModifier(Modifier.STATIC)
.typeMatches(FuzzyMatchers.matchRegex("(.*)(GameProfile)", 1))
.build();
return reflection.getField(contract).getType();
}
}
}
@ -663,10 +665,10 @@ public class MinecraftReflection {
if (isUsingNetty()) {
paketContract = FuzzyClassContract.newBuilder().
method(FuzzyMethodContract.newBuilder().
parameterDerivedOf(ByteBuf.class).
parameterDerivedOf(getByteBufClass()).
returnTypeVoid()).
method(FuzzyMethodContract.newBuilder().
parameterDerivedOf(ByteBuf.class, 0).
parameterDerivedOf(getByteBufClass(), 0).
parameterExactType(byte[].class, 1).
returnTypeVoid()).
build();
@ -698,6 +700,14 @@ public class MinecraftReflection {
}
}
public static Class<?> getByteBufClass() {
try {
return getClass("io.netty.buffer.ByteBuf");
} catch (Throwable ex) {
return getClass("net.minecraft.util.io.netty.buffer.ByteBuf");
}
}
/**
* Retrieve the EnumProtocol class in 1.7.2.
* @return The Enum protocol class.
@ -834,7 +844,7 @@ public class MinecraftReflection {
// Find a server ping object
AbstractFuzzyMatcher<Class<?>> serverPlayerContract = FuzzyClassContract.newBuilder().
constructor(FuzzyMethodContract.newBuilder().parameterExactArray(int.class, int.class)).
field(FuzzyFieldContract.newBuilder().typeExact(GameProfile[].class)).
field(FuzzyFieldContract.newBuilder().typeExact(getArrayClass(getGameProfileClass()))).
build().
and(getMinecraftObjectMatcher());
@ -1576,7 +1586,7 @@ public class MinecraftReflection {
Method method = FuzzyReflection.fromClass(packet).getMethod(
FuzzyMethodContract.newBuilder().
parameterCount(1).
parameterDerivedOf(ByteBuf.class).
parameterDerivedOf(getByteBufClass()).
returnTypeVoid().
build()
);
@ -1614,21 +1624,6 @@ public class MinecraftReflection {
}
}
/**
* Retrieve an instance of the packet data serializer wrapper.
* @param buffer - the buffer.
* @return The instance.
*/
public static ByteBuf getPacketDataSerializer(ByteBuf buffer) {
Class<?> packetSerializer = getPacketDataSerializerClass();
try {
return (ByteBuf) packetSerializer.getConstructor(ByteBuf.class).newInstance(buffer);
} catch (Exception e) {
throw new RuntimeException("Cannot construct packet serializer.", e);
}
}
/**
* Retrieve the NMS tile entity class.
* @return The tile entity class.
@ -1923,4 +1918,19 @@ public class MinecraftReflection {
public static String getNetLoginHandlerName() {
return getNetLoginHandlerClass().getSimpleName();
}
/**
* Retrieve an instance of the packet data serializer wrapper.
* @param buffer - the buffer.
* @return The instance.
*/
public static Object getPacketDataSerializer(Object buffer) {
Class<?> packetSerializer = getPacketDataSerializerClass();
try {
return packetSerializer.getConstructor(getByteBufClass()).newInstance(buffer);
} catch (Exception e) {
throw new RuntimeException("Cannot construct packet serializer.", e);
}
}
}

View File

@ -13,6 +13,7 @@ import javax.annotation.Nonnull;
import org.bukkit.inventory.ItemStack;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import com.comphenix.protocol.compat.netty.Netty;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
@ -109,7 +110,7 @@ public class StreamSerializer {
);
}
nmsItem = READ_ITEM_METHOD.invoke(ByteBufAdapter.packetReader(input));
nmsItem = READ_ITEM_METHOD.invoke(Netty.packetReader(input).getHandle());
} else {
if (READ_ITEM_METHOD == null) {
READ_ITEM_METHOD = Accessors.getMethodAccessor(
@ -153,7 +154,7 @@ public class StreamSerializer {
);
}
nmsCompound = READ_NBT_METHOD.invoke(ByteBufAdapter.packetReader(input));
nmsCompound = READ_NBT_METHOD.invoke(Netty.packetReader(input).getHandle());
} else {
if (READ_NBT_METHOD == null) {
READ_NBT_METHOD = Accessors.getMethodAccessor(
@ -206,7 +207,7 @@ public class StreamSerializer {
);
}
return (String) READ_STRING_METHOD.invoke(ByteBufAdapter.packetReader(input), maximumLength);
return (String) READ_STRING_METHOD.invoke(Netty.packetReader(input).getHandle(), maximumLength);
} else {
if (READ_STRING_METHOD == null) {
READ_STRING_METHOD = Accessors.getMethodAccessor(
@ -266,7 +267,7 @@ public class StreamSerializer {
);
}
WRITE_ITEM_METHOD.invoke(ByteBufAdapter.packetWriter(output), nmsItem);
WRITE_ITEM_METHOD.invoke(Netty.packetWriter(output).getHandle(), nmsItem);
} else {
if (WRITE_ITEM_METHOD == null)
WRITE_ITEM_METHOD = Accessors.getMethodAccessor(
@ -307,7 +308,7 @@ public class StreamSerializer {
);
}
WRITE_NBT_METHOD.invoke(ByteBufAdapter.packetWriter(output), handle);
WRITE_NBT_METHOD.invoke(Netty.packetWriter(output).getHandle(), handle);
} else {
if (WRITE_NBT_METHOD == null) {
WRITE_NBT_METHOD = Accessors.getMethodAccessor(
@ -348,7 +349,7 @@ public class StreamSerializer {
);
}
WRITE_STRING_METHOD.invoke(ByteBufAdapter.packetWriter(output), text);
WRITE_STRING_METHOD.invoke(Netty.packetWriter(output).getHandle(), text);
} else {
if (WRITE_STRING_METHOD == null) {
WRITE_STRING_METHOD = Accessors.getMethodAccessor(

View File

@ -1,10 +1,5 @@
package com.comphenix.protocol.wrappers;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.base64.Base64;
import io.netty.util.IllegalReferenceCountException;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
@ -22,6 +17,8 @@ import org.bukkit.entity.Player;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.compat.netty.Netty;
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
import com.comphenix.protocol.injector.BukkitUnwrapper;
import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.accessors.Accessors;
@ -38,7 +35,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.mojang.authlib.GameProfile;
/**
* Represents a server ping packet data.
@ -55,6 +51,9 @@ public class WrappedServerPing extends AbstractWrapper {
.build();
private static MinecraftVersion LAST_VERSION = MinecraftVersion.BOUNTIFUL_UPDATE;
private static Class<?> GAME_PROFILE = MinecraftReflection.getGameProfileClass();
private static Class<?> GAME_PROFILE_ARRAY = MinecraftReflection.getArrayClass(GAME_PROFILE);
// Server ping fields
private static Class<?> SERVER_PING = MinecraftReflection.getServerPingClass();
private static ConstructorAccessor SERVER_PING_CONSTRUCTOR = Accessors.getConstructorAccessor(SERVER_PING);
@ -65,13 +64,13 @@ public class WrappedServerPing extends AbstractWrapper {
// For converting to the underlying array
private static EquivalentConverter<Iterable<? extends WrappedGameProfile>> PROFILE_CONVERT =
BukkitConverters.getArrayConverter(GameProfile.class, BukkitConverters.getWrappedGameProfileConverter());
BukkitConverters.getArrayConverter(GAME_PROFILE, BukkitConverters.getWrappedGameProfileConverter());
// Server ping player sample fields
private static Class<?> PLAYERS_CLASS = MinecraftReflection.getServerPingPlayerSampleClass();
private static ConstructorAccessor PLAYERS_CONSTRUCTOR = Accessors.getConstructorAccessor(PLAYERS_CLASS, int.class, int.class);
private static FieldAccessor[] PLAYERS_INTS = Accessors.getFieldAccessorArray(PLAYERS_CLASS, int.class, true);
private static FieldAccessor PLAYERS_PROFILES = Accessors.getFieldAccessor(PLAYERS_CLASS, GameProfile[].class, true);
private static FieldAccessor PLAYERS_PROFILES = Accessors.getFieldAccessor(PLAYERS_CLASS, GAME_PROFILE_ARRAY, true);
private static FieldAccessor PLAYERS_MAXIMUM = PLAYERS_INTS[0];
private static FieldAccessor PLAYERS_ONLINE = PLAYERS_INTS[1];
@ -91,7 +90,7 @@ public class WrappedServerPing extends AbstractWrapper {
// Get profile from player
private static FieldAccessor ENTITY_HUMAN_PROFILE = Accessors.getFieldAccessor(
MinecraftReflection.getEntityPlayerClass().getSuperclass(), GameProfile.class, true);
MinecraftReflection.getEntityPlayerClass().getSuperclass(), GAME_PROFILE, true);
// Inner class
private Object players; // may be NULL
@ -297,7 +296,7 @@ public class WrappedServerPing extends AbstractWrapper {
public void setPlayers(Iterable<? extends WrappedGameProfile> profile) {
if (players == null)
resetPlayers();
PLAYERS_PROFILES.set(players, (profile != null) ? PROFILE_CONVERT.getGeneric(GameProfile[].class, profile) : null);
PLAYERS_PROFILES.set(players, (profile != null) ? PROFILE_CONVERT.getGeneric(GAME_PROFILE_ARRAY, profile) : null);
}
/**
@ -308,9 +307,10 @@ public class WrappedServerPing extends AbstractWrapper {
List<WrappedGameProfile> profiles = Lists.newArrayList();
for (Player player : players) {
GameProfile profile = (GameProfile) ENTITY_HUMAN_PROFILE.get(BukkitUnwrapper.getInstance().unwrapItem(player));
Object profile = ENTITY_HUMAN_PROFILE.get(BukkitUnwrapper.getInstance().unwrapItem(player));
profiles.add(WrappedGameProfile.fromHandle(profile));
}
setPlayers(profiles);
}
@ -438,7 +438,7 @@ public class WrappedServerPing extends AbstractWrapper {
return new EncodedCompressedImage("data:image/png;base64," + base64);
} catch (IllegalArgumentException e) {
// Remind the caller
throw new IllegalReferenceCountException("Must be a pure base64 encoded string. Cannot be an encoded text.", e);
throw new IllegalArgumentException("Must be a pure base64 encoded string. Cannot be an encoded text.", e);
}
}
@ -504,12 +504,9 @@ public class WrappedServerPing extends AbstractWrapper {
*/
public String toEncodedText() {
if (encoded == null) {
final ByteBuf buffer = Unpooled.wrappedBuffer(getData());
String computed = "data:" + mime + ";base64," +
Base64.encode(buffer).toString(Charsets.UTF_8);
encoded = computed;
encoded = Netty.toEncodedText(this);
}
return encoded;
}
}
@ -541,7 +538,7 @@ public class WrappedServerPing extends AbstractWrapper {
this.mime = segment.substring(5);
} else if (segment.startsWith("base64,")) {
byte[] encoded = segment.substring(7).getBytes(Charsets.UTF_8);
ByteBuf decoded = Base64.decode(Unpooled.wrappedBuffer(encoded));
WrappedByteBuf decoded = Netty.decode(encoded);
// Read into a byte array
byte[] data = new byte[decoded.readableBytes()];

View File

@ -2,14 +2,43 @@ package com.comphenix.protocol.wrappers;
import java.security.PublicKey;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.google.common.base.Objects;
import com.mojang.authlib.properties.Property;
/**
* Represents a wrapper over a signed property.
* @author Kristian
*/
public class WrappedSignedProperty extends AbstractWrapper {
private static Class<?> PROPERTY;
private static ConstructorAccessor CONSTRUCTOR;
private static MethodAccessor GET_NAME;
private static MethodAccessor GET_SIGNATURE;
private static MethodAccessor GET_VALUE;
private static MethodAccessor HAS_SIGNATURE;
private static MethodAccessor IS_SIGNATURE_VALID;
static {
try {
PROPERTY = Class.forName("com.mojang.authlib.properties.Property");
} catch (ClassNotFoundException ex) {
try {
PROPERTY = Class.forName("net.minecraft.util.com.mojang.authlib.properties.Property");
} catch (ClassNotFoundException ex1) {
throw new RuntimeException("Failed to obtain Property class", ex);
}
}
CONSTRUCTOR = Accessors.getConstructorAccessor(PROPERTY, String.class, String.class, String.class);
GET_NAME = Accessors.getMethodAccessor(PROPERTY, "getName");
GET_SIGNATURE = Accessors.getMethodAccessor(PROPERTY, "getSignature");
GET_VALUE = Accessors.getMethodAccessor(PROPERTY, "getValue");
HAS_SIGNATURE = Accessors.getMethodAccessor(PROPERTY, "hasSignature");
IS_SIGNATURE_VALID = Accessors.getMethodAccessor(PROPERTY, "isSigntureValid", PublicKey.class);
}
/**
* Construct a new wrapped signed property from the given values.
* @param name - the name of the property.
@ -17,7 +46,7 @@ public class WrappedSignedProperty extends AbstractWrapper {
* @param signature - the BASE64-encoded signature of the value.
*/
public WrappedSignedProperty(String name, String value, String signature) {
this(new Property(name, value, signature));
this(CONSTRUCTOR.invoke(name, value, signature));
}
/**
@ -25,7 +54,7 @@ public class WrappedSignedProperty extends AbstractWrapper {
* @param handle - the handle.
*/
private WrappedSignedProperty(Object handle) {
super(Property.class);
super(PROPERTY);
setHandle(handle);
}
@ -48,21 +77,13 @@ public class WrappedSignedProperty extends AbstractWrapper {
public static WrappedSignedProperty fromValues(String name, String value, String signature) {
return new WrappedSignedProperty(name, value, signature);
}
/**
* Retrieve the underlying signed property.
* @return The GameProfile.
*/
private Property getProfile() {
return (Property) handle;
}
/**
* Retrieve the name of the underlying property, such as "textures".
* @return Name of the property.
*/
public String getName() {
return getProfile().getName();
return (String) GET_NAME.invoke(handle);
}
/**
@ -70,7 +91,7 @@ public class WrappedSignedProperty extends AbstractWrapper {
* @return The signature of the property.
*/
public String getSignature() {
return getProfile().getSignature();
return (String) GET_SIGNATURE.invoke(handle);
}
/**
@ -78,7 +99,7 @@ public class WrappedSignedProperty extends AbstractWrapper {
* @return The value of the property.
*/
public String getValue() {
return getProfile().getValue();
return (String) GET_VALUE.invoke(handle);
}
/**
@ -86,7 +107,7 @@ public class WrappedSignedProperty extends AbstractWrapper {
* @return TRUE if it does, FALSE otherwise.
*/
public boolean hasSignature() {
return getProfile().hasSignature();
return (Boolean) HAS_SIGNATURE.invoke(handle);
}
/**
@ -95,7 +116,7 @@ public class WrappedSignedProperty extends AbstractWrapper {
* @return TRUE if it is, FALSE otherwise.
*/
public boolean isSignatureValid(PublicKey key) {
return getProfile().isSignatureValid(key);
return (Boolean) IS_SIGNATURE_VALID.invoke(handle, key);
}
@Override