diff --git a/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java b/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java index e3e00725d7..886dba3fa8 100644 --- a/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java +++ b/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java @@ -19,7 +19,8 @@ package net.minecraftforge.common.util; -import java.io.Serializable; +import java.lang.ref.WeakReference; +import java.util.Objects; import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.NBTTagCompound; @@ -27,7 +28,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.common.DimensionManager; +import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.registry.ForgeRegistries; import javax.annotation.Nullable; @@ -39,41 +40,25 @@ import javax.annotation.Nullable; * Unlike Block, which only one object can exist per coordinate, BlockSnapshot * can exist multiple times for any given Block. */ -@SuppressWarnings({"serial", "deprecation"}) -public class BlockSnapshot implements Serializable +public class BlockSnapshot { private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("forge.debugBlockSnapshot", "false")); private final BlockPos pos; private final int dimId; - private transient IBlockState replacedBlock; + @Nullable + private IBlockState replacedBlock; private int flag; @Nullable private final NBTTagCompound nbt; - private transient World world; + @Nullable + private WeakReference world; private final ResourceLocation registryName; private final int meta; public BlockSnapshot(World world, BlockPos pos, IBlockState state) { - this.setWorld(world); - this.dimId = world.provider.getDimension(); - this.pos = pos; - this.setReplacedBlock(state); - this.registryName = state.getBlock().getRegistryName(); - this.meta = state.getBlock().getMetaFromState(state); - this.setFlag(3); - TileEntity te = world.getTileEntity(pos); - if (te != null) - { - nbt = new NBTTagCompound(); - te.writeToNBT(getNbt()); - } - else nbt = null; - if (DEBUG) - { - System.out.printf("Created BlockSnapshot - [World: %s ][Location: %d,%d,%d ][Block: %s ][Meta: %d ]", world.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ(), getRegistryName(), getMeta()); - } + this(world, pos, state, getTileNBT(world.getTileEntity(pos))); } public BlockSnapshot(World world, BlockPos pos, IBlockState state, @Nullable NBTTagCompound nbt) @@ -98,15 +83,22 @@ public class BlockSnapshot implements Serializable this.setFlag(flag); } + /** @deprecated use {@link #BlockSnapshot(int, BlockPos, ResourceLocation, int, int, NBTTagCompound)} */ + @Deprecated + public BlockSnapshot(int dimension, BlockPos pos, String modId, String blockName, int meta, int flag, @Nullable NBTTagCompound nbt) + { + this(dimension, pos, new ResourceLocation(modId, blockName), meta, flag, nbt); + } + /** * Raw constructor designed for serialization usages. */ - public BlockSnapshot(int dimension, BlockPos pos, String modId, String blockName, int meta, int flag, @Nullable NBTTagCompound nbt) + public BlockSnapshot(int dimension, BlockPos pos, ResourceLocation registryName, int meta, int flag, @Nullable NBTTagCompound nbt) { this.dimId = dimension; this.pos = pos.toImmutable(); this.setFlag(flag); - this.registryName = new ResourceLocation(modId, blockName); + this.registryName = registryName; this.meta = meta; this.nbt = nbt; } @@ -123,16 +115,22 @@ public class BlockSnapshot implements Serializable public static BlockSnapshot readFromNBT(NBTTagCompound tag) { - NBTTagCompound nbt = tag.getBoolean("hasTE") ? null : tag.getCompoundTag("tileEntity"); - return new BlockSnapshot( tag.getInteger("dimension"), new BlockPos(tag.getInteger("posX"), tag.getInteger("posY"), tag.getInteger("posZ")), - tag.getString("blockMod"), - tag.getString("blockName"), + new ResourceLocation(tag.getString("blockMod"), tag.getString("blockName")), tag.getInteger("metadata"), tag.getInteger("flag"), - nbt); + tag.getBoolean("hasTE") ? tag.getCompoundTag("tileEntity") : null); + } + + @Nullable + private static NBTTagCompound getTileNBT(@Nullable TileEntity te) + { + if (te == null) return null; + NBTTagCompound nbt = new NBTTagCompound(); + te.writeToNBT(nbt); + return nbt; } public IBlockState getCurrentBlock() @@ -142,27 +140,28 @@ public class BlockSnapshot implements Serializable public World getWorld() { - if (this.world == null) + World world = this.world != null ? this.world.get() : null; + if (world == null) { - this.world = DimensionManager.getWorld(getDimId()); + world = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(getDimId()); + this.world = new WeakReference(world); } - return this.world; + return world; } public IBlockState getReplacedBlock() { if (this.replacedBlock == null) { - this.replacedBlock = ForgeRegistries.BLOCKS.getValue(this.getRegistryName()).getStateFromMeta(getMeta()); + this.replacedBlock = ForgeRegistries.BLOCKS.getValue(getRegistryName()).getStateFromMeta(getMeta()); } return this.replacedBlock; } + @Nullable public TileEntity getTileEntity() { - if (getNbt() != null) - return TileEntity.create(getWorld(), getNbt()); - else return null; + return getNbt() != null ? TileEntity.create(getWorld(), getNbt()) : null; } public boolean restore() @@ -175,51 +174,21 @@ public class BlockSnapshot implements Serializable return restore(force, true); } - public boolean restore(boolean force, boolean applyPhysics) + public boolean restore(boolean force, boolean notifyNeighbors) { - IBlockState current = getCurrentBlock(); - IBlockState replaced = getReplacedBlock(); - if (current.getBlock() != replaced.getBlock() || current.getBlock().getMetaFromState(current) != replaced.getBlock().getMetaFromState(replaced)) - { - if (force) - { - getWorld().setBlockState(getPos(), replaced, applyPhysics ? 3 : 2); - } - else - { - return false; - } - } - - getWorld().setBlockState(getPos(), replaced, applyPhysics ? 3 : 2); - getWorld().notifyBlockUpdate(getPos(), current, replaced, applyPhysics ? 3 : 2); - TileEntity te = null; - if (getNbt() != null) - { - te = getWorld().getTileEntity(getPos()); - if (te != null) - { - te.readFromNBT(getNbt()); - te.markDirty(); - } - } - - if (DEBUG) - { - System.out.printf("Restored BlockSnapshot with data [World: %s ][Location: %d,%d,%d ][Meta: %d ][Block: %s ][TileEntity: %s ][force: %s ][applyPhysics: %s]", getWorld().getWorldInfo().getWorldName(), getPos().getX(), getPos().getY(), getPos().getZ(), replaced.getBlock().getMetaFromState(replaced), replaced.getBlock().delegate.name(), te, force, applyPhysics); - } - return true; + return restoreToLocation(getWorld(), getPos(), force, notifyNeighbors); } - public boolean restoreToLocation(World world, BlockPos pos, boolean force, boolean applyPhysics) + public boolean restoreToLocation(World world, BlockPos pos, boolean force, boolean notifyNeighbors) { IBlockState current = getCurrentBlock(); IBlockState replaced = getReplacedBlock(); + if (current.getBlock() != replaced.getBlock() || current.getBlock().getMetaFromState(current) != replaced.getBlock().getMetaFromState(replaced)) { if (force) { - world.setBlockState(pos, replaced, applyPhysics ? 3 : 2); + world.setBlockState(pos, replaced, notifyNeighbors ? 3 : 2); } else { @@ -227,8 +196,9 @@ public class BlockSnapshot implements Serializable } } - world.setBlockState(pos, replaced, applyPhysics ? 3 : 2); - world.notifyBlockUpdate(pos, current, replaced, applyPhysics ? 3 : 2); + world.setBlockState(pos, replaced, notifyNeighbors ? 3 : 2); + world.notifyBlockUpdate(pos, current, replaced, notifyNeighbors ? 3 : 2); + TileEntity te = null; if (getNbt() != null) { @@ -242,7 +212,7 @@ public class BlockSnapshot implements Serializable if (DEBUG) { - System.out.printf("Restored BlockSnapshot with data [World: %s ][Location: %d,%d,%d ][Meta: %d ][Block: %s ][TileEntity: %s ][force: %s ][applyPhysics: %s]", world.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ(), replaced.getBlock().getMetaFromState(replaced), replaced.getBlock().delegate.name(), te, force, applyPhysics); + System.out.printf("Restored BlockSnapshot with data [World: %s ][Location: %d,%d,%d ][Meta: %d ][Block: %s ][TileEntity: %s ][force: %s ][notifyNeighbors: %s]", world.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ(), replaced.getBlock().getMetaFromState(replaced), replaced.getBlock().delegate.name(), te, force, notifyNeighbors); } return true; } @@ -269,6 +239,10 @@ public class BlockSnapshot implements Serializable @Override public boolean equals(Object obj) { + if (obj == this) + { + return true; + } if (obj == null) { return false; @@ -278,10 +252,6 @@ public class BlockSnapshot implements Serializable return false; } final BlockSnapshot other = (BlockSnapshot) obj; - if (!this.getPos().equals(other.getPos())) - { - return false; - } if (this.getMeta() != other.getMeta()) { return false; @@ -290,15 +260,15 @@ public class BlockSnapshot implements Serializable { return false; } - if (this.getNbt() != other.getNbt() && (this.getNbt() == null || !this.getNbt().equals(other.getNbt()))) + if (!this.getPos().equals(other.getPos())) { return false; } - if (this.getWorld() != other.getWorld() && (this.getWorld() == null || !this.getWorld().equals(other.getWorld()))) + if (!this.getRegistryName().equals(other.getRegistryName())) { return false; } - if (this.getRegistryName() != other.getRegistryName() && (this.getRegistryName() == null || !this.getRegistryName().equals(other.getRegistryName()))) + if (!Objects.equals(this.getNbt(), other.getNbt())) { return false; } @@ -309,25 +279,30 @@ public class BlockSnapshot implements Serializable public int hashCode() { int hash = 7; - hash = 73 * hash + this.getPos().getX(); - hash = 73 * hash + this.getPos().getY(); - hash = 73 * hash + this.getPos().getZ(); hash = 73 * hash + this.getMeta(); hash = 73 * hash + this.getDimId(); - hash = 73 * hash + (this.getNbt() != null ? this.getNbt().hashCode() : 0); - hash = 73 * hash + (this.getWorld() != null ? this.getWorld().hashCode() : 0); - hash = 73 * hash + (this.getRegistryName() != null ? this.getRegistryName().hashCode() : 0); + hash = 73 * hash + this.getPos().hashCode(); + hash = 73 * hash + this.getRegistryName().hashCode(); + hash = 73 * hash + Objects.hashCode(this.getNbt()); return hash; } public BlockPos getPos() { return pos; } + public int getDimId() { return dimId; } + public void setReplacedBlock(IBlockState replacedBlock) { this.replacedBlock = replacedBlock; } + public int getFlag() { return flag; } + public void setFlag(int flag) { this.flag = flag; } + @Nullable public NBTTagCompound getNbt() { return nbt; } - public void setWorld(World world) { this.world = world; } + + public void setWorld(World world) { this.world = new WeakReference(world); } + public ResourceLocation getRegistryName() { return registryName; } + public int getMeta() { return meta; } }