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

Fixed some bugs and Skins now work on Bungee

This commit is contained in:
Tim203
2020-12-20 17:33:11 +01:00
parent 928e5f05b0
commit 711789f549
17 changed files with 117 additions and 109 deletions

View File

@@ -59,24 +59,6 @@
</value>
</option>
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
</JetCodeStyleSettings>
<XML>
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />

View File

@@ -124,13 +124,6 @@ public final class BungeeDataHandler {
FloodgatePlayer player = result.getFloodgatePlayer();
String encryptedData = result.getHandshakeData()[1];
// remove skin from encrypted data if it has a skin
if (encryptedData.indexOf(0x21) != -1) {
encryptedData = encryptedData.substring(0, encryptedData.indexOf(0x21) - 1);
}
api.addEncryptedData(player.getCorrectUniqueId(), encryptedData);
event.getConnection().setOnlineMode(false);
event.getConnection().setUniqueId(player.getCorrectUniqueId());

View File

@@ -43,7 +43,7 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
import org.geysermc.floodgate.handler.BungeeDataHandler;
import org.geysermc.floodgate.platform.pluginmessage.PluginMessageHandler;
import org.geysermc.floodgate.pluginmessage.BungeePluginMessageHandler;
import org.geysermc.floodgate.skin.SkinHandler;
import org.geysermc.floodgate.util.LanguageManager;
@@ -54,7 +54,7 @@ public final class BungeeListener implements Listener {
@Inject private FloodgateLogger logger;
@Inject private ProxyFloodgateConfig config;
@Inject private PluginMessageHandler pluginMessageHandler;
@Inject private BungeePluginMessageHandler pluginMessageHandler;
@Inject private SkinHandler skinHandler;
@Inject
@@ -69,19 +69,17 @@ public final class BungeeListener implements Listener {
@EventHandler
public void onServerConnected(ServerConnectedEvent event) {
ProxiedPlayer player = event.getPlayer();
FloodgatePlayer floodgatePlayer = api.getPlayer(player.getUniqueId());
if (floodgatePlayer == null) {
FloodgatePlayer player = api.getPlayer(event.getPlayer().getUniqueId());
if (player == null) {
return;
}
// send skin request to server if data forwarding allows that
if (config.isSendFloodgateData()) {
pluginMessageHandler.sendSkinRequest(player.getUniqueId(),
floodgatePlayer.getRawSkin());
pluginMessageHandler.sendSkinRequest(event.getServer(), player.getRawSkin());
} else {
//todo also a Proxy SkinHandler to keep stuff clean?
skinHandler.handleSkinUploadFor(floodgatePlayer, null);
skinHandler.handleSkinUploadFor(player, null);
}
}

View File

@@ -47,7 +47,6 @@ import org.geysermc.floodgate.platform.pluginmessage.PluginMessageHandler;
import org.geysermc.floodgate.pluginmessage.BungeePluginMessageHandler;
import org.geysermc.floodgate.pluginmessage.BungeeSkinApplier;
import org.geysermc.floodgate.skin.SkinApplier;
import org.geysermc.floodgate.skin.SkinHandler;
import org.geysermc.floodgate.util.BungeeCommandUtil;
import org.geysermc.floodgate.util.LanguageManager;
@@ -55,6 +54,11 @@ import org.geysermc.floodgate.util.LanguageManager;
public final class BungeePlatformModule extends AbstractModule {
private final BungeePlugin plugin;
@Override
protected void configure() {
bind(PluginMessageHandler.class).to(BungeePluginMessageHandler.class);
}
@Provides
@Singleton
public Plugin bungeePlugin() {
@@ -92,7 +96,7 @@ public final class BungeePlatformModule extends AbstractModule {
@Provides
@Singleton
public PluginMessageHandler pluginMessageHandler(FloodgateConfigHolder configHolder) {
public BungeePluginMessageHandler pluginMessageHandler(FloodgateConfigHolder configHolder) {
return new BungeePluginMessageHandler(configHolder);
}
@@ -102,12 +106,6 @@ public final class BungeePlatformModule extends AbstractModule {
return new BungeeSkinApplier(logger);
}
@Provides
@Singleton
public SkinHandler skinHandler(SkinApplier skinApplier, FloodgateLogger logger) {
return new SkinHandler(skinApplier, logger);
}
/*
DebugAddon / PlatformInjector
*/

View File

@@ -41,6 +41,7 @@ import net.md_5.bungee.api.event.PluginMessageEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority;
import org.geysermc.cumulus.Form;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
@@ -79,7 +80,7 @@ public final class BungeePluginMessageHandler extends PluginMessageHandler imple
proxy.registerChannel(skinChannel);
}
@EventHandler
@EventHandler(priority = EventPriority.LOW)
public void onPluginMessage(PluginMessageEvent event) {
Connection source = event.getSender();
@@ -151,10 +152,12 @@ public final class BungeePluginMessageHandler extends PluginMessageHandler imple
return;
}
byte[] responseData = new byte[data.length - 2];
System.arraycopy(data, 2, responseData, 0, responseData.length);
JsonObject response;
try {
Reader reader = new InputStreamReader(
new ByteArrayInputStream(event.getData()));
Reader reader = new InputStreamReader(new ByteArrayInputStream(responseData));
response = GSON.fromJson(reader, JsonObject.class);
} catch (Throwable throwable) {
logger.error("Failed to read Skin response", throwable);
@@ -187,13 +190,20 @@ public final class BungeePluginMessageHandler extends PluginMessageHandler imple
return false;
}
@Override
public boolean sendSkinRequest(UUID uuid, RawSkin skin) {
ProxiedPlayer player = proxy.getPlayer(uuid);
if (player != null) {
player.sendData(skinChannel, createSkinRequestData(skin.encode()));
public boolean sendSkinRequest(Server server, RawSkin skin) {
if (server != null) {
server.sendData(skinChannel, createSkinRequestData(skin.encode()));
return true;
}
return false;
}
@Override
public boolean sendSkinRequest(UUID uuid, RawSkin skin) {
ProxiedPlayer player = proxy.getPlayer(uuid);
if (player != null) {
return sendSkinRequest(player.getServer(), skin);
}
return false;
}
}

View File

@@ -41,6 +41,7 @@ import org.geysermc.floodgate.config.FloodgateConfig;
import org.geysermc.floodgate.config.FloodgateConfigHolder;
import org.geysermc.floodgate.config.loader.ConfigLoader;
import org.geysermc.floodgate.link.PlayerLinkLoader;
import org.geysermc.floodgate.module.ConfigLoadedModule;
import org.geysermc.floodgate.module.PostInitializeModule;
public class FloodgatePlatform {
@@ -64,7 +65,7 @@ public class FloodgatePlatform {
@Inject
public void init(@Named("dataDirectory") Path dataDirectory, ConfigLoader configLoader,
PlayerLinkLoader playerLinkLoader, FloodgateConfigHolder configHolder) {
FloodgateConfigHolder configHolder) {
if (!Files.isDirectory(dataDirectory)) {
try {
@@ -81,7 +82,8 @@ public class FloodgatePlatform {
}
configHolder.set(config);
PlayerLink link = playerLinkLoader.load();
guice = guice.createChildInjector(new ConfigLoadedModule(config));
PlayerLink link = guice.getInstance(PlayerLinkLoader.class).load();
InstanceHolder.setInstance(api, link, this.injector, KEY);
}

View File

@@ -64,12 +64,15 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer {
private final InputMode inputMode;
private final String ip;
private final boolean fromProxy;
private final boolean proxy; // if current platform is a proxy
private final LinkedPlayer linkedPlayer;
private final RawSkin rawSkin;
@Getter(AccessLevel.PRIVATE)
public Map<PropertyKey, Object> propertyKeyToValue;
@Getter(AccessLevel.PRIVATE)
private Map<String, PropertyKey> stringToPropertyKey;
/**
* Returns true if the player is still logging in
*/
@@ -93,12 +96,6 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer {
UiProfile uiProfile = UiProfile.getById(data.getUiProfile());
InputMode inputMode = InputMode.getById(data.getInputMode());
// RawSkin must be removed from the encrypted data
if (api instanceof ProxyFloodgateApi) {
InstanceHolder.castApi(ProxyFloodgateApi.class)
.updateEncryptedData(javaUniqueId, data);
}
LinkedPlayer linkedPlayer;
// we'll use the LinkedPlayer provided by Bungee or Velocity (if they included one)
@@ -113,11 +110,11 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer {
FloodgatePlayerImpl player = new FloodgatePlayerImpl(
data.getVersion(), data.getUsername(), javaUsername, javaUniqueId, data.getXuid(),
deviceOs, data.getLanguageCode(), uiProfile, inputMode, data.getIp(),
data.isFromProxy(), linkedPlayer, skin);
data.isFromProxy(), api instanceof ProxyFloodgateApi, linkedPlayer, skin);
// encrypted data has been changed after fetching the linkedPlayer
// We have to update it...
if (linkedPlayer != null && api instanceof ProxyFloodgateApi) {
// RawSkin should be removed, fromProxy should be changed
// and encrypted data can be changed after fetching the linkedPlayer
if (api instanceof ProxyFloodgateApi) {
InstanceHolder.castApi(ProxyFloodgateApi.class)
.updateEncryptedData(player.getCorrectUniqueId(), player.toBedrockData());
}
@@ -169,7 +166,7 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer {
public BedrockData toBedrockData() {
return BedrockData.of(
version, username, xuid, deviceOs.ordinal(), languageCode,
uiProfile.ordinal(), inputMode.ordinal(), ip, linkedPlayer, fromProxy);
uiProfile.ordinal(), inputMode.ordinal(), ip, linkedPlayer, proxy);
}
public <T> T getProperty(PropertyKey key) {

View File

@@ -41,6 +41,7 @@ import org.geysermc.floodgate.api.player.PropertyKey;
import org.geysermc.floodgate.config.FloodgateConfigHolder;
import org.geysermc.floodgate.crypto.AesCipher;
import org.geysermc.floodgate.crypto.FloodgateCipher;
import org.geysermc.floodgate.util.Base64Utils;
import org.geysermc.floodgate.util.BedrockData;
import org.geysermc.floodgate.util.InvalidFormatException;
import org.geysermc.floodgate.util.RawSkin;
@@ -67,15 +68,16 @@ public final class HandshakeHandler {
return ResultType.NOT_FLOODGATE_DATA.getCachedResult();
}
// calculate the expected Base64 encoded IV length.
int expectedIvLength = 4 * ((AesCipher.IV_LENGTH + 2) / 3);
// header + base64 iv - 0x21 - encrypted data - 0x21 - RawSkin
int expectedHeaderLength = FloodgateCipher.HEADER_LENGTH +
Base64Utils.getEncodedLength(AesCipher.IV_LENGTH);
int lastSplitIndex = data.lastIndexOf(0x21);
byte[] floodgateData;
byte[] rawSkinData = null;
// if it has a RawSkin
if (lastSplitIndex - expectedIvLength != 0) {
if (lastSplitIndex - expectedHeaderLength > 0) {
floodgateData = data.substring(0, lastSplitIndex).getBytes(Charsets.UTF_8);
rawSkinData = data.substring(lastSplitIndex + 1).getBytes(Charsets.UTF_8);
} else {

View File

@@ -37,7 +37,7 @@ public class FloodgateConfig {
private String keyFileName;
private String usernamePrefix;
private boolean replaceSpaces;
private boolean applySkinDirectly; //todo
private boolean applySkinDirectly; //todo how is this possible for proxies?
private String defaultLocale;

View File

@@ -29,9 +29,8 @@ import static java.util.Objects.requireNonNull;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import java.io.IOException;
import java.io.InputStream;
@@ -42,21 +41,22 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import javax.inject.Named;
import org.geysermc.floodgate.api.link.PlayerLink;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.config.FloodgateConfig;
import org.geysermc.floodgate.config.FloodgateConfigHolder;
@RequiredArgsConstructor
@Singleton
public final class PlayerLinkLoader {
private final Injector injector;
private final FloodgateConfigHolder configHolder;
private final FloodgateLogger logger;
private final Path dataDirectory;
@Inject private Injector injector;
@Inject private FloodgateConfig config;
@Inject private FloodgateLogger logger;
@Inject
@Named("dataDirectory")
private Path dataDirectory;
public PlayerLink load() {
FloodgateConfig config = configHolder.get();
if (config == null) {
throw new IllegalStateException("Config cannot be null!");
}
@@ -125,17 +125,8 @@ public final class PlayerLinkLoader {
return null;
}
// allow the FloodgateConfig to be used directly instead of the FloodgateConfigHolder
Injector child = injector.createChildInjector(new AbstractModule() {
@Provides
@Singleton
public FloodgateConfig floodgateConfig() {
return config;
}
});
try {
PlayerLink instance = child.getInstance(mainClass);
PlayerLink instance = injector.getInstance(mainClass);
instance.load();
return instance;
} catch (Exception exception) {

View File

@@ -26,7 +26,6 @@
package org.geysermc.floodgate.module;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
@@ -50,7 +49,6 @@ import org.geysermc.floodgate.crypto.Base64Topping;
import org.geysermc.floodgate.crypto.FloodgateCipher;
import org.geysermc.floodgate.crypto.KeyProducer;
import org.geysermc.floodgate.inject.CommonPlatformInjector;
import org.geysermc.floodgate.link.PlayerLinkLoader;
import org.geysermc.floodgate.util.LanguageManager;
@RequiredArgsConstructor
@@ -114,15 +112,6 @@ public class CommonModule extends AbstractModule {
return new LanguageManager(configHolder, logger);
}
@Provides
@Singleton
public PlayerLinkLoader playerLinkLoader(Injector injector,
FloodgateConfigHolder configHolder,
FloodgateLogger logger,
@Named("dataDirectory") Path dataDirectory) {
return new PlayerLinkLoader(injector, configHolder, logger, dataDirectory);
}
@Provides
@Singleton
public HandshakeHandler handshakeHandler(SimpleFloodgateApi api, FloodgateCipher cipher,

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2019-2020 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.module;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import lombok.RequiredArgsConstructor;
import org.geysermc.floodgate.config.FloodgateConfig;
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
@RequiredArgsConstructor
public final class ConfigLoadedModule extends AbstractModule {
private final FloodgateConfig config;
@Override
protected void configure() {
if (config instanceof ProxyFloodgateConfig) {
bind(ProxyFloodgateConfig.class).toInstance((ProxyFloodgateConfig) config);
}
}
@Provides
@Singleton
public FloodgateConfig floodgateConfig() {
return config;
}
}

View File

@@ -45,6 +45,10 @@ public final class ServerSkinHandler extends SkinHandler {
}
public void handleSkinUploadFor(FloodgatePlayer player, RawSkin rawSkin) {
if (player == null || rawSkin == null) {
return;
}
handleSkinUploadFor(player, rawSkin,
(failed, response) -> {
if (player.isFromProxy()) {

View File

@@ -197,6 +197,7 @@ public final class SpigotDataHandler extends SimpleChannelInboundHandler<Object>
return;
}
// todo move this to HandshakeHandler?
ctx.channel().attr(playerAttribute).set(result.getFloodgatePlayer());
fPlayer = result.getFloodgatePlayer();

View File

@@ -98,6 +98,8 @@ public class SpigotPluginMessageRegister {
skinHandler.handleSkinUploadFor(floodgatePlayer, rawSkin);
}
);
messenger.registerOutgoingPluginChannel(plugin, skinChannel);
}
private void logKick(Player player, String reason) {

View File

@@ -110,7 +110,6 @@ public final class VelocityProxyDataHandler extends SimpleChannelInboundHandler<
// has the FloodgatePlayer attribute
ctx.channel().attr(playerAttribute).set(player);
api.addEncryptedData(player.getCorrectUniqueId(), result.getHandshakeData()[1]);
logger.info("Floodgate player who is logged in as {} {} joined",
player.getCorrectUsername(), player.getCorrectUniqueId());
}

View File

@@ -35,12 +35,9 @@ import com.velocitypowered.api.proxy.ProxyServer;
import io.netty.util.AttributeKey;
import org.geysermc.floodgate.VelocityPlugin;
import org.geysermc.floodgate.api.ProxyFloodgateApi;
import org.geysermc.floodgate.api.SimpleFloodgateApi;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.command.VelocityCommandRegistration;
import org.geysermc.floodgate.config.FloodgateConfig;
import org.geysermc.floodgate.config.FloodgateConfigHolder;
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
import org.geysermc.floodgate.crypto.FloodgateCipher;
import org.geysermc.floodgate.inject.CommonPlatformInjector;
import org.geysermc.floodgate.inject.velocity.VelocityInjector;
@@ -58,17 +55,9 @@ import org.slf4j.Logger;
public final class VelocityPlatformModule extends AbstractModule {
@Override
protected void configure() {
bind(SimpleFloodgateApi.class).to(ProxyFloodgateApi.class);
bind(CommandUtil.class).to(VelocityCommandUtil.class);
}
@Provides
@Singleton
@Named("configClass")
public Class<? extends FloodgateConfig> floodgateConfigClass() {
return ProxyFloodgateConfig.class;
}
@Provides
@Singleton
public ProxyFloodgateApi proxyFloodgateApi(PluginMessageHandler pluginMessageHandler,