Fix invisibility on teleport

This commit is contained in:
Runemoro 2018-01-25 20:56:43 -05:00
parent 6dd1d6fc24
commit 368565944a
4 changed files with 28 additions and 23 deletions

View file

@ -26,12 +26,12 @@ public final class MCPReflection {
} }
} }
public static Method getMCPMethod(Class<?> class0, String deobfuscatedName, String obfuscatedName, Class<?> args) throws NoSuchMethodException { public static Method getMCPMethod(Class<?> class0, String deobfuscatedName, String obfuscatedName, Class<?>... args) throws NoSuchMethodException {
Method method; Method method;
try { try {
method = Entity.class.getDeclaredMethod(obfuscatedName, args); method = class0.getDeclaredMethod(obfuscatedName, args);
} catch (NoSuchMethodException e) { // Running on deobfuscated Minecraft } catch (NoSuchMethodException e) { // Running on deobfuscated Minecraft
method = Entity.class.getDeclaredMethod(deobfuscatedName, args); method = class0.getDeclaredMethod(deobfuscatedName, args);
} }
method.setAccessible(true); method.setAccessible(true);
return method; return method;

View file

@ -3,11 +3,10 @@ package org.dimdev.ddutils;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityList;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.SoundEvents; import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.play.server.*; import net.minecraft.network.play.server.*;
import net.minecraft.potion.PotionEffect; import net.minecraft.potion.PotionEffect;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
@ -49,25 +48,44 @@ public final class TeleportUtils {
int oldDimension = entity.dimension; int oldDimension = entity.dimension;
// int newDimension = dim; // int newDimension = dim;
// Workaround for https://bugs.mojang.com/browse/MC-123364
if (entity instanceof EntityPlayerMP) { if (entity instanceof EntityPlayerMP) {
entity.noClip = true; entity.noClip = true;
} }
// Prevent Minecraft from cancelling the position change being too big if the player is not in creative
// This has to be done when the teleport is done from the player moved function (so any block collision event too)
if (entity instanceof EntityPlayerMP) {
EntityPlayerMP player = (EntityPlayerMP) entity;
try {
Field invulnerableDimensionChange = MCPReflection.getMCPField(EntityPlayerMP.class, "invulnerableDimensionChange", "field_184851_cj");
invulnerableDimensionChange.setBoolean(player, true);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
if (oldDimension == newDimension) { // Based on CommandTeleport.doTeleport if (oldDimension == newDimension) { // Based on CommandTeleport.doTeleport
if (entity instanceof EntityPlayerMP) { if (entity instanceof EntityPlayerMP) {
((EntityPlayerMP) entity).connection.setPlayerLocation( EntityPlayerMP player = (EntityPlayerMP) entity;
player.connection.setPlayerLocation(
x, x,
y, y,
z, z,
yaw, yaw,
pitch, pitch,
EnumSet.noneOf(SPacketPlayerPosLook.EnumFlags.class)); EnumSet.noneOf(SPacketPlayerPosLook.EnumFlags.class));
// https://bugs.mojang.com/browse/MC-98153?focusedCommentId=411524&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-411524
try {
Method captureCurrentPosition = MCPReflection.getMCPMethod(NetHandlerPlayServer.class, "captureCurrentPosition", "func_184342_d");
captureCurrentPosition.invoke(player.connection);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
} else { } else {
entity.setLocationAndAngles(x, y, z, yaw, pitch); entity.setLocationAndAngles(x, y, z, yaw, pitch);
} }
entity.setRotationYawHead(yaw); entity.setRotationYawHead(yaw);
entity.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1f, 1f);
WorldUtils.getWorld(newDimension).playSound(null, new BlockPos(x,y,z), SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.BLOCKS, 1.0f, 1.0f);
return entity; return entity;
} else { // Based on EntityUtils.changeDimension } else { // Based on EntityUtils.changeDimension
@ -80,12 +98,6 @@ public final class TeleportUtils {
if (entity instanceof EntityPlayerMP) { if (entity instanceof EntityPlayerMP) {
EntityPlayerMP player = (EntityPlayerMP) entity; EntityPlayerMP player = (EntityPlayerMP) entity;
try {
Field invulnerableDimensionChange = MCPReflection.getMCPField(EntityPlayerMP.class, "invulnerableDimensionChange", "field_184851_cj");
invulnerableDimensionChange.setBoolean(player, true); // Prevent Minecraft from cancelling the position change being too big if the player is not in creative
} catch (NoSuchFieldException|IllegalAccessException e) {
throw new RuntimeException(e);
}
// player.enteredNetherPosition = null; // player.enteredNetherPosition = null;
player.dimension = newDimension; player.dimension = newDimension;
player.connection.sendPacket(new SPacketRespawn(player.dimension, newServer.getDifficulty(), newServer.getWorldInfo().getTerrainType(), player.interactionManager.getGameType())); player.connection.sendPacket(new SPacketRespawn(player.dimension, newServer.getDifficulty(), newServer.getWorldInfo().getTerrainType(), player.interactionManager.getGameType()));
@ -120,14 +132,10 @@ public final class TeleportUtils {
FMLCommonHandler.instance().firePlayerChangedDimensionEvent(player, oldDimension, newDimension); FMLCommonHandler.instance().firePlayerChangedDimensionEvent(player, oldDimension, newDimension);
//player.connection.sendPacket(new SPacketEffect(1032, BlockPos.ORIGIN, 0, false)); // TODO
//player.prevBlockpos = null; // For frost walk. Is this needed? What about other fields? //player.prevBlockpos = null; // For frost walk. Is this needed? What about other fields?
/*player.lastExperience = -1; /*player.lastExperience = -1;
player.lastHealth = -1.0F; player.lastHealth = -1.0F;
player.lastFoodLevel = -1;*/ player.lastFoodLevel = -1;*/
entity.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1f, 1f);
WorldUtils.getWorld(newDimension).playSound(null, new BlockPos(x,y,z), SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.BLOCKS, 1.0f, 1.0f);
return entity; return entity;
} else { } else {
@ -164,9 +172,6 @@ public final class TeleportUtils {
newServer.resetUpdateEntityTick(); newServer.resetUpdateEntityTick();
entity.world.profiler.endSection(); entity.world.profiler.endSection();
entity.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1f, 1f);
WorldUtils.getWorld(newDimension).playSound(null, new BlockPos(x,y,z), SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.BLOCKS, 1.0f, 1.0f);
return newEntity; return newEntity;
} }
} }

View file

@ -41,7 +41,7 @@ import net.minecraft.util.math.AxisAlignedBB;
@Setter private boolean unregisterDisabled = false; @Setter private boolean unregisterDisabled = false;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public double renderAngle = 0; public double renderAngle; // This is @SideOnly(Side.CLIENT), don't initialize the field ( = 0), or class initialization won't work on the server!
public TileEntityFloatingRift() { public TileEntityFloatingRift() {
updateTimer = random.nextInt(UPDATE_PERIOD); updateTimer = random.nextInt(UPDATE_PERIOD);

View file

@ -43,7 +43,7 @@ public final class SchematicConverter {
private final static int NBT_COMPOUND_TAG_ID = NBTUtils.NBT_COMPOUND_TAG_ID; private final static int NBT_COMPOUND_TAG_ID = NBTUtils.NBT_COMPOUND_TAG_ID;
private final static int STRING_TAG_ID = NBTUtils.NBT_COMPOUND_TAG_ID; private final static int STRING_TAG_ID = NBTUtils.NBT_COMPOUND_TAG_ID;
private static final boolean GENERATE_DUNGEON_INFO = false; private static final boolean GENERATE_DUNGEON_INFO = true;
public static Schematic convertSchematic(NBTTagCompound nbt, String schematicId, String name, String author) { public static Schematic convertSchematic(NBTTagCompound nbt, String schematicId, String name, String author) {
Schematic schematic = new Schematic(); Schematic schematic = new Schematic();