diff --git a/README.md b/README.md
index 9f9522c..46da487 100644
--- a/README.md
+++ b/README.md
@@ -19,5 +19,6 @@ Here are all the parameters that you can set in the `FabricProxy-Lite.toml` conf
| `hackOnlineMode` | `FABRIC_PROXY_HACK_ONLINE_MODE` | Allows connection through a proxy without disabling online-mode. | `true` | |
| `hackEarlySend` | `FABRIC_PROXY_HACK_EARLY_SEND` | Fabric-API can't send packet before QUERY_START event, so player info(UUID) will not ready at QUERY_START event. Setting `hackEarlySend` to `true` will use mixin for early send packet to velocity.
This is **required** for some mods, such as LuckPerms. | `false` | |
| `hackMessageChain` | `FABRIC_PROXY_HACK_MESSAGE_CHAIN` | This option fixes players being kicked for `Received chat packet with missing or invalid signature.` or `Chat message validation failure`, which only happens when the player switches to another server.
See [#30](/../../issues/30) and [#121](/../../discussions/121) for more info. | `false` | |
+| `allowDirectConnections` | `FABRIC_PROXY_ALLOW_DIRECT_CONNECTIONS` | Allow direct connections from clients without Velocity. When enabled, the mod will accept non-Velocity connections. | `false` | |
| `disconnectMessage` | `FABRIC_PROXY_DISCONNECT_MESSAGE` | The custom disconnect/kick message for users that aren't connecting through Velocity. | `"This server requires you to connect with Velocity."` | |
| `secret` | `FABRIC_PROXY_SECRET` | The Velocity forwarding secret. This should be the same random string as in Velocity's `forwarding.secret` file.
Alternatively you could set the `FABRIC_PROXY_SECRET_FILE` environment variable to read the secret from a file instead of config. | | ✓ |
diff --git a/src/main/java/one/oktw/ModConfig.java b/src/main/java/one/oktw/ModConfig.java
index d3ef9ce..91c7dfa 100644
--- a/src/main/java/one/oktw/ModConfig.java
+++ b/src/main/java/one/oktw/ModConfig.java
@@ -13,6 +13,7 @@ public class ModConfig {
private boolean hackOnlineMode = true;
private boolean hackEarlySend = false;
private boolean hackMessageChain = false;
+ private boolean allowDirectConnections = false;
private String disconnectMessage = "This server requires you to connect with Velocity.";
private String secret = "";
@@ -50,6 +51,11 @@ public static ModConfig load(Path configPath) {
config.hackMessageChain = Boolean.parseBoolean(envHackMessageChain);
}
+ String envAllowDirectConnections = System.getenv("FABRIC_PROXY_ALLOW_DIRECT_CONNECTIONS");
+ if (envAllowDirectConnections != null) {
+ config.allowDirectConnections = Boolean.parseBoolean(envAllowDirectConnections);
+ }
+
String envDisconnectMessage = System.getenv("FABRIC_PROXY_DISCONNECT_MESSAGE");
if (envDisconnectMessage != null) {
config.disconnectMessage = envDisconnectMessage;
@@ -88,7 +94,11 @@ public boolean getHackMessageChain() {
return hackMessageChain;
}
+ public boolean getAllowDirectConnections() {
+ return allowDirectConnections;
+ }
+
public String getSecret() {
return secret;
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/one/oktw/PacketHandler.java b/src/main/java/one/oktw/PacketHandler.java
index 2483d4f..8b7c2dc 100644
--- a/src/main/java/one/oktw/PacketHandler.java
+++ b/src/main/java/one/oktw/PacketHandler.java
@@ -22,41 +22,43 @@ class PacketHandler {
void handleVelocityPacket(MinecraftServer server, ServerLoginPacketListenerImpl handler, boolean understood, FriendlyByteBuf buf, ServerLoginNetworking.LoginSynchronizer synchronizer, PacketSender ignored) {
if (!understood) {
- handler.disconnect(Component.nullToEmpty(config.getAbortedMessage()));
- return;
- }
-
- synchronizer.waitFor(server.submit(() -> {
- try {
- if (!VelocityLib.checkIntegrity(buf)) {
+ if (!this.config.getAllowDirectConnections()) {
+ handler.disconnect(Component.nullToEmpty(config.getAbortedMessage()));
+ return;
+ }
+ } else {
+ synchronizer.waitFor(server.submit(() -> {
+ try {
+ if (!VelocityLib.checkIntegrity(buf)) {
+ handler.disconnect(Component.nullToEmpty("Unable to verify player details"));
+ return;
+ }
+ VelocityLib.checkVersion(buf);
+ } catch (Throwable e) {
+ LogManager.getLogger().error("Secret check failed.", e);
handler.disconnect(Component.nullToEmpty("Unable to verify player details"));
return;
}
- VelocityLib.checkVersion(buf);
- } catch (Throwable e) {
- LogManager.getLogger().error("Secret check failed.", e);
- handler.disconnect(Component.nullToEmpty("Unable to verify player details"));
- return;
- }
- Connection connection = ((ServerLoginPacketListenerAccessor) handler).getConnection();
- ((ConnectionAccessor) connection).setAddress(new java.net.InetSocketAddress(VelocityLib.readAddress(buf), ((java.net.InetSocketAddress) (connection.getRemoteAddress())).getPort()));
+ Connection connection = ((ServerLoginPacketListenerAccessor) handler).getConnection();
+ ((ConnectionAccessor) connection).setAddress(new java.net.InetSocketAddress(VelocityLib.readAddress(buf), ((java.net.InetSocketAddress) (connection.getRemoteAddress())).getPort()));
- GameProfile profile;
- try {
- profile = VelocityLib.createProfile(buf);
- } catch (Exception e) {
- LogManager.getLogger().error("Profile create failed.", e);
- handler.disconnect(Component.nullToEmpty("Unable to read player profile"));
- return;
- }
+ GameProfile profile;
+ try {
+ profile = VelocityLib.createProfile(buf);
+ } catch (Exception e) {
+ LogManager.getLogger().error("Profile create failed.", e);
+ handler.disconnect(Component.nullToEmpty("Unable to read player profile"));
+ return;
+ }
- if (config.getHackEarlySend()) {
- ((ServerLoginPacketListenerAccessor) handler).setAuthenticatedProfile(profile);
- handler.handleHello(new ServerboundHelloPacket(profile.name(), profile.id()));
- }
+ if (config.getHackEarlySend()) {
+ ((ServerLoginPacketListenerAccessor) handler).setAuthenticatedProfile(profile);
+ handler.handleHello(new ServerboundHelloPacket(profile.name(), profile.id()));
+ }
- ((ServerLoginPacketListenerAccessor) handler).setAuthenticatedProfile(profile);
- }));
+ ((ServerLoginPacketListenerAccessor) handler).setAuthenticatedProfile(profile);
+ }));
+ }
}
}