1
0
mirror of https://github.com/GeyserMC/Floodgate.git synced 2025-12-19 14:59:20 +00:00

Merge remote-tracking branch 'origin/master' into dev/2.1.1

# Conflicts:
#	core/src/main/resources/languages
This commit is contained in:
Tim203
2022-01-27 12:33:43 +01:00
9 changed files with 99 additions and 36 deletions

4
.gitmodules vendored
View File

@@ -1,4 +0,0 @@
[submodule "core/src/main/resources/languages"]
path = core/src/main/resources/languages
url = https://github.com/GeyserMC/languages
branch = l10n_floodgate

View File

@@ -139,6 +139,7 @@ public class FloodgatePlatform {
} }
} }
guice.getInstance(NewsChecker.class).shutdown();
api.getPlayerLink().stop(); api.getPlayerLink().stop();
return true; return true;
} }

View File

@@ -35,7 +35,6 @@ import io.netty.util.AttributeKey;
import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.objects.ObjectObjectImmutablePair; import it.unimi.dsi.fastutil.objects.ObjectObjectImmutablePair;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import lombok.AccessLevel; import lombok.AccessLevel;
@@ -218,8 +217,6 @@ public final class FloodgateHandshakeHandler {
bedrockData.getVerifyCode()); bedrockData.getVerifyCode());
} }
correctHostname(handshakeData);
FloodgatePlayer player = FloodgatePlayerImpl.from(bedrockData, handshakeData); FloodgatePlayer player = FloodgatePlayerImpl.from(bedrockData, handshakeData);
api.addPlayer(player); api.addPlayer(player);
@@ -247,30 +244,9 @@ public final class FloodgateHandshakeHandler {
bedrockData, configHolder.get(), null, hostname); bedrockData, configHolder.get(), null, hostname);
handshakeHandlers.callHandshakeHandlers(handshakeData); handshakeHandlers.callHandshakeHandlers(handshakeData);
if (bedrockData != null) {
correctHostname(handshakeData);
}
return new HandshakeResult(resultType, handshakeData, bedrockData, null); return new HandshakeResult(resultType, handshakeData, bedrockData, null);
} }
private void correctHostname(HandshakeData handshakeData) {
BedrockData bedrockData = handshakeData.getBedrockData();
UUID correctUuid = handshakeData.getCorrectUniqueId();
// replace the ip and uuid with the Bedrock client IP and an uuid based of the xuid
String[] split = handshakeData.getHostname().split("\0");
if (split.length >= 3) {
if (logger.isDebug()) {
logger.info("Replacing hostname arg1 '{}' with '{}' and arg2 '{}' with '{}'",
split[1], bedrockData.getIp(), split[2], correctUuid.toString());
}
split[1] = bedrockData.getIp();
split[2] = correctUuid.toString();
}
handshakeData.setHostname(String.join("\0", split));
}
private CompletableFuture<Pair<BedrockData, LinkedPlayer>> fetchLinkedPlayer(BedrockData data) { private CompletableFuture<Pair<BedrockData, LinkedPlayer>> fetchLinkedPlayer(BedrockData data) {
if (!api.getPlayerLink().isEnabled()) { if (!api.getPlayerLink().isEnabled()) {
return CompletableFuture.completedFuture(new ObjectObjectImmutablePair<>(data, null)); return CompletableFuture.completedFuture(new ObjectObjectImmutablePair<>(data, null));

View File

@@ -28,6 +28,7 @@ package org.geysermc.floodgate;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.geysermc.floodgate.api.handshake.HandshakeHandlers;
import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.module.PluginMessageModule; import org.geysermc.floodgate.module.PluginMessageModule;
import org.geysermc.floodgate.module.ServerCommonModule; import org.geysermc.floodgate.module.ServerCommonModule;
@@ -35,6 +36,7 @@ import org.geysermc.floodgate.module.SpigotAddonModule;
import org.geysermc.floodgate.module.SpigotCommandModule; import org.geysermc.floodgate.module.SpigotCommandModule;
import org.geysermc.floodgate.module.SpigotListenerModule; import org.geysermc.floodgate.module.SpigotListenerModule;
import org.geysermc.floodgate.module.SpigotPlatformModule; import org.geysermc.floodgate.module.SpigotPlatformModule;
import org.geysermc.floodgate.util.SpigotHandshakeHandler;
import org.geysermc.floodgate.util.SpigotProtocolSupportHandler; import org.geysermc.floodgate.util.SpigotProtocolSupportHandler;
import org.geysermc.floodgate.util.SpigotProtocolSupportListener; import org.geysermc.floodgate.util.SpigotProtocolSupportListener;
@@ -66,6 +68,10 @@ public final class SpigotPlugin extends JavaPlugin {
new PluginMessageModule() new PluginMessageModule()
); );
//todo add proper support for disabling things on shutdown and enabling this on enable
injector.getInstance(HandshakeHandlers.class)
.addHandshakeHandler(injector.getInstance(SpigotHandshakeHandler.class));
// add ProtocolSupport support (hack) // add ProtocolSupport support (hack)
if (getServer().getPluginManager().getPlugin("ProtocolSupport") != null) { if (getServer().getPluginManager().getPlugin("ProtocolSupport") != null) {
injector.getInstance(SpigotProtocolSupportHandler.class); injector.getInstance(SpigotProtocolSupportHandler.class);

View File

@@ -42,6 +42,7 @@ import org.geysermc.floodgate.util.ProxyUtils;
public final class SpigotDataHandler extends CommonDataHandler { public final class SpigotDataHandler extends CommonDataHandler {
private Object networkManager; private Object networkManager;
private FloodgatePlayer player; private FloodgatePlayer player;
private boolean proxyData;
public SpigotDataHandler( public SpigotDataHandler(
FloodgateHandshakeHandler handshakeHandler, FloodgateHandshakeHandler handshakeHandler,
@@ -52,7 +53,6 @@ public final class SpigotDataHandler extends CommonDataHandler {
@Override @Override
protected void setNewIp(Channel channel, InetSocketAddress newIp) { protected void setNewIp(Channel channel, InetSocketAddress newIp) {
//todo the socket address will be overridden when bungeeData is true
setValue(networkManager, ClassNames.SOCKET_ADDRESS, newIp); setValue(networkManager, ClassNames.SOCKET_ADDRESS, newIp);
} }
@@ -76,20 +76,22 @@ public final class SpigotDataHandler extends CommonDataHandler {
// the server will do all the work if BungeeCord mode is enabled, // the server will do all the work if BungeeCord mode is enabled,
// otherwise we have to help the server. // otherwise we have to help the server.
boolean bungeeData = ProxyUtils.isProxyData(); proxyData = ProxyUtils.isProxyData();
if (!bungeeData) { if (!proxyData) {
// Use a spoofedUUID for initUUID (just like Bungeecord) // Use a spoofedUUID for initUUID (just like Bungeecord)
setValue(networkManager, "spoofedUUID", player.getCorrectUniqueId()); setValue(networkManager, "spoofedUUID", player.getCorrectUniqueId());
} }
return bungeeData; // we can only remove the handler if the data is proxy data and username validation doesn't
// exist. Otherwise, we need to wait and disable it.
return proxyData && ClassNames.PAPER_DISABLE_USERNAME_VALIDATION == null;
} }
@Override @Override
protected boolean shouldCallFireRead(Object queuedPacket) { protected boolean shouldCallFireRead(Object queuedPacket) {
// we have to ignore the 'login start' packet if BungeeCord mode is disabled, // we have to ignore the 'login start' packet,
// otherwise the server might ask the user to login // otherwise the server will ask the user to login
try { try {
if (checkAndHandleLogin(queuedPacket)) { if (checkAndHandleLogin(queuedPacket)) {
return false; return false;
@@ -136,6 +138,16 @@ public final class SpigotDataHandler extends CommonDataHandler {
return true; return true;
} }
if (ClassNames.PAPER_DISABLE_USERNAME_VALIDATION != null) {
// ensure that Paper will not be checking
setValue(packetListener, ClassNames.PAPER_DISABLE_USERNAME_VALIDATION, true);
if (proxyData) {
// the server will handle the rest if we have proxy data
ctx.pipeline().remove(this);
return false;
}
}
// set the player his GameProfile, we can't change the username without this // set the player his GameProfile, we can't change the username without this
GameProfile gameProfile = new GameProfile( GameProfile gameProfile = new GameProfile(
player.getCorrectUniqueId(), player.getCorrectUsername() player.getCorrectUniqueId(), player.getCorrectUsername()

View File

@@ -25,6 +25,7 @@
package org.geysermc.floodgate.util; package org.geysermc.floodgate.util;
import static org.geysermc.floodgate.util.ReflectionUtils.getField;
import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType; import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType;
import static org.geysermc.floodgate.util.ReflectionUtils.getMethod; import static org.geysermc.floodgate.util.ReflectionUtils.getMethod;
@@ -37,6 +38,7 @@ import java.lang.reflect.Method;
import java.net.SocketAddress; import java.net.SocketAddress;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.checkerframework.checker.nullness.qual.Nullable;
@SuppressWarnings("PMD.SystemPrintln") @SuppressWarnings("PMD.SystemPrintln")
public class ClassNames { public class ClassNames {
@@ -56,6 +58,8 @@ public class ClassNames {
public static final Field HANDSHAKE_HOST; public static final Field HANDSHAKE_HOST;
public static final Field LOGIN_PROFILE; public static final Field LOGIN_PROFILE;
public static final Field PACKET_LISTENER; public static final Field PACKET_LISTENER;
@Nullable
public static final Field PAPER_DISABLE_USERNAME_VALIDATION;
public static final Method GET_PROFILE_METHOD; public static final Method GET_PROFILE_METHOD;
public static final Method LOGIN_DISCONNECT; public static final Method LOGIN_DISCONNECT;
@@ -157,6 +161,13 @@ public class ClassNames {
FIRE_LOGIN_EVENTS = getMethod(LOGIN_HANDLER, "fireEvents"); FIRE_LOGIN_EVENTS = getMethod(LOGIN_HANDLER, "fireEvents");
checkNotNull(FIRE_LOGIN_EVENTS, "fireEvents from LoginHandler"); checkNotNull(FIRE_LOGIN_EVENTS, "fireEvents from LoginHandler");
PAPER_DISABLE_USERNAME_VALIDATION = getField(LOGIN_LISTENER,
"iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation");
if (Constants.DEBUG_MODE) {
System.out.println("Paper disable username validation field exists? " +
(PAPER_DISABLE_USERNAME_VALIDATION != null));
}
} }
private static Class<?> getClassOrFallBack(String className, String fallbackName) { private static Class<?> getClassOrFallBack(String className, String fallbackName) {

View File

@@ -66,4 +66,4 @@ public final class ProxyUtils {
return ReflectionUtils.getCastedValue(null, IS_MODERN_FORWARDING); return ReflectionUtils.getCastedValue(null, IS_MODERN_FORWARDING);
} }
} }

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Floodgate
*/
package org.geysermc.floodgate.util;
import com.google.inject.Inject;
import java.util.UUID;
import org.geysermc.floodgate.api.handshake.HandshakeData;
import org.geysermc.floodgate.api.handshake.HandshakeHandler;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
public class SpigotHandshakeHandler implements HandshakeHandler {
@Inject
private FloodgateLogger logger;
@Override
public void handle(HandshakeData data) {
// we never have to do anything when BedrockData is null.
// BedrockData is null when something went wrong (e.g. invalid key / exception)
if (data.getBedrockData() == null) {
return;
}
BedrockData bedrockData = data.getBedrockData();
UUID correctUuid = data.getCorrectUniqueId();
// replace the ip and uuid with the Bedrock client IP and an uuid based of the xuid
String[] split = data.getHostname().split("\0");
if (split.length >= 3) {
if (logger.isDebug()) {
logger.info("Replacing hostname arg1 '{}' with '{}' and arg2 '{}' with '{}'",
split[1], bedrockData.getIp(), split[2], correctUuid.toString()
);
}
split[1] = bedrockData.getIp();
split[2] = correctUuid.toString();
}
data.setHostname(String.join("\0", split));
}
}