Don't always store cert/client data used for skin uploaded

This takes up a decent 30K of memory that we don't use after the skin is uploaded. The GameProfileTranslator cannot be run more than once per session.
This commit is contained in:
Camotoy 2022-04-11 15:44:15 -04:00
parent 1d3eebc678
commit cb8858fc42
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
5 changed files with 24 additions and 15 deletions

View file

@ -25,6 +25,7 @@
package org.geysermc.geyser.session; package org.geysermc.geyser.session;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.data.GameProfile;
import com.github.steveice10.mc.auth.exception.request.InvalidCredentialsException; import com.github.steveice10.mc.auth.exception.request.InvalidCredentialsException;
import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.auth.exception.request.RequestException;
@ -142,6 +143,11 @@ public class GeyserSession implements GeyserConnection, CommandSender {
private AuthData authData; private AuthData authData;
@Setter @Setter
private BedrockClientData clientData; private BedrockClientData clientData;
/**
* Used for Floodgate skin uploading
*/
@Setter
private JsonNode certChainData;
/* Setter for GeyserConnect */ /* Setter for GeyserConnect */
@Setter @Setter

View file

@ -25,18 +25,7 @@
package org.geysermc.geyser.session.auth; package org.geysermc.geyser.session.auth;
import com.fasterxml.jackson.databind.JsonNode;
import org.geysermc.geyser.GeyserImpl;
import java.util.UUID; import java.util.UUID;
public record AuthData(String name, UUID uuid, String xuid, public record AuthData(String name, UUID uuid, String xuid) {
JsonNode certChainData, String clientData) {
public void upload(GeyserImpl geyser) {
// we can't upload the skin in LoginEncryptionUtil since the global server would return
// the skin too fast, that's why we upload it after we know for sure that the target server
// is ready to handle the result of the global server
geyser.getSkinUploader().uploadSkin(certChainData, clientData);
}
} }

View file

@ -25,9 +25,11 @@
package org.geysermc.geyser.session.auth; package org.geysermc.geyser.session.auth;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import org.geysermc.floodgate.util.DeviceOs; import org.geysermc.floodgate.util.DeviceOs;
import org.geysermc.floodgate.util.InputMode; import org.geysermc.floodgate.util.InputMode;
import org.geysermc.floodgate.util.UiProfile; import org.geysermc.floodgate.util.UiProfile;
@ -107,6 +109,10 @@ public final class BedrockClientData {
@JsonProperty(value = "PlayFabId") @JsonProperty(value = "PlayFabId")
private String playFabId; private String playFabId;
@JsonIgnore
@Setter
private String originalString = null;
public DeviceOs getDeviceOs() { public DeviceOs getDeviceOs() {
return deviceOs != null ? deviceOs : DeviceOs.UNKNOWN; return deviceOs != null ? deviceOs : DeviceOs.UNKNOWN;
} }

View file

@ -57,7 +57,13 @@ public class JavaGameProfileTranslator extends PacketTranslator<ClientboundGameP
if (remoteAuthType == AuthType.FLOODGATE) { if (remoteAuthType == AuthType.FLOODGATE) {
// We'll send the skin upload a bit after the handshake packet (aka this packet), // We'll send the skin upload a bit after the handshake packet (aka this packet),
// because otherwise the global server returns the data too fast. // because otherwise the global server returns the data too fast.
session.getAuthData().upload(session.getGeyser()); // We upload it after we know for sure that the target server
} // is ready to handle the result of the global server.
session.getGeyser().getSkinUploader().uploadSkin(session.getCertChainData(), session.getClientData().getOriginalString());
}
// We no longer need these variables; they're just taking up space in memory now
session.setCertChainData(null);
session.getClientData().setOriginalString(null);
} }
} }

View file

@ -155,10 +155,11 @@ public class LoginEncryptionUtils {
session.setAuthenticationData(new AuthData( session.setAuthenticationData(new AuthData(
extraData.get("displayName").asText(), extraData.get("displayName").asText(),
UUID.fromString(extraData.get("identity").asText()), UUID.fromString(extraData.get("identity").asText()),
extraData.get("XUID").asText(), extraData.get("XUID").asText()
certChainData, clientData
)); ));
session.setCertChainData(certChainData);
if (payload.get("identityPublicKey").getNodeType() != JsonNodeType.STRING) { if (payload.get("identityPublicKey").getNodeType() != JsonNodeType.STRING) {
throw new RuntimeException("Identity Public Key was not found!"); throw new RuntimeException("Identity Public Key was not found!");
} }
@ -169,6 +170,7 @@ public class LoginEncryptionUtils {
JsonNode clientDataJson = JSON_MAPPER.readTree(clientJwt.getPayload().toBytes()); JsonNode clientDataJson = JSON_MAPPER.readTree(clientJwt.getPayload().toBytes());
BedrockClientData data = JSON_MAPPER.convertValue(clientDataJson, BedrockClientData.class); BedrockClientData data = JSON_MAPPER.convertValue(clientDataJson, BedrockClientData.class);
data.setOriginalString(clientData);
session.setClientData(data); session.setClientData(data);
if (EncryptionUtils.canUseEncryption()) { if (EncryptionUtils.canUseEncryption()) {