Don't use the general thread pool to run an async method (#1397)

* Don't use the general thread pool for an async method

* Align nested class at the bottom
This commit is contained in:
Tim203 2020-10-15 05:34:24 +02:00 committed by GitHub
parent 73bec588fa
commit 2ca2436cdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 128 additions and 145 deletions

View File

@ -57,9 +57,8 @@ public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayer
if (self) {
// Entity is ourself
playerEntity = session.getPlayerEntity();
SkinUtils.requestAndHandleSkinAndCape(playerEntity, session, skinAndCape -> {
GeyserConnector.getInstance().getLogger().debug("Loading Local Bedrock Java Skin Data");
});
SkinUtils.requestAndHandleSkinAndCape(playerEntity, session, skinAndCape ->
GeyserConnector.getInstance().getLogger().debug("Loaded Local Bedrock Java Skin Data"));
} else {
playerEntity = session.getEntityCache().getPlayerEntity(entry.getProfile().getId());
}

View File

@ -33,9 +33,8 @@ import com.nukkitx.protocol.bedrock.data.skin.SerializedSkin;
import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.geysermc.connector.common.AuthType;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.common.AuthType;
import org.geysermc.connector.entity.PlayerEntity;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.session.auth.BedrockClientData;
@ -73,21 +72,6 @@ public class SkinUtils {
);
}
public static PlayerListPacket.Entry buildDefaultEntry(GeyserSession session, GameProfile profile, long geyserId) {
return buildEntryManually(
session,
profile.getId(),
profile.getName(),
geyserId,
"default",
SkinProvider.STEVE_SKIN,
SkinProvider.EMPTY_CAPE.getCapeId(),
SkinProvider.EMPTY_CAPE.getCapeData(),
SkinProvider.EMPTY_GEOMETRY.getGeometryName(),
SkinProvider.EMPTY_GEOMETRY.getGeometryData()
);
}
public static PlayerListPacket.Entry buildEntryManually(GeyserSession session, UUID uuid, String username, long geyserId,
String skinId, byte[] skinData,
String capeId, byte[] capeData,
@ -126,54 +110,8 @@ public class SkinUtils {
return entry;
}
@AllArgsConstructor
@Getter
public static class GameProfileData {
private String skinUrl;
private String capeUrl;
private boolean alex;
/**
* Generate the GameProfileData from the given GameProfile
*
* @param profile GameProfile to build the GameProfileData from
* @return The built GameProfileData
*/
public static GameProfileData from(GameProfile profile) {
// Fallback to the offline mode of working it out
boolean isAlex = (Math.abs(profile.getId().hashCode() % 2) == 1);
try {
GameProfile.Property skinProperty = profile.getProperty("textures");
JsonNode skinObject = new ObjectMapper().readTree(new String(Base64.getDecoder().decode(skinProperty.getValue()), StandardCharsets.UTF_8));
JsonNode textures = skinObject.get("textures");
JsonNode skinTexture = textures.get("SKIN");
String skinUrl = skinTexture.get("url").asText().replace("http://", "https://");
isAlex = skinTexture.has("metadata");
String capeUrl = null;
if (textures.has("CAPE")) {
JsonNode capeTexture = textures.get("CAPE");
capeUrl = capeTexture.get("url").asText().replace("http://", "https://");
}
return new GameProfileData(skinUrl, capeUrl, isAlex);
} catch (Exception exception) {
if (GeyserConnector.getInstance().getAuthType() != AuthType.OFFLINE) {
GeyserConnector.getInstance().getLogger().debug("Got invalid texture data for " + profile.getName() + " " + exception.getMessage());
}
// return default skin with default cape when texture data is invalid
return new GameProfileData((isAlex ? SkinProvider.EMPTY_SKIN_ALEX.getTextureUrl() : SkinProvider.EMPTY_SKIN.getTextureUrl()), SkinProvider.EMPTY_CAPE.getTextureUrl(), isAlex);
}
}
}
public static void requestAndHandleSkinAndCape(PlayerEntity entity, GeyserSession session,
Consumer<SkinProvider.SkinAndCape> skinAndCapeConsumer) {
GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> {
GameProfileData data = GameProfileData.from(entity.getProfile());
SkinProvider.requestSkinAndCape(entity.getUuid(), data.getSkinUrl(), data.getCapeUrl())
@ -202,7 +140,7 @@ public class SkinUtils {
// Not a bedrock player check for ears
if (geometry.isFailed() && SkinProvider.ALLOW_THIRD_PARTY_EARS) {
boolean isEars = false;
boolean isEars;
// Its deadmau5, gotta support his skin :)
if (entity.getUuid().toString().equals("1e18d5ff-643d-45c8-b509-43b8461d8614")) {
@ -261,8 +199,9 @@ public class SkinUtils {
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), e);
}
if (skinAndCapeConsumer != null) skinAndCapeConsumer.accept(skinAndCape);
});
if (skinAndCapeConsumer != null) {
skinAndCapeConsumer.accept(skinAndCape);
}
});
}
@ -270,11 +209,11 @@ public class SkinUtils {
GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.skin.bedrock.register", playerEntity.getUsername(), playerEntity.getUuid()));
try {
byte[] skinBytes = Base64.getDecoder().decode(clientData.getSkinData().getBytes("UTF-8"));
byte[] skinBytes = Base64.getDecoder().decode(clientData.getSkinData().getBytes(StandardCharsets.UTF_8));
byte[] capeBytes = clientData.getCapeData();
byte[] geometryNameBytes = Base64.getDecoder().decode(clientData.getGeometryName().getBytes("UTF-8"));
byte[] geometryBytes = Base64.getDecoder().decode(clientData.getGeometryData().getBytes("UTF-8"));
byte[] geometryNameBytes = Base64.getDecoder().decode(clientData.getGeometryName().getBytes(StandardCharsets.UTF_8));
byte[] geometryBytes = Base64.getDecoder().decode(clientData.getGeometryData().getBytes(StandardCharsets.UTF_8));
if (skinBytes.length <= (128 * 128 * 4) && !clientData.isPersonaSkin()) {
SkinProvider.storeBedrockSkin(playerEntity.getUuid(), clientData.getSkinId(), skinBytes);
@ -291,4 +230,49 @@ public class SkinUtils {
throw new AssertionError("Failed to cache skin for bedrock user (" + playerEntity.getUsername() + "): ", e);
}
}
@AllArgsConstructor
@Getter
public static class GameProfileData {
private final String skinUrl;
private final String capeUrl;
private final boolean alex;
/**
* Generate the GameProfileData from the given GameProfile
*
* @param profile GameProfile to build the GameProfileData from
* @return The built GameProfileData
*/
public static GameProfileData from(GameProfile profile) {
// Fallback to the offline mode of working it out
boolean isAlex = (Math.abs(profile.getId().hashCode() % 2) == 1);
try {
GameProfile.Property skinProperty = profile.getProperty("textures");
JsonNode skinObject = new ObjectMapper().readTree(new String(Base64.getDecoder().decode(skinProperty.getValue()), StandardCharsets.UTF_8));
JsonNode textures = skinObject.get("textures");
JsonNode skinTexture = textures.get("SKIN");
String skinUrl = skinTexture.get("url").asText().replace("http://", "https://");
isAlex = skinTexture.has("metadata");
String capeUrl = null;
if (textures.has("CAPE")) {
JsonNode capeTexture = textures.get("CAPE");
capeUrl = capeTexture.get("url").asText().replace("http://", "https://");
}
return new GameProfileData(skinUrl, capeUrl, isAlex);
} catch (Exception exception) {
if (GeyserConnector.getInstance().getAuthType() != AuthType.OFFLINE) {
GeyserConnector.getInstance().getLogger().debug("Got invalid texture data for " + profile.getName() + " " + exception.getMessage());
}
// return default skin with default cape when texture data is invalid
return new GameProfileData((isAlex ? SkinProvider.EMPTY_SKIN_ALEX.getTextureUrl() : SkinProvider.EMPTY_SKIN.getTextureUrl()), SkinProvider.EMPTY_CAPE.getTextureUrl(), isAlex);
}
}
}
}