diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java index d1193201..c059932a 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java @@ -2,20 +2,19 @@ package com.voxelmodpack.hdskins.skins; import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; import com.google.gson.annotations.Expose; import com.mojang.authlib.GameProfile; import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; import com.mojang.util.UUIDTypeAdapter; import com.voxelmodpack.hdskins.HDSkinManager; -import com.voxelmodpack.hdskins.upload.ThreadMultipartPostUpload; import net.minecraft.util.Session; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; import java.net.HttpURLConnection; -import java.net.URI; import java.net.URL; import java.util.EnumMap; import java.util.Locale; @@ -33,6 +32,7 @@ public class LegacySkinServer implements SkinServer { @Expose private final String address; + @Expose private final String gateway; @@ -43,7 +43,7 @@ public class LegacySkinServer implements SkinServer { @Override public CompletableFuture getPreviewTextures(GameProfile profile) { - if (Strings.isNullOrEmpty(this.gateway)) { + if (Strings.isNullOrEmpty(gateway)) { return CallableFutures.failedFuture(gatewayUnsupported()); } Map map = new EnumMap<>(MinecraftProfileTexture.Type.class); @@ -58,7 +58,7 @@ public class LegacySkinServer implements SkinServer { ImmutableMap.Builder builder = ImmutableMap.builder(); for (MinecraftProfileTexture.Type type : MinecraftProfileTexture.Type.values()) { - String url = getPath(this.address, type, profile); + String url = getPath(address, type, profile); try { builder.put(type, loadProfileTexture(profile, url)); } catch (IOException e) { @@ -82,23 +82,25 @@ public class LegacySkinServer implements SkinServer { return new MinecraftProfileTexture(url, null); } - @SuppressWarnings("deprecation") @Override - public CompletableFuture uploadSkin(Session session, SkinUpload skin) { - if (Strings.isNullOrEmpty(this.gateway)) { + public CompletableFuture uploadSkin(Session session, SkinUpload upload) { + if (Strings.isNullOrEmpty(gateway)) { return CallableFutures.failedFuture(gatewayUnsupported()); } return CallableFutures.asyncFailableFuture(() -> { - URI image = skin.getImage(); - MinecraftProfileTexture.Type type = skin.getType(); - Map metadata = skin.getMetadata(); - SkinServer.verifyServerConnection(session, SERVER_ID); - String model = metadata.getOrDefault("model", "default"); - Map data = image == null ? getClearData(session, type) : getUploadData(session, type, model, image); - ThreadMultipartPostUpload upload = new ThreadMultipartPostUpload(this.gateway, data); - String response = upload.uploadMultipart(); + + NetClient client = new NetClient("POST", gateway); + + client.putHeaders(createHeaders(session, upload)); + + if (upload.getImage() == null) { + client.putFile(upload.getType().toString().toLowerCase(Locale.US), "image/png", upload.getImage()); + } + + String response = client.send().text(); + if (response.startsWith("ERROR: ")) { response = response.substring(7); } @@ -114,21 +116,19 @@ public class LegacySkinServer implements SkinServer { return new UnsupportedOperationException("Server does not have a gateway."); } - private static Map getData(Session session, MinecraftProfileTexture.Type type, String model, String param, Object val) { - return ImmutableMap.of( - "user", session.getUsername(), - "uuid", UUIDTypeAdapter.fromUUID(session.getProfile().getId()), - "type", type.toString().toLowerCase(Locale.US), - "model", model, - param, val); - } + protected Map createHeaders(Session session, SkinUpload upload) { + Builder builder = ImmutableMap.builder() + .put("user", session.getUsername()) + .put("uuid", UUIDTypeAdapter.fromUUID(session.getProfile().getId())) + .put("type", upload.getType().toString().toLowerCase(Locale.US)); - private static Map getClearData(Session session, MinecraftProfileTexture.Type type) { - return getData(session, type, "default", "clear", "1"); - } + if (upload.getImage() == null) { + builder.put("clear", "1"); + } else { + builder.put("model", upload.getMetadata().getOrDefault("mode", "default")); + } - private static Map getUploadData(Session session, MinecraftProfileTexture.Type type, String model, URI skinFile) { - return getData(session, type, model, type.toString().toLowerCase(Locale.US), skinFile); + return builder.build(); } private static String getPath(String address, MinecraftProfileTexture.Type type, GameProfile profile) { @@ -139,7 +139,7 @@ public class LegacySkinServer implements SkinServer { @Override public boolean verifyGateway() { - return !Strings.isNullOrEmpty(this.gateway); + return !Strings.isNullOrEmpty(gateway); } @Override diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/upload/ThreadMultipartPostUpload.java b/src/hdskins/java/com/voxelmodpack/hdskins/upload/ThreadMultipartPostUpload.java deleted file mode 100644 index d9933a24..00000000 --- a/src/hdskins/java/com/voxelmodpack/hdskins/upload/ThreadMultipartPostUpload.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.voxelmodpack.hdskins.upload; - -import org.apache.commons.io.IOUtils; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Map; -import java.util.Map.Entry; - -import javax.annotation.Nullable; - -/** - * Uploader for Multipart form data - * - * @author Adam Mummery-Smith - * @deprecated Use httpmime multipart upload - */ -@Deprecated -public class ThreadMultipartPostUpload { - protected final Map sourceData; - - protected final String method; - - protected final String authorization; - - protected final String urlString; - - protected HttpURLConnection httpClient; - - protected static final String CRLF = "\r\n"; - - protected static final String twoHyphens = "--"; - - protected static final String boundary = "----------AaB03x"; - - public String response; - - public ThreadMultipartPostUpload(String method, String url, Map sourceData, @Nullable String authorization) { - this.method = method; - this.urlString = url; - this.sourceData = sourceData; - this.authorization = authorization; - } - - public ThreadMultipartPostUpload(String url, Map sourceData) { - this("POST", url, sourceData, null); - } - - public String uploadMultipart() throws IOException { - // open a URL connection - URL url = new URL(this.urlString); - - // Open a HTTP connection to the URL - this.httpClient = (HttpURLConnection) url.openConnection(); - this.httpClient.setDoOutput(true); - this.httpClient.setUseCaches(false); - - this.httpClient.setRequestMethod(this.method); - this.httpClient.setRequestProperty("Connection", "Close"); - this.httpClient.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); // For CloudFlare - - if (this.sourceData.size() > 0) { - this.httpClient.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); - } - - if (this.authorization != null) { - this.httpClient.addRequestProperty("Authorization", this.authorization); - } - - try (DataOutputStream outputStream = new DataOutputStream(this.httpClient.getOutputStream())) { - - for (Entry data : this.sourceData.entrySet()) { - outputStream.writeBytes(twoHyphens + boundary + CRLF); - - String paramName = data.getKey(); - Object paramData = data.getValue(); - - if (paramData instanceof URI) { - Path uploadPath = Paths.get((URI) paramData); - - outputStream.writeBytes("Content-Disposition: form-data; name=\"" + paramName + "\"; filename=\"" + uploadPath.getFileName() + "\"" + CRLF); - outputStream.writeBytes("Content-Type: image/png" + CRLF + CRLF); - - - Files.copy(uploadPath, outputStream); - } else { - outputStream.writeBytes("Content-Disposition: form-data; name=\"" + paramName + "\"" + CRLF + CRLF); - - outputStream.writeBytes(paramData.toString()); - } - - outputStream.writeBytes(ThreadMultipartPostUpload.CRLF); - } - - outputStream.writeBytes(twoHyphens + boundary + twoHyphens + CRLF); - } - - try (InputStream input = this.httpClient.getInputStream()) { - return IOUtils.toString(input, StandardCharsets.UTF_8); - } - } - -} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/upload/package-info.java b/src/hdskins/java/com/voxelmodpack/hdskins/upload/package-info.java deleted file mode 100644 index 188351cf..00000000 --- a/src/hdskins/java/com/voxelmodpack/hdskins/upload/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -package com.voxelmodpack.hdskins.upload; - -import mcp.MethodsReturnNonnullByDefault; - -import javax.annotation.ParametersAreNonnullByDefault;