/simplify!

This commit is contained in:
Sollace 2018-09-06 15:09:56 +02:00
parent 10eda59bed
commit fb013ea190
7 changed files with 91 additions and 80 deletions

View file

@ -179,7 +179,7 @@ public class SkinUploader implements Closeable {
sendingSkin = true; sendingSkin = true;
status = statusMsg; status = statusMsg;
return gateway.uploadSkin(mc.getSession(), new SkinUpload(skinType, localSkin == null ? null : localSkin.toURI(), skinMetadata)).handle((response, throwable) -> { return gateway.uploadSkin(new SkinUpload(mc.getSession(), skinType, localSkin == null ? null : localSkin.toURI(), skinMetadata)).handle((response, throwable) -> {
if (throwable == null) { if (throwable == null) {
LiteLoaderLogger.info("Upload completed with: %s", response); LiteLoaderLogger.info("Upload completed with: %s", response);
setError(null); setError(null);

View file

@ -10,7 +10,6 @@ import com.mojang.util.UUIDTypeAdapter;
import com.voxelmodpack.hdskins.util.IndentedToStringStyle; import com.voxelmodpack.hdskins.util.IndentedToStringStyle;
import com.voxelmodpack.hdskins.util.MoreHttpResponses; import com.voxelmodpack.hdskins.util.MoreHttpResponses;
import com.voxelmodpack.hdskins.util.NetClient; import com.voxelmodpack.hdskins.util.NetClient;
import net.minecraft.util.Session;
import java.io.IOException; import java.io.IOException;
import java.util.Locale; import java.util.Locale;
@ -40,12 +39,12 @@ public class BethlehemSkinServer implements SkinServer {
} }
@Override @Override
public SkinUploadResponse performSkinUpload(Session session, SkinUpload upload) throws IOException, AuthenticationException { public SkinUploadResponse performSkinUpload(SkinUpload upload) throws IOException, AuthenticationException {
SkinServer.verifyServerConnection(session, SERVER_ID); SkinServer.verifyServerConnection(upload.getSession(), SERVER_ID);
NetClient client = new NetClient("POST", address); NetClient client = new NetClient("POST", address);
client.putHeaders(createHeaders(session, upload)); client.putHeaders(createHeaders(upload));
if (upload.getImage() != null) { if (upload.getImage() != null) {
client.putFile(upload.getType().toString().toLowerCase(Locale.US), "image/png", upload.getImage()); client.putFile(upload.getType().toString().toLowerCase(Locale.US), "image/png", upload.getImage());
@ -59,11 +58,11 @@ public class BethlehemSkinServer implements SkinServer {
} }
} }
protected Map<String, ?> createHeaders(Session session, SkinUpload upload) { protected Map<String, ?> createHeaders(SkinUpload upload) {
Builder<String, Object> builder = ImmutableMap.<String, Object>builder() Builder<String, Object> builder = ImmutableMap.<String, Object>builder()
.put("accessToken", session.getToken()) .put("accessToken", upload.getSession().getToken())
.put("user", session.getUsername()) .put("user", upload.getSession().getUsername())
.put("uuid", UUIDTypeAdapter.fromUUID(session.getProfile().getId())) .put("uuid", UUIDTypeAdapter.fromUUID(upload.getSession().getProfile().getId()))
.put("type", upload.getType().toString().toLowerCase(Locale.US)); .put("type", upload.getType().toString().toLowerCase(Locale.US));
if (upload.getImage() == null) { if (upload.getImage() == null) {

View file

@ -16,7 +16,6 @@ import com.voxelmodpack.hdskins.util.MoreHttpResponses;
import com.voxelmodpack.hdskins.util.NetClient; import com.voxelmodpack.hdskins.util.NetClient;
import com.voxelmodpack.hdskins.util.TexturesPayloadBuilder; import com.voxelmodpack.hdskins.util.TexturesPayloadBuilder;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.util.Session;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HttpHeaders; import org.apache.http.HttpHeaders;
@ -109,16 +108,16 @@ public class LegacySkinServer implements SkinServer {
} }
@Override @Override
public SkinUploadResponse performSkinUpload(Session session, SkinUpload upload) throws IOException, AuthenticationException { public SkinUploadResponse performSkinUpload(SkinUpload upload) throws IOException, AuthenticationException {
if (Strings.isNullOrEmpty(gateway)) { if (Strings.isNullOrEmpty(gateway)) {
throw gatewayUnsupported(); throw gatewayUnsupported();
} }
SkinServer.verifyServerConnection(session, SERVER_ID); SkinServer.verifyServerConnection(upload.getSession(), SERVER_ID);
NetClient client = new NetClient("POST", gateway); NetClient client = new NetClient("POST", gateway);
client.putFormData(createHeaders(session, upload), "image/png"); client.putFormData(createHeaders(upload), "image/png");
if (upload.getImage() != null) { if (upload.getImage() != null) {
client.putFile(upload.getType().toString().toLowerCase(Locale.US), "image/png", upload.getImage()); client.putFile(upload.getType().toString().toLowerCase(Locale.US), "image/png", upload.getImage());
@ -141,10 +140,10 @@ public class LegacySkinServer implements SkinServer {
return new UnsupportedOperationException("Server does not have a gateway."); return new UnsupportedOperationException("Server does not have a gateway.");
} }
private Map<String, ?> createHeaders(Session session, SkinUpload upload) { private Map<String, ?> createHeaders(SkinUpload upload) {
Builder<String, Object> builder = ImmutableMap.<String, Object>builder() Builder<String, Object> builder = ImmutableMap.<String, Object>builder()
.put("user", session.getUsername()) .put("user", upload.getSession().getUsername())
.put("uuid", UUIDTypeAdapter.fromUUID(session.getProfile().getId())) .put("uuid", UUIDTypeAdapter.fromUUID(upload.getSession().getProfile().getId()))
.put("type", upload.getType().toString().toLowerCase(Locale.US)); .put("type", upload.getType().toString().toLowerCase(Locale.US));
if (upload.getImage() == null) { if (upload.getImage() == null) {

View file

@ -32,10 +32,10 @@ public interface SkinServer extends Exposable {
MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException; MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException;
SkinUploadResponse performSkinUpload(Session session, SkinUpload upload) throws IOException, AuthenticationException; SkinUploadResponse performSkinUpload(SkinUpload upload) throws IOException, AuthenticationException;
default CompletableFuture<SkinUploadResponse> uploadSkin(Session session, SkinUpload upload) { default CompletableFuture<SkinUploadResponse> uploadSkin(SkinUpload upload) {
return CallableFutures.asyncFailableFuture(() -> performSkinUpload(session, upload), HDSkinManager.skinUploadExecutor); return CallableFutures.asyncFailableFuture(() -> performSkinUpload(upload), HDSkinManager.skinUploadExecutor);
} }
default CompletableFuture<MinecraftTexturesPayload> getPreviewTextures(GameProfile profile) { default CompletableFuture<MinecraftTexturesPayload> getPreviewTextures(GameProfile profile) {

View file

@ -1,24 +1,35 @@
package com.voxelmodpack.hdskins.server; package com.voxelmodpack.hdskins.server;
import net.minecraft.util.Session;
import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
public class SkinUpload { public class SkinUpload {
private URI image; private final Session session;
private Map<String, String> metadata; private final URI image;
private MinecraftProfileTexture.Type type; private final Map<String, String> metadata;
private final Type type;
public SkinUpload(MinecraftProfileTexture.Type type, @Nullable URI image, Map<String, String> metadata) { public SkinUpload(Session session, Type type, @Nullable URI image, Map<String, String> metadata) {
this.session = session;
this.image = image; this.image = image;
this.metadata = metadata; this.metadata = metadata;
this.type = type; this.type = type;
} }
public Session getSession() {
return session;
}
@Nullable @Nullable
public URI getImage() { public URI getImage() {
return image; return image;

View file

@ -1,7 +1,6 @@
package com.voxelmodpack.hdskins.server; package com.voxelmodpack.hdskins.server;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.gson.JsonObject;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException; import com.mojang.authlib.exceptions.AuthenticationException;
@ -14,23 +13,18 @@ import com.voxelmodpack.hdskins.util.MoreHttpResponses;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.util.Session; import net.minecraft.util.Session;
import org.apache.http.HttpHeaders; import org.apache.http.HttpHeaders;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder; import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.message.BasicNameValuePair;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nullable;
@ServerType("valhalla") @ServerType("valhalla")
public class ValhallaSkinServer implements SkinServer { public class ValhallaSkinServer implements SkinServer {
@ -45,88 +39,80 @@ public class ValhallaSkinServer implements SkinServer {
@Override @Override
public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException { public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException {
try (MoreHttpResponses response = MoreHttpResponses.execute(HDSkinManager.httpClient, new HttpGet(getTexturesURI(profile)))) { try (MoreHttpResponses response = MoreHttpResponses.execute(HDSkinManager.httpClient, new HttpGet(getTexturesURI(profile)))) {
if (response.ok()) { if (response.ok()) {
return readJson(response, MinecraftTexturesPayload.class); return response.unwrapAsJson(MinecraftTexturesPayload.class);
} }
throw new IOException("Server sent non-ok response code: " + response.getResponseCode()); throw new IOException("Server sent non-ok response code: " + response.getResponseCode());
} }
} }
@Override @Override
public SkinUploadResponse performSkinUpload(Session session, SkinUpload upload) throws IOException, AuthenticationException { public SkinUploadResponse performSkinUpload(SkinUpload upload) throws IOException, AuthenticationException {
URI image = upload.getImage();
Map<String, String> metadata = upload.getMetadata();
MinecraftProfileTexture.Type type = upload.getType();
authorize(session);
try { try {
return upload(session, image, type, metadata); return uploadPlayerSkin(upload);
} catch (IOException e) { } catch (IOException e) {
if (e.getMessage().equals("Authorization failed")) { if (e.getMessage().equals("Authorization failed")) {
accessToken = null; accessToken = null;
authorize(session); return uploadPlayerSkin(upload);
return upload(session, image, type, metadata);
} }
throw e; throw e;
} }
} }
private SkinUploadResponse upload(Session session, @Nullable URI image, MinecraftProfileTexture.Type type, Map<String, String> metadata) throws IOException { private SkinUploadResponse uploadPlayerSkin(SkinUpload upload) throws IOException, AuthenticationException {
GameProfile profile = session.getProfile(); authorize(upload.getSession());
if (image == null) { switch (upload.getSchemaAction()) {
return resetSkin(profile, type); case "none":
} return resetSkin(upload);
switch (image.getScheme()) {
case "file": case "file":
return uploadFile(new File(image), profile, type, metadata); return uploadFile(upload);
case "http": case "http":
case "https": case "https":
return uploadUrl(image, profile, type, metadata); return uploadUrl(upload);
default: default:
throw new IOException("Unsupported URI scheme: " + image.getScheme()); throw new IOException("Unsupported URI scheme: " + upload.getSchemaAction());
} }
} }
private SkinUploadResponse resetSkin(GameProfile profile, MinecraftProfileTexture.Type type) throws IOException { private SkinUploadResponse resetSkin(SkinUpload upload) throws IOException {
return upload(RequestBuilder.delete() return upload(RequestBuilder.delete()
.setUri(buildUserTextureUri(profile, type)) .setUri(buildUserTextureUri(upload.getSession().getProfile(), upload.getType()))
.addHeader(HttpHeaders.AUTHORIZATION, this.accessToken) .addHeader(HttpHeaders.AUTHORIZATION, this.accessToken)
.build()); .build());
} }
private SkinUploadResponse uploadFile(File file, GameProfile profile, MinecraftProfileTexture.Type type, Map<String, String> metadata) throws IOException { private SkinUploadResponse uploadFile(SkinUpload upload) throws IOException {
MultipartEntityBuilder b = MultipartEntityBuilder.create(); final File file = new File(upload.getImage());
b.addBinaryBody("file", file, ContentType.create("image/png"), file.getName());
metadata.forEach(b::addTextBody); MultipartEntityBuilder b = MultipartEntityBuilder.create()
.addBinaryBody("file", file, ContentType.create("image/png"), file.getName());
upload.getMetadata().forEach(b::addTextBody);
return upload(RequestBuilder.put() return upload(RequestBuilder.put()
.setUri(buildUserTextureUri(profile, type)) .setUri(buildUserTextureUri(upload.getSession().getProfile(), upload.getType()))
.addHeader(HttpHeaders.AUTHORIZATION, this.accessToken) .addHeader(HttpHeaders.AUTHORIZATION, this.accessToken)
.setEntity(b.build()) .setEntity(b.build())
.build()); .build());
} }
private SkinUploadResponse uploadUrl(URI uri, GameProfile profile, MinecraftProfileTexture.Type type, Map<String, String> metadata) throws IOException { private SkinUploadResponse uploadUrl(SkinUpload upload) throws IOException {
return upload(RequestBuilder.post() return upload(RequestBuilder.post()
.setUri(buildUserTextureUri(profile, type)) .setUri(buildUserTextureUri(upload.getSession().getProfile(), upload.getType()))
.addHeader(HttpHeaders.AUTHORIZATION, this.accessToken) .addHeader(HttpHeaders.AUTHORIZATION, this.accessToken)
.addParameter("file", uri.toString()) .addParameter("file", upload.getImage().toString())
.addParameters(metadata.entrySet().stream() .addParameters(MoreHttpResponses.mapAsParameters(upload.getMetadata()))
.map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue()))
.toArray(NameValuePair[]::new))
.build()); .build());
} }
private SkinUploadResponse upload(HttpUriRequest request) throws IOException { private SkinUploadResponse upload(HttpUriRequest request) throws IOException {
try (MoreHttpResponses response = MoreHttpResponses.execute(HDSkinManager.httpClient, request)) { try (MoreHttpResponses response = MoreHttpResponses.execute(HDSkinManager.httpClient, request)) {
return readJson(response, SkinUploadResponse.class); return response.unwrapAsJson(SkinUploadResponse.class);
} }
} }
@ -152,24 +138,12 @@ public class ValhallaSkinServer implements SkinServer {
this.accessToken = response.accessToken; this.accessToken = response.accessToken;
} }
private <T> T readJson(MoreHttpResponses resp, Class<T> cl) throws IOException {
String type = resp.getResponse().getEntity().getContentType().getValue();
if (!"application/json".equals(type)) {
throw new IOException("Server returned a non-json response!");
}
if (resp.ok()) {
return resp.json(cl);
}
throw new IOException(resp.json(JsonObject.class).get("message").getAsString());
}
private AuthHandshake authHandshake(String name) throws IOException { private AuthHandshake authHandshake(String name) throws IOException {
try (MoreHttpResponses resp = MoreHttpResponses.execute(HDSkinManager.httpClient, RequestBuilder.post() try (MoreHttpResponses resp = MoreHttpResponses.execute(HDSkinManager.httpClient, RequestBuilder.post()
.setUri(getHandshakeURI()) .setUri(getHandshakeURI())
.addParameter("name", name) .addParameter("name", name)
.build())) { .build())) {
return readJson(resp, AuthHandshake.class); return resp.unwrapAsJson(AuthHandshake.class);
} }
} }
@ -179,7 +153,7 @@ public class ValhallaSkinServer implements SkinServer {
.addParameter("name", name) .addParameter("name", name)
.addParameter("verifyToken", String.valueOf(verifyToken)) .addParameter("verifyToken", String.valueOf(verifyToken))
.build())) { .build())) {
return readJson(resp, AuthResponse.class); return resp.unwrapAsJson(AuthResponse.class);
} }
} }

View file

@ -1,12 +1,15 @@
package com.voxelmodpack.hdskins.util; package com.voxelmodpack.hdskins.util;
import com.google.common.io.CharStreams; import com.google.common.io.CharStreams;
import com.google.gson.JsonObject;
import com.voxelmodpack.hdskins.server.SkinServer; import com.voxelmodpack.hdskins.server.SkinServer;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
@ -14,6 +17,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -32,6 +36,10 @@ public interface MoreHttpResponses extends AutoCloseable {
return getResponse().getStatusLine().getStatusCode(); return getResponse().getStatusLine().getStatusCode();
} }
default String getContentType() {
return getResponse().getEntity().getContentType().getValue();
}
default InputStream getInputStream() throws IOException { default InputStream getInputStream() throws IOException {
return getResponse().getEntity().getContent(); return getResponse().getEntity().getContent();
} }
@ -64,6 +72,18 @@ public interface MoreHttpResponses extends AutoCloseable {
} }
} }
default <T> T unwrapAsJson(Type type) throws IOException {
if (!"application/json".equals(getContentType())) {
throw new IOException("Server returned a non-json response!");
}
if (ok()) {
return json(type);
}
throw new IOException(json(JsonObject.class).get("message").getAsString());
}
@Override @Override
default void close() throws IOException { default void close() throws IOException {
this.getResponse().close(); this.getResponse().close();
@ -73,4 +93,12 @@ public interface MoreHttpResponses extends AutoCloseable {
CloseableHttpResponse response = client.execute(request); CloseableHttpResponse response = client.execute(request);
return () -> response; return () -> response;
} }
static NameValuePair[] mapAsParameters(Map<String, String> parameters) {
return parameters.entrySet().stream()
.map(entry ->
new BasicNameValuePair(entry.getKey(), entry.getValue())
)
.toArray(NameValuePair[]::new);
}
} }