diff --git a/build.gradle b/build.gradle index 813b9460..2bbff83a 100644 --- a/build.gradle +++ b/build.gradle @@ -265,6 +265,7 @@ dependencies { 11904: '1.19.4', 12001: '1.20.1', 12002: '1.20.2', + 12003: '1.20.3-rc1', ][mcVersion] mappings 'net.fabricmc:yarn:' + [ 11404: '1.14.4+build.16', @@ -283,6 +284,7 @@ dependencies { 11904: '1.19.4+build.1:v2', 12001: '1.20.1+build.2:v2', 12002: '1.20.2+build.4:v2', + 12003: '1.20.3-rc1+build.2:v2', ][mcVersion] modImplementation 'net.fabricmc:fabric-loader:0.14.11' def fabricApiVersion = [ @@ -302,6 +304,7 @@ dependencies { 11904: '0.76.0+1.19.4', 12001: '0.83.1+1.20.1', 12002: '0.90.7+1.20.2', + 12003: '0.91.1+1.20.3', ][mcVersion] def fabricApiModules = [ "api-base", @@ -382,7 +385,7 @@ dependencies { shadow 'com.github.ReplayMod.JavaBlend:2.79.0:a0696f8' - shadow "com.github.ReplayMod:ReplayStudio:e7a8ff7", shadeExclusions + shadow "com.github.ReplayMod:ReplayStudio:5052121", 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) @@ -393,7 +396,9 @@ dependencies { shadow 'com.github.ReplayMod:lwjgl-utils:27dcd66' if (FABRIC) { - if (mcVersion >= 12002) { + if (mcVersion >= 12003) { + modImplementation 'com.terraformersmc:modmenu:9.0.0-pre.1' + } else if (mcVersion >= 12002) { modImplementation 'com.terraformersmc:modmenu:8.0.0' } else if (mcVersion >= 12000) { modImplementation 'com.terraformersmc:modmenu:7.0.1' diff --git a/jGui b/jGui index d4f6bc60..b4a618ae 160000 --- a/jGui +++ b/jGui @@ -1 +1 @@ -Subproject commit d4f6bc60c9f4368a4db1465465dfd1b9d2a06430 +Subproject commit b4a618aef9f4a9260e8bb75368d75d95b6a72e0c diff --git a/root.gradle.kts b/root.gradle.kts index 632364cd..cef238dd 100755 --- a/root.gradle.kts +++ b/root.gradle.kts @@ -193,6 +193,7 @@ val doRelease by tasks.registering { defaultTasks("bundleJar") preprocess { + val mc12003 = createNode("1.20.3", 12003, "yarn") val mc12002 = createNode("1.20.2", 12002, "yarn") val mc12001 = createNode("1.20.1", 12001, "yarn") val mc11904 = createNode("1.19.4", 11904, "yarn") @@ -219,6 +220,7 @@ preprocess { val mc10800 = createNode("1.8", 10800, "srg") val mc10710 = createNode("1.7.10", 10710, "srg") + mc12003.link(mc12002, file("versions/mapping-fabric-1.20.3-1.20.2.txt")) mc12002.link(mc12001) mc12001.link(mc11904) mc11904.link(mc11903) diff --git a/settings.gradle.kts b/settings.gradle.kts index 05dbe159..3ab38e6b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -39,6 +39,7 @@ val jGuiVersions = listOf( "1.19.4", "1.20.1", "1.20.2", + "1.20.3", ) val replayModVersions = listOf( // "1.7.10", @@ -66,6 +67,7 @@ val replayModVersions = listOf( "1.19.4", "1.20.1", "1.20.2", + "1.20.3", ) rootProject.buildFileName = "root.gradle.kts" diff --git a/src/main/java/com/replaymod/core/utils/WrappedTimer.java b/src/main/java/com/replaymod/core/utils/WrappedTimer.java index 2db83188..754db425 100644 --- a/src/main/java/com/replaymod/core/utils/WrappedTimer.java +++ b/src/main/java/com/replaymod/core/utils/WrappedTimer.java @@ -9,7 +9,9 @@ public class WrappedTimer extends RenderTickCounter { protected final RenderTickCounter wrapped; public WrappedTimer(RenderTickCounter wrapped) { - //#if MC>=11400 + //#if MC>=12003 + //$$ super(0, 0, f -> f); + //#elseif MC>=11400 super(0, 0); //#else //$$ super(0); diff --git a/src/main/java/com/replaymod/core/versions/MCVer.java b/src/main/java/com/replaymod/core/versions/MCVer.java index a8cbb328..44e64f14 100644 --- a/src/main/java/com/replaymod/core/versions/MCVer.java +++ b/src/main/java/com/replaymod/core/versions/MCVer.java @@ -168,6 +168,7 @@ public class MCVer { //$$ } //#endif + //#if MC<12003 public static //#if MC>=11400 CompletableFuture @@ -195,6 +196,7 @@ public class MCVer { //#endif //#endif } + //#endif public static void addCallback( //#if MC>=11400 diff --git a/src/main/java/com/replaymod/pathing/player/ReplayTimer.java b/src/main/java/com/replaymod/pathing/player/ReplayTimer.java index 30d5f462..d970cb05 100644 --- a/src/main/java/com/replaymod/pathing/player/ReplayTimer.java +++ b/src/main/java/com/replaymod/pathing/player/ReplayTimer.java @@ -8,7 +8,9 @@ import net.minecraft.client.render.RenderTickCounter; * Wrapper around the current timer that prevents the timer from advancing by itself. */ public class ReplayTimer extends WrappedTimer { - //#if MC>=11400 + //#if MC>=12003 + //$$ private final RenderTickCounter state = new RenderTickCounter(0, 0, f -> f); + //#elseif MC>=11400 private final RenderTickCounter state = new RenderTickCounter(0, 0); //#else //$$ private final Timer state = new Timer(0); diff --git a/src/main/java/com/replaymod/recording/packet/PacketListener.java b/src/main/java/com/replaymod/recording/packet/PacketListener.java index 6f06a823..1cd11622 100644 --- a/src/main/java/com/replaymod/recording/packet/PacketListener.java +++ b/src/main/java/com/replaymod/recording/packet/PacketListener.java @@ -92,16 +92,24 @@ public class PacketListener extends ChannelInboundHandlerAdapter { private static final MinecraftClient mc = getMinecraft(); private static final Logger logger = LogManager.getLogger(); + private static final ResourcePackSendS2CPacket RESOURCE_PACK_SEND_PACKET = + //#if MC>=12003 + //$$ new ResourcePackSendS2CPacket(null, "", "", false, null) + //#elseif MC>=11700 + //$$ new ResourcePackSendS2CPacket("", "", false, null) + //#else + new ResourcePackSendS2CPacket() + //#endif + ; + private static final int PACKET_ID_RESOURCE_PACK_SEND = getPacketId(NetworkState.PLAY, RESOURCE_PACK_SEND_PACKET); + //#if MC>=12002 + //$$ private static final int PACKET_ID_CONFIG_RESOURCE_PACK_SEND = getPacketId(NetworkState.CONFIGURATION, RESOURCE_PACK_SEND_PACKET); + //#endif //#if MC>=11700 - //$$ private static final int PACKET_ID_RESOURCE_PACK_SEND = getPacketId(NetworkState.PLAY, new ResourcePackSendS2CPacket("", "", false, null)); //$$ private static final int PACKET_ID_LOGIN_COMPRESSION = getPacketId(NetworkState.LOGIN, new LoginCompressionS2CPacket(0)); //#else - private static final int PACKET_ID_RESOURCE_PACK_SEND = getPacketId(NetworkState.PLAY, new ResourcePackSendS2CPacket()); private static final int PACKET_ID_LOGIN_COMPRESSION = getPacketId(NetworkState.LOGIN, new LoginCompressionS2CPacket()); //#endif - //#if MC>=12002 - //$$ private static final int PACKET_ID_CONFIG_RESOURCE_PACK_SEND = getPacketId(NetworkState.CONFIGURATION, new ResourcePackSendS2CPacket("", "", false, null)); - //#endif //#if MC<10904 //$$ private static final int PACKET_ID_PLAY_COMPRESSION = getPacketId(EnumConnectionState.PLAY, new S46PacketSetCompressionLevel()); //#endif @@ -388,6 +396,9 @@ public class PacketListener extends ChannelInboundHandlerAdapter { ) { ClientConnection connection = ctx.pipeline().get(ClientConnection.class); save(resourcePackRecorder.handleResourcePack(connection, (ResourcePackSendS2CPacket) decodeMcPacket(packet))); + //#if MC>=12003 + //$$ super.channelRead(ctx, msg); + //#endif return; } @@ -516,6 +527,10 @@ public class PacketListener extends ChannelInboundHandlerAdapter { this.serverWasPaused = true; } + public ResourcePackRecorder getResourcePackRecorder() { + return resourcePackRecorder; + } + private class DecodedPacketListener extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { diff --git a/src/main/java/com/replaymod/recording/packet/ResourcePackRecorder.java b/src/main/java/com/replaymod/recording/packet/ResourcePackRecorder.java index 01fd26c9..1d2fc815 100644 --- a/src/main/java/com/replaymod/recording/packet/ResourcePackRecorder.java +++ b/src/main/java/com/replaymod/recording/packet/ResourcePackRecorder.java @@ -1,7 +1,6 @@ package com.replaymod.recording.packet; import com.google.common.hash.Hashing; -import com.google.common.io.Files; import com.replaymod.replaystudio.replay.ReplayFile; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ConfirmScreen; @@ -11,6 +10,10 @@ import net.minecraft.client.resource.ClientBuiltinResourcePackProvider; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +//#if MC>=12003 +//$$ import java.util.UUID; +//#endif + //#if MC>=11900 //$$ import java.net.MalformedURLException; //$$ import java.net.URL; @@ -55,6 +58,8 @@ import net.minecraft.network.ClientConnection; import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.HashMap; import java.util.Map; @@ -75,10 +80,10 @@ public class ResourcePackRecorder { this.replayFile = replayFile; } - public void recordResourcePack(File file, int requestId) { + public void recordResourcePack(Path file, int requestId) { try { // Read in resource pack file - byte[] bytes = Files.toByteArray(file); + byte[] bytes = Files.readAllBytes(file); // Check whether it is already known String hash = Hashing.sha1().hashBytes(bytes).toString(); boolean doWrite = false; // Whether we are the first and have to write it @@ -105,7 +110,24 @@ public class ResourcePackRecorder { } } - //#if MC>=10800 + //#if MC>=12003 + //$$ private final Map mcIdToReplayId = new HashMap<>(); + //$$ + //$$ public synchronized ResourcePackSendS2CPacket handleResourcePack(ClientConnection netManager, ResourcePackSendS2CPacket packet) { + //$$ final int requestId = nextRequestId++; + //$$ mcIdToReplayId.put(packet.id(), requestId); + //$$ return new ResourcePackSendS2CPacket(packet.id(), "replay://" + requestId, "", packet.required(), packet.prompt()); + //$$ } + //$$ + //$$ public void recordResourcePack(Path file, UUID uuid) { + //$$ Integer id = mcIdToReplayId.get(uuid); + //$$ if (id == null) { + //$$ logger.warn("Got resource pack download for unexpected uuid " + uuid + " at " + file); + //$$ return; + //$$ } + //$$ recordResourcePack(file, id); + //$$ } + //#elseif MC>=10800 public ResourcePackStatusC2SPacket makeStatusPacket(String hash, Status action) { //#if MC>=11002 return new ResourcePackStatusC2SPacket(action); @@ -128,7 +150,7 @@ public class ResourcePackRecorder { if (levelDir.isFile()) { netManager.send(makeStatusPacket(hash, Status.ACCEPTED)); addCallback(setServerResourcePack(levelDir), result -> { - recordResourcePack(levelDir, requestId); + recordResourcePack(levelDir.toPath(), requestId); netManager.send(makeStatusPacket(hash, Status.SUCCESSFULLY_LOADED)); }, throwable -> { netManager.send(makeStatusPacket(hash, Status.FAILED_DOWNLOAD)); @@ -196,7 +218,7 @@ public class ResourcePackRecorder { //#endif downloadResourcePack(final int requestId, String url, String hash) { ClientBuiltinResourcePackProvider packFinder = mc.getResourcePackDownloader(); - ((IDownloadingPackFinder) packFinder).setRequestCallback(file -> recordResourcePack(file, requestId)); + ((IDownloadingPackFinder) packFinder).setRequestCallback(file -> recordResourcePack(file.toPath(), requestId)); //#if MC>=11900 //$$ try { //$$ URL theUrl = new URL(url); @@ -286,7 +308,7 @@ public class ResourcePackRecorder { //$$ acc.setActive(false); //$$ acc.setPack(new FileResourcePack(file)); //$$ Minecraft.getMinecraft().scheduleResourcesRefresh(); - //$$ recordResourcePack(file, requestId); + //$$ recordResourcePack(file.toPath(), requestId); //$$ } //$$ } //$$ }, hashmap, 50*1024*1024, guiScreen, Minecraft.getMinecraft().getProxy()); diff --git a/src/main/java/com/replaymod/render/mixin/Mixin_BlockOnChunkRebuilds.java b/src/main/java/com/replaymod/render/mixin/Mixin_BlockOnChunkRebuilds.java index fdbdd826..579e3268 100644 --- a/src/main/java/com/replaymod/render/mixin/Mixin_BlockOnChunkRebuilds.java +++ b/src/main/java/com/replaymod/render/mixin/Mixin_BlockOnChunkRebuilds.java @@ -9,6 +9,7 @@ import net.minecraft.util.thread.TaskExecutor; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -20,12 +21,28 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +//#if MC>=12003 +//$$ import net.minecraft.client.render.chunk.BlockBufferBuilderPool; +//#endif + @Mixin(ChunkBuilder.class) public abstract class Mixin_BlockOnChunkRebuilds implements ForceChunkLoadingHook.IBlockOnChunkRebuilds { + //#if MC>=12003 + //$$ @Shadow @Final private BlockBufferBuilderPool buffersPool; + //$$ @Unique + //$$ private int getAvailableBufferCount() { + //$$ return this.buffersPool.getAvailableBuilderCount(); + //$$ } + //#else @Shadow @Final private Queue threadBuffers; + @Unique + private int getAvailableBufferCount() { + return threadBuffers.size(); + } + //#endif //#if MC>=11800 - //$$ @org.spongepowered.asm.mixin.Unique + //$$ @Unique //$$ private boolean upload() { //$$ boolean anything = false; //$$ Runnable runnable; @@ -52,12 +69,12 @@ public abstract class Mixin_BlockOnChunkRebuilds implements ForceChunkLoadingHoo @Inject(method = "", at = @At("RETURN")) private void rememberTotalThreads(CallbackInfo ci) { - this.totalBufferCount = this.threadBuffers.size(); + this.totalBufferCount = getAvailableBufferCount(); } @Inject(method = "scheduleRunTasks", at = @At("RETURN")) private void notifyMainThreadIfEverythingIsDone(CallbackInfo ci) { - if (this.threadBuffers.size() == this.totalBufferCount) { + if (getAvailableBufferCount() == this.totalBufferCount) { // Looks like we're done, better notify the main thread in case the previous task didn't generate an upload this.waitingForWorkLock.lock(); try { @@ -84,7 +101,7 @@ public abstract class Mixin_BlockOnChunkRebuilds implements ForceChunkLoadingHoo private boolean waitForMainThreadWork() { boolean allDone = this.mailbox.ask(reply -> () -> { scheduleRunTasks(); - reply.send(this.threadBuffers.size() == this.totalBufferCount); + reply.send(getAvailableBufferCount() == this.totalBufferCount); }).join(); if (allDone) { diff --git a/src/main/java/com/replaymod/replay/FullReplaySender.java b/src/main/java/com/replaymod/replay/FullReplaySender.java index 7272c7a4..39ea79ec 100644 --- a/src/main/java/com/replaymod/replay/FullReplaySender.java +++ b/src/main/java/com/replaymod/replay/FullReplaySender.java @@ -655,7 +655,11 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend if(p instanceof ResourcePackSendS2CPacket) { ResourcePackSendS2CPacket packet = (ResourcePackSendS2CPacket) p; + //#if MC>=12003 + //$$ String url = packet.url(); + //#else String url = packet.getURL(); + //#endif if (url.startsWith("replay://")) { //#else //$$ String url; @@ -671,7 +675,11 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend if (!file.exists()) { IOUtils.copy(replayFile.getResourcePack(hash).get(), new FileOutputStream(file)); } + //#if MC>=12003 + //$$ mc.getServerResourcePackProvider().addResourcePack(packet.id(), file.toPath()); + //#else setServerResourcePack(file); + //#endif } } return null; diff --git a/src/main/java/com/replaymod/replay/ReplayHandler.java b/src/main/java/com/replaymod/replay/ReplayHandler.java index c0475556..15b14a57 100644 --- a/src/main/java/com/replaymod/replay/ReplayHandler.java +++ b/src/main/java/com/replaymod/replay/ReplayHandler.java @@ -42,6 +42,10 @@ import net.minecraft.network.ClientConnection; import java.io.IOException; import java.util.*; +//#if MC>=12003 +//$$ import net.minecraft.client.resource.server.ServerResourcePackManager; +//#endif + //#if MC>=12002 //$$ import io.netty.channel.ChannelDuplexHandler; //$$ import io.netty.channel.ChannelPromise; @@ -355,6 +359,10 @@ public class ReplayHandler { //#if MC>=11400 ((MinecraftAccessor) mc).setConnection(networkManager); //#endif + + //#if MC>=12003 + //$$ mc.getServerResourcePackProvider().init(networkManager, ServerResourcePackManager.AcceptanceStatus.ALLOWED); + //#endif } public ReplayFile getReplayFile() { diff --git a/versions/1.20.3/src/main/java/com/replaymod/recording/mixin/MixinDownloadingPackFinder.java b/versions/1.20.3/src/main/java/com/replaymod/recording/mixin/MixinDownloadingPackFinder.java new file mode 100644 index 00000000..7dc67921 --- /dev/null +++ b/versions/1.20.3/src/main/java/com/replaymod/recording/mixin/MixinDownloadingPackFinder.java @@ -0,0 +1,29 @@ +package com.replaymod.recording.mixin; + +import com.replaymod.recording.ReplayModRecording; +import com.replaymod.recording.packet.PacketListener; +import net.minecraft.client.resource.server.ServerResourcePackManager; +import net.minecraft.util.Downloader; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Coerce; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.nio.file.Path; +import java.util.Map; +import java.util.UUID; + +@Mixin(ServerResourcePackManager.class) +public abstract class MixinDownloadingPackFinder { + @Inject(method = "onDownload", at = @At("HEAD")) + private void recordDownloadedPack(@Coerce Object packs, Downloader.DownloadResult result, CallbackInfo ci) { + PacketListener packetListener = ReplayModRecording.instance.getConnectionEventHandler().getPacketListener(); + if (packetListener == null) { + return; + } + for (Map.Entry entry : result.downloaded().entrySet()) { + packetListener.getResourcePackRecorder().recordResourcePack(entry.getValue(), entry.getKey()); + } + } +} diff --git a/versions/mapping-fabric-1.20.3-1.20.2.txt b/versions/mapping-fabric-1.20.3-1.20.2.txt index e69de29b..91036156 100644 --- a/versions/mapping-fabric-1.20.3-1.20.2.txt +++ b/versions/mapping-fabric-1.20.3-1.20.2.txt @@ -0,0 +1 @@ +net.minecraft.text.PlainTextContent net.minecraft.text.LiteralTextContent