mirror of
https://github.com/SKCraft/Launcher.git
synced 2025-01-05 19:09:03 +01:00
Fix persistence, download & persist avatar locally
This commit is contained in:
parent
b6252863da
commit
18a99b338e
@ -42,4 +42,9 @@ subprojects {
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaExec) {
|
||||
workingDir = new File(rootDir, "run/")
|
||||
workingDir.mkdirs()
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.skcraft.launcher.dialog.component.ListListenerReducer;
|
||||
import com.skcraft.launcher.persistence.Scrambled;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.apache.commons.lang.RandomStringUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
@ -17,7 +19,9 @@ import java.util.List;
|
||||
* Persisted account list
|
||||
*/
|
||||
@Scrambled("ACCOUNT_LIST_NOT_SECURITY!")
|
||||
@Data
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class NewAccountList implements ListModel<SavedSession> {
|
||||
private List<SavedSession> accounts = Lists.newArrayList();
|
||||
|
@ -62,6 +62,11 @@ public class OfflineSession implements Session {
|
||||
return UserType.LEGACY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAvatarImage() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnline() {
|
||||
return false;
|
||||
|
@ -1,9 +1,12 @@
|
||||
package com.skcraft.launcher.auth;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* Represents a session saved to disk.
|
||||
*/
|
||||
@ -15,6 +18,12 @@ public class SavedSession {
|
||||
private String username;
|
||||
private String accessToken;
|
||||
private String refreshToken;
|
||||
private String avatarImage;
|
||||
|
||||
@JsonIgnore
|
||||
public byte[] getAvatarBytes() {
|
||||
return Base64.getDecoder().decode(avatarImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
@ -64,6 +64,13 @@ public interface Session {
|
||||
*/
|
||||
UserType getUserType();
|
||||
|
||||
/**
|
||||
* Get the user's avatar
|
||||
*
|
||||
* @return User's avatar as a base64 string.
|
||||
*/
|
||||
String getAvatarImage();
|
||||
|
||||
/**
|
||||
* Return true if the user is in an online session.
|
||||
*
|
||||
@ -82,6 +89,7 @@ public interface Session {
|
||||
savedSession.setUsername(getName());
|
||||
savedSession.setUuid(getUuid());
|
||||
savedSession.setAccessToken(getAccessToken());
|
||||
savedSession.setAvatarImage(getAvatarImage());
|
||||
|
||||
return savedSession;
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
package com.skcraft.launcher.auth;
|
||||
|
||||
import com.skcraft.launcher.util.HttpRequest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
import static com.skcraft.launcher.util.HttpRequest.url;
|
||||
|
||||
public class VisageSkinService {
|
||||
public static String fetchSkinHead(String uuid) throws IOException, InterruptedException {
|
||||
String skinUrl = String.format("https://visage.surgeplay.com/face/32/%s.png", uuid);
|
||||
|
||||
byte[] skinBytes = HttpRequest.get(url(skinUrl))
|
||||
.execute()
|
||||
.expectResponseCode(200)
|
||||
.returnContent()
|
||||
.asBytes();
|
||||
|
||||
return Base64.getEncoder().encodeToString(skinBytes);
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ package com.skcraft.launcher.auth;
|
||||
import com.fasterxml.jackson.annotation.*;
|
||||
import com.skcraft.launcher.util.HttpRequest;
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.java.Log;
|
||||
|
||||
@ -22,27 +22,17 @@ import java.util.Map;
|
||||
* Creates authenticated sessions using the Mojang Yggdrasil login protocol.
|
||||
*/
|
||||
@Log
|
||||
@RequiredArgsConstructor
|
||||
public class YggdrasilLoginService implements LoginService {
|
||||
|
||||
private final URL authUrl;
|
||||
private final String clientId;
|
||||
|
||||
/**
|
||||
* Create a new login service with the given authentication URL.
|
||||
*
|
||||
* @param authUrl the authentication URL
|
||||
* @param clientId
|
||||
*/
|
||||
public YggdrasilLoginService(@NonNull URL authUrl, String clientId) {
|
||||
this.authUrl = authUrl;
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public Session login(String agent, String id, String password)
|
||||
throws IOException, InterruptedException, AuthenticationException {
|
||||
AuthenticatePayload payload = new AuthenticatePayload(new Agent(agent), id, password, clientId);
|
||||
|
||||
return call(this.authUrl, payload);
|
||||
return call(this.authUrl, payload, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -50,10 +40,10 @@ public class YggdrasilLoginService implements LoginService {
|
||||
throws IOException, InterruptedException, AuthenticationException {
|
||||
RefreshPayload payload = new RefreshPayload(savedSession.getAccessToken(), clientId);
|
||||
|
||||
return call(new URL(this.authUrl, "/refresh"), payload);
|
||||
return call(new URL(this.authUrl, "/refresh"), payload, savedSession);
|
||||
}
|
||||
|
||||
private Session call(URL url, Object payload)
|
||||
private Session call(URL url, Object payload, SavedSession previous)
|
||||
throws IOException, InterruptedException, AuthenticationException {
|
||||
HttpRequest req = HttpRequest
|
||||
.post(url)
|
||||
@ -66,8 +56,15 @@ public class YggdrasilLoginService implements LoginService {
|
||||
throw new AuthenticationException(error.getErrorMessage(), error.getErrorMessage());
|
||||
} else {
|
||||
AuthenticateResponse response = req.returnContent().asJson(AuthenticateResponse.class);
|
||||
Profile profile = response.getSelectedProfile();
|
||||
|
||||
return response.getSelectedProfile();
|
||||
if (previous == null || previous.getAvatarImage() == null) {
|
||||
profile.setAvatarImage(VisageSkinService.fetchSkinHead(profile.getUuid()));
|
||||
} else {
|
||||
profile.setAvatarImage(previous.getAvatarImage());
|
||||
}
|
||||
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,6 +114,7 @@ public class YggdrasilLoginService implements LoginService {
|
||||
@JsonProperty("id") private String uuid;
|
||||
private String name;
|
||||
private boolean legacy;
|
||||
private String avatarImage;
|
||||
@JsonIgnore private final Map<String, String> userProperties = Collections.emptyMap();
|
||||
@JsonBackReference private AuthenticateResponse response;
|
||||
|
||||
|
@ -17,16 +17,13 @@ import lombok.RequiredArgsConstructor;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static com.skcraft.launcher.util.HttpRequest.url;
|
||||
|
||||
public class AccountSelectDialog extends JDialog {
|
||||
private final JList<SavedSession> accountList;
|
||||
private final JButton loginButton = new JButton(SharedLocale.tr("login.login"));
|
||||
private final JButton cancelButton = new JButton(SharedLocale.tr("button.cancel"));
|
||||
private final JButton addAccountButton = new JButton(SharedLocale.tr("accounts.addNew"));
|
||||
private final JButton addAccountButton = new JButton(SharedLocale.tr("accounts.addMojang"));
|
||||
private final LinedBoxPanel buttonsPanel = new LinedBoxPanel(true);
|
||||
|
||||
private final Launcher launcher;
|
||||
@ -82,6 +79,7 @@ public class AccountSelectDialog extends JDialog {
|
||||
|
||||
if (newSession != null) {
|
||||
launcher.getAccounts().add(newSession.toSavedSession());
|
||||
setResult(newSession);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -117,7 +115,6 @@ public class AccountSelectDialog extends JDialog {
|
||||
Futures.addCallback(future, new FutureCallback<Session>() {
|
||||
@Override
|
||||
public void onSuccess(Session result) {
|
||||
// session.setAccessToken(result.getAccessToken());
|
||||
setResult(result);
|
||||
}
|
||||
|
||||
@ -161,9 +158,11 @@ public class AccountSelectDialog extends JDialog {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<? extends SavedSession> list, SavedSession value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
setText(value.getUsername());
|
||||
|
||||
URL avatarUrl = url("https://visage.surgeplay.com/face/24/" + value.getUuid() + ".png");
|
||||
setIcon(new ImageIcon(avatarUrl));
|
||||
if (value.getAvatarImage() != null) {
|
||||
setIcon(new ImageIcon(value.getAvatarBytes()));
|
||||
} else {
|
||||
setIcon(SwingHelper.createIcon(Launcher.class, "default_skin.png", 32, 32));
|
||||
}
|
||||
|
||||
if (isSelected) {
|
||||
setOpaque(true);
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 484 B |
@ -89,7 +89,8 @@ launcher.updatePendingHint=(pending update)
|
||||
|
||||
accounts.title=Select the account to play with
|
||||
accounts.refreshingStatus=Refreshing login session...
|
||||
accounts.addNew=Add a new account...
|
||||
accounts.addMojang=Log in via Mojang
|
||||
accounts.addMicrosoft=Log in via Microsoft
|
||||
|
||||
login.rememberId=Remember my account in the list
|
||||
login.rememberPassword=Remember my password
|
||||
|
Loading…
Reference in New Issue
Block a user