diff --git a/build.gradle b/build.gradle index 6055b10f..bd4894a1 100644 --- a/build.gradle +++ b/build.gradle @@ -252,6 +252,7 @@ dependencies { 11901: '1.19.1', 11902: '1.19.2', 11903: '1.19.3-rc3', + 11904: '1.19.4', ][mcVersion] mappings 'net.fabricmc:yarn:' + [ 11404: '1.14.4+build.16', @@ -268,6 +269,7 @@ dependencies { 11901: '1.19.1+build.5:v2', 11902: '1.19.2+build.28:v2', 11903: '1.19.3-rc3+build.1:v2', + 11904: '1.19.4+build.1:v2', ][mcVersion] modImplementation 'net.fabricmc:fabric-loader:0.14.11' def fabricApiVersion = [ @@ -285,6 +287,7 @@ dependencies { 11901: '0.58.5+1.19.1', 11902: '0.68.0+1.19.2', 11903: '0.68.1+1.19.3', + 11904: '0.76.0+1.19.4', ][mcVersion] def fabricApiModules = [ "api-base", @@ -357,7 +360,7 @@ dependencies { shadow 'com.github.ReplayMod.JavaBlend:2.79.0:a0696f8' - shadow "com.github.ReplayMod:ReplayStudio:21ef505", shadeExclusions + shadow "com.github.ReplayMod:ReplayStudio:b5cc75a", shadeExclusions // FIXME this should be pulled in by ReplayStudio, and IntelliJ sees it, but javac for some reason does not implementation 'com.github.viaversion:opennbt:0a02214' // 2.0-SNAPSHOT (ViaVersion Edition) @@ -368,7 +371,9 @@ dependencies { shadow 'com.github.ReplayMod:lwjgl-utils:27dcd66' if (FABRIC) { - if (mcVersion >= 11903) { + if (mcVersion >= 11904) { + modImplementation 'com.terraformersmc:modmenu:6.1.0-rc.4' + } else if (mcVersion >= 11903) { modImplementation 'com.terraformersmc:modmenu:5.0.0-alpha.4' } else if (mcVersion >= 11901) { modImplementation 'com.terraformersmc:modmenu:4.0.5' diff --git a/jGui b/jGui index 7a80b50c..34d9d6bb 160000 --- a/jGui +++ b/jGui @@ -1 +1 @@ -Subproject commit 7a80b50c2e7cd0557c5ab670c59b46b256c0434c +Subproject commit 34d9d6bb1531a425c4a4906920c6e235b24a8031 diff --git a/root.gradle.kts b/root.gradle.kts index 511e29e6..6f78706d 100755 --- a/root.gradle.kts +++ b/root.gradle.kts @@ -193,6 +193,7 @@ val doRelease by tasks.registering { defaultTasks("bundleJar") preprocess { + val mc11904 = createNode("1.19.4", 11904, "yarn") val mc11903 = createNode("1.19.3", 11903, "yarn") val mc11902 = createNode("1.19.2", 11902, "yarn") val mc11901 = createNode("1.19.1", 11901, "yarn") @@ -217,6 +218,7 @@ preprocess { val mc10800 = createNode("1.8", 10800, "srg") val mc10710 = createNode("1.7.10", 10710, "srg") + mc11904.link(mc11903) mc11903.link(mc11902, file("versions/mapping-fabric-1.19.3-1.19.2.txt")) mc11902.link(mc11901) mc11901.link(mc11900) diff --git a/settings.gradle.kts b/settings.gradle.kts index fa478e0a..ea849bd8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,6 +37,7 @@ val jGuiVersions = listOf( "1.19.1", "1.19.2", "1.19.3", + "1.19.4", ) val replayModVersions = listOf( // "1.7.10", @@ -62,6 +63,7 @@ val replayModVersions = listOf( "1.19.1", "1.19.2", "1.19.3", + "1.19.4", ) rootProject.buildFileName = "root.gradle.kts" diff --git a/src/main/java/com/replaymod/core/ReplayModBackend.java b/src/main/java/com/replaymod/core/ReplayModBackend.java index d6313852..2e120df9 100644 --- a/src/main/java/com/replaymod/core/ReplayModBackend.java +++ b/src/main/java/com/replaymod/core/ReplayModBackend.java @@ -2,6 +2,7 @@ package com.replaymod.core; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.SharedConstants; import static com.replaymod.core.ReplayMod.MOD_ID; @@ -20,7 +21,7 @@ public class ReplayModBackend implements ClientModInitializer { } public String getMinecraftVersion() { - return mod.getMinecraft().getGame().getVersion().getName(); + return SharedConstants.getGameVersion().getName(); } public boolean isModLoaded(String id) { diff --git a/src/main/java/com/replaymod/recording/mixin/MixinWorldClient.java b/src/main/java/com/replaymod/recording/mixin/MixinWorldClient.java index e859e2a3..b33c0436 100644 --- a/src/main/java/com/replaymod/recording/mixin/MixinWorldClient.java +++ b/src/main/java/com/replaymod/recording/mixin/MixinWorldClient.java @@ -6,7 +6,6 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket; -import net.minecraft.util.profiler.Profiler; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvent; import net.minecraft.util.math.BlockPos; @@ -21,87 +20,26 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; //$$ import net.minecraft.util.registry.RegistryEntry; //#endif -//#if MC>=11600 -import net.minecraft.util.registry.RegistryKey; -import net.minecraft.world.MutableWorldProperties; -import java.util.function.Supplier; -//#else -//$$ import net.minecraft.world.level.LevelProperties; -//#endif - -//#if MC>=11400 -import net.minecraft.world.chunk.ChunkManager; -//#if MC<11600 -//$$ import net.minecraft.world.dimension.Dimension; -//#endif -import net.minecraft.world.dimension.DimensionType; -import java.util.function.BiFunction; -//#else -//$$ import net.minecraft.world.storage.ISaveHandler; -//#if MC>=11400 -//$$ import net.minecraft.world.dimension.Dimension; -//$$ import net.minecraft.world.storage.WorldSavedDataStorage; -//#else -//$$ import net.minecraft.world.WorldProvider; -//#endif -//#endif - @Mixin(ClientWorld.class) public abstract class MixinWorldClient extends World implements RecordingEventHandler.RecordingEventSender { @Shadow private MinecraftClient client; - //#if MC>=11600 - protected MixinWorldClient(MutableWorldProperties mutableWorldProperties, RegistryKey registryKey, - //#if MC<11602 - //$$ RegistryKey registryKey2, - //#endif - //#if MC>=11802 - //$$ RegistryEntry dimensionType, - //#else - DimensionType dimensionType, - //#endif - Supplier profiler, boolean bl, boolean bl2, long l - //#if MC>=11900 - //$$ , int maxChainedNeighborUpdates - //#endif - ) { - super(mutableWorldProperties, registryKey, - //#if MC<11602 - //$$ registryKey2, - //#endif - dimensionType, profiler, bl, bl2, l - //#if MC>=11900 - //$$ , maxChainedNeighborUpdates - //#endif - ); + @SuppressWarnings("ConstantConditions") + protected MixinWorldClient() { + //#if MC>=11904 + //$$ super(null, null, null, null, null, false, false, 0, 0); + //#elseif MC>=11900 + //$$ super(null, null, null, null, false, false, 0, 0); + //#elseif MC>=11602 + super(null, null, null, null, false, false, 0); + //#elseif MC>=11600 + //$$ super(null, null, null, null, null, false, false, 0); + //#else + //$$ super(null, null, null, null, false); + //#endif } - //#else - //#if MC>=11400 - //$$ protected MixinWorldClient(LevelProperties levelProperties_1, DimensionType dimensionType_1, BiFunction biFunction_1, Profiler profiler_1, boolean boolean_1) { - //$$ super(levelProperties_1, dimensionType_1, biFunction_1, profiler_1, boolean_1); - //$$ } - //#else - //$$ protected MixinWorldClient(ISaveHandler saveHandlerIn, - //#if MC>=11400 - //$$ WorldSavedDataStorage mapStorage, - //#endif - //$$ WorldInfo info, - //#if MC>=11400 - //$$ Dimension providerIn, - //#else - //$$ WorldProvider providerIn, - //#endif - //$$ Profiler profilerIn, boolean client) { - //$$ super(saveHandlerIn, - //#if MC>=11400 - //$$ mapStorage, - //#endif - //$$ info, providerIn, profilerIn, client); - //$$ } - //#endif - //#endif private RecordingEventHandler replayModRecording_getRecordingEventHandler() { return ((RecordingEventHandler.RecordingEventSender) this.client.worldRenderer).getRecordingEventHandler(); diff --git a/src/main/java/com/replaymod/recording/packet/PacketListener.java b/src/main/java/com/replaymod/recording/packet/PacketListener.java index 677673ad..be72bedb 100644 --- a/src/main/java/com/replaymod/recording/packet/PacketListener.java +++ b/src/main/java/com/replaymod/recording/packet/PacketListener.java @@ -69,6 +69,11 @@ import static com.replaymod.core.versions.MCVer.*; import static com.replaymod.replaystudio.util.Utils.writeInt; import static java.util.Objects.requireNonNull; +//#if MC>=11904 +//$$ import net.minecraft.network.PacketBundleHandler; +//$$ import java.util.ArrayList; +//#endif + @ChannelHandler.Sharable // so we can re-order it public class PacketListener extends ChannelInboundHandlerAdapter { @@ -341,7 +346,25 @@ public class PacketListener extends ChannelInboundHandlerAdapter { } else if (msg instanceof net.minecraft.network.Packet) { // for integrated server connections MC is passing the packet objects directly, so we need to encode them // ourselves to be able to store them + //#if MC>=11904 + //$$ PacketBundleHandler bundleHandler = ctx.channel().attr(PacketBundleHandler.KEY).get().getBundler(NetworkSide.CLIENTBOUND); + //$$ List packets = new ArrayList<>(1); + //$$ bundleHandler.forEachPacket((net.minecraft.network.packet.Packet) msg, unbundledPacket -> { + //$$ try { + //$$ packets.add(encodeMcPacket(connectionState, unbundledPacket)); + //$$ } catch (Exception e) { + //$$ throw new RuntimeException(e); + //$$ } + //$$ }); + //$$ if (packets.size() > 1) { + //$$ packets.forEach(this::save); + //$$ super.channelRead(ctx, msg); + //$$ return; + //$$ } + //$$ packet = packets.isEmpty() ? null : packets.get(0); + //#else packet = encodeMcPacket(connectionState, (net.minecraft.network.Packet) msg); + //#endif } if (packet != null) { diff --git a/src/main/java/com/replaymod/render/capturer/OpenGlFrameCapturer.java b/src/main/java/com/replaymod/render/capturer/OpenGlFrameCapturer.java index eb26e0bc..bc9bdad5 100644 --- a/src/main/java/com/replaymod/render/capturer/OpenGlFrameCapturer.java +++ b/src/main/java/com/replaymod/render/capturer/OpenGlFrameCapturer.java @@ -88,7 +88,9 @@ public abstract class OpenGlFrameCapturer=11500 diff --git a/src/main/java/com/replaymod/replay/FullReplaySender.java b/src/main/java/com/replaymod/replay/FullReplaySender.java index 9c9621e0..5eab0b60 100644 --- a/src/main/java/com/replaymod/replay/FullReplaySender.java +++ b/src/main/java/com/replaymod/replay/FullReplaySender.java @@ -57,6 +57,10 @@ import net.minecraft.util.math.Vec3d; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; +//#if MC>=11904 +//$$ import net.minecraft.network.packet.s2c.play.PositionFlag; +//#endif + //#if MC>=11903 //$$ import net.minecraft.network.packet.s2c.play.ProfilelessChatMessageS2CPacket; //#endif @@ -804,7 +808,10 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend if(replayHandler.shouldSuppressCameraMovements()) return null; //#if MC>=10800 - //#if MC>=11400 + //#if MC>=11904 + //$$ for (PositionFlag relative : ppl.getFlags()) { + //$$ if (relative == PositionFlag.X || relative == PositionFlag.Y || relative == PositionFlag.Z) { + //#elseif MC>=11400 for (PlayerPositionLookS2CPacket.Flag relative : ppl.getFlags()) { if (relative == PlayerPositionLookS2CPacket.Flag.X || relative == PlayerPositionLookS2CPacket.Flag.Y diff --git a/src/main/java/com/replaymod/replay/NoGuiScreenshot.java b/src/main/java/com/replaymod/replay/NoGuiScreenshot.java index a3cd6d56..69a995b6 100644 --- a/src/main/java/com/replaymod/replay/NoGuiScreenshot.java +++ b/src/main/java/com/replaymod/replay/NoGuiScreenshot.java @@ -69,7 +69,9 @@ public class NoGuiScreenshot { //#endif ); mc.getFramebuffer().beginWrite(true); + //#if MC<11904 GlStateManager.enableTexture(); + //#endif float tickDelta = mc.getTickDelta(); //#if MC>=11500 diff --git a/src/main/java/com/replaymod/replay/ReplayHandler.java b/src/main/java/com/replaymod/replay/ReplayHandler.java index 800377b6..1e9278d6 100644 --- a/src/main/java/com/replaymod/replay/ReplayHandler.java +++ b/src/main/java/com/replaymod/replay/ReplayHandler.java @@ -33,6 +33,7 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.DownloadingTerrainScreen; import net.minecraft.client.network.ClientLoginNetworkHandler; import net.minecraft.client.util.Window; +import net.minecraft.network.NetworkState; import net.minecraft.util.crash.CrashReport; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; @@ -41,6 +42,10 @@ import net.minecraft.network.ClientConnection; import java.io.IOException; import java.util.*; +//#if MC>=11904 +//$$ import net.minecraft.network.PacketBundler; +//#endif + //#if MC>=11700 //$$ import net.minecraft.client.render.DiffuseLighting; //$$ import net.minecraft.util.math.Matrix4f; @@ -317,9 +322,16 @@ public class ReplayHandler { channel.pipeline().addLast("ReplayModReplay_quickReplaySender", quickReplaySender); //#endif channel.pipeline().addLast("ReplayModReplay_replaySender", fullReplaySender); + //#if MC>=11904 + //$$ channel.pipeline().addLast("bundler", new PacketBundler(NetworkSide.CLIENTBOUND)); + //#endif channel.pipeline().addLast("packet_handler", networkManager); channel.pipeline().fireChannelActive(); + // MC usually transitions from handshake to login via the packets it sends. + // We don't send any packets (there is no server to receive them), so we need to switch manually. + networkManager.setState(NetworkState.LOGIN); + //#if MC>=11400 ((MinecraftAccessor) mc).setConnection(networkManager); //#endif @@ -626,7 +638,9 @@ public class ReplayHandler { , true //#endif ); + //#if MC<11904 GlStateManager.enableTexture(); + //#endif mc.getFramebuffer().beginWrite(true); Window window = mc.getWindow(); //#if MC>=11500 diff --git a/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java b/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java index d2117cf8..560d5d4b 100644 --- a/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java +++ b/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java @@ -395,8 +395,11 @@ public class GuiPathing { public void keyframeRepoButtonPressed() { abortPathPlayback(); try { + TimelineSerialization serialization = new TimelineSerialization(mod.getCurrentTimeline(), null); + String serialized = serialization.serialize(Collections.singletonMap("", mod.getCurrentTimeline().getTimeline())); + Timeline currentTimeline = serialization.deserialize(serialized).get(""); GuiKeyframeRepository gui = new GuiKeyframeRepository( - mod.getCurrentTimeline(), replayHandler.getReplayFile(), mod.getCurrentTimeline().getTimeline()); + mod.getCurrentTimeline(), replayHandler.getReplayFile(), currentTimeline); Futures.addCallback(gui.getFuture(), new FutureCallback() { @Override public void onSuccess(Timeline result) { diff --git a/version.txt b/version.txt index a04abec9..bc02b868 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.6.10 +2.6.11 diff --git a/versions/1.18.1/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java b/versions/1.18.1/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java index 1d95dd1b..1c497b25 100644 --- a/versions/1.18.1/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java +++ b/versions/1.18.1/src/main/java/com/replaymod/replay/mixin/Mixin_FixEntityNotTracking.java @@ -20,6 +20,14 @@ public class Mixin_FixEntityNotTracking { private void updatePositionIfNotTracked(Entity entity) { if (entity != null && entity.world instanceof ClientWorldAccessor world) { if (!world.getEntityList().has(entity)) { + // This only applies to entities that are server-controlled. + // You wouldn't think this check is necessary but for some stupid reason Spigot sends entities before + // chunks, so we must not update the entity if it is being ridden by the client player because those + // will fall into the void and die (client-side only ofc). + if (entity.isLogicalSideForUpdatingMovement()) { + return; + } + // Skip interpolation of position updates coming from server // (See: newX in EntityLivingBase or otherPlayerMPX in EntityOtherPlayerMP) int ticks = 0; diff --git a/versions/1.19.4/.gitkeep b/versions/1.19.4/.gitkeep new file mode 100644 index 00000000..e69de29b