mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-19 14:59:20 +00:00
Changed the plugin name and it can now receive RawSkins
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
name: ${outputName}
|
name: ${project.parent.version}
|
||||||
description: ${project.description}
|
description: ${project.description}
|
||||||
version: ${project.version}
|
version: ${project.version}
|
||||||
author: ${project.organization.name}
|
author: ${project.organization.name}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer {
|
|||||||
@Setter
|
@Setter
|
||||||
private boolean login = true;
|
private boolean login = true;
|
||||||
|
|
||||||
FloodgatePlayerImpl(BedrockData data, String prefix, boolean replaceSpaces) {
|
FloodgatePlayerImpl(BedrockData data, RawSkin skin, String prefix, boolean replaceSpaces) {
|
||||||
FloodgateApi api = FloodgateApi.getInstance();
|
FloodgateApi api = FloodgateApi.getInstance();
|
||||||
version = data.getVersion();
|
version = data.getVersion();
|
||||||
username = data.getUsername();
|
username = data.getUsername();
|
||||||
|
|||||||
@@ -26,16 +26,17 @@
|
|||||||
|
|
||||||
package org.geysermc.floodgate;
|
package org.geysermc.floodgate;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.geysermc.floodgate.api.SimpleFloodgateApi;
|
import org.geysermc.floodgate.api.SimpleFloodgateApi;
|
||||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
|
import org.geysermc.floodgate.crypto.AesCipher;
|
||||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||||
import org.geysermc.floodgate.util.BedrockData;
|
import org.geysermc.floodgate.util.BedrockData;
|
||||||
import org.geysermc.floodgate.util.InvalidHeaderException;
|
import org.geysermc.floodgate.util.InvalidFormatException;
|
||||||
|
import org.geysermc.floodgate.util.RawSkin;
|
||||||
import java.util.Base64;
|
|
||||||
|
|
||||||
import static org.geysermc.floodgate.util.BedrockData.EXPECTED_LENGTH;
|
import static org.geysermc.floodgate.util.BedrockData.EXPECTED_LENGTH;
|
||||||
|
|
||||||
@@ -57,35 +58,67 @@ public final class HandshakeHandler {
|
|||||||
|
|
||||||
public HandshakeResult handle(@NonNull String handshakeData) {
|
public HandshakeResult handle(@NonNull String handshakeData) {
|
||||||
try {
|
try {
|
||||||
String[] data = handshakeData.split("\0");
|
String[] dataArray = handshakeData.split("\0");
|
||||||
|
|
||||||
boolean isBungeeData = data.length == 5;
|
boolean isBungeeData = dataArray.length == 5;
|
||||||
// this can be Bungee data (without skin) or Floodgate data
|
// this can be Bungee data (without skin) or Floodgate data
|
||||||
if (data.length == 4) {
|
if (dataArray.length == 4) {
|
||||||
isBungeeData = FloodgateCipher.hasHeader(data[3]);
|
isBungeeData = FloodgateCipher.hasHeader(dataArray[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy && isBungeeData || !isBungeeData && data.length != 2) {
|
if (proxy && isBungeeData || !isBungeeData && dataArray.length != 2) {
|
||||||
return ResultType.NOT_FLOODGATE_DATA.getCachedResult();
|
return ResultType.NOT_FLOODGATE_DATA.getCachedResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
String decrypted = cipher.decryptToString(Base64.getDecoder().decode(data[1]));
|
// calculate the expected Base64 encoded IV length.
|
||||||
|
int expectedIvLength = 4 * ((AesCipher.IV_LENGTH + 2) / 3);
|
||||||
|
int lastSplitIndex = dataArray[1].lastIndexOf(0x21);
|
||||||
|
|
||||||
|
byte[] floodgateData;
|
||||||
|
byte[] rawSkinData = null;
|
||||||
|
|
||||||
|
// if it has a RawSkin
|
||||||
|
if (lastSplitIndex - expectedIvLength != 0) {
|
||||||
|
floodgateData = dataArray[1].substring(0, lastSplitIndex).getBytes(Charsets.UTF_8);
|
||||||
|
rawSkinData = dataArray[1].substring(lastSplitIndex + 1).getBytes(Charsets.UTF_8);
|
||||||
|
} else {
|
||||||
|
floodgateData = dataArray[1].getBytes(Charsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// actual decryption
|
||||||
|
String decrypted = cipher.decryptToString(floodgateData);
|
||||||
BedrockData bedrockData = BedrockData.fromString(decrypted);
|
BedrockData bedrockData = BedrockData.fromString(decrypted);
|
||||||
|
|
||||||
if (bedrockData.getDataLength() != EXPECTED_LENGTH) {
|
if (bedrockData.getDataLength() != EXPECTED_LENGTH) {
|
||||||
return ResultType.INVALID_DATA_LENGTH.getCachedResult();
|
return ResultType.INVALID_DATA_LENGTH.getCachedResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RawSkin rawSkin = null;
|
||||||
|
// only decompile the skin after knowing that the floodgateData is legit
|
||||||
|
// note that we don't store a hash or anything in the BedrockData,
|
||||||
|
// so a mitm can change skins
|
||||||
|
if (rawSkinData != null) {
|
||||||
|
rawSkin = RawSkin.decode(rawSkinData);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(rawSkin);
|
||||||
|
|
||||||
FloodgatePlayer player =
|
FloodgatePlayer player =
|
||||||
new FloodgatePlayerImpl(bedrockData, usernamePrefix, replaceSpaces);
|
new FloodgatePlayerImpl(bedrockData, rawSkin, usernamePrefix, replaceSpaces);
|
||||||
api.addPlayer(player.getJavaUniqueId(), player);
|
api.addPlayer(player.getJavaUniqueId(), player);
|
||||||
|
|
||||||
return new HandshakeResult(ResultType.SUCCESS, data, bedrockData, player);
|
return new HandshakeResult(ResultType.SUCCESS, dataArray, bedrockData, player);
|
||||||
} catch (InvalidHeaderException headerException) {
|
} catch (InvalidFormatException formatException) {
|
||||||
return ResultType.NOT_FLOODGATE_DATA.getCachedResult();
|
// only header exceptions should return 'not floodgate data',
|
||||||
|
// all the other format exceptions are because of invalid/tempered Floodgate data
|
||||||
|
if (formatException.isHeader()) {
|
||||||
|
return ResultType.NOT_FLOODGATE_DATA.getCachedResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
formatException.printStackTrace();
|
||||||
|
return ResultType.EXCEPTION.getCachedResult();
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
System.out.println(handshakeData);
|
|
||||||
return ResultType.EXCEPTION.getCachedResult();
|
return ResultType.EXCEPTION.getCachedResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,10 +42,7 @@ import org.geysermc.floodgate.config.FloodgateConfig;
|
|||||||
import org.geysermc.floodgate.config.loader.ConfigLoader;
|
import org.geysermc.floodgate.config.loader.ConfigLoader;
|
||||||
import org.geysermc.floodgate.config.updater.ConfigFileUpdater;
|
import org.geysermc.floodgate.config.updater.ConfigFileUpdater;
|
||||||
import org.geysermc.floodgate.config.updater.ConfigUpdater;
|
import org.geysermc.floodgate.config.updater.ConfigUpdater;
|
||||||
import org.geysermc.floodgate.crypto.AesCipher;
|
import org.geysermc.floodgate.crypto.*;
|
||||||
import org.geysermc.floodgate.crypto.AesKeyProducer;
|
|
||||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
|
||||||
import org.geysermc.floodgate.crypto.KeyProducer;
|
|
||||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||||
import org.geysermc.floodgate.link.PlayerLinkLoader;
|
import org.geysermc.floodgate.link.PlayerLinkLoader;
|
||||||
|
|
||||||
@@ -70,7 +67,7 @@ public final class CommonModule extends AbstractModule {
|
|||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public FloodgateCipher cipher() {
|
public FloodgateCipher cipher() {
|
||||||
return new AesCipher();
|
return new AesCipher(new Base64Topping());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -21,7 +21,7 @@
|
|||||||
<url>https://github.com/GeyserMC/Floodgate</url>
|
<url>https://github.com/GeyserMC/Floodgate</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<geyser.version>1.0.0</geyser.version>
|
<geyser.version>1.1.0</geyser.version>
|
||||||
<bukkit.version>1.8.8-R0.1-SNAPSHOT</bukkit.version>
|
<bukkit.version>1.8.8-R0.1-SNAPSHOT</bukkit.version>
|
||||||
<bungee.version>1.15-SNAPSHOT</bungee.version>
|
<bungee.version>1.15-SNAPSHOT</bungee.version>
|
||||||
<velocity.version>1.1.0-SNAPSHOT</velocity.version>
|
<velocity.version>1.1.0-SNAPSHOT</velocity.version>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
name: ${outputName}
|
name: ${project.parent.name}
|
||||||
description: ${project.description}
|
description: ${project.description}
|
||||||
version: ${project.version}
|
version: ${project.version}
|
||||||
author: ${project.organization.name}
|
author: ${project.organization.name}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"id": "${project.parent.name}", "name": "${outputName}", "version": "${project.version}", "description": "${project.description}", "url": "${project.url}", "authors": ["${project.organization.name}"], "main": "org.geysermc.floodgate.VelocityPlugin"}
|
{"id": "${project.parent.name}", "name": "${project.parent.name}", "version": "${project.version}", "description": "${project.description}", "url": "${project.url}", "authors": ["${project.organization.name}"], "main": "org.geysermc.floodgate.VelocityPlugin"}
|
||||||
Reference in New Issue
Block a user