1
0
forked from xjboss/KCauldronX

Initial commit (Forge 1291).

This commit is contained in:
gamerforEA
2015-03-22 20:38:04 +03:00
commit 16773ead6a
611 changed files with 64826 additions and 0 deletions

View File

@ -0,0 +1,266 @@
--- ../src-base/minecraft/net/minecraft/world/chunk/Chunk.java
+++ ../src-work/minecraft/net/minecraft/world/chunk/Chunk.java
@@ -36,6 +36,17 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+// CraftBukkit start
+import net.minecraft.block.BlockContainer;
+import org.bukkit.Bukkit;
+// CraftBukkit end
+// Spigot start
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.entity.EnumCreatureType;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.inventory.IInventory;
+// Spigot end
+
public class Chunk
{
private static final Logger logger = LogManager.getLogger();
@@ -62,6 +73,8 @@
public int heightMapMinimum;
public long inhabitedTime;
private int queuedLightChecks;
+ public gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot (Cauldron protected -> public)
+ public int lastAccessedTick; // Cauldron track last time the chunk was accessed
private static final String __OBFID = "CL_00000373";
public Chunk(World p_i1995_1_, int p_i1995_2_, int p_i1995_3_)
@@ -80,13 +93,22 @@
for (int k = 0; k < this.entityLists.length; ++k)
{
- this.entityLists[k] = new ArrayList();
+ this.entityLists[k] = new org.bukkit.craftbukkit.util.UnsafeList(); // CraftBukkit - ArrayList -> UnsafeList
}
Arrays.fill(this.precipitationHeightMap, -999);
Arrays.fill(this.blockBiomeArray, (byte) - 1);
+ // CraftBukkit start
+ if (!(this instanceof EmptyChunk))
+ {
+ this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this);
+ }
}
+ public org.bukkit.Chunk bukkitChunk;
+ public boolean mustSave;
+ // CraftBukkit end
+
public Chunk(World p_i45446_1_, Block[] p_i45446_2_, int p_i45446_3_, int p_i45446_4_)
{
this(p_i45446_1_, p_i45446_3_, p_i45446_4_);
@@ -589,9 +611,10 @@
if (!this.worldObj.isRemote)
{
+ if (block1 == null) return false; // Cauldron
block1.onBlockPreDestroy(this.worldObj, l1, p_150807_2_, i2, k1);
}
-
+ // Cauldron - Removed CB patch that fixes BUKKIT-5238 to prevent stackoverflows. See issue #1165 and #1169
extendedblockstorage.func_150818_a(p_150807_1_, p_150807_2_ & 15, p_150807_3_, p_150807_4_);
extendedblockstorage.setExtBlockMetadata(p_150807_1_, p_150807_2_ & 15, p_150807_3_, p_150807_5_); // This line duplicates the one below, so breakBlock fires with valid worldstate
@@ -777,8 +800,14 @@
if (i != this.xPosition || j != this.zPosition)
{
- logger.warn("Wrong location! " + p_76612_1_ + " (at " + i + ", " + j + " instead of " + this.xPosition + ", " + this.zPosition + ")");
- Thread.dumpStack();
+ // CraftBukkit start
+ Bukkit.getLogger().warning("Wrong location for " + p_76612_1_ + " in world '" + worldObj.getWorld().getName() + "'!");
+ //logger.warn("Wrong location! " + p_76612_1_ + " (at " + i + ", " + j + " instead of " + this.xPosition + ", " + this.zPosition + ")");
+ //Thread.dumpStack();
+ Bukkit.getLogger().warning(
+ "Entity is at " + p_76612_1_.posX + "," + p_76612_1_.posZ + " (chunk " + i + "," + j + ") but was stored in chunk " + this.xPosition + ","
+ + this.zPosition);
+ // CraftBukkit end
}
int k = MathHelper.floor_double(p_76612_1_.posY / 16.0D);
@@ -799,6 +828,26 @@
p_76612_1_.chunkCoordY = k;
p_76612_1_.chunkCoordZ = this.zPosition;
this.entityLists[k].add(p_76612_1_);
+ // Spigot start - increment creature type count
+ // Keep this synced up with World.a(Class)
+ if (p_76612_1_ instanceof EntityLiving)
+ {
+ EntityLiving entityliving = (EntityLiving) p_76612_1_;
+
+ if (entityliving.canDespawn_CB() && entityliving.isNoDespawnRequired())
+ {
+ return;
+ }
+ }
+
+ for (EnumCreatureType creatureType : EnumCreatureType.values())
+ {
+ if (creatureType.getCreatureClass().isAssignableFrom(p_76612_1_.getClass()))
+ {
+ this.entityCount.adjustOrPutValue(creatureType.getCreatureClass(), 1, 1);
+ }
+ }
+ // Spigot end
}
public void removeEntity(Entity p_76622_1_)
@@ -819,6 +868,26 @@
}
this.entityLists[p_76608_2_].remove(p_76608_1_);
+ // Spigot start - decrement creature type count
+ // Keep this synced up with World.a(Class)
+ if (p_76608_1_ instanceof EntityLiving)
+ {
+ EntityLiving entityliving = (EntityLiving) p_76608_1_;
+
+ if (entityliving.canDespawn_CB() && entityliving.isNoDespawnRequired())
+ {
+ return;
+ }
+ }
+
+ for (EnumCreatureType creatureType : EnumCreatureType.values())
+ {
+ if (creatureType.getCreatureClass().isAssignableFrom(p_76608_1_.getClass()))
+ {
+ this.entityCount.adjustValue(creatureType.getCreatureClass(), -1);
+ }
+ }
+ // Spigot end
}
public boolean canBlockSeeTheSky(int p_76619_1_, int p_76619_2_, int p_76619_3_)
@@ -874,9 +943,23 @@
p_150812_4_.xCoord = this.xPosition * 16 + p_150812_1_;
p_150812_4_.yCoord = p_150812_2_;
p_150812_4_.zCoord = this.zPosition * 16 + p_150812_3_;
+ // Cauldron start - validate TE for corrupted data
+ Block block = null;
+ try
+ {
+ block = this.getBlock(p_150812_1_, p_150812_2_, p_150812_3_);
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ System.out.println("ERROR: Detected corrupted TileEntity " + p_150812_4_ + " with bad extended block ID of "
+ + ((p_150812_2_ & 15) << 8 | p_150812_3_ << 4 | p_150812_1_) + " @ " + p_150812_4_.xCoord + ", " + p_150812_4_.yCoord + ", "
+ + p_150812_4_.zCoord + ". Removing TE to avoid crash...");
+ p_150812_4_.invalidate();
+ return;
+ }
int metadata = getBlockMetadata(p_150812_1_, p_150812_2_, p_150812_3_);
- if (this.getBlock(p_150812_1_, p_150812_2_, p_150812_3_).hasTileEntity(metadata))
+ if (block != null && block.hasTileEntity(metadata)) // Cauldron end
{
if (this.chunkTileEntityMap.containsKey(chunkposition))
{
@@ -886,6 +969,16 @@
p_150812_4_.validate();
this.chunkTileEntityMap.put(chunkposition, p_150812_4_);
}
+ // CraftBukkit start
+ else if (net.minecraft.server.MinecraftServer.getServer().tileEntityConfig.enableTEPlaceWarning.getValue()) // Cauldron
+ {
+ System.out.println("Attempted to place a tile entity (" + p_150812_4_ + ") at " + p_150812_4_.xCoord + "," + p_150812_4_.yCoord + ","
+ + p_150812_4_.zCoord + " (" + org.bukkit.Material.getMaterial(Block.getIdFromBlock(getBlock(p_150812_1_, p_150812_2_, p_150812_3_)))
+ + ") where there was no entity tile!");
+ System.out.println("Chunk coordinates: " + (this.xPosition * 16) + "," + (this.zPosition * 16));
+ new Exception().printStackTrace();
+ }
+ // CraftBukkit end
}
public void removeTileEntity(int p_150805_1_, int p_150805_2_, int p_150805_3_)
@@ -936,6 +1029,21 @@
for (int i = 0; i < this.entityLists.length; ++i)
{
+ // CraftBukkit start
+ java.util.Iterator iter = this.entityLists[i].iterator();
+
+ while (iter.hasNext())
+ {
+ Entity entity = (Entity) iter.next();
+
+ // Do not pass along players, as doing so can get them stuck outside of time.
+ // (which for example disables inventory icon updates and prevents block breaking)
+ if (entity instanceof EntityPlayerMP)
+ {
+ iter.remove();
+ }
+ }
+ // CraftBukkit end
this.worldObj.unloadEntities(this.entityLists[i]);
}
MinecraftForge.EVENT_BUS.post(new ChunkEvent.Unload(this));
@@ -1035,6 +1143,7 @@
public void populateChunk(IChunkProvider p_76624_1_, IChunkProvider p_76624_2_, int p_76624_3_, int p_76624_4_)
{
+ worldObj.timings.syncChunkLoadPostTimer.startTiming(); // Spigot
if (!this.isTerrainPopulated && p_76624_1_.chunkExists(p_76624_3_ + 1, p_76624_4_ + 1) && p_76624_1_.chunkExists(p_76624_3_, p_76624_4_ + 1) && p_76624_1_.chunkExists(p_76624_3_ + 1, p_76624_4_))
{
p_76624_1_.populate(p_76624_2_, p_76624_3_, p_76624_4_);
@@ -1054,6 +1163,7 @@
{
p_76624_1_.populate(p_76624_2_, p_76624_3_ - 1, p_76624_4_ - 1);
}
+ worldObj.timings.syncChunkLoadPostTimer.stopTiming(); // Spigot
}
public int getPrecipitationHeight(int p_76626_1_, int p_76626_2_)
@@ -1184,8 +1294,10 @@
if ((p_76607_2_ & 1 << l) != 0 && this.storageArrays[l] != null)
{
nibblearray = this.storageArrays[l].getMetadataArray();
- System.arraycopy(p_76607_1_, k, nibblearray.data, 0, nibblearray.data.length);
- k += nibblearray.data.length;
+ // Spigot start
+ System.arraycopy(p_76607_1_, k, nibblearray.getValueArray(), 0, nibblearray.getValueArray().length);
+ k += nibblearray.getValueArray().length;
+ // Spigot end
}
}
@@ -1194,8 +1306,10 @@
if ((p_76607_2_ & 1 << l) != 0 && this.storageArrays[l] != null)
{
nibblearray = this.storageArrays[l].getBlocklightArray();
- System.arraycopy(p_76607_1_, k, nibblearray.data, 0, nibblearray.data.length);
- k += nibblearray.data.length;
+ // Spigot start
+ System.arraycopy(p_76607_1_, k, nibblearray.getValueArray(), 0, nibblearray.getValueArray().length);
+ k += nibblearray.getValueArray().length;
+ // Spigot end
}
}
@@ -1206,8 +1320,10 @@
if ((p_76607_2_ & 1 << l) != 0 && this.storageArrays[l] != null)
{
nibblearray = this.storageArrays[l].getSkylightArray();
- System.arraycopy(p_76607_1_, k, nibblearray.data, 0, nibblearray.data.length);
- k += nibblearray.data.length;
+ // Spigot start
+ System.arraycopy(p_76607_1_, k, nibblearray.getValueArray(), 0, nibblearray.getValueArray().length);
+ k += nibblearray.getValueArray().length;
+ // Spigot end
}
}
}
@@ -1229,8 +1345,8 @@
nibblearray = this.storageArrays[l].createBlockMSBArray();
}
- System.arraycopy(p_76607_1_, k, nibblearray.data, 0, nibblearray.data.length);
- k += nibblearray.data.length;
+ System.arraycopy(p_76607_1_, k, nibblearray.getValueArray(), 0, nibblearray.getValueArray().length);
+ k += nibblearray.getValueArray().length;
}
}
else if (p_76607_4_ && this.storageArrays[l] != null && this.storageArrays[l].getBlockMSBArray() != null)

View File

@ -0,0 +1,233 @@
--- ../src-base/minecraft/net/minecraft/world/chunk/NibbleArray.java
+++ ../src-work/minecraft/net/minecraft/world/chunk/NibbleArray.java
@@ -1,47 +1,215 @@
package net.minecraft.world.chunk;
+import java.util.Arrays; // Spigot
+
public class NibbleArray
{
- public final byte[] data;
+ public byte[] data; // Spigot - remove final // Cauldron - make public
private final int depthBits;
private final int depthBitsPlusFour;
private static final String __OBFID = "CL_00000371";
- public NibbleArray(int p_i1992_1_, int p_i1992_2_)
+ // Spigot start
+ private byte trivialValue;
+ private byte trivialByte;
+ private int length;
+ private static final int LEN2K = 2048; // Universal length used right now - optimize around this
+ private static final byte[][] TrivLen2k;
+
+ static
{
- this.data = new byte[p_i1992_1_ >> 1];
- this.depthBits = p_i1992_2_;
- this.depthBitsPlusFour = p_i1992_2_ + 4;
+ TrivLen2k = new byte[16][];
+
+ for (int i = 0; i < 16; i++)
+ {
+ TrivLen2k[i] = new byte[LEN2K];
+ Arrays.fill(TrivLen2k[i], (byte)(i | (i << 4)));
+ }
}
- public NibbleArray(byte[] p_i1993_1_, int p_i1993_2_)
+ // Try to convert array to trivial array
+ public void detectAndProcessTrivialArray()
{
- this.data = p_i1993_1_;
- this.depthBits = p_i1993_2_;
- this.depthBitsPlusFour = p_i1993_2_ + 4;
+ trivialValue = (byte)(data[0] & 0xF);
+ trivialByte = (byte)(trivialValue | (trivialValue << 4));
+
+ for (int i = 0; i < data.length; i++)
+ {
+ if (data[i] != trivialByte)
+ {
+ return;
+ }
+ }
+
+ // All values matches, so array is trivial
+ this.length = data.length;
+ this.data = null;
}
- public int get(int p_76582_1_, int p_76582_2_, int p_76582_3_)
+ // Force array to non-trivial state
+ public void forceToNonTrivialArray()
{
- int l = p_76582_2_ << this.depthBitsPlusFour | p_76582_3_ << this.depthBits | p_76582_1_;
+ if (this.data == null)
+ {
+ this.data = new byte[this.length];
+
+ if (this.trivialByte != 0)
+ {
+ Arrays.fill(this.data, this.trivialByte);
+ }
+ }
+ }
+
+ // Test if array is in trivial state
+ public boolean isTrivialArray()
+ {
+ return (this.data == null);
+ }
+
+ // Get value of all elements (only valid if array is in trivial state)
+ public int getTrivialArrayValue()
+ {
+ return this.trivialValue;
+ }
+
+ // Get logical length of byte array for nibble data (whether trivial or non-trivial)
+ public int getByteLength()
+ {
+ if (this.data == null)
+ {
+ return this.length;
+ }
+ else
+ {
+ return this.data.length;
+ }
+ }
+
+ // Return byte encoding of array (whether trivial or non-trivial) - returns read-only array if trivial (do not modify!)
+ public byte[] getValueArray()
+ {
+ if (this.data != null)
+ {
+ return this.data;
+ }
+ else
+ {
+ byte[] rslt;
+
+ if (this.length == LEN2K) // All current uses are 2k long, but be safe
+ {
+ rslt = TrivLen2k[this.trivialValue];
+ }
+ else
+ {
+ rslt = new byte[this.length];
+
+ if (this.trivialByte != 0)
+ {
+ Arrays.fill(rslt, this.trivialByte);
+ }
+ }
+
+ return rslt;
+ }
+ }
+
+ // Copy byte representation of array to given offset in given byte array
+ public int copyToByteArray(byte[] dest, int off)
+ {
+ if (this.data == null)
+ {
+ Arrays.fill(dest, off, off + this.length, this.trivialByte);
+ return off + this.length;
+ }
+ else
+ {
+ System.arraycopy(this.data, 0, dest, off, this.data.length);
+ return off + this.data.length;
+ }
+ }
+
+ // Resize array to given byte length
+ public void resizeArray(int len)
+ {
+ if (this.data == null)
+ {
+ this.length = len;
+ }
+ else if (this.data.length != len)
+ {
+ byte[] newa = new byte[len];
+ System.arraycopy(this.data, 0, newa, 0, ((this.data.length > len) ? len : this.data.length));
+ this.data = newa;
+ }
+ }
+ // Spigot end
+
+ public NibbleArray(int par1, int par2)
+ {
+ // Spigot start
+ //this.a = new byte[i >> 1];
+ this.data = null; // Start off as trivial value (all same zero value)
+ this.length = par1 >> 1;
+ this.trivialByte = this.trivialValue = 0;
+ // Spigot end
+ this.depthBits = par2;
+ this.depthBitsPlusFour = par2 + 4;
+ }
+
+ public NibbleArray(byte[] par1ArrayOfByte, int par2)
+ {
+ this.data = par1ArrayOfByte;
+ this.depthBits = par2;
+ this.depthBitsPlusFour = par2 + 4;
+ detectAndProcessTrivialArray(); // Spigot
+ }
+
+ public int get(int par1, int par2, int par3)
+ {
+ if (this.data == null)
+ {
+ return this.trivialValue; // Spigot
+ }
+
+ int l = par2 << this.depthBitsPlusFour | par3 << this.depthBits | par1;
int i1 = l >> 1;
int j1 = l & 1;
return j1 == 0 ? this.data[i1] & 15 : this.data[i1] >> 4 & 15;
}
- public void set(int p_76581_1_, int p_76581_2_, int p_76581_3_, int p_76581_4_)
+ public void set(int par1, int par2, int par3, int par4)
{
- int i1 = p_76581_2_ << this.depthBitsPlusFour | p_76581_3_ << this.depthBits | p_76581_1_;
+ // Spigot start
+ if (this.data == null)
+ {
+ if (par4 != this.trivialValue) // Not same as trivial value, array no longer trivial
+ {
+ this.data = new byte[this.length];
+
+ if (this.trivialByte != 0)
+ {
+ Arrays.fill(this.data, this.trivialByte);
+ }
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ // Spigot end
+ int i1 = par2 << this.depthBitsPlusFour | par3 << this.depthBits | par1;
int j1 = i1 >> 1;
int k1 = i1 & 1;
if (k1 == 0)
{
- this.data[j1] = (byte)(this.data[j1] & 240 | p_76581_4_ & 15);
+ this.data[j1] = (byte)(this.data[j1] & 240 | par4 & 15);
}
else
{
- this.data[j1] = (byte)(this.data[j1] & 15 | (p_76581_4_ & 15) << 4);
+ this.data[j1] = (byte)(this.data[j1] & 15 | (par4 & 15) << 4);
}
}
}

View File

@ -0,0 +1,228 @@
--- ../src-base/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java
+++ ../src-work/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java
@@ -33,6 +33,13 @@
import org.apache.logging.log4j.Logger;
import cpw.mods.fml.common.FMLLog;
+// Cauldron start
+import java.util.Map;
+import net.minecraft.server.MinecraftServer;
+import net.minecraftforge.cauldron.CauldronUtils;
+import net.minecraftforge.common.util.EnumHelper;
+import cpw.mods.fml.common.asm.transformers.SideTransformer;
+// Cauldron end
public class AnvilChunkLoader implements IChunkLoader, IThreadedFileIO
{
@@ -41,6 +48,7 @@
private Set pendingAnvilChunksCoordinates = new HashSet();
private Object syncLockObject = new Object();
public final File chunkSaveLocation;
+ private List checkedTileEntities = new ArrayList(); // Cauldron
private static final String __OBFID = "CL_00000384";
public AnvilChunkLoader(File p_i2003_1_)
@@ -73,13 +81,16 @@
public Chunk loadChunk(World p_75815_1_, int p_75815_2_, int p_75815_3_) throws IOException
{
+ p_75815_1_.timings.syncChunkLoadDataTimer.startTiming(); // Spigot
Object[] data = this.loadChunk__Async(p_75815_1_, p_75815_2_, p_75815_3_);
+ p_75815_1_.timings.syncChunkLoadDataTimer.stopTiming(); // Spigot
if (data != null)
{
Chunk chunk = (Chunk) data[0];
NBTTagCompound nbttagcompound = (NBTTagCompound) data[1];
this.loadEntities(p_75815_1_, nbttagcompound.getCompoundTag("Level"), chunk);
+ MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, nbttagcompound)); // Cauldron - Don't call ChunkDataEvent.Load async
return chunk;
}
@@ -156,8 +167,8 @@
if (!chunk.isAtLocation(p_75822_2_, p_75822_3_))
{
logger.error("Chunk file at " + p_75822_2_ + "," + p_75822_3_ + " is in the wrong location; relocating. (Expected " + p_75822_2_ + ", " + p_75822_3_ + ", got " + chunk.xPosition + ", " + chunk.zPosition + ")");
- p_75822_4_.setInteger("xPos", p_75822_2_);
- p_75822_4_.setInteger("zPos", p_75822_3_);
+ p_75822_4_.getCompoundTag("Level").setInteger("xPos", p_75822_2_); // CraftBukkit - .getCompound("Level")
+ p_75822_4_.getCompoundTag("Level").setInteger("zPos", p_75822_3_); // CraftBukkit - .getCompound("Level")
// Have to move tile entities since we don't load them at this stage
NBTTagList tileEntities = p_75822_4_.getCompoundTag("Level").getTagList("TileEntities", 10);
@@ -187,8 +198,18 @@
public void saveChunk(World p_75816_1_, Chunk p_75816_2_) throws MinecraftException, IOException
{
- p_75816_1_.checkSessionLock();
+ // CraftBukkit start - "handle" exception
+ try
+ {
+ p_75816_1_.checkSessionLock();
+ }
+ catch (MinecraftException ex)
+ {
+ ex.printStackTrace();
+ }
+ // CraftBukkit end
+
try
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
@@ -230,7 +251,7 @@
public boolean writeNextIO()
{
- AnvilChunkLoader.PendingChunk pendingchunk = null;
+ PendingChunk pendingchunktosave = null;
Object object = this.syncLockObject;
synchronized (this.syncLockObject)
@@ -240,15 +261,15 @@
return false;
}
- pendingchunk = (AnvilChunkLoader.PendingChunk)this.chunksToRemove.remove(0);
- this.pendingAnvilChunksCoordinates.remove(pendingchunk.chunkCoordinate);
+ pendingchunktosave = (PendingChunk) this.chunksToRemove.remove(0);
+ this.pendingAnvilChunksCoordinates.remove(pendingchunktosave.chunkCoordinate);
}
- if (pendingchunk != null)
+ if (pendingchunktosave != null)
{
try
{
- this.writeChunkNBTTags(pendingchunk);
+ this.writeChunkNBTTags(pendingchunktosave);
}
catch (Exception exception)
{
@@ -259,7 +280,7 @@
return true;
}
- private void writeChunkNBTTags(AnvilChunkLoader.PendingChunk p_75821_1_) throws IOException
+ public void writeChunkNBTTags(AnvilChunkLoader.PendingChunk p_75821_1_) throws java.io.IOException // CraftBukkit - public -> private, added throws
{
DataOutputStream dataoutputstream = RegionFileCache.getChunkOutputStream(this.chunkSaveLocation, p_75821_1_.chunkCoordinate.chunkXPos, p_75821_1_.chunkCoordinate.chunkZPos);
CompressedStreamTools.write(p_75821_1_.nbtTags, dataoutputstream);
@@ -307,19 +328,19 @@
if (extendedblockstorage.getBlockMSBArray() != null)
{
- nbttagcompound1.setByteArray("Add", extendedblockstorage.getBlockMSBArray().data);
+ nbttagcompound1.setByteArray("Add", extendedblockstorage.getBlockMSBArray().getValueArray()); // Spigot
}
- nbttagcompound1.setByteArray("Data", extendedblockstorage.getMetadataArray().data);
- nbttagcompound1.setByteArray("BlockLight", extendedblockstorage.getBlocklightArray().data);
+ nbttagcompound1.setByteArray("Data", extendedblockstorage.getMetadataArray().getValueArray()); // Spigot
+ nbttagcompound1.setByteArray("BlockLight", extendedblockstorage.getBlocklightArray().getValueArray()); // Spigot
if (flag)
{
- nbttagcompound1.setByteArray("SkyLight", extendedblockstorage.getSkylightArray().data);
+ nbttagcompound1.setByteArray("SkyLight", extendedblockstorage.getSkylightArray().getValueArray()); // Spigot
}
else
{
- nbttagcompound1.setByteArray("SkyLight", new byte[extendedblockstorage.getBlocklightArray().data.length]);
+ nbttagcompound1.setByteArray("SkyLight", new byte[extendedblockstorage.getBlocklightArray().getValueArray().length]); // Spigot
}
nbttaglist.appendTag(nbttagcompound1);
@@ -455,6 +476,7 @@
public void loadEntities(World p_75823_1_, NBTTagCompound p_75823_2_, Chunk chunk)
{
+ p_75823_1_.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot
NBTTagList nbttaglist1 = p_75823_2_.getTagList("Entities", 10);
if (nbttaglist1 != null)
@@ -468,24 +490,31 @@
if (entity2 != null)
{
chunk.addEntity(entity2);
- Entity entity = entity2;
-
- for (NBTTagCompound nbttagcompound2 = nbttagcompound3; nbttagcompound2.hasKey("Riding", 10); nbttagcompound2 = nbttagcompound2.getCompoundTag("Riding"))
+ // Cauldron start - check to see if we killed entity due to invalid location
+ if (!entity2.isDead)
{
- Entity entity1 = EntityList.createEntityFromNBT(nbttagcompound2.getCompoundTag("Riding"), p_75823_1_);
+ Entity entity = entity2;
- if (entity1 != null)
+ for (NBTTagCompound nbttagcompound2 = nbttagcompound3; nbttagcompound2.hasKey("Riding", 10); nbttagcompound2 = nbttagcompound2.getCompoundTag("Riding"))
{
- chunk.addEntity(entity1);
- entity.mountEntity(entity1);
- }
+ Entity entity1 = EntityList.createEntityFromNBT(nbttagcompound2.getCompoundTag("Riding"), p_75823_1_);
- entity = entity1;
+ if (entity1 != null)
+ {
+ chunk.addEntity(entity1);
+ entity.mountEntity(entity1);
+ }
+
+ entity = entity1;
+ }
}
+ // Cauldron end
}
}
}
+ p_75823_1_.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot
+ p_75823_1_.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot
NBTTagList nbttaglist2 = p_75823_2_.getTagList("TileEntities", 10);
if (nbttaglist2 != null)
@@ -497,11 +526,35 @@
if (tileentity != null)
{
+ // Cauldron start - check if TE should tick and inject into Bukkit's InventoryType
+ if (!this.checkedTileEntities.contains(tileentity.getClass()))
+ {
+ // verify if TE should tick
+ if (MinecraftServer.getServer().tileEntityConfig.preventInvalidTileEntityUpdates.getValue())
+ {
+ SideTransformer.allowInvalidSide = true;
+ if (!CauldronUtils.isOverridingUpdateEntity(tileentity.getClass()) && CauldronUtils.canTileEntityUpdate(tileentity.getClass()))
+ {
+ if (MinecraftServer.getServer().tileEntityConfig.enableTECanUpdateWarning.getValue())
+ {
+ MinecraftServer.getServer().logInfo("Detected TE " + tileentity.getClass().getName() + " with canUpdate set to true and no updateEntity override!. Please report to mod author as this can hurt performance.");
+ }
+ MinecraftServer.getServer().bannedTileEntityUpdates.add(tileentity.getClass());
+ }
+ SideTransformer.allowInvalidSide = false;
+ }
+ // inject TE into InventoryType to support inventory events
+ EnumHelper.addInventoryType(tileentity);
+ this.checkedTileEntities.add(tileentity.getClass());
+ }
+ // Cauldron end
chunk.addTileEntity(tileentity);
}
}
}
+ p_75823_1_.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot
+ p_75823_1_.timings.syncChunkLoadTileTicksTimer.startTiming(); // Spigot
if (p_75823_2_.hasKey("TileTicks", 9))
{
NBTTagList nbttaglist3 = p_75823_2_.getTagList("TileTicks", 10);
@@ -515,6 +568,7 @@
}
}
}
+ p_75823_1_.timings.syncChunkLoadTileTicksTimer.stopTiming(); // Spigot
// return chunk;
}

View File

@ -0,0 +1,25 @@
--- ../src-base/minecraft/net/minecraft/world/chunk/storage/AnvilSaveHandler.java
+++ ../src-work/minecraft/net/minecraft/world/chunk/storage/AnvilSaveHandler.java
@@ -21,6 +21,11 @@
public IChunkLoader getChunkLoader(WorldProvider p_75763_1_)
{
File file1 = this.getWorldDirectory();
+ // Cauldron start
+ // To workaround the issue of Bukkit relying on every world having a seperate container
+ // we won't be generating a DIMXX folder for chunk loaders since this name is already generated
+ // for the world container with provider.getSaveFolder().
+ /*
File file2;
if (p_75763_1_.getSaveFolder() != null)
@@ -32,7 +37,9 @@
else
{
return new AnvilChunkLoader(file1);
- }
+ } */
+ return new AnvilChunkLoader(file1);
+ // Cauldron end
}
public void saveWorldInfoWithPlayer(WorldInfo p_75755_1_, NBTTagCompound p_75755_2_)

View File

@ -0,0 +1,17 @@
--- ../src-base/minecraft/net/minecraft/world/chunk/storage/ChunkLoader.java
+++ ../src-work/minecraft/net/minecraft/world/chunk/storage/ChunkLoader.java
@@ -113,9 +113,11 @@
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Y", (byte)(j & 255));
nbttagcompound1.setByteArray("Blocks", abyte1);
- nbttagcompound1.setByteArray("Data", nibblearray.data);
- nbttagcompound1.setByteArray("SkyLight", nibblearray1.data);
- nbttagcompound1.setByteArray("BlockLight", nibblearray2.data);
+ // Spigot start - data -> getValueArray() accessor
+ nbttagcompound1.setByteArray("Data", nibblearray.getValueArray());
+ nbttagcompound1.setByteArray("SkyLight", nibblearray1.getValueArray());
+ nbttagcompound1.setByteArray("BlockLight", nibblearray2.getValueArray());
+ // Spigot end
nbttaglist.appendTag(nbttagcompound1);
}
}

View File

@ -0,0 +1,217 @@
--- ../src-base/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java
+++ ../src-work/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java
@@ -31,6 +31,29 @@
}
}
+ // CraftBukkit start
+ public ExtendedBlockStorage(int y, boolean flag, byte[] blkIds, byte[] extBlkIds)
+ {
+ this.yBase = y;
+ this.blockLSBArray = blkIds;
+
+ if (extBlkIds != null)
+ {
+ this.blockMSBArray = new NibbleArray(extBlkIds, 4);
+ }
+
+ this.blockMetadataArray = new NibbleArray(this.blockLSBArray.length, 4);
+ this.blocklightArray = new NibbleArray(this.blockLSBArray.length, 4);
+
+ if (flag)
+ {
+ this.skylightArray = new NibbleArray(this.blockLSBArray.length, 4);
+ }
+
+ this.removeInvalidBlocks();
+ }
+ // CraftBukkit end
+
public Block getBlockByExtId(int p_150819_1_, int p_150819_2_, int p_150819_3_)
{
int l = this.blockLSBArray[p_150819_2_ << 8 | p_150819_3_ << 4 | p_150819_1_] & 255;
@@ -139,6 +162,106 @@
public void removeInvalidBlocks()
{
+ // CraftBukkit start - Optimize for speed
+ byte[] blkIds = this.blockLSBArray;
+ int cntNonEmpty = 0;
+ int cntTicking = 0;
+
+ if (this.blockMSBArray == null) // No extended block IDs? Don't waste time messing with them
+ {
+ for (int off = 0; off < blkIds.length; off++)
+ {
+ int l = blkIds[off] & 0xFF;
+
+ if (l > 0)
+ {
+ if (Block.getBlockById(l) == null)
+ {
+ blkIds[off] = 0;
+ }
+ else
+ {
+ ++cntNonEmpty;
+
+ if (Block.getBlockById(l).getTickRandomly())
+ {
+ ++cntTicking;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ this.blockMSBArray.forceToNonTrivialArray(); // Spigot
+ byte[] ext = this.blockMSBArray.getValueArray();
+
+ for (int off = 0, off2 = 0; off < blkIds.length;)
+ {
+ byte extid = ext[off2];
+ int l = (blkIds[off] & 0xFF) | ((extid & 0xF) << 8); // Even data
+
+ if (l > 0)
+ {
+ if (Block.getBlockById(l) == null)
+ {
+ blkIds[off] = 0;
+ ext[off2] &= 0xF0;
+ }
+ else
+ {
+ ++cntNonEmpty;
+
+ if (Block.getBlockById(l).getTickRandomly())
+ {
+ ++cntTicking;
+ }
+ }
+ }
+
+ off++;
+ l = (blkIds[off] & 0xFF) | ((extid & 0xF0) << 4); // Odd data
+
+ if (l > 0)
+ {
+ if (Block.getBlockById(l) == null)
+ {
+ blkIds[off] = 0;
+ ext[off2] &= 0x0F;
+ }
+ else
+ {
+ ++cntNonEmpty;
+
+ if (Block.getBlockById(l).getTickRandomly())
+ {
+ ++cntTicking;
+ }
+ }
+ }
+
+ off++;
+ off2++;
+ }
+
+ // Spigot start
+ this.blockMSBArray.detectAndProcessTrivialArray();
+
+ if (this.blockMSBArray.isTrivialArray() && (this.blockMSBArray.getTrivialArrayValue() == 0))
+ {
+ this.blockMSBArray = null;
+ }
+
+ // Spigot end
+ }
+
+ this.blockRefCount = cntNonEmpty;
+ this.tickRefCount = cntTicking;
+ }
+
+ public void old_recalcBlockCounts()
+ {
+ // CraftBukkit end
this.blockRefCount = 0;
this.tickRefCount = 0;
@@ -197,29 +320,72 @@
public void setBlockLSBArray(byte[] p_76664_1_)
{
- this.blockLSBArray = p_76664_1_;
+ this.blockLSBArray = this.validateByteArray(p_76664_1_); // CraftBukkit - Validate data
}
public void setBlockMSBArray(NibbleArray p_76673_1_)
{
- this.blockMSBArray = p_76673_1_;
+ // CraftBukkit start - Don't hang on to an empty nibble array
+ boolean empty = true;
+
+ // Spigot start
+ if ((!p_76673_1_.isTrivialArray()) || (p_76673_1_.getTrivialArrayValue() != 0))
+ {
+ empty = false;
+ }
+
+ // Spigot end
+
+ if (empty)
+ {
+ return;
+ }
+
+ // CraftBukkit end
+ this.blockMSBArray = this.validateNibbleArray(p_76673_1_); // CraftBukkit - Validate data
}
public void setBlockMetadataArray(NibbleArray p_76668_1_)
{
- this.blockMetadataArray = p_76668_1_;
+ this.blockMetadataArray = this.validateNibbleArray(p_76668_1_); // CraftBukkit - Validate data
}
public void setBlocklightArray(NibbleArray p_76659_1_)
{
- this.blocklightArray = p_76659_1_;
+ this.blocklightArray = this.validateNibbleArray(p_76659_1_); // CraftBukkit - Validate data
}
public void setSkylightArray(NibbleArray p_76666_1_)
{
- this.skylightArray = p_76666_1_;
+ this.skylightArray = this.validateNibbleArray(p_76666_1_); // CraftBukkit - Validate data
}
+ // CraftBukkit start - Validate array lengths
+ private NibbleArray validateNibbleArray(NibbleArray nibbleArray)
+ {
+ // Spigot start - fix for more awesome nibble arrays
+ if (nibbleArray != null && nibbleArray.getByteLength() < 2048)
+ {
+ nibbleArray.resizeArray(2048);
+ }
+
+ // Spigot end
+ return nibbleArray;
+ }
+
+ private byte[] validateByteArray(byte[] byteArray)
+ {
+ if (byteArray != null && byteArray.length < 4096)
+ {
+ byte[] newArray = new byte[4096];
+ System.arraycopy(byteArray, 0, newArray, 0, byteArray.length);
+ byteArray = newArray;
+ }
+
+ return byteArray;
+ }
+ // CraftBukkit end
+
@SideOnly(Side.CLIENT)
public NibbleArray createBlockMSBArray()
{

View File

@ -0,0 +1,11 @@
--- ../src-base/minecraft/net/minecraft/world/chunk/storage/RegionFileCache.java
+++ ../src-work/minecraft/net/minecraft/world/chunk/storage/RegionFileCache.java
@@ -10,7 +10,7 @@
public class RegionFileCache
{
- private static final Map regionsByFilename = new HashMap();
+ public static final Map regionsByFilename = new HashMap(); // CraftBukkit - private -> public
private static final String __OBFID = "CL_00000383";
public static synchronized RegionFile createOrLoadRegionFile(File p_76550_0_, int p_76550_1_, int p_76550_2_)