mirror of
https://github.com/SKCraft/Launcher.git
synced 2024-11-27 12:46:22 +01:00
Switch to using Minecraft services as skin provider
We do some local processing to draw the head of the skin in 32px resolution.
This commit is contained in:
parent
fd78863697
commit
5d5a462387
@ -11,7 +11,7 @@ import com.skcraft.launcher.auth.microsoft.model.McAuthResponse;
|
||||
import com.skcraft.launcher.auth.microsoft.model.McProfileResponse;
|
||||
import com.skcraft.launcher.auth.microsoft.model.TokenResponse;
|
||||
import com.skcraft.launcher.auth.microsoft.model.XboxAuthorization;
|
||||
import com.skcraft.launcher.auth.skin.VisageSkinService;
|
||||
import com.skcraft.launcher.auth.skin.MinecraftSkinService;
|
||||
import com.skcraft.launcher.util.HttpRequest;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -103,10 +103,9 @@ public class MicrosoftLoginService implements LoginService {
|
||||
if (previous != null && previous.getAvatarImage() != null) {
|
||||
session.setAvatarImage(previous.getAvatarImage());
|
||||
} else {
|
||||
session.setAvatarImage(VisageSkinService.fetchSkinHead(profile.getUuid()));
|
||||
session.setAvatarImage(MinecraftSkinService.fetchSkinHead(profile));
|
||||
}
|
||||
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,9 @@
|
||||
package com.skcraft.launcher.auth;
|
||||
|
||||
import com.fasterxml.jackson.annotation.*;
|
||||
import com.skcraft.launcher.auth.skin.VisageSkinService;
|
||||
import com.skcraft.launcher.auth.microsoft.MinecraftServicesAuthorizer;
|
||||
import com.skcraft.launcher.auth.microsoft.model.McProfileResponse;
|
||||
import com.skcraft.launcher.auth.skin.MinecraftSkinService;
|
||||
import com.skcraft.launcher.util.HttpRequest;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -60,7 +62,10 @@ public class YggdrasilLoginService implements LoginService {
|
||||
if (previous != null && previous.getAvatarImage() != null) {
|
||||
profile.setAvatarImage(previous.getAvatarImage());
|
||||
} else {
|
||||
profile.setAvatarImage(VisageSkinService.fetchSkinHead(profile.getUuid()));
|
||||
McProfileResponse skinProfile = MinecraftServicesAuthorizer
|
||||
.getUserProfile("Bearer " + response.getAccessToken());
|
||||
|
||||
profile.setAvatarImage(MinecraftSkinService.fetchSkinHead(skinProfile));
|
||||
}
|
||||
|
||||
return profile;
|
||||
|
@ -28,8 +28,13 @@ public class MinecraftServicesAuthorizer {
|
||||
|
||||
public static McProfileResponse getUserProfile(McAuthResponse auth)
|
||||
throws IOException, InterruptedException, AuthenticationException {
|
||||
return getUserProfile(auth.getAuthorization());
|
||||
}
|
||||
|
||||
public static McProfileResponse getUserProfile(String authorization)
|
||||
throws IOException, InterruptedException, AuthenticationException {
|
||||
return HttpRequest.get(MC_SERVICES_PROFILE)
|
||||
.header("Authorization", auth.getAuthorization())
|
||||
.header("Authorization", authorization)
|
||||
.execute()
|
||||
.expectResponseCodeOr(200, req -> {
|
||||
McServicesError error = req.returnContent().asJson(McServicesError.class);
|
||||
|
@ -1,12 +1,28 @@
|
||||
package com.skcraft.launcher.auth.microsoft.model;
|
||||
|
||||
import com.beust.jcommander.internal.Lists;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class McProfileResponse {
|
||||
@JsonProperty("id") private String uuid;
|
||||
private String name;
|
||||
private List<Skin> skins = Lists.newArrayList();
|
||||
|
||||
public Skin getActiveSkin() {
|
||||
return skins.stream().filter(skin -> skin.getState().equals("ACTIVE")).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class Skin {
|
||||
private String state;
|
||||
private String url;
|
||||
private String variant;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
package com.skcraft.launcher.auth.skin;
|
||||
|
||||
import com.skcraft.launcher.auth.microsoft.model.McProfileResponse;
|
||||
import com.skcraft.launcher.util.HttpRequest;
|
||||
import lombok.extern.java.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@Log
|
||||
public class MinecraftSkinService {
|
||||
static byte[] downloadSkin(String textureUrl) throws IOException, InterruptedException {
|
||||
return HttpRequest.get(HttpRequest.url(textureUrl))
|
||||
.execute()
|
||||
.expectResponseCode(200)
|
||||
.returnContent()
|
||||
.asBytes();
|
||||
}
|
||||
|
||||
public static byte[] fetchSkinHead(McProfileResponse profile) throws InterruptedException {
|
||||
try {
|
||||
byte[] skin = downloadSkin(profile.getActiveSkin().getUrl());
|
||||
|
||||
return SkinProcessor.renderHead(skin);
|
||||
} catch (IOException e) {
|
||||
log.log(Level.WARNING, "Failed to download or process skin.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.skcraft.launcher.auth.skin;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class SkinProcessor {
|
||||
public static byte[] renderHead(byte[] skinData) throws IOException {
|
||||
BufferedImage skin = ImageIO.read(new ByteArrayInputStream(skinData));
|
||||
|
||||
BufferedImage result = new BufferedImage(32, 32, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics graphics = result.getGraphics();
|
||||
|
||||
// Draw bottom head layer
|
||||
graphics.drawImage(skin, 0, 0, 32, 32, 8, 8, 16, 16, null);
|
||||
// Draw top head layer
|
||||
graphics.drawImage(skin, 0, 0, 32, 32, 40, 8, 48, 16, null);
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
ImageIO.write(result, "png", outputStream);
|
||||
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
package com.skcraft.launcher.auth.skin;
|
||||
|
||||
import com.skcraft.launcher.util.HttpRequest;
|
||||
import lombok.extern.java.Log;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.skcraft.launcher.util.HttpRequest.url;
|
||||
|
||||
@Log
|
||||
public class VisageSkinService {
|
||||
@Nullable
|
||||
public static byte[] fetchSkinHead(String uuid) throws InterruptedException {
|
||||
@ -19,6 +22,7 @@ public class VisageSkinService {
|
||||
.returnContent()
|
||||
.asBytes();
|
||||
} catch (IOException e) {
|
||||
log.log(Level.WARNING, "Failed to download or process skin from Visage.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user