4 Commits
22 changed files with 151 additions and 58 deletions

No files matched your search

+4 -9
View File
@@ -5,7 +5,6 @@ import org.yaml.snakeyaml.Yaml
import java.nio.charset.StandardCharsets
// --
// Building
// --
@@ -24,15 +23,13 @@ plugins {
id 'idea'
}
// --
// Variables
// --
version = '2.5.4'
version = '2.6.0'
group = 'net.tcpshield.tcpshield'
archivesBaseName = 'TCPShield'
// --
// Misc.
// --
@@ -68,7 +65,6 @@ compileJava {
options.encoding = 'UTF-8'
}
// --
// Dependencies
// --
@@ -97,10 +93,9 @@ repositories {
}
dependencies {
// Bukkit
compileOnly group: 'org.spigotmc', name: 'spigot-api', version: '1.11-R0.1-SNAPSHOT'
compileOnly group: 'com.comphenix.protocol', name: 'ProtocolLib', version: '4.4.0'
compileOnly group: 'com.comphenix.protocol', name: 'ProtocolLib', version: '5.0.0-SNAPSHOT'
// Paper
compileOnly group: 'com.destroystokyo.paper', name: 'paper-api', version: '1.15.2-R0.1-SNAPSHOT'
@@ -114,7 +109,7 @@ dependencies {
// Testing
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.7.0-M1'
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.7.0-M1'
compileOnly 'org.geysermc.floodgate:api:2.0-SNAPSHOT'
compileOnly 'org.geysermc.floodgate:api:2.1.1-SNAPSHOT'
}
processResources {
@@ -180,4 +175,4 @@ void updateJsons() {
}
}
build.dependsOn updateVersion
build.dependsOn updateVersion
@@ -12,24 +12,28 @@ public interface TCPShieldPlugin {
/**
* Gets the plugin's config provider
*
* @return The plugin's config provider
*/
ConfigProvider getConfigProvider();
/**
* Gets the plugin's logger
*
* @return The plugin's logger
*/
Logger getLogger();
/**
* Gets the packet handler
*
* @return The packet handler
*/
TCPShieldPacketHandler getPacketHandler();
/**
* Gets the plugin's debugger
*
* @return The plugin's debugger
*/
Debugger getDebugger();
@@ -40,12 +44,15 @@ public interface TCPShieldPlugin {
*/
default void initialization() {
String jvmVersion = System.getProperty("java.version");
// Java 11 check/warning (Will eventually force Java 16 without warning)
String[] versionParts = jvmVersion.split("\\.");
int baseVersion = Integer.parseInt(versionParts[0]);
if (baseVersion < 11) // Java 8, and below, starts with 1, but since we are using Java 11 we can ignore sub values
this.getDebugger().warn("The Java version you are running is outdated for TCPShield and may cause issues. Update to atleast Java 11. Your version: Java %s", jvmVersion);
try {
// Java 11 check/warning (Will eventually force Java 16 without warning)
String[] versionParts = jvmVersion.split("\\.");
int baseVersion = Integer.parseInt(versionParts[0]);
if (baseVersion < 11) // Java 8, and below, starts with 1, but since we are using Java 11 we can ignore sub values
this.getDebugger().warn("The Java version you are running is outdated for TCPShield and may cause issues. Update to atleast Java 11. Your version: Java %s", jvmVersion);
} catch (Throwable t) {
this.getDebugger().error("Failed to check java version for string: " + jvmVersion);
}
}
}
@@ -66,12 +66,13 @@ public class BukkitConfig extends ConfigProvider {
try {
loadedConfiguration = YamlConfiguration.loadConfiguration(configFile);
checkNodes("only-allow-proxy-connections", "timestamp-validation", "debug-mode");
checkNodes("only-allow-proxy-connections", "timestamp-validation", "debug-mode", "enable-geyser-support", "prefer-protocollib");
this.onlyProxy = loadedConfiguration.getBoolean("only-allow-proxy-connections");
this.timestampValidationMode = loadedConfiguration.getString("timestamp-validation");
this.doDebug = loadedConfiguration.getBoolean("debug-mode");
this.geyser = loadedConfiguration.getBoolean("enable-geyser-support");
this.preferProtocolLib = loadedConfiguration.getBoolean("prefer-protocollib");
} catch (Exception e) {
throw new ConfigLoadException(e);
}
@@ -29,15 +29,16 @@ public class TCPShieldBukkit extends JavaPlugin implements TCPShieldPlugin {
debugger = Debugger.createDebugger(this);
packetHandler = new TCPShieldPacketHandler(this);
if (BukkitImplProvider.hasPaperEvent())
bukkitImpl = new BukkitPaper(this);
else {
if (getServer().getPluginManager().getPlugin("ProtocolLib") == null) {
getLogger().severe("TCPShield not loading because ProtocolLib is not installed. Either use Paper to enable native compatibility or install ProtocolLib.");
return;
}
// check force plib option -> paper -> plib -> error
if (this.configProvider.preferProtocolLib() && getServer().getPluginManager().getPlugin("ProtocolLib") != null) {
bukkitImpl = new BukkitProtocolLib(this);
} else if (BukkitImplProvider.hasPaperEvent()) {
bukkitImpl = new BukkitPaper(this);
} else if (getServer().getPluginManager().getPlugin("ProtocolLib") != null) {
bukkitImpl = new BukkitProtocolLib(this);
} else {
getLogger().severe("TCPShield not loading because ProtocolLib is not installed. Either use Paper to enable native compatibility or install ProtocolLib.");
return;
}
bukkitImpl.load();
@@ -48,6 +49,7 @@ public class TCPShieldBukkit extends JavaPlugin implements TCPShieldPlugin {
} catch (Exception e) {
throw new InitializationException(e);
}
}
@@ -13,7 +13,6 @@ public class BukkitPaper extends BukkitImplProvider {
super(bukkitPlugin);
}
@Override
public void load() {
PaperHandshakeHandler packetHandler = new PaperHandshakeHandler(this);
@@ -19,7 +19,6 @@ public class PaperHandshakeHandler implements Listener {
this.bukkitProvider = bukkitProvider;
}
@EventHandler(priority = EventPriority.LOWEST)
public void onHandshake(PlayerHandshakeEvent e) {
PaperPacket packet = new PaperPacket(e);
@@ -36,6 +35,8 @@ public class PaperHandshakeHandler implements Listener {
public void onServerPing(PaperServerListPingEvent e) {
if (e.getClient().isLegacy())
e.setCancelled(true);
}
}
@@ -15,7 +15,6 @@ public class PaperPacket implements PacketProvider {
this.handshakeEvent = handshakeEvent;
}
@Override
public String getPayloadString() {
return handshakeEvent.getOriginalHandshake();
@@ -18,7 +18,6 @@ public class PaperPlayer implements PlayerProvider {
this.handshakeEvent = handshakeEvent;
}
/**
* Trys to grab the UUID of the handshake
* @return If found, the corrosponding uuid, if not, unknown
@@ -13,7 +13,6 @@ public class BukkitProtocolLib extends BukkitImplProvider {
super(bukkitPlugin);
}
@Override
public void load() {
ProtocolLibHandshakeHandler packetHandler = new ProtocolLibHandshakeHandler(this);
@@ -19,7 +19,6 @@ public class ProtocolLibHandshakeHandler extends PacketAdapter {
this.bukkitProvider = bukkitProvider;
}
@Override
public void onPacketReceiving(PacketEvent e) {
ProtocolLibPacket packet = new ProtocolLibPacket(e.getPacket());
@@ -17,7 +17,6 @@ public class ProtocolLibPacket implements PacketProvider {
this.rawPayload = packetContainer.getStrings().read(0);
}
@Override
public String getPayloadString() {
return rawPayload;
@@ -1,7 +1,7 @@
package net.tcpshield.tcpshield.bukkit.protocollib.handler;
import com.comphenix.protocol.injector.server.SocketInjector;
import com.comphenix.protocol.injector.server.TemporaryPlayerFactory;
import com.comphenix.protocol.injector.temporary.MinimalInjector;
import com.comphenix.protocol.injector.temporary.TemporaryPlayerFactory;
import net.tcpshield.tcpshield.provider.PlayerProvider;
import net.tcpshield.tcpshield.util.ReflectionUtil;
import net.tcpshield.tcpshield.util.exception.manipulate.PlayerManipulationException;
@@ -34,7 +34,6 @@ public class ProtocolLibPlayer implements PlayerProvider {
}
}
private final Player player;
private String ip;
@@ -72,13 +71,13 @@ public class ProtocolLibPlayer implements PlayerProvider {
try {
this.ip = ip.getAddress().getHostAddress();
SocketInjector ignored = TemporaryPlayerFactory.getInjectorFromPlayer(player);
MinimalInjector ignored = TemporaryPlayerFactory.getInjectorFromPlayer(player);
Object injector = ReflectionUtil.getObjectInPrivateField(ignored, "injector");
Object networkManager = ReflectionUtil.getObjectInPrivateField(injector, "networkManager");
ReflectionUtil.setFinalField(networkManager, ReflectionUtil.searchFieldByClass(networkManager.getClass(), SocketAddress.class), ip);
Object channel = ReflectionUtil.getObjectInPrivateField(injector, "originalChannel");
Object channel = ReflectionUtil.getObjectInPrivateField(injector, "wrappedChannel");
ReflectionUtil.setFinalField(channel, ReflectionUtil.getDeclaredField(abstractChannelClass, "remoteAddress"), ip);
} catch (Exception e) {
throw new PlayerManipulationException(e);
@@ -19,16 +19,24 @@ public abstract class ConfigProvider {
protected String timestampValidationMode = "htpdate";
protected boolean doDebug = true; // Fail-safe default set to true
protected boolean geyser = false;
protected boolean velocityHandlePreLoginEvent = true;
// spigot/paper only option
protected boolean preferProtocolLib;
protected File dataFolder;
protected File configFile;
public boolean isOnlyProxy() {
return onlyProxy;
return this.onlyProxy;
}
public boolean isGeyser() {
return geyser;
return this.geyser;
}
public boolean handlePreLoginEvent() {
return this.velocityHandlePreLoginEvent;
}
public String getTimestampValidationMode() {
@@ -36,7 +44,11 @@ public abstract class ConfigProvider {
}
public boolean doDebug() {
return doDebug;
return this.doDebug;
}
public boolean preferProtocolLib() {
return this.preferProtocolLib;
}
public File getDataFolder() {
@@ -65,12 +65,13 @@ public class VelocityConfig extends ConfigProvider {
try {
loadedToml = new Toml().read(configFile);
checkNodes("only-allow-proxy-connections", "timestamp-validation", "debug-mode");
checkNodes("only-allow-proxy-connections", "timestamp-validation", "debug-mode", "enable-geyser-support", "pre-login-event");
this.onlyProxy = loadedToml.getBoolean("only-allow-proxy-connections");
this.timestampValidationMode = loadedToml.getString("timestamp-validation");
this.doDebug = loadedToml.getBoolean("debug-mode");
this.geyser = loadedToml.getBoolean("enable-geyser-support");
this.velocityHandlePreLoginEvent = loadedToml.getBoolean("pre-login-event");
} catch (Exception e) {
throw new ConfigLoadException(e);
}
@@ -23,11 +23,15 @@ public class VelocityHandshakeHandler {
// Turns out this event sometimes passes erroneous hostnames
// which have the null bytes terminated as FML data which causes
// issues with the verification process.
// @Subscribe(order = PostOrder.FIRST)
// public void onPreLogin(PreLoginEvent e) {
// InboundConnection connection = e.getConnection();
// handleEvent(connection, "onPreLogin");
// }
@Subscribe(order = PostOrder.FIRST)
public void onPreLogin(PreLoginEvent e) {
if (!this.plugin.getConfigProvider().handlePreLoginEvent()) {
return;
}
InboundConnection connection = e.getConnection();
handleEvent(connection, "onPreLogin");
}
@Subscribe(order = PostOrder.FIRST)
public void onHandshake(ConnectionHandshakeEvent e) {
@@ -43,7 +47,7 @@ public class VelocityHandshakeHandler {
private void handleEvent(InboundConnection connection, String debugSource) {
VelocityPlayer player = new VelocityPlayer(connection);
if (player.isLegacy()) {
if (player.getConnectionType() == VelocityPlayer.ConnectionType.LEGACY) {
player.disconnect();
return;
}
@@ -22,6 +22,10 @@ public class VelocityPacket implements PacketProvider {
private static final Field HOSTNAME_FIELD;
private static final Field CLEANED_ADDRESS_FIELD;
// new velocity support
private static Class<?> LOGIN_INBOUND_CONNECTION_CLASS;
private static Field LOGIN_INBOUND_CONNECTION_DELEGATE_FIELD;
static {
try {
Class<?> inboundConnection = Class.forName("com.velocitypowered.proxy.connection.client.InitialInboundConnection");
@@ -32,6 +36,14 @@ public class VelocityPacket implements PacketProvider {
} catch (Exception e) {
throw new InitializationException(new ReflectionException(e));
}
// LoginInboundConnection support
try {
LOGIN_INBOUND_CONNECTION_CLASS = Class.forName("com.velocitypowered.proxy.connection.client.LoginInboundConnection");
LOGIN_INBOUND_CONNECTION_DELEGATE_FIELD = ReflectionUtil.getPrivateField(LOGIN_INBOUND_CONNECTION_CLASS, "delegate");
} catch (Exception e) {
// ignore for old versions of velocity
}
}
@@ -39,6 +51,15 @@ public class VelocityPacket implements PacketProvider {
private final String rawPayload;
public VelocityPacket(InboundConnection inboundConnection) {
// support new velocity connection type
if (inboundConnection.getClass() == LOGIN_INBOUND_CONNECTION_CLASS) {
try {
inboundConnection = (InboundConnection) LOGIN_INBOUND_CONNECTION_DELEGATE_FIELD.get(inboundConnection);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
this.inboundConnection = inboundConnection;
try {
this.rawPayload = (String) HOSTNAME_FIELD.get(HANDSHAKE_FIELD.get(inboundConnection));
@@ -26,6 +26,10 @@ public class VelocityPlayer implements PlayerProvider {
private static final Field REMOTE_ADDRESS_FIELD;
private static final Method CLOSE_CHANNEL_METHOD;
// new velocity support
private static Class<?> LOGIN_INBOUND_CONNECTION_CLASS;
private static Field LOGIN_INBOUND_CONNECTION_DELEGATE_FIELD;
static {
try {
INITIAL_INBOUND_CONNECTION_CLASS = Class.forName("com.velocitypowered.proxy.connection.client.InitialInboundConnection");
@@ -38,22 +42,39 @@ public class VelocityPlayer implements PlayerProvider {
} catch (Exception e) {
throw new InitializationException(new ReflectionException(e));
}
// LoginInboundConnection support
try {
LOGIN_INBOUND_CONNECTION_CLASS = Class.forName("com.velocitypowered.proxy.connection.client.LoginInboundConnection");
LOGIN_INBOUND_CONNECTION_DELEGATE_FIELD = ReflectionUtil.getPrivateField(LOGIN_INBOUND_CONNECTION_CLASS, "delegate");
} catch (Exception e) {
// ignore for old versions of velocity
}
}
private final InboundConnection inboundConnection;
private final boolean legacy;
// private final boolean legacy;
private final ConnectionType connectionType;
private String ip;
public VelocityPlayer(InboundConnection inboundConnection) {
this.inboundConnection = inboundConnection;
this.legacy = inboundConnection.getClass() != INITIAL_INBOUND_CONNECTION_CLASS;
// this.legacy = inboundConnection.getClass() != INITIAL_INBOUND_CONNECTION_CLASS && inboundConnection.getClass() != LOGIN_INBOUND_CONNECTION_CLASS;
this.ip = inboundConnection.getRemoteAddress().getAddress().getHostAddress();
}
if (this.inboundConnection.getClass() == INITIAL_INBOUND_CONNECTION_CLASS) {
this.connectionType = ConnectionType.INITIAL_INBOUND;
} else if (this.inboundConnection.getClass() == LOGIN_INBOUND_CONNECTION_CLASS) {
this.connectionType = ConnectionType.LOGIN_INBOUND;
} else {
this.connectionType = ConnectionType.LEGACY;
}
}
/**
* Unsupported with Velocity handshakes
*
* @return unknown
*/
@Override
@@ -63,6 +84,7 @@ public class VelocityPlayer implements PlayerProvider {
/**
* Unsupported with Velocity handshakes
*
* @return unknown
*/
@Override
@@ -75,26 +97,26 @@ public class VelocityPlayer implements PlayerProvider {
return ip;
}
public boolean isLegacy() {
return legacy;
}
@Override
public void setIP(InetSocketAddress ip) throws PlayerManipulationException {
try {
this.ip = ip.getAddress().getHostAddress();
Object minecraftConnection = MINECRAFT_CONNECTION_FIELD.get(inboundConnection);
Object minecraftConnection = this.getMinecraftConnection();
REMOTE_ADDRESS_FIELD.set(minecraftConnection, ip);
} catch (Exception e) {
throw new PlayerManipulationException(e);
}
}
// public boolean isLegacy() {
// return legacy;
// }
@Override
public void disconnect() {
try {
Object minecraftConnection = legacy ? LEGACY_MINECRAFT_CONNECTION_FIELD.get(inboundConnection) : MINECRAFT_CONNECTION_FIELD.get(inboundConnection);
Object minecraftConnection = this.getMinecraftConnection();
CLOSE_CHANNEL_METHOD.invoke(minecraftConnection);
} catch (Exception e) {
@@ -102,4 +124,32 @@ public class VelocityPlayer implements PlayerProvider {
}
}
private Object getMinecraftConnection() {
try {
switch (this.connectionType) {
case LEGACY:
return LEGACY_MINECRAFT_CONNECTION_FIELD.get(inboundConnection);
case INITIAL_INBOUND:
return MINECRAFT_CONNECTION_FIELD.get(inboundConnection);
case LOGIN_INBOUND: {
// starts as login_inbound, get delegate initial_inbound
Object initialInboundConnection = LOGIN_INBOUND_CONNECTION_DELEGATE_FIELD.get(this.inboundConnection);
return MINECRAFT_CONNECTION_FIELD.get(initialInboundConnection);
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public ConnectionType getConnectionType() {
return connectionType;
}
enum ConnectionType {
LOGIN_INBOUND, INITIAL_INBOUND, LEGACY;
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
name: TCPShield
version: 2.5.4
version: 2.6.0
main: net.tcpshield.tcpshield.bungee.TCPShieldBungee
author: https://tcpshield.com
softdepends:
+3
View File
@@ -9,3 +9,6 @@ debug-mode = false
# Toggle to enable support for Geyser/Floodgate v2
enable-geyser-support = false
# enable handling handshake on PreLoginEvent
pre-login-event = true
+3
View File
@@ -9,3 +9,6 @@ debug-mode: false
# Toggle to enable support for Geyser/Floodgate v2
enable-geyser-support: false
# Spigot/Paper option only, does not affect bungeecord
prefer-protocollib: true
+1 -1
View File
@@ -1,5 +1,5 @@
name: TCPShield
version: 2.5.4
version: 2.6.0
main: net.tcpshield.tcpshield.bukkit.TCPShieldBukkit
softdepend:
- ProtocolLib
+1 -1
View File
@@ -1,7 +1,7 @@
{
"id": "tcpshield",
"name": "TCPShield",
"version": "2.5.4",
"version": "2.6.0",
"description": "TCPShield IP parsing capabilities for Velocity",
"authors": [
"TCPShield"