diff --git a/libs/replaystudio-0.0.1-SNAPSHOT-all.jar b/libs/replaystudio-0.0.1-SNAPSHOT-all.jar index 9d462c12..593dae90 100644 Binary files a/libs/replaystudio-0.0.1-SNAPSHOT-all.jar and b/libs/replaystudio-0.0.1-SNAPSHOT-all.jar differ diff --git a/src/main/java/com/replaymod/online/ReplayModOnline.java b/src/main/java/com/replaymod/online/ReplayModOnline.java index 6c61efaf..2c21c60c 100644 --- a/src/main/java/com/replaymod/online/ReplayModOnline.java +++ b/src/main/java/com/replaymod/online/ReplayModOnline.java @@ -4,14 +4,21 @@ import com.replaymod.core.ReplayMod; import com.replaymod.online.api.ApiClient; import com.replaymod.online.gui.GuiLoginPrompt; import com.replaymod.online.gui.GuiReplayDownloading; +import com.replaymod.online.gui.GuiSaveModifiedReplay; import com.replaymod.online.handler.GuiHandler; import com.replaymod.replay.ReplayModReplay; +import com.replaymod.replay.events.ReplayCloseEvent; import de.johni0702.minecraft.gui.container.GuiScreen; +import de.johni0702.replaystudio.replay.ReplayFile; +import de.johni0702.replaystudio.replay.ZipReplayFile; +import de.johni0702.replaystudio.studio.ReplayStudio; import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.apache.logging.log4j.Logger; import java.io.File; @@ -36,6 +43,13 @@ public class ReplayModOnline { private ApiClient apiClient; + /** + * In case the currently opened replay gets modified, the resulting replay file is saved to this location. + * Usually a file within the normal replays folder with a unique name. + * When the replay is closed, the user is asked whether they want to give it a proper name. + */ + private File currentReplayOutputFile; + @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { logger = event.getModLog(); @@ -55,6 +69,7 @@ public class ReplayModOnline { } new GuiHandler(this).register(); + FMLCommonHandler.instance().bus().register(this); } @Mod.EventHandler @@ -102,9 +117,21 @@ public class ReplayModOnline { public void startReplay(int id, String name, GuiScreen onDownloadCancelled) throws IOException { File file = getDownloadedFile(id); if (file.exists()) { - replayModule.startReplay(file); + currentReplayOutputFile = new File(core.getReplayFolder(), System.currentTimeMillis() + ".mcpr"); + ReplayFile replayFile = new ZipReplayFile(new ReplayStudio(), file, currentReplayOutputFile); + replayModule.startReplay(replayFile); } else { new GuiReplayDownloading(onDownloadCancelled, this, id, name).display(); } } + + @SubscribeEvent + public void onReplayClosed(ReplayCloseEvent.Post event) { + if (currentReplayOutputFile != null) { + if (currentReplayOutputFile.exists()) { // Replay was modified, ask user for new name + new GuiSaveModifiedReplay(currentReplayOutputFile).display(); + } + currentReplayOutputFile = null; + } + } } diff --git a/src/main/java/com/replaymod/online/gui/GuiReplayDownloading.java b/src/main/java/com/replaymod/online/gui/GuiReplayDownloading.java index 0eefa64b..70f46534 100644 --- a/src/main/java/com/replaymod/online/gui/GuiReplayDownloading.java +++ b/src/main/java/com/replaymod/online/gui/GuiReplayDownloading.java @@ -58,7 +58,7 @@ public class GuiReplayDownloading extends AbstractGuiScreen> fileDropdown; - private GuiAdvancedButton chooseButton, cancelButton; - private ComposedElement composedElement; - - private List filesToChooseFrom = new ArrayList(); - - private final String TITLE = I18n.format("replaymod.gui.viewer.chooser.title"); - private final String REPLAYFILE = I18n.format("replaymod.gui.editor.replayfile")+":"; - private final String MESSAGE; - - private final String ORIGINAL = ChatFormatting.GREEN+I18n.format("replaymod.gui.original")+ChatFormatting.RESET; - private final String MODIFIED = ChatFormatting.RED+I18n.format("replaymod.gui.modified")+ChatFormatting.RESET; - - public GuiReplayInstanceChooser(final FileInfo fileInfo, File downloadedFile) { - int id = fileInfo.getId(); - - this.MESSAGE = I18n.format("replaymod.gui.viewer.chooser.message", ChatFormatting.UNDERLINE+fileInfo.getName()+ChatFormatting.RESET); - - //gather all applicable replay files - try { - File replayFolder = ReplayFileIO.getReplayFolder(); - - List chooseableFiles = new ArrayList(); - - File[] files = replayFolder.listFiles(); - if(files != null) { - for(File file : files) { - try { - String extension = FilenameUtils.getExtension(file.getAbsolutePath()); - if(!"zip".equals(extension)) continue; - - String filename = FilenameUtils.getBaseName(file.getAbsolutePath()); - String[] split = filename.split("_"); - String first = split[0]; - - if(StringUtils.isNumeric(first) && Integer.valueOf(first) == id) { - chooseableFiles.add(file); - } - } catch(Exception e) { - e.printStackTrace(); - } - } - } - - //if no modified versions of the replay were found, start the downloaded one - if(chooseableFiles.isEmpty()) { - // TODO -// ReplayHandler.startReplay(downloadedFile); - return; - } - - chooseableFiles.add(0, downloadedFile); - this.filesToChooseFrom = chooseableFiles; - - } catch(IOException e) { - e.printStackTrace(); - } - } - - @Override - public void initGui() { - if(!initialized) { - dropdownTitle = new GuiString(0, 0, Color.WHITE, REPLAYFILE); - - fileDropdown = new GuiDropdown>(fontRendererObj, 0, 0, 0, 5); - - int i = 0; - for(File file : filesToChooseFrom) { - String displayName = FilenameUtils.getName(file.getAbsolutePath()) + " (" + (i == 0 ? ORIGINAL : MODIFIED) + ")"; - fileDropdown.addElement(new GuiEntryListValueEntry(displayName, file)); - i++; - } - - chooseButton = new GuiAdvancedButton(0, 0, 100, 20, I18n.format("replaymod.gui.load"), new Runnable() { - @Override - public void run() { - try { - File file = fileDropdown.getElement(fileDropdown.getSelectionIndex()).getValue(); - //TODO -// ReplayHandler.startReplay(file); - } catch(Exception e) { - e.printStackTrace(); - } - } - }, null); - - cancelButton = new GuiAdvancedButton(0, 0, 100, 20, I18n.format("replaymod.gui.cancel"), new Runnable() { - @Override - public void run() { -// mc.displayGuiScreen(new GuiReplayCenter()); - } - }, null); - - composedElement = new ComposedElement(dropdownTitle, fileDropdown, chooseButton, cancelButton); - } - - fileDropdown.width = 200; - - int strWidth = fontRendererObj.getStringWidth(REPLAYFILE); - int totWidth = strWidth + fileDropdown.width + 5; - - dropdownTitle.positionX = (this.width-totWidth)/2; - fileDropdown.xPosition = dropdownTitle.positionX + strWidth + 5; - - fileDropdown.yPosition = this.height/2 - 10; - - dropdownTitle.positionY = fileDropdown.yPosition + 6; - - cancelButton.xPosition = this.width - 100 - 5; - chooseButton.xPosition = cancelButton.xPosition - 100 - 5; - - cancelButton.yPosition = chooseButton.yPosition = this.height - 5 - 20; - - this.initialized = true; - } - - @Override - public void drawScreen(int mouseX, int mouseY, float partialTicks) { - this.drawDefaultBackground(); - drawCenteredString(fontRendererObj, ChatFormatting.UNDERLINE+TITLE, this.width / 2, 15, Color.WHITE.getRGB()); - - String[] lines = eu.crushedpixel.replaymod.utils.StringUtils.splitStringInMultipleRows(MESSAGE, this.width-40); - int i = 0; - for(String line : lines) { - drawString(fontRendererObj, line, 20, 40+(15*i), Color.WHITE.getRGB()); - i++; - } - - composedElement.draw(mc, mouseX, mouseY); - } - - @Override - protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { - composedElement.mouseClick(mc, mouseX, mouseY, mouseButton); - } - - @Override - protected void mouseReleased(int mouseX, int mouseY, int state) { - composedElement.mouseRelease(mc, mouseX, mouseY, state); - } -} diff --git a/src/main/java/com/replaymod/online/gui/GuiSaveModifiedReplay.java b/src/main/java/com/replaymod/online/gui/GuiSaveModifiedReplay.java new file mode 100644 index 00000000..5e7cedfb --- /dev/null +++ b/src/main/java/com/replaymod/online/gui/GuiSaveModifiedReplay.java @@ -0,0 +1,87 @@ +package com.replaymod.online.gui; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import de.johni0702.minecraft.gui.container.GuiPanel; +import de.johni0702.minecraft.gui.container.GuiScreen; +import de.johni0702.minecraft.gui.element.GuiButton; +import de.johni0702.minecraft.gui.element.GuiLabel; +import de.johni0702.minecraft.gui.element.GuiTextField; +import de.johni0702.minecraft.gui.layout.CustomLayout; +import de.johni0702.minecraft.gui.layout.HorizontalLayout; +import de.johni0702.minecraft.gui.layout.VerticalLayout; +import de.johni0702.minecraft.gui.popup.GuiYesNoPopup; +import de.johni0702.minecraft.gui.utils.Colors; +import lombok.RequiredArgsConstructor; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; + +@RequiredArgsConstructor +public class GuiSaveModifiedReplay extends GuiScreen { + public final File file; + public final GuiLabel message = new GuiLabel().setI18nText("replaymod.gui.replaymodified.message"); + public final GuiTextField name = new GuiTextField().setSize(300, 20).setI18nHint("replaymod.gui.viewer.rename.name"); + public final GuiButton saveButton = new GuiButton().onClick(new Runnable() { + @Override + public void run() { + String resultName = name.getText().trim().replace("[^a-zA-Z0-9\\.\\- ]", "_"); + final File resultFile = new File(file.getParentFile(), resultName + ".mcpr"); + if (resultFile.exists()) { + Futures.addCallback(GuiYesNoPopup.open(GuiSaveModifiedReplay.this, + new GuiLabel().setI18nText("replaymod.gui.replaymodified.warning1", resultName).setColor(Colors.BLACK), + new GuiLabel().setI18nText("replaymod.gui.replaymodified.warning2").setColor(Colors.BLACK)) + .setYesI18nLabel("gui.yes").setNoI18nLabel("gui.no") + .getFuture(), new FutureCallback() { + @Override + public void onSuccess(Boolean result) { + if (result) { + try { + FileUtils.forceDelete(resultFile); + FileUtils.moveFile(file, resultFile); + } catch (IOException e) { + e.printStackTrace(); + } + getMinecraft().displayGuiScreen(null); + } + } + + @Override + public void onFailure(Throwable t) { + t.printStackTrace(); + } + }); + } else { + try { + FileUtils.moveFile(file, resultFile); + } catch (IOException e) { + e.printStackTrace(); + } + getMinecraft().displayGuiScreen(null); + } + } + }).setSize(147, 20).setI18nLabel("replaymod.gui.replaymodified.yes"); + public final GuiButton deleteButton = new GuiButton().onClick(new Runnable() { + @Override + public void run() { + FileUtils.deleteQuietly(file); + getMinecraft().displayGuiScreen(null); + } + }).setSize(147, 20).setI18nLabel("replaymod.gui.replaymodified.no"); + + public final GuiPanel contentPanel = new GuiPanel(this).setLayout(new VerticalLayout().setSpacing(5)) + .addElements(new VerticalLayout.Data(0.5), message, name, + new GuiPanel().setSize(300, 20).setLayout(new HorizontalLayout().setSpacing(6)) + .addElements(null, saveButton, deleteButton)); + + { + setTitle(new GuiLabel().setI18nText("replaymod.gui.replaysaving.title")); + setLayout(new CustomLayout() { + @Override + protected void layout(GuiScreen container, int width, int height) { + pos(contentPanel, width / 2 - width(contentPanel) / 2, height / 2 - height(contentPanel) / 2); + } + }); + } +} diff --git a/src/main/java/com/replaymod/replay/ReplayModReplay.java b/src/main/java/com/replaymod/replay/ReplayModReplay.java index c7b30072..b0e6edf4 100644 --- a/src/main/java/com/replaymod/replay/ReplayModReplay.java +++ b/src/main/java/com/replaymod/replay/ReplayModReplay.java @@ -136,7 +136,10 @@ public class ReplayModReplay { } public void startReplay(File file) throws IOException { - ReplayFile replayFile = new ZipReplayFile(new ReplayStudio(), file); + startReplay(new ZipReplayFile(new ReplayStudio(), file)); + } + + public void startReplay(ReplayFile replayFile) throws IOException { replayHandler = new ReplayHandler(replayFile, true); } diff --git a/src/main/java/com/replaymod/replay/handler/GuiHandler.java b/src/main/java/com/replaymod/replay/handler/GuiHandler.java index 769cf7eb..23e9b657 100644 --- a/src/main/java/com/replaymod/replay/handler/GuiHandler.java +++ b/src/main/java/com/replaymod/replay/handler/GuiHandler.java @@ -99,12 +99,12 @@ public class GuiHandler { if (event.gui instanceof GuiIngameMenu && mod.getReplayHandler() != null) { if (event.button.id == BUTTON_EXIT_REPLAY) { event.button.enabled = false; + mc.displayGuiScreen(new GuiMainMenu()); try { mod.getReplayHandler().endReplay(); } catch (IOException e) { e.printStackTrace(); } - mc.displayGuiScreen(new GuiMainMenu()); } } } diff --git a/src/main/resources/assets/replaymod/lang/en_US.lang b/src/main/resources/assets/replaymod/lang/en_US.lang index 8722cab8..dfc50a87 100644 --- a/src/main/resources/assets/replaymod/lang/en_US.lang +++ b/src/main/resources/assets/replaymod/lang/en_US.lang @@ -232,6 +232,11 @@ replaymod.gui.cancelrender.message=Are you sure that you want to cancel the curr #Saving Replay GUI replaymod.gui.replaysaving.title=Saving Replay File... replaymod.gui.replaysaving.message=Please wait while your recent Replay is being saved. +replaymod.gui.replaymodified.message=Replay was modified. Would you like to save the changes? +replaymod.gui.replaymodified.yes=Save Modified Replay +replaymod.gui.replaymodified.no=Discard Changes +replaymod.gui.replaymodified.warning1=A Replay named "%1$s" already exist. +replaymod.gui.replaymodified.warning2=Are you sure you want to replace it? #Player Overview GUI replaymod.gui.playeroverview.visible=Visible