Adding TinyProtocol to the example directory.
Dieser Commit ist enthalten in:
Ursprung
d62955dc71
Commit
5267e73311
31
Examples/TinyProtocol/.classpath
Normale Datei
31
Examples/TinyProtocol/.classpath
Normale Datei
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
2
Examples/TinyProtocol/.gitignore
vendored
Normale Datei
2
Examples/TinyProtocol/.gitignore
vendored
Normale Datei
@ -0,0 +1,2 @@
|
||||
target/
|
||||
class/
|
23
Examples/TinyProtocol/.project
Normale Datei
23
Examples/TinyProtocol/.project
Normale Datei
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>TinyProtocol</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
49
Examples/TinyProtocol/pom.xml
Normale Datei
49
Examples/TinyProtocol/pom.xml
Normale Datei
@ -0,0 +1,49 @@
|
||||
<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.tinyprotocol</groupId>
|
||||
<artifactId>TinyProtocol</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>TinyProtocol</name>
|
||||
<description>Intercept packets without ProtocolLib.</description>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>bukkit-rep</id>
|
||||
<url>http://repo.bukkit.org/content/groups/public</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>comphenix-rep</id>
|
||||
<name>Comphenix Maven Releases</name>
|
||||
<url>http://repo.comphenix.net/content/groups/public</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.0</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
<version>1.7.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,28 @@
|
||||
package com.comphenix.tinyprotocol;
|
||||
|
||||
import net.minecraft.server.v1_7_R1.PacketPlayInChat;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
public class ExamplePlugin extends JavaPlugin {
|
||||
private Function<Object, String> CHAT_MESSAGE = TinyProtocol.getFieldAccessor(
|
||||
PacketPlayInChat.class, String.class, 0);
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
new TinyProtocol(this) {
|
||||
@Override
|
||||
public Object onPacketInAsync(Player sender, Object packet) {
|
||||
// Cancel chat packets
|
||||
if (packet instanceof PacketPlayInChat) {
|
||||
if (CHAT_MESSAGE.apply(packet).contains("dirty"))
|
||||
return null;
|
||||
}
|
||||
return super.onPacketInAsync(sender, packet);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,151 @@
|
||||
package com.comphenix.tinyprotocol;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.server.v1_7_R1.NetworkManager;
|
||||
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_R1.entity.CraftPlayer;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
public abstract class TinyProtocol implements Listener {
|
||||
private static Function<Object, Channel> CHANNEL_ACCESSOR = getFieldAccessor(NetworkManager.class, Channel.class, 0);
|
||||
|
||||
private boolean closed;
|
||||
private Plugin plugin;
|
||||
|
||||
public TinyProtocol(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
|
||||
// Prepare existing players
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
injectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public final void onPlayerJoin(PlayerJoinEvent e) {
|
||||
if (closed)
|
||||
return;
|
||||
injectPlayer(e.getPlayer());
|
||||
}
|
||||
|
||||
private void injectPlayer(final Player player) {
|
||||
// Inject our packet interceptor
|
||||
getChannel(player).pipeline().addBefore("packet_handler", getHandlerName(), new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object result = onPacketInAsync(player, msg);
|
||||
|
||||
if (result != null) {
|
||||
super.channelRead(ctx, result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object result = onPacketOutAsync(player, msg);
|
||||
|
||||
if (result != null) {
|
||||
super.write(ctx, result, promise);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String getHandlerName() {
|
||||
return "tiny-" + plugin.getName();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public final void onPluginDisable(PluginDisableEvent e) {
|
||||
if (e.getPlugin().equals(plugin)) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
private Channel getChannel(Player player) {
|
||||
NetworkManager manager = ((CraftPlayer) player.getPlayer()).getHandle().playerConnection.networkManager;
|
||||
return CHANNEL_ACCESSOR.apply(manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the server is starting to send a packet to a player.
|
||||
* <p>
|
||||
* Note that this is not executed on the main thread.
|
||||
* @param reciever - the receiving player.
|
||||
* @param packet - the packet being sent.
|
||||
* @return The packet to send instead, or NULL to cancel the transmission.
|
||||
*/
|
||||
public Object onPacketOutAsync(Player reciever, Object packet) {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the server has received a packet from a given player.
|
||||
* @param sender - the player that sent the packet.
|
||||
* @param packet - the packet being sent.
|
||||
* @return The packet to recieve instead, or NULL to cancel.
|
||||
*/
|
||||
public Object onPacketInAsync(Player sender, Object packet) {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a field accessor for a specific field type and index.
|
||||
* @param target - the target type.
|
||||
* @param fieldType - the field type.
|
||||
* @param index - the index.
|
||||
* @return The field accessor.
|
||||
*/
|
||||
public static <T> Function<Object, T> getFieldAccessor(Class<?> target, Class<T> fieldType, int index) {
|
||||
for (Field field : target.getDeclaredFields()) {
|
||||
if (fieldType.isAssignableFrom(field.getType()) && index-- <= 0) {
|
||||
final Field targetField = field;
|
||||
field.setAccessible(true);
|
||||
|
||||
// A function for retrieving a specific field value
|
||||
return new Function<Object, T>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T apply(@Nullable Object instance) {
|
||||
try {
|
||||
return (T) targetField.get(instance);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Cannot access reflection.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Search in parent classes
|
||||
if (target.getSuperclass() != null)
|
||||
return getFieldAccessor(target.getSuperclass(), fieldType, index);
|
||||
throw new IllegalArgumentException("Cannot find field with type " + fieldType);
|
||||
}
|
||||
|
||||
public final void close() {
|
||||
if (!closed) {
|
||||
closed = true;
|
||||
|
||||
// Remove our handlers
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
getChannel(player).pipeline().remove(getHandlerName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
Examples/TinyProtocol/src/main/resources/plugin.yml
Normale Datei
9
Examples/TinyProtocol/src/main/resources/plugin.yml
Normale Datei
@ -0,0 +1,9 @@
|
||||
name: TinyProtocol
|
||||
version: 0.0.1-SNAPSHOT
|
||||
description: Intercept packets without ProtocolLib
|
||||
author: Comphenix
|
||||
|
||||
load: startup
|
||||
|
||||
main: com.comphenix.tinyprotocol.ExamplePlugin
|
||||
database: false
|
In neuem Issue referenzieren
Einen Benutzer sperren