forked from xjboss/KCauldronX
Initial commit (Forge 1291).
This commit is contained in:
117
patches/net/minecraft/world/Explosion.java.patch
Normal file
117
patches/net/minecraft/world/Explosion.java.patch
Normal file
@ -0,0 +1,117 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/Explosion.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/Explosion.java
|
||||
@@ -20,6 +20,12 @@
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.Vec3;
|
||||
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
+import org.bukkit.Location;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public class Explosion
|
||||
{
|
||||
public boolean isFlaming;
|
||||
@@ -34,6 +40,7 @@
|
||||
public float explosionSize;
|
||||
public List affectedBlockPositions = new ArrayList();
|
||||
private Map field_77288_k = new HashMap();
|
||||
+ public boolean wasCanceled = false; // CraftBukkit
|
||||
private static final String __OBFID = "CL_00000134";
|
||||
|
||||
public Explosion(World p_i1948_1_, Entity p_i1948_2_, double p_i1948_3_, double p_i1948_5_, double p_i1948_7_, float p_i1948_9_)
|
||||
@@ -48,6 +55,12 @@
|
||||
|
||||
public void doExplosionA()
|
||||
{
|
||||
+ // CraftBukkit start
|
||||
+ if (this.explosionSize < 0.1F)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
float f = this.explosionSize;
|
||||
HashSet hashset = new HashSet();
|
||||
int i;
|
||||
@@ -135,7 +148,15 @@
|
||||
d7 /= d9;
|
||||
double d10 = (double)this.worldObj.getBlockDensity(vec3, entity.boundingBox);
|
||||
double d11 = (1.0D - d4) * d10;
|
||||
- entity.attackEntityFrom(DamageSource.setExplosionSource(this), (float)((int)((d11 * d11 + d11) / 2.0D * 8.0D * (double)this.explosionSize + 1.0D)));
|
||||
+ // CraftBukkit start
|
||||
+ CraftEventFactory.entityDamage = exploder;
|
||||
+ if (!entity.attackEntityFrom(DamageSource.setExplosionSource(this), (float) ((int) ((d11 * d11 + d11) / 2.0D * 8.0D
|
||||
+ * (double) this.explosionSize + 1.0D))))
|
||||
+ {
|
||||
+ CraftEventFactory.entityDamage = null;
|
||||
+ continue;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
double d8 = EnchantmentProtection.func_92092_a(entity, d11);
|
||||
entity.motionX += d5 * d8;
|
||||
entity.motionY += d6 * d8;
|
||||
@@ -174,6 +195,39 @@
|
||||
|
||||
if (this.isSmoking)
|
||||
{
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.World bworld = this.worldObj.getWorld();
|
||||
+ org.bukkit.entity.Entity explode = this.exploder == null ? null : this.exploder.getBukkitEntity();
|
||||
+ Location location = new Location(bworld, this.explosionX, this.explosionY, this.explosionZ);
|
||||
+ List<org.bukkit.block.Block> blockList = new ArrayList<org.bukkit.block.Block>();
|
||||
+
|
||||
+ for (int i1 = this.affectedBlockPositions.size() - 1; i1 >= 0; i1--)
|
||||
+ {
|
||||
+ ChunkPosition cpos = (ChunkPosition) this.affectedBlockPositions.get(i1);
|
||||
+ org.bukkit.block.Block bblock = bworld.getBlockAt(cpos.chunkPosX, cpos.chunkPosY, cpos.chunkPosZ);
|
||||
+
|
||||
+ if (bblock.getType() != org.bukkit.Material.AIR)
|
||||
+ {
|
||||
+ blockList.add(bblock);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, 0.3F);
|
||||
+ this.worldObj.getServer().getPluginManager().callEvent(event);
|
||||
+ this.affectedBlockPositions.clear();
|
||||
+
|
||||
+ for (org.bukkit.block.Block bblock : event.blockList())
|
||||
+ {
|
||||
+ ChunkPosition coords = new ChunkPosition(bblock.getX(), bblock.getY(), bblock.getZ());
|
||||
+ affectedBlockPositions.add(coords);
|
||||
+ }
|
||||
+
|
||||
+ if (event.isCancelled())
|
||||
+ {
|
||||
+ this.wasCanceled = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
iterator = this.affectedBlockPositions.iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
@@ -209,7 +263,8 @@
|
||||
{
|
||||
if (block.canDropFromExplosion(this))
|
||||
{
|
||||
- block.dropBlockAsItemWithChance(this.worldObj, i, j, k, this.worldObj.getBlockMetadata(i, j, k), 1.0F / this.explosionSize, 0);
|
||||
+ // CraftBukkit - add yield
|
||||
+ block.dropBlockAsItemWithChance(this.worldObj, i, j, k, this.worldObj.getBlockMetadata(i, j, k), event.getYield(), 0);
|
||||
}
|
||||
|
||||
block.onBlockExploded(this.worldObj, i, j, k, this);
|
||||
@@ -232,7 +287,12 @@
|
||||
|
||||
if (block.getMaterial() == Material.air && block1.func_149730_j() && this.explosionRNG.nextInt(3) == 0)
|
||||
{
|
||||
- this.worldObj.setBlock(i, j, k, Blocks.fire);
|
||||
+ // CraftBukkit start - Ignition by explosion
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(this.worldObj, i, j, k, this).isCancelled())
|
||||
+ {
|
||||
+ this.worldObj.setBlock(i, j, k, Blocks.fire);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
}
|
130
patches/net/minecraft/world/SpawnerAnimals.java.patch
Normal file
130
patches/net/minecraft/world/SpawnerAnimals.java.patch
Normal file
@ -0,0 +1,130 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/SpawnerAnimals.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/SpawnerAnimals.java
|
||||
@@ -22,9 +22,15 @@
|
||||
import cpw.mods.fml.common.eventhandler.Event.Result;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.craftbukkit.util.LongHash;
|
||||
+import org.bukkit.craftbukkit.util.LongObjectHashMap;
|
||||
+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public final class SpawnerAnimals
|
||||
{
|
||||
- private HashMap eligibleChunksForSpawning = new HashMap();
|
||||
+ private LongObjectHashMap<Boolean> eligibleChunksForSpawning = new LongObjectHashMap<Boolean>(); // CraftBukkit - HashMap -> LongObjectHashMap
|
||||
private static final String __OBFID = "CL_00000152";
|
||||
|
||||
protected static ChunkPosition func_151350_a(World p_151350_0_, int p_151350_1_, int p_151350_2_)
|
||||
@@ -54,22 +60,30 @@
|
||||
int j = MathHelper.floor_double(entityplayer.posX / 16.0D);
|
||||
k = MathHelper.floor_double(entityplayer.posZ / 16.0D);
|
||||
byte b0 = 8;
|
||||
+ // Spigot Start
|
||||
+ b0 = p_77192_1_.getSpigotConfig().mobSpawnRange; // Cauldron
|
||||
+ b0 = (b0 > p_77192_1_.getSpigotConfig().viewDistance) ? (byte) p_77192_1_.spigotConfig.viewDistance : b0; // Cauldron
|
||||
+ b0 = (b0 > 8) ? 8 : b0;
|
||||
+ // Spigot End
|
||||
|
||||
for (int l = -b0; l <= b0; ++l)
|
||||
{
|
||||
for (int i1 = -b0; i1 <= b0; ++i1)
|
||||
{
|
||||
boolean flag3 = l == -b0 || l == b0 || i1 == -b0 || i1 == b0;
|
||||
- ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(l + j, i1 + k);
|
||||
+ // CraftBukkit start
|
||||
+ long chunkCoords = LongHash.toLong(l + j, i1 + k);
|
||||
|
||||
if (!flag3)
|
||||
{
|
||||
- this.eligibleChunksForSpawning.put(chunkcoordintpair, Boolean.valueOf(false));
|
||||
+ this.eligibleChunksForSpawning.put(chunkCoords, false);
|
||||
}
|
||||
- else if (!this.eligibleChunksForSpawning.containsKey(chunkcoordintpair))
|
||||
+ else if (!this.eligibleChunksForSpawning.containsKey(chunkCoords))
|
||||
{
|
||||
- this.eligibleChunksForSpawning.put(chunkcoordintpair, Boolean.valueOf(true));
|
||||
+ this.eligibleChunksForSpawning.put(chunkCoords, true);
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,22 +96,46 @@
|
||||
for (int k3 = 0; k3 < k; ++k3)
|
||||
{
|
||||
EnumCreatureType enumcreaturetype = aenumcreaturetype[k3];
|
||||
+ // CraftBukkit start - Use per-world spawn limits
|
||||
+ int limit = enumcreaturetype.getMaxNumberOfCreature();
|
||||
|
||||
- if ((!enumcreaturetype.getPeacefulCreature() || p_77192_3_) && (enumcreaturetype.getPeacefulCreature() || p_77192_2_) && (!enumcreaturetype.getAnimal() || p_77192_4_) && p_77192_1_.countEntities(enumcreaturetype, true) <= enumcreaturetype.getMaxNumberOfCreature() * this.eligibleChunksForSpawning.size() / 256)
|
||||
+ switch (enumcreaturetype)
|
||||
{
|
||||
+ case monster:
|
||||
+ limit = p_77192_1_.getWorld().getMonsterSpawnLimit();
|
||||
+ break;
|
||||
+ case creature:
|
||||
+ limit = p_77192_1_.getWorld().getAnimalSpawnLimit();
|
||||
+ break;
|
||||
+ case waterCreature:
|
||||
+ limit = p_77192_1_.getWorld().getWaterAnimalSpawnLimit();
|
||||
+ break;
|
||||
+ case ambient:
|
||||
+ limit = p_77192_1_.getWorld().getAmbientSpawnLimit();
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (limit == 0)
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ if ((!enumcreaturetype.getPeacefulCreature() || p_77192_3_) && (enumcreaturetype.getPeacefulCreature() || p_77192_2_) && (!enumcreaturetype.getAnimal() || p_77192_4_) && p_77192_1_.countEntities(enumcreaturetype.getCreatureClass()) <= limit * eligibleChunksForSpawning.size() / 256) // CraftBukkit - use per-world limits
|
||||
+ {
|
||||
Iterator iterator = this.eligibleChunksForSpawning.keySet().iterator();
|
||||
- ArrayList<ChunkCoordIntPair> tmp = new ArrayList(eligibleChunksForSpawning.keySet());
|
||||
- Collections.shuffle(tmp);
|
||||
- iterator = tmp.iterator();
|
||||
label110:
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
- ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair)iterator.next();
|
||||
+ // CraftBukkit start
|
||||
+ long key = ((Long) iterator.next()).longValue();
|
||||
|
||||
- if (!((Boolean)this.eligibleChunksForSpawning.get(chunkcoordintpair1)).booleanValue())
|
||||
+ if (!(this.eligibleChunksForSpawning.get(key)))
|
||||
{
|
||||
- ChunkPosition chunkposition = func_151350_a(p_77192_1_, chunkcoordintpair1.chunkXPos, chunkcoordintpair1.chunkZPos);
|
||||
+ ChunkPosition chunkposition = func_151350_a(p_77192_1_, LongHash.msw(key), LongHash.lsw(key));
|
||||
+ // CraftBukkit end
|
||||
int j1 = chunkposition.chunkPosX;
|
||||
int k1 = chunkposition.chunkPosY;
|
||||
int l1 = chunkposition.chunkPosZ;
|
||||
@@ -170,7 +208,8 @@
|
||||
if (canSpawn == Result.ALLOW || (canSpawn == Result.DEFAULT && entityliving.getCanSpawnHere()))
|
||||
{
|
||||
++i2;
|
||||
- p_77192_1_.spawnEntityInWorld(entityliving);
|
||||
+ // CraftBukkit start - Added a reason for spawning this creature, moved entityliving.onSpawnWithEgg(ientitylivingdata) up
|
||||
+ p_77192_1_.addEntity(entityliving, SpawnReason.NATURAL);
|
||||
if (!ForgeEventFactory.doSpecialSpawn(entityliving, p_77192_1_, f, f1, f2))
|
||||
{
|
||||
ientitylivingdata = entityliving.onSpawnWithEgg(ientitylivingdata);
|
||||
@@ -266,8 +305,10 @@
|
||||
}
|
||||
|
||||
entityliving.setLocationAndAngles((double)f, (double)f1, (double)f2, p_77191_6_.nextFloat() * 360.0F, 0.0F);
|
||||
- p_77191_0_.spawnEntityInWorld(entityliving);
|
||||
+ // CraftBukkit start - Added a reason for spawning this creature, moved entityliving.a(ientitylivingdata) up
|
||||
ientitylivingdata = entityliving.onSpawnWithEgg(ientitylivingdata);
|
||||
+ p_77191_0_.addEntity(entityliving, SpawnReason.CHUNK_GEN);
|
||||
+ // CraftBukkit end
|
||||
flag = true;
|
||||
}
|
||||
|
838
patches/net/minecraft/world/Teleporter.java.patch
Normal file
838
patches/net/minecraft/world/Teleporter.java.patch
Normal file
@ -0,0 +1,838 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/Teleporter.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/Teleporter.java
|
||||
@@ -12,6 +12,12 @@
|
||||
import net.minecraft.util.LongHashMap;
|
||||
import net.minecraft.util.MathHelper;
|
||||
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.event.entity.EntityPortalExitEvent;
|
||||
+import org.bukkit.util.Vector;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public class Teleporter
|
||||
{
|
||||
private final WorldServer worldServerInstance;
|
||||
@@ -20,100 +26,172 @@
|
||||
private final List destinationCoordinateKeys = new ArrayList();
|
||||
private static final String __OBFID = "CL_00000153";
|
||||
|
||||
- public Teleporter(WorldServer p_i1963_1_)
|
||||
+ public Teleporter(WorldServer par1WorldServer)
|
||||
{
|
||||
- this.worldServerInstance = p_i1963_1_;
|
||||
- this.random = new Random(p_i1963_1_.getSeed());
|
||||
+ this.worldServerInstance = par1WorldServer;
|
||||
+ this.random = new Random(par1WorldServer.getSeed());
|
||||
}
|
||||
|
||||
- public void placeInPortal(Entity p_77185_1_, double p_77185_2_, double p_77185_4_, double p_77185_6_, float p_77185_8_)
|
||||
+ public void placeInPortal(Entity par1Entity, double par2, double par4, double par6, float par8)
|
||||
{
|
||||
if (this.worldServerInstance.provider.dimensionId != 1)
|
||||
{
|
||||
- if (!this.placeInExistingPortal(p_77185_1_, p_77185_2_, p_77185_4_, p_77185_6_, p_77185_8_))
|
||||
+ if (!this.placeInExistingPortal(par1Entity, par2, par4, par6, par8))
|
||||
{
|
||||
- this.makePortal(p_77185_1_);
|
||||
- this.placeInExistingPortal(p_77185_1_, p_77185_2_, p_77185_4_, p_77185_6_, p_77185_8_);
|
||||
+ this.makePortal(par1Entity);
|
||||
+ this.placeInExistingPortal(par1Entity, par2, par4, par6, par8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
- int i = MathHelper.floor_double(p_77185_1_.posX);
|
||||
- int j = MathHelper.floor_double(p_77185_1_.posY) - 1;
|
||||
- int k = MathHelper.floor_double(p_77185_1_.posZ);
|
||||
- byte b0 = 1;
|
||||
- byte b1 = 0;
|
||||
+ // CraftBukkit start - Modularize end portal creation
|
||||
+ ChunkCoordinates created = this.createEndPortal(par2, par4, par6);
|
||||
+ par1Entity.setLocationAndAngles((double) created.posX, (double) created.posY, (double) created.posZ, par1Entity.rotationYaw, 0.0F);
|
||||
+ par1Entity.motionX = par1Entity.motionY = par1Entity.motionZ = 0.0D;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- for (int l = -2; l <= 2; ++l)
|
||||
+ // Split out from original a(Entity, double, double, double, float) method in order to enable being called from createPortal
|
||||
+ private ChunkCoordinates createEndPortal(double x, double y, double z)
|
||||
+ {
|
||||
+ int i = MathHelper.floor_double(x);
|
||||
+ int j = MathHelper.floor_double(y) - 1;
|
||||
+ int k = MathHelper.floor_double(z);
|
||||
+ // CraftBukkit end
|
||||
+ byte b0 = 1;
|
||||
+ byte b1 = 0;
|
||||
+
|
||||
+ for (int l = -2; l <= 2; ++l)
|
||||
+ {
|
||||
+ for (int i1 = -2; i1 <= 2; ++i1)
|
||||
{
|
||||
- for (int i1 = -2; i1 <= 2; ++i1)
|
||||
+ for (int j1 = -1; j1 < 3; ++j1)
|
||||
{
|
||||
- for (int j1 = -1; j1 < 3; ++j1)
|
||||
+ int k1 = i + i1 * b0 + l * b1;
|
||||
+ int l1 = j + j1;
|
||||
+ int i2 = k + i1 * b1 - l * b0;
|
||||
+ boolean flag = j1 < 0;
|
||||
+ this.worldServerInstance.setBlock(k1, l1, i2, flag ? Blocks.obsidian : Blocks.air);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ return new ChunkCoordinates(i, j, k);
|
||||
+ }
|
||||
+
|
||||
+ // use logic based on creation to verify end portal
|
||||
+ private ChunkCoordinates findEndPortal(ChunkCoordinates portal)
|
||||
+ {
|
||||
+ int i = portal.posX;
|
||||
+ int j = portal.posY - 1;
|
||||
+ int k = portal.posZ;
|
||||
+ byte b0 = 1;
|
||||
+ byte b1 = 0;
|
||||
+
|
||||
+ for (int l = -2; l <= 2; ++l)
|
||||
+ {
|
||||
+ for (int i1 = -2; i1 <= 2; ++i1)
|
||||
+ {
|
||||
+ for (int j1 = -1; j1 < 3; ++j1)
|
||||
+ {
|
||||
+ int k1 = i + i1 * b0 + l * b1;
|
||||
+ int l1 = j + j1;
|
||||
+ int i2 = k + i1 * b1 - l * b0;
|
||||
+ boolean flag = j1 < 0;
|
||||
+
|
||||
+ if (this.worldServerInstance.getBlock(k1, l1, i2) != (flag ? Blocks.obsidian : Blocks.air))
|
||||
{
|
||||
- int k1 = i + i1 * b0 + l * b1;
|
||||
- int l1 = j + j1;
|
||||
- int i2 = k + i1 * b1 - l * b0;
|
||||
- boolean flag = j1 < 0;
|
||||
- this.worldServerInstance.setBlock(k1, l1, i2, flag ? Blocks.obsidian : Blocks.air);
|
||||
+ return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+ }
|
||||
|
||||
- p_77185_1_.setLocationAndAngles((double)i, (double)j, (double)k, p_77185_1_.rotationYaw, 0.0F);
|
||||
- p_77185_1_.motionX = p_77185_1_.motionY = p_77185_1_.motionZ = 0.0D;
|
||||
+ return new ChunkCoordinates(i, j, k);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ public boolean placeInExistingPortal(Entity par1Entity, double par2, double par4, double par6, float par8)
|
||||
+ {
|
||||
+ // CraftBukkit start - Modularize portal search process and entity teleportation
|
||||
+ ChunkCoordinates found = this.findPortal(par1Entity.posX, par1Entity.posY, par1Entity.posZ, 128);
|
||||
+
|
||||
+ if (found == null)
|
||||
+ {
|
||||
+ return false;
|
||||
}
|
||||
+
|
||||
+ Location exit = new Location(this.worldServerInstance.getWorld(), found.posX, found.posY, found.posZ, par8, par1Entity.rotationPitch);
|
||||
+ Vector velocity = par1Entity.getBukkitEntity().getVelocity();
|
||||
+ this.adjustExit(par1Entity, exit, velocity);
|
||||
+ par1Entity.setLocationAndAngles(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch());
|
||||
+
|
||||
+ if (par1Entity.motionX != velocity.getX() || par1Entity.motionY != velocity.getY() || par1Entity.motionZ != velocity.getZ())
|
||||
+ {
|
||||
+ par1Entity.getBukkitEntity().setVelocity(velocity);
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
}
|
||||
|
||||
- public boolean placeInExistingPortal(Entity p_77184_1_, double p_77184_2_, double p_77184_4_, double p_77184_6_, float p_77184_8_)
|
||||
+ public ChunkCoordinates findPortal(double x, double y, double z, int short1)
|
||||
{
|
||||
- short short1 = 128;
|
||||
+ if (this.worldServerInstance.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END)
|
||||
+ {
|
||||
+ return this.findEndPortal(this.worldServerInstance.provider.getEntrancePortalLocation());
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit end
|
||||
double d3 = -1.0D;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
- int l = MathHelper.floor_double(p_77184_1_.posX);
|
||||
- int i1 = MathHelper.floor_double(p_77184_1_.posZ);
|
||||
+ // CraftBukkit start
|
||||
+ int l = MathHelper.floor_double(x);
|
||||
+ int i1 = MathHelper.floor_double(z);
|
||||
+ // CraftBukkit end
|
||||
long j1 = ChunkCoordIntPair.chunkXZ2Int(l, i1);
|
||||
boolean flag = true;
|
||||
- double d7;
|
||||
- int l3;
|
||||
+ double d4;
|
||||
+ int k1;
|
||||
|
||||
if (this.destinationCoordinateCache.containsItem(j1))
|
||||
{
|
||||
- Teleporter.PortalPosition portalposition = (Teleporter.PortalPosition)this.destinationCoordinateCache.getValueByKey(j1);
|
||||
+ PortalPosition chunkcoordinatesportal = (PortalPosition) this.destinationCoordinateCache.getValueByKey(j1);
|
||||
d3 = 0.0D;
|
||||
- i = portalposition.posX;
|
||||
- j = portalposition.posY;
|
||||
- k = portalposition.posZ;
|
||||
- portalposition.lastUpdateTime = this.worldServerInstance.getTotalWorldTime();
|
||||
+ i = chunkcoordinatesportal.posX;
|
||||
+ j = chunkcoordinatesportal.posY;
|
||||
+ k = chunkcoordinatesportal.posZ;
|
||||
+ chunkcoordinatesportal.lastUpdateTime = this.worldServerInstance.getTotalWorldTime();
|
||||
flag = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
- for (l3 = l - short1; l3 <= l + short1; ++l3)
|
||||
+ for (k1 = l - short1; k1 <= l + short1; ++k1)
|
||||
{
|
||||
- double d4 = (double)l3 + 0.5D - p_77184_1_.posX;
|
||||
+ double d5 = (double) k1 + 0.5D - x; // CraftBukkit
|
||||
|
||||
for (int l1 = i1 - short1; l1 <= i1 + short1; ++l1)
|
||||
{
|
||||
- double d5 = (double)l1 + 0.5D - p_77184_1_.posZ;
|
||||
+ double d6 = (double) l1 + 0.5D - z; // CraftBukkit
|
||||
|
||||
for (int i2 = this.worldServerInstance.getActualHeight() - 1; i2 >= 0; --i2)
|
||||
{
|
||||
- if (this.worldServerInstance.getBlock(l3, i2, l1) == Blocks.portal)
|
||||
+ if (this.worldServerInstance.getBlock(k1, i2, l1) == Blocks.portal)
|
||||
{
|
||||
- while (this.worldServerInstance.getBlock(l3, i2 - 1, l1) == Blocks.portal)
|
||||
+ while (this.worldServerInstance.getBlock(k1, i2 - 1, l1) == Blocks.portal)
|
||||
{
|
||||
--i2;
|
||||
}
|
||||
|
||||
- d7 = (double)i2 + 0.5D - p_77184_1_.posY;
|
||||
- double d8 = d4 * d4 + d7 * d7 + d5 * d5;
|
||||
+ d4 = (double) i2 + 0.5D - y; // CraftBukkit
|
||||
+ double d7 = d5 * d5 + d4 * d4 + d6 * d6;
|
||||
|
||||
- if (d3 < 0.0D || d8 < d3)
|
||||
+ if (d3 < 0.0D || d7 < d3)
|
||||
{
|
||||
- d3 = d8;
|
||||
- i = l3;
|
||||
+ d3 = d7;
|
||||
+ i = k1;
|
||||
j = i2;
|
||||
k = l1;
|
||||
}
|
||||
@@ -127,61 +205,93 @@
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
- this.destinationCoordinateCache.add(j1, new Teleporter.PortalPosition(i, j, k, this.worldServerInstance.getTotalWorldTime()));
|
||||
+ this.destinationCoordinateCache.add(j1, new PortalPosition(i, j, k, this.worldServerInstance.getTotalWorldTime()));
|
||||
this.destinationCoordinateKeys.add(Long.valueOf(j1));
|
||||
}
|
||||
|
||||
- double d11 = (double)i + 0.5D;
|
||||
- double d6 = (double)j + 0.5D;
|
||||
- d7 = (double)k + 0.5D;
|
||||
- int i4 = -1;
|
||||
+ // CraftBukkit start - Moved entity teleportation logic into exit
|
||||
+ return new ChunkCoordinates(i, j, k);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return null;
|
||||
+ }
|
||||
+ }
|
||||
+ // Entity repositioning logic split out from original b method and combined with repositioning logic for The End from original a method
|
||||
+ public void adjustExit(Entity entity, Location position, Vector velocity)
|
||||
+ {
|
||||
+ Location from = position.clone();
|
||||
+ Vector before = velocity.clone();
|
||||
+ int i = position.getBlockX();
|
||||
+ int j = position.getBlockY();
|
||||
+ int k = position.getBlockZ();
|
||||
+ float f = position.getYaw();
|
||||
|
||||
+ if (this.worldServerInstance.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END)
|
||||
+ {
|
||||
+ // entity.setPositionRotation((double) i, (double) j, (double) k, entity.yaw, 0.0F);
|
||||
+ // entity.motX = entity.motY = entity.motZ = 0.0D;
|
||||
+ position.setPitch(0.0F);
|
||||
+ velocity.setX(0);
|
||||
+ velocity.setY(0);
|
||||
+ velocity.setZ(0);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ double d4;
|
||||
+ int k1;
|
||||
+ // CraftBukkit end
|
||||
+ double d8 = (double) i + 0.5D;
|
||||
+ double d9 = (double) j + 0.5D;
|
||||
+ d4 = (double) k + 0.5D;
|
||||
+ int j2 = -1;
|
||||
+
|
||||
if (this.worldServerInstance.getBlock(i - 1, j, k) == Blocks.portal)
|
||||
{
|
||||
- i4 = 2;
|
||||
+ j2 = 2;
|
||||
}
|
||||
|
||||
if (this.worldServerInstance.getBlock(i + 1, j, k) == Blocks.portal)
|
||||
{
|
||||
- i4 = 0;
|
||||
+ j2 = 0;
|
||||
}
|
||||
|
||||
if (this.worldServerInstance.getBlock(i, j, k - 1) == Blocks.portal)
|
||||
{
|
||||
- i4 = 3;
|
||||
+ j2 = 3;
|
||||
}
|
||||
|
||||
if (this.worldServerInstance.getBlock(i, j, k + 1) == Blocks.portal)
|
||||
{
|
||||
- i4 = 1;
|
||||
+ j2 = 1;
|
||||
}
|
||||
|
||||
- int j2 = p_77184_1_.getTeleportDirection();
|
||||
+ int k2 = entity.getTeleportDirection();
|
||||
|
||||
- if (i4 > -1)
|
||||
+ if (j2 > -1)
|
||||
{
|
||||
- int k2 = Direction.rotateLeft[i4];
|
||||
- int l2 = Direction.offsetX[i4];
|
||||
- int i3 = Direction.offsetZ[i4];
|
||||
- int j3 = Direction.offsetX[k2];
|
||||
- int k3 = Direction.offsetZ[k2];
|
||||
- boolean flag1 = !this.worldServerInstance.isAirBlock(i + l2 + j3, j, k + i3 + k3) || !this.worldServerInstance.isAirBlock(i + l2 + j3, j + 1, k + i3 + k3);
|
||||
- boolean flag2 = !this.worldServerInstance.isAirBlock(i + l2, j, k + i3) || !this.worldServerInstance.isAirBlock(i + l2, j + 1, k + i3);
|
||||
+ int l2 = Direction.rotateLeft[j2];
|
||||
+ int i3 = Direction.offsetX[j2];
|
||||
+ int j3 = Direction.offsetZ[j2];
|
||||
+ int k3 = Direction.offsetX[l2];
|
||||
+ int l3 = Direction.offsetZ[l2];
|
||||
+ boolean flag1 = !this.worldServerInstance.isAirBlock(i + i3 + k3, j, k + j3 + l3) || !this.worldServerInstance.isAirBlock(i + i3 + k3, j + 1, k + j3 + l3);
|
||||
+ boolean flag2 = !this.worldServerInstance.isAirBlock(i + i3, j, k + j3) || !this.worldServerInstance.isAirBlock(i + i3, j + 1, k + j3);
|
||||
|
||||
if (flag1 && flag2)
|
||||
{
|
||||
- i4 = Direction.rotateOpposite[i4];
|
||||
- k2 = Direction.rotateOpposite[k2];
|
||||
- l2 = Direction.offsetX[i4];
|
||||
- i3 = Direction.offsetZ[i4];
|
||||
- j3 = Direction.offsetX[k2];
|
||||
- k3 = Direction.offsetZ[k2];
|
||||
- l3 = i - j3;
|
||||
- d11 -= (double)j3;
|
||||
- int k1 = k - k3;
|
||||
- d7 -= (double)k3;
|
||||
- flag1 = !this.worldServerInstance.isAirBlock(l3 + l2 + j3, j, k1 + i3 + k3) || !this.worldServerInstance.isAirBlock(l3 + l2 + j3, j + 1, k1 + i3 + k3);
|
||||
- flag2 = !this.worldServerInstance.isAirBlock(l3 + l2, j, k1 + i3) || !this.worldServerInstance.isAirBlock(l3 + l2, j + 1, k1 + i3);
|
||||
+ j2 = Direction.rotateOpposite[j2];
|
||||
+ l2 = Direction.rotateOpposite[l2];
|
||||
+ i3 = Direction.offsetX[j2];
|
||||
+ j3 = Direction.offsetZ[j2];
|
||||
+ k3 = Direction.offsetX[l2];
|
||||
+ l3 = Direction.offsetZ[l2];
|
||||
+ k1 = i - k3;
|
||||
+ d8 -= (double) k3;
|
||||
+ int i4 = k - l3;
|
||||
+ d4 -= (double) l3;
|
||||
+ flag1 = !this.worldServerInstance.isAirBlock(k1 + i3 + k3, j, i4 + j3 + l3) || !this.worldServerInstance.isAirBlock(k1 + i3 + k3, j + 1, i4 + j3 + l3);
|
||||
+ flag2 = !this.worldServerInstance.isAirBlock(k1 + i3, j, i4 + j3) || !this.worldServerInstance.isAirBlock(k1 + i3, j + 1, i4 + j3);
|
||||
}
|
||||
|
||||
float f1 = 0.5F;
|
||||
@@ -200,24 +310,24 @@
|
||||
f2 = 0.0F;
|
||||
}
|
||||
|
||||
- d11 += (double)((float)j3 * f1 + f2 * (float)l2);
|
||||
- d7 += (double)((float)k3 * f1 + f2 * (float)i3);
|
||||
+ d8 += (double)((float) k3 * f1 + f2 * (float) i3);
|
||||
+ d4 += (double)((float) l3 * f1 + f2 * (float) j3);
|
||||
float f3 = 0.0F;
|
||||
float f4 = 0.0F;
|
||||
float f5 = 0.0F;
|
||||
float f6 = 0.0F;
|
||||
|
||||
- if (i4 == j2)
|
||||
+ if (j2 == k2)
|
||||
{
|
||||
f3 = 1.0F;
|
||||
f4 = 1.0F;
|
||||
}
|
||||
- else if (i4 == Direction.rotateOpposite[j2])
|
||||
+ else if (j2 == Direction.rotateOpposite[k2])
|
||||
{
|
||||
f3 = -1.0F;
|
||||
f4 = -1.0F;
|
||||
}
|
||||
- else if (i4 == Direction.rotateRight[j2])
|
||||
+ else if (j2 == Direction.rotateRight[k2])
|
||||
{
|
||||
f5 = 1.0F;
|
||||
f6 = -1.0F;
|
||||
@@ -228,33 +338,77 @@
|
||||
f6 = 1.0F;
|
||||
}
|
||||
|
||||
- double d9 = p_77184_1_.motionX;
|
||||
- double d10 = p_77184_1_.motionZ;
|
||||
- p_77184_1_.motionX = d9 * (double)f3 + d10 * (double)f6;
|
||||
- p_77184_1_.motionZ = d9 * (double)f5 + d10 * (double)f4;
|
||||
- p_77184_1_.rotationYaw = p_77184_8_ - (float)(j2 * 90) + (float)(i4 * 90);
|
||||
+ // CraftBukkit start
|
||||
+ double d10 = velocity.getX();
|
||||
+ double d11 = velocity.getZ();
|
||||
+ // CraftBukkit end
|
||||
+ // CraftBukkit start - Adjust position and velocity instances instead of entity
|
||||
+ velocity.setX(d10 * (double) f3 + d11 * (double) f6);
|
||||
+ velocity.setZ(d10 * (double) f5 + d11 * (double) f4);
|
||||
+ f = f - (float)(k2 * 90) + (float)(j2 * 90);
|
||||
}
|
||||
else
|
||||
{
|
||||
- p_77184_1_.motionX = p_77184_1_.motionY = p_77184_1_.motionZ = 0.0D;
|
||||
+ // entity.motX = entity.motY = entity.motZ = 0.0D;
|
||||
+ velocity.setX(0);
|
||||
+ velocity.setY(0);
|
||||
+ velocity.setZ(0);
|
||||
}
|
||||
|
||||
- p_77184_1_.setLocationAndAngles(d11, d6, d7, p_77184_1_.rotationYaw, p_77184_1_.rotationPitch);
|
||||
- return true;
|
||||
+ // entity.setPositionRotation(d8, d9, d4, entity.yaw, entity.pitch);
|
||||
+ position.setX(d8);
|
||||
+ position.setY(d9);
|
||||
+ position.setZ(d4);
|
||||
+ position.setYaw(f);
|
||||
}
|
||||
+
|
||||
+ EntityPortalExitEvent event = new EntityPortalExitEvent(entity.getBukkitEntity(), from, position, before, velocity);
|
||||
+ this.worldServerInstance.getServer().getPluginManager().callEvent(event);
|
||||
+ Location to = event.getTo();
|
||||
+
|
||||
+ if (event.isCancelled() || to == null || !entity.isEntityAlive())
|
||||
+ {
|
||||
+ position.setX(from.getX());
|
||||
+ position.setY(from.getY());
|
||||
+ position.setZ(from.getZ());
|
||||
+ position.setYaw(from.getYaw());
|
||||
+ position.setPitch(from.getPitch());
|
||||
+ velocity.copy(before);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
- return false;
|
||||
+ position.setX(to.getX());
|
||||
+ position.setY(to.getY());
|
||||
+ position.setZ(to.getZ());
|
||||
+ position.setYaw(to.getYaw());
|
||||
+ position.setPitch(to.getPitch());
|
||||
+ velocity.copy(event.getAfter()); // event.getAfter() will never be null, as setAfter() will cause an NPE if null is passed in
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
- public boolean makePortal(Entity p_85188_1_)
|
||||
+ public boolean makePortal(Entity par1Entity)
|
||||
{
|
||||
- byte b0 = 16;
|
||||
+ // CraftBukkit start - Allow for portal creation to be based on coordinates instead of entity
|
||||
+ return this.createPortal(par1Entity.posX, par1Entity.posY, par1Entity.posZ, 16);
|
||||
+ }
|
||||
+
|
||||
+ public boolean createPortal(double x, double y, double z, int b0)
|
||||
+ {
|
||||
+ if (this.worldServerInstance.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END)
|
||||
+ {
|
||||
+ this.createEndPortal(x, y, z);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit end
|
||||
double d0 = -1.0D;
|
||||
- int i = MathHelper.floor_double(p_85188_1_.posX);
|
||||
- int j = MathHelper.floor_double(p_85188_1_.posY);
|
||||
- int k = MathHelper.floor_double(p_85188_1_.posZ);
|
||||
+ // CraftBukkit start
|
||||
+ int i = MathHelper.floor_double(x);
|
||||
+ int j = MathHelper.floor_double(y);
|
||||
+ int k = MathHelper.floor_double(z);
|
||||
+ // CraftBukkit end
|
||||
int l = i;
|
||||
int i1 = j;
|
||||
int j1 = k;
|
||||
@@ -262,8 +416,10 @@
|
||||
int l1 = this.random.nextInt(4);
|
||||
int i2;
|
||||
double d1;
|
||||
- int k2;
|
||||
double d2;
|
||||
+ int j2;
|
||||
+ int k2;
|
||||
+ int l2;
|
||||
int i3;
|
||||
int j3;
|
||||
int k3;
|
||||
@@ -271,125 +427,123 @@
|
||||
int i4;
|
||||
int j4;
|
||||
int k4;
|
||||
- int l4;
|
||||
- int i5;
|
||||
double d3;
|
||||
double d4;
|
||||
-
|
||||
+
|
||||
for (i2 = i - b0; i2 <= i + b0; ++i2)
|
||||
{
|
||||
- d1 = (double)i2 + 0.5D - p_85188_1_.posX;
|
||||
-
|
||||
- for (k2 = k - b0; k2 <= k + b0; ++k2)
|
||||
+ d1 = (double) i2 + 0.5D - x; // CraftBukkit
|
||||
+
|
||||
+ for (j2 = k - b0; j2 <= k + b0; ++j2)
|
||||
{
|
||||
- d2 = (double)k2 + 0.5D - p_85188_1_.posZ;
|
||||
+ d2 = (double) j2 + 0.5D - z; // CraftBukkit
|
||||
label274:
|
||||
-
|
||||
- for (i3 = this.worldServerInstance.getActualHeight() - 1; i3 >= 0; --i3)
|
||||
+
|
||||
+ for (k2 = this.worldServerInstance.getActualHeight() - 1; k2 >= 0; --k2)
|
||||
{
|
||||
- if (this.worldServerInstance.isAirBlock(i2, i3, k2))
|
||||
+ if (this.worldServerInstance.isAirBlock(i2, k2, j2))
|
||||
{
|
||||
- while (i3 > 0 && this.worldServerInstance.isAirBlock(i2, i3 - 1, k2))
|
||||
+ while (k2 > 0 && this.worldServerInstance.isAirBlock(i2, k2 - 1, j2))
|
||||
{
|
||||
- --i3;
|
||||
+ --k2;
|
||||
}
|
||||
-
|
||||
- for (j3 = l1; j3 < l1 + 4; ++j3)
|
||||
+
|
||||
+ for (i3 = l1; i3 < l1 + 4; ++i3)
|
||||
{
|
||||
- k3 = j3 % 2;
|
||||
- l3 = 1 - k3;
|
||||
-
|
||||
- if (j3 % 4 >= 2)
|
||||
+ l2 = i3 % 2;
|
||||
+ k3 = 1 - l2;
|
||||
+
|
||||
+ if (i3 % 4 >= 2)
|
||||
{
|
||||
+ l2 = -l2;
|
||||
k3 = -k3;
|
||||
- l3 = -l3;
|
||||
}
|
||||
-
|
||||
- for (i4 = 0; i4 < 3; ++i4)
|
||||
+
|
||||
+ for (j3 = 0; j3 < 3; ++j3)
|
||||
{
|
||||
- for (j4 = 0; j4 < 4; ++j4)
|
||||
+ for (i4 = 0; i4 < 4; ++i4)
|
||||
{
|
||||
- for (k4 = -1; k4 < 4; ++k4)
|
||||
+ for (l3 = -1; l3 < 4; ++l3)
|
||||
{
|
||||
- l4 = i2 + (j4 - 1) * k3 + i4 * l3;
|
||||
- i5 = i3 + k4;
|
||||
- int j5 = k2 + (j4 - 1) * l3 - i4 * k3;
|
||||
-
|
||||
- if (k4 < 0 && !this.worldServerInstance.getBlock(l4, i5, j5).getMaterial().isSolid() || k4 >= 0 && !this.worldServerInstance.isAirBlock(l4, i5, j5))
|
||||
+ k4 = i2 + (i4 - 1) * l2 + j3 * k3;
|
||||
+ j4 = k2 + l3;
|
||||
+ int l4 = j2 + (i4 - 1) * k3 - j3 * l2;
|
||||
+
|
||||
+ if (l3 < 0 && !this.worldServerInstance.getBlock(k4, j4, l4).getMaterial().isSolid() || l3 >= 0 && !this.worldServerInstance.isAirBlock(k4, j4, l4))
|
||||
{
|
||||
continue label274;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- d3 = (double)i3 + 0.5D - p_85188_1_.posY;
|
||||
+
|
||||
+ d3 = (double) k2 + 0.5D - y; // CraftBukkit
|
||||
d4 = d1 * d1 + d3 * d3 + d2 * d2;
|
||||
-
|
||||
+
|
||||
if (d0 < 0.0D || d4 < d0)
|
||||
{
|
||||
d0 = d4;
|
||||
l = i2;
|
||||
- i1 = i3;
|
||||
- j1 = k2;
|
||||
- k1 = j3 % 4;
|
||||
+ i1 = k2;
|
||||
+ j1 = j2;
|
||||
+ k1 = i3 % 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
if (d0 < 0.0D)
|
||||
{
|
||||
for (i2 = i - b0; i2 <= i + b0; ++i2)
|
||||
{
|
||||
- d1 = (double)i2 + 0.5D - p_85188_1_.posX;
|
||||
-
|
||||
- for (k2 = k - b0; k2 <= k + b0; ++k2)
|
||||
+ d1 = (double) i2 + 0.5D - x; // CraftBukkit
|
||||
+
|
||||
+ for (j2 = k - b0; j2 <= k + b0; ++j2)
|
||||
{
|
||||
- d2 = (double)k2 + 0.5D - p_85188_1_.posZ;
|
||||
+ d2 = (double) j2 + 0.5D - z; // CraftBukkit
|
||||
label222:
|
||||
-
|
||||
- for (i3 = this.worldServerInstance.getActualHeight() - 1; i3 >= 0; --i3)
|
||||
+
|
||||
+ for (k2 = this.worldServerInstance.getActualHeight() - 1; k2 >= 0; --k2)
|
||||
{
|
||||
- if (this.worldServerInstance.isAirBlock(i2, i3, k2))
|
||||
+ if (this.worldServerInstance.isAirBlock(i2, k2, j2))
|
||||
{
|
||||
- while (i3 > 0 && this.worldServerInstance.isAirBlock(i2, i3 - 1, k2))
|
||||
+ while (k2 > 0 && this.worldServerInstance.isAirBlock(i2, k2 - 1, j2))
|
||||
{
|
||||
- --i3;
|
||||
+ --k2;
|
||||
}
|
||||
-
|
||||
- for (j3 = l1; j3 < l1 + 2; ++j3)
|
||||
+
|
||||
+ for (i3 = l1; i3 < l1 + 2; ++i3)
|
||||
{
|
||||
- k3 = j3 % 2;
|
||||
- l3 = 1 - k3;
|
||||
-
|
||||
- for (i4 = 0; i4 < 4; ++i4)
|
||||
+ l2 = i3 % 2;
|
||||
+ k3 = 1 - l2;
|
||||
+
|
||||
+ for (j3 = 0; j3 < 4; ++j3)
|
||||
{
|
||||
- for (j4 = -1; j4 < 4; ++j4)
|
||||
+ for (i4 = -1; i4 < 4; ++i4)
|
||||
{
|
||||
- k4 = i2 + (i4 - 1) * k3;
|
||||
- l4 = i3 + j4;
|
||||
- i5 = k2 + (i4 - 1) * l3;
|
||||
-
|
||||
- if (j4 < 0 && !this.worldServerInstance.getBlock(k4, l4, i5).getMaterial().isSolid() || j4 >= 0 && !this.worldServerInstance.isAirBlock(k4, l4, i5))
|
||||
+ l3 = i2 + (j3 - 1) * l2;
|
||||
+ k4 = k2 + i4;
|
||||
+ j4 = j2 + (j3 - 1) * k3;
|
||||
+
|
||||
+ if (i4 < 0 && !this.worldServerInstance.getBlock(l3, k4, j4).getMaterial().isSolid() || i4 >= 0 && !this.worldServerInstance.isAirBlock(l3, k4, j4))
|
||||
{
|
||||
continue label222;
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- d3 = (double)i3 + 0.5D - p_85188_1_.posY;
|
||||
+
|
||||
+ d3 = (double) k2 + 0.5D - y; // CraftBukkit
|
||||
d4 = d1 * d1 + d3 * d3 + d2 * d2;
|
||||
-
|
||||
+
|
||||
if (d0 < 0.0D || d4 < d0)
|
||||
{
|
||||
d0 = d4;
|
||||
l = i2;
|
||||
- i1 = i3;
|
||||
- j1 = k2;
|
||||
- k1 = j3 % 2;
|
||||
+ i1 = k2;
|
||||
+ j1 = j2;
|
||||
+ k1 = i3 % 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,93 +551,93 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- int k5 = l;
|
||||
- int j2 = i1;
|
||||
- k2 = j1;
|
||||
- int l5 = k1 % 2;
|
||||
- int l2 = 1 - l5;
|
||||
-
|
||||
+
|
||||
+ int i5 = l;
|
||||
+ int j5 = i1;
|
||||
+ j2 = j1;
|
||||
+ int k5 = k1 % 2;
|
||||
+ int l5 = 1 - k5;
|
||||
+
|
||||
if (k1 % 4 >= 2)
|
||||
{
|
||||
+ k5 = -k5;
|
||||
l5 = -l5;
|
||||
- l2 = -l2;
|
||||
}
|
||||
-
|
||||
+
|
||||
boolean flag;
|
||||
-
|
||||
+
|
||||
if (d0 < 0.0D)
|
||||
{
|
||||
if (i1 < 70)
|
||||
{
|
||||
i1 = 70;
|
||||
}
|
||||
-
|
||||
+
|
||||
if (i1 > this.worldServerInstance.getActualHeight() - 10)
|
||||
{
|
||||
i1 = this.worldServerInstance.getActualHeight() - 10;
|
||||
}
|
||||
-
|
||||
- j2 = i1;
|
||||
-
|
||||
- for (i3 = -1; i3 <= 1; ++i3)
|
||||
+
|
||||
+ j5 = i1;
|
||||
+
|
||||
+ for (k2 = -1; k2 <= 1; ++k2)
|
||||
{
|
||||
- for (j3 = 1; j3 < 3; ++j3)
|
||||
+ for (i3 = 1; i3 < 3; ++i3)
|
||||
{
|
||||
- for (k3 = -1; k3 < 3; ++k3)
|
||||
+ for (l2 = -1; l2 < 3; ++l2)
|
||||
{
|
||||
- l3 = k5 + (j3 - 1) * l5 + i3 * l2;
|
||||
- i4 = j2 + k3;
|
||||
- j4 = k2 + (j3 - 1) * l2 - i3 * l5;
|
||||
- flag = k3 < 0;
|
||||
- this.worldServerInstance.setBlock(l3, i4, j4, flag ? Blocks.obsidian : Blocks.air);
|
||||
+ k3 = i5 + (i3 - 1) * k5 + k2 * l5;
|
||||
+ j3 = j5 + l2;
|
||||
+ i4 = j2 + (i3 - 1) * l5 - k2 * k5;
|
||||
+ flag = l2 < 0;
|
||||
+ this.worldServerInstance.setBlock(k3, j3, i4, flag ? Blocks.obsidian : Blocks.air);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- for (i3 = 0; i3 < 4; ++i3)
|
||||
+
|
||||
+ for (k2 = 0; k2 < 4; ++k2)
|
||||
{
|
||||
- for (j3 = 0; j3 < 4; ++j3)
|
||||
+ for (i3 = 0; i3 < 4; ++i3)
|
||||
{
|
||||
- for (k3 = -1; k3 < 4; ++k3)
|
||||
+ for (l2 = -1; l2 < 4; ++l2)
|
||||
{
|
||||
- l3 = k5 + (j3 - 1) * l5;
|
||||
- i4 = j2 + k3;
|
||||
- j4 = k2 + (j3 - 1) * l2;
|
||||
- flag = j3 == 0 || j3 == 3 || k3 == -1 || k3 == 3;
|
||||
- this.worldServerInstance.setBlock(l3, i4, j4, (Block)(flag ? Blocks.obsidian : Blocks.portal), 0, 2);
|
||||
+ k3 = i5 + (i3 - 1) * k5;
|
||||
+ j3 = j5 + l2;
|
||||
+ i4 = j2 + (i3 - 1) * l5;
|
||||
+ flag = i3 == 0 || i3 == 3 || l2 == -1 || l2 == 3;
|
||||
+ this.worldServerInstance.setBlock(k3, j3, i4, flag ? Blocks.obsidian : Blocks.portal, 0, 2);
|
||||
}
|
||||
}
|
||||
-
|
||||
- for (j3 = 0; j3 < 4; ++j3)
|
||||
+
|
||||
+ for (i3 = 0; i3 < 4; ++i3)
|
||||
{
|
||||
- for (k3 = -1; k3 < 4; ++k3)
|
||||
+ for (l2 = -1; l2 < 4; ++l2)
|
||||
{
|
||||
- l3 = k5 + (j3 - 1) * l5;
|
||||
- i4 = j2 + k3;
|
||||
- j4 = k2 + (j3 - 1) * l2;
|
||||
- this.worldServerInstance.notifyBlocksOfNeighborChange(l3, i4, j4, this.worldServerInstance.getBlock(l3, i4, j4));
|
||||
+ k3 = i5 + (i3 - 1) * k5;
|
||||
+ j3 = j5 + l2;
|
||||
+ i4 = j2 + (i3 - 1) * l5;
|
||||
+ this.worldServerInstance.notifyBlocksOfNeighborChange(k3, j3, i4, this.worldServerInstance.getBlock(k3, j3, i4));
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
- public void removeStalePortalLocations(long p_85189_1_)
|
||||
+ public void removeStalePortalLocations(long par1)
|
||||
{
|
||||
- if (p_85189_1_ % 100L == 0L)
|
||||
+ if (par1 % 100L == 0L)
|
||||
{
|
||||
Iterator iterator = this.destinationCoordinateKeys.iterator();
|
||||
- long j = p_85189_1_ - 600L;
|
||||
-
|
||||
+ long j = par1 - 600L;
|
||||
+
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
- Long olong = (Long)iterator.next();
|
||||
- Teleporter.PortalPosition portalposition = (Teleporter.PortalPosition)this.destinationCoordinateCache.getValueByKey(olong.longValue());
|
||||
-
|
||||
- if (portalposition == null || portalposition.lastUpdateTime < j)
|
||||
+ Long olong = (Long) iterator.next();
|
||||
+ PortalPosition chunkcoordinatesportal = (PortalPosition) this.destinationCoordinateCache.getValueByKey(olong.longValue());
|
||||
+
|
||||
+ if (chunkcoordinatesportal == null || chunkcoordinatesportal.lastUpdateTime < j)
|
||||
{
|
||||
iterator.remove();
|
||||
this.destinationCoordinateCache.remove(olong.longValue());
|
||||
@@ -491,16 +645,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
public class PortalPosition extends ChunkCoordinates
|
||||
{
|
||||
public long lastUpdateTime;
|
||||
private static final String __OBFID = "CL_00000154";
|
||||
-
|
||||
- public PortalPosition(int p_i1962_2_, int p_i1962_3_, int p_i1962_4_, long p_i1962_5_)
|
||||
+
|
||||
+ public PortalPosition(int par2, int par3, int par4, long par5)
|
||||
{
|
||||
- super(p_i1962_2_, p_i1962_3_, p_i1962_4_);
|
||||
- this.lastUpdateTime = p_i1962_5_;
|
||||
+ super(par2, par3, par4);
|
||||
+ this.lastUpdateTime = par5;
|
||||
}
|
||||
}
|
||||
}
|
1282
patches/net/minecraft/world/World.java.patch
Normal file
1282
patches/net/minecraft/world/World.java.patch
Normal file
File diff suppressed because it is too large
Load Diff
11
patches/net/minecraft/world/WorldManager.java.patch
Normal file
11
patches/net/minecraft/world/WorldManager.java.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/WorldManager.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/WorldManager.java
|
||||
@@ -12,7 +12,7 @@
|
||||
public class WorldManager implements IWorldAccess
|
||||
{
|
||||
private MinecraftServer mcServer;
|
||||
- private WorldServer theWorldServer;
|
||||
+ public WorldServer theWorldServer; // CraftBukkit - private -> public
|
||||
private static final String __OBFID = "CL_00001433";
|
||||
|
||||
public WorldManager(MinecraftServer p_i1517_1_, WorldServer p_i1517_2_)
|
607
patches/net/minecraft/world/WorldServer.java.patch
Normal file
607
patches/net/minecraft/world/WorldServer.java.patch
Normal file
@ -0,0 +1,607 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/WorldServer.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/WorldServer.java
|
||||
@@ -67,11 +67,25 @@
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
+// CraftBukkit start
|
||||
+import net.minecraft.block.ITileEntityProvider;
|
||||
+import net.minecraft.block.BlockJukebox;
|
||||
+import net.minecraft.tileentity.*;
|
||||
+import org.bukkit.WeatherType;
|
||||
+import org.bukkit.block.BlockState;
|
||||
+import org.bukkit.craftbukkit.util.LongHash;
|
||||
+
|
||||
+import org.bukkit.event.block.BlockFormEvent;
|
||||
+import org.bukkit.event.weather.LightningStrikeEvent;
|
||||
+import org.bukkit.event.weather.ThunderChangeEvent;
|
||||
+import org.bukkit.event.weather.WeatherChangeEvent;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public class WorldServer extends World
|
||||
{
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private final MinecraftServer mcServer;
|
||||
- private final EntityTracker theEntityTracker;
|
||||
+ public EntityTracker theEntityTracker; // CraftBukkit - private final -> public
|
||||
private final PlayerManager thePlayerManager;
|
||||
private Set pendingTickListEntriesHashSet;
|
||||
private TreeSet pendingTickListEntriesTreeSet;
|
||||
@@ -92,9 +106,13 @@
|
||||
protected Set<ChunkCoordIntPair> doneChunks = new HashSet<ChunkCoordIntPair>();
|
||||
public List<Teleporter> customTeleporters = new ArrayList<Teleporter>();
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ public final int dimension;
|
||||
+
|
||||
public WorldServer(MinecraftServer p_i45284_1_, ISaveHandler p_i45284_2_, String p_i45284_3_, int p_i45284_4_, WorldSettings p_i45284_5_, Profiler p_i45284_6_)
|
||||
{
|
||||
super(p_i45284_2_, p_i45284_3_, p_i45284_5_, WorldProvider.getProviderForDimension(p_i45284_4_), p_i45284_6_);
|
||||
+ this.dimension = p_i45284_4_;
|
||||
this.mcServer = p_i45284_1_;
|
||||
this.theEntityTracker = new EntityTracker(this);
|
||||
this.thePlayerManager = new PlayerManager(this);
|
||||
@@ -124,6 +142,47 @@
|
||||
this.mapStorage.setData("scoreboard", scoreboardsavedata);
|
||||
}
|
||||
|
||||
+ scoreboardsavedata.func_96499_a(this.worldScoreboard);
|
||||
+ ((ServerScoreboard) this.worldScoreboard).func_96547_a(scoreboardsavedata);
|
||||
+ }
|
||||
+
|
||||
+ // Add env and gen to constructor
|
||||
+ public WorldServer(MinecraftServer p_i45284_1_, ISaveHandler p_i45284_2_, String p_i45284_3_, int p_i45284_4_, WorldSettings p_i45284_5_,
|
||||
+ Profiler p_i45284_6_, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen)
|
||||
+ {
|
||||
+ super(p_i45284_2_, p_i45284_3_, p_i45284_5_, WorldProvider.getProviderForDimension(p_i45284_4_), p_i45284_6_, gen, env);
|
||||
+ this.dimension = p_i45284_4_;
|
||||
+ this.pvpMode = p_i45284_1_.isPVPEnabled();
|
||||
+ // CraftBukkit end
|
||||
+ this.mcServer = p_i45284_1_;
|
||||
+ this.theEntityTracker = new EntityTracker(this);
|
||||
+ this.thePlayerManager = new PlayerManager(this, spigotConfig.viewDistance); // Spigot
|
||||
+
|
||||
+ if (this.entityIdMap == null)
|
||||
+ {
|
||||
+ this.entityIdMap = new IntHashMap();
|
||||
+ }
|
||||
+
|
||||
+ if (this.pendingTickListEntriesHashSet == null)
|
||||
+ {
|
||||
+ this.pendingTickListEntriesHashSet = new HashSet();
|
||||
+ }
|
||||
+
|
||||
+ if (this.pendingTickListEntriesTreeSet == null)
|
||||
+ {
|
||||
+ this.pendingTickListEntriesTreeSet = new TreeSet();
|
||||
+ }
|
||||
+
|
||||
+ this.worldTeleporter = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit
|
||||
+ this.worldScoreboard = new ServerScoreboard(p_i45284_1_);
|
||||
+ ScoreboardSaveData scoreboardsavedata = (ScoreboardSaveData) this.mapStorage.loadData(ScoreboardSaveData.class, "scoreboard");
|
||||
+
|
||||
+ if (scoreboardsavedata == null)
|
||||
+ {
|
||||
+ scoreboardsavedata = new ScoreboardSaveData();
|
||||
+ this.mapStorage.setData("scoreboard", scoreboardsavedata);
|
||||
+ }
|
||||
+
|
||||
if (!(this instanceof WorldServerMulti)) //Forge: We fix the global mapStorage, which causes us to share scoreboards early. So don't associate the save data with the temporary scoreboard
|
||||
{
|
||||
scoreboardsavedata.func_96499_a(this.worldScoreboard);
|
||||
@@ -132,6 +191,31 @@
|
||||
DimensionManager.setWorld(p_i45284_4_, this);
|
||||
}
|
||||
|
||||
+ public WorldServer(MinecraftServer minecraftServer, ISaveHandler saveHandler, String par2String, WorldProvider provider, WorldSettings par4WorldSettings,
|
||||
+ Profiler theProfiler)
|
||||
+ {
|
||||
+ super(saveHandler, par2String, provider, par4WorldSettings, theProfiler);
|
||||
+ this.dimension = provider.dimensionId;
|
||||
+ this.pvpMode = minecraftServer.isPVPEnabled();
|
||||
+ this.mcServer = minecraftServer;
|
||||
+ this.theEntityTracker = null;
|
||||
+ this.thePlayerManager = null;
|
||||
+ this.worldTeleporter = null;
|
||||
+ }
|
||||
+
|
||||
+ private boolean canSpawn(int x, int z)
|
||||
+ {
|
||||
+ if (this.generator != null)
|
||||
+ {
|
||||
+ return this.generator.canSpawn(this.getWorld(), x, z);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return this.provider.canCoordinateBeSpawn(x, z);
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
public void tick()
|
||||
{
|
||||
super.tick();
|
||||
@@ -155,12 +239,19 @@
|
||||
}
|
||||
|
||||
this.theProfiler.startSection("mobSpawner");
|
||||
+ // CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals
|
||||
+ long time = this.worldInfo.getWorldTotalTime();
|
||||
|
||||
- if (this.getGameRules().getGameRuleBooleanValue("doMobSpawning"))
|
||||
+ if (this.getGameRules().getGameRuleBooleanValue("doMobSpawning") && (this.spawnHostileMobs || this.spawnPeacefulMobs) && (this instanceof WorldServer && this.playerEntities.size() > 0))
|
||||
{
|
||||
- this.animalSpawner.findChunksForSpawning(this, this.spawnHostileMobs, this.spawnPeacefulMobs, this.worldInfo.getWorldTotalTime() % 400L == 0L);
|
||||
+ timings.mobSpawn.startTiming(); // Spigot
|
||||
+ this.animalSpawner.findChunksForSpawning(this, this.spawnHostileMobs
|
||||
+ && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.spawnPeacefulMobs
|
||||
+ && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldInfo.getWorldTotalTime() % 400L == 0L);
|
||||
+ timings.mobSpawn.stopTiming(); // Spigot
|
||||
}
|
||||
-
|
||||
+ // CraftBukkit end
|
||||
+ timings.doChunkUnload.startTiming(); // Spigot
|
||||
this.theProfiler.endStartSection("chunkSource");
|
||||
this.chunkProvider.unloadQueuedChunks();
|
||||
int j = this.calculateSkylightSubtracted(1.0F);
|
||||
@@ -177,23 +268,40 @@
|
||||
this.worldInfo.setWorldTime(this.worldInfo.getWorldTime() + 1L);
|
||||
}
|
||||
|
||||
+ timings.doChunkUnload.stopTiming(); // Spigot
|
||||
this.theProfiler.endStartSection("tickPending");
|
||||
+ timings.doTickPending.startTiming(); // Spigot
|
||||
this.tickUpdates(false);
|
||||
+ timings.doChunkUnload.stopTiming(); // Spigot
|
||||
this.theProfiler.endStartSection("tickBlocks");
|
||||
+ timings.doTickTiles.startTiming(); // Spigot
|
||||
this.func_147456_g();
|
||||
+ timings.doTickTiles.stopTiming(); // Spigot
|
||||
this.theProfiler.endStartSection("chunkMap");
|
||||
+ timings.doChunkMap.startTiming(); // Spigot
|
||||
this.thePlayerManager.updatePlayerInstances();
|
||||
+ timings.doChunkMap.stopTiming(); // Spigot
|
||||
this.theProfiler.endStartSection("village");
|
||||
+ timings.doVillages.startTiming(); // Spigot
|
||||
this.villageCollectionObj.tick();
|
||||
this.villageSiegeObj.tick();
|
||||
+ timings.doVillages.stopTiming(); // Spigot
|
||||
this.theProfiler.endStartSection("portalForcer");
|
||||
+ timings.doPortalForcer.startTiming(); // Spigot
|
||||
this.worldTeleporter.removeStalePortalLocations(this.getTotalWorldTime());
|
||||
for (Teleporter tele : customTeleporters)
|
||||
{
|
||||
tele.removeStalePortalLocations(getTotalWorldTime());
|
||||
}
|
||||
+ timings.doPortalForcer.stopTiming(); // Spigot
|
||||
this.theProfiler.endSection();
|
||||
+ timings.doSounds.startTiming(); // Spigot
|
||||
this.func_147488_Z();
|
||||
+ timings.doSounds.stopTiming(); // Spigot
|
||||
+
|
||||
+ timings.doChunkGC.startTiming(); // Spigot
|
||||
+ this.getWorld().processChunkGC(); // CraftBukkit
|
||||
+ timings.doChunkGC.stopTiming(); // Spigot
|
||||
}
|
||||
|
||||
public BiomeGenBase.SpawnListEntry spawnRandomCreature(EnumCreatureType p_73057_1_, int p_73057_2_, int p_73057_3_, int p_73057_4_)
|
||||
@@ -212,7 +320,7 @@
|
||||
{
|
||||
EntityPlayer entityplayer = (EntityPlayer)iterator.next();
|
||||
|
||||
- if (!entityplayer.isPlayerSleeping())
|
||||
+ if (!entityplayer.isPlayerSleeping() && !entityplayer.fauxSleeping) // CraftBukkit
|
||||
{
|
||||
this.allPlayersSleeping = false;
|
||||
break;
|
||||
@@ -240,7 +348,25 @@
|
||||
|
||||
private void resetRainAndThunder()
|
||||
{
|
||||
- provider.resetRainAndThunder();
|
||||
+ // CraftBukkit start
|
||||
+ WeatherChangeEvent weather = new WeatherChangeEvent(this.getWorld(), false);
|
||||
+ this.getServer().getPluginManager().callEvent(weather);
|
||||
+ ThunderChangeEvent thunder = new ThunderChangeEvent(this.getWorld(), false);
|
||||
+ this.getServer().getPluginManager().callEvent(thunder);
|
||||
+
|
||||
+ if (!weather.isCancelled())
|
||||
+ {
|
||||
+ this.worldInfo.setRainTime(0);
|
||||
+ this.worldInfo.setRaining(false);
|
||||
+ }
|
||||
+
|
||||
+ if (!thunder.isCancelled())
|
||||
+ {
|
||||
+ this.worldInfo.setThunderTime(0);
|
||||
+ this.worldInfo.setThundering(false);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ if (!weather.isCancelled() && !thunder.isCancelled()) provider.resetRainAndThunder(); // Cauldron
|
||||
}
|
||||
|
||||
public boolean areAllPlayersAsleep()
|
||||
@@ -248,19 +374,26 @@
|
||||
if (this.allPlayersSleeping && !this.isRemote)
|
||||
{
|
||||
Iterator iterator = this.playerEntities.iterator();
|
||||
+ // CraftBukkit - This allows us to assume that some people are in bed but not really, allowing time to pass in spite of AFKers
|
||||
+ boolean foundActualSleepers = false;
|
||||
EntityPlayer entityplayer;
|
||||
|
||||
do
|
||||
{
|
||||
if (!iterator.hasNext())
|
||||
{
|
||||
- return true;
|
||||
+ return foundActualSleepers; // CraftBukkit
|
||||
}
|
||||
|
||||
entityplayer = (EntityPlayer)iterator.next();
|
||||
+ // CraftBukkit start
|
||||
+ if (entityplayer.isPlayerFullyAsleep())
|
||||
+ {
|
||||
+ foundActualSleepers = true;
|
||||
+ }
|
||||
}
|
||||
- while (entityplayer.isPlayerFullyAsleep());
|
||||
-
|
||||
+ while (entityplayer.isPlayerFullyAsleep() || entityplayer.fauxSleeping);
|
||||
+ // CraftBukkit end
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -302,15 +435,29 @@
|
||||
super.func_147456_g();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
- Iterator iterator = this.activeChunkSet.iterator();
|
||||
+ // Iterator iterator = this.activeChunkSet.iterator();
|
||||
|
||||
- while (iterator.hasNext())
|
||||
+ // Spigot start
|
||||
+ for (gnu.trove.iterator.TLongShortIterator iter = activeChunkSet_CB.iterator(); iter.hasNext();)
|
||||
{
|
||||
- ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair)iterator.next();
|
||||
- int k = chunkcoordintpair.chunkXPos * 16;
|
||||
- int l = chunkcoordintpair.chunkZPos * 16;
|
||||
+ iter.advance();
|
||||
+ long chunkCoord = iter.key();
|
||||
+ int chunkX = World.keyToX(chunkCoord);
|
||||
+ int chunkZ = World.keyToZ(chunkCoord);
|
||||
+ // If unloaded, or in process of being unloaded, drop it
|
||||
+ if ((!this.chunkExists(chunkX, chunkZ)) || (this.theChunkProviderServer.chunksToUnload.contains(chunkX, chunkZ)))
|
||||
+ {
|
||||
+ activeChunkSet.remove(new ChunkCoordIntPair(chunkX, chunkZ)); // Cauldron - vanilla compatibility
|
||||
+ iter.remove();
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+ // ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next();
|
||||
+ int k = chunkX * 16;
|
||||
+ int l = chunkZ * 16;
|
||||
+
|
||||
this.theProfiler.startSection("getChunk");
|
||||
- Chunk chunk = this.getChunkFromChunkCoords(chunkcoordintpair.chunkXPos, chunkcoordintpair.chunkZPos);
|
||||
+ Chunk chunk = this.getChunkFromChunkCoords(chunkX, chunkZ);
|
||||
this.func_147467_a(k, l, chunk);
|
||||
this.theProfiler.endStartSection("tickChunk");
|
||||
chunk.func_150804_b(false);
|
||||
@@ -346,12 +493,32 @@
|
||||
|
||||
if (this.isBlockFreezableNaturally(j1 + k, l1 - 1, k1 + l))
|
||||
{
|
||||
- this.setBlock(j1 + k, l1 - 1, k1 + l, Blocks.ice);
|
||||
+ // CraftBukkit start
|
||||
+ BlockState blockState = this.getWorld().getBlockAt(j1 + k, l1 - 1, k1 + l).getState();
|
||||
+ blockState.setTypeId(Block.getIdFromBlock(Blocks.ice));
|
||||
+ BlockFormEvent iceBlockForm = new BlockFormEvent(blockState.getBlock(), blockState);
|
||||
+ this.getServer().getPluginManager().callEvent(iceBlockForm);
|
||||
+
|
||||
+ if (!iceBlockForm.isCancelled())
|
||||
+ {
|
||||
+ blockState.update(true);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
if (this.isRaining() && this.func_147478_e(j1 + k, l1, k1 + l, true))
|
||||
{
|
||||
- this.setBlock(j1 + k, l1, k1 + l, Blocks.snow_layer);
|
||||
+ // CraftBukkit start
|
||||
+ BlockState blockState = this.getWorld().getBlockAt(j1 + k, l1, k1 + l).getState();
|
||||
+ blockState.setTypeId(Block.getIdFromBlock(Blocks.snow_layer));
|
||||
+ BlockFormEvent snow = new BlockFormEvent(blockState.getBlock(), blockState);
|
||||
+ this.getServer().getPluginManager().callEvent(snow);
|
||||
+
|
||||
+ if (!snow.isCancelled())
|
||||
+ {
|
||||
+ blockState.update(true);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
if (this.isRaining())
|
||||
@@ -388,6 +555,7 @@
|
||||
if (block.getTickRandomly())
|
||||
{
|
||||
++i;
|
||||
+ this.growthOdds = (iter.value() < 1) ? this.modifiedOdds : 100; // Spigot - grow fast if no players are in this chunk (value = player count)
|
||||
block.updateTick(this, j2 + k, l2 + extendedblockstorage.getYLocation(), k2 + l, this.rand);
|
||||
}
|
||||
}
|
||||
@@ -396,6 +564,13 @@
|
||||
|
||||
this.theProfiler.endSection();
|
||||
}
|
||||
+ // Spigot Start
|
||||
+ if (this.getSpigotConfig().clearChunksOnTick) // Cauldron
|
||||
+ {
|
||||
+ activeChunkSet_CB.clear();
|
||||
+ activeChunkSet.clear(); // Cauldron
|
||||
+ }
|
||||
+ // Spigot End
|
||||
}
|
||||
|
||||
public boolean isBlockTickScheduledThisTick(int p_147477_1_, int p_147477_2_, int p_147477_3_, Block p_147477_4_)
|
||||
@@ -474,7 +649,7 @@
|
||||
|
||||
public void updateEntities()
|
||||
{
|
||||
- if (this.playerEntities.isEmpty() && getPersistentChunks().isEmpty())
|
||||
+ if (this.playerEntities.isEmpty() && getPersistentChunks().isEmpty()) // Cauldron Use Forge logic here
|
||||
{
|
||||
if (this.updateEntityTick++ >= 1200)
|
||||
{
|
||||
@@ -506,7 +681,16 @@
|
||||
{
|
||||
if (i > 1000)
|
||||
{
|
||||
- i = 1000;
|
||||
+ // CraftBukkit start - If the server has too much to process over time, try to alleviate that
|
||||
+ if (i > 20 * 1000)
|
||||
+ {
|
||||
+ i = i / 20;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ i = 1000;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
this.theProfiler.startSection("cleaning");
|
||||
@@ -651,7 +835,37 @@
|
||||
protected IChunkProvider createChunkProvider()
|
||||
{
|
||||
IChunkLoader ichunkloader = this.saveHandler.getChunkLoader(this.provider);
|
||||
- this.theChunkProviderServer = new ChunkProviderServer(this, ichunkloader, this.provider.createChunkGenerator());
|
||||
+ // Cauldron start - if provider is vanilla, proceed to create a bukkit compatible chunk generator
|
||||
+ if (this.provider.getClass().toString().length() <= 3 || this.provider.getClass().toString().contains("net.minecraft"))
|
||||
+ {
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.craftbukkit.generator.InternalChunkGenerator gen;
|
||||
+
|
||||
+ if (this.generator != null)
|
||||
+ {
|
||||
+ gen = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, this.getSeed(), this.generator);
|
||||
+ }
|
||||
+ else if (this.provider instanceof WorldProviderHell)
|
||||
+ {
|
||||
+ gen = new org.bukkit.craftbukkit.generator.NetherChunkGenerator(this, this.getSeed());
|
||||
+ }
|
||||
+ else if (this.provider instanceof WorldProviderEnd)
|
||||
+ {
|
||||
+ gen = new org.bukkit.craftbukkit.generator.SkyLandsChunkGenerator(this, this.getSeed());
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ gen = new org.bukkit.craftbukkit.generator.NormalChunkGenerator(this, this.getSeed());
|
||||
+ }
|
||||
+ this.theChunkProviderServer = new ChunkProviderServer(this, ichunkloader, gen);
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+ else
|
||||
+ // custom provider, load normally for forge compatibility
|
||||
+ {
|
||||
+ this.theChunkProviderServer = new ChunkProviderServer(this, ichunkloader, this.provider.createChunkGenerator());
|
||||
+ }
|
||||
+ // Cauldron end
|
||||
return this.theChunkProviderServer;
|
||||
}
|
||||
|
||||
@@ -659,29 +873,31 @@
|
||||
{
|
||||
ArrayList arraylist = new ArrayList();
|
||||
|
||||
- for(int x = (p_147486_1_ >> 4); x <= (p_147486_4_ >> 4); x++)
|
||||
+ // CraftBukkit start - Get tile entities from chunks instead of world
|
||||
+ for (int chunkX = (p_147486_1_ >> 4); chunkX <= ((p_147486_4_ - 1) >> 4); chunkX++)
|
||||
{
|
||||
- for(int z = (p_147486_3_ >> 4); z <= (p_147486_6_ >> 4); z++)
|
||||
+ for (int chunkZ = (p_147486_3_ >> 4); chunkZ <= ((p_147486_6_ - 1) >> 4); chunkZ++)
|
||||
{
|
||||
- Chunk chunk = getChunkFromChunkCoords(x, z);
|
||||
- if (chunk != null)
|
||||
+ Chunk chunk = getChunkFromChunkCoords(chunkX, chunkZ);
|
||||
+
|
||||
+ if (chunk == null)
|
||||
{
|
||||
- for(Object obj : chunk.chunkTileEntityMap.values())
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ for (Object te : chunk.chunkTileEntityMap.values())
|
||||
+ {
|
||||
+ TileEntity tileentity = (TileEntity) te;
|
||||
+
|
||||
+ if ((tileentity.xCoord >= p_147486_1_) && (tileentity.yCoord >= p_147486_2_) && (tileentity.zCoord >= p_147486_3_)
|
||||
+ && (tileentity.xCoord < p_147486_4_) && (tileentity.yCoord < p_147486_5_) && (tileentity.zCoord < p_147486_6_))
|
||||
{
|
||||
- TileEntity entity = (TileEntity)obj;
|
||||
- if (!entity.isInvalid())
|
||||
- {
|
||||
- if (entity.xCoord >= p_147486_1_ && entity.yCoord >= p_147486_2_ && entity.zCoord >= p_147486_3_ &&
|
||||
- entity.xCoord <= p_147486_4_ && entity.yCoord <= p_147486_5_ && entity.zCoord <= p_147486_6_)
|
||||
- {
|
||||
- arraylist.add(entity);
|
||||
- }
|
||||
- }
|
||||
+ arraylist.add(tileentity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
+ // CraftBukkit end
|
||||
return arraylist;
|
||||
}
|
||||
|
||||
@@ -733,7 +949,28 @@
|
||||
int i = 0;
|
||||
int j = this.provider.getAverageGroundLevel();
|
||||
int k = 0;
|
||||
+ // CraftBukkit start
|
||||
+ if (this.generator != null)
|
||||
+ {
|
||||
+ Random rand = new Random(this.getSeed());
|
||||
+ org.bukkit.Location spawn = this.generator.getFixedSpawnLocation(((WorldServer) this).getWorld(), rand);
|
||||
|
||||
+ if (spawn != null)
|
||||
+ {
|
||||
+ if (spawn.getWorld() != ((WorldServer) this).getWorld())
|
||||
+ {
|
||||
+ throw new IllegalStateException("Cannot set spawn point for " + this.worldInfo.getWorldName() + " to be in another world ("
|
||||
+ + spawn.getWorld().getName() + ")");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ this.worldInfo.setSpawnPosition(spawn.getBlockX(), spawn.getBlockY(), spawn.getBlockZ());
|
||||
+ this.findingSpawnPoint = false;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (chunkposition != null)
|
||||
{
|
||||
i = chunkposition.chunkPosX;
|
||||
@@ -876,6 +1113,20 @@
|
||||
|
||||
public boolean addWeatherEffect(Entity p_72942_1_)
|
||||
{
|
||||
+ // Cauldron start - vanilla compatibility
|
||||
+ if (p_72942_1_ instanceof net.minecraft.entity.effect.EntityLightningBolt)
|
||||
+ {
|
||||
+ // CraftBukkit start
|
||||
+ LightningStrikeEvent lightning = new LightningStrikeEvent(this.getWorld(), (org.bukkit.entity.LightningStrike) p_72942_1_.getBukkitEntity());
|
||||
+ this.getServer().getPluginManager().callEvent(lightning);
|
||||
+
|
||||
+ if (lightning.isCancelled())
|
||||
+ {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+ // Cauldron end
|
||||
if (super.addWeatherEffect(p_72942_1_))
|
||||
{
|
||||
this.mcServer.getConfigurationManager().sendToAllNear(p_72942_1_.posX, p_72942_1_.posY, p_72942_1_.posZ, 512.0D, this.provider.dimensionId, new S2CPacketSpawnGlobalEntity(p_72942_1_));
|
||||
@@ -894,13 +1145,23 @@
|
||||
|
||||
public Explosion newExplosion(Entity p_72885_1_, double p_72885_2_, double p_72885_4_, double p_72885_6_, float p_72885_8_, boolean p_72885_9_, boolean p_72885_10_)
|
||||
{
|
||||
+ // CraftBukkit start
|
||||
+ Explosion explosion = super.newExplosion(p_72885_1_, p_72885_2_, p_72885_4_, p_72885_6_, p_72885_8_, p_72885_9_, p_72885_10_);
|
||||
+
|
||||
+ if (explosion.wasCanceled)
|
||||
+ {
|
||||
+ return explosion;
|
||||
+ }
|
||||
+
|
||||
+ /* Remove
|
||||
Explosion explosion = new Explosion(this, p_72885_1_, p_72885_2_, p_72885_4_, p_72885_6_, p_72885_8_);
|
||||
explosion.isFlaming = p_72885_9_;
|
||||
explosion.isSmoking = p_72885_10_;
|
||||
if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this, explosion)) return explosion;
|
||||
explosion.doExplosionA();
|
||||
explosion.doExplosionB(false);
|
||||
-
|
||||
+ */
|
||||
+ // CraftBukkit end - TODO: Check if explosions are still properly implemented
|
||||
if (!p_72885_10_)
|
||||
{
|
||||
explosion.affectedBlockPositions.clear();
|
||||
@@ -977,7 +1238,7 @@
|
||||
{
|
||||
boolean flag = this.isRaining();
|
||||
super.updateWeather();
|
||||
-
|
||||
+ /* CraftBukkit start
|
||||
if (this.prevRainingStrength != this.rainingStrength)
|
||||
{
|
||||
this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(7, this.rainingStrength), this.provider.dimensionId);
|
||||
@@ -988,10 +1249,6 @@
|
||||
this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(8, this.thunderingStrength), this.provider.dimensionId);
|
||||
}
|
||||
|
||||
- /*The function in use here has been replaced in order to only send the weather info to players in the correct dimension,
|
||||
- rather than to all players on the server. This is what causes the client-side rain, as the
|
||||
- client believes that it has started raining locally, rather than in another dimension.
|
||||
- */
|
||||
if (flag != this.isRaining())
|
||||
{
|
||||
if (flag)
|
||||
@@ -1006,6 +1263,20 @@
|
||||
this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(7, this.rainingStrength), this.provider.dimensionId);
|
||||
this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(8, this.thunderingStrength), this.provider.dimensionId);
|
||||
}
|
||||
+ // */
|
||||
+ if (flag != this.isRaining())
|
||||
+ {
|
||||
+ // Only send weather packets to those affected
|
||||
+ for (int i = 0; i < this.playerEntities.size(); ++i)
|
||||
+ {
|
||||
+ if (((EntityPlayerMP) this.playerEntities.get(i)).worldObj == this)
|
||||
+ {
|
||||
+ ((EntityPlayerMP) this.playerEntities.get(i)).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
}
|
||||
|
||||
protected int func_152379_p()
|
||||
@@ -1069,4 +1340,31 @@
|
||||
this();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit start - Compatibility methods for BlockChangeDelegate
|
||||
+ public boolean setRawTypeId(int x, int y, int z, int typeId)
|
||||
+ {
|
||||
+ return this.setBlock(x, y, z, Block.getBlockById(typeId), 0, 4);
|
||||
+ }
|
||||
+
|
||||
+ public boolean setRawTypeIdAndData(int x, int y, int z, int typeId, int data)
|
||||
+ {
|
||||
+ return this.setBlock(x, y, z, Block.getBlockById(typeId), data, 4);
|
||||
+ }
|
||||
+
|
||||
+ public boolean setTypeId(int x, int y, int z, int typeId)
|
||||
+ {
|
||||
+ return this.setBlock(x, y, z, Block.getBlockById(typeId), 0, 3);
|
||||
+ }
|
||||
+
|
||||
+ public boolean setTypeIdAndData(int x, int y, int z, int typeId, int data)
|
||||
+ {
|
||||
+ return this.setBlock(x, y, z, Block.getBlockById(typeId), data, 3);
|
||||
+ }
|
||||
+
|
||||
+ public int getTypeId(int x, int y, int z)
|
||||
+ {
|
||||
+ return Block.getIdFromBlock(getBlock(x, y, z));
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
36
patches/net/minecraft/world/WorldServerMulti.java.patch
Normal file
36
patches/net/minecraft/world/WorldServerMulti.java.patch
Normal file
@ -0,0 +1,36 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/WorldServerMulti.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/WorldServerMulti.java
|
||||
@@ -9,6 +9,17 @@
|
||||
{
|
||||
private static final String __OBFID = "CL_00001430";
|
||||
|
||||
+ // CraftBukkit start - Add Environment and ChunkGenerator arguments
|
||||
+ public WorldServerMulti(MinecraftServer p_i45283_1_, ISaveHandler p_i45283_2_, String p_i45283_3_, int p_i45283_4_, WorldSettings p_i45283_5_, WorldServer p_i45283_6_, Profiler p_i45283_7_, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen)
|
||||
+ {
|
||||
+ super(p_i45283_1_, p_i45283_2_, p_i45283_3_, p_i45283_4_, p_i45283_5_, p_i45283_7_, env, gen);
|
||||
+ // CraftBukkit end
|
||||
+ this.mapStorage = p_i45283_6_.mapStorage;
|
||||
+ this.worldScoreboard = p_i45283_6_.getScoreboard();
|
||||
+ //this.worldInfo = new DerivedWorldInfo(p_i45283_6_.getWorldInfo());
|
||||
+ }
|
||||
+
|
||||
+ // Cauldron start - vanilla compatibility
|
||||
public WorldServerMulti(MinecraftServer p_i45283_1_, ISaveHandler p_i45283_2_, String p_i45283_3_, int p_i45283_4_, WorldSettings p_i45283_5_, WorldServer p_i45283_6_, Profiler p_i45283_7_)
|
||||
{
|
||||
super(p_i45283_1_, p_i45283_2_, p_i45283_3_, p_i45283_4_, p_i45283_5_, p_i45283_7_);
|
||||
@@ -16,9 +27,15 @@
|
||||
this.worldScoreboard = p_i45283_6_.getScoreboard();
|
||||
this.worldInfo = new DerivedWorldInfo(p_i45283_6_.getWorldInfo());
|
||||
}
|
||||
+ // Cauldron end
|
||||
|
||||
+ /* we handle all saving including perWorldStorage in WorldServer.saveLevel. This needs to be disabled since we follow
|
||||
+ // bukkit's world saving methods by using a seperate save handler for each world. Each world folder needs to generate a corresponding
|
||||
+ // level.dat for plugins that require it such as MultiWorld.
|
||||
protected void saveLevel() throws MinecraftException
|
||||
{
|
||||
this.perWorldStorage.saveAllData();
|
||||
}
|
||||
+ */
|
||||
+ // Cauldron end
|
||||
}
|
23
patches/net/minecraft/world/WorldType.java.patch
Normal file
23
patches/net/minecraft/world/WorldType.java.patch
Normal file
@ -0,0 +1,23 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/WorldType.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/WorldType.java
|
||||
@@ -19,6 +19,7 @@
|
||||
import net.minecraft.world.gen.layer.GenLayerZoom;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
+import net.minecraftforge.common.util.EnumHelper; // Cauldron
|
||||
|
||||
public class WorldType
|
||||
{
|
||||
@@ -49,6 +50,12 @@
|
||||
this.canBeCreated = true;
|
||||
this.worldTypeId = p_i1960_1_;
|
||||
worldTypes[p_i1960_1_] = this;
|
||||
+ // Cauldron start - add worldtype for bukkit if it does not already exist
|
||||
+ if (org.bukkit.WorldType.getByName(p_i1960_2_) == null)
|
||||
+ {
|
||||
+ EnumHelper.addBukkitWorldType(p_i1960_2_);
|
||||
+ }
|
||||
+ // Cauldron end
|
||||
}
|
||||
|
||||
public String getWorldTypeName()
|
164
patches/net/minecraft/world/biome/BiomeDecorator.java.patch
Normal file
164
patches/net/minecraft/world/biome/BiomeDecorator.java.patch
Normal file
@ -0,0 +1,164 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/biome/BiomeDecorator.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/biome/BiomeDecorator.java
|
||||
@@ -24,6 +24,14 @@
|
||||
import net.minecraftforge.common.*;
|
||||
import net.minecraftforge.event.terraingen.*;
|
||||
|
||||
+// Spigot Start
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Iterator;
|
||||
+import java.util.List;
|
||||
+
|
||||
+import net.minecraft.world.chunk.Chunk;
|
||||
+// Spigot End
|
||||
+
|
||||
public class BiomeDecorator
|
||||
{
|
||||
public World currentWorld;
|
||||
@@ -61,6 +69,7 @@
|
||||
public int clayPerChunk;
|
||||
public int bigMushroomsPerChunk;
|
||||
public boolean generateLakes;
|
||||
+ private final List<Chunk> chunksToUnload = new ArrayList<Chunk>(); // Spigot
|
||||
private static final String __OBFID = "CL_00000164";
|
||||
|
||||
public BiomeDecorator()
|
||||
@@ -194,7 +203,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
|
||||
+ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
|
||||
WorldGenerator worldgenerator = p_150513_1_.getRandomWorldGenForGrass(this.randomGenerator);
|
||||
worldgenerator.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
@@ -204,7 +213,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
|
||||
+ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
|
||||
(new WorldGenDeadBush(Blocks.deadbush)).generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -214,7 +223,7 @@
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
|
||||
- for (i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2); i1 > 0 && this.currentWorld.isAirBlock(k, i1 - 1, l); --i1)
|
||||
+ for (i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); i1 > 0 && this.currentWorld.isAirBlock(k, i1 - 1, l); --i1) // Spigot
|
||||
{
|
||||
;
|
||||
}
|
||||
@@ -229,7 +238,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- i1 = this.currentWorld.getHeightValue(k, l);
|
||||
+ i1 = this.getHighestBlockYAt(k, l); // Spigot
|
||||
this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -237,7 +246,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
|
||||
+ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
|
||||
this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
}
|
||||
@@ -246,7 +255,7 @@
|
||||
{
|
||||
j = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- l = nextInt(this.currentWorld.getHeightValue(j, k) * 2);
|
||||
+ l = nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot
|
||||
this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, j, l, k);
|
||||
}
|
||||
|
||||
@@ -254,7 +263,7 @@
|
||||
{
|
||||
j = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- l = nextInt(this.currentWorld.getHeightValue(j, k) * 2);
|
||||
+ l = nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot
|
||||
this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, j, l, k);
|
||||
}
|
||||
|
||||
@@ -263,7 +272,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
|
||||
+ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
|
||||
this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -271,7 +280,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
|
||||
+ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
|
||||
this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -280,7 +289,7 @@
|
||||
{
|
||||
j = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- l = nextInt(this.currentWorld.getHeightValue(j, k) * 2);
|
||||
+ l = nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot
|
||||
(new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, j, l, k);
|
||||
}
|
||||
|
||||
@@ -289,7 +298,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
|
||||
+ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
|
||||
this.cactusGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -313,6 +322,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ this.unloadChunks(); // Spigot - unload chunks we force loaded
|
||||
MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
|
||||
}
|
||||
|
||||
@@ -360,6 +370,31 @@
|
||||
MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
|
||||
}
|
||||
|
||||
+ // Spigot start - force load chunks
|
||||
+ private int getHighestBlockYAt(int i, int j)
|
||||
+ {
|
||||
+ // Make sure the chunk is loaded
|
||||
+ if (!this.currentWorld.chunkExists(i >> 4, j >> 4))
|
||||
+ {
|
||||
+ // If not, load it, then add it to our unload list
|
||||
+ this.chunksToUnload.add(this.currentWorld.getChunkFromChunkCoords(i >> 4, j >> 4));
|
||||
+ }
|
||||
+
|
||||
+ return this.currentWorld.getHeightValue(i, j);
|
||||
+ }
|
||||
+
|
||||
+ private void unloadChunks()
|
||||
+ {
|
||||
+ Iterator<Chunk> iter = this.chunksToUnload.iterator();
|
||||
+
|
||||
+ while (iter.hasNext())
|
||||
+ {
|
||||
+ this.currentWorld.getWorld().unloadChunk(iter.next().bukkitChunk);
|
||||
+ iter.remove();
|
||||
+ }
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+
|
||||
private int nextInt(int i) {
|
||||
if (i <= 1)
|
||||
return 0;
|
266
patches/net/minecraft/world/chunk/Chunk.java.patch
Normal file
266
patches/net/minecraft/world/chunk/Chunk.java.patch
Normal 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)
|
233
patches/net/minecraft/world/chunk/NibbleArray.java.patch
Normal file
233
patches/net/minecraft/world/chunk/NibbleArray.java.patch
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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_)
|
@ -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);
|
||||
}
|
||||
}
|
@ -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()
|
||||
{
|
@ -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_)
|
465
patches/net/minecraft/world/gen/ChunkProviderServer.java.patch
Normal file
465
patches/net/minecraft/world/gen/ChunkProviderServer.java.patch
Normal file
@ -0,0 +1,465 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/gen/ChunkProviderServer.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/gen/ChunkProviderServer.java
|
||||
@@ -32,23 +32,40 @@
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
+// CraftBukkit start
|
||||
+import java.util.Random;
|
||||
+import net.minecraft.block.BlockSand;
|
||||
+import org.bukkit.Server;
|
||||
+import org.bukkit.craftbukkit.util.LongHash;
|
||||
+import org.bukkit.craftbukkit.util.LongHashSet;
|
||||
+import org.bukkit.craftbukkit.util.LongObjectHashMap;
|
||||
+import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
+// CraftBukkit end
|
||||
+// Cauldron start
|
||||
+import cpw.mods.fml.common.FMLCommonHandler;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraftforge.cauldron.configuration.CauldronConfig;
|
||||
+import net.minecraftforge.cauldron.CauldronHooks;
|
||||
+// Cauldron end
|
||||
|
||||
public class ChunkProviderServer implements IChunkProvider
|
||||
{
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
- private Set chunksToUnload = Collections.newSetFromMap(new ConcurrentHashMap());
|
||||
- private Chunk defaultEmptyChunk;
|
||||
+ public LongHashSet chunksToUnload = new LongHashSet(); // LongHashSet
|
||||
+ public Chunk defaultEmptyChunk;
|
||||
public IChunkProvider currentChunkProvider;
|
||||
public IChunkLoader currentChunkLoader;
|
||||
- public boolean loadChunkOnProvideRequest = true;
|
||||
- public LongHashMap loadedChunkHashMap = new LongHashMap();
|
||||
- public List loadedChunks = new ArrayList();
|
||||
+ public boolean loadChunkOnProvideRequest = MinecraftServer.getServer().cauldronConfig.loadChunkOnRequest.getValue(); // Cauldron - if true, allows mods to force load chunks. to disable, set load-chunk-on-request in cauldron.yml to false
|
||||
+ public int initialTick; // Cauldron counter to keep track of when this loader was created
|
||||
+ public LongObjectHashMap<Chunk> loadedChunkHashMap = new LongObjectHashMap<Chunk>();
|
||||
+ public List loadedChunks = new ArrayList(); // Cauldron - vanilla compatibility
|
||||
public WorldServer worldObj;
|
||||
private Set<Long> loadingChunks = com.google.common.collect.Sets.newHashSet();
|
||||
private static final String __OBFID = "CL_00001436";
|
||||
|
||||
public ChunkProviderServer(WorldServer p_i1520_1_, IChunkLoader p_i1520_2_, IChunkProvider p_i1520_3_)
|
||||
{
|
||||
+ this.initialTick = MinecraftServer.currentTick; // Cauldron keep track of when the loader was created
|
||||
this.defaultEmptyChunk = new EmptyChunk(p_i1520_1_, 0, 0);
|
||||
this.worldObj = p_i1520_1_;
|
||||
this.currentChunkLoader = p_i1520_2_;
|
||||
@@ -57,10 +74,10 @@
|
||||
|
||||
public boolean chunkExists(int p_73149_1_, int p_73149_2_)
|
||||
{
|
||||
- return this.loadedChunkHashMap.containsItem(ChunkCoordIntPair.chunkXZ2Int(p_73149_1_, p_73149_2_));
|
||||
+ return this.loadedChunkHashMap.containsKey(LongHash.toLong(p_73149_1_, p_73149_2_)); // CraftBukkit
|
||||
}
|
||||
|
||||
- public List func_152380_a()
|
||||
+ public List func_152380_a() // Vanilla compatibility
|
||||
{
|
||||
return this.loadedChunks;
|
||||
}
|
||||
@@ -74,20 +91,39 @@
|
||||
int l = p_73241_2_ * 16 + 8 - chunkcoordinates.posZ;
|
||||
short short1 = 128;
|
||||
|
||||
+ // CraftBukkit start
|
||||
if (k < -short1 || k > short1 || l < -short1 || l > short1)
|
||||
{
|
||||
- this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(p_73241_1_, p_73241_2_)));
|
||||
+ this.chunksToUnload.add(p_73241_1_, p_73241_2_);
|
||||
+ Chunk c = this.loadedChunkHashMap.get(LongHash.toLong(p_73241_1_, p_73241_2_));
|
||||
+
|
||||
+ if (c != null)
|
||||
+ {
|
||||
+ c.mustSave = true;
|
||||
+ }
|
||||
+ CauldronHooks.logChunkUnload(this, p_73241_1_, p_73241_2_, "Chunk added to unload queue");
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
else
|
||||
{
|
||||
- this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(p_73241_1_, p_73241_2_)));
|
||||
+ // CraftBukkit start
|
||||
+ this.chunksToUnload.add(p_73241_1_, p_73241_2_);
|
||||
+ Chunk c = this.loadedChunkHashMap.get(LongHash.toLong(p_73241_1_, p_73241_2_));
|
||||
+
|
||||
+ if (c != null)
|
||||
+ {
|
||||
+ c.mustSave = true;
|
||||
+ }
|
||||
+ CauldronHooks.logChunkUnload(this, p_73241_1_, p_73241_2_, "Chunk added to unload queue");
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
|
||||
public void unloadAllChunks()
|
||||
{
|
||||
- Iterator iterator = this.loadedChunks.iterator();
|
||||
+ Iterator iterator = this.loadedChunkHashMap.values().iterator(); // CraftBukkit
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
@@ -103,9 +139,9 @@
|
||||
|
||||
public Chunk loadChunk(int par1, int par2, Runnable runnable)
|
||||
{
|
||||
- long k = ChunkCoordIntPair.chunkXZ2Int(par1, par2);
|
||||
- this.chunksToUnload.remove(Long.valueOf(k));
|
||||
- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k);
|
||||
+ this.chunksToUnload.remove(par1, par2);
|
||||
+ Chunk chunk = (Chunk) this.loadedChunkHashMap.get(LongHash.toLong(par1, par2));
|
||||
+ boolean newChunk = false;
|
||||
AnvilChunkLoader loader = null;
|
||||
|
||||
if (this.currentChunkLoader instanceof AnvilChunkLoader)
|
||||
@@ -113,6 +149,8 @@
|
||||
loader = (AnvilChunkLoader) this.currentChunkLoader;
|
||||
}
|
||||
|
||||
+ CauldronHooks.logChunkLoad(this, "Get", par1, par2, true);
|
||||
+
|
||||
// We can only use the queue for already generated chunks
|
||||
if (chunk == null && loader != null && loader.chunkExists(this.worldObj, par1, par2))
|
||||
{
|
||||
@@ -142,18 +180,19 @@
|
||||
|
||||
public Chunk originalLoadChunk(int p_73158_1_, int p_73158_2_)
|
||||
{
|
||||
- long k = ChunkCoordIntPair.chunkXZ2Int(p_73158_1_, p_73158_2_);
|
||||
- this.chunksToUnload.remove(Long.valueOf(k));
|
||||
- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k);
|
||||
+ this.chunksToUnload.remove(p_73158_1_, p_73158_2_);
|
||||
+ Chunk chunk = (Chunk) this.loadedChunkHashMap.get(LongHash.toLong(p_73158_1_, p_73158_2_));
|
||||
+ boolean newChunk = false; // CraftBukkit
|
||||
|
||||
if (chunk == null)
|
||||
{
|
||||
- boolean added = loadingChunks.add(k);
|
||||
+ worldObj.timings.syncChunkLoadTimer.startTiming(); // Spigot
|
||||
+ boolean added = loadingChunks.add(LongHash.toLong(p_73158_1_, p_73158_2_));
|
||||
if (!added)
|
||||
{
|
||||
cpw.mods.fml.common.FMLLog.bigWarning("There is an attempt to load a chunk (%d,%d) in dimension %d that is already being loaded. This will cause weird chunk breakages.", p_73158_1_, p_73158_2_, worldObj.provider.dimensionId);
|
||||
}
|
||||
- chunk = ForgeChunkManager.fetchDormantChunk(k, this.worldObj);
|
||||
+ chunk = ForgeChunkManager.fetchDormantChunk(LongHash.toLong(p_73158_1_, p_73158_2_), this.worldObj);
|
||||
if (chunk == null)
|
||||
{
|
||||
chunk = this.safeLoadChunk(p_73158_1_, p_73158_2_);
|
||||
@@ -176,18 +215,39 @@
|
||||
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Exception generating new chunk");
|
||||
CrashReportCategory crashreportcategory = crashreport.makeCategory("Chunk to be generated");
|
||||
crashreportcategory.addCrashSection("Location", String.format("%d,%d", new Object[] {Integer.valueOf(p_73158_1_), Integer.valueOf(p_73158_2_)}));
|
||||
- crashreportcategory.addCrashSection("Position hash", Long.valueOf(k));
|
||||
+ crashreportcategory.addCrashSection("Position hash", LongHash.toLong(p_73158_1_, p_73158_2_));
|
||||
crashreportcategory.addCrashSection("Generator", this.currentChunkProvider.makeString());
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ newChunk = true; // CraftBukkit
|
||||
}
|
||||
|
||||
- this.loadedChunkHashMap.add(k, chunk);
|
||||
- this.loadedChunks.add(chunk);
|
||||
- loadingChunks.remove(k);
|
||||
- chunk.onChunkLoad();
|
||||
+ this.loadedChunkHashMap.put(LongHash.toLong(p_73158_1_, p_73158_2_), chunk); // CraftBukkit
|
||||
+ this.loadedChunks.add(chunk); // Cauldron - vanilla compatibility
|
||||
+ loadingChunks.remove(LongHash.toLong(p_73158_1_, p_73158_2_)); // Cauldron - LongHash
|
||||
+
|
||||
+ if (chunk != null)
|
||||
+ {
|
||||
+ chunk.onChunkLoad();
|
||||
+ }
|
||||
+ // CraftBukkit start
|
||||
+ Server server = this.worldObj.getServer();
|
||||
+
|
||||
+ if (server != null)
|
||||
+ {
|
||||
+ /*
|
||||
+ * If it's a new world, the first few chunks are generated inside
|
||||
+ * the World constructor. We can't reliably alter that, so we have
|
||||
+ * no way of creating a CraftWorld/CraftServer at that point.
|
||||
+ */
|
||||
+ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, newChunk));
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit end
|
||||
chunk.populateChunk(this, this, p_73158_1_, p_73158_2_);
|
||||
+ worldObj.timings.syncChunkLoadTimer.stopTiming(); // Spigot
|
||||
}
|
||||
|
||||
return chunk;
|
||||
@@ -195,11 +255,29 @@
|
||||
|
||||
public Chunk provideChunk(int p_73154_1_, int p_73154_2_)
|
||||
{
|
||||
- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(ChunkCoordIntPair.chunkXZ2Int(p_73154_1_, p_73154_2_));
|
||||
- return chunk == null ? (!this.worldObj.findingSpawnPoint && !this.loadChunkOnProvideRequest ? this.defaultEmptyChunk : this.loadChunk(p_73154_1_, p_73154_2_)) : chunk;
|
||||
+ // CraftBukkit start
|
||||
+ Chunk chunk = (Chunk) this.loadedChunkHashMap.get(LongHash.toLong(p_73154_1_, p_73154_2_));
|
||||
+ chunk = chunk == null ? (shouldLoadChunk() ? this.loadChunk(p_73154_1_, p_73154_2_) : this.defaultEmptyChunk) : chunk; // Cauldron handle forge server tick events and load the chunk within 5 seconds of the world being loaded (for chunk loaders)
|
||||
+
|
||||
+ if (chunk == this.defaultEmptyChunk)
|
||||
+ {
|
||||
+ return chunk;
|
||||
+ }
|
||||
+
|
||||
+ if (p_73154_1_ != chunk.xPosition || p_73154_2_ != chunk.zPosition)
|
||||
+ {
|
||||
+ logger.error("Chunk (" + chunk.xPosition + ", " + chunk.zPosition + ") stored at (" + p_73154_1_ + ", " + p_73154_2_ + ") in world '" + worldObj.getWorld().getName() + "'");
|
||||
+ logger.error(chunk.getClass().getName());
|
||||
+ Throwable ex = new Throwable();
|
||||
+ ex.fillInStackTrace();
|
||||
+ ex.printStackTrace();
|
||||
+ }
|
||||
+ chunk.lastAccessedTick = MinecraftServer.getServer().getTickCounter(); // Cauldron
|
||||
+ return chunk;
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
- private Chunk safeLoadChunk(int p_73239_1_, int p_73239_2_)
|
||||
+ public Chunk safeLoadChunk(int p_73239_1_, int p_73239_2_) // CraftBukkit - private -> public
|
||||
{
|
||||
if (this.currentChunkLoader == null)
|
||||
{
|
||||
@@ -209,6 +287,7 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
+ CauldronHooks.logChunkLoad(this, "Safe Load", p_73239_1_, p_73239_2_, false); // Cauldron
|
||||
Chunk chunk = this.currentChunkLoader.loadChunk(this.worldObj, p_73239_1_, p_73239_2_);
|
||||
|
||||
if (chunk != null)
|
||||
@@ -217,8 +296,11 @@
|
||||
|
||||
if (this.currentChunkProvider != null)
|
||||
{
|
||||
+ worldObj.timings.syncChunkLoadStructuresTimer.startTiming(); // Spigot
|
||||
this.currentChunkProvider.recreateStructures(p_73239_1_, p_73239_2_);
|
||||
+ worldObj.timings.syncChunkLoadStructuresTimer.stopTiming(); // Spigot
|
||||
}
|
||||
+ chunk.lastAccessedTick = MinecraftServer.getServer().getTickCounter(); // Cauldron
|
||||
}
|
||||
|
||||
return chunk;
|
||||
@@ -231,7 +313,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private void safeSaveExtraChunkData(Chunk p_73243_1_)
|
||||
+ public void safeSaveExtraChunkData(Chunk p_73243_1_) // CraftBukkit - private -> public
|
||||
{
|
||||
if (this.currentChunkLoader != null)
|
||||
{
|
||||
@@ -246,7 +328,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private void safeSaveChunk(Chunk p_73242_1_)
|
||||
+ public void safeSaveChunk(Chunk p_73242_1_) // CraftBukkit - private -> public
|
||||
{
|
||||
if (this.currentChunkLoader != null)
|
||||
{
|
||||
@@ -254,15 +336,18 @@
|
||||
{
|
||||
p_73242_1_.lastSaveTime = this.worldObj.getTotalWorldTime();
|
||||
this.currentChunkLoader.saveChunk(this.worldObj, p_73242_1_);
|
||||
+ // CraftBukkit start - IOException to Exception
|
||||
}
|
||||
- catch (IOException ioexception)
|
||||
+ catch (Exception ioexception)
|
||||
{
|
||||
logger.error("Couldn\'t save chunk", ioexception);
|
||||
}
|
||||
+ /* Remove extra exception
|
||||
catch (MinecraftException minecraftexception)
|
||||
{
|
||||
logger.error("Couldn\'t save chunk; already in use by another instance of Minecraft?", minecraftexception);
|
||||
}
|
||||
+ // CraftBukkit end */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,6 +362,35 @@
|
||||
if (this.currentChunkProvider != null)
|
||||
{
|
||||
this.currentChunkProvider.populate(p_73153_1_, p_73153_2_, p_73153_3_);
|
||||
+ // CraftBukkit start
|
||||
+ BlockSand.fallInstantly = true;
|
||||
+ Random random = new Random();
|
||||
+ random.setSeed(worldObj.getSeed());
|
||||
+ long xRand = random.nextLong() / 2L * 2L + 1L;
|
||||
+ long zRand = random.nextLong() / 2L * 2L + 1L;
|
||||
+ random.setSeed((long) p_73153_2_ * xRand + (long) p_73153_3_ * zRand ^ worldObj.getSeed());
|
||||
+ org.bukkit.World world = this.worldObj.getWorld();
|
||||
+
|
||||
+ if (world != null)
|
||||
+ {
|
||||
+ this.worldObj.populating = true;
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ for (org.bukkit.generator.BlockPopulator populator : world.getPopulators())
|
||||
+ {
|
||||
+ populator.populate(world, random, chunk.bukkitChunk);
|
||||
+ }
|
||||
+ }
|
||||
+ finally
|
||||
+ {
|
||||
+ this.worldObj.populating = false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ BlockSand.fallInstantly = false;
|
||||
+ this.worldObj.getServer().getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(chunk.bukkitChunk));
|
||||
+ // CraftBukkit end
|
||||
GameRegistry.generateWorld(p_73153_2_, p_73153_3_, worldObj, currentChunkProvider, p_73153_1_);
|
||||
chunk.setChunkModified();
|
||||
}
|
||||
@@ -286,11 +400,13 @@
|
||||
public boolean saveChunks(boolean p_73151_1_, IProgressUpdate p_73151_2_)
|
||||
{
|
||||
int i = 0;
|
||||
- ArrayList arraylist = Lists.newArrayList(this.loadedChunks);
|
||||
+ // Cauldron start - use thread-safe method for iterating loaded chunks
|
||||
+ Object[] chunks = this.loadedChunks.toArray();
|
||||
|
||||
- for (int j = 0; j < arraylist.size(); ++j)
|
||||
+ for (int j = 0; j < chunks.length; ++j)
|
||||
{
|
||||
- Chunk chunk = (Chunk)arraylist.get(j);
|
||||
+ Chunk chunk = (Chunk)chunks[j];
|
||||
+ //Cauldron end
|
||||
|
||||
if (p_73151_1_)
|
||||
{
|
||||
@@ -325,36 +441,60 @@
|
||||
{
|
||||
if (!this.worldObj.levelSaving)
|
||||
{
|
||||
- for (ChunkCoordIntPair forced : this.worldObj.getPersistentChunks().keySet())
|
||||
+ // Cauldron start - remove any chunk that has a ticket associated with it
|
||||
+ if (!this.chunksToUnload.isEmpty())
|
||||
{
|
||||
- this.chunksToUnload.remove(ChunkCoordIntPair.chunkXZ2Int(forced.chunkXPos, forced.chunkZPos));
|
||||
+ for (ChunkCoordIntPair forcedChunk : this.worldObj.getPersistentChunks().keys())
|
||||
+ {
|
||||
+ this.chunksToUnload.remove(forcedChunk.chunkXPos, forcedChunk.chunkZPos);
|
||||
+ }
|
||||
}
|
||||
+ // Cauldron end
|
||||
+ // CraftBukkit start
|
||||
+ Server server = this.worldObj.getServer();
|
||||
|
||||
- for (int i = 0; i < 100; ++i)
|
||||
+ for (int i = 0; i < 100 && !this.chunksToUnload.isEmpty(); i++)
|
||||
{
|
||||
- if (!this.chunksToUnload.isEmpty())
|
||||
+ long chunkcoordinates = this.chunksToUnload.popFirst();
|
||||
+ Chunk chunk = this.loadedChunkHashMap.get(chunkcoordinates);
|
||||
+
|
||||
+ if (chunk == null)
|
||||
{
|
||||
- Long olong = (Long)this.chunksToUnload.iterator().next();
|
||||
- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(olong.longValue());
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- if (chunk != null)
|
||||
- {
|
||||
- chunk.onChunkUnload();
|
||||
- this.safeSaveChunk(chunk);
|
||||
- this.safeSaveExtraChunkData(chunk);
|
||||
- this.loadedChunks.remove(chunk);
|
||||
- ForgeChunkManager.putDormantChunk(ChunkCoordIntPair.chunkXZ2Int(chunk.xPosition, chunk.zPosition), chunk);
|
||||
- if(loadedChunks.size() == 0 && ForgeChunkManager.getPersistentChunksFor(this.worldObj).size() == 0 && !DimensionManager.shouldLoadSpawn(this.worldObj.provider.dimensionId)){
|
||||
- DimensionManager.unloadWorld(this.worldObj.provider.dimensionId);
|
||||
- return currentChunkProvider.unloadQueuedChunks();
|
||||
- }
|
||||
- }
|
||||
+ // Cauldron static - check if the chunk was accessed recently and keep it loaded if there are players in world
|
||||
+ /*if (!shouldUnloadChunk(chunk) && this.worldObj.playerEntities.size() > 0)
|
||||
+ {
|
||||
+ CauldronHooks.logChunkUnload(this, chunk.xPosition, chunk.zPosition, "** Chunk kept from unloading due to recent activity");
|
||||
+ continue;
|
||||
+ }*/
|
||||
+ // Cauldron end
|
||||
|
||||
- this.chunksToUnload.remove(olong);
|
||||
- this.loadedChunkHashMap.remove(olong.longValue());
|
||||
+
|
||||
+ ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk);
|
||||
+ server.getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (!event.isCancelled())
|
||||
+ {
|
||||
+ CauldronHooks.logChunkUnload(this, chunk.xPosition, chunk.zPosition, "Unloading Chunk at");
|
||||
+
|
||||
+ chunk.onChunkUnload();
|
||||
+ this.safeSaveChunk(chunk);
|
||||
+ this.safeSaveExtraChunkData(chunk);
|
||||
+ // this.unloadQueue.remove(olong);
|
||||
+ this.loadedChunkHashMap.remove(chunkcoordinates); // CraftBukkit
|
||||
+ this.loadedChunks.remove(chunk); // Cauldron - vanilla compatibility
|
||||
+ ForgeChunkManager.putDormantChunk(chunkcoordinates, chunk);
|
||||
+ if(this.loadedChunkHashMap.size() == 0 && ForgeChunkManager.getPersistentChunksFor(this.worldObj).size() == 0 && !DimensionManager.shouldLoadSpawn(this.worldObj.provider.dimensionId)){
|
||||
+ DimensionManager.unloadWorld(this.worldObj.provider.dimensionId);
|
||||
+ return currentChunkProvider.unloadQueuedChunks();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
if (this.currentChunkLoader != null)
|
||||
{
|
||||
this.currentChunkLoader.chunkTick();
|
||||
@@ -371,7 +511,8 @@
|
||||
|
||||
public String makeString()
|
||||
{
|
||||
- return "ServerChunkCache: " + this.loadedChunkHashMap.getNumHashElements() + " Drop: " + this.chunksToUnload.size();
|
||||
+ // CraftBukkit - this.chunks.count() -> .values().size()
|
||||
+ return "ServerChunkCache: " + this.loadedChunkHashMap.values().size() + " Drop: " + this.chunksToUnload.size();
|
||||
}
|
||||
|
||||
public List getPossibleCreatures(EnumCreatureType p_73155_1_, int p_73155_2_, int p_73155_3_, int p_73155_4_)
|
||||
@@ -386,8 +527,32 @@
|
||||
|
||||
public int getLoadedChunkCount()
|
||||
{
|
||||
- return this.loadedChunkHashMap.getNumHashElements();
|
||||
+ // CraftBukkit - this.chunks.count() -> .values().size()
|
||||
+ return this.loadedChunkHashMap.values().size();
|
||||
}
|
||||
|
||||
public void recreateStructures(int p_82695_1_, int p_82695_2_) {}
|
||||
+
|
||||
+ // Cauldron start
|
||||
+ private boolean shouldLoadChunk()
|
||||
+ {
|
||||
+ return this.worldObj.findingSpawnPoint ||
|
||||
+ this.loadChunkOnProvideRequest ||
|
||||
+ (MinecraftServer.callingForgeTick && MinecraftServer.getServer().cauldronConfig.loadChunkOnForgeTick.getValue()) ||
|
||||
+ (MinecraftServer.currentTick - initialTick <= 100);
|
||||
+ }
|
||||
+
|
||||
+ public long lastAccessed(int x, int z)
|
||||
+ {
|
||||
+ long chunkHash = LongHash.toLong(x, z);
|
||||
+ if (!loadedChunkHashMap.containsKey(chunkHash)) return 0;
|
||||
+ return loadedChunkHashMap.get(chunkHash).lastAccessedTick;
|
||||
+ }
|
||||
+
|
||||
+ /*private boolean shouldUnloadChunk(Chunk chunk)
|
||||
+ {
|
||||
+ if (chunk == null) return false;
|
||||
+ return MinecraftServer.getServer().getTickCounter() - chunk.lastAccessedTick > CauldronConfig.chunkGCGracePeriod.getValue();
|
||||
+ }*/
|
||||
+ // Cauldron end
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/gen/feature/WorldGenShrub.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/gen/feature/WorldGenShrub.java
|
||||
@@ -62,7 +62,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
+ // CraftBukkit start - Return false if gen was unsuccessful
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return false;
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
|
||||
return true;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/gen/structure/MapGenStronghold.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/gen/structure/MapGenStronghold.java
|
||||
@@ -92,7 +92,17 @@
|
||||
double d1 = (1.25D * (double)l + random.nextDouble()) * this.field_82671_h * (double)l;
|
||||
int j1 = (int)Math.round(Math.cos(d0) * d1);
|
||||
int k1 = (int)Math.round(Math.sin(d0) * d1);
|
||||
- ChunkPosition chunkposition = this.worldObj.getWorldChunkManager().findBiomePosition((j1 << 4) + 8, (k1 << 4) + 8, 112, this.field_151546_e, random);
|
||||
+ // Cauldron start - catch invalid positions
|
||||
+ ChunkPosition chunkposition = null;
|
||||
+ try
|
||||
+ {
|
||||
+ chunkposition = this.worldObj.getWorldChunkManager().findBiomePosition((j1 << 4) + 8, (k1 << 4) + 8, 112, this.field_151546_e, random);
|
||||
+ }
|
||||
+ catch (ArrayIndexOutOfBoundsException e)
|
||||
+ {
|
||||
+ // ignore
|
||||
+ }
|
||||
+ // Cauldron end
|
||||
|
||||
if (chunkposition != null)
|
||||
{
|
@ -0,0 +1,21 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/gen/structure/MapGenStructure.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/gen/structure/MapGenStructure.java
|
||||
@@ -239,8 +239,17 @@
|
||||
{
|
||||
if (this.field_143029_e == null)
|
||||
{
|
||||
- this.field_143029_e = (MapGenStructureData)p_143027_1_.perWorldStorage.loadData(MapGenStructureData.class, this.func_143025_a());
|
||||
+ // Spigot Start
|
||||
+ if (p_143027_1_.getSpigotConfig().saveStructureInfo && !this.func_143025_a().equals("Mineshaft")) // Cauldron
|
||||
+ {
|
||||
+ this.field_143029_e = (MapGenStructureData) p_143027_1_.loadItemData(MapGenStructureData.class, this.func_143025_a());
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ this.field_143029_e = new MapGenStructureData(this.func_143025_a());
|
||||
+ }
|
||||
|
||||
+ // Spigot End
|
||||
if (this.field_143029_e == null)
|
||||
{
|
||||
this.field_143029_e = new MapGenStructureData(this.func_143025_a());
|
@ -0,0 +1,12 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/gen/structure/StructureStart.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/gen/structure/StructureStart.java
|
||||
@@ -41,7 +41,8 @@
|
||||
{
|
||||
StructureComponent structurecomponent = (StructureComponent)iterator.next();
|
||||
|
||||
- if (structurecomponent.getBoundingBox().intersectsWith(p_75068_3_) && !structurecomponent.addComponentParts(p_75068_1_, p_75068_2_, p_75068_3_))
|
||||
+ // Cauldron - validate structurecomponent
|
||||
+ if ((structurecomponent == null || structurecomponent.getBoundingBox() == null) || (structurecomponent.getBoundingBox().intersectsWith(p_75068_3_) && !structurecomponent.addComponentParts(p_75068_1_, p_75068_2_, p_75068_3_)))
|
||||
{
|
||||
iterator.remove();
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/storage/ISaveHandler.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/storage/ISaveHandler.java
|
||||
@@ -27,4 +27,6 @@
|
||||
File getMapFileFromName(String p_75758_1_);
|
||||
|
||||
String getWorldDirectoryName();
|
||||
+
|
||||
+ java.util.UUID getUUID(); // CraftBukkit
|
||||
}
|
116
patches/net/minecraft/world/storage/MapData.java.patch
Normal file
116
patches/net/minecraft/world/storage/MapData.java.patch
Normal file
@ -0,0 +1,116 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/storage/MapData.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/storage/MapData.java
|
||||
@@ -14,6 +14,14 @@
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldSavedData;
|
||||
|
||||
+// CraftBukkit start
|
||||
+import java.util.UUID;
|
||||
+
|
||||
+import org.bukkit.craftbukkit.CraftServer;
|
||||
+import org.bukkit.craftbukkit.CraftWorld;
|
||||
+import org.bukkit.craftbukkit.map.CraftMapView;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public class MapData extends WorldSavedData
|
||||
{
|
||||
public int xCenter;
|
||||
@@ -24,11 +32,21 @@
|
||||
public List playersArrayList = new ArrayList();
|
||||
private Map playersHashMap = new HashMap();
|
||||
public Map playersVisibleOnMap = new LinkedHashMap();
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ public final CraftMapView mapView;
|
||||
+ private CraftServer server;
|
||||
+ private UUID uniqueId = null;
|
||||
+ // CraftBukkit end
|
||||
private static final String __OBFID = "CL_00000577";
|
||||
|
||||
public MapData(String p_i2140_1_)
|
||||
{
|
||||
super(p_i2140_1_);
|
||||
+ // CraftBukkit start
|
||||
+ mapView = new CraftMapView(this);
|
||||
+ server = (CraftServer) org.bukkit.Bukkit.getServer();
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound p_76184_1_)
|
||||
@@ -107,7 +125,7 @@
|
||||
{
|
||||
if (!this.playersHashMap.containsKey(p_76191_1_))
|
||||
{
|
||||
- MapData.MapInfo mapinfo = new MapData.MapInfo(p_76191_1_);
|
||||
+ MapData.MapInfo mapinfo = new MapData.MapInfo(this, p_76191_1_); // Cauldron
|
||||
this.playersHashMap.put(p_76191_1_, mapinfo);
|
||||
this.playersArrayList.add(mapinfo);
|
||||
}
|
||||
@@ -265,7 +283,7 @@
|
||||
|
||||
if (mapinfo == null)
|
||||
{
|
||||
- mapinfo = new MapData.MapInfo(p_82568_1_);
|
||||
+ mapinfo = new MapData.MapInfo(this, p_82568_1_); // Cauldron
|
||||
this.playersHashMap.put(p_82568_1_, mapinfo);
|
||||
this.playersArrayList.add(mapinfo);
|
||||
}
|
||||
@@ -300,10 +318,12 @@
|
||||
private byte[] lastPlayerLocationOnMap;
|
||||
public int field_82569_d;
|
||||
private boolean field_82570_i;
|
||||
+ final MapData mapDataObj; // Cauldron
|
||||
private static final String __OBFID = "CL_00000578";
|
||||
|
||||
- public MapInfo(EntityPlayer p_i2138_2_)
|
||||
+ public MapInfo(MapData mapData, EntityPlayer p_i2138_2_)
|
||||
{
|
||||
+ this.mapDataObj = mapData; // Cauldron
|
||||
this.entityplayerObj = p_i2138_2_;
|
||||
|
||||
for (int i = 0; i < this.field_76209_b.length; ++i)
|
||||
@@ -328,20 +348,37 @@
|
||||
int i;
|
||||
int i1;
|
||||
|
||||
+ // Spigot start
|
||||
+ boolean custom = this.mapDataObj.mapView.renderers.size() > 1 || !(this.mapDataObj.mapView.renderers.get(0) instanceof org.bukkit.craftbukkit.map.CraftMapRenderer);
|
||||
+ org.bukkit.craftbukkit.map.RenderData render = (custom) ? this.mapDataObj.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) entityplayerObj.getBukkitEntity()) : null; // CraftBukkit
|
||||
+
|
||||
if (--this.ticksUntilPlayerLocationMapUpdate < 0)
|
||||
{
|
||||
this.ticksUntilPlayerLocationMapUpdate = 4;
|
||||
- abyte = new byte[MapData.this.playersVisibleOnMap.size() * 3 + 1];
|
||||
+ abyte = new byte[((custom) ? render.cursors.size() : this.mapDataObj.playersVisibleOnMap.size()) * 3 + 1]; // CraftBukkit
|
||||
abyte[0] = 1;
|
||||
i = 0;
|
||||
-
|
||||
- for (Iterator iterator = MapData.this.playersVisibleOnMap.values().iterator(); iterator.hasNext(); ++i)
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+
|
||||
+ // Spigot start
|
||||
+ for (Iterator iterator = ((custom) ? render.cursors.iterator() : this.mapDataObj.playersVisibleOnMap.values().iterator()); iterator.hasNext(); ++i)
|
||||
{
|
||||
- MapData.MapCoord mapcoord = (MapData.MapCoord)iterator.next();
|
||||
- abyte[i * 3 + 1] = (byte)(mapcoord.iconSize << 4 | mapcoord.iconRotation & 15);
|
||||
- abyte[i * 3 + 2] = mapcoord.centerX;
|
||||
- abyte[i * 3 + 3] = mapcoord.centerZ;
|
||||
+ org.bukkit.map.MapCursor cursor = (custom) ? (org.bukkit.map.MapCursor) iterator.next() : null;
|
||||
+
|
||||
+ if (cursor != null && !cursor.isVisible())
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ MapCoord deco = (custom) ? null : (MapCoord) iterator.next();
|
||||
+ abyte[i * 3 + 1] = (byte)(((custom) ? cursor.getRawType() : deco.iconSize) << 4 | ((custom) ? cursor.getDirection() : deco.iconRotation) & 15);
|
||||
+ abyte[i * 3 + 2] = (byte)((custom) ? cursor.getX() : deco.centerX);
|
||||
+ abyte[i * 3 + 3] = (byte)((custom) ? cursor.getY() : deco.centerZ);
|
||||
}
|
||||
+
|
||||
+ // Spigot end
|
||||
+ // CraftBukkit end
|
||||
|
||||
boolean flag = !p_76204_1_.isOnItemFrame();
|
||||
|
233
patches/net/minecraft/world/storage/SaveHandler.java.patch
Normal file
233
patches/net/minecraft/world/storage/SaveHandler.java.patch
Normal file
@ -0,0 +1,233 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/storage/SaveHandler.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/storage/SaveHandler.java
|
||||
@@ -10,6 +10,7 @@
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.StartupQuery;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
+import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -19,6 +20,13 @@
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
+// CraftBukkit start
|
||||
+import java.util.UUID;
|
||||
+
|
||||
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
+// CraftBukkit end
|
||||
+import cpw.mods.fml.common.registry.GameData; // Cauldron
|
||||
+
|
||||
public class SaveHandler implements ISaveHandler, IPlayerFileData
|
||||
{
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
@@ -27,6 +35,8 @@
|
||||
private final File mapDataDir;
|
||||
private final long initializationTime = MinecraftServer.getSystemTimeMillis();
|
||||
private final String saveDirectoryName;
|
||||
+ private UUID uuid = null; // CraftBukkit
|
||||
+ private static boolean initializedBukkit = false; // Cauldron
|
||||
private static final String __OBFID = "CL_00000585";
|
||||
|
||||
public SaveHandler(File p_i2146_1_, String p_i2146_2_, boolean p_i2146_3_)
|
||||
@@ -65,7 +75,7 @@
|
||||
catch (IOException ioexception)
|
||||
{
|
||||
ioexception.printStackTrace();
|
||||
- throw new RuntimeException("Failed to check session lock, aborting");
|
||||
+ throw new RuntimeException("Failed to check session lock for world " + this.worldDirectory + ", aborting"); // Cauldron
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +95,7 @@
|
||||
{
|
||||
if (datainputstream.readLong() != this.initializationTime)
|
||||
{
|
||||
- throw new MinecraftException("The save is being accessed from another location, aborting");
|
||||
+ throw new MinecraftException("The save folder for world " + this.worldDirectory + " is being accessed from another location, aborting"); // Cauldron
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -95,7 +105,10 @@
|
||||
}
|
||||
catch (IOException ioexception)
|
||||
{
|
||||
- throw new MinecraftException("Failed to check session lock, aborting");
|
||||
+ // Cauldron start
|
||||
+ ioexception.printStackTrace();
|
||||
+ throw new MinecraftException("Failed to check session lock for world " + this.worldDirectory + ", aborting");
|
||||
+ // Cauldron end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,6 +133,7 @@
|
||||
nbttagcompound1 = nbttagcompound.getCompoundTag("Data");
|
||||
worldInfo = new WorldInfo(nbttagcompound1);
|
||||
FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound);
|
||||
+ this.initBukkitData(worldInfo); // Cauldron
|
||||
return worldInfo;
|
||||
}
|
||||
catch (StartupQuery.AbortedException e)
|
||||
@@ -143,6 +157,7 @@
|
||||
nbttagcompound1 = nbttagcompound.getCompoundTag("Data");
|
||||
worldInfo = new WorldInfo(nbttagcompound1);
|
||||
FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound);
|
||||
+ this.initBukkitData(worldInfo); // Cauldron
|
||||
return worldInfo;
|
||||
}
|
||||
catch (StartupQuery.AbortedException e)
|
||||
@@ -154,7 +169,7 @@
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
-
|
||||
+ this.initBukkitData(worldInfo); // Cauldron
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -282,6 +297,18 @@
|
||||
|
||||
if (nbttagcompound != null)
|
||||
{
|
||||
+ // CraftBukkit start
|
||||
+ if (p_75752_1_ instanceof EntityPlayerMP)
|
||||
+ {
|
||||
+ CraftPlayer player = (CraftPlayer) p_75752_1_.getBukkitEntity(); // Cauldron
|
||||
+ // Only update first played if it is older than the one we have
|
||||
+ long modified = new File(playersDirectory, p_75752_1_.getCommandSenderName() + ".dat").lastModified();
|
||||
+ if (modified < player.getFirstPlayed()) {
|
||||
+ player.setFirstPlayed(modified);
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
p_75752_1_.readFromNBT(nbttagcompound);
|
||||
}
|
||||
|
||||
@@ -289,6 +316,27 @@
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ public NBTTagCompound getPlayerData(String par1Str)
|
||||
+ {
|
||||
+ try
|
||||
+ {
|
||||
+ File file1 = new File(this.playersDirectory, par1Str + ".dat");
|
||||
+
|
||||
+ if (file1.exists())
|
||||
+ {
|
||||
+ return CompressedStreamTools.readCompressed(new FileInputStream(file1));
|
||||
+ }
|
||||
+ }
|
||||
+ catch (Exception exception)
|
||||
+ {
|
||||
+ logger.warn("Failed to load player data for " + par1Str);
|
||||
+ }
|
||||
+
|
||||
+ return null;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
public IPlayerFileData getSaveHandler()
|
||||
{
|
||||
return this;
|
||||
@@ -320,4 +368,97 @@
|
||||
{
|
||||
return this.saveDirectoryName;
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ public UUID getUUID()
|
||||
+ {
|
||||
+ if (uuid != null)
|
||||
+ {
|
||||
+ return uuid;
|
||||
+ }
|
||||
+
|
||||
+ File file1 = new File(this.worldDirectory, "uid.dat");
|
||||
+
|
||||
+ if (file1.exists())
|
||||
+ {
|
||||
+ DataInputStream dis = null;
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ dis = new DataInputStream(new FileInputStream(file1));
|
||||
+ return uuid = new UUID(dis.readLong(), dis.readLong());
|
||||
+ }
|
||||
+ catch (IOException ex)
|
||||
+ {
|
||||
+ logger.warn("Failed to read " + file1 + ", generating new random UUID", ex);
|
||||
+ }
|
||||
+ finally
|
||||
+ {
|
||||
+ if (dis != null)
|
||||
+ {
|
||||
+ try
|
||||
+ {
|
||||
+ dis.close();
|
||||
+ }
|
||||
+ catch (IOException ex)
|
||||
+ {
|
||||
+ // NOOP
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ uuid = UUID.randomUUID();
|
||||
+ DataOutputStream dos = null;
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ dos = new DataOutputStream(new FileOutputStream(file1));
|
||||
+ dos.writeLong(uuid.getMostSignificantBits());
|
||||
+ dos.writeLong(uuid.getLeastSignificantBits());
|
||||
+ }
|
||||
+ catch (IOException ex)
|
||||
+ {
|
||||
+ logger.warn("Failed to write " + file1, ex);
|
||||
+ }
|
||||
+ finally
|
||||
+ {
|
||||
+ if (dos != null)
|
||||
+ {
|
||||
+ try
|
||||
+ {
|
||||
+ dos.close();
|
||||
+ }
|
||||
+ catch (IOException ex)
|
||||
+ {
|
||||
+ // NOOP
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return uuid;
|
||||
+ }
|
||||
+
|
||||
+ public File getPlayerDir()
|
||||
+ {
|
||||
+ return playersDirectory;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ // Cauldron start
|
||||
+ public void initBukkitData(WorldInfo worldInfo)
|
||||
+ {
|
||||
+ // inject bukkit materials before plugins load
|
||||
+ if (!this.initializedBukkit && (worldInfo == null || worldInfo.getDimension() == 0))
|
||||
+ {
|
||||
+ GameData.injectBlockBukkitMaterials();
|
||||
+ GameData.injectItemBukkitMaterials();
|
||||
+ // since we modify bukkit enums, we need to guarantee that plugins are
|
||||
+ // loaded after all mods have been loaded by FML to avoid race conditions.
|
||||
+ MinecraftServer.getServer().server.loadPlugins();
|
||||
+ MinecraftServer.getServer().server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP);
|
||||
+ this.initializedBukkit = true;
|
||||
+ }
|
||||
+ }
|
||||
+ // Cauldron end
|
||||
}
|
24
patches/net/minecraft/world/storage/SaveHandlerMP.java.patch
Normal file
24
patches/net/minecraft/world/storage/SaveHandlerMP.java.patch
Normal file
@ -0,0 +1,24 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/storage/SaveHandlerMP.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/storage/SaveHandlerMP.java
|
||||
@@ -3,6 +3,8 @@
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import java.io.File;
|
||||
+import java.util.UUID;
|
||||
+
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.MinecraftException;
|
||||
import net.minecraft.world.WorldProvider;
|
||||
@@ -50,4 +52,12 @@
|
||||
{
|
||||
return null;
|
||||
}
|
||||
+
|
||||
+ // Cauldron start
|
||||
+ @Override
|
||||
+ public UUID getUUID()
|
||||
+ {
|
||||
+ return this.getUUID();
|
||||
+ }
|
||||
+ // Cauldron end
|
||||
}
|
48
patches/net/minecraft/world/storage/WorldInfo.java.patch
Normal file
48
patches/net/minecraft/world/storage/WorldInfo.java.patch
Normal file
@ -0,0 +1,48 @@
|
||||
--- ../src-base/minecraft/net/minecraft/world/storage/WorldInfo.java
|
||||
+++ ../src-work/minecraft/net/minecraft/world/storage/WorldInfo.java
|
||||
@@ -117,6 +117,7 @@
|
||||
this.thunderTime = p_i2157_1_.getInteger("thunderTime");
|
||||
this.thundering = p_i2157_1_.getBoolean("thundering");
|
||||
this.hardcore = p_i2157_1_.getBoolean("hardcore");
|
||||
+ this.dimension = p_i2157_1_.getInteger("dimension"); // Cauldron
|
||||
|
||||
if (p_i2157_1_.hasKey("initialized", 99))
|
||||
{
|
||||
@@ -193,6 +194,7 @@
|
||||
this.allowCommands = p_i2159_1_.allowCommands;
|
||||
this.initialized = p_i2159_1_.initialized;
|
||||
this.theGameRules = p_i2159_1_.theGameRules;
|
||||
+ this.dimension = p_i2159_1_.dimension; // Cauldron
|
||||
}
|
||||
|
||||
public NBTTagCompound getNBTTagCompound()
|
||||
@@ -234,6 +236,7 @@
|
||||
p_76064_1_.setBoolean("allowCommands", this.allowCommands);
|
||||
p_76064_1_.setBoolean("initialized", this.initialized);
|
||||
p_76064_1_.setTag("GameRules", this.theGameRules.writeGameRulesToNBT());
|
||||
+ p_76064_1_.setInteger("dimension", this.dimension); // Cauldron
|
||||
|
||||
if (p_76064_2_ != null)
|
||||
{
|
||||
@@ -282,6 +285,21 @@
|
||||
return this.playerTag;
|
||||
}
|
||||
|
||||
+ // Cauldron start
|
||||
+ /**
|
||||
+ * Sets the Dimension.
|
||||
+ */
|
||||
+ public void setDimension(int dim)
|
||||
+ {
|
||||
+ this.dimension = dim;
|
||||
+ }
|
||||
+
|
||||
+ public int getDimension()
|
||||
+ {
|
||||
+ return this.dimension;
|
||||
+ }
|
||||
+ // Cauldron end
|
||||
+
|
||||
public int getVanillaDimension()
|
||||
{
|
||||
return this.dimension;
|
Reference in New Issue
Block a user