diff --git a/.drone.yml.sig b/.drone.yml.sig index ed8895d0..0af065e5 100644 --- a/.drone.yml.sig +++ b/.drone.yml.sig @@ -1 +1 @@ -eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgY2xvbmU6CiAgICBpbWFnZTogcGx1Z2lucy9naXQKICAgIHRhZ3M6IHRydWUKICBidWlsZDoKICAgIGltYWdlOiBtYXZlbjozLjMuOS1qZGstOAogICAgY29tbWFuZHM6CiAgICAgIC0gY3VybCAtLWZhaWwgLS1jcmVhdGUtZGlycyAtbyAkSE9NRS8uZ3JhZGxlL2luaXQuZC9taXJyb3IuZ3JhZGxlIGh0dHBzOi8vbWF2ZW4uam9obmkwNzAyLmRlL2NvbmZpZy9ncmFkbGUKICAgICAgLSBnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIuZW1haWwgInJlcGxheW1vZEBkcm9uZSIgJiYgZ2l0IGNvbmZpZyAtLWdsb2JhbCB1c2VyLm5hbWUgIkRyb25lIgogICAgICAtIFNJR05FRF9KQVI9JCghIGdpdCBkZXNjcmliZSAtLWV4YWN0IDI-JjEgPiAvZGV2L251bGw7IGVjaG8gJD8pIFJFUFJPRFVDSUJMRV9CVUlMRD0xIC4vZ3JhZGxldyA6YnVpbGQKICBhcmNoaXZlOgogICAgaW1hZ2U6IHBsdWdpbnMvczMKICAgIGFjbDogcHVibGljLXJlYWQKICAgIHJlZ2lvbjogInVzLWVhc3QtMSIKICAgIGJ1Y2tldDogInJlcGxheW1vZCIKICAgIHBhdGhfc3R5bGU6IHRydWUKICAgIHNvdXJjZTogYnVpbGQvbGlicy8qCiAgICBzdHJpcF9wcmVmaXg6IGJ1aWxkL2xpYnMvCiAgICB0YXJnZXQ6IC8K.cFk9CFCSYjJSwQhcJJp0BqSMwigKYCBd6r-KkvxlQZ0 \ No newline at end of file +eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgY2xvbmU6CiAgICBpbWFnZTogcGx1Z2lucy9naXQKICAgIHRhZ3M6IHRydWUKICBidWlsZDoKICAgIGltYWdlOiBtYXZlbjozLjMuOS1qZGstOAogICAgY29tbWFuZHM6CiAgICAgIC0gY3VybCAtLWZhaWwgLS1jcmVhdGUtZGlycyAtbyAkSE9NRS8uZ3JhZGxlL2luaXQuZC9taXJyb3IuZ3JhZGxlIGh0dHBzOi8vbWF2ZW4uam9obmkwNzAyLmRlL2NvbmZpZy9ncmFkbGUKICAgICAgLSBnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIuZW1haWwgInJlcGxheW1vZEBkcm9uZSIgJiYgZ2l0IGNvbmZpZyAtLWdsb2JhbCB1c2VyLm5hbWUgIkRyb25lIgogICAgICAtIFNJR05FRF9KQVI9JCghIGdpdCBkZXNjcmliZSAtLWV4YWN0IDI-JjEgPiAvZGV2L251bGw7IGVjaG8gJD8pIFJFUFJPRFVDSUJMRV9CVUlMRD0xIC4vZ3JhZGxldyA6YnVpbGQKICBhcmNoaXZlOgogICAgaW1hZ2U6IHBsdWdpbnMvczMKICAgIGFjbDogcHVibGljLXJlYWQKICAgIHJlZ2lvbjogInVzLWVhc3QtMSIKICAgIGJ1Y2tldDogInJlcGxheW1vZCIKICAgIHBhdGhfc3R5bGU6IHRydWUKICAgIHNvdXJjZTogYnVpbGQvbGlicy8qCiAgICBzdHJpcF9wcmVmaXg6IGJ1aWxkL2xpYnMvCiAgICB0YXJnZXQ6IC8K.cFk9CFCSYjJSwQhcJJp0BqSMwigKYCBd6r-KkvxlQZ0 diff --git a/build.gradle b/build.gradle index e50e7cce..cff5e8b1 100755 --- a/build.gradle +++ b/build.gradle @@ -17,8 +17,8 @@ buildscript { } } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:2.1-SNAPSHOT' - classpath 'org.spongepowered:mixingradle:0.3-SNAPSHOT' + classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT' + classpath 'org.spongepowered:mixingradle:0.4-SNAPSHOT' } } @@ -34,9 +34,9 @@ archivesBaseName = "replaymod" minecraft { coreMod = 'com.replaymod.core.LoadingPlugin' - version = '1.8.9-11.15.1.1722' + version = '1.9.4-12.17.0.1976' runDir = "eclipse" - mappings = "stable_22" + mappings = "snapshot_20160518" replace '@MOD_VERSION@', project.version // Includes intentional whitespace to stop Forge from declaring the mod to be compatible with // a newer srg-compatible MC version (that may be using a different protocol version) @@ -69,7 +69,7 @@ dependencies { shade 'org.aspectj:aspectjrt:1.8.2' - shade 'com.github.replaymod:ReplayStudio:2df8d8b' + shade 'com.github.replaymod:ReplayStudio:c7ed696' testCompile 'junit:junit:4.11' } @@ -111,6 +111,7 @@ jar { manifest { attributes 'TweakClass': 'org.spongepowered.asm.launch.MixinTweaker', 'TweakOrder': '0', + 'FMLCorePluginContainsFMLMod': 'true', 'FMLAT': 'replaymod_at.cfg' } } @@ -179,6 +180,57 @@ setupDecompWorkspace.dependsOn copySrg setupDevWorkspace.dependsOn copySrg project.tasks.idea.dependsOn copySrg + +import org.objectweb.asm.* + +import java.util.zip.ZipEntry +import java.util.zip.ZipFile +import java.util.zip.ZipOutputStream + +import static org.objectweb.asm.Opcodes.ASM5 + +// MC binaries were complied with a java version that produces invalid class files under certain circumstances +// This causes setupCIWorkspace to be insufficient for compiling. +// Related JDK bug: https://bugs.openjdk.java.net/browse/JDK-8066725 +// As a workaround, to use setupCIWorkspace on Drone, we modify the bin jar in-place and remove all parameter annotations. +// WARNING: This piece of code ignores any and all gradle conventions and will probably fail horribly when run outside +// of a single-use environment (e.g. Drone). Use setupDecompWorkspace for normal use. +tasks.deobfMcMCP.doLast { + println "Applying RuntimeInvisibleParameterAnnotations workaround..." + File jar = getOutJar() + File tmp = new File((File) getTemporaryDir(), "workaround.jar") + tmp.withOutputStream { + new ZipOutputStream(it).withStream { dst -> + new ZipFile(jar).withCloseable { src -> + src.entries().each { + if (it.name.startsWith("net/minecraft/") && it.name.endsWith(".class")) { + def cw = new ClassWriter(0) + def cv = new ClassVisitor(ASM5, cw) { + @Override + MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + return new MethodVisitor(ASM5, cv.visitMethod(access, name, desc, signature, exceptions)) { + @Override + AnnotationVisitor visitParameterAnnotation(int parameter, String pdesc, boolean visible) { + return null // Strip all parameter annotations + } + } + } + } + new ClassReader(src.getInputStream(it)).accept(cv, 0) + dst.putNextEntry(new ZipEntry(it.name)) + dst.write(cw.toByteArray()) + } else { + dst.putNextEntry(it) + dst.write(src.getInputStream(it).bytes) + } + } + } + } + } + jar.delete() + tmp.renameTo(jar) +} + task runIntegrationTest(type: JavaExec, dependsOn: ["makeStart", "jar"]) { main = 'GradleStart' standardOutput = System.out diff --git a/jGui b/jGui index 1e92ad85..e2bd9062 160000 --- a/jGui +++ b/jGui @@ -1 +1 @@ -Subproject commit 1e92ad85df9c4282d88e017e433a189a76bea433 +Subproject commit e2bd90628e29809609f7dad0acb1ab3adab2b7c8 diff --git a/src/integration-test/java/com/replaymod/core/AbstractTask.java b/src/integration-test/java/com/replaymod/core/AbstractTask.java index e21d7b52..c6abf8f5 100644 --- a/src/integration-test/java/com/replaymod/core/AbstractTask.java +++ b/src/integration-test/java/com/replaymod/core/AbstractTask.java @@ -50,10 +50,8 @@ public abstract class AbstractTask implements Task { public ListenableFuture execute() { future = SettableFuture.create(); - FMLCommonHandler.instance().bus().register(this); MinecraftForge.EVENT_BUS.register(this); addCallback(future, success -> { - FMLCommonHandler.instance().bus().unregister(this); MinecraftForge.EVENT_BUS.unregister(this); }, error -> {}); @@ -92,7 +90,7 @@ public abstract class AbstractTask implements Task { public void onGuiOpen(TickEvent.RenderTickEvent event) { if (event.phase != TickEvent.Phase.START) return; if (currentScreen != mc.currentScreen) { - FMLCommonHandler.instance().bus().unregister(this); + MinecraftForge.EVENT_BUS.unregister(this); onClosed.run(); } else { if (framesPassed < timeout) { @@ -106,7 +104,7 @@ public abstract class AbstractTask implements Task { } } } - FMLCommonHandler.instance().bus().register(new EventHandler()); + MinecraftForge.EVENT_BUS.register(new EventHandler()); } public void expectPopupClosed(Runnable onClosed) { @@ -130,7 +128,7 @@ public abstract class AbstractTask implements Task { public void onGuiOpen(TickEvent.RenderTickEvent event) { if (event.phase != TickEvent.Phase.START) return; if (getPopup(mc.currentScreen) != popup) { - FMLCommonHandler.instance().bus().unregister(this); + MinecraftForge.EVENT_BUS.unregister(this); onClosed.run(); } else { if (framesPassed < timeout) { @@ -143,7 +141,7 @@ public abstract class AbstractTask implements Task { } } } - FMLCommonHandler.instance().bus().register(new EventHandler()); + MinecraftForge.EVENT_BUS.register(new EventHandler()); } private AbstractGuiPopup getPopup(net.minecraft.client.gui.GuiScreen minecraft) { @@ -181,7 +179,7 @@ public abstract class AbstractTask implements Task { return; } - FMLCommonHandler.instance().bus().unregister(this); + MinecraftForge.EVENT_BUS.unregister(this); Object foundGui = null; if (AbstractGuiScreen.class.isAssignableFrom(guiClass)) { @@ -219,7 +217,7 @@ public abstract class AbstractTask implements Task { future.setException(new UnexpectedGuiException(foundGui == null ? currentScreen : foundGui)); } } - FMLCommonHandler.instance().bus().register(new EventHandler()); + MinecraftForge.EVENT_BUS.register(new EventHandler()); } private void clickNow(int x, int y) { diff --git a/src/integration-test/java/com/replaymod/recording/CreateSPWorld.java b/src/integration-test/java/com/replaymod/recording/CreateSPWorld.java index 95f4cb16..a6a4e684 100644 --- a/src/integration-test/java/com/replaymod/recording/CreateSPWorld.java +++ b/src/integration-test/java/com/replaymod/recording/CreateSPWorld.java @@ -3,7 +3,7 @@ package com.replaymod.recording; import com.replaymod.core.AbstractTask; import net.minecraft.client.gui.GuiCreateWorld; import net.minecraft.client.gui.GuiMainMenu; -import net.minecraft.client.gui.GuiSelectWorld; +import net.minecraft.client.gui.GuiWorldSelection; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -13,7 +13,7 @@ public class CreateSPWorld extends AbstractTask { protected void init() { expectGui(GuiMainMenu.class, mainMenu -> { click("Singleplayer"); - expectGui(GuiSelectWorld.class, selectWorld -> { + expectGui(GuiWorldSelection.class, selectWorld -> { click("Create New World"); expectGui(GuiCreateWorld.class, createWorld -> { click("Create New World"); diff --git a/src/main/java/com/replaymod/compat/ReplayModCompat.java b/src/main/java/com/replaymod/compat/ReplayModCompat.java index 9347cd2f..15f04a0c 100644 --- a/src/main/java/com/replaymod/compat/ReplayModCompat.java +++ b/src/main/java/com/replaymod/compat/ReplayModCompat.java @@ -4,7 +4,7 @@ import com.replaymod.compat.bettersprinting.DisableBetterSprinting; import com.replaymod.compat.optifine.DisableFastRender; import com.replaymod.compat.oranges17animations.HideInvisibleEntities; import com.replaymod.compat.shaders.ShaderBeginRender; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.eventhandler.EventBus; @@ -19,7 +19,7 @@ public class ReplayModCompat { @Mod.EventHandler public void init(FMLInitializationEvent event) { - EventBus bus = FMLCommonHandler.instance().bus(); + EventBus bus = MinecraftForge.EVENT_BUS; bus.register(new ShaderBeginRender()); bus.register(new DisableFastRender()); bus.register(new HideInvisibleEntities()); diff --git a/src/main/java/com/replaymod/compat/bettersprinting/DisableBetterSprinting.java b/src/main/java/com/replaymod/compat/bettersprinting/DisableBetterSprinting.java index 6d8b4f48..06cda215 100644 --- a/src/main/java/com/replaymod/compat/bettersprinting/DisableBetterSprinting.java +++ b/src/main/java/com/replaymod/compat/bettersprinting/DisableBetterSprinting.java @@ -2,12 +2,16 @@ package com.replaymod.compat.bettersprinting; import com.replaymod.replay.ReplayModReplay; import com.replaymod.replay.events.ReplayChatMessageEvent; +import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.BlockPos; -import net.minecraft.world.IWorldAccess; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorldEventListener; +import net.minecraft.world.World; import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.Loader; @@ -18,6 +22,7 @@ import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion; import net.minecraftforge.fml.common.versioning.Restriction; import net.minecraftforge.fml.common.versioning.VersionRange; +import javax.annotation.Nullable; import java.util.Collections; /** @@ -50,14 +55,14 @@ public class DisableBetterSprinting { if (ReplayModReplay.instance.getReplayHandler() != null && mc.theWorld != null) { // During replay, get ready to revert BetterSprinting's overwritten playerController originalController = mc.playerController; - mc.theWorld.addWorldAccess(worldAccessHook); + mc.theWorld.addEventListener(worldAccessHook); } } @SubscribeEvent(priority = EventPriority.LOW) public void afterGuiOpenEvent(GuiOpenEvent event) { if (ReplayModReplay.instance.getReplayHandler() != null && mc.theWorld != null) { - mc.theWorld.removeWorldAccess(worldAccessHook); + mc.theWorld.addEventListener(worldAccessHook); } } @@ -72,7 +77,7 @@ public class DisableBetterSprinting { } } - private class BetterSprintingWorldAccess implements IWorldAccess { + private class BetterSprintingWorldAccess implements IWorldEventListener { @Override public void onEntityRemoved(Entity entityIn) { if (mc.playerController != null && mc.playerController.getClass().getName().equals(CONTROLLER_OVERRIDE_CLASS_NAME)) { @@ -82,16 +87,15 @@ public class DisableBetterSprinting { } } - @Override public void markBlockForUpdate(BlockPos pos) {} + @Override public void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags) {} @Override public void notifyLightSet(BlockPos pos) {} @Override public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) {} - @Override public void playSound(String soundName, double x, double y, double z, float volume, float pitch) {} - @Override public void playSoundToNearExcept(EntityPlayer except, String soundName, double x, double y, double z, float volume, float pitch) {} + @Override public void playSoundToAllNearExcept(@Nullable EntityPlayer player, SoundEvent soundIn, SoundCategory category, double x, double y, double z, float volume, float pitch) {} + @Override public void playRecord(SoundEvent soundIn, BlockPos pos) {} @Override public void spawnParticle(int p_180442_1_, boolean p_180442_2_, double p_180442_3_, double p_180442_5_, double p_180442_7_, double p_180442_9_, double p_180442_11_, double p_180442_13_, int... p_180442_15_) {} @Override public void onEntityAdded(Entity entityIn) {} - @Override public void playRecord(String recordName, BlockPos blockPosIn) {} @Override public void broadcastSound(int p_180440_1_, BlockPos p_180440_2_, int p_180440_3_) {} - @Override public void playAuxSFX(EntityPlayer p_180439_1_, int p_180439_2_, BlockPos blockPosIn, int p_180439_4_) {} + @Override public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data) {} @Override public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) {} } } diff --git a/src/main/java/com/replaymod/compat/oranges17animations/HideInvisibleEntities.java b/src/main/java/com/replaymod/compat/oranges17animations/HideInvisibleEntities.java index 1600905d..58d8bb7f 100644 --- a/src/main/java/com/replaymod/compat/oranges17animations/HideInvisibleEntities.java +++ b/src/main/java/com/replaymod/compat/oranges17animations/HideInvisibleEntities.java @@ -20,7 +20,7 @@ public class HideInvisibleEntities { @SubscribeEvent(priority = EventPriority.HIGH) public void preRenderLiving(RenderLivingEvent.Pre event) { if (modLoaded) { - if (mc.thePlayer instanceof CameraEntity && event.entity.isInvisible()) { + if (mc.thePlayer instanceof CameraEntity && event.getEntity().isInvisible()) { event.setCanceled(true); } } diff --git a/src/main/java/com/replaymod/core/KeyBindingRegistry.java b/src/main/java/com/replaymod/core/KeyBindingRegistry.java index 8231700c..9d792864 100644 --- a/src/main/java/com/replaymod/core/KeyBindingRegistry.java +++ b/src/main/java/com/replaymod/core/KeyBindingRegistry.java @@ -16,7 +16,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.Callable; public class KeyBindingRegistry { private Map keyBindings = new HashMap(); @@ -86,7 +85,7 @@ public class KeyBindingRegistry { CrashReport crashReport = CrashReport.makeCrashReport(cause, "Handling Key Binding"); CrashReportCategory category = crashReport.makeCategory("Key Binding"); category.addCrashSection("Key Binding", keyBinding); - category.addCrashSectionCallable("Handler", runnable::toString); + category.setDetail("Handler", runnable::toString); throw new ReportedException(crashReport); } } @@ -101,12 +100,7 @@ public class KeyBindingRegistry { CrashReport crashReport = CrashReport.makeCrashReport(cause, "Handling Raw Key Binding"); CrashReportCategory category = crashReport.makeCategory("Key Binding"); category.addCrashSection("Key Code", keyCode); - category.addCrashSectionCallable("Handler", new Callable() { - @Override - public Object call() throws Exception { - return runnable; - } - }); + category.setDetail("Handler", runnable::toString); throw new ReportedException(crashReport); } } diff --git a/src/main/java/com/replaymod/core/ReplayMod.java b/src/main/java/com/replaymod/core/ReplayMod.java index cd3ee038..cfdd0b2a 100755 --- a/src/main/java/com/replaymod/core/ReplayMod.java +++ b/src/main/java/com/replaymod/core/ReplayMod.java @@ -6,7 +6,6 @@ import com.replaymod.core.gui.GuiReplaySettings; import com.replaymod.core.gui.RestoreReplayGui; import com.replaymod.core.handler.MainMenuHandler; import com.replaymod.core.utils.OpenGLUtils; -import com.replaymod.render.utils.SoundHandler; import com.replaymod.replaystudio.util.I18n; import de.johni0702.minecraft.gui.container.GuiScreen; import lombok.Getter; @@ -14,15 +13,11 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.settings.GameSettings; import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReportCategory; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.ChatStyle; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.IChatComponent; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.*; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.fml.client.FMLClientHandler; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; @@ -76,8 +71,6 @@ public class ReplayMod { @Deprecated public static Configuration config; - @Deprecated - public static SoundHandler soundHandler = new SoundHandler(); private final KeyBindingRegistry keyBindingRegistry = new KeyBindingRegistry(); private final SettingsRegistry settingsRegistry = new SettingsRegistry(); @@ -120,7 +113,7 @@ public class ReplayMod { new MainMenuHandler().register(); - FMLCommonHandler.instance().bus().register(keyBindingRegistry); + MinecraftForge.EVENT_BUS.register(keyBindingRegistry); getKeyBindingRegistry().registerKeyBinding("replaymod.input.settings", 0, () -> { new GuiReplaySettings(null, settingsRegistry).display(); @@ -179,7 +172,7 @@ public class ReplayMod { public void runLater(Runnable runnable) { if (mc.isCallingFromMinecraftThread() && inRunLater) { - EventBus bus = FMLCommonHandler.instance().bus(); + EventBus bus = MinecraftForge.EVENT_BUS; bus.register(new Object() { @SubscribeEvent public void onRenderTick(TickEvent.RenderTickEvent event) { @@ -228,13 +221,13 @@ public class ReplayMod { private void printToChat(boolean warning, String message, Object... args) { if (getSettingsRegistry().get(Setting.NOTIFICATIONS)) { // Some nostalgia: "§8[§6Replay Mod§8]§r Your message goes here" - ChatStyle coloredDarkGray = new ChatStyle().setColor(EnumChatFormatting.DARK_GRAY); - ChatStyle coloredGold = new ChatStyle().setColor(EnumChatFormatting.GOLD); - IChatComponent text = new ChatComponentText("[").setChatStyle(coloredDarkGray) - .appendSibling(new ChatComponentTranslation("replaymod.title").setChatStyle(coloredGold)) - .appendSibling(new ChatComponentText("] ")) - .appendSibling(new ChatComponentTranslation(message, args).setChatStyle(new ChatStyle() - .setColor(warning ? EnumChatFormatting.RED : EnumChatFormatting.DARK_GREEN))); + Style coloredDarkGray = new Style().setColor(TextFormatting.DARK_GRAY); + Style coloredGold = new Style().setColor(TextFormatting.GOLD); + ITextComponent text = new TextComponentString("[").setStyle(coloredDarkGray) + .appendSibling(new TextComponentTranslation("replaymod.title").setStyle(coloredGold)) + .appendSibling(new TextComponentString("] ")) + .appendSibling(new TextComponentTranslation(message, args).setStyle(new Style() + .setColor(warning ? TextFormatting.RED : TextFormatting.DARK_GREEN))); // Send message to chat GUI // The ingame GUI is initialized at startup, therefore this is possible before the client is connected mc.ingameGUI.getChatGUI().printChatMessage(text); diff --git a/src/main/java/com/replaymod/core/SettingsRegistry.java b/src/main/java/com/replaymod/core/SettingsRegistry.java index 8d4636d8..2feef45e 100644 --- a/src/main/java/com/replaymod/core/SettingsRegistry.java +++ b/src/main/java/com/replaymod/core/SettingsRegistry.java @@ -2,8 +2,8 @@ package com.replaymod.core; import com.replaymod.core.events.SettingsChangedEvent; import net.minecraft.client.resources.I18n; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.fml.common.FMLCommonHandler; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -83,7 +83,7 @@ public class SettingsRegistry { throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported."); } settings.put(key, value); - FMLCommonHandler.instance().bus().post(new SettingsChangedEvent(this, key)); + MinecraftForge.EVENT_BUS.post(new SettingsChangedEvent(this, key)); } public void save() { diff --git a/src/main/java/com/replaymod/core/handler/MainMenuHandler.java b/src/main/java/com/replaymod/core/handler/MainMenuHandler.java index d12bbeaa..475f02ea 100644 --- a/src/main/java/com/replaymod/core/handler/MainMenuHandler.java +++ b/src/main/java/com/replaymod/core/handler/MainMenuHandler.java @@ -6,8 +6,6 @@ import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import java.util.List; - /** * Moves certain buttons on the main menu upwards so we can inject our own. */ @@ -18,14 +16,12 @@ public class MainMenuHandler { @SubscribeEvent public void onInit(GuiScreenEvent.InitGuiEvent.Post event) { - if (event.gui instanceof GuiMainMenu) { - @SuppressWarnings("unchecked") - List buttonList = event.buttonList; - for (GuiButton button : buttonList) { + if (event.getGui() instanceof GuiMainMenu) { + for (GuiButton button : event.getButtonList()) { // Buttons that aren't in a rectangle directly above our space don't need moving - if (button.xPosition + button.width < event.gui.width / 2 - 100 - || button.xPosition > event.gui.width / 2 + 100 - || button.yPosition > event.gui.height / 4 + 10 + 4 * 24) continue; + if (button.xPosition + button.width < event.getGui().width / 2 - 100 + || button.xPosition > event.getGui().width / 2 + 100 + || button.yPosition > event.getGui().height / 4 + 10 + 4 * 24) continue; // Move button up to make space for two rows of buttons // and then move back down by 10 to compensate for the space to the exit button that was already there button.yPosition -= 2 * 24 - 10; diff --git a/src/main/java/com/replaymod/core/utils/OpenGLUtils.java b/src/main/java/com/replaymod/core/utils/OpenGLUtils.java index 8f3653de..b7260b7a 100644 --- a/src/main/java/com/replaymod/core/utils/OpenGLUtils.java +++ b/src/main/java/com/replaymod/core/utils/OpenGLUtils.java @@ -2,7 +2,7 @@ package com.replaymod.core.utils; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL11; @@ -35,7 +35,7 @@ public class OpenGLUtils { float f5 = 1.0F / textureHeight; Tessellator tessellator = Tessellator.getInstance(); - WorldRenderer vertexBuffer = tessellator.getWorldRenderer(); + VertexBuffer vertexBuffer = tessellator.getBuffer(); GlStateManager.translate(x+(width/2), y+(width/2), 0); GlStateManager.rotate(rotation, 0, 0, 1); vertexBuffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); diff --git a/src/main/java/com/replaymod/core/utils/Restrictions.java b/src/main/java/com/replaymod/core/utils/Restrictions.java index 06248597..f3f0f437 100644 --- a/src/main/java/com/replaymod/core/utils/Restrictions.java +++ b/src/main/java/com/replaymod/core/utils/Restrictions.java @@ -1,7 +1,7 @@ package com.replaymod.core.utils; import net.minecraft.network.PacketBuffer; -import net.minecraft.network.play.server.S3FPacketCustomPayload; +import net.minecraft.network.play.server.SPacketCustomPayload; /** * Restrictions set by the server, @@ -14,7 +14,7 @@ public class Restrictions { private boolean onlyFirstPerson; private boolean onlyRecordingPlayer; - public String handle(S3FPacketCustomPayload packet) { + public String handle(SPacketCustomPayload packet) { PacketBuffer buffer = packet.getBufferData(); while (buffer.isReadable()) { String name = buffer.readStringFromBuffer(64); diff --git a/src/main/java/com/replaymod/core/utils/Utils.java b/src/main/java/com/replaymod/core/utils/Utils.java index fb32c44c..3f42aff6 100644 --- a/src/main/java/com/replaymod/core/utils/Utils.java +++ b/src/main/java/com/replaymod/core/utils/Utils.java @@ -160,7 +160,7 @@ public class Utils { } public static ResourceLocation getResourceLocationForPlayerUUID(UUID uuid) { - NetworkPlayerInfo info = getMinecraft().getNetHandler().getPlayerInfo(uuid); + NetworkPlayerInfo info = getMinecraft().getConnection().getPlayerInfo(uuid); ResourceLocation skinLocation; if (info != null && info.hasLocationSkin()) { skinLocation = info.getLocationSkin(); diff --git a/src/main/java/com/replaymod/editor/handler/GuiHandler.java b/src/main/java/com/replaymod/editor/handler/GuiHandler.java index 7fdb59e1..adae091a 100644 --- a/src/main/java/com/replaymod/editor/handler/GuiHandler.java +++ b/src/main/java/com/replaymod/editor/handler/GuiHandler.java @@ -8,11 +8,8 @@ import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.resources.I18n; import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import java.util.List; - public class GuiHandler { private static final int BUTTON_REPLAY_EDITOR = 17890237; @@ -23,31 +20,28 @@ public class GuiHandler { } public void register() { - FMLCommonHandler.instance().bus().register(this); MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent public void injectIntoMainMenu(GuiScreenEvent.InitGuiEvent event) { - if (!(event.gui instanceof GuiMainMenu)) { + if (!(event.getGui() instanceof GuiMainMenu)) { return; } - @SuppressWarnings("unchecked") - List buttonList = event.buttonList; - GuiButton button = new GuiButton(BUTTON_REPLAY_EDITOR, event.gui.width / 2 + 2, - event.gui.height / 4 + 10 + 3 * 24, I18n.format("replaymod.gui.replayeditor")); + GuiButton button = new GuiButton(BUTTON_REPLAY_EDITOR, event.getGui().width / 2 + 2, + event.getGui().height / 4 + 10 + 3 * 24, I18n.format("replaymod.gui.replayeditor")); button.width = button.width / 2 - 2; - buttonList.add(button); + event.getButtonList().add(button); } @SubscribeEvent public void onButton(GuiScreenEvent.ActionPerformedEvent.Pre event) { - if(!event.button.enabled) return; + if(!event.getButton().enabled) return; - if (event.gui instanceof GuiMainMenu) { - if (event.button.id == BUTTON_REPLAY_EDITOR) { - new GuiReplayEditor(GuiScreen.wrap(event.gui), mod.getCore()).display(); + if (event.getGui() instanceof GuiMainMenu) { + if (event.getButton().id == BUTTON_REPLAY_EDITOR) { + new GuiReplayEditor(GuiScreen.wrap(event.getGui()), mod.getCore()).display(); } } } diff --git a/src/main/java/com/replaymod/extras/FullBrightness.java b/src/main/java/com/replaymod/extras/FullBrightness.java index 754bdf8e..9564df54 100644 --- a/src/main/java/com/replaymod/extras/FullBrightness.java +++ b/src/main/java/com/replaymod/extras/FullBrightness.java @@ -9,7 +9,7 @@ import de.johni0702.minecraft.gui.element.GuiImage; import de.johni0702.minecraft.gui.element.IGuiImage; import de.johni0702.minecraft.gui.layout.HorizontalLayout; import net.minecraft.client.settings.GameSettings; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import org.lwjgl.input.Keyboard; @@ -40,7 +40,7 @@ public class FullBrightness implements Extra { } }); - FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent diff --git a/src/main/java/com/replaymod/extras/HotkeyButtons.java b/src/main/java/com/replaymod/extras/HotkeyButtons.java index c660e37e..b559c7b2 100644 --- a/src/main/java/com/replaymod/extras/HotkeyButtons.java +++ b/src/main/java/com/replaymod/extras/HotkeyButtons.java @@ -17,7 +17,7 @@ import de.johni0702.minecraft.gui.layout.GridLayout; import de.johni0702.minecraft.gui.layout.HorizontalLayout; import de.johni0702.minecraft.gui.layout.LayoutData; import net.minecraft.client.resources.I18n; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.lwjgl.input.Keyboard; import org.lwjgl.util.Dimension; @@ -35,7 +35,7 @@ public class HotkeyButtons implements Extra { public void register(ReplayMod mod) throws Exception { this.mod = mod; - FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent diff --git a/src/main/java/com/replaymod/extras/LocalizationExtra.java b/src/main/java/com/replaymod/extras/LocalizationExtra.java index 994c45e9..27f0eb19 100644 --- a/src/main/java/com/replaymod/extras/LocalizationExtra.java +++ b/src/main/java/com/replaymod/extras/LocalizationExtra.java @@ -5,7 +5,7 @@ import com.replaymod.core.ReplayMod; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.IResourcePack; import net.minecraft.client.resources.data.IMetadataSection; -import net.minecraft.client.resources.data.IMetadataSerializer; +import net.minecraft.client.resources.data.MetadataSerializer; import net.minecraft.util.ResourceLocation; import org.apache.commons.io.IOUtils; @@ -99,12 +99,12 @@ public class LocalizationExtra implements Extra { } @Override - public Set getResourceDomains() { + public Set getResourceDomains() { return ImmutableSet.of("replaymod"); } @Override - public IMetadataSection getPackMetadata(IMetadataSerializer p_135058_1_, String p_135058_2_) throws IOException { + public T getPackMetadata(MetadataSerializer metadataSerializer, String metadataSectionName) throws IOException { return null; } diff --git a/src/main/java/com/replaymod/extras/playeroverview/PlayerOverview.java b/src/main/java/com/replaymod/extras/playeroverview/PlayerOverview.java index 67619f84..feb9b459 100644 --- a/src/main/java/com/replaymod/extras/playeroverview/PlayerOverview.java +++ b/src/main/java/com/replaymod/extras/playeroverview/PlayerOverview.java @@ -13,7 +13,6 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.client.event.RenderHandEvent; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.lwjgl.input.Keyboard; @@ -56,7 +55,6 @@ public class PlayerOverview implements Extra { } }); - FMLCommonHandler.instance().bus().register(this); MinecraftForge.EVENT_BUS.register(this); } diff --git a/src/main/java/com/replaymod/extras/playeroverview/PlayerOverviewGui.java b/src/main/java/com/replaymod/extras/playeroverview/PlayerOverviewGui.java index 12fb2d9c..7e0ce988 100644 --- a/src/main/java/com/replaymod/extras/playeroverview/PlayerOverviewGui.java +++ b/src/main/java/com/replaymod/extras/playeroverview/PlayerOverviewGui.java @@ -21,7 +21,8 @@ import de.johni0702.minecraft.gui.utils.Colors; import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EnumPlayerModelParts; -import net.minecraft.potion.Potion; +import net.minecraft.init.MobEffects; +import net.minecraft.init.SoundEvents; import net.minecraft.util.ResourceLocation; import org.lwjgl.util.Dimension; import org.lwjgl.util.ReadableDimension; @@ -46,14 +47,14 @@ public class PlayerOverviewGui extends GuiScreen implements Closeable { public final GuiCheckbox checkAll = new GuiCheckbox(contentPanel){ @Override public void onClick() { - getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(BUTTON_SOUND, 1.0F)); + getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.UI_BUTTON_CLICK, 1.0F)); playersScrollable.forEach(IGuiCheckbox.class).setChecked(true); } }.setLabel("").setChecked(true).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.showall")); public final GuiCheckbox uncheckAll = new GuiCheckbox(contentPanel){ @Override public void onClick() { - getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(BUTTON_SOUND, 1.0F)); + getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.UI_BUTTON_CLICK, 1.0F)); playersScrollable.forEach(IGuiCheckbox.class).setChecked(false); } }.setLabel("").setChecked(false).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.hideall")); @@ -145,7 +146,7 @@ public class PlayerOverviewGui extends GuiScreen implements Closeable { } private static boolean isSpectator(EntityPlayer e) { - return e.isInvisible() && e.getActivePotionEffect(Potion.invisibility) == null; + return e.isInvisible() && e.getActivePotionEffect(MobEffects.INVISIBILITY) == null; } private static final class PlayerComparator implements Comparator { diff --git a/src/main/java/com/replaymod/extras/youtube/YoutubeUpload.java b/src/main/java/com/replaymod/extras/youtube/YoutubeUpload.java index bd740632..6e695f17 100644 --- a/src/main/java/com/replaymod/extras/youtube/YoutubeUpload.java +++ b/src/main/java/com/replaymod/extras/youtube/YoutubeUpload.java @@ -17,8 +17,8 @@ public class YoutubeUpload implements Extra { @SubscribeEvent public void onGuiOpen(GuiScreenEvent.InitGuiEvent.Post event) { - if (GuiScreen.from(event.gui) instanceof GuiRenderingDone) { - GuiRenderingDone gui = (GuiRenderingDone) GuiScreen.from(event.gui); + if (GuiScreen.from(event.getGui()) instanceof GuiRenderingDone) { + GuiRenderingDone gui = (GuiRenderingDone) GuiScreen.from(event.getGui()); // Check if there already is a youtube button if (gui.actionsPanel.getChildren().stream().anyMatch(it -> it instanceof YoutubeButton)) { return; // Button already added diff --git a/src/main/java/com/replaymod/online/ReplayModOnline.java b/src/main/java/com/replaymod/online/ReplayModOnline.java index 44092066..ffdfd3bb 100644 --- a/src/main/java/com/replaymod/online/ReplayModOnline.java +++ b/src/main/java/com/replaymod/online/ReplayModOnline.java @@ -12,8 +12,8 @@ import com.replaymod.replaystudio.replay.ReplayFile; import com.replaymod.replaystudio.replay.ZipReplayFile; import com.replaymod.replaystudio.studio.ReplayStudio; import de.johni0702.minecraft.gui.container.GuiScreen; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; @@ -75,7 +75,7 @@ public class ReplayModOnline { } new GuiHandler(this).register(); - FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); } @Mod.EventHandler diff --git a/src/main/java/com/replaymod/online/api/replay/holders/MinecraftVersion.java b/src/main/java/com/replaymod/online/api/replay/holders/MinecraftVersion.java index a6ed8b22..de5d2285 100644 --- a/src/main/java/com/replaymod/online/api/replay/holders/MinecraftVersion.java +++ b/src/main/java/com/replaymod/online/api/replay/holders/MinecraftVersion.java @@ -2,7 +2,8 @@ package com.replaymod.online.api.replay.holders; public enum MinecraftVersion { - MC_1_8("Minecraft 1.8", "1.8"); + MC_1_8("Minecraft 1.8", "1.8"), + MC_1_9_4("Minecraft 1.9.4", "1.9.4"); private String niceName, apiName; diff --git a/src/main/java/com/replaymod/online/handler/GuiHandler.java b/src/main/java/com/replaymod/online/handler/GuiHandler.java index bf631767..8d36fa61 100644 --- a/src/main/java/com/replaymod/online/handler/GuiHandler.java +++ b/src/main/java/com/replaymod/online/handler/GuiHandler.java @@ -14,11 +14,9 @@ import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.resources.I18n; import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import java.io.File; -import java.util.List; public class GuiHandler { private static final int BUTTON_REPLAY_CENTER = 17890236; @@ -30,26 +28,23 @@ public class GuiHandler { } public void register() { - FMLCommonHandler.instance().bus().register(this); MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent public void injectIntoMainMenu(GuiScreenEvent.InitGuiEvent event) { - if (!(event.gui instanceof GuiMainMenu)) { + if (!(event.getGui() instanceof GuiMainMenu)) { return; } - @SuppressWarnings("unchecked") - List buttonList = event.buttonList; - GuiButton button = new GuiButton(BUTTON_REPLAY_CENTER, event.gui.width / 2 - 100, - event.gui.height / 4 + 10 + 4 * 24, I18n.format("replaymod.gui.replaycenter")); - buttonList.add(button); + GuiButton button = new GuiButton(BUTTON_REPLAY_CENTER, event.getGui().width / 2 - 100, + event.getGui().height / 4 + 10 + 4 * 24, I18n.format("replaymod.gui.replaycenter")); + event.getButtonList().add(button); } @SubscribeEvent public void injectIntoReplayViewer(GuiScreenEvent.InitGuiEvent.Post event) { - AbstractGuiScreen guiScreen = GuiScreen.from(event.gui); + AbstractGuiScreen guiScreen = GuiScreen.from(event.getGui()); if (!(guiScreen instanceof GuiReplayViewer)) { return; } @@ -75,15 +70,15 @@ public class GuiHandler { @SubscribeEvent public void onButton(GuiScreenEvent.ActionPerformedEvent.Pre event) { - if(!event.button.enabled) return; + if(!event.getButton().enabled) return; - if (event.gui instanceof GuiMainMenu) { - if (event.button.id == BUTTON_REPLAY_CENTER) { + if (event.getGui() instanceof GuiMainMenu) { + if (event.getButton().id == BUTTON_REPLAY_CENTER) { GuiReplayCenter replayCenter = new GuiReplayCenter(mod); if (mod.isLoggedIn()) { replayCenter.display(); } else { - new GuiLoginPrompt(mod.getApiClient(), GuiScreen.wrap(event.gui), replayCenter, true).display(); + new GuiLoginPrompt(mod.getApiClient(), GuiScreen.wrap(event.getGui()), replayCenter, true).display(); } } } diff --git a/src/main/java/com/replaymod/pathing/player/AbstractTimelinePlayer.java b/src/main/java/com/replaymod/pathing/player/AbstractTimelinePlayer.java index 04104787..367d28ee 100644 --- a/src/main/java/com/replaymod/pathing/player/AbstractTimelinePlayer.java +++ b/src/main/java/com/replaymod/pathing/player/AbstractTimelinePlayer.java @@ -11,7 +11,7 @@ import com.replaymod.replaystudio.pathing.path.Keyframe; import com.replaymod.replaystudio.pathing.path.Path; import com.replaymod.replaystudio.pathing.path.Timeline; import net.minecraft.client.Minecraft; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import javax.annotation.Nullable; @@ -65,7 +65,7 @@ public abstract class AbstractTimelinePlayer { } replayHandler.getReplaySender().setSyncModeAndWait(); - FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); lastTime = 0; mc.timer = new ReplayTimer(mc.timer); mc.timer.timerSpeed = 1; @@ -87,7 +87,7 @@ public abstract class AbstractTimelinePlayer { mc.timer = ((ReplayTimer) mc.timer).getWrapped(); replayHandler.getReplaySender().setReplaySpeed(0); replayHandler.getReplaySender().setAsyncMode(true); - FMLCommonHandler.instance().bus().unregister(this); + MinecraftForge.EVENT_BUS.unregister(this); return; } long time = getTimePassed(); diff --git a/src/main/java/com/replaymod/pathing/player/ReplayTimer.java b/src/main/java/com/replaymod/pathing/player/ReplayTimer.java index ca5858ed..e2f4f615 100644 --- a/src/main/java/com/replaymod/pathing/player/ReplayTimer.java +++ b/src/main/java/com/replaymod/pathing/player/ReplayTimer.java @@ -2,7 +2,7 @@ package com.replaymod.pathing.player; import com.replaymod.core.utils.WrappedTimer; import net.minecraft.util.Timer; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.Event; /** @@ -20,7 +20,7 @@ public class ReplayTimer extends WrappedTimer { copy(this, state); // Save our current state super.updateTimer(); // Update current state copy(state, this); // Restore our old state - FMLCommonHandler.instance().bus().post(new UpdatedEvent()); + MinecraftForge.EVENT_BUS.post(new UpdatedEvent()); } public Timer getWrapped() { diff --git a/src/main/java/com/replaymod/recording/ReplayModRecording.java b/src/main/java/com/replaymod/recording/ReplayModRecording.java index b2458985..ea066c8b 100644 --- a/src/main/java/com/replaymod/recording/ReplayModRecording.java +++ b/src/main/java/com/replaymod/recording/ReplayModRecording.java @@ -6,8 +6,8 @@ import com.replaymod.recording.handler.ConnectionEventHandler; import com.replaymod.recording.packet.PacketListener; import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraft.network.NetworkManager; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -54,7 +54,7 @@ public class ReplayModRecording { @Mod.EventHandler public void init(FMLInitializationEvent event) { - EventBus bus = FMLCommonHandler.instance().bus(); + EventBus bus = MinecraftForge.EVENT_BUS; bus.register(connectionEventHandler = new ConnectionEventHandler(logger, core)); NetworkRegistry.INSTANCE.newChannel(Restrictions.PLUGIN_CHANNEL, new RestrictionsChannelHandler()); diff --git a/src/main/java/com/replaymod/recording/gui/GuiRecordingOverlay.java b/src/main/java/com/replaymod/recording/gui/GuiRecordingOverlay.java index 775276f8..9a5a5e41 100644 --- a/src/main/java/com/replaymod/recording/gui/GuiRecordingOverlay.java +++ b/src/main/java/com/replaymod/recording/gui/GuiRecordingOverlay.java @@ -40,7 +40,7 @@ public class GuiRecordingOverlay { */ @SubscribeEvent public void renderRecordingIndicator(RenderGameOverlayEvent.Post event) { - if (event.type != RenderGameOverlayEvent.ElementType.ALL) return; + if (event.getType() != RenderGameOverlayEvent.ElementType.ALL) return; if (settingsRegistry.get(Setting.INDICATOR)) { FontRenderer fontRenderer = mc.fontRendererObj; fontRenderer.drawString(I18n.format("replaymod.gui.recording").toUpperCase(), 30, 18 - (fontRenderer.FONT_HEIGHT / 2), 0xffffffff); diff --git a/src/main/java/com/replaymod/recording/handler/RecordingEventHandler.java b/src/main/java/com/replaymod/recording/handler/RecordingEventHandler.java index 9dfb6f55..9129c159 100755 --- a/src/main/java/com/replaymod/recording/handler/RecordingEventHandler.java +++ b/src/main/java/com/replaymod/recording/handler/RecordingEventHandler.java @@ -1,24 +1,22 @@ package com.replaymod.recording.handler; import com.replaymod.recording.packet.PacketListener; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import net.minecraft.client.Minecraft; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.network.Packet; -import net.minecraft.network.PacketBuffer; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.network.play.server.*; -import net.minecraft.network.play.server.S14PacketEntity.S17PacketEntityLookMove; import net.minecraft.server.integrated.IntegratedServer; -import net.minecraft.util.BlockPos; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.minecart.MinecartInteractEvent; import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent; -import net.minecraftforge.event.entity.player.PlayerUseItemEvent; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent.ItemPickupEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; @@ -32,24 +30,24 @@ public class RecordingEventHandler { private final PacketListener packetListener; private Double lastX, lastY, lastZ; - private ItemStack[] playerItems = new ItemStack[5]; + private ItemStack[] playerItems = new ItemStack[6]; private int ticksSinceLastCorrection; private boolean wasSleeping; private int lastRiding = -1; private Integer rotationYawHeadBefore; + private boolean wasHandActive; + private EnumHand lastActiveHand; public RecordingEventHandler(PacketListener packetListener) { this.packetListener = packetListener; } public void register() { - FMLCommonHandler.instance().bus().register(this); MinecraftForge.EVENT_BUS.register(this); ((RecordingEventSender) mc.renderGlobal).setRecordingEventHandler(this); } public void unregister() { - FMLCommonHandler.instance().bus().unregister(this); MinecraftForge.EVENT_BUS.unregister(this); RecordingEventSender recordingEventSender = ((RecordingEventSender) mc.renderGlobal); if (recordingEventSender.getRecordingEventHandler() == this) { @@ -59,7 +57,7 @@ public class RecordingEventHandler { public void onPlayerJoin() { try { - packetListener.save(spawnPlayer(mc.thePlayer)); + packetListener.save(new SPacketSpawnPlayer(mc.thePlayer)); } catch(Exception e1) { e1.printStackTrace(); } @@ -67,39 +65,28 @@ public class RecordingEventHandler { public void onPlayerRespawn() { try { - packetListener.save(spawnPlayer(mc.thePlayer)); + packetListener.save(new SPacketSpawnPlayer(mc.thePlayer)); } catch(Exception e) { e.printStackTrace(); } } - private S0CPacketSpawnPlayer spawnPlayer(EntityPlayer player) { + public void onClientSound(SoundEvent sound, SoundCategory category, + double x, double y, double z, float volume, float pitch) { try { - S0CPacketSpawnPlayer packet = new S0CPacketSpawnPlayer(); - - ByteBuf bb = Unpooled.buffer(); - PacketBuffer pb = new PacketBuffer(bb); - - pb.writeVarIntToBuffer(player.getEntityId()); - pb.writeUuid(EntityPlayer.getUUID(player.getGameProfile())); - - pb.writeInt(MathHelper.floor_double(player.posX * 32.0D)); - pb.writeInt(MathHelper.floor_double(player.posY * 32.0D)); - pb.writeInt(MathHelper.floor_double(player.posZ * 32.0D)); - pb.writeByte((byte) ((int) (player.rotationYaw * 256.0F / 360.0F))); - pb.writeByte((byte) ((int) (player.rotationPitch * 256.0F / 360.0F))); - - ItemStack itemstack = player.inventory.getCurrentItem(); - pb.writeShort(itemstack == null ? 0 : Item.getIdFromItem(itemstack.getItem())); - - player.getDataWatcher().writeTo(pb); - - packet.readPacketData(pb); - - return packet; + // Send to all other players in ServerWorldEventHandler#playSoundToAllNearExcept + packetListener.save(new SPacketSoundEffect(sound, category, x, y, z, volume, pitch)); + } catch(Exception e) { + e.printStackTrace(); + } + } + + public void onClientEffect(int type, BlockPos pos, int data) { + try { + // Send to all other players in ServerWorldEventHandler#playEvent + packetListener.save(new SPacketEffect(type, pos, data, false)); } catch(Exception e) { e.printStackTrace(); - return null; } } @@ -131,19 +118,14 @@ public class RecordingEventHandler { lastZ = e.player.posZ; Packet packet; - if(force || Math.abs(dx) > 4.0 || Math.abs(dy) > 4.0 || Math.abs(dz) > 4.0) { - int x = MathHelper.floor_double(e.player.posX * 32.0D); - int y = MathHelper.floor_double(e.player.posY * 32.0D); - int z = MathHelper.floor_double(e.player.posZ * 32.0D); - byte yaw = (byte) ((int) (e.player.rotationYaw * 256.0F / 360.0F)); - byte pitch = (byte) ((int) (e.player.rotationPitch * 256.0F / 360.0F)); - packet = new S18PacketEntityTeleport(e.player.getEntityId(), x, y, z, yaw, pitch, e.player.onGround); + if (force || Math.abs(dx) > 8.0 || Math.abs(dy) > 8.0 || Math.abs(dz) > 8.0) { + packet = new SPacketEntityTeleport(e.player); } else { byte newYaw = (byte) ((int) (e.player.rotationYaw * 256.0F / 360.0F)); byte newPitch = (byte) ((int) (e.player.rotationPitch * 256.0F / 360.0F)); - packet = new S17PacketEntityLookMove(e.player.getEntityId(), - (byte) Math.round(dx * 32), (byte) Math.round(dy * 32), (byte) Math.round(dz * 32), + packet = new SPacketEntity.S17PacketEntityLookMove(e.player.getEntityId(), + (short) Math.round(dx * 4096), (short) Math.round(dy * 4096), (short) Math.round(dz * 4096), newYaw, newPitch, e.player.onGround); } @@ -153,37 +135,16 @@ public class RecordingEventHandler { int rotationYawHead = ((int)(e.player.rotationYawHead * 256.0F / 360.0F)); if(!Objects.equals(rotationYawHead, rotationYawHeadBefore)) { - S19PacketEntityHeadLook head = new S19PacketEntityHeadLook(); - ByteBuf bb1 = Unpooled.buffer(); - PacketBuffer pb1 = new PacketBuffer(bb1); - - pb1.writeVarIntToBuffer(e.player.getEntityId()); - pb1.writeByte(rotationYawHead); - - head.readPacketData(pb1); - - packetListener.save(head); - + packetListener.save(new SPacketEntityHeadLook(e.player, (byte) rotationYawHead)); rotationYawHeadBefore = rotationYawHead; } - S12PacketEntityVelocity vel = new S12PacketEntityVelocity(e.player.getEntityId(), e.player.motionX, e.player.motionY, e.player.motionZ); - packetListener.save(vel); + packetListener.save(new SPacketEntityVelocity(e.player.getEntityId(), e.player.motionX, e.player.motionY, e.player.motionZ)); //Animation Packets //Swing Animation - if(e.player.swingProgressInt == 1) { - S0BPacketAnimation pac = new S0BPacketAnimation(); - - ByteBuf bb = Unpooled.buffer(); - PacketBuffer pb = new PacketBuffer(bb); - - pb.writeVarIntToBuffer(e.player.getEntityId()); - pb.writeByte(0); - - pac.readPacketData(pb); - - packetListener.save(pac); + if (e.player.isSwingInProgress && e.player.swingProgressInt == -1) { + packetListener.save(new SPacketAnimation(e.player, e.player.swingingHand == EnumHand.MAIN_HAND ? 0 : 3)); } /* @@ -207,77 +168,64 @@ public class RecordingEventHandler { */ //Inventory Handling - if(playerItems[0] != mc.thePlayer.getHeldItem()) { - playerItems[0] = mc.thePlayer.getHeldItem(); - S04PacketEntityEquipment pee = new S04PacketEntityEquipment(e.player.getEntityId(), 0, playerItems[0]); - packetListener.save(pee); + if (playerItems[0] != mc.thePlayer.getHeldItem(EnumHand.MAIN_HAND)) { + playerItems[0] = mc.thePlayer.getHeldItem(EnumHand.MAIN_HAND); + packetListener.save(new SPacketEntityEquipment(e.player.getEntityId(), EntityEquipmentSlot.MAINHAND, playerItems[0])); } - if(playerItems[1] != mc.thePlayer.inventory.armorInventory[0]) { - playerItems[1] = mc.thePlayer.inventory.armorInventory[0]; - S04PacketEntityEquipment pee = new S04PacketEntityEquipment(e.player.getEntityId(), 1, playerItems[1]); - packetListener.save(pee); + if (playerItems[1] != mc.thePlayer.getHeldItem(EnumHand.OFF_HAND)) { + playerItems[1] = mc.thePlayer.getHeldItem(EnumHand.OFF_HAND); + packetListener.save(new SPacketEntityEquipment(e.player.getEntityId(), EntityEquipmentSlot.OFFHAND, playerItems[1])); } - if(playerItems[2] != mc.thePlayer.inventory.armorInventory[1]) { - playerItems[2] = mc.thePlayer.inventory.armorInventory[1]; - S04PacketEntityEquipment pee = new S04PacketEntityEquipment(e.player.getEntityId(), 2, playerItems[2]); - packetListener.save(pee); + if (playerItems[2] != mc.thePlayer.inventory.armorInventory[0]) { + playerItems[2] = mc.thePlayer.inventory.armorInventory[0]; + packetListener.save(new SPacketEntityEquipment(e.player.getEntityId(), EntityEquipmentSlot.FEET, playerItems[2])); } - if(playerItems[3] != mc.thePlayer.inventory.armorInventory[2]) { - playerItems[3] = mc.thePlayer.inventory.armorInventory[2]; - S04PacketEntityEquipment pee = new S04PacketEntityEquipment(e.player.getEntityId(), 3, playerItems[3]); - packetListener.save(pee); + if (playerItems[3] != mc.thePlayer.inventory.armorInventory[1]) { + playerItems[3] = mc.thePlayer.inventory.armorInventory[1]; + packetListener.save(new SPacketEntityEquipment(e.player.getEntityId(), EntityEquipmentSlot.LEGS, playerItems[3])); } - if(playerItems[4] != mc.thePlayer.inventory.armorInventory[3]) { - playerItems[4] = mc.thePlayer.inventory.armorInventory[3]; - S04PacketEntityEquipment pee = new S04PacketEntityEquipment(e.player.getEntityId(), 4, playerItems[4]); - packetListener.save(pee); + if (playerItems[4] != mc.thePlayer.inventory.armorInventory[2]) { + playerItems[4] = mc.thePlayer.inventory.armorInventory[2]; + packetListener.save(new SPacketEntityEquipment(e.player.getEntityId(), EntityEquipmentSlot.CHEST, playerItems[4])); + } + + if (playerItems[5] != mc.thePlayer.inventory.armorInventory[3]) { + playerItems[5] = mc.thePlayer.inventory.armorInventory[3]; + packetListener.save(new SPacketEntityEquipment(e.player.getEntityId(), EntityEquipmentSlot.HEAD, playerItems[5])); } //Leaving Ride if((!mc.thePlayer.isRiding() && lastRiding != -1) || - (mc.thePlayer.isRiding() && lastRiding != mc.thePlayer.ridingEntity.getEntityId())) { + (mc.thePlayer.isRiding() && lastRiding != mc.thePlayer.getRidingEntity().getEntityId())) { if(!mc.thePlayer.isRiding()) { lastRiding = -1; } else { - lastRiding = mc.thePlayer.ridingEntity.getEntityId(); + lastRiding = mc.thePlayer.getRidingEntity().getEntityId(); } - - S1BPacketEntityAttach pea = new S1BPacketEntityAttach(); - - ByteBuf buf = Unpooled.buffer(); - PacketBuffer pbuf = new PacketBuffer(buf); - - pbuf.writeInt(e.player.getEntityId()); - pbuf.writeInt(lastRiding); - pbuf.writeBoolean(false); - - pea.readPacketData(pbuf); - - packetListener.save(pea); + packetListener.save(new SPacketEntityAttach(e.player, e.player.getRidingEntity())); } //Sleeping if(!mc.thePlayer.isPlayerSleeping() && wasSleeping) { - S0BPacketAnimation pac = new S0BPacketAnimation(); - - ByteBuf bb = Unpooled.buffer(); - PacketBuffer pb = new PacketBuffer(bb); - - pb.writeVarIntToBuffer(e.player.getEntityId()); - pb.writeByte(2); - - pac.readPacketData(pb); - - packetListener.save(pac); - + packetListener.save(new SPacketAnimation(e.player, 2)); wasSleeping = false; } + // Active hand (e.g. eating, drinking, blocking) + if (mc.thePlayer.isHandActive() ^ wasHandActive || mc.thePlayer.getActiveHand() != lastActiveHand) { + wasHandActive = mc.thePlayer.isHandActive(); + lastActiveHand = mc.thePlayer.getActiveHand(); + EntityDataManager dataManager = new EntityDataManager(null); + int state = (wasHandActive ? 1 : 0) | (lastActiveHand == EnumHand.OFF_HAND ? 2 : 0); + dataManager.register(EntityLiving.HAND_STATES, (byte) state); + packetListener.save(new SPacketEntityMetadata(mc.thePlayer.getEntityId(), dataManager, true)); + } + } catch(Exception e1) { e1.printStackTrace(); } @@ -286,27 +234,7 @@ public class RecordingEventHandler { @SubscribeEvent public void onPickupItem(ItemPickupEvent event) { try { - packetListener.save(new S0DPacketCollectItem(event.pickedUp.getEntityId(), event.player.getEntityId())); - } catch(Exception e) { - e.printStackTrace(); - } - } - - @SubscribeEvent - public void onStartEating(PlayerUseItemEvent.Start event) { - try { - if(!event.entityPlayer.isEating()) return; - S0BPacketAnimation packet = new S0BPacketAnimation(); - - ByteBuf bb = Unpooled.buffer(); - PacketBuffer pb = new PacketBuffer(bb); - - pb.writeVarIntToBuffer(event.entityPlayer.getEntityId()); - pb.writeByte(3); - - packet.readPacketData(pb); - - packetListener.save(packet); + packetListener.save(new SPacketCollectItem(event.pickedUp.getEntityId(), event.player.getEntityId())); } catch(Exception e) { e.printStackTrace(); } @@ -315,21 +243,11 @@ public class RecordingEventHandler { @SubscribeEvent public void onSleep(PlayerSleepInBedEvent event) { try { - if(event.entityPlayer != mc.thePlayer) { + if (event.getEntityPlayer() != mc.thePlayer) { return; } - S0APacketUseBed pub = new S0APacketUseBed(); - - ByteBuf buf = Unpooled.buffer(); - PacketBuffer pbuf = new PacketBuffer(buf); - - pbuf.writeVarIntToBuffer(event.entityPlayer.getEntityId()); - pbuf.writeBlockPos(event.pos); - - pub.readPacketData(pbuf); - - packetListener.save(pub); + packetListener.save(new SPacketUseBed(event.getEntityPlayer(), event.getPos())); wasSleeping = true; @@ -341,24 +259,13 @@ public class RecordingEventHandler { @SubscribeEvent public void enterMinecart(MinecartInteractEvent event) { try { - if(event.player != mc.thePlayer) { + if(event.getEntity() != mc.thePlayer) { return; } - S1BPacketEntityAttach pea = new S1BPacketEntityAttach(); + packetListener.save(new SPacketEntityAttach(event.getPlayer(), event.getMinecart())); - ByteBuf buf = Unpooled.buffer(); - PacketBuffer pbuf = new PacketBuffer(buf); - - pbuf.writeInt(event.player.getEntityId()); - pbuf.writeInt(event.minecart.getEntityId()); - pbuf.writeBoolean(false); - - pea.readPacketData(pbuf); - - packetListener.save(pea); - - lastRiding = event.minecart.getEntityId(); + lastRiding = event.getMinecart().getEntityId(); } catch(Exception e) { e.printStackTrace(); } @@ -367,7 +274,7 @@ public class RecordingEventHandler { public void onBlockBreakAnim(int breakerId, BlockPos pos, int progress) { EntityPlayer thePlayer = mc.thePlayer; if (thePlayer != null && breakerId == thePlayer.getEntityId()) { - packetListener.save(new S25PacketBlockBreakAnim(breakerId, pos, progress)); + packetListener.save(new SPacketBlockBreakAnim(breakerId, pos, progress)); } } diff --git a/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerPlayClient.java b/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerPlayClient.java index 3f86c108..b7db8327 100644 --- a/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerPlayClient.java +++ b/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerPlayClient.java @@ -4,8 +4,8 @@ import com.replaymod.recording.handler.RecordingEventHandler; import net.minecraft.client.Minecraft; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.client.network.NetworkPlayerInfo; -import net.minecraft.network.play.server.S07PacketRespawn; -import net.minecraft.network.play.server.S38PacketPlayerListItem; +import net.minecraft.network.play.server.SPacketPlayerListItem; +import net.minecraft.network.play.server.SPacketRespawn; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -36,12 +36,12 @@ public abstract class MixinNetHandlerPlayClient { * @param ci Callback info */ @Inject(method = "handlePlayerListItem", at=@At("HEAD")) - public void recordOwnJoin(S38PacketPlayerListItem packet, CallbackInfo ci) { + public void recordOwnJoin(SPacketPlayerListItem packet, CallbackInfo ci) { if (gameController.thePlayer == null) return; RecordingEventHandler handler = getRecordingEventHandler(); - if (handler != null && packet.getAction() == S38PacketPlayerListItem.Action.ADD_PLAYER) { - for (S38PacketPlayerListItem.AddPlayerData data : packet.getEntries()) { + if (handler != null && packet.getAction() == SPacketPlayerListItem.Action.ADD_PLAYER) { + for (SPacketPlayerListItem.AddPlayerData data : packet.getEntries()) { if (data.getProfile() == null || data.getProfile().getId() == null) continue; // Only add spawn packet for our own player and only if he isn't known yet if (data.getProfile().getId().equals(Minecraft.getMinecraft().thePlayer.getGameProfile().getId()) @@ -55,12 +55,12 @@ public abstract class MixinNetHandlerPlayClient { /** * Record the own player entity respawning. * We cannot use the {@link net.minecraftforge.event.entity.EntityJoinWorldEvent} because that would also include - * the first spawn which is already handled by {@link #recordOwnJoin(S38PacketPlayerListItem, CallbackInfo)}. + * the first spawn which is already handled by {@link #recordOwnJoin(SPacketPlayerListItem, CallbackInfo)}. * @param packet The packet * @param ci Callback info */ @Inject(method = "handleRespawn", at=@At("RETURN")) - public void recordOwnRespawn(S07PacketRespawn packet, CallbackInfo ci) { + public void recordOwnRespawn(SPacketRespawn packet, CallbackInfo ci) { RecordingEventHandler handler = getRecordingEventHandler(); if (handler != null) { handler.onPlayerRespawn(); diff --git a/src/main/java/com/replaymod/recording/mixin/MixinPlayerControllerMP.java b/src/main/java/com/replaymod/recording/mixin/MixinPlayerControllerMP.java new file mode 100644 index 00000000..366141e0 --- /dev/null +++ b/src/main/java/com/replaymod/recording/mixin/MixinPlayerControllerMP.java @@ -0,0 +1,28 @@ +package com.replaymod.recording.mixin; + +import com.replaymod.recording.handler.RecordingEventHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.PlayerControllerMP; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(PlayerControllerMP.class) +public abstract class MixinPlayerControllerMP implements RecordingEventHandler.RecordingEventSender { + + @Shadow + private Minecraft mc; + + // Redirects the call to playEvent without the initial player argument to the method with that argument + // The new method will then play it and (if applicable) record it. (See MixinWorldClient) + // This is necessary for the block break event (particles and sound) to be recorded. Otherwise it looks like the + // event was emitted because of a packet (player will be null) and not as it actually was (by the player). + @Redirect(method = "onPlayerDestroyBlock", at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/World;playEvent(ILnet/minecraft/util/math/BlockPos;I)V")) + public void replayModRecording_playEvent_fixed(World world, int type, BlockPos pos, int data) { + world.playEvent(mc.thePlayer, type, pos, data); + } +} diff --git a/src/main/java/com/replaymod/recording/mixin/MixinRenderGlobal.java b/src/main/java/com/replaymod/recording/mixin/MixinRenderGlobal.java index d9e11de1..a27cbf0c 100644 --- a/src/main/java/com/replaymod/recording/mixin/MixinRenderGlobal.java +++ b/src/main/java/com/replaymod/recording/mixin/MixinRenderGlobal.java @@ -2,7 +2,7 @@ package com.replaymod.recording.mixin; import com.replaymod.recording.handler.RecordingEventHandler; import net.minecraft.client.renderer.RenderGlobal; -import net.minecraft.util.BlockPos; +import net.minecraft.util.math.BlockPos; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/com/replaymod/recording/mixin/MixinWorldClient.java b/src/main/java/com/replaymod/recording/mixin/MixinWorldClient.java new file mode 100644 index 00000000..74a5a57c --- /dev/null +++ b/src/main/java/com/replaymod/recording/mixin/MixinWorldClient.java @@ -0,0 +1,62 @@ +package com.replaymod.recording.mixin; + +import com.replaymod.recording.handler.RecordingEventHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.profiler.Profiler; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldProvider; +import net.minecraft.world.storage.ISaveHandler; +import net.minecraft.world.storage.WorldInfo; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(WorldClient.class) +public abstract class MixinWorldClient extends World implements RecordingEventHandler.RecordingEventSender { + @Shadow + private Minecraft mc; + + protected MixinWorldClient(ISaveHandler saveHandlerIn, WorldInfo info, WorldProvider providerIn, Profiler profilerIn, boolean client) { + super(saveHandlerIn, info, providerIn, profilerIn, client); + } + + private RecordingEventHandler replayModRecording_getRecordingEventHandler() { + return ((RecordingEventHandler.RecordingEventSender) mc.renderGlobal).getRecordingEventHandler(); + } + + // Sounds that are emitted by thePlayer no longer take the long way over the server + // but are instead played directly by the client. The server only sends these sounds to + // other clients so we have to record them manually. + // E.g. Block place sounds + @Inject(method = "playSound", at = @At("HEAD")) + public void replayModRecording_recordClientSound(EntityPlayer player, double x, double y, double z, SoundEvent sound, SoundCategory category, + float volume, float pitch, CallbackInfo ci) { + if (player == mc.thePlayer) { + RecordingEventHandler handler = replayModRecording_getRecordingEventHandler(); + if (handler != null) { + handler.onClientSound(sound, category, x, y, z, volume, pitch); + } + } + } + + // Same goes for level events (also called effects). E.g. door open, block break, etc. + // These are handled in the World class, so we override the method in WorldClient and add our special handling. + @Override + public void playEvent(EntityPlayer player, int type, BlockPos pos, int data) { + if (player == mc.thePlayer) { + // We caused this event, the server won't send it to us + RecordingEventHandler handler = replayModRecording_getRecordingEventHandler(); + if (handler != null) { + handler.onClientEffect(type, pos, data); + } + } + super.playEvent(player, type, pos, data); + } +} diff --git a/src/main/java/com/replaymod/recording/packet/PacketListener.java b/src/main/java/com/replaymod/recording/packet/PacketListener.java index c6a3c8e7..3f721ec8 100755 --- a/src/main/java/com/replaymod/recording/packet/PacketListener.java +++ b/src/main/java/com/replaymod/recording/packet/PacketListener.java @@ -9,21 +9,29 @@ import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import net.minecraft.client.Minecraft; -import net.minecraft.entity.DataWatcher; import net.minecraft.entity.Entity; import net.minecraft.network.EnumConnectionState; import net.minecraft.network.EnumPacketDirection; import net.minecraft.network.Packet; import net.minecraft.network.PacketBuffer; -import net.minecraft.network.play.server.*; -import net.minecraft.util.ChatComponentText; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.network.play.server.SPacketCollectItem; +import net.minecraft.network.play.server.SPacketCustomPayload; +import net.minecraft.network.play.server.SPacketDisconnect; +import net.minecraft.network.play.server.SPacketResourcePackSend; +import net.minecraft.network.play.server.SPacketSpawnMob; +import net.minecraft.network.play.server.SPacketSpawnPlayer; +import net.minecraft.util.text.TextComponentString; import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.DataOutputStream; import java.io.IOException; -import java.util.*; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -84,16 +92,13 @@ public class PacketListener extends ChannelInboundHandlerAdapter { public void save(Packet packet) { try { - if(packet instanceof S0CPacketSpawnPlayer) { - UUID uuid = ((S0CPacketSpawnPlayer) packet).getPlayer(); + if(packet instanceof SPacketSpawnPlayer) { + UUID uuid = ((SPacketSpawnPlayer) packet).getUniqueId(); Set uuids = new HashSet<>(Arrays.asList(metaData.getPlayers())); uuids.add(uuid.toString()); metaData.setPlayers(uuids.toArray(new String[uuids.size()])); saveMetaData(); } - if (packet instanceof S46PacketSetCompressionLevel) { - return; // Replay data is never compressed on the packet level - } byte[] bytes = getPacketData(packet); long now = System.currentTimeMillis(); @@ -154,16 +159,16 @@ public class PacketListener extends ChannelInboundHandlerAdapter { try { Packet packet = (Packet) msg; - if(packet instanceof S0DPacketCollectItem) { + if(packet instanceof SPacketCollectItem) { if(mc.thePlayer != null || - ((S0DPacketCollectItem) packet).getEntityID() == mc.thePlayer.getEntityId()) { + ((SPacketCollectItem) packet).getEntityID() == mc.thePlayer.getEntityId()) { super.channelRead(ctx, msg); return; } } - if (packet instanceof S48PacketResourcePackSend) { - save(resourcePackRecorder.handleResourcePack((S48PacketResourcePackSend) packet)); + if (packet instanceof SPacketResourcePackSend) { + save(resourcePackRecorder.handleResourcePack((SPacketResourcePackSend) packet)); return; } @@ -176,10 +181,10 @@ public class PacketListener extends ChannelInboundHandlerAdapter { save(packet); - if (packet instanceof S3FPacketCustomPayload) { - S3FPacketCustomPayload p = (S3FPacketCustomPayload) packet; + if (packet instanceof SPacketCustomPayload) { + SPacketCustomPayload p = (SPacketCustomPayload) packet; if (Restrictions.PLUGIN_CHANNEL.equals(p.getChannelName())) { - packet = new S40PacketDisconnect(new ChatComponentText("Please update to view this replay.")); + packet = new SPacketDisconnect(new TextComponentString("Please update to view this replay.")); save(packet); } } @@ -192,27 +197,31 @@ public class PacketListener extends ChannelInboundHandlerAdapter { super.channelRead(ctx, msg); } + private void DataManager_set(EntityDataManager dataManager, EntityDataManager.DataEntry entry) { + dataManager.register(entry.getKey(), entry.getValue()); + } + @SuppressWarnings("unchecked") private byte[] getPacketData(Packet packet) throws IOException { - if(packet instanceof S0FPacketSpawnMob) { - S0FPacketSpawnMob p = (S0FPacketSpawnMob) packet; - if (p.field_149043_l == null) { - p.field_149043_l = new DataWatcher(null); - if(p.func_149027_c() != null) { - for(DataWatcher.WatchableObject wo : (List) p.func_149027_c()) { - p.field_149043_l.addObject(wo.getDataValueId(), wo.getObject()); + if (packet instanceof SPacketSpawnMob) { + SPacketSpawnMob p = (SPacketSpawnMob) packet; + if (p.dataManager == null) { + p.dataManager = new EntityDataManager(null); + if (p.getDataManagerEntries() != null) { + for (EntityDataManager.DataEntry entry : p.getDataManagerEntries()) { + DataManager_set(p.dataManager, entry); } } } } - if(packet instanceof S0CPacketSpawnPlayer) { - S0CPacketSpawnPlayer p = (S0CPacketSpawnPlayer) packet; + if (packet instanceof SPacketSpawnPlayer) { + SPacketSpawnPlayer p = (SPacketSpawnPlayer) packet; if (p.watcher == null) { - p.watcher = new DataWatcher(null); - if(p.func_148944_c() != null) { - for(DataWatcher.WatchableObject wo : p.func_148944_c()) { - p.watcher.addObject(wo.getDataValueId(), wo.getObject()); + p.watcher = new EntityDataManager(null); + if (p.getDataManagerEntries() != null) { + for (EntityDataManager.DataEntry entry : p.getDataManagerEntries()) { + DataManager_set(p.watcher, entry); } } } diff --git a/src/main/java/com/replaymod/recording/packet/ResourcePackRecorder.java b/src/main/java/com/replaymod/recording/packet/ResourcePackRecorder.java index 30e421c7..2e383fcb 100644 --- a/src/main/java/com/replaymod/recording/packet/ResourcePackRecorder.java +++ b/src/main/java/com/replaymod/recording/packet/ResourcePackRecorder.java @@ -15,8 +15,8 @@ import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.ResourcePackRepository; import net.minecraft.network.NetworkManager; -import net.minecraft.network.play.client.C19PacketResourcePackStatus; -import net.minecraft.network.play.server.S48PacketResourcePackSend; +import net.minecraft.network.play.client.CPacketResourcePackStatus; +import net.minecraft.network.play.server.SPacketResourcePackSend; import net.minecraft.util.HttpUtil; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; @@ -74,9 +74,9 @@ public class ResourcePackRecorder { } } - public synchronized S48PacketResourcePackSend handleResourcePack(S48PacketResourcePackSend packet) { + public synchronized SPacketResourcePackSend handleResourcePack(SPacketResourcePackSend packet) { final int requestId = nextRequestId++; - final NetHandlerPlayClient netHandler = mc.getNetHandler(); + final NetHandlerPlayClient netHandler = mc.getConnection(); final NetworkManager netManager = netHandler.getNetworkManager(); final String url = packet.getURL(); final String hash = packet.getHash(); @@ -87,60 +87,60 @@ public class ResourcePackRecorder { final File levelDir = new File(savesDir, levelName); if (levelDir.isFile()) { - netManager.sendPacket(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.ACCEPTED)); + netManager.sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.ACCEPTED)); Futures.addCallback(mc.getResourcePackRepository().setResourcePackInstance(levelDir), new FutureCallback() { @Override public void onSuccess(Object result) { recordResourcePack(levelDir, requestId); - netManager.sendPacket(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.SUCCESSFULLY_LOADED)); + netManager.sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.SUCCESSFULLY_LOADED)); } @Override public void onFailure(@Nonnull Throwable throwable) { - netManager.sendPacket(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.FAILED_DOWNLOAD)); + netManager.sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.FAILED_DOWNLOAD)); } }); } else { - netManager.sendPacket(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.FAILED_DOWNLOAD)); + netManager.sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.FAILED_DOWNLOAD)); } } else { final ServerData serverData = mc.getCurrentServerData(); if (serverData != null && serverData.getResourceMode() == ServerData.ServerResourceMode.ENABLED) { - netManager.sendPacket(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.ACCEPTED)); + netManager.sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.ACCEPTED)); downloadResourcePackFuture(requestId, url, hash); } else if (serverData != null && serverData.getResourceMode() != ServerData.ServerResourceMode.PROMPT) { - netManager.sendPacket(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.DECLINED)); + netManager.sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.DECLINED)); } else { mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiYesNo((result, id) -> { if (serverData != null) { serverData.setResourceMode(result ? ServerData.ServerResourceMode.ENABLED : ServerData.ServerResourceMode.DISABLED); } if (result) { - netManager.sendPacket(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.ACCEPTED)); + netManager.sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.ACCEPTED)); downloadResourcePackFuture(requestId, url, hash); } else { - netManager.sendPacket(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.DECLINED)); + netManager.sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.DECLINED)); } - ServerList.func_147414_b(serverData); + ServerList.saveSingleServer(serverData); mc.displayGuiScreen(null); }, I18n.format("multiplayer.texturePrompt.line1"), I18n.format("multiplayer.texturePrompt.line2"), 0))); } } - return new S48PacketResourcePackSend("replay://" + requestId, ""); + return new SPacketResourcePackSend("replay://" + requestId, ""); } private void downloadResourcePackFuture(int requestId, String url, final String hash) { Futures.addCallback(downloadResourcePack(requestId, url, hash), new FutureCallback() { @Override public void onSuccess(Object result) { - mc.getNetHandler().addToSendQueue(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.SUCCESSFULLY_LOADED)); + mc.getConnection().sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.SUCCESSFULLY_LOADED)); } @Override public void onFailure(@Nonnull Throwable throwable) { - mc.getNetHandler().addToSendQueue(new C19PacketResourcePackStatus(hash, C19PacketResourcePackStatus.Action.FAILED_DOWNLOAD)); + mc.getConnection().sendPacket(new CPacketResourcePackStatus(hash, CPacketResourcePackStatus.Action.FAILED_DOWNLOAD)); } }); } diff --git a/src/main/java/com/replaymod/render/ReplayModRender.java b/src/main/java/com/replaymod/render/ReplayModRender.java index 6b7f3668..4ad3e125 100644 --- a/src/main/java/com/replaymod/render/ReplayModRender.java +++ b/src/main/java/com/replaymod/render/ReplayModRender.java @@ -5,8 +5,8 @@ import com.replaymod.render.utils.RenderJob; import com.replaymod.replay.events.ReplayCloseEvent; import net.minecraft.crash.CrashReport; import net.minecraft.util.ReportedException; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -46,7 +46,7 @@ public class ReplayModRender { core = ReplayMod.instance; configuration = new Configuration(event.getSuggestedConfigurationFile()); - FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); core.getSettingsRegistry().register(Setting.class); } diff --git a/src/main/java/com/replaymod/render/hooks/ChunkLoadingRenderGlobal.java b/src/main/java/com/replaymod/render/hooks/ChunkLoadingRenderGlobal.java index 405a9508..8e7b5711 100644 --- a/src/main/java/com/replaymod/render/hooks/ChunkLoadingRenderGlobal.java +++ b/src/main/java/com/replaymod/render/hooks/ChunkLoadingRenderGlobal.java @@ -10,7 +10,7 @@ import net.minecraft.client.renderer.chunk.RenderChunk; import java.lang.reflect.Field; import java.util.Iterator; -import java.util.concurrent.BlockingQueue; +import java.util.concurrent.PriorityBlockingQueue; public class ChunkLoadingRenderGlobal { @@ -27,10 +27,10 @@ public class ChunkLoadingRenderGlobal { this.renderWorker = new CustomChunkRenderWorker(renderDispatcher, new RegionRenderCacheBuilder()); int workerThreads = renderDispatcher.listThreadedWorkers.size(); - BlockingQueue queueChunkUpdates = renderDispatcher.queueChunkUpdates; + PriorityBlockingQueue queueChunkUpdates = renderDispatcher.queueChunkUpdates; workerJailingQueue = new JailingQueue<>(queueChunkUpdates); renderDispatcher.queueChunkUpdates = workerJailingQueue; - ChunkCompileTaskGenerator element = new ChunkCompileTaskGenerator(null, null); + ChunkCompileTaskGenerator element = new ChunkCompileTaskGenerator(null, null, 0); element.finish(); for (int i = 0; i < workerThreads; i++) { queueChunkUpdates.add(element); @@ -68,7 +68,7 @@ public class ChunkLoadingRenderGlobal { renderDispatcher.updateChunkNow(renderchunk); - renderchunk.setNeedsUpdate(false); + renderchunk.clearNeedsUpdate(); iterator.remove(); } } diff --git a/src/main/java/com/replaymod/render/mixin/MixinEffectRenderer.java b/src/main/java/com/replaymod/render/mixin/MixinEffectRenderer.java deleted file mode 100644 index e374e562..00000000 --- a/src/main/java/com/replaymod/render/mixin/MixinEffectRenderer.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.replaymod.render.mixin; - -import com.replaymod.render.hooks.EntityRendererHandler; -import net.minecraft.client.Minecraft; -import net.minecraft.client.particle.EffectRenderer; -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.renderer.WorldRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(EffectRenderer.class) -public abstract class MixinEffectRenderer { - @Redirect(method = "renderParticles", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/EntityFX;renderParticle(Lnet/minecraft/client/renderer/WorldRenderer;Lnet/minecraft/entity/Entity;FFFFFF)V")) - private void renderNormalParticle(EntityFX fx, WorldRenderer worldRenderer, Entity view, float partialTicks, - float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) { - renderParticle(fx, worldRenderer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); - } - - @Redirect(method = "renderLitParticles", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/EntityFX;renderParticle(Lnet/minecraft/client/renderer/WorldRenderer;Lnet/minecraft/entity/Entity;FFFFFF)V")) - private void renderLitParticle(EntityFX fx, WorldRenderer worldRenderer, Entity view, float partialTicks, - float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) { - renderParticle(fx, worldRenderer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); - } - - private void renderParticle(EntityFX fx, WorldRenderer worldRenderer, Entity view, float partialTicks, - float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) { - EntityRendererHandler handler = ((EntityRendererHandler.IEntityRenderer) Minecraft.getMinecraft().entityRenderer).replayModRender_getHandler(); - if (handler != null && handler.omnidirectional) { - // Align all particles towards the camera - double dx = fx.prevPosX + (fx.posX - fx.prevPosX) * partialTicks - view.posX; - double dy = fx.prevPosY + (fx.posY - fx.prevPosY) * partialTicks - view.posY; - double dz = fx.prevPosZ + (fx.posZ - fx.prevPosZ) * partialTicks - view.posZ; - double pitch = -Math.atan2(dy, Math.sqrt(dx * dx + dz * dz)); - double yaw = -Math.atan2(dx, dz); - - rotX = (float) Math.cos(yaw); - rotZ = (float) Math.sin(yaw); - rotXZ = (float) Math.cos(pitch); - - rotYZ = (float) (-rotZ * Math.sin(pitch)); - rotXY = (float) (rotX * Math.sin(pitch)); - } - fx.renderParticle(worldRenderer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); - } -} diff --git a/src/main/java/com/replaymod/render/mixin/MixinEntityRenderer.java b/src/main/java/com/replaymod/render/mixin/MixinEntityRenderer.java index f3711094..8c792b4c 100644 --- a/src/main/java/com/replaymod/render/mixin/MixinEntityRenderer.java +++ b/src/main/java/com/replaymod/render/mixin/MixinEntityRenderer.java @@ -12,7 +12,7 @@ import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.client.settings.GameSettings; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.math.RayTraceResult; import org.lwjgl.opengl.GL11; import org.lwjgl.util.ReadableColor; import org.lwjgl.util.glu.Project; @@ -118,10 +118,10 @@ public abstract class MixinEntityRenderer implements EntityRendererHandler.IEnti @Shadow public abstract void renderHand(float partialTicks, int renderPass); - @Redirect(method = "renderWorldPass", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;drawSelectionBox(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/util/MovingObjectPosition;IF)V")) - private void replayModRender_drawSelectionBox(RenderGlobal instance, EntityPlayer player, MovingObjectPosition mop, int alwaysZero, float partialTicks) { + @Redirect(method = "renderWorldPass", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;drawSelectionBox(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/util/math/RayTraceResult;IF)V")) + private void replayModRender_drawSelectionBox(RenderGlobal instance, EntityPlayer player, RayTraceResult rtr, int alwaysZero, float partialTicks) { if (replayModRender_handler == null) { - instance.drawSelectionBox(player, mop, alwaysZero, partialTicks); + instance.drawSelectionBox(player, rtr, alwaysZero, partialTicks); } } diff --git a/src/main/java/com/replaymod/render/mixin/MixinParticleManager.java b/src/main/java/com/replaymod/render/mixin/MixinParticleManager.java new file mode 100644 index 00000000..867cf624 --- /dev/null +++ b/src/main/java/com/replaymod/render/mixin/MixinParticleManager.java @@ -0,0 +1,47 @@ +package com.replaymod.render.mixin; + +import com.replaymod.render.hooks.EntityRendererHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleManager; +import net.minecraft.client.renderer.VertexBuffer; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ParticleManager.class) +public abstract class MixinParticleManager { + @Redirect(method = "renderParticles", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/Particle;renderParticle(Lnet/minecraft/client/renderer/VertexBuffer;Lnet/minecraft/entity/Entity;FFFFFF)V")) + private void renderNormalParticle(Particle particle, VertexBuffer vertexBuffer, Entity view, float partialTicks, + float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) { + renderParticle(particle, vertexBuffer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); + } + + @Redirect(method = "renderLitParticles", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/Particle;renderParticle(Lnet/minecraft/client/renderer/VertexBuffer;Lnet/minecraft/entity/Entity;FFFFFF)V")) + private void renderLitParticle(Particle particle, VertexBuffer vertexBuffer, Entity view, float partialTicks, + float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) { + renderParticle(particle, vertexBuffer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); + } + + private void renderParticle(Particle particle, VertexBuffer vertexBuffer, Entity view, float partialTicks, + float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) { + EntityRendererHandler handler = ((EntityRendererHandler.IEntityRenderer) Minecraft.getMinecraft().entityRenderer).replayModRender_getHandler(); + if (handler != null && handler.omnidirectional) { + // Align all particles towards the camera + double dx = particle.prevPosX + (particle.posX - particle.prevPosX) * partialTicks - view.posX; + double dy = particle.prevPosY + (particle.posY - particle.prevPosY) * partialTicks - view.posY; + double dz = particle.prevPosZ + (particle.posZ - particle.prevPosZ) * partialTicks - view.posZ; + double pitch = -Math.atan2(dy, Math.sqrt(dx * dx + dz * dz)); + double yaw = -Math.atan2(dx, dz); + + rotX = (float) Math.cos(yaw); + rotZ = (float) Math.sin(yaw); + rotXZ = (float) Math.cos(pitch); + + rotYZ = (float) (-rotZ * Math.sin(pitch)); + rotXY = (float) (rotX * Math.sin(pitch)); + } + particle.renderParticle(vertexBuffer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); + } +} diff --git a/src/main/java/com/replaymod/render/mixin/MixinRender.java b/src/main/java/com/replaymod/render/mixin/MixinRender.java index f29678b8..898f7140 100644 --- a/src/main/java/com/replaymod/render/mixin/MixinRender.java +++ b/src/main/java/com/replaymod/render/mixin/MixinRender.java @@ -7,15 +7,14 @@ import net.minecraft.entity.Entity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(Render.class) public abstract class MixinRender { - @Inject(method = "canRenderName", at = @At("HEAD"), cancellable = true) - private void replayModRender_areAllNamesHidden(Entity entity, CallbackInfoReturnable ci) { + @Inject(method = "renderLivingLabel", at = @At("HEAD"), cancellable = true) + private void replayModRender_areAllNamesHidden(Entity entityIn, String str, double x, double y, double z, int maxDistance, CallbackInfo ci) { EntityRendererHandler handler = ((EntityRendererHandler.IEntityRenderer) Minecraft.getMinecraft().entityRenderer).replayModRender_getHandler(); if (handler != null && !handler.getSettings().isRenderNameTags()) { - ci.setReturnValue(false); ci.cancel(); } } diff --git a/src/main/java/com/replaymod/render/mixin/MixinRenderGlobal.java b/src/main/java/com/replaymod/render/mixin/MixinRenderGlobal.java index 7f5cae0a..e388aec9 100644 --- a/src/main/java/com/replaymod/render/mixin/MixinRenderGlobal.java +++ b/src/main/java/com/replaymod/render/mixin/MixinRenderGlobal.java @@ -3,16 +3,13 @@ package com.replaymod.render.mixin; import com.replaymod.render.hooks.ChunkLoadingRenderGlobal; import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher; -import net.minecraft.client.renderer.chunk.RenderChunk; import net.minecraft.client.renderer.culling.ICamera; import net.minecraft.entity.Entity; -import net.minecraft.util.BlockPos; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(RenderGlobal.class) public abstract class MixinRenderGlobal { @@ -37,6 +34,8 @@ public abstract class MixinRenderGlobal { do { setupTerrain(viewEntity, partialTicks, camera, replayModRender_hook.nextFrameId(), playerSpectator); + + replayModRender_hook.updateChunks(); } while (displayListEntitiesDirty); displayListEntitiesDirty = true; @@ -46,13 +45,6 @@ public abstract class MixinRenderGlobal { } } - @Inject(method = "isPositionInRenderChunk", at = @At("HEAD"), cancellable = true) - public void replayModRender_isPositionInRenderChunk(BlockPos pos, RenderChunk chunk, CallbackInfoReturnable ci) { - if (replayModRender_hook != null) { - ci.setReturnValue(true); - } - } - @Inject(method = "updateChunks", at = @At("HEAD"), cancellable = true) public void replayModRender_updateChunks(long finishTimeNano, CallbackInfo ci) { if (replayModRender_hook != null) { diff --git a/src/main/java/com/replaymod/render/mixin/MixinRenderManager.java b/src/main/java/com/replaymod/render/mixin/MixinRenderManager.java index f12637f5..beb90680 100644 --- a/src/main/java/com/replaymod/render/mixin/MixinRenderManager.java +++ b/src/main/java/com/replaymod/render/mixin/MixinRenderManager.java @@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(RenderManager.class) public abstract class MixinRenderManager { @@ -19,7 +19,7 @@ public abstract class MixinRenderManager { private float playerViewY; @Inject(method = "doRenderEntity", at = @At("HEAD")) - private void replayModRender_reorientForCubicRendering(Entity entity, double dx, double dy, double dz, float iDoNotKnow, float partialTicks, boolean iDoNotCare, CallbackInfoReturnable ci) { + private void replayModRender_reorientForCubicRendering(Entity entity, double dx, double dy, double dz, float iDoNotKnow, float partialTicks, boolean iDoNotCare, CallbackInfo ci) { EntityRendererHandler handler = ((EntityRendererHandler.IEntityRenderer) Minecraft.getMinecraft().entityRenderer).replayModRender_getHandler(); if (handler != null && handler.omnidirectional) { double pitch = -Math.atan2(dy, Math.sqrt(dx * dx + dz * dz)); diff --git a/src/main/java/com/replaymod/render/mixin/MixinRendererLivingEntity.java b/src/main/java/com/replaymod/render/mixin/MixinRendererLivingEntity.java deleted file mode 100644 index 38cbe2ae..00000000 --- a/src/main/java/com/replaymod/render/mixin/MixinRendererLivingEntity.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.replaymod.render.mixin; - -import com.replaymod.render.hooks.EntityRendererHandler; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.entity.RendererLivingEntity; -import net.minecraft.entity.EntityLivingBase; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(RendererLivingEntity.class) -public abstract class MixinRendererLivingEntity { - @Inject(method = "canRenderName", at = @At("HEAD"), cancellable = true) - private void replayModRender_areAllNamesHidden(EntityLivingBase entity, CallbackInfoReturnable ci) { - EntityRendererHandler handler = ((EntityRendererHandler.IEntityRenderer) Minecraft.getMinecraft().entityRenderer).replayModRender_getHandler(); - if (handler != null && !handler.getSettings().isRenderNameTags()) { - ci.setReturnValue(false); //this calls the cancel method - } - } -} diff --git a/src/main/java/com/replaymod/render/rendering/VideoRenderer.java b/src/main/java/com/replaymod/render/rendering/VideoRenderer.java index 9a375085..0a0d8726 100644 --- a/src/main/java/com/replaymod/render/rendering/VideoRenderer.java +++ b/src/main/java/com/replaymod/render/rendering/VideoRenderer.java @@ -1,6 +1,5 @@ package com.replaymod.render.rendering; -import com.replaymod.core.ReplayMod; import com.replaymod.pathing.player.AbstractTimelinePlayer; import com.replaymod.pathing.player.ReplayTimer; import com.replaymod.pathing.properties.TimestampProperty; @@ -14,17 +13,18 @@ import com.replaymod.render.gui.GuiRenderingDone; import com.replaymod.render.gui.GuiVideoRenderer; import com.replaymod.render.hooks.ChunkLoadingRenderGlobal; import com.replaymod.render.metadata.MetadataInjector; +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; import com.replaymod.replaystudio.pathing.path.Timeline; import net.minecraft.client.Minecraft; -import net.minecraft.client.audio.SoundCategory; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.shader.Framebuffer; +import net.minecraft.util.SoundCategory; import net.minecraft.util.Timer; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.common.MinecraftForge; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.Display; import org.lwjgl.util.Dimension; @@ -55,7 +55,7 @@ public class VideoRenderer implements RenderInfo { private int fps; private boolean mouseWasGrabbed; private boolean debugInfoWasShown; - private Map originalSoundLevels; + private Map originalSoundLevels; private TimelinePlayer timelinePlayer; private Future timelinePlayerFuture; @@ -92,7 +92,7 @@ public class VideoRenderer implements RenderInfo { * @return {@code true} if rendering was successful, {@code false} if the user aborted rendering (or the window was closed) */ public boolean renderVideo() throws Throwable { - FMLCommonHandler.instance().bus().post(new ReplayRenderEvent.Pre(this)); + MinecraftForge.EVENT_BUS.post(new ReplayRenderEvent.Pre(this)); setup(); @@ -138,7 +138,7 @@ public class VideoRenderer implements RenderInfo { finish(); - FMLCommonHandler.instance().bus().post(new ReplayRenderEvent.Post(this)); + MinecraftForge.EVENT_BUS.post(new ReplayRenderEvent.Post(this)); if (failureCause != null) { throw failureCause; @@ -202,9 +202,9 @@ public class VideoRenderer implements RenderInfo { for (SoundCategory category : SoundCategory.values()) { mutedSounds.put(category, 0f); } - originalSoundLevels = mc.gameSettings.mapSoundLevels; - mutedSounds.put(SoundCategory.MASTER, (Float) originalSoundLevels.get(SoundCategory.MASTER)); - mc.gameSettings.mapSoundLevels = mutedSounds; + originalSoundLevels = mc.gameSettings.soundLevels; + mutedSounds.put(SoundCategory.MASTER, originalSoundLevels.get(SoundCategory.MASTER)); + mc.gameSettings.soundLevels = mutedSounds; fps = settings.getFramesPerSecond(); @@ -225,9 +225,6 @@ public class VideoRenderer implements RenderInfo { updateDisplaySize(); - ScaledResolution scaled = new ScaledResolution(mc); - gui.toMinecraft().setWorldAndResolution(mc, scaled.getScaledWidth(), scaled.getScaledHeight()); - chunkLoadingRenderGlobal = new ChunkLoadingRenderGlobal(mc.renderGlobal); // Set up our own framebuffer to render the GUI to @@ -248,13 +245,13 @@ public class VideoRenderer implements RenderInfo { if (mouseWasGrabbed) { mc.mouseHelper.grabMouseCursor(); } - mc.gameSettings.mapSoundLevels = originalSoundLevels; + mc.gameSettings.soundLevels = originalSoundLevels; mc.displayGuiScreen(null); if (chunkLoadingRenderGlobal != null) { chunkLoadingRenderGlobal.uninstall(); } - ReplayMod.soundHandler.playRenderSuccessSound(); + new SoundHandler().playRenderSuccessSound(); try { if (!hasFailed()) { diff --git a/src/main/java/com/replaymod/render/utils/JailingQueue.java b/src/main/java/com/replaymod/render/utils/JailingQueue.java index ccf702c8..0a7f6ab2 100644 --- a/src/main/java/com/replaymod/render/utils/JailingQueue.java +++ b/src/main/java/com/replaymod/render/utils/JailingQueue.java @@ -2,15 +2,18 @@ package com.replaymod.render.utils; import com.google.common.base.Preconditions; -import java.util.*; -import java.util.concurrent.BlockingQueue; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.TimeUnit; -public class JailingQueue extends AbstractQueue implements BlockingQueue { - private final BlockingQueue delegate; +public class JailingQueue extends PriorityBlockingQueue { + private final PriorityBlockingQueue delegate; private final Set jailed = new HashSet(); - public JailingQueue(BlockingQueue delegate) { + public JailingQueue(PriorityBlockingQueue delegate) { this.delegate = delegate; } @@ -59,13 +62,13 @@ public class JailingQueue extends AbstractQueue implements BlockingQueue(replayFile.getMarkers().or(Collections.emptySet())); @@ -87,7 +87,7 @@ public class ReplayHandler { overlay = new GuiReplayOverlay(this); overlay.setVisible(true); - FMLCommonHandler.instance().bus().post(new ReplayOpenEvent.Post(this)); + MinecraftForge.EVENT_BUS.post(new ReplayOpenEvent.Post(this)); } void restartedReplay() { @@ -101,7 +101,7 @@ public class ReplayHandler { public void endReplay() throws IOException { Preconditions.checkState(mc.isCallingFromMinecraftThread(), "Must be called from Minecraft thread."); - FMLCommonHandler.instance().bus().post(new ReplayCloseEvent.Pre(this)); + MinecraftForge.EVENT_BUS.post(new ReplayCloseEvent.Pre(this)); replaySender.terminateReplay(); @@ -126,7 +126,7 @@ public class ReplayHandler { mc.displayGuiScreen(null); - FMLCommonHandler.instance().bus().post(new ReplayCloseEvent.Post(this)); + MinecraftForge.EVENT_BUS.post(new ReplayCloseEvent.Post(this)); } private void setup() { @@ -333,7 +333,7 @@ public class ReplayHandler { replaySender.setAsyncMode(true); replaySender.setReplaySpeed(0); - mc.getNetHandler().getNetworkManager().processReceivedPackets(); + mc.getConnection().getNetworkManager().processReceivedPackets(); for (Entity entity : mc.theWorld.loadedEntityList) { if (entity instanceof EntityOtherPlayerMP) { EntityOtherPlayerMP e = (EntityOtherPlayerMP) entity; diff --git a/src/main/java/com/replaymod/replay/ReplaySender.java b/src/main/java/com/replaymod/replay/ReplaySender.java index 3d2a8c36..bed3de85 100755 --- a/src/main/java/com/replaymod/replay/ReplaySender.java +++ b/src/main/java/com/replaymod/replay/ReplaySender.java @@ -13,21 +13,26 @@ import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityOtherPlayerMP; import net.minecraft.client.gui.GuiDownloadTerrain; import net.minecraft.client.gui.GuiErrorScreen; import net.minecraft.client.resources.I18n; import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.network.*; import net.minecraft.network.play.server.*; import net.minecraft.util.ClassInheritanceMultiMap; -import net.minecraft.util.IChatComponent; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.ITextComponent; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; import net.minecraft.world.WorldSettings.GameType; import net.minecraft.world.WorldType; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.IChunkProvider; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -44,30 +49,22 @@ import java.util.Map; */ @Sharable public class ReplaySender extends ChannelDuplexHandler { - - /** - * Previously packets for the client player were inserted using one fixed entity id (this one). - * This is no longer the case however to provide backwards compatibility, we have to convert - * these old packets to use the normal entity id. - * Need to punch someone? -> CrushedPixel - */ - public static final int LEGACY_ENTITY_ID = Integer.MIN_VALUE + 9001; - /** * These packets are ignored completely during replay. */ private static final List BAD_PACKETS = Arrays.asList( - S06PacketUpdateHealth.class, - S2DPacketOpenWindow.class, - S2EPacketCloseWindow.class, - S2FPacketSetSlot.class, - S30PacketWindowItems.class, - S36PacketSignEditorOpen.class, - S37PacketStatistics.class, - S1FPacketSetExperience.class, - S43PacketCamera.class, - S39PacketPlayerAbilities.class, - S45PacketTitle.class); + // TODO Update possibly more? + SPacketUpdateHealth.class, + SPacketOpenWindow.class, + SPacketCloseWindow.class, + SPacketSetSlot.class, + SPacketWindowItems.class, + SPacketSignEditorOpen.class, + SPacketStatistics.class, + SPacketSetExperience.class, + SPacketCamera.class, + SPacketPlayerAbilities.class, + SPacketTitle.class); private static int TP_DISTANCE_LIMIT = 128; @@ -176,6 +173,8 @@ public class ReplaySender extends ChannelDuplexHandler { this.asyncMode = asyncMode; this.replayLength = file.getMetaData().getDuration(); + MinecraftForge.EVENT_BUS.register(this); + if (asyncMode) { new Thread(asyncSender, "replaymod-async-sender").start(); } @@ -244,6 +243,7 @@ public class ReplaySender extends ChannelDuplexHandler { */ public void terminateReplay() { terminate = true; + MinecraftForge.EVENT_BUS.unregister(this); try { channelInactive(ctx); ctx.channel().pipeline().close(); @@ -253,6 +253,25 @@ public class ReplaySender extends ChannelDuplexHandler { } } + @SubscribeEvent + public void onWorldTick(TickEvent.ClientTickEvent event) { + // Unfortunately the WorldTickEvent doesn't seem to be emitted on the CLIENT side + if (event.phase != TickEvent.Phase.START) return; + + // Spawning a player into an empty chunk (which we might do with the recording player) + // prevents it from being moved by teleport packets (it essentially gets stuck) because + // Entity#addedToChunk is not set and it is therefore not updated every tick. + // To counteract this, we need to manually update it's position if it hasn't been added + // to any chunk yet. + if (mc.theWorld != null) { + for (EntityPlayer playerEntity : mc.theWorld.playerEntities) { + if (!playerEntity.addedToChunk && playerEntity instanceof EntityOtherPlayerMP) { + playerEntity.onLivingUpdate(); + } + } + } + } + @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { @@ -280,21 +299,21 @@ public class ReplaySender extends ChannelDuplexHandler { // Therefore we have to remove all loaded, dead entities manually if we are in sync mode. // We do this after every SpawnX packet and after the destroy entities packet. if (!asyncMode && mc.theWorld != null) { - if (p instanceof S0CPacketSpawnPlayer - || p instanceof S0EPacketSpawnObject - || p instanceof S0FPacketSpawnMob - || p instanceof S2CPacketSpawnGlobalEntity - || p instanceof S10PacketSpawnPainting - || p instanceof S11PacketSpawnExperienceOrb - || p instanceof S13PacketDestroyEntities) { + if (p instanceof SPacketSpawnPlayer + || p instanceof SPacketSpawnObject + || p instanceof SPacketSpawnMob + || p instanceof SPacketSpawnGlobalEntity + || p instanceof SPacketSpawnPainting + || p instanceof SPacketSpawnExperienceOrb + || p instanceof SPacketDestroyEntities) { World world = mc.theWorld; for (int i = 0; i < world.loadedEntityList.size(); ++i) { - Entity entity = (Entity) world.loadedEntityList.get(i); + Entity entity = world.loadedEntityList.get(i); if (entity.isDead) { int chunkX = entity.chunkCoordX; int chunkY = entity.chunkCoordZ; - if (entity.addedToChunk && world.getChunkProvider().chunkExists(chunkX, chunkY)) { + if (entity.addedToChunk && world.getChunkProvider().getLoadedChunk(chunkX, chunkY) != null) { world.getChunkFromChunkCoords(chunkX, chunkY).removeEntity(entity); } @@ -332,8 +351,8 @@ public class ReplaySender extends ChannelDuplexHandler { * @return The processed packet or {@code null} if no packet shall be sent */ protected Packet processPacket(Packet p) throws Exception { - if (p instanceof S3FPacketCustomPayload) { - S3FPacketCustomPayload packet = (S3FPacketCustomPayload) p; + if (p instanceof SPacketCustomPayload) { + SPacketCustomPayload packet = (SPacketCustomPayload) p; if (Restrictions.PLUGIN_CHANNEL.equals(packet.getChannelName())) { final String unknown = replayHandler.getRestrictions().handle(packet); if (unknown == null) { @@ -359,8 +378,8 @@ public class ReplaySender extends ChannelDuplexHandler { } } } - if (p instanceof S40PacketDisconnect) { - IChatComponent reason = ((S40PacketDisconnect) p).getReason(); + if (p instanceof SPacketDisconnect) { + ITextComponent reason = ((SPacketDisconnect) p).getReason(); if ("Please update to view this replay.".equals(reason.getUnformattedText())) { // This version of the mod supports replay restrictions so we are allowed // to remove this packet. @@ -370,17 +389,15 @@ public class ReplaySender extends ChannelDuplexHandler { if(BAD_PACKETS.contains(p.getClass())) return null; - if (p instanceof S3FPacketCustomPayload) { - S3FPacketCustomPayload packet = (S3FPacketCustomPayload) p; + if (p instanceof SPacketCustomPayload) { + SPacketCustomPayload packet = (SPacketCustomPayload) p; if ("MC|BOpen".equals(packet.getChannelName())) { return null; } } - convertLegacyEntityIds(p); - - if(p instanceof S48PacketResourcePackSend) { - S48PacketResourcePackSend packet = (S48PacketResourcePackSend) p; + if(p instanceof SPacketResourcePackSend) { + SPacketResourcePackSend packet = (SPacketResourcePackSend) p; String url = packet.getURL(); if (url.startsWith("replay://")) { int id = Integer.parseInt(url.substring("replay://".length())); @@ -399,10 +416,10 @@ public class ReplaySender extends ChannelDuplexHandler { } } - if(p instanceof S01PacketJoinGame) { - S01PacketJoinGame packet = (S01PacketJoinGame) p; + if(p instanceof SPacketJoinGame) { + SPacketJoinGame packet = (SPacketJoinGame) p; allowMovement = true; - int entId = packet.getEntityId(); + int entId = packet.getPlayerId(); actualID = entId; entId = -1789435; // Camera entity id should be negative which is an invalid id and can't be used by servers int dimension = packet.getDimension(); @@ -410,21 +427,21 @@ public class ReplaySender extends ChannelDuplexHandler { int maxPlayers = packet.getMaxPlayers(); WorldType worldType = packet.getWorldType(); - p = new S01PacketJoinGame(entId, GameType.SPECTATOR, false, dimension, + p = new SPacketJoinGame(entId, GameType.SPECTATOR, false, dimension, difficulty, maxPlayers, worldType, false); } - if(p instanceof S07PacketRespawn) { - S07PacketRespawn respawn = (S07PacketRespawn) p; - p = new S07PacketRespawn(respawn.getDimensionID(), + if(p instanceof SPacketRespawn) { + SPacketRespawn respawn = (SPacketRespawn) p; + p = new SPacketRespawn(respawn.getDimensionID(), respawn.getDifficulty(), respawn.getWorldType(), GameType.SPECTATOR); allowMovement = true; } - if(p instanceof S08PacketPlayerPosLook) { + if(p instanceof SPacketPlayerPosLook) { if(!hasWorldLoaded) hasWorldLoaded = true; - final S08PacketPlayerPosLook ppl = (S08PacketPlayerPosLook) p; + final SPacketPlayerPosLook ppl = (SPacketPlayerPosLook) p; if (mc.currentScreen instanceof GuiDownloadTerrain) { // Close the world loading screen manually in case we swallow the packet @@ -435,10 +452,10 @@ public class ReplaySender extends ChannelDuplexHandler { CameraEntity cent = replayHandler.getCameraEntity(); - for (Object relative : ppl.func_179834_f()) { - if (relative == S08PacketPlayerPosLook.EnumFlags.X - || relative == S08PacketPlayerPosLook.EnumFlags.Y - || relative == S08PacketPlayerPosLook.EnumFlags.Z) { + for (SPacketPlayerPosLook.EnumFlags relative : ppl.getFlags()) { + if (relative == SPacketPlayerPosLook.EnumFlags.X + || relative == SPacketPlayerPosLook.EnumFlags.Y + || relative == SPacketPlayerPosLook.EnumFlags.Z) { return null; // At least one of the coordinates is relative, so we don't care } } @@ -467,8 +484,8 @@ public class ReplaySender extends ChannelDuplexHandler { }.run(); } - if(p instanceof S2BPacketChangeGameState) { - S2BPacketChangeGameState pg = (S2BPacketChangeGameState)p; + if(p instanceof SPacketChangeGameState) { + SPacketChangeGameState pg = (SPacketChangeGameState)p; int reason = pg.getGameState(); // only allow the following packets: @@ -483,7 +500,7 @@ public class ReplaySender extends ChannelDuplexHandler { } } - if (p instanceof S02PacketChat) { + if (p instanceof SPacketChat) { if (!ReplayModReplay.instance.getCore().getSettingsRegistry().get(Setting.SHOW_CHAT)) { return null; } @@ -496,7 +513,7 @@ public class ReplaySender extends ChannelDuplexHandler { @SuppressWarnings("unchecked") public void channelActive(ChannelHandlerContext ctx) throws Exception { this.ctx = ctx; - ctx.attr(NetworkManager.attrKeyConnectionState).set(EnumConnectionState.PLAY); + ctx.attr(NetworkManager.PROTOCOL_ATTRIBUTE_KEY).set(EnumConnectionState.PLAY); super.channelActive(ctx); } @@ -714,10 +731,10 @@ public class ReplaySender extends ChannelDuplexHandler { protected Packet processPacketAsync(Packet p) { //If hurrying, ignore some packets, except for short durations if(desiredTimeStamp - lastTimeStamp > 1000) { - if(p instanceof S2APacketParticles) return null; + if(p instanceof SPacketParticles) return null; - if(p instanceof S0EPacketSpawnObject) { - S0EPacketSpawnObject pso = (S0EPacketSpawnObject)p; + if(p instanceof SPacketSpawnObject) { + SPacketSpawnObject pso = (SPacketSpawnObject)p; int type = pso.getType(); if(type == 76) { // Firework rocket return null; @@ -804,46 +821,45 @@ public class ReplaySender extends ChannelDuplexHandler { } protected Packet processPacketSync(Packet p) { - if (p instanceof S21PacketChunkData) { - S21PacketChunkData packet = (S21PacketChunkData) p; - if (packet.getExtractedSize() == 0) { - // If the chunk is getting unloaded, we will have to forcefully update the position of all entities - // within. Otherwise, if there wasn't a game tick recently, there may be entities that have moved - // out of the chunk by now but are still registered in it. If we do not update those, they will get - // unloaded even though they shouldn't. - // To make things worse, it seems like players were never supposed to be unloaded this way because - // they will remain glitched in the World#playerEntities list. - World world = mc.theWorld; - IChunkProvider chunkProvider = world.getChunkProvider(); - // Get the chunk that will be unloaded - Chunk chunk = chunkProvider.provideChunk(packet.getChunkX(), packet.getChunkZ()); - if (!chunk.isEmpty()) { - List entitiesInChunk = new ArrayList<>(); - // Gather all entities in that chunk - for (ClassInheritanceMultiMap entityList : chunk.getEntityLists()) { - entitiesInChunk.addAll(entityList); + if (p instanceof SPacketUnloadChunk) { + SPacketUnloadChunk packet = (SPacketUnloadChunk) p; + // If the chunk is getting unloaded, we will have to forcefully update the position of all entities + // within. Otherwise, if there wasn't a game tick recently, there may be entities that have moved + // out of the chunk by now but are still registered in it. If we do not update those, they will get + // unloaded even though they shouldn't. + // To make things worse, it seems like players were never supposed to be unloaded this way because + // they will remain glitched in the World#playerEntities list. + World world = mc.theWorld; + IChunkProvider chunkProvider = world.getChunkProvider(); + // Get the chunk that will be unloaded + Chunk chunk = chunkProvider.provideChunk(packet.getX(), packet.getZ()); + if (!chunk.isEmpty()) { + List entitiesInChunk = new ArrayList<>(); + // Gather all entities in that chunk + for (ClassInheritanceMultiMap entityList : chunk.getEntityLists()) { + entitiesInChunk.addAll(entityList); + } + for (Entity entity : entitiesInChunk) { + // Skip interpolation of position updates coming from server + // (See: newX in EntityLivingBase or otherPlayerMPX in EntityOtherPlayerMP) + // Needs to be called at least 4 times thanks to + // EntityOtherPlayerMP#otherPlayerMPPosRotationIncrements (max vanilla value is 3) + for (int i = 0; i < 4; i++) { + entity.onUpdate(); } - for (Entity entity : entitiesInChunk) { - // Skip interpolation of position updates coming from server - // (See: newX in EntityLivingBase or otherPlayerMPX in EntityOtherPlayerMP) - // Needs to be called at least 4 times thanks to - // EntityOtherPlayerMP#otherPlayerMPPosRotationIncrements (max vanilla value is 3) - for (int i = 0; i < 4; i++) { - entity.onUpdate(); - } - // Check whether the entity has left the chunk - int chunkX = MathHelper.floor_double(entity.posX / 16); - int chunkZ = MathHelper.floor_double(entity.posZ / 16); - if (entity.chunkCoordX != chunkX || entity.chunkCoordZ != chunkZ) { - // Entity has left the chunk - chunk.removeEntityAtIndex(entity, entity.chunkCoordY); - if (chunkProvider.chunkExists(chunkX, chunkZ)) { - chunkProvider.provideChunk(chunkX, chunkZ).addEntity(entity); - } else { - // Entity has left all loaded chunks - entity.addedToChunk = false; - } + // Check whether the entity has left the chunk + int chunkX = MathHelper.floor_double(entity.posX / 16); + int chunkZ = MathHelper.floor_double(entity.posZ / 16); + if (entity.chunkCoordX != chunkX || entity.chunkCoordZ != chunkZ) { + // Entity has left the chunk + chunk.removeEntityAtIndex(entity, entity.chunkCoordY); + Chunk newChunk = chunkProvider.getLoadedChunk(chunkX, chunkZ); + if (newChunk != null) { + newChunk.addEntity(entity); + } else { + // Entity has left all loaded chunks + entity.addedToChunk = false; } } } @@ -852,68 +868,6 @@ public class ReplaySender extends ChannelDuplexHandler { return p; // During synchronous playback everything is sent normally } - /** - * This is necessary to convert packets from old replays to new replays. - * @param packet The packet to be transformed. - * @see #LEGACY_ENTITY_ID - */ - private void convertLegacyEntityIds(Packet packet) { - if (packet instanceof S0CPacketSpawnPlayer) { - S0CPacketSpawnPlayer p = (S0CPacketSpawnPlayer) packet; - if (p.entityId == LEGACY_ENTITY_ID) { - p.entityId = actualID; - } - } else if (packet instanceof S18PacketEntityTeleport) { - S18PacketEntityTeleport p = (S18PacketEntityTeleport) packet; - if (p.entityId == LEGACY_ENTITY_ID) { - p.entityId = actualID; - } - } else if (packet instanceof S14PacketEntity.S17PacketEntityLookMove) { - S14PacketEntity.S17PacketEntityLookMove p = (S14PacketEntity.S17PacketEntityLookMove) packet; - if (p.entityId == LEGACY_ENTITY_ID) { - p.entityId = actualID; - } - } else if (packet instanceof S19PacketEntityHeadLook) { - S19PacketEntityHeadLook p = (S19PacketEntityHeadLook) packet; - if (p.entityId == LEGACY_ENTITY_ID) { - p.entityId = actualID; - } - } else if (packet instanceof S12PacketEntityVelocity) { - S12PacketEntityVelocity p = (S12PacketEntityVelocity) packet; - if (p.entityID == LEGACY_ENTITY_ID) { - p.entityID = actualID; - } - } else if (packet instanceof S0BPacketAnimation) { - S0BPacketAnimation p = (S0BPacketAnimation) packet; - if (p.entityId == LEGACY_ENTITY_ID) { - p.entityId = actualID; - } - } else if (packet instanceof S04PacketEntityEquipment) { - S04PacketEntityEquipment p = (S04PacketEntityEquipment) packet; - if (p.entityID == LEGACY_ENTITY_ID) { - p.entityID = actualID; - } - } else if (packet instanceof S1BPacketEntityAttach) { - S1BPacketEntityAttach p = (S1BPacketEntityAttach) packet; - if (p.entityId == LEGACY_ENTITY_ID) { - p.entityId = actualID; - } - if (p.vehicleEntityId == LEGACY_ENTITY_ID) { - p.vehicleEntityId = actualID; - } - } else if (packet instanceof S0DPacketCollectItem) { - S0DPacketCollectItem p = (S0DPacketCollectItem) packet; - if (p.entityId == LEGACY_ENTITY_ID) { - p.entityId = actualID; - } - } else if (packet instanceof S13PacketDestroyEntities) { - S13PacketDestroyEntities p = (S13PacketDestroyEntities) packet; - if (p.entityIDs.length == 1 && p.entityIDs[0] == LEGACY_ENTITY_ID) { - p.entityIDs[0] = actualID; - } - } - } - private static final class PacketData { private final int timestamp; private final byte[] bytes; diff --git a/src/main/java/com/replaymod/replay/camera/CameraEntity.java b/src/main/java/com/replaymod/replay/camera/CameraEntity.java index 9935baf5..a733b511 100755 --- a/src/main/java/com/replaymod/replay/camera/CameraEntity.java +++ b/src/main/java/com/replaymod/replay/camera/CameraEntity.java @@ -19,17 +19,18 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.item.EntityItemFrame; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.stats.StatFileWriter; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.IChatComponent; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.stats.StatisticsManager; +import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; import net.minecraftforge.client.event.EntityViewRenderEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderHandEvent; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; @@ -67,9 +68,8 @@ public class CameraEntity extends EntityPlayerSP { */ private final EventHandler eventHandler = new EventHandler(); - public CameraEntity(Minecraft mcIn, World worldIn, NetHandlerPlayClient netHandlerPlayClient, StatFileWriter statFileWriter) { - super(mcIn, worldIn, netHandlerPlayClient, statFileWriter); - FMLCommonHandler.instance().bus().register(eventHandler); + public CameraEntity(Minecraft mcIn, World worldIn, NetHandlerPlayClient netHandlerPlayClient, StatisticsManager statisticsManager) { + super(mcIn, worldIn, netHandlerPlayClient, statisticsManager); MinecraftForge.EVENT_BUS.register(eventHandler); if (ReplayModReplay.instance.getReplayHandler().getSpectatedUUID() == null) { cameraController = ReplayModReplay.instance.createCameraController(this); @@ -296,12 +296,49 @@ public class CameraEntity extends EntityPlayerSP { } @Override - public MovingObjectPosition rayTrace(double p_174822_1_, float p_174822_3_) { - MovingObjectPosition pos = super.rayTrace(p_174822_1_, 1f); + public float getCooldownPeriod() { + Entity view = mc.getRenderViewEntity(); + if (view != this && view instanceof EntityPlayer) { + return ((EntityPlayer) view).getCooldownPeriod(); + } + return 1; + } + + @Override + public float getCooledAttackStrength(float adjustTicks) { + Entity view = mc.getRenderViewEntity(); + if (view != this && view instanceof EntityPlayer) { + return ((EntityPlayer) view).getCooledAttackStrength(adjustTicks); + } + // Default to 1 as to not render the cooldown indicator (renders for < 1) + return 1; + } + + @Override + public EnumHand getActiveHand() { + Entity view = mc.getRenderViewEntity(); + if (view != this && view instanceof EntityPlayer) { + return ((EntityPlayer) view).getActiveHand(); + } + return super.getActiveHand(); + } + + @Override + public boolean isHandActive() { + Entity view = mc.getRenderViewEntity(); + if (view != this && view instanceof EntityPlayer) { + return ((EntityPlayer) view).isHandActive(); + } + return super.isHandActive(); + } + + @Override + public RayTraceResult rayTrace(double p_174822_1_, float p_174822_3_) { + RayTraceResult pos = super.rayTrace(p_174822_1_, 1f); // Make sure we can never look at blocks (-> no outline) - if(pos != null && pos.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { - pos.typeOfHit = MovingObjectPosition.MovingObjectType.MISS; + if(pos != null && pos.typeOfHit == RayTraceResult.Type.BLOCK) { + pos.typeOfHit = RayTraceResult.Type.MISS; } return pos; @@ -316,7 +353,6 @@ public class CameraEntity extends EntityPlayerSP { @Override public void setDead() { super.setDead(); - FMLCommonHandler.instance().bus().unregister(eventHandler); MinecraftForge.EVENT_BUS.unregister(eventHandler); } @@ -356,7 +392,7 @@ public class CameraEntity extends EntityPlayerSP { } @Override - public void addChatMessage(IChatComponent message) { + public void addChatMessage(ITextComponent message) { if (MinecraftForge.EVENT_BUS.post(new ReplayChatMessageEvent(this))) return; super.addChatMessage(message); } @@ -380,9 +416,13 @@ public class CameraEntity extends EntityPlayerSP { @SubscribeEvent public void preCrosshairRender(RenderGameOverlayEvent.Pre event) { // The crosshair should only render if targeted entity can actually be spectated - if (event.type == RenderGameOverlayEvent.ElementType.CROSSHAIRS) { + if (event.getType() == RenderGameOverlayEvent.ElementType.CROSSHAIRS) { event.setCanceled(!canSpectate(mc.pointedEntity)); } + // Hotbar should never be rendered + if (event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR) { + event.setCanceled(true); + } } @SubscribeEvent @@ -413,10 +453,13 @@ public class CameraEntity extends EntityPlayerSP { if (lastHandRendered != player) { lastHandRendered = player; - mc.entityRenderer.itemRenderer.prevEquippedProgress = 1; - mc.entityRenderer.itemRenderer.equippedProgress = 1; - mc.entityRenderer.itemRenderer.itemToRender = player.inventory.getCurrentItem(); - mc.entityRenderer.itemRenderer.equippedItemSlot = player.inventory.currentItem; + mc.entityRenderer.itemRenderer.prevEquippedProgressMainHand = 1; + mc.entityRenderer.itemRenderer.prevEquippedProgressOffHand = 1; + mc.entityRenderer.itemRenderer.equippedProgressMainHand = 1; + mc.entityRenderer.itemRenderer.equippedProgressOffHand = 1; + mc.entityRenderer.itemRenderer.itemStackMainHand = player.getItemStackFromSlot(EntityEquipmentSlot.MAINHAND); + mc.entityRenderer.itemRenderer.itemStackOffHand = player.getItemStackFromSlot(EntityEquipmentSlot.OFFHAND); + mc.thePlayer.renderArmYaw = mc.thePlayer.prevRenderArmYaw = player.rotationYaw; mc.thePlayer.renderArmPitch = mc.thePlayer.prevRenderArmPitch = player.rotationPitch; @@ -427,7 +470,7 @@ public class CameraEntity extends EntityPlayerSP { @SubscribeEvent public void onEntityViewRenderEvent(EntityViewRenderEvent.CameraSetup event) { if (mc.getRenderViewEntity() == CameraEntity.this) { - event.roll = roll; + event.setRoll(roll); } } @@ -435,7 +478,7 @@ public class CameraEntity extends EntityPlayerSP { @SubscribeEvent public void preRenderGameOverlay(RenderGameOverlayEvent.Pre event) { - switch (event.type) { + switch (event.getType()) { case ALL: heldItemTooltipsWasTrue = mc.gameSettings.heldItemTooltips; mc.gameSettings.heldItemTooltips = false; @@ -448,12 +491,15 @@ public class CameraEntity extends EntityPlayerSP { case EXPERIENCE: case HEALTHMOUNT: case JUMPBAR: + case POTION_ICONS: event.setCanceled(true); break; case HELMET: case PORTAL: case CROSSHAIRS: case BOSSHEALTH: + case BOSSINFO: + case SUBTITLES: case TEXT: case CHAT: case PLAYER_LIST: @@ -464,7 +510,7 @@ public class CameraEntity extends EntityPlayerSP { @SubscribeEvent public void postRenderGameOverlay(RenderGameOverlayEvent.Post event) { - if (event.type != RenderGameOverlayEvent.ElementType.ALL) return; + if (event.getType() != RenderGameOverlayEvent.ElementType.ALL) return; mc.gameSettings.heldItemTooltips = heldItemTooltipsWasTrue; } } diff --git a/src/main/java/com/replaymod/replay/camera/ClassicCameraController.java b/src/main/java/com/replaymod/replay/camera/ClassicCameraController.java index 797776ee..57bfa770 100644 --- a/src/main/java/com/replaymod/replay/camera/ClassicCameraController.java +++ b/src/main/java/com/replaymod/replay/camera/ClassicCameraController.java @@ -2,8 +2,8 @@ package com.replaymod.replay.camera; import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import org.lwjgl.Sys; // TODO: Marius is responsible for this. Please, someone clean it up. @@ -18,8 +18,8 @@ public class ClassicCameraController implements CameraController { private double THRESHOLD = MAX_SPEED / 20; private double DECAY = MAX_SPEED/3; - private Vec3 direction; - private Vec3 dirBefore; + private Vec3d direction; + private Vec3d dirBefore; private double motion; private long lastCall = Sys.getTime(); @@ -129,7 +129,7 @@ public class ClassicCameraController implements CameraController { return; } - Vec3 movement = direction.normalize(); + Vec3d movement = direction.normalize(); double factor = motion * (frac / 1000D); camera.moveCamera(movement.xCoord * factor, movement.yCoord * factor, movement.zCoord * factor); @@ -158,7 +158,7 @@ public class ClassicCameraController implements CameraController { break; } - Vec3 dbf = direction; + Vec3d dbf = direction; if(dirBefore != null) { direction = dirBefore.normalize().add(direction); @@ -169,12 +169,12 @@ public class ClassicCameraController implements CameraController { updateMovement(); } - private Vec3 getVectorForRotation(float pitch, float yaw) { + private Vec3d getVectorForRotation(float pitch, float yaw) { float f2 = MathHelper.cos(-yaw * 0.017453292F - (float) Math.PI); float f3 = MathHelper.sin(-yaw * 0.017453292F - (float)Math.PI); float f4 = -MathHelper.cos(-pitch * 0.017453292F); float f5 = MathHelper.sin(-pitch * 0.017453292F); - return new Vec3((double)(f3 * f4), (double)f5, (double)(f2 * f4)); + return new Vec3d((double)(f3 * f4), (double)f5, (double)(f2 * f4)); } public enum MoveDirection { diff --git a/src/main/java/com/replaymod/replay/camera/SpectatorCameraController.java b/src/main/java/com/replaymod/replay/camera/SpectatorCameraController.java index 3bab138f..85c8a833 100644 --- a/src/main/java/com/replaymod/replay/camera/SpectatorCameraController.java +++ b/src/main/java/com/replaymod/replay/camera/SpectatorCameraController.java @@ -41,8 +41,9 @@ public class SpectatorCameraController implements CameraController { if (view instanceof EntityPlayer) { EntityPlayer viewPlayer = (EntityPlayer) view; camera.inventory = viewPlayer.inventory; - camera.itemInUse = viewPlayer.itemInUse; - camera.itemInUseCount = viewPlayer.itemInUseCount; + camera.itemStackMainHand = viewPlayer.itemStackMainHand; + camera.swingingHand = viewPlayer.swingingHand; + camera.activeItemStackUseCount = viewPlayer.activeItemStackUseCount; } } } diff --git a/src/main/java/com/replaymod/replay/gui/overlay/GuiMarkerTimeline.java b/src/main/java/com/replaymod/replay/gui/overlay/GuiMarkerTimeline.java index d3219d2c..04cf7391 100644 --- a/src/main/java/com/replaymod/replay/gui/overlay/GuiMarkerTimeline.java +++ b/src/main/java/com/replaymod/replay/gui/overlay/GuiMarkerTimeline.java @@ -2,14 +2,14 @@ package com.replaymod.replay.gui.overlay; import com.replaymod.core.ReplayMod; import com.replaymod.replay.ReplayHandler; +import com.replaymod.replaystudio.data.Marker; import com.replaymod.replaystudio.util.Location; import de.johni0702.minecraft.gui.GuiRenderer; import de.johni0702.minecraft.gui.RenderInfo; import de.johni0702.minecraft.gui.element.advanced.AbstractGuiTimeline; import de.johni0702.minecraft.gui.function.Draggable; -import com.replaymod.replaystudio.data.Marker; import net.minecraft.client.resources.I18n; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.MathHelper; import org.lwjgl.util.Point; import org.lwjgl.util.ReadableDimension; import org.lwjgl.util.ReadablePoint; diff --git a/src/main/java/com/replaymod/replay/gui/overlay/GuiReplayOverlay.java b/src/main/java/com/replaymod/replay/gui/overlay/GuiReplayOverlay.java index 63c4326d..8e6ac252 100644 --- a/src/main/java/com/replaymod/replay/gui/overlay/GuiReplayOverlay.java +++ b/src/main/java/com/replaymod/replay/gui/overlay/GuiReplayOverlay.java @@ -16,7 +16,7 @@ import de.johni0702.minecraft.gui.layout.CustomLayout; import de.johni0702.minecraft.gui.layout.HorizontalLayout; import net.minecraft.client.resources.I18n; import net.minecraft.client.settings.GameSettings; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent; import org.lwjgl.input.Keyboard; @@ -138,9 +138,9 @@ public class GuiReplayOverlay extends AbstractGuiOverlay { public void setVisible(boolean visible) { if (isVisible() != visible) { if (visible) { - FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); } else { - FMLCommonHandler.instance().bus().unregister(this); + MinecraftForge.EVENT_BUS.unregister(this); } } super.setVisible(visible); diff --git a/src/main/java/com/replaymod/replay/handler/GuiHandler.java b/src/main/java/com/replaymod/replay/handler/GuiHandler.java index f05d2971..25af1b22 100644 --- a/src/main/java/com/replaymod/replay/handler/GuiHandler.java +++ b/src/main/java/com/replaymod/replay/handler/GuiHandler.java @@ -9,7 +9,6 @@ import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.resources.I18n; import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import java.io.IOException; @@ -34,13 +33,12 @@ public class GuiHandler { } public void register() { - FMLCommonHandler.instance().bus().register(this); MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent public void injectIntoIngameMenu(GuiScreenEvent.InitGuiEvent.Post event) { - if (!(event.gui instanceof GuiIngameMenu)) { + if (!(event.getGui() instanceof GuiIngameMenu)) { return; } @@ -49,8 +47,7 @@ public class GuiHandler { mod.getReplayHandler().getReplaySender().setReplaySpeed(0); GuiButton achievements = null, stats = null, openToLan = null; - @SuppressWarnings("unchecked") - List buttonList = event.buttonList; + List buttonList = event.getButtonList(); for(GuiButton b : new ArrayList<>(buttonList)) { switch (b.id) { // Replace "Exit Server" button with "Exit Replay" button @@ -98,31 +95,29 @@ public class GuiHandler { @SubscribeEvent public void injectIntoMainMenu(GuiScreenEvent.InitGuiEvent event) { - if (!(event.gui instanceof GuiMainMenu)) { + if (!(event.getGui() instanceof GuiMainMenu)) { return; } - @SuppressWarnings("unchecked") - List buttonList = event.buttonList; - GuiButton button = new GuiButton(BUTTON_REPLAY_VIEWER, event.gui.width / 2 - 100, - event.gui.height / 4 + 10 + 3 * 24, I18n.format("replaymod.gui.replayviewer")); + GuiButton button = new GuiButton(BUTTON_REPLAY_VIEWER, event.getGui().width / 2 - 100, + event.getGui().height / 4 + 10 + 3 * 24, I18n.format("replaymod.gui.replayviewer")); button.width = button.width / 2 - 2; - buttonList.add(button); + event.getButtonList().add(button); } @SubscribeEvent public void onButton(GuiScreenEvent.ActionPerformedEvent.Pre event) { - if(!event.button.enabled) return; + if(!event.getButton().enabled) return; - if (event.gui instanceof GuiMainMenu) { - if (event.button.id == BUTTON_REPLAY_VIEWER) { + if (event.getGui() instanceof GuiMainMenu) { + if (event.getButton().id == BUTTON_REPLAY_VIEWER) { new GuiReplayViewer(mod).display(); } } - if (event.gui instanceof GuiIngameMenu && mod.getReplayHandler() != null) { - if (event.button.id == BUTTON_EXIT_REPLAY) { - event.button.enabled = false; + if (event.getGui() instanceof GuiIngameMenu && mod.getReplayHandler() != null) { + if (event.getButton().id == BUTTON_EXIT_REPLAY) { + event.getButton().enabled = false; mc.displayGuiScreen(new GuiMainMenu()); try { mod.getReplayHandler().endReplay(); diff --git a/src/main/java/com/replaymod/replay/mixin/MixinGuiSpectator.java b/src/main/java/com/replaymod/replay/mixin/MixinGuiSpectator.java index 081c702c..4525ddd8 100644 --- a/src/main/java/com/replaymod/replay/mixin/MixinGuiSpectator.java +++ b/src/main/java/com/replaymod/replay/mixin/MixinGuiSpectator.java @@ -12,12 +12,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(GuiSpectator.class) public abstract class MixinGuiSpectator { @Shadow - private Minecraft field_175268_g; + private Minecraft mc; - @Inject(method = "func_175260_a", at = @At("HEAD"), cancellable = true) + @Inject(method = "onHotbarSelected", at = @At("HEAD"), cancellable = true) public void isInReplay(int i, CallbackInfo ci) { // Prevent spectator gui from opening while in a replay - if (field_175268_g.thePlayer instanceof CameraEntity) { + if (mc.thePlayer instanceof CameraEntity) { ci.cancel(); } } diff --git a/src/main/java/com/replaymod/replay/mixin/MixinParticleManager.java b/src/main/java/com/replaymod/replay/mixin/MixinParticleManager.java new file mode 100644 index 00000000..ff4dc3d9 --- /dev/null +++ b/src/main/java/com/replaymod/replay/mixin/MixinParticleManager.java @@ -0,0 +1,31 @@ +package com.replaymod.replay.mixin; + +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleManager; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Queue; + +@Mixin(ParticleManager.class) +public abstract class MixinParticleManager { + @Shadow + private Queue queueEntityFX; + + /** + * This method additionally clears the queue of particles to be added when the world is changed. + * Otherwise particles from the previous world might show up in this one if they were spawned after + * the last tick in the previous world. + * + * @param world The new world + * @param ci Callback info + */ + @Inject(method = "clearEffects", at = @At("HEAD")) + public void replayModReplay_clearParticleQueue(World world, CallbackInfo ci) { + queueEntityFX.clear(); + } +} diff --git a/src/main/java/com/replaymod/replay/mixin/MixinPlayerControllerMP.java b/src/main/java/com/replaymod/replay/mixin/MixinPlayerControllerMP.java index 2998fec5..e70bb184 100644 --- a/src/main/java/com/replaymod/replay/mixin/MixinPlayerControllerMP.java +++ b/src/main/java/com/replaymod/replay/mixin/MixinPlayerControllerMP.java @@ -1,12 +1,12 @@ package com.replaymod.replay.mixin; -import com.replaymod.replay.camera.CameraEntity; import com.replaymod.replay.ReplayModReplay; +import com.replaymod.replay.camera.CameraEntity; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.client.network.NetHandlerPlayClient; -import net.minecraft.stats.StatFileWriter; +import net.minecraft.stats.StatisticsManager; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -21,12 +21,12 @@ public abstract class MixinPlayerControllerMP { private Minecraft mc; @Shadow - private NetHandlerPlayClient netClientHandler; + private NetHandlerPlayClient connection; - @Inject(method = "func_178892_a", at=@At("HEAD"), cancellable = true) - private void replayModReplay_createReplayCamera(World worldIn, StatFileWriter statFileWriter, CallbackInfoReturnable ci) { + @Inject(method = "createClientPlayer", at=@At("HEAD"), cancellable = true) + private void replayModReplay_createReplayCamera(World worldIn, StatisticsManager statisticsManager, CallbackInfoReturnable ci) { if (ReplayModReplay.instance.getReplayHandler() != null) { - ci.setReturnValue(new CameraEntity(mc, worldIn, netClientHandler, statFileWriter)); + ci.setReturnValue(new CameraEntity(mc, worldIn, connection, statisticsManager)); ci.cancel(); } } diff --git a/src/main/java/com/replaymod/replay/mixin/MixinRenderArrow.java b/src/main/java/com/replaymod/replay/mixin/MixinRenderArrow.java index 03787d5d..301df383 100644 --- a/src/main/java/com/replaymod/replay/mixin/MixinRenderArrow.java +++ b/src/main/java/com/replaymod/replay/mixin/MixinRenderArrow.java @@ -14,6 +14,7 @@ public abstract class MixinRenderArrow extends Render { super(renderManager); } + @SuppressWarnings("unchecked") @Override public boolean shouldRender(Entity entity, ICamera camera, double camX, double camY, double camZ) { // Force arrows to always render, otherwise they stop rendering when you get close to them diff --git a/src/main/java/com/replaymod/replay/mixin/MixinRenderItem.java b/src/main/java/com/replaymod/replay/mixin/MixinRenderItem.java index 3439c689..542aa978 100644 --- a/src/main/java/com/replaymod/replay/mixin/MixinRenderItem.java +++ b/src/main/java/com/replaymod/replay/mixin/MixinRenderItem.java @@ -3,7 +3,7 @@ package com.replaymod.replay.mixin; import com.replaymod.replay.ReplayHandler; import com.replaymod.replay.ReplayModReplay; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.RenderItem; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; diff --git a/src/main/java/com/replaymod/replay/mixin/MixinRendererLivingEntity.java b/src/main/java/com/replaymod/replay/mixin/MixinRenderLivingBase.java similarity index 89% rename from src/main/java/com/replaymod/replay/mixin/MixinRendererLivingEntity.java rename to src/main/java/com/replaymod/replay/mixin/MixinRenderLivingBase.java index 14f86443..fe497cc4 100644 --- a/src/main/java/com/replaymod/replay/mixin/MixinRendererLivingEntity.java +++ b/src/main/java/com/replaymod/replay/mixin/MixinRenderLivingBase.java @@ -2,7 +2,7 @@ package com.replaymod.replay.mixin; import com.replaymod.replay.camera.CameraEntity; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.client.renderer.entity.RenderLivingBase; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import org.spongepowered.asm.mixin.Mixin; @@ -11,8 +11,8 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -@Mixin(RendererLivingEntity.class) -public abstract class MixinRendererLivingEntity { +@Mixin(RenderLivingBase.class) +public abstract class MixinRenderLivingBase { @Inject(method = "canRenderName", at = @At("HEAD"), cancellable = true) private void replayModReplay_canRenderInvisibleName(EntityLivingBase entity, CallbackInfoReturnable ci) { EntityPlayer thePlayer = Minecraft.getMinecraft().thePlayer; diff --git a/src/main/java/com/replaymod/replay/mixin/MixinViewFrustum.java b/src/main/java/com/replaymod/replay/mixin/MixinViewFrustum.java index 94e44a58..35773daa 100644 --- a/src/main/java/com/replaymod/replay/mixin/MixinViewFrustum.java +++ b/src/main/java/com/replaymod/replay/mixin/MixinViewFrustum.java @@ -5,8 +5,8 @@ import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.client.renderer.ViewFrustum; import net.minecraft.client.renderer.chunk.IRenderChunkFactory; import net.minecraft.client.renderer.chunk.RenderChunk; -import net.minecraft.util.BlockPos; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -31,7 +31,7 @@ public abstract class MixinViewFrustum { } /** - * Instead of calling {@link RenderChunk#setPosition(BlockPos)} we recreate the render chunk + * Instead of calling {@link RenderChunk#setOrigin(int, int, int)} we recreate the render chunk * which seems to solve the problem that chunks are invisible when you leave an area and return * to it. * Any better fixes are welcome. @@ -48,17 +48,18 @@ public abstract class MixinViewFrustum { int k = this.countChunksX * 16; for (int l = 0; l < this.countChunksX; ++l) { - int i1 = this.func_178157_a(i, k, l); + int i1 = this.getBaseCoordinate(i, k, l); for (int j1 = 0; j1 < this.countChunksZ; ++j1) { - int k1 = this.func_178157_a(j, k, j1); + int k1 = this.getBaseCoordinate(j, k, j1); for (int l1 = 0; l1 < this.countChunksY; ++l1) { int i2 = l1 * 16; RenderChunk renderchunk = this.renderChunks[(j1 * this.countChunksY + l1) * this.countChunksX + l]; BlockPos blockpos = new BlockPos(i1, i2, k1); if (!blockpos.equals(renderchunk.getPosition())) { // Recreate render chunk instead of setting its position - renderChunks[(j1 * this.countChunksY + l1) * this.countChunksX + l] = - renderChunkFactory.makeRenderChunk(world, renderGlobal, blockpos, 0); + (renderChunks[(j1 * this.countChunksY + l1) * this.countChunksX + l] = + renderChunkFactory.create(world, renderGlobal, 0) + ).setOrigin(blockpos.getX(), blockpos.getY(), blockpos.getZ()); } } } @@ -66,5 +67,5 @@ public abstract class MixinViewFrustum { ci.cancel(); } - @Shadow abstract int func_178157_a(int p_178157_1_, int p_178157_2_, int p_178157_3_); + @Shadow abstract int getBaseCoordinate(int p_178157_1_, int p_178157_2_, int p_178157_3_); } diff --git a/src/main/java/com/replaymod/simplepathing/ReplayModSimplePathing.java b/src/main/java/com/replaymod/simplepathing/ReplayModSimplePathing.java index ecb1e436..dc7684a0 100644 --- a/src/main/java/com/replaymod/simplepathing/ReplayModSimplePathing.java +++ b/src/main/java/com/replaymod/simplepathing/ReplayModSimplePathing.java @@ -9,7 +9,7 @@ import com.replaymod.simplepathing.SPTimeline.SPPath; import com.replaymod.simplepathing.gui.GuiPathing; import com.replaymod.simplepathing.preview.PathPreview; import lombok.Getter; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -40,7 +40,7 @@ public class ReplayModSimplePathing { core.getSettingsRegistry().register(Setting.class); - FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); PathPreview pathPreview = new PathPreview(this); pathPreview.register(); diff --git a/src/main/java/com/replaymod/simplepathing/SPTimeline.java b/src/main/java/com/replaymod/simplepathing/SPTimeline.java index 71cde911..a41c6079 100644 --- a/src/main/java/com/replaymod/simplepathing/SPTimeline.java +++ b/src/main/java/com/replaymod/simplepathing/SPTimeline.java @@ -658,7 +658,7 @@ public class SPTimeline implements PathingRegistry { } catch (IOException e) { CrashReport crash = CrashReport.makeCrashReport(e, "Serializing interpolator"); CrashReportCategory category = crash.makeCategory("Serializing interpolator"); - category.addCrashSectionCallable("Interpolator", interpolator::toString); + category.setDetail("Interpolator", interpolator::toString); throw new ReportedException(crash); } diff --git a/src/main/java/com/replaymod/simplepathing/preview/PathPreview.java b/src/main/java/com/replaymod/simplepathing/preview/PathPreview.java index 30a60336..ae10cfe6 100644 --- a/src/main/java/com/replaymod/simplepathing/preview/PathPreview.java +++ b/src/main/java/com/replaymod/simplepathing/preview/PathPreview.java @@ -8,7 +8,7 @@ import com.replaymod.replay.events.ReplayCloseEvent; import com.replaymod.replay.events.ReplayOpenEvent; import com.replaymod.simplepathing.ReplayModSimplePathing; import com.replaymod.simplepathing.Setting; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.lwjgl.input.Keyboard; @@ -23,7 +23,7 @@ public class PathPreview { } public void register() { - FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); ReplayMod core = mod.getCore(); mod.getCore().getKeyBindingRegistry().registerKeyBinding("replaymod.input.pathpreview", Keyboard.KEY_H, () -> { diff --git a/src/main/java/com/replaymod/simplepathing/preview/PathPreviewRenderer.java b/src/main/java/com/replaymod/simplepathing/preview/PathPreviewRenderer.java index 13896bd8..092c861a 100644 --- a/src/main/java/com/replaymod/simplepathing/preview/PathPreviewRenderer.java +++ b/src/main/java/com/replaymod/simplepathing/preview/PathPreviewRenderer.java @@ -17,7 +17,7 @@ import com.replaymod.simplepathing.gui.GuiPathing; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; @@ -204,7 +204,7 @@ public class PathPreviewRenderer { if (distanceSquared(view, pos2) > renderDistanceSquared) return; Tessellator tessellator = Tessellator.getInstance(); - WorldRenderer vertexBuffer = tessellator.getWorldRenderer(); + VertexBuffer vertexBuffer = tessellator.getBuffer(); vertexBuffer.setTranslation(-view.getLeft(), -view.getMiddle(), -view.getRight()); vertexBuffer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR); @@ -231,7 +231,7 @@ public class PathPreviewRenderer { Triple pos, Keyframe keyframe) { Tessellator tessellator = Tessellator.getInstance(); - WorldRenderer vertexBuffer = tessellator.getWorldRenderer(); + VertexBuffer vertexBuffer = tessellator.getBuffer(); vertexBuffer.setTranslation(0, 0, 0); mc.renderEngine.bindTexture(TEXTURE); @@ -280,7 +280,7 @@ public class PathPreviewRenderer { Triple pos, Triple rot) { Tessellator tessellator = Tessellator.getInstance(); - WorldRenderer vertexBuffer = tessellator.getWorldRenderer(); + VertexBuffer vertexBuffer = tessellator.getBuffer(); vertexBuffer.setTranslation(0, 0, 0); mc.renderEngine.bindTexture(CAMERA_HEAD); diff --git a/src/main/resources/META-INF/replaymod_at.cfg b/src/main/resources/META-INF/replaymod_at.cfg index 59d3b95e..51605cc5 100644 --- a/src/main/resources/META-INF/replaymod_at.cfg +++ b/src/main/resources/META-INF/replaymod_at.cfg @@ -21,23 +21,23 @@ public net.minecraft.client.Minecraft func_147112_ai()V # middleClickMouse public net.minecraft.client.Minecraft func_147115_a(Z)V # sendClickBlockToController # Packets -public net.minecraft.network.play.server.S0FPacketSpawnMob field_149043_l # dataWatcher +public net.minecraft.network.play.server.SPacketSpawnMob field_149043_l # dataManager +public net.minecraft.network.play.server.SPacketSpawnPlayer field_148960_i # watcher #public net.minecraft.network.play.server.S38PacketPlayerListItem field_179964_d # profile -public net.minecraft.network.play.server.S1DPacketEntityEffect field_149434_a # entityId -public net.minecraft.network.play.server.S1CPacketEntityMetadata field_149379_a # entityId -public net.minecraft.network.play.server.S1CPacketEntityMetadata field_149378_b # list -public net.minecraft.network.play.server.S0BPacketAnimation field_148981_a # entityId -public net.minecraft.network.play.server.S02PacketChat field_179842_b # position -public net.minecraft.network.play.server.S19PacketEntityStatus field_149164_a # entityId -public net.minecraft.network.play.server.S0CPacketSpawnPlayer * -public net.minecraft.network.play.server.S18PacketEntityTeleport * -public net.minecraft.network.play.server.S14PacketEntity * -public net.minecraft.network.play.server.S19PacketEntityHeadLook * -public net.minecraft.network.play.server.S12PacketEntityVelocity * -public net.minecraft.network.play.server.S04PacketEntityEquipment * -public net.minecraft.network.play.server.S1BPacketEntityAttach * -public net.minecraft.network.play.server.S0DPacketCollectItem * -public net.minecraft.network.play.server.S13PacketDestroyEntities * +# public net.minecraft.network.play.server.S1DPacketEntityEffect field_149434_a # entityId +# public net.minecraft.network.play.server.S1CPacketEntityMetadata field_149379_a # entityId +# public net.minecraft.network.play.server.S1CPacketEntityMetadata field_149378_b # list +# public net.minecraft.network.play.server.S0BPacketAnimation field_148981_a # entityId +# public net.minecraft.network.play.server.S02PacketChat field_179842_b # position +# public net.minecraft.network.play.server.S19PacketEntityStatus field_149164_a # entityId +# public net.minecraft.network.play.server.S18PacketEntityTeleport * +# public net.minecraft.network.play.server.S14PacketEntity * +# public net.minecraft.network.play.server.S19PacketEntityHeadLook * +# public net.minecraft.network.play.server.S12PacketEntityVelocity * +# public net.minecraft.network.play.server.S04PacketEntityEquipment * +# public net.minecraft.network.play.server.S1BPacketEntityAttach * +# public net.minecraft.network.play.server.S0DPacketCollectItem * +# public net.minecraft.network.play.server.S13PacketDestroyEntities * # GuiTextField public net.minecraft.client.gui.GuiTextField field_146216_j # text @@ -61,7 +61,7 @@ public net.minecraft.client.renderer.RenderGlobal field_175009_l # chunksToUpdat public net.minecraft.client.renderer.RenderGlobal field_72755_R # renderInfos public net.minecraft.client.renderer.RenderGlobal field_175009_l # chunksToUpdate public net.minecraft.client.renderer.RenderGlobal field_72740_G # renderEntitiesStartupCounter -public net.minecraft.client.renderer.RenderGlobal func_174983_a(Lnet.minecraft.util.BlockPos;Lnet.minecraft.client.renderer.chunk.RenderChunk;)Z # isPositionInRenderChunk +# public net.minecraft.client.renderer.RenderGlobal func_174983_a(Lnet.minecraft.util.BlockPos;Lnet.minecraft.client.renderer.chunk.RenderChunk;)Z # isPositionInRenderChunk public net.minecraft.client.renderer.RenderGlobal$ContainerLocalRenderInformation #public net.minecraft.client.renderer.RenderGlobal$ContainerLocalRenderInformation field_178553_a # renderChunk @@ -88,14 +88,14 @@ public net.minecraft.entity.player.EntityPlayer * public net.minecraft.client.entity.EntityOtherPlayerMP * # EffectRenderer -public net.minecraft.client.particle.EffectRenderer field_110737_b # particleTextures -public net.minecraft.client.particle.EffectRenderer field_78876_b # fxLayers +# public net.minecraft.client.particle.EffectRenderer field_110737_b # particleTextures +# public net.minecraft.client.particle.EffectRenderer field_78876_b # fxLayers # IntegratedServer public net.minecraft.server.integrated.IntegratedServer field_71348_o # isGamePaused # GameSettings -public net.minecraft.client.settings.GameSettings field_151446_aD # mapSoundLevels +public net.minecraft.client.settings.GameSettings field_186714_aM # soundLevels # Frustum public net.minecraft.client.renderer.culling.Frustum field_78552_a # clippingHelper @@ -117,5 +117,12 @@ public net.minecraft.client.renderer.GlStateManager$FogState public net.minecraft.client.renderer.GlStateManager$BooleanState public net.minecraft.client.renderer.GlStateManager$BooleanState * +# EntityLivingBase +public net.minecraft.entity.EntityLivingBase field_184621_as # HAND_STATES +public net.minecraft.entity.EntityLivingBase field_184628_bn # activeItemStackUseCount + +# EntityLivingBase +public net.minecraft.client.particle.Particle * + # Example # public net.minecraft.package.ClassName func_some_id(Ljava/lang/Class;IZS)V # methodName diff --git a/src/main/resources/mixins.recording.replaymod.json b/src/main/resources/mixins.recording.replaymod.json index 75e77050..5a88e180 100644 --- a/src/main/resources/mixins.recording.replaymod.json +++ b/src/main/resources/mixins.recording.replaymod.json @@ -7,7 +7,9 @@ "MixinNetHandlerLoginClient", "MixinNetHandlerPlayClient", "MixinNetworkDispatcher", - "MixinRenderGlobal" + "MixinPlayerControllerMP", + "MixinRenderGlobal", + "MixinWorldClient" ], "compatibilityLevel": "JAVA_8", "minVersion": "0.6.11", diff --git a/src/main/resources/mixins.render.replaymod.json b/src/main/resources/mixins.render.replaymod.json index 539d1c55..60b10552 100644 --- a/src/main/resources/mixins.render.replaymod.json +++ b/src/main/resources/mixins.render.replaymod.json @@ -2,11 +2,10 @@ "required": true, "package": "com.replaymod.render.mixin", "mixins": [ - "MixinEffectRenderer", "MixinEntityRenderer", "MixinFrustum", + "MixinParticleManager", "MixinRender", - "MixinRendererLivingEntity", "MixinRenderGlobal", "MixinRenderManager" ], diff --git a/src/main/resources/mixins.replay.replaymod.json b/src/main/resources/mixins.replay.replaymod.json index e92257fb..ba74e0a0 100644 --- a/src/main/resources/mixins.replay.replaymod.json +++ b/src/main/resources/mixins.replay.replaymod.json @@ -3,10 +3,11 @@ "package": "com.replaymod.replay.mixin", "mixins": [ "MixinGuiSpectator", + "MixinParticleManager", "MixinPlayerControllerMP", "MixinRenderArrow", - "MixinRendererLivingEntity", "MixinRenderItem", + "MixinRenderLivingBase", "MixinRenderManager", "MixinTileEntityEndPortalRenderer", "MixinViewFrustum",