Update to 1.21.9/10

This commit is contained in:
Jonas Herzig
2025-10-12 14:37:21 +02:00
parent e6db9daf80
commit d3929cb6dc
26 changed files with 321 additions and 22 deletions

View File

@@ -40,10 +40,14 @@ import java.util.function.Consumer;
import java.util.function.Function;
public class KeyBindingRegistry extends EventRegistrations {
//#if MC>=12109
//$$ private static final KeyBinding.Category CATEGORY = KeyBinding.Category.create(identifier(MOD_ID, "general"));
//#else
private static final String CATEGORY = "replaymod.title";
//#if FABRIC>=1 && MC<11600
//$$ static { net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry.INSTANCE.addCategory(CATEGORY); }
//#endif
//#endif
private final Map<String, Binding> bindings = new HashMap<>();
private Set<KeyBinding> onlyInReplay = new HashSet<>();

View File

@@ -258,6 +258,10 @@ public class ReplayMod implements Module, Scheduler {
}
private void printToChat(boolean warning, String message, Object... args) {
if (!mc.isOnThread()) {
runLater(() -> printToChat(warning, message, args));
return;
}
if (getSettingsRegistry().get(Setting.NOTIFICATIONS)) {
// Some nostalgia: "§8[§6Replay Mod§8]§r Your message goes here"
//#if MC>=10904

View File

@@ -14,15 +14,20 @@ public class MixinKeyboardListener {
private static final String ON_KEY_PRESSED = "Lnet/minecraft/client/options/KeyBinding;onKeyPressed(Lnet/minecraft/client/util/InputUtil$Key;)V";
@Inject(method = "onKey", at = @At(value = "INVOKE", target = ON_KEY_PRESSED), cancellable = true)
//#if MC>=12109
//$$ private void beforeKeyBindingTick(long window, int action, net.minecraft.client.input.KeyInput mcKeyInput, CallbackInfo ci) {
//$$ KeyInput keyInput = new KeyInput(mcKeyInput);
//#else
private void beforeKeyBindingTick(long windowPointer, int key, int scanCode, int action, int modifiers, CallbackInfo ci) {
KeyInput keyInput = new KeyInput(key, scanCode, modifiers);
//#endif
if (KeyEventCallback.EVENT.invoker().onKeyEvent(keyInput, action)) {
ci.cancel();
}
}
@Inject(method = "onKey", at = @At(value = "INVOKE", target = ON_KEY_PRESSED, shift = At.Shift.AFTER))
private void afterKeyBindingTick(long windowPointer, int key, int scanCode, int action, int modifiers, CallbackInfo ci) {
private void afterKeyBindingTick(CallbackInfo ci) {
KeyBindingEventCallback.EVENT.invoker().onKeybindingEvent();
}
}

View File

@@ -8,6 +8,11 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
//#if MC>=12109
//$$ import net.minecraft.network.PacketApplyBatcher;
//$$ import org.spongepowered.asm.mixin.Final;
//#endif
//#if MC>=11400
import com.replaymod.core.events.PostRenderCallback;
import com.replaymod.core.events.PreRenderCallback;
@@ -42,8 +47,14 @@ public abstract class MixinMinecraft
}
//#if MC>=11400
//#if MC>=12109
//$$ @Shadow @Final private PacketApplyBatcher packetApplyBatcher;
//#endif
@Override
public void replayModExecuteTaskQueue() {
//#if MC>=12109
//$$ this.packetApplyBatcher.apply();
//#endif
runTasks();
}
//#endif

View File

@@ -68,6 +68,11 @@ import java.util.function.Consumer;
import static com.replaymod.core.versions.MCVer.getMinecraft;
//#if MC>=12109
//$$ import com.replaymod.core.versions.MCVer.Keyboard;
//$$ import net.minecraft.client.input.SystemKeycodes;
//#endif
//#if MC>=12100
//$$ import net.minecraft.util.crash.ReportType;
//#endif
@@ -229,7 +234,9 @@ public class Utils {
}
public static boolean isCtrlDown() {
//#if MC>=11400
//#if MC>=12109
//$$ return Keyboard.isKeyDown(SystemKeycodes.LEFT_CTRL) || Keyboard.isKeyDown(SystemKeycodes.RIGHT_CTRL);
//#elseif MC>=11400
return Screen.hasControlDown();
//#else
//$$ return Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);

View File

@@ -190,6 +190,11 @@ public class LangResourcePack extends AbstractFileResourcePack {
key = String.format(FABRIC_KEY_FORMAT, key.substring(LEGACY_KEY_PREFIX.length()));
}
//#endif
//#if MC>=12109
if (key.equals("replaymod.title")) {
properties.put("key.category.replaymod.general", value);
}
//#endif
properties.put(key, value);
}

View File

@@ -622,7 +622,9 @@ public class MCVer {
//#endif
public static boolean isKeyDown(int keyCode) {
//#if MC>=11500
//#if MC>=12109
//$$ return InputUtil.isKeyPressed(getMinecraft().getWindow(), keyCode);
//#elseif MC>=11500
return InputUtil.isKeyPressed(getMinecraft().getWindow().getHandle(), keyCode);
//#else
//#if MC>=11400

View File

@@ -982,7 +982,9 @@ class Patterns {
@Pattern
public Identifier getSkinTexture(AbstractClientPlayerEntity player) {
//#if MC>=12002
//#if MC>=12109
//$$ return player.getSkin().body().texturePath();
//#elseif MC>=12002
//$$ return player.getSkinTextures().texture();
//#else
return player.getSkinTexture();

View File

@@ -191,7 +191,21 @@ public class PacketListener extends ChannelInboundHandlerAdapter {
// Otherwise, injected packets may end up further down the packet stream than they were supposed to and other
// inbound packets which may rely on the injected packet would behave incorrectly when played back.
if (!mc.isOnThread()) {
// Note that we must use the same queue as regular packets, otherwise stuff will be out of order!
//#if MC>=12109
//$$ mc.getPacketApplyBatcher().add(channel.pipeline().get(ClientConnection.class).getPacketListener(), new net.minecraft.network.packet.Packet<>() {
//$$ @Override
//$$ public net.minecraft.network.packet.PacketType<? extends net.minecraft.network.packet.Packet<net.minecraft.network.listener.PacketListener>> getPacketType() {
//$$ return null;
//$$ }
//$$ @Override
//$$ public void apply(net.minecraft.network.listener.PacketListener listener) {
//$$ save(packet);
//$$ }
//$$ });
//#else
mc.send(() -> save(packet));
//#endif
return;
}
try {

View File

@@ -40,6 +40,10 @@ import net.minecraft.util.crash.CrashException;
import net.minecraft.sound.SoundCategory;
import org.lwjgl.glfw.GLFW;
//#if MC>=12109
//$$ import net.minecraft.client.gui.screen.Overlay;
//#endif
//#if MC>=12106
//$$ import com.replaymod.render.mixin.GameRendererAccessor;
//$$ import net.minecraft.client.gui.render.GuiRenderer;
@@ -335,13 +339,18 @@ public class VideoRenderer implements RenderInfo {
//$$ Display.setResizable(false);
//$$ }
//#endif
//#if MC>=12109
//$$ if (mc.debugHudEntryList.isF3Enabled()) {
//$$ mc.debugHudEntryList.setF3Enabled(false);
//#else
if (mc.options.debugEnabled) {
debugInfoWasShown = true;
//#if MC>=12002
//$$ mc.getDebugHud().toggleDebugHud();
//#else
mc.options.debugEnabled = false;
//#endif
//#endif
debugInfoWasShown = true;
}
//#if MC>=11400
if (mc.mouse.isCursorLocked()) {
@@ -406,7 +415,9 @@ public class VideoRenderer implements RenderInfo {
//$$ }
//#endif
if (debugInfoWasShown) {
//#if MC>=12002
//#if MC>=12109
//$$ mc.debugHudEntryList.setF3Enabled(true);
//#elseif MC>=12002
//$$ mc.getDebugHud().toggleDebugHud();
//#else
mc.options.debugEnabled = true;
@@ -453,6 +464,15 @@ public class VideoRenderer implements RenderInfo {
while (mc.getOverlay() != null) {
drawGui();
((MinecraftMethodAccessor) mc).replayModExecuteTaskQueue();
//#if MC>=12109
//$$ // The SplashOverlay now only closes on `tick`, but there are no ticks while we're waiting,
//$$ // so we need to manually tick it to not get stuck.
//$$ Overlay overlay = mc.getOverlay();
//$$ if (overlay != null) {
//$$ overlay.tick();
//$$ }
//#endif
}
CompletableFuture<Void> resourceReloadFuture = ((MinecraftAccessor) mc).getResourceReloadFuture();

View File

@@ -23,7 +23,6 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.OtherClientPlayerEntity;
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
import net.minecraft.client.gui.screen.NoticeScreen;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
@@ -56,6 +55,17 @@ import net.minecraft.util.math.Vec3d;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
//#if MC>=12109
//$$ import net.minecraft.network.ClientConnection;
//$$ import net.minecraft.network.listener.PacketListener;
//#endif
//#if MC>=12109
//$$ import net.minecraft.client.gui.screen.world.LevelLoadingScreen;
//#else
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
//#endif
//#if MC>=12105
//#else
import net.minecraft.network.packet.s2c.play.ExperienceOrbSpawnS2CPacket;
@@ -853,7 +863,11 @@ public class FullReplaySender extends ChannelInboundHandlerAdapter implements Re
if(!hasWorldLoaded) hasWorldLoaded = true;
ReplayMod.instance.runLater(() -> {
//#if MC>=12109
//$$ if (mc.currentScreen instanceof LevelLoadingScreen) {
//#else
if (mc.currentScreen instanceof DownloadingTerrainScreen) {
//#endif
// Close the world loading screen manually in case we swallow the packet
mc.openScreen(null);
}
@@ -969,7 +983,7 @@ public class FullReplaySender extends ChannelInboundHandlerAdapter implements Re
return processPacketAsync(p);
} else {
Packet fp = p;
mc.send(() -> processPacketSync(fp));
schedulePacketHandler(() -> processPacketSync(fp));
return p;
}
}
@@ -1383,7 +1397,18 @@ public class FullReplaySender extends ChannelInboundHandlerAdapter implements Re
if (mc.isOnThread()) {
runnable.run();
} else {
//#if MC>=11400
//#if MC>=12109
//$$ mc.getPacketApplyBatcher().add(channel.pipeline().get(ClientConnection.class).getPacketListener(), new Packet<>() {
//$$ @Override
//$$ public net.minecraft.network.packet.PacketType<? extends Packet<PacketListener>> getPacketType() {
//$$ return null;
//$$ }
//$$ @Override
//$$ public void apply(PacketListener listener) {
//$$ runnable.run();
//$$ }
//$$ });
//#elseif MC>=11400
mc.execute(runnable);
//#else
//$$ mc.addScheduledTask(runnable);

View File

@@ -7,9 +7,17 @@ import com.replaymod.replay.camera.CameraEntity;
import de.johni0702.minecraft.gui.versions.ScreenExt;
import net.minecraft.client.MinecraftClient;
//#if MC>=12109
//$$ import net.minecraft.client.gui.screen.Overlay;
//#endif
//#if MC>=12109
//$$ import net.minecraft.client.gui.screen.world.LevelLoadingScreen;
//#else
//#if MC>=11802
//$$ import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
//#endif
//#endif
//#if MC>=11400
import org.lwjgl.glfw.GLFW;
@@ -92,11 +100,23 @@ public class InputReplayTimer {
//#if MC>=11802
//$$ // As of 1.18.2, this screen always stays open for at least two seconds, and requires ticking to close.
//$$ // Thanks, but we'll have none of that (at least while in a replay).
//#if MC>=12109
//$$ if (mc.currentScreen instanceof LevelLoadingScreen) {
//#else
//$$ if (mc.currentScreen instanceof DownloadingTerrainScreen) {
//#endif
//$$ mc.currentScreen.close();
//$$ }
//#endif
//#if MC>=12109
//$$ // The SplashOverlay now only closes on `tick`, but there are no ticks while the replay is paused.
//$$ // so we need to manually tick it to not get stuck.
//$$ Overlay overlay = mc.getOverlay();
//$$ if (overlay != null) {
//$$ overlay.tick();
//$$ }
//#endif
}
}

View File

@@ -31,7 +31,6 @@ import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.channel.embedded.EmbeddedChannel;
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.DecoderHandler;
@@ -45,6 +44,12 @@ import net.minecraft.network.ClientConnection;
import java.io.IOException;
import java.util.*;
//#if MC>=12109
//$$ import net.minecraft.client.gui.screen.world.LevelLoadingScreen;
//#else
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
//#endif
//#if MC>=12106
//$$ import com.replaymod.render.mixin.GameRendererAccessor;
//$$ import net.minecraft.client.gui.render.state.GuiRenderState;
@@ -373,7 +378,11 @@ public class ReplayHandler {
// We don't send any packets (there is no server to receive them), so we need to switch manually.
//#if MC>=12006
//$$ networkManager.transitionInbound(LoginStates.S2C, new ClientLoginNetworkHandler(
//$$ networkManager, mc, null, null, false, null, it -> {}, null
//$$ networkManager, mc, null, null, false, null, it -> {},
//#if MC>=12109
//$$ new net.minecraft.client.world.ClientChunkLoadProgress(),
//#endif
//$$ null
//$$ ));
//$$ networkManager.transitionOutbound(LoginStates.C2S);
//#else
@@ -697,7 +706,11 @@ public class ReplayHandler {
do {
replaySender.sendPacketsTill(targetTime);
targetTime += 500;
//#if MC>=12109
//$$ } while (mc.player == null || mc.currentScreen instanceof LevelLoadingScreen);
//#else
} while (mc.player == null || mc.currentScreen instanceof DownloadingTerrainScreen);
//#endif
replaySender.setAsyncMode(true);
for (int i = 0; i < Math.min(diff / 50, 3); i++) {
@@ -852,7 +865,11 @@ public class ReplayHandler {
do {
replaySender.sendPacketsTill(targetTime);
targetTime += 500;
//#if MC>=12109
//$$ } while (mc.player == null || mc.currentScreen instanceof LevelLoadingScreen);
//#else
} while (mc.player == null || mc.currentScreen instanceof DownloadingTerrainScreen);
//#endif
replaySender.setAsyncMode(true);
replaySender.setReplaySpeed(0);

View File

@@ -30,6 +30,12 @@ import net.minecraft.item.ItemStack;
import net.minecraft.stat.StatHandler;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Box;
import net.minecraft.world.World;
//#if MC>=12109
//$$ import net.minecraft.client.network.ClientPlayerLikeEntity;
//$$ import net.minecraft.entity.PlayerLikeEntity;
//#endif
//#if MC>=12106
//$$ import net.minecraft.util.PlayerInput;
@@ -322,15 +328,18 @@ public class CameraEntity
// This is important if the spectated player respawns as their
// entity is recreated and we have to spectate a new entity
UUID spectating = ReplayModReplay.instance.getReplayHandler().getSpectatedUUID();
// FIXME remap bug: Pattern doesn't work when these two are inlined
World cameraWorld = this.world;
World viewWorld = view.world;
if (spectating != null && (view.getUuid() != spectating
|| view.world != this.world)
|| this.world.getEntityById(view.getEntityId()) != view) {
|| viewWorld != cameraWorld)
|| cameraWorld.getEntityById(view.getEntityId()) != view) {
if (spectating == null) {
// Entity (non-player) died, stop spectating
ReplayModReplay.instance.getReplayHandler().spectateEntity(this);
return;
}
view = this.world.getPlayerByUuid(spectating);
view = cameraWorld.getPlayerByUuid(spectating);
if (view != null) {
this.client.setCameraEntity(view);
} else {
@@ -502,7 +511,16 @@ public class CameraEntity
return super.isInvisible();
}
//#if MC>=12002
//#if MC>=12109
//$$ @Override
//$$ public SkinTextures getSkin() {
//$$ Entity view = this.client.getCameraEntity();
//$$ if (view != this && view instanceof ClientPlayerLikeEntity) {
//$$ return ((ClientPlayerLikeEntity) view).getSkin();
//$$ }
//$$ return super.getSkin();
//$$ }
//#elseif MC>=12002
//$$ @Override
//$$ public SkinTextures getSkinTextures() {
//$$ Entity view = this.client.getCameraEntity();
@@ -533,7 +551,16 @@ public class CameraEntity
//#endif
//#endif
//#if MC>=10800
//#if MC>=12109
//$$ @Override
//$$ public boolean isModelPartVisible(PlayerModelPart modelPart) {
//$$ Entity view = this.client.getCameraEntity();
//$$ if (view != this && view instanceof PlayerLikeEntity) {
//$$ return ((PlayerLikeEntity) view).isModelPartVisible(modelPart);
//$$ }
//$$ return super.isModelPartVisible(modelPart);
//$$ }
//#elseif MC>=10800
@Override
public boolean isPartVisible(PlayerModelPart modelPart) {
Entity view = this.client.getCameraEntity();