diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index bda43a71..1040b528 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -59,24 +59,6 @@
-
-
-
-
diff --git a/bungee/src/main/java/org/geysermc/floodgate/handler/BungeeDataHandler.java b/bungee/src/main/java/org/geysermc/floodgate/handler/BungeeDataHandler.java
index 7acc7093..6c3f9a3f 100644
--- a/bungee/src/main/java/org/geysermc/floodgate/handler/BungeeDataHandler.java
+++ b/bungee/src/main/java/org/geysermc/floodgate/handler/BungeeDataHandler.java
@@ -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());
diff --git a/bungee/src/main/java/org/geysermc/floodgate/listener/BungeeListener.java b/bungee/src/main/java/org/geysermc/floodgate/listener/BungeeListener.java
index c3b5b655..d8a420f6 100644
--- a/bungee/src/main/java/org/geysermc/floodgate/listener/BungeeListener.java
+++ b/bungee/src/main/java/org/geysermc/floodgate/listener/BungeeListener.java
@@ -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);
}
}
diff --git a/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java b/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java
index 3f29141a..7c86d11b 100644
--- a/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java
+++ b/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java
@@ -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
*/
diff --git a/bungee/src/main/java/org/geysermc/floodgate/pluginmessage/BungeePluginMessageHandler.java b/bungee/src/main/java/org/geysermc/floodgate/pluginmessage/BungeePluginMessageHandler.java
index 06453b01..8e87d050 100644
--- a/bungee/src/main/java/org/geysermc/floodgate/pluginmessage/BungeePluginMessageHandler.java
+++ b/bungee/src/main/java/org/geysermc/floodgate/pluginmessage/BungeePluginMessageHandler.java
@@ -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;
+ }
}
diff --git a/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java b/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java
index 2064e605..bbccfb52 100644
--- a/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java
+++ b/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java
@@ -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);
}
diff --git a/common/src/main/java/org/geysermc/floodgate/FloodgatePlayerImpl.java b/common/src/main/java/org/geysermc/floodgate/FloodgatePlayerImpl.java
index 909a4174..0130895d 100644
--- a/common/src/main/java/org/geysermc/floodgate/FloodgatePlayerImpl.java
+++ b/common/src/main/java/org/geysermc/floodgate/FloodgatePlayerImpl.java
@@ -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 propertyKeyToValue;
@Getter(AccessLevel.PRIVATE)
private Map 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 getProperty(PropertyKey key) {
diff --git a/common/src/main/java/org/geysermc/floodgate/HandshakeHandler.java b/common/src/main/java/org/geysermc/floodgate/HandshakeHandler.java
index 4cdd07a6..f727d7aa 100644
--- a/common/src/main/java/org/geysermc/floodgate/HandshakeHandler.java
+++ b/common/src/main/java/org/geysermc/floodgate/HandshakeHandler.java
@@ -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 {
diff --git a/common/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java b/common/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java
index de48850d..f8d54ad9 100644
--- a/common/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java
+++ b/common/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java
@@ -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;
diff --git a/common/src/main/java/org/geysermc/floodgate/link/PlayerLinkLoader.java b/common/src/main/java/org/geysermc/floodgate/link/PlayerLinkLoader.java
index 7b010c34..1238ee57 100644
--- a/common/src/main/java/org/geysermc/floodgate/link/PlayerLinkLoader.java
+++ b/common/src/main/java/org/geysermc/floodgate/link/PlayerLinkLoader.java
@@ -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) {
diff --git a/common/src/main/java/org/geysermc/floodgate/module/CommonModule.java b/common/src/main/java/org/geysermc/floodgate/module/CommonModule.java
index f5b648d4..822bac53 100644
--- a/common/src/main/java/org/geysermc/floodgate/module/CommonModule.java
+++ b/common/src/main/java/org/geysermc/floodgate/module/CommonModule.java
@@ -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,
diff --git a/common/src/main/java/org/geysermc/floodgate/module/ConfigLoadedModule.java b/common/src/main/java/org/geysermc/floodgate/module/ConfigLoadedModule.java
new file mode 100644
index 00000000..b5414f0f
--- /dev/null
+++ b/common/src/main/java/org/geysermc/floodgate/module/ConfigLoadedModule.java
@@ -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;
+ }
+}
diff --git a/common/src/main/java/org/geysermc/floodgate/skin/ServerSkinHandler.java b/common/src/main/java/org/geysermc/floodgate/skin/ServerSkinHandler.java
index f5d0c8c0..49aaecc5 100644
--- a/common/src/main/java/org/geysermc/floodgate/skin/ServerSkinHandler.java
+++ b/common/src/main/java/org/geysermc/floodgate/skin/ServerSkinHandler.java
@@ -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()) {
diff --git a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java
index 86a0f63c..b0941314 100644
--- a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java
+++ b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java
@@ -197,6 +197,7 @@ public final class SpigotDataHandler extends SimpleChannelInboundHandler