diff --git a/README.md b/README.md index 3ee421a5..a05f2b8e 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,6 @@ Build the mod via Gradle as explained above at least once (`./gradlew compileJav Then import the Gradle project from within IDEA: File -> Open -> build.gradle -> Open as Project Finally configure IDEA to build everything by itself instead of delegating it to Gradle (cause that is slow): File -> Settings -> Build, Execution, Deployment -> Build Tools -> Gradle -> Build and run using: IntelliJ IDEA -The generation of run configurations for 1.14+ currently depends on https://github.com/FabricMC/fabric-loom/pull/236 - ### Eclipse ## Development diff --git a/versions/common.gradle b/build.gradle similarity index 98% rename from versions/common.gradle rename to build.gradle index be04eb4f..e103e23f 100644 --- a/versions/common.gradle +++ b/build.gradle @@ -10,7 +10,9 @@ buildscript { repositories { mavenLocal() - jcenter() + maven { + url = "https://plugins.gradle.org/m2/" + } mavenCentral() maven { name = "fabric" @@ -32,7 +34,7 @@ buildscript { dependencies { classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.2' if (fabric) { - classpath 'fabric-loom:fabric-loom.gradle.plugin:0.4-SNAPSHOT' + classpath 'fabric-loom:fabric-loom.gradle.plugin:0.5-SNAPSHOT' } else if (mcVersion >= 11400) { classpath('net.minecraftforge.gradle:ForgeGradle:3.+'){ exclude group: 'trove', module: 'trove' // preprocessor/idea requires more recent one @@ -189,7 +191,7 @@ repositories { mavenLocal() maven { name = "SpongePowered Repo" - url = "http://repo.spongepowered.org/maven/" + url = "https://repo.spongepowered.org/maven/" } maven { name = "fabric" @@ -272,7 +274,7 @@ dependencies { if (!FABRIC) { // Mixin 0.8 is no longer compatible with MC 1.11.2 or older - def mixinVersion = mcVersion >= 11200 ? '0.8' : '0.7.10-SNAPSHOT' + def mixinVersion = mcVersion >= 11200 ? '0.8.2' : '0.7.11-SNAPSHOT' annotationProcessor "org.spongepowered:mixin:$mixinVersion" compileOnly "org.spongepowered:mixin:$mixinVersion" shade("org.spongepowered:mixin:$mixinVersion") { @@ -283,6 +285,7 @@ dependencies { annotationProcessor 'com.google.code.gson:gson:2.2.4' annotationProcessor 'com.google.guava:guava:21.0' annotationProcessor 'org.ow2.asm:asm-tree:6.2' + annotationProcessor 'org.apache.logging.log4j:log4j-core:2.0-beta9' } shadow 'com.googlecode.mp4parser:isoparser:1.1.7' shadow 'org.apache.commons:commons-exec:1.3' @@ -309,7 +312,7 @@ dependencies { shadow 'com.github.ReplayMod.JavaBlend:2.79.0:a0696f8' - shadow "com.github.ReplayMod:ReplayStudio:dac74cc", shadeExclusions + shadow "com.github.ReplayMod:ReplayStudio:a1f82a7", shadeExclusions implementation(jGui){ transitive = false // FG 1.2 puts all MC deps into the compile configuration and we don't want to shade those diff --git a/jGui b/jGui index 6b16892d..66418363 160000 --- a/jGui +++ b/jGui @@ -1 +1 @@ -Subproject commit 6b16892d6489bf28cbf6945329f71c2effb52bc2 +Subproject commit 6641836321f4583e6f56d8ceb59da452213396e7 diff --git a/build.gradle.kts b/root.gradle.kts similarity index 99% rename from build.gradle.kts rename to root.gradle.kts index 0193959a..61825fc4 100755 --- a/build.gradle.kts +++ b/root.gradle.kts @@ -2,7 +2,7 @@ import groovy.json.JsonOutput import java.io.ByteArrayOutputStream plugins { - id("fabric-loom") version "0.4-SNAPSHOT" apply false + id("fabric-loom") version "0.5-SNAPSHOT" apply false id("com.replaymod.preprocess") version "24ac087" id("com.github.hierynomus.license") version "0.15.0" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 355bcbc5..b99f2a4a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,7 +2,6 @@ pluginManagement { repositories { mavenLocal() gradlePluginPortal() - jcenter() mavenCentral() google() maven("https://jitpack.io") @@ -49,6 +48,8 @@ val replayModVersions = listOf( "1.16.4" ) +rootProject.buildFileName = "root.gradle.kts" + include(":jGui") project(":jGui").apply { projectDir = file("jGui") @@ -58,7 +59,7 @@ jGuiVersions.forEach { version -> include(":jGui:$version") project(":jGui:$version").apply { projectDir = file("jGui/versions/$version") - buildFileName = "../common.gradle" + buildFileName = "../../build.gradle" } } @@ -66,6 +67,6 @@ replayModVersions.forEach { version -> include(":$version") project(":$version").apply { projectDir = file("versions/$version") - buildFileName = "../common.gradle" + buildFileName = "../../build.gradle" } } diff --git a/src/main/java/com/replaymod/core/ReplayMod.java b/src/main/java/com/replaymod/core/ReplayMod.java index 9971ba6e..6afd4bdd 100644 --- a/src/main/java/com/replaymod/core/ReplayMod.java +++ b/src/main/java/com/replaymod/core/ReplayMod.java @@ -476,6 +476,14 @@ public class ReplayMod implements String name = path.getFileName().toString(); if (name.endsWith(".mcpr.tmp") && Files.isDirectory(path)) { Path original = path.resolveSibling(FilenameUtils.getBaseName(name)); + Path noRecoverMarker = original.resolveSibling(original.getFileName() + ".no_recover"); + if (Files.exists(noRecoverMarker)) { + // This file, when its markers are processed, doesn't actually result in any replays. + // So we don't really need to recover it either, let's just get rid of it. + FileUtils.deleteDirectory(path.toFile()); + Files.delete(noRecoverMarker); + continue; + } new RestoreReplayGui(this, GuiScreen.wrap(mc.currentScreen), original.toFile()).display(); } } diff --git a/src/main/java/com/replaymod/core/versions/MCVer.java b/src/main/java/com/replaymod/core/versions/MCVer.java index f0c99a10..75d17f50 100644 --- a/src/main/java/com/replaymod/core/versions/MCVer.java +++ b/src/main/java/com/replaymod/core/versions/MCVer.java @@ -80,9 +80,16 @@ import org.lwjgl.glfw.GLFW; //$$ import java.io.IOException; //#endif +//#if MC>=11400 +import net.minecraft.client.sound.PositionedSoundInstance; +//#else +//$$ import net.minecraft.client.audio.PositionedSoundRecord; +//#endif + //#if MC>=10904 import com.replaymod.render.blend.mixin.ParticleAccessor; import net.minecraft.client.particle.Particle; +import net.minecraft.sound.SoundEvent; import net.minecraft.util.math.Vec3d; //#endif @@ -758,6 +765,20 @@ public class MCVer { } } + public static void playSound(Identifier sound) { + getMinecraft().getSoundManager().play( + //#if MC>=11400 + PositionedSoundInstance.master(new SoundEvent(sound), 1.0F) + //#elseif MC>=10904 + //$$ PositionedSoundRecord.getMasterRecord(new SoundEvent(sound), 1.0F) + //#elseif MC>=10800 + //$$ PositionedSoundRecord.create(sound, 1.0F) + //#else + //$$ PositionedSoundRecord.createPositionedSoundRecord(sound, 1.0F) + //#endif + ); + } + //#if MC>=11400 private static Boolean hasOptifine; public static boolean hasOptifine() { diff --git a/src/main/java/com/replaymod/recording/packet/PacketListener.java b/src/main/java/com/replaymod/recording/packet/PacketListener.java index 40d4605c..83f573cd 100644 --- a/src/main/java/com/replaymod/recording/packet/PacketListener.java +++ b/src/main/java/com/replaymod/recording/packet/PacketListener.java @@ -272,6 +272,10 @@ public class PacketListener extends ChannelInboundHandlerAdapter { // Immediately close the saving popup, the user doesn't care about it core.runLater(guiSavingReplay::close); + // If we crash right here, on the next start we'll prompt the user for recovery + // but we don't really want that, so drop a marker file to skip recovery for this replay. + Files.createFile(outputPath.resolveSibling(outputPath.getFileName() + ".no_recover")); + // We still have the replay, so we just save it (at least for a few weeks) in case they change their mind String replayName = FilenameUtils.getBaseName(outputPath.getFileName().toString()); Path rawFolder = ReplayMod.instance.getRawReplayFolder(); diff --git a/src/main/java/com/replaymod/render/RenderSettings.java b/src/main/java/com/replaymod/render/RenderSettings.java index 1043792d..511ef027 100644 --- a/src/main/java/com/replaymod/render/RenderSettings.java +++ b/src/main/java/com/replaymod/render/RenderSettings.java @@ -443,4 +443,32 @@ public class RenderSettings { public boolean isHighPerformance() { return highPerformance; } + + @Override + public String toString() { + return "RenderSettings{" + + "renderMethod=" + renderMethod + + ", encodingPreset=" + encodingPreset + + ", videoWidth=" + videoWidth + + ", videoHeight=" + videoHeight + + ", framesPerSecond=" + framesPerSecond + + ", bitRate=" + bitRate + + ", outputFile=" + outputFile + + ", renderNameTags=" + renderNameTags + + ", stabilizeYaw=" + stabilizeYaw + + ", stabilizePitch=" + stabilizePitch + + ", stabilizeRoll=" + stabilizeRoll + + ", chromaKeyingColor=" + chromaKeyingColor + + ", sphericalFovX=" + sphericalFovX + + ", sphericalFovY=" + sphericalFovY + + ", injectSphericalMetadata=" + injectSphericalMetadata + + ", depthMap=" + depthMap + + ", cameraPathExport=" + cameraPathExport + + ", antiAliasing=" + antiAliasing + + ", exportCommand='" + exportCommand + '\'' + + ", exportArgumentsPreBgra='" + exportArgumentsPreBgra + '\'' + + ", exportArguments='" + exportArguments + '\'' + + ", highPerformance=" + highPerformance + + '}'; + } } diff --git a/src/main/java/com/replaymod/render/gui/GuiRenderQueue.java b/src/main/java/com/replaymod/render/gui/GuiRenderQueue.java index 33d1392a..7cd0a6cd 100644 --- a/src/main/java/com/replaymod/render/gui/GuiRenderQueue.java +++ b/src/main/java/com/replaymod/render/gui/GuiRenderQueue.java @@ -48,6 +48,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.function.Supplier; +import java.util.stream.Collectors; import static com.replaymod.render.ReplayModRender.LOGGER; @@ -148,8 +149,15 @@ public class GuiRenderQueue extends AbstractGuiPopup implements renderButton.onClick(() -> { LOGGER.trace("Render button clicked"); List renderQueue = new ArrayList<>(); - for (Entry entry : selectedEntries) { - renderQueue.add(entry.job); + if (selectedEntries.isEmpty()) { + renderQueue.addAll(jobs); + } else { + Set selectedJobs = selectedEntries.stream().map(it -> it.job).collect(Collectors.toSet()); + for (RenderJob job : jobs) { + if (selectedJobs.contains(job)) { + renderQueue.add(job); + } + } } ReplayMod.instance.runLaterWithoutLock(() -> processQueue(container, replayHandler, renderQueue, () -> {})); }); @@ -337,7 +345,7 @@ public class GuiRenderQueue extends AbstractGuiPopup implements addButton.setEnabled(timelineSupplier != null); editButton.setEnabled(selected == 1); removeButton.setEnabled(selected >= 1); - renderButton.setEnabled(selected > 0); + renderButton.setEnabled(jobs.size() > 0); renderButton.setI18nLabel("replaymod.gui.renderqueue.render" + (selected > 0 ? "selected" : "all")); String[] compatError = VideoRenderer.checkCompat(); diff --git a/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java b/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java index cf0f58f5..24aac257 100644 --- a/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java +++ b/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java @@ -129,7 +129,7 @@ public class GuiRenderSettings extends AbstractGuiPopup { public void run() { GuiFileChooserPopup popup = GuiFileChooserPopup.openSaveGui(GuiRenderSettings.this, "replaymod.gui.save", encodingPresetDropdown.getSelectedValue().getFileExtension()); - popup.setFolder(outputFile.getParentFile()); + popup.setFolder(getParentFile(outputFile)); popup.setFileName(outputFile.getName()); Futures.addCallback( popup.getFuture(), @@ -538,13 +538,13 @@ public class GuiRenderSettings extends AbstractGuiPopup { bitRateUnit.setSelected(0); } File savedOutputFile = settings.getOutputFile(); - if (savedOutputFile == null || !savedOutputFile.getParentFile().exists()) { + if (savedOutputFile == null || !getParentFile(savedOutputFile).exists()) { this.outputFile = generateOutputFile(encodingPreset); userDefinedOutputFileName = false; } else if (savedOutputFile.exists()) { String name = generateOutputFile(encodingPreset).getName(); boolean isFolder = savedOutputFile.isDirectory() && !savedOutputFile.getName().endsWith(".exr"); - this.outputFile = new File(isFolder ? savedOutputFile : savedOutputFile.getParentFile(), name); + this.outputFile = new File(isFolder ? savedOutputFile : getParentFile(savedOutputFile), name); userDefinedOutputFileName = false; } else { this.outputFile = conformExtension(savedOutputFile, encodingPreset); @@ -588,7 +588,7 @@ public class GuiRenderSettings extends AbstractGuiPopup { videoHeight.getInteger(), frameRateSlider.getValue() + 10, bitRateField.getInteger() << (10 * bitRateUnit.getSelected()), - serialize && !userDefinedOutputFileName ? outputFile.getParentFile() : outputFile, + serialize && !userDefinedOutputFileName ? getParentFile(outputFile) : outputFile, nametagCheckbox.isChecked(), stabilizeYaw.isChecked() && (serialize || stabilizeYaw.isEnabled()), stabilizePitch.isChecked() && (serialize || stabilizePitch.isEnabled()), @@ -617,7 +617,7 @@ public class GuiRenderSettings extends AbstractGuiPopup { public void setOutputFileBaseName(String base) { RenderSettings.EncodingPreset preset = encodingPresetDropdown.getSelectedValue(); - File file = new File(outputFile.getParentFile(), base + "." + preset.getFileExtension()); + File file = new File(getParentFile(outputFile), base + "." + preset.getFileExtension()); // Ensure the file name is valid try { //noinspection ResultOfMethodCallIgnored @@ -634,7 +634,7 @@ public class GuiRenderSettings extends AbstractGuiPopup { if (name.contains(".")) { name = name.substring(0, name.lastIndexOf('.')); } - return new File(file.getParentFile(), name + "." + preset.getFileExtension()); + return new File(getParentFile(file), name + "." + preset.getFileExtension()); } protected Path getSettingsPath() { @@ -677,4 +677,10 @@ public class GuiRenderSettings extends AbstractGuiPopup { screen.setBackground(AbstractGuiScreen.Background.NONE); return screen; } + + private static File getParentFile(File file) { + File parent = file.getParentFile(); + // parent this can be null if file is just a name (i.e. in CWD) + return parent == null ? new File(".") : parent; + } } diff --git a/src/main/java/com/replaymod/render/rendering/VideoRenderer.java b/src/main/java/com/replaymod/render/rendering/VideoRenderer.java index 565b84eb..46f56a04 100644 --- a/src/main/java/com/replaymod/render/rendering/VideoRenderer.java +++ b/src/main/java/com/replaymod/render/rendering/VideoRenderer.java @@ -19,7 +19,6 @@ import com.replaymod.render.gui.GuiRenderingDone; import com.replaymod.render.gui.GuiVideoRenderer; import com.replaymod.render.metadata.MetadataInjector; import com.replaymod.render.mixin.WorldRendererAccessor; -import com.replaymod.render.utils.SoundHandler; import com.replaymod.replay.ReplayHandler; import com.replaymod.replaystudio.pathing.path.Keyframe; import com.replaymod.replaystudio.pathing.path.Path; @@ -29,6 +28,7 @@ import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension; import net.minecraft.client.MinecraftClient; import com.mojang.blaze3d.platform.GLX; import net.minecraft.client.gl.Framebuffer; +import net.minecraft.util.Identifier; import net.minecraft.util.crash.CrashException; import net.minecraft.sound.SoundCategory; import net.minecraft.client.render.RenderTickCounter; @@ -422,7 +422,7 @@ public class VideoRenderer implements RenderInfo { } } - new SoundHandler().playRenderSuccessSound(); + MCVer.playSound(new Identifier("replaymod", "render_success")); try { if (!hasFailed() && ffmpegWriter != null) { diff --git a/src/main/java/com/replaymod/render/utils/SoundHandler.java b/src/main/java/com/replaymod/render/utils/SoundHandler.java deleted file mode 100644 index 940d51bc..00000000 --- a/src/main/java/com/replaymod/render/utils/SoundHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.replaymod.render.utils; - -import com.replaymod.core.versions.MCVer; -import net.minecraft.util.Identifier; -import org.apache.commons.io.IOUtils; - -import javax.sound.sampled.AudioInputStream; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.Clip; -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -public class SoundHandler { - - private final Identifier successSoundLocation = new Identifier("replaymod", "render_success.wav"); - - public void playRenderSuccessSound() { - playSound(successSoundLocation); - } - - /** - * Plays a .wav Sound from a ResourceLocation. This method does not respect Game Settings like Audio Volume. - * @param loc The Sound File's ResourceLocation - */ - public void playSound(Identifier loc) { - try { - InputStream is = MCVer.getMinecraft().getResourceManager().getResource(loc).getInputStream(); - byte[] bytes = IOUtils.toByteArray(is); - is.close(); - AudioInputStream ais = AudioSystem.getAudioInputStream(new ByteArrayInputStream(bytes)); - - Clip clip = AudioSystem.getClip(); - clip.open(ais); - clip.start(); - } catch(Exception e) { - e.printStackTrace(); - } - } -} diff --git a/src/main/java/com/replaymod/replay/FullReplaySender.java b/src/main/java/com/replaymod/replay/FullReplaySender.java index c5ee6517..20ab761d 100644 --- a/src/main/java/com/replaymod/replay/FullReplaySender.java +++ b/src/main/java/com/replaymod/replay/FullReplaySender.java @@ -339,9 +339,8 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend */ @Override public int currentTimeStamp() { - if (asyncMode) { - int timePassed = (int) (System.currentTimeMillis() - lastPacketSent); - return lastTimeStamp + (int) (timePassed * getReplaySpeed()); + if (asyncMode && !paused()) { + return (int) ((System.currentTimeMillis() - realTimeStart) * realTimeStartSpeed); } else { return lastTimeStamp; } @@ -864,7 +863,11 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend */ @Override public void setReplaySpeed(final double d) { - if(d != 0) this.replaySpeed = d; + if (d != 0) { + this.replaySpeed = d; + this.realTimeStartSpeed = d; + this.realTimeStart = System.currentTimeMillis() - (long) (lastTimeStamp / d); + } TimerAccessor timer = (TimerAccessor) ((MinecraftAccessor) mc).getTimer(); //#if MC>=11200 timer.setTickLength(WrappedTimer.DEFAULT_MS_PER_TICK / (float) d); @@ -878,9 +881,18 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend ///////////////////////////////////////////////////////// /** - * The real time at which the last packet was sent in milliseconds. + * Timestamp in milliseconds of when we started (or would have started when taking pauses and speed into account) + * the playback of the replay. + * Updated only when replay speed changes or on pause/unpause but definitely not on every packet to prevent gradual + * drifting. */ - private long lastPacketSent; + private long realTimeStart; + + /** + * The replay speed used for {@link #realTimeStart}. + * If the target speed differs from this one, the timestamp is recalculated. + */ + private double realTimeStartSpeed; /** * There is no waiting performed until a packet with at least this timestamp is reached (but not yet sent). @@ -936,15 +948,13 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend // If we aren't jumping and the world has already been loaded (no dirt-screens) then wait // the required amount to get proper packet timing if (!isHurrying() && hasWorldLoaded) { - // How much time should have passed - int timeWait = (int) Math.round((nextTimeStamp - lastTimeStamp) / replaySpeed); - // How much time did pass - long timeDiff = System.currentTimeMillis() - lastPacketSent; - // How much time we need to wait to make up for the difference - long timeToSleep = Math.max(0, timeWait - timeDiff); - - Thread.sleep(timeToSleep); - lastPacketSent = System.currentTimeMillis(); + // Timestamp of when the next packet should be sent + long expectedTime = realTimeStart + (long) (nextTimeStamp / replaySpeed); + long now = System.currentTimeMillis(); + // If the packet should not yet be sent, wait a bit + if (expectedTime > now) { + Thread.sleep(expectedTime - now); + } } // Process packet @@ -961,7 +971,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend replayHandler.moveCameraToTargetPosition(); - // Pause after jumping + // Pause after jumping (this will also reset realTimeStart accordingly) setReplaySpeed(0); } } catch (EOFException eof) { @@ -988,7 +998,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend loginPhase = true; startFromBeginning = false; nextPacket = null; - lastPacketSent = System.currentTimeMillis(); + realTimeStart = System.currentTimeMillis(); if (replayIn != null) { replayIn.close(); replayIn = null; @@ -1133,7 +1143,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend } // This might be required if we change to async mode anytime soon - lastPacketSent = System.currentTimeMillis(); + realTimeStart = System.currentTimeMillis() - (long) (timestamp / replaySpeed); lastTimeStamp = timestamp; } } catch (Exception e) { diff --git a/src/main/java/com/replaymod/replay/camera/CameraEntity.java b/src/main/java/com/replaymod/replay/camera/CameraEntity.java index 6244acfc..591a37d2 100644 --- a/src/main/java/com/replaymod/replay/camera/CameraEntity.java +++ b/src/main/java/com/replaymod/replay/camera/CameraEntity.java @@ -51,6 +51,7 @@ import net.minecraft.util.hit.HitResult; //$$ import net.minecraft.util.math.RayTraceResult; //$$ import net.minecraft.util.text.ITextComponent; //$$ import net.minecraft.world.World; +//$$ import net.minecraftforge.fml.common.gameevent.InputEvent; //$$ //#if MC>=11400 //$$ import net.minecraft.util.math.RayTraceFluidMode; @@ -637,12 +638,11 @@ public class CameraEntity } public boolean canSpectate(Entity e) { - return e != null && !e.isInvisible() - //#if MC>=10800 - && (e instanceof PlayerEntity || e instanceof MobEntity || e instanceof ItemFrameEntity); - //#else - //$$ && e instanceof EntityPlayer; // cannot be more generic since 1.7.10 has no concept of eye height + return e != null + //#if MC<10800 + //$$ && e instanceof EntityPlayer // cannot be more generic since 1.7.10 has no concept of eye height //#endif + && !e.isInvisible(); } //#if MC<11400 @@ -695,6 +695,16 @@ public class CameraEntity //#if FABRIC>=1 { on(KeyBindingEventCallback.EVENT, CameraEntity.this::handleInputEvents); } + //#elseif MC<11400 + //$$ @SubscribeEvent + //$$ public void onKeyEvent(InputEvent.KeyInputEvent event) { + //$$ handleInputEvents(); + //$$ } + //$$ + //$$ @SubscribeEvent + //$$ public void onMouseInput(InputEvent.MouseInputEvent event) { + //$$ handleInputEvents(); + //$$ } //#endif //#if FABRIC>=1 diff --git a/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java b/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java index f805dd58..d38ddad1 100644 --- a/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java +++ b/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java @@ -67,6 +67,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.IOException; import java.util.Collections; +import java.util.concurrent.CancellationException; import java.util.function.Consumer; import static com.replaymod.core.utils.Utils.error; @@ -287,7 +288,9 @@ public class GuiPathing { @Override public void onFailure(Throwable t) { - t.printStackTrace(); + if (!(t instanceof CancellationException)) { + t.printStackTrace(); + } overlay.setCloseable(true); } }); diff --git a/src/main/resources/assets/replaymod/render_success.wav b/src/main/resources/assets/replaymod/render_success.wav deleted file mode 100644 index 311e8693..00000000 Binary files a/src/main/resources/assets/replaymod/render_success.wav and /dev/null differ diff --git a/src/main/resources/assets/replaymod/sounds.json b/src/main/resources/assets/replaymod/sounds.json new file mode 100644 index 00000000..0bf83f53 --- /dev/null +++ b/src/main/resources/assets/replaymod/sounds.json @@ -0,0 +1,5 @@ +{ + "render_success": { + "sounds": [{ "name": "replaymod:render_success" }] + } +} diff --git a/src/main/resources/assets/replaymod/sounds/render_success.ogg b/src/main/resources/assets/replaymod/sounds/render_success.ogg new file mode 100644 index 00000000..3cc89443 Binary files /dev/null and b/src/main/resources/assets/replaymod/sounds/render_success.ogg differ diff --git a/version.txt b/version.txt index 73462a5a..f225a78a 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.5.1 +2.5.2