Release 2.6.7

This commit is contained in:
Jonas Herzig
2022-07-31 13:46:49 +02:00
22 changed files with 123 additions and 138 deletions

View File

@@ -35,7 +35,7 @@ It has by now acquired a lot more sophisticated features to make it as noninvasi
Please read the [preprocessor's README](https://github.com/ReplayMod/preprocessor/blob/master/README.md) to understand how it works. Please read the [preprocessor's README](https://github.com/ReplayMod/preprocessor/blob/master/README.md) to understand how it works.
### Versioning ### Versioning
The ReplayMod uses the versioning scheme outlined [here](http://mcforge.readthedocs.io/en/latest/conventions/versioning/) The ReplayMod uses the versioning scheme outlined [here](https://docs.minecraftforge.net/en/1.12.x/conventions/versioning/)
with three changes: with three changes:
- No `MAJORAPI`, the ReplayMod does not provide any external API - No `MAJORAPI`, the ReplayMod does not provide any external API
- "Updating to a new Minecraft version" should not increment `MAJORMOD`, we maintain one version of the ReplayMod - "Updating to a new Minecraft version" should not increment `MAJORMOD`, we maintain one version of the ReplayMod

View File

@@ -249,6 +249,7 @@ dependencies {
11801: '1.18.1', 11801: '1.18.1',
11802: '1.18.2', 11802: '1.18.2',
11900: '1.19', 11900: '1.19',
11901: '1.19.1',
][mcVersion] ][mcVersion]
mappings 'net.fabricmc:yarn:' + [ mappings 'net.fabricmc:yarn:' + [
11404: '1.14.4+build.16', 11404: '1.14.4+build.16',
@@ -262,6 +263,7 @@ dependencies {
11801: '1.18.1+build.1:v2', 11801: '1.18.1+build.1:v2',
11802: '1.18.2+build.1:v2', 11802: '1.18.2+build.1:v2',
11900: '1.19+build.2:v2', 11900: '1.19+build.2:v2',
11901: '1.19.1+build.5:v2',
][mcVersion] ][mcVersion]
modImplementation 'net.fabricmc:fabric-loader:0.14.6' modImplementation 'net.fabricmc:fabric-loader:0.14.6'
def fabricApiVersion = [ def fabricApiVersion = [
@@ -276,6 +278,7 @@ dependencies {
11801: '0.43.1+1.18', 11801: '0.43.1+1.18',
11802: '0.47.9+1.18.2', 11802: '0.47.9+1.18.2',
11900: '0.55.3+1.19', 11900: '0.55.3+1.19',
11901: '0.58.5+1.19.1',
][mcVersion] ][mcVersion]
def fabricApiModules = [ def fabricApiModules = [
"api-base", "api-base",
@@ -348,7 +351,7 @@ dependencies {
shadow 'com.github.ReplayMod.JavaBlend:2.79.0:a0696f8' shadow 'com.github.ReplayMod.JavaBlend:2.79.0:a0696f8'
shadow "com.github.ReplayMod:ReplayStudio:74d8465", shadeExclusions shadow "com.github.ReplayMod:ReplayStudio:b2c999d", shadeExclusions
// FIXME this should be pulled in by ReplayStudio, and IntelliJ sees it, but javac for some reason does not // 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) implementation 'com.github.viaversion:opennbt:0a02214' // 2.0-SNAPSHOT (ViaVersion Edition)
@@ -359,8 +362,10 @@ dependencies {
shadow 'com.github.ReplayMod:lwjgl-utils:27dcd66' shadow 'com.github.ReplayMod:lwjgl-utils:27dcd66'
if (FABRIC) { if (FABRIC) {
if (mcVersion >= 11900) { if (mcVersion >= 11901) {
modCompileOnly 'com.terraformersmc:modmenu:3.1.0' // FIXME update modImplementation 'com.terraformersmc:modmenu:4.0.5'
} else if (mcVersion >= 11900) {
modImplementation 'com.terraformersmc:modmenu:4.0.4'
} else if (mcVersion >= 11802) { } else if (mcVersion >= 11802) {
modImplementation 'com.terraformersmc:modmenu:3.1.0' modImplementation 'com.terraformersmc:modmenu:3.1.0'
} else if (mcVersion >= 11800) { } else if (mcVersion >= 11800) {

View File

@@ -582,7 +582,10 @@ In General, the Replay Mod _should_ be compatible with most Forge and Fabric Mod
### Shaders Mod [shaders] ### Shaders Mod [shaders]
_Karyonix' Shaders Mod_ is no longer compatible with Minecraft Forge starting with 1.9.4. As such it is not compatible with the Replay Mod either. _Karyonix' Shaders Mod_ is no longer compatible with Minecraft Forge starting with 1.9.4. As such it is not compatible with the Replay Mod either.
Please use _Optifine_ instead.
Below Minecraft 1.16 you can try _Optifine_ instead. Note however, that official support has ended and many versions break ReplayMod.
On Minecraft 1.16.5 and up you can use _Iris_, which is fully supported. For the time being, you will have to use it with the custom _Sodium_ provided on our download page. The fix it includes is pending for the official version.
### Custom Main Menu [custom-main-menu] ### Custom Main Menu [custom-main-menu]
The _Custom Main Menu_ mod is often used in mod packs to customize their Main Menu with a button layout fitting the background image, links to their website / bug tracker and similar. The _Custom Main Menu_ mod is often used in mod packs to customize their Main Menu with a button layout fitting the background image, links to their website / bug tracker and similar.
@@ -619,7 +622,7 @@ The _Baritone_ mod can cause a crash when you're trying to load a replay. If you
Minecraft may crash if you try to use _RandomPatches_ together with ReplayMod. Try removing RandomPatches if Minecraft crashes on startup. Minecraft may crash if you try to use _RandomPatches_ together with ReplayMod. Try removing RandomPatches if Minecraft crashes on startup.
### Sodium [sodium] ### Sodium [sodium]
ReplayMod can record when _Sodium_ is installed but will crash during render. Disable Sodium before rendering, it can be re-enabled after that. ReplayMod can record when _Sodium_ is installed, but currently lacks the FREX Flawless Frames API to render. A modified build of _Sodium_, that supports this API, is available from the ReplayMod downloads, by clicking the `Click to show compatible Sodium versions` button.
### Resource Loader [resourceloader] ### Resource Loader [resourceloader]
The _Resource Loader_ mod is not compatible with ReplayMod. The _Resource Loader_ mod is not compatible with ReplayMod.

2
jGui

Submodule jGui updated: c1e43fc9f0...aa031212c7

View File

@@ -189,6 +189,7 @@ val doRelease by tasks.registering {
defaultTasks("bundleJar") defaultTasks("bundleJar")
preprocess { preprocess {
val mc11901 = createNode("1.19.1", 11901, "yarn")
val mc11900 = createNode("1.19", 11900, "yarn") val mc11900 = createNode("1.19", 11900, "yarn")
val mc11802 = createNode("1.18.2", 11802, "yarn") val mc11802 = createNode("1.18.2", 11802, "yarn")
val mc11801 = createNode("1.18.1", 11801, "yarn") val mc11801 = createNode("1.18.1", 11801, "yarn")
@@ -210,6 +211,7 @@ preprocess {
val mc10800 = createNode("1.8", 10800, "srg") val mc10800 = createNode("1.8", 10800, "srg")
val mc10710 = createNode("1.7.10", 10710, "srg") val mc10710 = createNode("1.7.10", 10710, "srg")
mc11901.link(mc11900)
mc11900.link(mc11802, file("versions/mapping-fabric-1.19-1.18.2.txt")) mc11900.link(mc11802, file("versions/mapping-fabric-1.19-1.18.2.txt"))
mc11802.link(mc11801) mc11802.link(mc11801)
mc11801.link(mc11701, file("versions/mapping-fabric-1.18.1-1.17.1.txt")) mc11801.link(mc11701, file("versions/mapping-fabric-1.18.1-1.17.1.txt"))

View File

@@ -34,6 +34,7 @@ val jGuiVersions = listOf(
"1.18.1", "1.18.1",
"1.18.2", "1.18.2",
"1.19", "1.19",
"1.19.1",
) )
val replayModVersions = listOf( val replayModVersions = listOf(
// "1.7.10", // "1.7.10",
@@ -56,6 +57,7 @@ val replayModVersions = listOf(
"1.18.1", "1.18.1",
"1.18.2", "1.18.2",
"1.19", "1.19",
"1.19.1",
) )
rootProject.buildFileName = "root.gradle.kts" rootProject.buildFileName = "root.gradle.kts"

View File

@@ -1,16 +0,0 @@
package com.replaymod.core.mixin;
import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.gui.screen.Screen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(TitleScreen.class)
public interface GuiMainMenuAccessor {
//#if MC>=10904
@Accessor("realmsNotificationGui")
Screen getRealmsNotification();
@Accessor("realmsNotificationGui")
void setRealmsNotification(Screen value);
//#endif
}

View File

@@ -1,7 +1,6 @@
package com.replaymod.core.utils; package com.replaymod.core.utils;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.net.PercentEscaper; import com.google.common.net.PercentEscaper;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
@@ -27,7 +26,6 @@ import de.johni0702.minecraft.gui.versions.Image;
import de.johni0702.minecraft.gui.versions.MCVer; import de.johni0702.minecraft.gui.versions.MCVer;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.crash.CrashReport; import net.minecraft.util.crash.CrashReport;
import net.minecraft.util.Identifier;
import org.apache.commons.io.Charsets; import org.apache.commons.io.Charsets;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@@ -38,15 +36,6 @@ import org.apache.logging.log4j.Logger;
//$$ import org.lwjgl.input.Keyboard; //$$ import org.lwjgl.input.Keyboard;
//#endif //#endif
//#if MC>=10800
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.client.util.DefaultSkinHelper;
//#else
//$$ import net.minecraft.client.Minecraft;
//$$ import net.minecraft.client.entity.AbstractClientPlayer;
//$$ import net.minecraft.entity.player.EntityPlayer;
//#endif
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@@ -233,25 +222,6 @@ public class Utils {
} }
} }
public static Identifier getResourceLocationForPlayerUUID(UUID uuid) {
//#if MC>=10800
PlayerListEntry info = getMinecraft().getNetworkHandler().getPlayerListEntry(uuid);
Identifier skinLocation;
if (info != null && info.hasSkinTexture()) {
skinLocation = info.getSkinTexture();
} else {
skinLocation = DefaultSkinHelper.getTexture(uuid);
}
return skinLocation;
//#else
//$$ EntityPlayer player = Minecraft.getMinecraft().theWorld.getPlayerEntityByUUID(uuid);
//$$ if (player != null || !(player instanceof AbstractClientPlayer)) {
//$$ return AbstractClientPlayer.locationStevePng;
//$$ }
//$$ return ((AbstractClientPlayer) player).getLocationSkin();
//#endif
}
public static boolean isCtrlDown() { public static boolean isCtrlDown() {
//#if MC>=11400 //#if MC>=11400
return Screen.hasControlDown(); return Screen.hasControlDown();

View File

@@ -15,6 +15,7 @@ import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.resource.Resource; import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager; import net.minecraft.resource.ResourceManager;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
@@ -49,6 +50,10 @@ import net.minecraft.client.util.Window;
//$$ import net.minecraft.client.gui.GuiButton; //$$ import net.minecraft.client.gui.GuiButton;
//#endif //#endif
//#if MC>=11100
import net.minecraft.util.collection.DefaultedList;
//#endif
//#if MC>=10904 //#if MC>=10904
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.util.crash.CrashCallable; import net.minecraft.util.crash.CrashCallable;
@@ -669,4 +674,13 @@ class Patterns {
return manager.getResource(id); return manager.getResource(id);
//#endif //#endif
} }
@Pattern
private static List<ItemStack> DefaultedList_ofSize_ItemStack_Empty(int size) {
//#if MC>=11100
return DefaultedList.ofSize(size, ItemStack.EMPTY);
//#else
//$$ return java.util.Arrays.asList(new ItemStack[size]);
//#endif
}
} }

View File

@@ -1,6 +1,5 @@
package com.replaymod.extras.playeroverview; package com.replaymod.extras.playeroverview;
import com.replaymod.core.utils.Utils;
import com.replaymod.replay.ReplayModReplay; import com.replaymod.replay.ReplayModReplay;
import de.johni0702.minecraft.gui.GuiRenderer; import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo; import de.johni0702.minecraft.gui.RenderInfo;
@@ -20,6 +19,7 @@ import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.utils.Colors; import de.johni0702.minecraft.gui.utils.Colors;
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension; import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension; import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@@ -94,7 +94,8 @@ public class PlayerOverviewGui extends GuiScreen implements Closeable {
Collections.sort(players, new PlayerComparator()); // Sort by name, spectators last Collections.sort(players, new PlayerComparator()); // Sort by name, spectators last
for (final PlayerEntity p : players) { for (final PlayerEntity p : players) {
final Identifier texture = Utils.getResourceLocationForPlayerUUID(p.getUuid()); if (!(p instanceof AbstractClientPlayerEntity)) continue;
final Identifier texture = ((AbstractClientPlayerEntity) p).getSkinTexture();
final GuiClickable panel = new GuiClickable().setLayout(new HorizontalLayout().setSpacing(2)).addElements( final GuiClickable panel = new GuiClickable().setLayout(new HorizontalLayout().setSpacing(2)).addElements(
new HorizontalLayout.Data(0.5), new GuiImage() { new HorizontalLayout.Data(0.5), new GuiImage() {
@Override @Override

View File

@@ -40,6 +40,10 @@ import java.util.Collections;
//$$ import net.minecraft.network.play.server.SPacketUseBed; //$$ import net.minecraft.network.play.server.SPacketUseBed;
//#endif //#endif
//#if MC>=11100
import net.minecraft.util.collection.DefaultedList;
//#endif
//#if MC>=10904 //#if MC>=10904
import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.WorldEventS2CPacket; import net.minecraft.network.packet.s2c.play.WorldEventS2CPacket;
@@ -53,6 +57,7 @@ import net.minecraft.util.math.BlockPos;
//$$ import net.minecraft.util.MathHelper; //$$ import net.minecraft.util.MathHelper;
//#endif //#endif
import java.util.List;
import java.util.Objects; import java.util.Objects;
import static com.replaymod.core.versions.MCVer.*; import static com.replaymod.core.versions.MCVer.*;
@@ -63,7 +68,7 @@ public class RecordingEventHandler extends EventRegistrations {
private final PacketListener packetListener; private final PacketListener packetListener;
private Double lastX, lastY, lastZ; private Double lastX, lastY, lastZ;
private ItemStack[] playerItems = new ItemStack[6]; private final List<ItemStack> playerItems = DefaultedList.ofSize(6, ItemStack.EMPTY);
private int ticksSinceLastCorrection; private int ticksSinceLastCorrection;
private boolean wasSleeping; private boolean wasSleeping;
private int lastRiding = -1; private int lastRiding = -1;
@@ -254,8 +259,17 @@ public class RecordingEventHandler extends EventRegistrations {
//#if MC>=10904 //#if MC>=10904
for (EquipmentSlot slot : EquipmentSlot.values()) { for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack stack = player.getEquippedStack(slot); ItemStack stack = player.getEquippedStack(slot);
if (playerItems[slot.ordinal()] != stack) { int index = slot.ordinal();
playerItems[slot.ordinal()] = stack; //#else
//$$ for (int slot = 0; slot < 5; slot++) {
//$$ ItemStack stack = player.getEquipmentInSlot(slot);
//$$ int index = slot;
//#endif
if (!ItemStack.areEqual(playerItems.get(index), stack)) {
// ItemStack has internal mutability, so we need to make a copy now if we want to compare its
// current state with future states (e.g. dropping on modern versions will set the count to zero).
stack = stack != null ? stack.copy() : null;
playerItems.set(index, stack);
//#if MC>=11600 //#if MC>=11600
packetListener.save(new EntityEquipmentUpdateS2CPacket(player.getEntityId(), Collections.singletonList(Pair.of(slot, stack)))); packetListener.save(new EntityEquipmentUpdateS2CPacket(player.getEntityId(), Collections.singletonList(Pair.of(slot, stack))));
//#else //#else
@@ -263,37 +277,6 @@ public class RecordingEventHandler extends EventRegistrations {
//#endif //#endif
} }
} }
//#else
//$$ if(playerItems[0] != mc.thePlayer.getHeldItem()) {
//$$ playerItems[0] = mc.thePlayer.getHeldItem();
//$$ S04PacketEntityEquipment pee = new S04PacketEntityEquipment(player.getEntityId(), 0, playerItems[0]);
//$$ packetListener.save(pee);
//$$ }
//$$
//$$ if(playerItems[1] != mc.thePlayer.inventory.armorInventory[0]) {
//$$ playerItems[1] = mc.thePlayer.inventory.armorInventory[0];
//$$ S04PacketEntityEquipment pee = new S04PacketEntityEquipment(player.getEntityId(), 1, playerItems[1]);
//$$ packetListener.save(pee);
//$$ }
//$$
//$$ if(playerItems[2] != mc.thePlayer.inventory.armorInventory[1]) {
//$$ playerItems[2] = mc.thePlayer.inventory.armorInventory[1];
//$$ S04PacketEntityEquipment pee = new S04PacketEntityEquipment(player.getEntityId(), 2, playerItems[2]);
//$$ packetListener.save(pee);
//$$ }
//$$
//$$ if(playerItems[3] != mc.thePlayer.inventory.armorInventory[2]) {
//$$ playerItems[3] = mc.thePlayer.inventory.armorInventory[2];
//$$ S04PacketEntityEquipment pee = new S04PacketEntityEquipment(player.getEntityId(), 3, playerItems[3]);
//$$ packetListener.save(pee);
//$$ }
//$$
//$$ if(playerItems[4] != mc.thePlayer.inventory.armorInventory[3]) {
//$$ playerItems[4] = mc.thePlayer.inventory.armorInventory[3];
//$$ S04PacketEntityEquipment pee = new S04PacketEntityEquipment(player.getEntityId(), 4, playerItems[4]);
//$$ packetListener.save(pee);
//$$ }
//#endif
//Leaving Ride //Leaving Ride

View File

@@ -2,42 +2,25 @@ package com.replaymod.render.processor;
import com.replaymod.render.frame.OpenGlFrame; import com.replaymod.render.frame.OpenGlFrame;
import com.replaymod.render.frame.BitmapFrame; import com.replaymod.render.frame.BitmapFrame;
import com.replaymod.render.utils.ByteBufferPool;
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension; import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
public class OpenGlToBitmapProcessor extends AbstractFrameProcessor<OpenGlFrame, BitmapFrame> { import static com.replaymod.render.utils.Utils.openGlBytesToBitmap;
private byte[] row, rowSwap; public class OpenGlToBitmapProcessor extends AbstractFrameProcessor<OpenGlFrame, BitmapFrame> {
@Override @Override
public BitmapFrame process(OpenGlFrame rawFrame) { public BitmapFrame process(OpenGlFrame rawFrame) {
// Flip whole image in place
ReadableDimension size = rawFrame.getSize(); ReadableDimension size = rawFrame.getSize();
int width = size.getWidth();
int height = size.getHeight();
int bpp = rawFrame.getBytesPerPixel(); int bpp = rawFrame.getBytesPerPixel();
int rowSize = size.getWidth() * bpp; ByteBuffer result = ByteBufferPool.allocate(width * height * bpp);
if (row == null || row.length < rowSize) { openGlBytesToBitmap(rawFrame, 0, 0, result, width);
row = new byte[rowSize]; ByteBufferPool.release(rawFrame.getByteBuffer());
rowSwap = new byte[rowSize]; return new BitmapFrame(rawFrame.getFrameId(), new Dimension(width, height), bpp, result);
}
ByteBuffer buffer = rawFrame.getByteBuffer();
int rows = size.getHeight();
byte[] row = this.row;
byte[] rowSwap = this.rowSwap;
for (int i = 0; i < rows / 2; i++) {
int from = rowSize * i;
int to = rowSize * (rows - i - 1);
buffer.position(from);
buffer.get(row);
buffer.position(to);
buffer.get(rowSwap);
buffer.position(to);
buffer.put(row);
buffer.position(from);
buffer.put(rowSwap);
}
buffer.rewind();
return new BitmapFrame(rawFrame.getFrameId(), size, bpp, buffer);
} }
} }

View File

@@ -651,7 +651,7 @@ public class VideoRenderer implements RenderInfo {
return new String[] { return new String[] {
"Rendering is not supported with your Sodium version.", "Rendering is not supported with your Sodium version.",
"It is missing support for the FREX Flawless Frames API.", "It is missing support for the FREX Flawless Frames API.",
"Either update to the latest version or uninstall Sodium before rendering!", "Either use the Sodium build from replaymod.com or uninstall Sodium before rendering!",
}; };
} }
//#if MC>=11700 //#if MC>=11700

View File

@@ -58,6 +58,7 @@ import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
//#if MC>=11900 //#if MC>=11900
//$$ import net.minecraft.network.packet.s2c.play.ChatMessageS2CPacket;
//#else //#else
import net.minecraft.network.packet.s2c.play.MobSpawnS2CPacket; import net.minecraft.network.packet.s2c.play.MobSpawnS2CPacket;
import net.minecraft.network.packet.s2c.play.PaintingSpawnS2CPacket; import net.minecraft.network.packet.s2c.play.PaintingSpawnS2CPacket;
@@ -266,6 +267,8 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
/** /**
* Whether to allow (process) the next player movement packet. * Whether to allow (process) the next player movement packet.
*
* Must only be accessed from the main thread.
*/ */
protected boolean allowMovement; protected boolean allowMovement;
@@ -638,7 +641,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
if(p instanceof GameJoinS2CPacket) { if(p instanceof GameJoinS2CPacket) {
GameJoinS2CPacket packet = (GameJoinS2CPacket) p; GameJoinS2CPacket packet = (GameJoinS2CPacket) p;
int entId = packet.getEntityId(); int entId = packet.getEntityId();
allowMovement = true; schedulePacketHandler(() -> allowMovement = true);
actualID = entId; actualID = entId;
entId = -1789435; // Camera entity id should be negative which is an invalid id and can't be used by servers entId = -1789435; // Camera entity id should be negative which is an invalid id and can't be used by servers
//#if MC>=11400 //#if MC>=11400
@@ -772,7 +775,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
//#endif //#endif
//#endif //#endif
allowMovement = true; schedulePacketHandler(() -> allowMovement = true);
} }
if(p instanceof PlayerPositionLookS2CPacket) { if(p instanceof PlayerPositionLookS2CPacket) {
@@ -788,8 +791,6 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
if(replayHandler.shouldSuppressCameraMovements()) return null; if(replayHandler.shouldSuppressCameraMovements()) return null;
CameraEntity cent = replayHandler.getCameraEntity();
//#if MC>=10800 //#if MC>=10800
//#if MC>=11400 //#if MC>=11400
for (PlayerPositionLookS2CPacket.Flag relative : ppl.getFlags()) { for (PlayerPositionLookS2CPacket.Flag relative : ppl.getFlags()) {
@@ -811,28 +812,30 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
} }
//#endif //#endif
if(cent != null) { schedulePacketHandler(new Runnable() {
if(!allowMovement && !((Math.abs(cent.getX() - ppl.getX()) > TP_DISTANCE_LIMIT) ||
(Math.abs(cent.getZ() - ppl.getZ()) > TP_DISTANCE_LIMIT))) {
return null;
} else {
allowMovement = false;
}
}
new Runnable() {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void run() { public void run() {
// FIXME: world shouldn't ever be null at this point, now that we use the packet queue
// probably fine to remove on the next non-patch version (don't want to break stuff now)
if (mc.world == null || !mc.isOnThread()) { if (mc.world == null || !mc.isOnThread()) {
ReplayMod.instance.runLater(this); ReplayMod.instance.runLater(this);
return; return;
} }
CameraEntity cent = replayHandler.getCameraEntity(); CameraEntity cent = replayHandler.getCameraEntity();
if (!allowMovement && !((Math.abs(cent.getX() - ppl.getX()) > TP_DISTANCE_LIMIT) ||
(Math.abs(cent.getZ() - ppl.getZ()) > TP_DISTANCE_LIMIT))) {
return;
} else {
allowMovement = false;
}
cent.setCameraPosition(ppl.getX(), ppl.getY(), ppl.getZ()); cent.setCameraPosition(ppl.getX(), ppl.getY(), ppl.getZ());
cent.setCameraRotation(ppl.getYaw(), ppl.getPitch(), cent.roll);
} }
}.run(); });
return null;
} }
if(p instanceof GameStateChangeS2CPacket) { if(p instanceof GameStateChangeS2CPacket) {
@@ -861,7 +864,11 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
} }
} }
//#if MC>=11900
//$$ if (p instanceof GameMessageS2CPacket || p instanceof ChatMessageS2CPacket) {
//#else
if (p instanceof GameMessageS2CPacket) { if (p instanceof GameMessageS2CPacket) {
//#endif
if (!ReplayModReplay.instance.getCore().getSettingsRegistry().get(Setting.SHOW_CHAT)) { if (!ReplayModReplay.instance.getCore().getSettingsRegistry().get(Setting.SHOW_CHAT)) {
return null; return null;
} }
@@ -1265,6 +1272,22 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
ReplayMod.instance.runTasks(); ReplayMod.instance.runTasks();
} }
/**
* Runs the given runnable on the main thread as if it was a packet handler.
* Note that the packet handler queue has different behavior than the standard ReplayMod queue.
*/
private void schedulePacketHandler(Runnable runnable) {
if (mc.isOnThread()) {
runnable.run();
} else {
//#if MC>=11400
mc.execute(runnable);
//#else
//$$ mc.addScheduledTask(runnable);
//#endif
}
}
protected void processPacketSync(Packet p) { protected void processPacketSync(Packet p) {
//#if MC>=10904 //#if MC>=10904
if (p instanceof UnloadChunkS2CPacket) { if (p instanceof UnloadChunkS2CPacket) {

View File

@@ -73,6 +73,7 @@ import net.minecraft.client.recipebook.ClientRecipeBook;
//$$ import net.minecraft.stats.RecipeBook; //$$ import net.minecraft.stats.RecipeBook;
//#endif //#endif
//#endif //#endif
import net.minecraft.util.Arm;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
//#endif //#endif
@@ -472,8 +473,8 @@ public class CameraEntity
@Override @Override
public Identifier getSkinTexture() { public Identifier getSkinTexture() {
Entity view = this.client.getCameraEntity(); Entity view = this.client.getCameraEntity();
if (view != this && view instanceof PlayerEntity) { if (view != this && view instanceof AbstractClientPlayerEntity) {
return Utils.getResourceLocationForPlayerUUID(view.getUuid()); return ((AbstractClientPlayerEntity) view).getSkinTexture();
} }
return super.getSkinTexture(); return super.getSkinTexture();
} }
@@ -498,6 +499,17 @@ public class CameraEntity
} }
//#endif //#endif
//#if MC>=10904
@Override
public Arm getMainArm() {
Entity view = this.client.getCameraEntity();
if (view != this && view instanceof PlayerEntity) {
return ((PlayerEntity) view).getMainArm();
}
return super.getMainArm();
}
//#endif
@Override @Override
public float getHandSwingProgress(float renderPartialTicks) { public float getHandSwingProgress(float renderPartialTicks) {
Entity view = this.client.getCameraEntity(); Entity view = this.client.getCameraEntity();

View File

@@ -138,7 +138,7 @@ public class GuiHandler extends EventRegistrations {
//#if MC<11400 //#if MC<11400
//$$ openToLan = b; //$$ openToLan = b;
//#endif //#endif
//#if MC>=11400 //#if MC>=11400 && MC<11901
} else if (id.equals(BUTTON_OPTIONS)) { } else if (id.equals(BUTTON_OPTIONS)) {
//#if MC>=11400 //#if MC>=11400
b.setWidth(204); b.setWidth(204);

View File

@@ -18,7 +18,6 @@
//#endif //#endif
"MixinKeyboardListener", "MixinKeyboardListener",
"MixinMinecraft", "MixinMinecraft",
"GuiMainMenuAccessor",
"GuiScreenAccessor", "GuiScreenAccessor",
"KeyBindingAccessor", "KeyBindingAccessor",
"MinecraftAccessor", "MinecraftAccessor",

View File

@@ -1 +1 @@
2.6.6 2.6.7

View File

@@ -1 +1,2 @@
net.minecraft.item.ItemStack EMPTY field_190927_a net.minecraft.item.ItemStack EMPTY field_190927_a
net.minecraft.util.NonNullList withSize() func_191197_a()

View File

@@ -23,6 +23,7 @@ org.lwjgl.glfw.GLFW com.replaymod.core.versions.GLFW
net.minecraft.client.MainWindow com.replaymod.core.versions.Window net.minecraft.client.MainWindow com.replaymod.core.versions.Window
net.minecraft.client.audio.SimpleSound net.minecraft.client.audio.PositionedSoundRecord net.minecraft.client.audio.SimpleSound net.minecraft.client.audio.PositionedSoundRecord
net.minecraft.client.gui.IngameGui net.minecraft.client.gui.GuiIngame net.minecraft.client.gui.IngameGui net.minecraft.client.gui.GuiIngame
net.minecraft.util.HandSide net.minecraft.util.EnumHandSide
net.minecraft.resources.FolderPack getInputStream() getInputStreamByName() net.minecraft.resources.FolderPack getInputStream() getInputStreamByName()
net.minecraft.client.gui.GuiYesNoCallback confirmResult() confirmClicked() net.minecraft.client.gui.GuiYesNoCallback confirmResult() confirmClicked()

View File

@@ -8,6 +8,8 @@ net.minecraft.network.play.server.S48PacketResourcePackSend getHash() func_17978
net.minecraft.network.play.server.S08PacketPlayerPosLook getX() func_148932_c() net.minecraft.network.play.server.S08PacketPlayerPosLook getX() func_148932_c()
net.minecraft.network.play.server.S08PacketPlayerPosLook getY() func_148928_d() net.minecraft.network.play.server.S08PacketPlayerPosLook getY() func_148928_d()
net.minecraft.network.play.server.S08PacketPlayerPosLook getZ() func_148933_e() net.minecraft.network.play.server.S08PacketPlayerPosLook getZ() func_148933_e()
net.minecraft.network.play.server.S08PacketPlayerPosLook getYaw() func_148931_f()
net.minecraft.network.play.server.S08PacketPlayerPosLook getPitch() func_148930_g()
net.minecraft.network.play.server.S2BPacketChangeGameState getGameState() func_149138_c() net.minecraft.network.play.server.S2BPacketChangeGameState getGameState() func_149138_c()
net.minecraft.network.play.server.S0EPacketSpawnObject getType() func_148993_l() net.minecraft.network.play.server.S0EPacketSpawnObject getType() func_148993_l()
net.minecraft.network.play.server.S21PacketChunkData getChunkX() func_149273_e() net.minecraft.network.play.server.S21PacketChunkData getChunkX() func_149273_e()