diff --git a/src/main/java/eu/crushedpixel/replaymod/api/client/ApiClient.java b/src/main/java/eu/crushedpixel/replaymod/api/client/ApiClient.java index bc71a0fb..dcdd5f5e 100644 --- a/src/main/java/eu/crushedpixel/replaymod/api/client/ApiClient.java +++ b/src/main/java/eu/crushedpixel/replaymod/api/client/ApiClient.java @@ -78,33 +78,6 @@ public class ApiClient { return info; } - public void uploadFile(String auth, File file, Category category) throws IOException, ApiException { - QueryBuilder builder = new QueryBuilder(ApiMethods.upload_file); - builder.put("auth", auth); - builder.put("category", category.getId()); - String url = builder.toString(); - - CloseableHttpClient client = new DefaultHttpClient(); - HttpPost post = new HttpPost(url); - - FileEntity entity = new FileEntity(file); - post.setEntity(entity); - HttpResponse response = client.execute(post); - - if(response.getStatusLine().getStatusCode() != 200) { - JsonElement element = jsonParser.parse(EntityUtils.toString(response.getEntity())); - try { - ApiError err = gson.fromJson(element, ApiError.class); - if(err.getDesc() != null) { - client.close(); - throw new ApiException(err); - } - } catch(Exception e) {} - } - - client.close(); - } - public void downloadFile(String auth, int file, File target) throws IOException { QueryBuilder builder = new QueryBuilder(ApiMethods.download_file); builder.put("auth", auth); diff --git a/src/main/java/eu/crushedpixel/replaymod/api/client/FileUploader.java b/src/main/java/eu/crushedpixel/replaymod/api/client/FileUploader.java new file mode 100644 index 00000000..e6151637 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/api/client/FileUploader.java @@ -0,0 +1,104 @@ +package eu.crushedpixel.replaymod.api.client; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.HashMap; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; + +import eu.crushedpixel.replaymod.api.client.holders.Category; + +public class FileUploader { + private static Gson gson = new Gson(); + private static JsonParser jsonParser = new JsonParser(); + + private boolean uploading = false; + private long filesize; + private long current; + + private String attachmentName = "file"; + private String attachmentFileName = "file.mcpr"; + private String crlf = "\r\n"; + private String twoHyphens = "--"; + + private String boundary = "*****"; + //private CountingHttpEntity counter; + + public void uploadFile(String auth, String filename, File file, Category category) throws IOException, ApiException, RuntimeException { + if(uploading) throw new RuntimeException("FileUploader is already uploading"); + uploading = true; + + filesize = file.length(); + current = 0; + + String postData = "?auth="+auth+"&category="+category.getId()+"&name="+filename; + + String url = "http://ReplayMod.com/api/upload_file"+postData; + HttpURLConnection con = (HttpURLConnection)new URL(url).openConnection(); + con.setUseCaches(false); + con.setDoOutput(true); + con.setRequestMethod("POST"); + con.setRequestProperty("Connection", "Keep-Alive"); + con.setRequestProperty("Cache-Control", "no-cache"); + con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + this.boundary); + + HashMap params = new HashMap(); + params.put("auth", auth); + params.put("name", filename); + params.put("category", category.getId()+""); + + DataOutputStream request = new DataOutputStream(con.getOutputStream()); + + request.writeBytes(this.twoHyphens + this.boundary + this.crlf); + request.writeBytes("Content-Disposition: form-data; name=\"" + this.attachmentName + "\";filename=\"" + this.attachmentFileName + "\"" + this.crlf); + request.writeBytes(this.crlf); + + byte[] buf = new byte[1024]; + FileInputStream fis = new FileInputStream(file); + int len; + while((len = fis.read(buf)) != -1) { + request.write(buf); + current += len; + } + fis.close(); + + request.writeBytes(this.crlf); + request.writeBytes(this.twoHyphens + this.boundary + this.twoHyphens + this.crlf); + + request.flush(); + request.close(); + + int responseCode = ((HttpURLConnection)con).getResponseCode(); + InputStream is = null; + if(responseCode == 200) { + is = con.getInputStream(); + } else { + is = con.getErrorStream(); + } + + BufferedReader r = new BufferedReader(new InputStreamReader(is)); + + while(r.ready()) { + System.out.println(r.readLine()); + } + + System.out.println(responseCode); // Should be 200 + + con.disconnect(); + + uploading = false; + } + + public float getUploadProgress() { + if(!uploading) return 0.1f; + return (float)((double)current/(double)filesize); + } +} diff --git a/src/main/java/eu/crushedpixel/replaymod/api/client/holders/Category.java b/src/main/java/eu/crushedpixel/replaymod/api/client/holders/Category.java index 8794aedf..4aa82c01 100644 --- a/src/main/java/eu/crushedpixel/replaymod/api/client/holders/Category.java +++ b/src/main/java/eu/crushedpixel/replaymod/api/client/holders/Category.java @@ -20,4 +20,20 @@ public enum Category { } return null; } + + public String toNiceString() { + return (""+this).charAt(0)+(""+this).substring(1).toLowerCase(); + } + + public Category next() { + for(int i=0; i buttonBar = new ArrayList(); - GuiButton overviewButton = new GuiButton(GuiConstants.CENTER_OVERVIEW_BUTTON, 20, 30, "Overview"); - buttonBar.add(overviewButton); + GuiButton recentButton = new GuiButton(GuiConstants.CENTER_RECENT_BUTTON, 20, 30, "Newest Replays"); + buttonBar.add(recentButton); + + GuiButton bestButton = new GuiButton(GuiConstants.CENTER_BEST_BUTTON, 20, 30, "Best Replays"); + buttonBar.add(bestButton); GuiButton ownReplayButton = new GuiButton(GuiConstants.CENTER_MY_REPLAYS_BUTTON, 20, 30, "My Replays"); buttonBar.add(ownReplayButton); - GuiButton uploadReplayButton = new GuiButton(GuiConstants.CENTER_UPLOAD_BUTTON, 20, 30, "Upload"); - buttonBar.add(uploadReplayButton); + GuiButton searchButton = new GuiButton(GuiConstants.CENTER_SEARCH_BUTTON, 20, 30, "Search"); + buttonBar.add(searchButton); int i = 0; for(GuiButton b : buttonBar) { @@ -64,8 +68,11 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback { //Bottom Button Bar (dat alliteration) List bottomBar = new ArrayList(); - GuiButton exitButton = new GuiButton(GuiConstants.CENTER_BACK_BUTTON, 20, 20, "Back"); + GuiButton exitButton = new GuiButton(GuiConstants.CENTER_BACK_BUTTON, 20, 20, "Main Menu"); bottomBar.add(exitButton); + + GuiButton managerButton = new GuiButton(GuiConstants.CENTER_MANAGER_BUTTON, 20, 20, "Replay Manager"); + bottomBar.add(managerButton); GuiButton logoutButton = new GuiButton(GuiConstants.CENTER_LOGOUT_BUTTON, 20, 20, "Logout"); bottomBar.add(logoutButton); @@ -85,7 +92,7 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback { i++; } - showOverview(); + showOnlineRecent(); } @Override @@ -93,9 +100,18 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback { if(!button.enabled) return; if(button.id == GuiConstants.CENTER_BACK_BUTTON) { mc.displayGuiScreen(new GuiMainMenu()); - return; } else if(button.id == GuiConstants.CENTER_LOGOUT_BUTTON) { mc.displayGuiScreen(getYesNoGui(this, LOGOUT_CALLBACK_ID)); + } else if(button.id == GuiConstants.CENTER_MANAGER_BUTTON) { + mc.displayGuiScreen(new GuiReplayManager()); + } else if(button.id == GuiConstants.CENTER_RECENT_BUTTON) { + showOnlineRecent(); + } else if(button.id == GuiConstants.CENTER_BEST_BUTTON) { + + } else if(button.id == GuiConstants.CENTER_MY_REPLAYS_BUTTON) { + + } else if(button.id == GuiConstants.CENTER_SEARCH_BUTTON) { + } } @@ -136,7 +152,7 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback { Keyboard.enableRepeatEvents(false); } - public void showOverview() { + public void showOnlineRecent() { mc.addScheduledTask(new Runnable() { @Override public void run() { diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiUploadFile.java b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiUploadFile.java new file mode 100644 index 00000000..c41f7b88 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiUploadFile.java @@ -0,0 +1,264 @@ +package eu.crushedpixel.replaymod.gui.online; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.image.BufferedImage; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +import javax.imageio.ImageIO; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiMainMenu; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.util.ResourceLocation; + +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.apache.commons.io.FilenameUtils; +import org.lwjgl.input.Keyboard; + +import com.google.gson.Gson; + +import eu.crushedpixel.replaymod.api.client.ApiException; +import eu.crushedpixel.replaymod.api.client.FileUploader; +import eu.crushedpixel.replaymod.api.client.holders.Category; +import eu.crushedpixel.replaymod.gui.GuiConstants; +import eu.crushedpixel.replaymod.gui.replaymanager.ResourceHelper; +import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler; +import eu.crushedpixel.replaymod.recording.ConnectionEventHandler; +import eu.crushedpixel.replaymod.recording.ReplayMetaData; +import eu.crushedpixel.replaymod.reflection.MCPNames; +import eu.crushedpixel.replaymod.utils.ImageUtils; + +public class GuiUploadFile extends GuiScreen { + + private GuiTextField fileTitleInput; + private GuiButton categoryButton, startUploadButton, cancelUploadButton, backButton; + + private Gson gson = new Gson(); + + private File replayFile; + private ReplayMetaData metaData; + private BufferedImage thumb; + + private FileUploader uploader = new FileUploader(); + + private Category category = Category.MINIGAME; + + private final ResourceLocation textureResource; + private DynamicTexture dynTex = null; + + private Minecraft mc = Minecraft.getMinecraft(); + + public GuiUploadFile(File file) { + this.textureResource = new ResourceLocation("upload_thumbs/"+FilenameUtils.getBaseName(file.getAbsolutePath())); + dynTex = null; + + boolean correctFile = false; + this.replayFile = file; + + if(("."+FilenameUtils.getExtension(file.getAbsolutePath())).equals(ConnectionEventHandler.ZIP_FILE_EXTENSION)) { + ZipFile archive = null; + try { + archive = new ZipFile(file); + ZipArchiveEntry recfile = archive.getEntry("recording"+ConnectionEventHandler.TEMP_FILE_EXTENSION); + ZipArchiveEntry metadata = archive.getEntry("metaData"+ConnectionEventHandler.JSON_FILE_EXTENSION); + + ZipArchiveEntry image = archive.getEntry("thumb"); + BufferedImage img = null; + if(image != null) { + InputStream is = archive.getInputStream(image); + is.skip(7); + BufferedImage bimg = ImageIO.read(is); + if(bimg != null) { + thumb = ImageUtils.scaleImage(bimg, new Dimension(1280, 720)); + } + } + + InputStream is = archive.getInputStream(metadata); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + String json = br.readLine(); + + metaData = gson.fromJson(json, ReplayMetaData.class); + + archive.close(); + correctFile = true; + } catch(Exception e) { + e.printStackTrace(); + } finally { + if(archive != null) { + try { + archive.close(); + } catch (IOException e) {} + } + } + } + + if(!correctFile) { + System.out.println("Invalid file provided to upload"); + mc.displayGuiScreen(new GuiMainMenu()); //TODO: Error message + replayFile = null; + return; + } + + //If thumb is null, set image to placeholder + if(thumb == null) { + try { + thumb = ImageIO.read(MCPNames.class.getClassLoader().getResourceAsStream("default_thumb.jpg")); + } catch(Exception e) { + e.printStackTrace(); + } + } + } + + @Override + public void initGui() { + if(replayFile == null) return; + + fileTitleInput = new GuiTextField(GuiConstants.UPLOAD_NAME_INPUT, fontRendererObj, 200, 21, 120, 20); + String fname = FilenameUtils.getBaseName(replayFile.getAbsolutePath()); + fileTitleInput.setText(fname); + + + categoryButton = new GuiButton(GuiConstants.UPLOAD_CATEGORY_BUTTON, 200, 80, "Category: "+category.toNiceString()); + categoryButton.width = 120; + buttonList.add(categoryButton); + + List bottomBar = new ArrayList(); + startUploadButton = new GuiButton(GuiConstants.UPLOAD_START_BUTTON, 0, 0, "Start Upload"); + bottomBar.add(startUploadButton); + + cancelUploadButton = new GuiButton(GuiConstants.UPLOAD_CANCEL_BUTTON, 0, 0, "Cancel Upload"); + cancelUploadButton.enabled = false; + bottomBar.add(cancelUploadButton); + + backButton = new GuiButton(GuiConstants.UPLOAD_BACK_BUTTON, 0, 0, "Back"); + bottomBar.add(backButton); + + int i = 0; + for(GuiButton b : bottomBar) { + int w = this.width - 30; + int w2 = w/bottomBar.size(); + + int x = 15+(w2*i); + b.xPosition = x; + b.yPosition = height-30; + b.width = w2-4; + + buttonList.add(b); + + i++; + } + + startUploadButton.enabled = (!(fileTitleInput.getText().trim().length() < 5 || fileTitleInput.getText().trim().length() > 30 || + p.matcher(fileTitleInput.getText()).find())); + } + + @Override + protected void actionPerformed(GuiButton button) throws IOException { + if(!button.enabled) return; + if(button.id == GuiConstants.UPLOAD_CATEGORY_BUTTON) { + category = category.next(); + categoryButton.displayString = "Category: "+category.toNiceString(); + } else if(button.id == GuiConstants.UPLOAD_BACK_BUTTON) { + mc.displayGuiScreen(new GuiMainMenu()); + } else if(button.id == GuiConstants.UPLOAD_START_BUTTON) { + mc.addScheduledTask(new Runnable() { + @Override + public void run() { + try { + uploader.uploadFile(AuthenticationHandler.getKey(), fileTitleInput.getText().trim(), replayFile, category); + } catch (ApiException e) { //TODO: Error handling + e.printStackTrace(); + mc.displayGuiScreen(new GuiMainMenu()); + } catch (RuntimeException e) { + e.printStackTrace(); + mc.displayGuiScreen(new GuiMainMenu()); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + } + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + this.drawDefaultBackground(); + + drawString(fontRendererObj, metaData.getServerName(), 200, 50, Color.GRAY.getRGB()); + drawString(fontRendererObj, "Duration: "+String.format("%02dm%02ds", + TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()), + TimeUnit.MILLISECONDS.toSeconds(metaData.getDuration()) - + TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration())) + ), 200, 65, Color.GRAY.getRGB()); + + drawCenteredString(fontRendererObj, "Upload File", this.width/2, 5, Color.WHITE.getRGB()); + + //Draw thumbnail + if(thumb != null) { + if(dynTex == null) { + dynTex = new DynamicTexture(thumb); + mc.getTextureManager().loadTexture(textureResource, dynTex); + dynTex.updateDynamicTexture(); + ResourceHelper.registerResource(textureResource); + } + + mc.getTextureManager().bindTexture(textureResource); //Will be freed by the ResourceHelper + Gui.drawScaledCustomSizeModalRect(20, 20, 0, 0, 1280, 720, 57*3, 32*3, 1280, 720); + } + + fileTitleInput.drawTextBox(); + + super.drawScreen(mouseX, mouseY, partialTicks); + + this.drawRect(20, this.height-100, width-20, this.height-80, Color.BLACK.getRGB()); + this.drawRect(22, this.height-98, width-22, this.height-82, Color.WHITE.getRGB()); + + int width = this.width-22 - 22; + float w = width*uploader.getUploadProgress(); + + this.drawRect(22, this.height-98, Math.round(22+w), this.height-82, Color.RED.getRGB()); + } + + @Override + public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + super.mouseClicked(mouseX, mouseY, mouseButton); + fileTitleInput.mouseClicked(mouseX, mouseY, mouseButton); + } + + @Override + public void updateScreen() { + fileTitleInput.updateCursorCounter(); + } + + @Override + public void onGuiClosed() { + Keyboard.enableRepeatEvents(false); + } + + private static final Pattern p = Pattern.compile("[^a-z0-9 \\-_]", Pattern.CASE_INSENSITIVE); + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + if(fileTitleInput.isFocused()) { + fileTitleInput.textboxKeyTyped(typedChar, keyCode); + } + + startUploadButton.enabled = (!(fileTitleInput.getText().trim().length() < 5 || fileTitleInput.getText().trim().length() > 30 || + p.matcher(fileTitleInput.getText()).find())); + + } +} diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/replaymanager/GuiReplayManager.java b/src/main/java/eu/crushedpixel/replaymod/gui/replaymanager/GuiReplayManager.java index 392887d3..eb915ed9 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/replaymanager/GuiReplayManager.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/replaymanager/GuiReplayManager.java @@ -38,8 +38,11 @@ import com.google.gson.Gson; import com.mojang.realmsclient.util.Pair; import eu.crushedpixel.replaymod.gui.GuiReplaySettings; +import eu.crushedpixel.replaymod.gui.online.GuiUploadFile; +import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler; import eu.crushedpixel.replaymod.recording.ConnectionEventHandler; import eu.crushedpixel.replaymod.recording.ReplayMetaData; +import eu.crushedpixel.replaymod.reflection.MCPNames; import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.utils.ImageUtils; @@ -53,20 +56,21 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback { private boolean initialized; private GuiReplayListExtended replayGuiList; private List, BufferedImage>> replayFileList = new ArrayList, BufferedImage>>(); - private GuiButton loadButton, folderButton, renameButton, deleteButton, cancelButton, settingsButton; + private GuiButton loadButton, uploadButton, folderButton, renameButton, deleteButton, cancelButton, settingsButton; private static Gson gson = new Gson(); private boolean replaying = false; private static final int LOAD_BUTTON_ID = 9001; - private static final int FOLDER_BUTTON_ID = 9002; - private static final int RENAME_BUTTON_ID = 9003; - private static final int DELETE_BUTTON_ID = 9004; - private static final int SETTINGS_BUTTON_ID = 9005; - private static final int CANCEL_BUTTON_ID = 9006; + private static final int UPLOAD_BUTTON_ID = 9002; + private static final int FOLDER_BUTTON_ID = 9003; + private static final int RENAME_BUTTON_ID = 9004; + private static final int DELETE_BUTTON_ID = 9005; + private static final int SETTINGS_BUTTON_ID = 9006; + private static final int CANCEL_BUTTON_ID = 9007; private boolean delete_file = false; - + private void reloadFiles() { replayGuiList.clearEntries(); replayFileList = new ArrayList, BufferedImage>>(); @@ -91,6 +95,11 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback { img = ImageUtils.scaleImage(bimg, new Dimension(1280, 720)); } } + + //If thumb is null, set image to placeholder + if(img == null) { + img = ImageIO.read(MCPNames.class.getClassLoader().getResourceAsStream("default_thumb.jpg")); + } InputStream is = archive.getInputStream(metadata); BufferedReader br = new BufferedReader(new InputStreamReader(is)); @@ -146,7 +155,8 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback { } private void createButtons() { - this.buttonList.add(loadButton = new GuiButton(LOAD_BUTTON_ID, this.width / 2 - 154, this.height - 52, 150, 20, I18n.format("Load Replay", new Object[0]))); + this.buttonList.add(loadButton = new GuiButton(LOAD_BUTTON_ID, this.width / 2 - 154, this.height - 52, 73, 20, I18n.format("Load", new Object[0]))); + this.buttonList.add(uploadButton = new GuiButton(UPLOAD_BUTTON_ID, this.width / 2 - 154 + 78, this.height - 52, 73, 20, I18n.format("Upload", new Object[0]))); this.buttonList.add(folderButton = new GuiButton(FOLDER_BUTTON_ID, this.width / 2 + 4, this.height - 52, 150, 20, I18n.format("Open Replay Folder...", new Object[0]))); this.buttonList.add(renameButton = new GuiButton(RENAME_BUTTON_ID, this.width / 2 - 154, this.height - 28, 72, 20, I18n.format("Rename", new Object[0]))); this.buttonList.add(deleteButton = new GuiButton(DELETE_BUTTON_ID, this.width / 2 - 76, this.height - 28, 72, 20, I18n.format("Delete", new Object[0]))); @@ -185,20 +195,17 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback { @Override protected void actionPerformed(GuiButton button) throws IOException { - if (button.enabled) { + if(button.enabled) { if(button.id == LOAD_BUTTON_ID) { loadReplay(replayGuiList.selected); } - else if (button.id == CANCEL_BUTTON_ID) - { + else if(button.id == CANCEL_BUTTON_ID) { mc.displayGuiScreen(parentScreen); } - else if (button.id == DELETE_BUTTON_ID) - { + else if(button.id == DELETE_BUTTON_ID) { String s = replayGuiList.getListEntry(replayGuiList.selected).getFileName(); - if (s != null) - { + if (s != null) { delete_file = true; GuiYesNo guiyesno = getYesNoGui(this, s, 1); this.mc.displayGuiScreen(guiyesno); @@ -207,53 +214,48 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback { else if(button.id == SETTINGS_BUTTON_ID) { this.mc.displayGuiScreen(new GuiReplaySettings(this)); } - else if(button.id == RENAME_BUTTON_ID) - { + else if(button.id == RENAME_BUTTON_ID) { File file = replayFileList.get(replayGuiList.selected).first().first(); this.mc.displayGuiScreen(new GuiRenameReplay(this, file)); } - else if(button.id == FOLDER_BUTTON_ID) - { + else if(button.id == UPLOAD_BUTTON_ID) { + File file = replayFileList.get(replayGuiList.selected).first().first(); + this.mc.displayGuiScreen(new GuiUploadFile(file)); + } + else if(button.id == FOLDER_BUTTON_ID) { File file1 = new File("./replay_recordings/"); file1.mkdirs(); String s = file1.getAbsolutePath(); - if (Util.getOSType() == Util.EnumOS.OSX) - { - try - { + if(Util.getOSType() == Util.EnumOS.OSX) { + try { Runtime.getRuntime().exec(new String[] {"/usr/bin/open", s}); return; } - catch (IOException ioexception1) {} + catch(IOException ioexception1) {} } - else if (Util.getOSType() == Util.EnumOS.WINDOWS) - { + else if(Util.getOSType() == Util.EnumOS.WINDOWS) { String s1 = String.format("cmd.exe /C start \"Open file\" \"%s\"", new Object[] {s}); - try - { + try{ Runtime.getRuntime().exec(s1); return; } - catch (IOException ioexception) {} + catch(IOException ioexception) {} } boolean flag = false; - try - { + try { Class oclass = Class.forName("java.awt.Desktop"); Object object = oclass.getMethod("getDesktop", new Class[0]).invoke((Object)null, new Object[0]); oclass.getMethod("browse", new Class[] {URI.class}).invoke(object, new Object[] {file1.toURI()}); } - catch (Throwable throwable) - { + catch(Throwable throwable) { flag = true; } - if (flag) - { + if(flag) { Sys.openURL("file://" + s); } } @@ -286,6 +288,12 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback { public void setButtonsEnabled(boolean b) { loadButton.enabled = b; + if(!b || !AuthenticationHandler.isAuthenticated()) { + uploadButton.enabled = false; + } else { + uploadButton.enabled = true; + } + renameButton.enabled = b; deleteButton.enabled = b; } diff --git a/src/main/java/eu/crushedpixel/replaymod/online/CountingHttpEntity.java b/src/main/java/eu/crushedpixel/replaymod/online/CountingHttpEntity.java new file mode 100644 index 00000000..fbf521bb --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/online/CountingHttpEntity.java @@ -0,0 +1,77 @@ +package eu.crushedpixel.replaymod.online; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.http.entity.ContentType; +import org.apache.http.entity.FileEntity; + +public class CountingHttpEntity extends FileEntity { + + private OutputStreamProgress outstream; + + public class OutputStreamProgress extends OutputStream { + + private final OutputStream outstream; + private volatile long bytesWritten=0; + + public OutputStreamProgress(OutputStream outstream) { + this.outstream = outstream; + } + + @Override + public void write(int b) throws IOException { + outstream.write(b); + bytesWritten++; + } + + @Override + public void write(byte[] b) throws IOException { + outstream.write(b); + bytesWritten += b.length; + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + outstream.write(b, off, len); + bytesWritten += len; + } + + @Override + public void flush() throws IOException { + outstream.flush(); + } + + @Override + public void close() throws IOException { + outstream.close(); + } + + public long getWrittenLength() { + return bytesWritten; + } + } + + public CountingHttpEntity(File file, ContentType type) { + super(file, type); + } + + @Override + public void writeTo(OutputStream outstream) throws IOException { + this.outstream = new OutputStreamProgress(outstream); + super.writeTo(this.outstream); + } + + public float getProgress() { + if (outstream == null) { + return 0; + } + long contentLength = getContentLength(); + if (contentLength <= 0) { + return 0; + } + long writtenLength = outstream.getWrittenLength(); + return (writtenLength/contentLength); + } +} \ No newline at end of file diff --git a/src/main/java/eu/crushedpixel/replaymod/reflection/MCPNames.java b/src/main/java/eu/crushedpixel/replaymod/reflection/MCPNames.java index e8f2e18e..b0f33c90 100644 --- a/src/main/java/eu/crushedpixel/replaymod/reflection/MCPNames.java +++ b/src/main/java/eu/crushedpixel/replaymod/reflection/MCPNames.java @@ -37,8 +37,6 @@ public final class MCPNames { static { if (use()) { String mappingsDir = "./../build/unpacked/mappings/"; - ResourceLocation fieldsLocation = new ResourceLocation("assets/replaymod/fields.csv"); - ResourceLocation methodsLocation = new ResourceLocation("assets/replaymod/methods.csv"); InputStream fieldsIs = MCPNames.class.getClassLoader().getResourceAsStream("fields.csv"); InputStream methodsIs = MCPNames.class.getClassLoader().getResourceAsStream("methods.csv"); diff --git a/src/main/resources/default_thumb.jpg b/src/main/resources/default_thumb.jpg new file mode 100644 index 00000000..fbe12762 Binary files /dev/null and b/src/main/resources/default_thumb.jpg differ