Added a button to download your skin

This commit is contained in:
Sollace 2018-08-20 14:19:42 +02:00
parent 8ef6c30a6d
commit bb39a312c6
5 changed files with 96 additions and 4 deletions

View file

@ -12,16 +12,23 @@ public class PreviewTexture extends ThreadDownloadImageData {
private String model; private String model;
private String fileUrl;
public PreviewTexture(@Nullable String model, String url, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) { public PreviewTexture(@Nullable String model, String url, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) {
super(null, url, fallbackTexture, imageBuffer); super(null, url, fallbackTexture, imageBuffer);
this.model = model == null ? "default" : model; this.model = model == null ? "default" : model;
this.fileUrl = url;
} }
public boolean isTextureUploaded() { public boolean isTextureUploaded() {
return uploaded && this.getGlTextureId() > -1; return uploaded && this.getGlTextureId() > -1;
} }
public String getUrl() {
return fileUrl;
}
@Override @Override
public void deleteGlTexture() { public void deleteGlTexture() {
super.deleteGlTexture(); super.deleteGlTexture();

View file

@ -14,9 +14,12 @@ import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger; import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.HDSkinManager;
import com.voxelmodpack.hdskins.PreviewTextureManager; import com.voxelmodpack.hdskins.PreviewTextureManager;
import com.voxelmodpack.hdskins.skins.NetClient;
import com.voxelmodpack.hdskins.skins.SkinServer; import com.voxelmodpack.hdskins.skins.SkinServer;
import com.voxelmodpack.hdskins.skins.SkinUpload; import com.voxelmodpack.hdskins.skins.SkinUpload;
import com.voxelmodpack.hdskins.skins.SkinUploadResponse; import com.voxelmodpack.hdskins.skins.SkinUploadResponse;
import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFile;
import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFileFolder;
import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG; import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.audio.PositionedSoundRecord;
@ -32,6 +35,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
@ -65,6 +70,7 @@ public class GuiSkins extends GameGui {
private SkinServer gateway; private SkinServer gateway;
private Button btnUpload; private Button btnUpload;
private Button btnDownload;
private Button btnClear; private Button btnClear;
private Button btnModeSteve; private Button btnModeSteve;
@ -93,7 +99,7 @@ public class GuiSkins extends GameGui {
private int refreshCounter = 0; private int refreshCounter = 0;
private ThreadOpenFilePNG openFileThread; private ThreadOpenFile openFileThread;
private final Object skinLock = new Object(); private final Object skinLock = new Object();
@ -180,6 +186,7 @@ public class GuiSkins extends GameGui {
selectedSkin = pendingSkinFile; selectedSkin = pendingSkinFile;
pendingSkinFile = null; pendingSkinFile = null;
btnUpload.enabled = true; btnUpload.enabled = true;
btnDownload.enabled = true;
onSetLocalSkin(textureType); onSetLocalSkin(textureType);
} }
} }
@ -244,10 +251,14 @@ public class GuiSkins extends GameGui {
sender.enabled = false; sender.enabled = false;
})).setEnabled(!mc.isFullScreen()); })).setEnabled(!mc.isFullScreen());
addButton(btnUpload = new Button(width / 2 - 24, height / 2 - 10, 48, 20, "hdskins.options.chevy", sender -> { addButton(btnUpload = new Button(width / 2 - 24, height / 2 - 20, 48, 20, "hdskins.options.chevy", sender -> {
punchServer("hdskins.upload", selectedSkin.toURI()); punchServer("hdskins.upload", selectedSkin.toURI());
})).setEnabled(canUpload()).setTooltip("hdskins.options.chevy.title"); })).setEnabled(canUpload()).setTooltip("hdskins.options.chevy.title");
addButton(btnDownload = new Button(width / 2 - 24, height / 2 + 20, 48, 20, "hdskins.options.download", sender -> {
launchSkinDownload(sender);
})).setEnabled(canDownload()).setTooltip("hdskins.options.download.title");
addButton(btnClear = new Button(width / 2 + 60, height - 27, 90, 20, "hdskins.options.clear", sender -> { addButton(btnClear = new Button(width / 2 + 60, height - 27, 90, 20, "hdskins.options.clear", sender -> {
if (remotePlayer.isTextureSetupComplete()) { if (remotePlayer.isTextureSetupComplete()) {
punchServer("hdskins.request", null); punchServer("hdskins.request", null);
@ -570,12 +581,37 @@ public class GuiSkins extends GameGui {
uploadingSkin = true; uploadingSkin = true;
uploadMessage = format(uploadMsg); uploadMessage = format(uploadMsg);
btnUpload.enabled = canUpload(); btnUpload.enabled = canUpload();
btnDownload.enabled = canDownload();
gateway.uploadSkin(mc.getSession(), new SkinUpload(textureType, path, getMetadata())) gateway.uploadSkin(mc.getSession(), new SkinUpload(textureType, path, getMetadata()))
.thenAccept(this::onUploadComplete) .thenAccept(this::onUploadComplete)
.exceptionally(this::onUploadFailure); .exceptionally(this::onUploadFailure);
} }
private void launchSkinDownload(Button sender) {
sender.enabled = false;
String loc = remotePlayer.getLocal(textureType).getRemote().getUrl();
new NetClient("GET", loc).async(HDSkinManager.skinDownloadExecutor).thenAccept(response -> {
openFileThread = new ThreadOpenFileFolder(mc, format("hdskins.open.title"), (fileDialog, dialogResult) -> {
openFileThread = null;
sender.enabled = true;
if (dialogResult == 0) {
File out = fileDialog.getSelectedFile();
try {
out.createNewFile();
FileUtils.copyInputStreamToFile(response.getInputStream(), out);
} catch (IOException e) {
e.printStackTrace();
}
}
});
openFileThread.start();
});
}
private Map<String, String> getMetadata() { private Map<String, String> getMetadata() {
return ImmutableMap.of("model", thinArmType ? "slim" : "default"); return ImmutableMap.of("model", thinArmType ? "slim" : "default");
} }
@ -587,6 +623,7 @@ public class GuiSkins extends GameGui {
showMessage = true; showMessage = true;
uploadingSkin = false; uploadingSkin = false;
btnUpload.enabled = canUpload(); btnUpload.enabled = canUpload();
btnDownload.enabled = canDownload();
return null; return null;
} }
@ -596,12 +633,17 @@ public class GuiSkins extends GameGui {
pendingRemoteSkinRefresh = true; pendingRemoteSkinRefresh = true;
uploadingSkin = false; uploadingSkin = false;
btnUpload.enabled = canUpload(); btnUpload.enabled = canUpload();
btnDownload.enabled = canDownload();
} }
protected boolean canUpload() { protected boolean canUpload() {
return selectedSkin != null && !uploadingSkin && !pendingRemoteSkinRefresh; return selectedSkin != null && !uploadingSkin && !pendingRemoteSkinRefresh;
} }
protected boolean canDownload() {
return remotePlayer.getLocal(textureType).hasRemote();
}
CompletableFuture<PreviewTextureManager> loadTextures(GameProfile profile) { CompletableFuture<PreviewTextureManager> loadTextures(GameProfile profile) {
return gateway.getPreviewTextures(profile).thenApply(PreviewTextureManager::new); return gateway.getPreviewTextures(profile).thenApply(PreviewTextureManager::new);
} }

View file

@ -11,6 +11,8 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
/** /**
* Ew. Why so many builders? >.< * Ew. Why so many builders? >.<
@ -43,10 +45,16 @@ public class NetClient {
public MoreHttpResponses send() throws IOException { public MoreHttpResponses send() throws IOException {
HttpUriRequest request = rqBuilder.build(); HttpUriRequest request = rqBuilder.build();
if (headers != null) {
for (Map.Entry<String, ?> parameter : headers.entrySet()) { for (Map.Entry<String, ?> parameter : headers.entrySet()) {
request.addHeader(parameter.getKey(), parameter.getValue().toString()); request.addHeader(parameter.getKey(), parameter.getValue().toString());
} }
}
return MoreHttpResponses.execute(HDSkinManager.httpClient, request); return MoreHttpResponses.execute(HDSkinManager.httpClient, request);
} }
public CompletableFuture<MoreHttpResponses> async(Executor exec) {
return CallableFutures.asyncFailableFuture(this::send, exec);
}
} }

View file

@ -0,0 +1,32 @@
package com.voxelmodpack.hdskins.upload.awt;
import net.minecraft.client.Minecraft;
import javax.swing.filechooser.FileFilter;
import java.io.File;
/**
* Opens an awt "Open File" dialog that only accepts directories.
*/
public class ThreadOpenFileFolder extends ThreadOpenFile {
public ThreadOpenFileFolder(Minecraft minecraft, String dialogTitle, IOpenFileCallback callback)
throws IllegalStateException {
super(minecraft, dialogTitle, callback);
}
@Override
protected FileFilter getFileFilter() {
return new FileFilter() {
@Override
public String getDescription() {
return "Directories";
}
@Override
public boolean accept(File f) {
return f.isDirectory();
}
};
}
}

View file

@ -24,6 +24,9 @@ hdskins.mode.skin=%s
hdskins.options.chevy=>> hdskins.options.chevy=>>
hdskins.options.chevy.title=Upload Skin hdskins.options.chevy.title=Upload Skin
hdskins.options.download=<<
hdskins.options.download.title=Save Skin
hdskins.options.close=Close hdskins.options.close=Close
hdskins.options.clear=Clear hdskins.options.clear=Clear
hdskins.options.browse=Browse hdskins.options.browse=Browse