3
0

Implement ReverseClonner, which should fix all issues with teleportation/inventories/crashed after respawning

This commit is contained in:
Sergey Shatunov 2016-02-06 04:29:03 +07:00
parent 313adcfbb0
commit 0b251c5440
10 changed files with 69 additions and 65 deletions

View File

@ -23,12 +23,8 @@
public abstract class EntityPlayer extends EntityLivingBase implements ICommandSender
{
public static final String PERSISTED_NBT_TAG = "PlayerPersisted";
@@ -99,10 +115,10 @@
private HashMap<Integer, Boolean> spawnForcedMap = new HashMap<Integer, Boolean>();
public InventoryPlayer inventory = new InventoryPlayer(this);
- private InventoryEnderChest theInventoryEnderChest = new InventoryEnderChest();
+ public InventoryEnderChest theInventoryEnderChest = new InventoryEnderChest();
@@ -102,7 +118,7 @@
private InventoryEnderChest theInventoryEnderChest = new InventoryEnderChest();
public Container inventoryContainer;
public Container openContainer;
- protected FoodStats foodStats = new FoodStats();
@ -503,12 +499,12 @@
}
}
@@ -2023,7 +2246,7 @@
this.setScore(p_71049_1_.getScore());
@@ -2035,7 +2258,7 @@
{
getEntityData().setTag(PERSISTED_NBT_TAG, old.getCompoundTag(PERSISTED_NBT_TAG));
}
- MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerEvent.Clone(this, p_71049_1_, !p_71049_2_));
+ //MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerEvent.Clone(this, p_71049_1_, !p_71049_2_)); // KCauldron - moved to ReverseClonner
}
- this.theInventoryEnderChest = p_71049_1_.theInventoryEnderChest;
+ // this.theInventoryEnderChest = p_71049_1_.theInventoryEnderChest; // KCauldron - moved up
this.spawnChunkMap = p_71049_1_.spawnChunkMap;
this.spawnForcedMap = p_71049_1_.spawnForcedMap;
protected boolean canTriggerWalking()

View File

@ -705,16 +705,7 @@
public void addChatComponentMessage(IChatComponent p_146105_1_)
{
this.playerNetServerHandler.sendPacket(new S02PacketChat(p_146105_1_));
@@ -878,6 +1204,8 @@
public void clonePlayer(EntityPlayer p_71049_1_, boolean p_71049_2_)
{
+ this.theInventoryEnderChest = p_71049_1_.theInventoryEnderChest;
+ if (p_71049_1_ instanceof EntityPlayerMP) ((org.bukkit.craftbukkit.entity.CraftLivingEntity) (bukkitEntity = ((EntityPlayerMP) p_71049_1_).bukkitEntity)).updateEntity(this);
super.clonePlayer(p_71049_1_, p_71049_2_);
this.lastExperience = -1;
this.lastHealth = -1.0F;
@@ -1037,6 +1365,114 @@
@@ -1037,6 +1363,114 @@
return this.field_143005_bX;
}

View File

@ -1140,18 +1140,27 @@
+ if (this.playerEntity.dimension == 1) // coming from end
+ {
+ // We really should be calling transferPlayerToDimension since the player is coming in contact with a portal.
+ this.serverController.getConfigurationManager().respawnPlayer(this.playerEntity, 0, true); // set flag to indicate player is leaving end.
+ this.serverController.getConfigurationManager().respawnPlayer(this.playerEntity, 0, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL, null); // set flag to indicate player is leaving end.
}
+ else
+ // not coming from end
+ {
+ this.playerEntity = this.serverController.getConfigurationManager().respawnPlayer(this.playerEntity, 0, false);
+ this.playerEntity = this.serverController.getConfigurationManager().respawnPlayer(this.playerEntity, 0, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, null);
+ }
+ // Cauldron end
+ }
else if (this.playerEntity.getServerForPlayer().getWorldInfo().isHardcoreModeEnabled())
{
if (this.serverController.isSinglePlayer() && this.playerEntity.getCommandSenderName().equals(this.serverController.getServerOwner()))
@@ -857,7 +1612,7 @@
return;
}
- this.playerEntity = this.serverController.getConfigurationManager().respawnPlayer(this.playerEntity, playerEntity.dimension, false);
+ this.playerEntity = this.serverController.getConfigurationManager().respawnPlayer(this.playerEntity, playerEntity.dimension, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.DEATH, null);
}
break;
@@ -871,17 +1626,461 @@
public void processCloseWindow(C0DPacketCloseWindow p_147356_1_)

View File

@ -381,7 +381,7 @@
public EntityPlayerMP createPlayerForUser(GameProfile p_148545_1_)
{
UUID uuid = EntityPlayer.func_146094_a(p_148545_1_);
@@ -410,80 +620,200 @@
@@ -410,80 +620,199 @@
return new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(0), p_148545_1_, (ItemInWorldManager)object);
}
@ -451,10 +451,10 @@
+ // Cauldron start - refactor entire method for sanity.
+ public EntityPlayerMP respawnPlayer(EntityPlayerMP par1EntityPlayerMP, int par2, boolean par3)
+ {
+ return this.respawnPlayer(par1EntityPlayerMP, par2, par3, null, TeleportCause.DEATH);
+ return this.respawnPlayer(par1EntityPlayerMP, par2, par3 ? TeleportCause.END_PORTAL : TeleportCause.UNKNOWN, null);
+ }
+
+ public EntityPlayerMP respawnPlayer(EntityPlayerMP par1EntityPlayerMP, int targetDimension, boolean returnFromEnd, Location location, TeleportCause cause)
+ public EntityPlayerMP respawnPlayer(EntityPlayerMP par1EntityPlayerMP, int targetDimension, TeleportCause cause, Location location)
+ {
+ // Phase 1 - check if the player is allowed to respawn in same dimension
+ World world = mcServer.worldServerForDimension(targetDimension);
@ -470,7 +470,7 @@
+ }
+
+ // Phase 2 - handle return from End
+ if (returnFromEnd)
+ if (cause == TeleportCause.END_PORTAL)
+ {
+ WorldServer exitWorld = this.mcServer.worldServerForDimension(targetDimension);
+ Location enter = par1EntityPlayerMP.getBukkitEntity().getLocation();
@ -488,7 +488,7 @@
+ Bukkit.getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled() || event.getTo() == null)
+ {
+ return par1EntityPlayerMP;
+ return null;
+ }
+ }
+
@ -504,9 +504,8 @@
+ boolean spawnForced = par1EntityPlayerMP.isSpawnForced(targetDimension);
+ par1EntityPlayerMP.dimension = targetDimension;
+ // CraftBukkit start
+ EntityPlayerMP entityplayermp1 = par1EntityPlayerMP;
+ EntityPlayerMP entityplayermp1 = kcauldron.ReverseClonner.clone(par1EntityPlayerMP, cause == TeleportCause.DEATH);
+ entityplayermp1.setWorld(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension)); // make sure to update reference for bed spawn logic
+ MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerEvent.Clone(entityplayermp1, entityplayermp1, cause == TeleportCause.DEATH));
+ entityplayermp1.playerConqueredTheEnd = false;
ChunkCoordinates chunkcoordinates1;
+ boolean isBedSpawn = false;
@ -614,7 +613,7 @@
entityplayermp1.setHealth(entityplayermp1.getHealth());
- FMLCommonHandler.instance().firePlayerRespawnEvent(entityplayermp1);
+ // If world changed then fire the appropriate change world event else respawn
+ if (fromWorld != location.getWorld())
+ if (fromWorld != location.getWorld() && cause != TeleportCause.DEATH)
+ FMLCommonHandler.instance().firePlayerChangedDimensionEvent(entityplayermp1, ((CraftWorld) fromWorld).getHandle().provider.dimensionId,
+ ((CraftWorld) location.getWorld()).getHandle().provider.dimensionId, (CraftWorld) fromWorld); // Cauldron - fire forge changed dimension event
+ else
@ -622,7 +621,7 @@
return entityplayermp1;
}
@@ -492,34 +822,112 @@
@@ -492,34 +821,112 @@
transferPlayerToDimension(p_72356_1_, p_72356_2_, mcServer.worldServerForDimension(p_72356_2_).getDefaultTeleporter());
}
@ -754,7 +753,7 @@
}
public void transferEntityToWorld(Entity p_82448_1_, int p_82448_2_, WorldServer p_82448_3_, WorldServer p_82448_4_, Teleporter teleporter)
@@ -605,6 +1013,109 @@
@@ -605,6 +1012,109 @@
p_82448_1_.setWorld(p_82448_4_);
}
@ -864,7 +863,7 @@
public void sendPlayerInfoToAllPlayers()
{
if (++this.playerPingIndex > 600)
@@ -612,11 +1123,13 @@
@@ -612,11 +1122,13 @@
this.playerPingIndex = 0;
}
@ -878,7 +877,7 @@
}
public void sendPacketToAllPlayers(Packet p_148540_1_)
@@ -877,13 +1390,24 @@
@@ -877,13 +1389,24 @@
for (int j = 0; j < this.playerEntityList.size(); ++j)
{
EntityPlayerMP entityplayermp = (EntityPlayerMP)this.playerEntityList.get(j);
@ -905,7 +904,7 @@
if (d4 * d4 + d5 * d5 + d6 * d6 < p_148543_8_ * p_148543_8_)
{
entityplayermp.playerNetServerHandler.sendPacket(p_148543_11_);
@@ -941,13 +1465,16 @@
@@ -941,13 +1464,16 @@
p_72354_1_.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(1, 0.0F));
p_72354_1_.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(7, p_72354_2_.getRainStrength(1.0F)));
p_72354_1_.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(8, p_72354_2_.getWeightedThunderStrength(1.0F)));
@ -923,7 +922,7 @@
p_72385_1_.playerNetServerHandler.sendPacket(new S09PacketHeldItemChange(p_72385_1_.inventory.currentItem));
}
@@ -961,9 +1488,17 @@
@@ -961,9 +1487,17 @@
return this.maxPlayers;
}
@ -942,7 +941,7 @@
}
public void setWhiteListEnabled(boolean p_72371_1_)
@@ -1032,12 +1567,30 @@
@@ -1032,12 +1566,30 @@
public void removeAllPlayers()
{

View File

@ -0,0 +1,24 @@
package kcauldron;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ContainerPlayer;
import net.minecraft.server.management.ItemInWorldManager;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;
public enum ReverseClonner {
;
public static EntityPlayerMP clone(EntityPlayerMP player, boolean wasDeath) {
EntityPlayerMP shadowCopy = new EntityPlayerMP(player.mcServer, (WorldServer) player.worldObj,
player.getGameProfile(), new ItemInWorldManager(player.worldObj));
shadowCopy.clonePlayer(player, true);
if (wasDeath) {
player.inventory.clearInventory(null, -1);
player.inventoryContainer = new ContainerPlayer(player.inventory, !player.worldObj.isRemote, player);
}
MinecraftForge.EVENT_BUS.post(new PlayerEvent.Clone(player, shadowCopy, wasDeath));
return player;
}
}

View File

@ -27,8 +27,6 @@ import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
import net.minecraft.entity.EntityLivingBase;
public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
private CraftInventoryPlayer inventory;
private CraftInventory enderChest;
@ -40,13 +38,6 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
super(server, entity);
mode = server.getDefaultGameMode();
}
@Override
public void updateEntity(EntityLivingBase entity) {
super.updateEntity(entity);
if (inventory != null) inventory.updateInventory(((net.minecraft.entity.player.EntityPlayer) entity).inventory);
if (enderChest != null) enderChest.updateInventory(((net.minecraft.entity.player.EntityPlayer) entity).getInventoryEnderChest());
}
public String getName() {
return getHandle().getCommandSenderName();

View File

@ -48,18 +48,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
public Class<? extends net.minecraft.entity.EntityLivingBase> entityClass;
public String entityName;
// Cauldron end
public void updateEntity(net.minecraft.entity.EntityLivingBase entity) {
super.entity = entity;
public CraftLivingEntity(final CraftServer server, final net.minecraft.entity.EntityLivingBase entity) {
super(server, entity);
// Cauldron start
this.entityClass = entity.getClass();
this.entityName = EntityRegistry.getCustomEntityTypeName(entityClass);
if (entityName == null)
entityName = entity.getCommandSenderName();
}
public CraftLivingEntity(final CraftServer server, final net.minecraft.entity.EntityLivingBase entity) {
super(server, entity);
updateEntity(entity); // KCauldron
// Cauldron end
if (entity instanceof net.minecraft.entity.EntityLiving) {
equipment = new CraftEntityEquipment(this);

View File

@ -55,6 +55,7 @@ import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerRegisterChannelEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerUnregisterChannelEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.InventoryView.Property;
import org.bukkit.map.MapView;
import org.bukkit.metadata.MetadataValue;
@ -503,7 +504,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
if (fromWorld == toWorld) {
entity.playerNetServerHandler.teleport(to);
} else {
server.getHandle().respawnPlayer(entity, toWorld.dimension, false, to, cause); // Cauldron
server.getHandle().respawnPlayer(entity, toWorld.dimension, cause, to); // Cauldron
}
return true;
}
@ -1324,7 +1325,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
{
if ( getHealth() <= 0 && isOnline() )
{
server.getServer().getConfigurationManager().respawnPlayer( getHandle(), 0, false );
server.getServer().getConfigurationManager().respawnPlayer( getHandle(), 0, TeleportCause.DEATH, null );
}
}

View File

@ -17,15 +17,11 @@ import org.bukkit.Material;
public class CraftInventory implements Inventory {
protected net.minecraft.inventory.IInventory inventory;
protected final net.minecraft.inventory.IInventory inventory;
public CraftInventory(net.minecraft.inventory.IInventory inventory) {
this.inventory = inventory;
}
public void updateInventory(net.minecraft.inventory.IInventory inventory) {
this.inventory = inventory;
}
public net.minecraft.inventory.IInventory getInventory() {
return inventory;

View File

@ -11,7 +11,7 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
public CraftInventoryPlayer(net.minecraft.entity.player.InventoryPlayer inventory) {
super(inventory);
}
@Override
public net.minecraft.entity.player.InventoryPlayer getInventory() {
return (net.minecraft.entity.player.InventoryPlayer) inventory;