Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ This plugin is for:

* Version: 3.4.0+
* Install the plugin **only on Velocity** if Velocity is present.
* **Do NOT install it on the backend server when using Velocity**, otherwise players will be unable to join.
* **The plugin in the backend server won't operate when using Velocity**

#### Unsupported Server Types

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
}

group = "io.github.lumine1909"
version = "2.1.1"
version = "2.2.0"

repositories {
mavenCentral()
Expand Down
5 changes: 5 additions & 0 deletions compatibility/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
repositories {
maven("https://repo.viaversion.com")
maven("https://maven.leafmc.one/snapshots/")
maven("https://repo.william278.net/velocity") // Thank you william278!
}

dependencies {
implementation(project(":common"))
compileOnly("com.viaversion:viaversion-api:5.7.1")
compileOnly("cn.dreeam.leaf:leaf-api:1.21.11-R0.1-SNAPSHOT")
compileOnly(files("libs/FastLoginBukkit.jar"))

compileOnly("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT")
compileOnly("com.velocitypowered:velocity-proxy:3.4.0-SNAPSHOT")
}
Binary file added compatibility/libs/FastLoginBukkit.jar
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,46 +1,89 @@
package io.github.lumine1909.offlineencryptor.compat;

import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.velocitypowered.api.event.connection.PreLoginEvent;
import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import io.github.lumine1909.reflexion.Field;
import io.github.lumine1909.reflexion.Method;
import io.github.lumine1909.reflexion.exception.NotFoundException;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.dreeam.leaf.event.AsyncPreAuthenticateEvent;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.List;
import java.util.UUID;
import java.util.function.BooleanSupplier;

public class AuthenticateCompats {

public static final List<AuthCompat> authCompats = List.of(new LeafEvent(), new LOMCompat());
public final List<AuthCompat> authCompats;
private final BooleanSupplier disableByDefault;

private AuthenticateCompats(BooleanSupplier disableByDefault) {
private AuthenticateCompats(BooleanSupplier disableByDefault, Object serverInstance) {
this.disableByDefault = disableByDefault;
this.authCompats = List.of(new DisableWithProxy(), new LeafEvent(), new LOMCompat(), new FastLoginBukkitCompat(), new VelocityEvent(serverInstance));
}

public static AuthenticateCompats create(BooleanSupplier disableByDefault) {
return new AuthenticateCompats(disableByDefault);
return new AuthenticateCompats(disableByDefault, null);
}

public boolean hasAuthenticate(String username, UUID uuid, SocketAddress socketAddress) {
boolean hasEnabled = false;
boolean hasAuth = false;
for (AuthCompat authCompat : authCompats) {
if (!authCompat.isEnable()) {
continue;
public static AuthenticateCompats create(BooleanSupplier disableByDefault, Object serverInstance) {
return new AuthenticateCompats(disableByDefault, serverInstance);
}

public boolean hasAuthenticate(String username, UUID uuid, SocketAddress socketAddress, Object... otherParams) {
try {
for (AuthCompat authCompat : authCompats) {
if (!authCompat.isEnable()) {
continue;
}
if (authCompat.hasAuthentication(username, uuid, socketAddress, otherParams)) {
return true;
}
}
hasEnabled = true;
hasAuth |= authCompat.hasAuthentication(username, uuid, socketAddress);
return disableByDefault.getAsBoolean();
} catch (Throwable t) {
t.printStackTrace(); // What's happened?
return true; // Disable encryption for safety
}
return hasEnabled ? hasAuth : disableByDefault.getAsBoolean();
}

public interface AuthCompat {

boolean isEnable();

boolean hasAuthentication(String username, UUID uuid, SocketAddress socketAddress);
boolean hasAuthentication(String username, UUID uuid, SocketAddress socketAddress, Object... otherParams);
}

static class DisableWithProxy implements AuthCompat {

private final boolean enable;

DisableWithProxy() {
boolean enable;
try {
Class.forName("org.bukkit.Bukkit");
enable = true;
} catch (ClassNotFoundException e) {
enable = false;
}
this.enable = enable;
}

@Override
public boolean isEnable() {
return enable;
}

@Override
public boolean hasAuthentication(String username, UUID uuid, SocketAddress socketAddress, Object... otherParams) {
return Bukkit.getServerConfig().isProxyEnabled();
}
}

static class LeafEvent implements AuthCompat {
Expand All @@ -63,25 +106,28 @@ public boolean isEnable() {
return enable;
}

// Awful but I have to do that
@Override
public boolean hasAuthentication(String username, UUID uuid, SocketAddress socketAddress) {
public boolean hasAuthentication(String username, UUID uuid, SocketAddress socketAddress, Object... otherParams) {
return new AsyncPreAuthenticateEvent(username, uuid, socketAddress, !Bukkit.getOnlineMode()).callEvent();
}
}

static class LOMCompat implements AuthCompat {

private final boolean enable;
private Method<Boolean> method$isUserAllowed;
private final Method<Boolean> method$isUserAllowed;

public LOMCompat() {
LOMCompat() {
Method<Boolean> method$isUserAllowed;
boolean enable = true;
try {
Class<?> clazz = Class.forName("de.moritxius.limitedofflinemode.LimitedOfflineModePaper");
method$isUserAllowed = Method.of(clazz, "isUserAllowed", boolean.class, String.class);
} catch (ClassNotFoundException e) {
method$isUserAllowed = Method.of("de.moritxius.limitedofflinemode.LimitedOfflineModePaper", "isUserAllowed", boolean.class, String.class);
} catch (NotFoundException e) {
enable = false;
method$isUserAllowed = null;
}
this.method$isUserAllowed = method$isUserAllowed;
this.enable = enable;
}

Expand All @@ -92,9 +138,80 @@ public boolean isEnable() {
}

@Override
public boolean hasAuthentication(String username, UUID uuid, SocketAddress socketAddress) {
public boolean hasAuthentication(String username, UUID uuid, SocketAddress socketAddress, Object... otherParams) {
Plugin plugin = Bukkit.getPluginManager().getPlugin("LimitedOfflineMode");
return plugin != null && !method$isUserAllowed.invoke(plugin, username);
return plugin != null && plugin.isEnabled() && !method$isUserAllowed.invoke(plugin, username);
}
}

static class FastLoginBukkitCompat implements AuthCompat {

private final boolean enable;

FastLoginBukkitCompat() {
boolean enable = true;
try {
Class.forName("com.github.games647.fastlogin.bukkit.FastLoginBukkit");
} catch (ClassNotFoundException e) {
enable = false;
}
this.enable = enable;
}

@Override
public boolean isEnable() {
return enable;
}

@Override
public boolean hasAuthentication(String username, UUID uuid, SocketAddress socketAddress, Object... otherParams) {
if (Bukkit.getPluginManager().getPlugin("FastLogin") instanceof FastLoginBukkit plugin && plugin.isEnabled()) {
return plugin.getSession((InetSocketAddress) socketAddress).getVerifyToken().length != 0;
} else {
return false;
}
}
}

static class VelocityEvent implements AuthCompat {

private final boolean enable;
private final Object proxyServer;
private final Field<?> field$inbound;

VelocityEvent(Object proxyServer) {
Field<?> field$inbound;
boolean enable = true;
try {
field$inbound = Field.of("com.velocitypowered.proxy.connection.client.InitialLoginSessionHandler", "inbound");
} catch (NotFoundException e) {
enable = false;
field$inbound = null;
}
this.field$inbound = field$inbound;
this.enable = enable;
this.proxyServer = proxyServer;
}

@Override
public boolean isEnable() {
return enable;
}

// Awful but I have to do that
@Override
public boolean hasAuthentication(String username, UUID uuid, SocketAddress socketAddress, Object... otherParams) {
VelocityServer server = (VelocityServer) proxyServer;
MinecraftConnection mcConnection = (MinecraftConnection) otherParams[0];
Object inbound = field$inbound.get(otherParams[1]);

final PreLoginEvent event = new PreLoginEvent((InboundConnection) inbound, username, uuid);
server.getEventManager().fire(event).join();
if (mcConnection.isClosed()) {
return true;
}
PreLoginEvent.PreLoginComponentResult result = event.getResult();
return !result.isForceOfflineMode() && (server.getConfiguration().isOnlineMode() || result.isOnlineModeAllowed());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class OfflineEncryptor extends JavaPlugin {
private static final Key KEY = Key.key("oe:handler");

public static OfflineEncryptor plugin;
private final AuthenticateCompats authenticateCompats = AuthenticateCompats.create(() -> Bukkit.getOnlineMode() || Bukkit.getServerConfig().isProxyEnabled());
private final AuthenticateCompats authenticateCompats = AuthenticateCompats.create(Bukkit::getOnlineMode);
private final ViaVersionCompat viaVersionCompat = ViaVersionCompat.create(false, Bukkit.getPluginManager().getPlugin("ViaVersion") != null);
private final NetworkProcessor<ServerboundHelloPacket> networkProcessor = new PaperNetworkProcessor();

Expand Down
1 change: 1 addition & 0 deletions paper/src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ folia-supported: true
softdepend:
- ViaVersion
- LimitedOfflineMode
- FastLogin
authors:
- Lumine1909
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public OfflineEncryptor(ProxyServer server, Logger logger, Metrics.Factory metri
this.server = (VelocityServer) server;
this.logger = logger;
this.metricsFactory = metricsFactory;
this.authenticateCompats = AuthenticateCompats.create(server.getConfiguration()::isOnlineMode);
this.authenticateCompats = AuthenticateCompats.create(server.getConfiguration()::isOnlineMode, server);
this.viaVersionCompat = ViaVersionCompat.create(true, server.getPluginManager().getPlugin("viaversion").isPresent());
plugin = this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
super.channelRead(ctx, msg);
}
case ServerLoginPacket packet -> {
if (!validate(viaCompat.getProtocolVersion(channel), authCompat.hasAuthenticate(packet.getUsername(), packet.getHolderUuid(), connection.getRemoteAddress()))) {
if (!validate(
viaCompat.getProtocolVersion(channel),
authCompat.hasAuthenticate(
packet.getUsername(), packet.getHolderUuid(), connection.getRemoteAddress(),
connection, connection.getActiveSessionHandler())
)) {
super.channelRead(ctx, msg);
return;
}
Expand Down
Loading