Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-12-18 20:40:08 +01:00
SPIGOT-4752: Fixed inconsistency between isChunkLoaded and chunk load/unload events
Dieser Commit ist enthalten in:
Ursprung
3f9f31c3ce
Commit
8d0f37228d
@ -1,32 +1,18 @@
|
|||||||
--- a/net/minecraft/server/Chunk.java
|
--- a/net/minecraft/server/Chunk.java
|
||||||
+++ b/net/minecraft/server/Chunk.java
|
+++ b/net/minecraft/server/Chunk.java
|
||||||
@@ -22,6 +22,13 @@
|
@@ -95,8 +95,19 @@
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
+// CraftBukkit start
|
|
||||||
+import com.google.common.collect.Lists;
|
|
||||||
+import java.util.LinkedList;
|
|
||||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
|
||||||
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
||||||
+// CraftBukkit end
|
|
||||||
+
|
|
||||||
public class Chunk implements IChunkAccess {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
|
||||||
@@ -95,8 +102,19 @@
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this);
|
+ this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this);
|
||||||
+ }
|
}
|
||||||
+
|
|
||||||
+ public org.bukkit.Chunk bukkitChunk;
|
+ public org.bukkit.Chunk bukkitChunk;
|
||||||
+ public org.bukkit.Chunk getBukkitChunk() {
|
+ public org.bukkit.Chunk getBukkitChunk() {
|
||||||
+ return bukkitChunk;
|
+ return bukkitChunk;
|
||||||
}
|
+ }
|
||||||
|
+
|
||||||
+ public boolean mustNotSave;
|
+ public boolean mustNotSave;
|
||||||
+ public boolean needsDecoration;
|
+ public boolean needsDecoration;
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
@ -34,7 +20,7 @@
|
|||||||
public Chunk(World world, ProtoChunk protochunk) {
|
public Chunk(World world, ProtoChunk protochunk) {
|
||||||
this(world, protochunk.getPos(), protochunk.getBiomeIndex(), protochunk.p(), protochunk.n(), protochunk.o(), protochunk.q(), protochunk.getSections(), (Consumer) null);
|
this(world, protochunk.getPos(), protochunk.getBiomeIndex(), protochunk.p(), protochunk.n(), protochunk.o(), protochunk.q(), protochunk.getSections(), (Consumer) null);
|
||||||
Iterator iterator = protochunk.y().iterator();
|
Iterator iterator = protochunk.y().iterator();
|
||||||
@@ -138,6 +156,7 @@
|
@@ -138,6 +149,7 @@
|
||||||
|
|
||||||
this.b(protochunk.r());
|
this.b(protochunk.r());
|
||||||
this.s = true;
|
this.s = true;
|
||||||
@ -42,7 +28,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -228,9 +247,16 @@
|
@@ -228,9 +240,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +45,7 @@
|
|||||||
int i = blockposition.getX() & 15;
|
int i = blockposition.getX() & 15;
|
||||||
int j = blockposition.getY();
|
int j = blockposition.getY();
|
||||||
int k = blockposition.getZ() & 15;
|
int k = blockposition.getZ() & 15;
|
||||||
@@ -282,7 +308,8 @@
|
@@ -282,7 +301,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +55,7 @@
|
|||||||
iblockdata.onPlace(this.world, blockposition, iblockdata1, flag);
|
iblockdata.onPlace(this.world, blockposition, iblockdata1, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +409,12 @@
|
@@ -382,7 +402,12 @@
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public TileEntity a(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) {
|
public TileEntity a(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) {
|
||||||
@ -83,7 +69,7 @@
|
|||||||
|
|
||||||
if (tileentity == null) {
|
if (tileentity == null) {
|
||||||
NBTTagCompound nbttagcompound = (NBTTagCompound) this.e.remove(blockposition);
|
NBTTagCompound nbttagcompound = (NBTTagCompound) this.e.remove(blockposition);
|
||||||
@@ -429,6 +461,13 @@
|
@@ -429,6 +454,13 @@
|
||||||
tileentity1.m();
|
tileentity1.m();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +83,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,6 +496,41 @@
|
@@ -457,6 +489,50 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +99,7 @@
|
|||||||
+ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(this.bukkitChunk, this.needsDecoration));
|
+ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(this.bukkitChunk, this.needsDecoration));
|
||||||
+
|
+
|
||||||
+ if (this.needsDecoration) {
|
+ if (this.needsDecoration) {
|
||||||
|
+ this.needsDecoration = false;
|
||||||
+ java.util.Random random = new java.util.Random();
|
+ java.util.Random random = new java.util.Random();
|
||||||
+ random.setSeed(world.getSeed());
|
+ random.setSeed(world.getSeed());
|
||||||
+ long xRand = random.nextLong() / 2L * 2L + 1L;
|
+ long xRand = random.nextLong() / 2L * 2L + 1L;
|
||||||
@ -134,12 +121,20 @@
|
|||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ public void unloadCallback() {
|
||||||
|
+ org.bukkit.Server server = this.world.getServer();
|
||||||
|
+ org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(this.bukkitChunk, this.isNeedsSaving());
|
||||||
|
+ server.getPluginManager().callEvent(unloadEvent);
|
||||||
|
+ // note: saving can be prevented, but not forced if no saving is actually required
|
||||||
|
+ this.mustNotSave = !unloadEvent.isSaveChunk();
|
||||||
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+
|
+
|
||||||
public void markDirty() {
|
public void markDirty() {
|
||||||
this.s = true;
|
this.s = true;
|
||||||
}
|
}
|
||||||
@@ -531,7 +605,7 @@
|
@@ -531,7 +607,7 @@
|
||||||
Iterator iterator = this.entitySlices[k].a(oclass).iterator();
|
Iterator iterator = this.entitySlices[k].a(oclass).iterator();
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
@ -148,7 +143,7 @@
|
|||||||
|
|
||||||
if (t0.getBoundingBox().c(axisalignedbb) && (predicate == null || predicate.test(t0))) {
|
if (t0.getBoundingBox().c(axisalignedbb) && (predicate == null || predicate.test(t0))) {
|
||||||
list.add(t0);
|
list.add(t0);
|
||||||
@@ -605,7 +679,7 @@
|
@@ -605,7 +681,7 @@
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNeedsSaving() {
|
public boolean isNeedsSaving() {
|
||||||
@ -157,7 +152,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void d(boolean flag) {
|
public void d(boolean flag) {
|
||||||
@@ -746,7 +820,7 @@
|
@@ -746,7 +822,7 @@
|
||||||
|
|
||||||
public void B() {
|
public void B() {
|
||||||
if (this.o instanceof ProtoChunkTickList) {
|
if (this.o instanceof ProtoChunkTickList) {
|
||||||
@ -166,7 +161,7 @@
|
|||||||
return this.getType(blockposition).getBlock();
|
return this.getType(blockposition).getBlock();
|
||||||
});
|
});
|
||||||
this.o = TickListEmpty.a();
|
this.o = TickListEmpty.a();
|
||||||
@@ -756,7 +830,7 @@
|
@@ -756,7 +832,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.p instanceof ProtoChunkTickList) {
|
if (this.p instanceof ProtoChunkTickList) {
|
||||||
@ -175,7 +170,7 @@
|
|||||||
return this.getFluid(blockposition).getType();
|
return this.getFluid(blockposition).getType();
|
||||||
});
|
});
|
||||||
this.p = TickListEmpty.a();
|
this.p = TickListEmpty.a();
|
||||||
@@ -768,12 +842,12 @@
|
@@ -768,12 +844,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void a(WorldServer worldserver) {
|
public void a(WorldServer worldserver) {
|
||||||
|
@ -1,6 +1,49 @@
|
|||||||
--- a/net/minecraft/server/ChunkProviderServer.java
|
--- a/net/minecraft/server/ChunkProviderServer.java
|
||||||
+++ b/net/minecraft/server/ChunkProviderServer.java
|
+++ b/net/minecraft/server/ChunkProviderServer.java
|
||||||
@@ -241,6 +241,17 @@
|
@@ -81,7 +81,7 @@
|
||||||
|
for (int l = 0; l < 4; ++l) {
|
||||||
|
if (k == this.n[l] && chunkstatus == this.o[l]) {
|
||||||
|
ichunkaccess = this.p[l];
|
||||||
|
- if (ichunkaccess != null || !flag) {
|
||||||
|
+ if (ichunkaccess != null) { // CraftBukkit - the chunk can become accessible in the meantime TODO for non-null chunks it might also make sense to check that the chunk's state hasn't changed in the meantime
|
||||||
|
return ichunkaccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -125,7 +125,15 @@
|
||||||
|
int l = 33 + ChunkStatus.a(chunkstatus);
|
||||||
|
PlayerChunk playerchunk = this.getChunk(k);
|
||||||
|
|
||||||
|
- if (flag) {
|
||||||
|
+ // CraftBukkit start - don't add new ticket for currently unloading chunk
|
||||||
|
+ boolean currentlyUnloading = false;
|
||||||
|
+ if (playerchunk != null) {
|
||||||
|
+ PlayerChunk.State oldChunkState = PlayerChunk.c(playerchunk.oldTicketLevel); // PAIL getChunkState
|
||||||
|
+ PlayerChunk.State currentChunkState = PlayerChunk.c(playerchunk.getTicketLevel()); // PAIL getChunkState
|
||||||
|
+ currentlyUnloading = (oldChunkState.a(PlayerChunk.State.BORDER) && !currentChunkState.a(PlayerChunk.State.BORDER)); // PAIL isAtLeast
|
||||||
|
+ }
|
||||||
|
+ if (flag && !currentlyUnloading) {
|
||||||
|
+ // CraftBukkit end
|
||||||
|
this.chunkMapDistance.a(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair);
|
||||||
|
if (this.a(playerchunk, l)) {
|
||||||
|
GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler();
|
||||||
|
@@ -144,14 +152,14 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean a(@Nullable PlayerChunk playerchunk, int i) {
|
||||||
|
- return playerchunk == null || playerchunk.getTicketLevel() > i;
|
||||||
|
+ return playerchunk == null || playerchunk.oldTicketLevel > i; // CraftBukkit using oldTicketLevel for isLoaded checks
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLoaded(int i, int j) {
|
||||||
|
PlayerChunk playerchunk = this.getChunk((new ChunkCoordIntPair(i, j)).pair());
|
||||||
|
int k = 33 + ChunkStatus.a(ChunkStatus.FULL);
|
||||||
|
|
||||||
|
- return playerchunk != null && playerchunk.getTicketLevel() <= k ? ((Either) playerchunk.getStatusFuture(ChunkStatus.FULL).getNow(PlayerChunk.UNLOADED_CHUNK_ACCESS)).left().isPresent() : false;
|
||||||
|
+ return playerchunk != null && playerchunk.oldTicketLevel <= k ? ((Either) playerchunk.getStatusFuture(ChunkStatus.FULL).getNow(PlayerChunk.UNLOADED_CHUNK_ACCESS)).left().isPresent() : false; // CraftBukkit using oldTicketLevel for isLoaded checks
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@@ -241,6 +249,18 @@
|
||||||
this.playerChunkMap.close();
|
this.playerChunkMap.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12,13 +55,14 @@
|
|||||||
+ this.world.getMethodProfiler().exitEnter("unload");
|
+ this.world.getMethodProfiler().exitEnter("unload");
|
||||||
+ this.playerChunkMap.unloadChunks(() -> true);
|
+ this.playerChunkMap.unloadChunks(() -> true);
|
||||||
+ this.world.getMethodProfiler().exit();
|
+ this.world.getMethodProfiler().exit();
|
||||||
|
+ this.l(); // PAIL clearCache
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+
|
+
|
||||||
public void tick(BooleanSupplier booleansupplier) {
|
public void tick(BooleanSupplier booleansupplier) {
|
||||||
this.world.getMethodProfiler().enter("purge");
|
this.world.getMethodProfiler().enter("purge");
|
||||||
this.chunkMapDistance.purgeTickets();
|
this.chunkMapDistance.purgeTickets();
|
||||||
@@ -260,13 +271,13 @@
|
@@ -260,13 +280,13 @@
|
||||||
this.lastTickTime = i;
|
this.lastTickTime = i;
|
||||||
WorldData worlddata = this.world.getWorldData();
|
WorldData worlddata = this.world.getWorldData();
|
||||||
boolean flag = worlddata.getType() == WorldType.DEBUG_ALL_BLOCK_STATES;
|
boolean flag = worlddata.getType() == WorldType.DEBUG_ALL_BLOCK_STATES;
|
||||||
@ -34,7 +78,7 @@
|
|||||||
|
|
||||||
this.world.getMethodProfiler().enter("naturalSpawnCount");
|
this.world.getMethodProfiler().enter("naturalSpawnCount");
|
||||||
int l = this.chunkMapDistance.b();
|
int l = this.chunkMapDistance.b();
|
||||||
@@ -299,8 +310,30 @@
|
@@ -299,8 +319,30 @@
|
||||||
for (int j1 = 0; j1 < i1; ++j1) {
|
for (int j1 = 0; j1 < i1; ++j1) {
|
||||||
EnumCreatureType enumcreaturetype = aenumcreaturetype1[j1];
|
EnumCreatureType enumcreaturetype = aenumcreaturetype1[j1];
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
protected static final Logger LOGGER = LogManager.getLogger();
|
protected static final Logger LOGGER = LogManager.getLogger();
|
||||||
private static final AtomicInteger entityCount = new AtomicInteger();
|
private static final AtomicInteger entityCount = new AtomicInteger();
|
||||||
private static final List<ItemStack> c = Collections.emptyList();
|
private static final List<ItemStack> c = Collections.emptyList();
|
||||||
@@ -106,6 +155,16 @@
|
@@ -106,6 +155,20 @@
|
||||||
private long aH;
|
private long aH;
|
||||||
private EntitySize size;
|
private EntitySize size;
|
||||||
private float headHeight;
|
private float headHeight;
|
||||||
@ -71,11 +71,15 @@
|
|||||||
+ public float getBukkitYaw() {
|
+ public float getBukkitYaw() {
|
||||||
+ return this.yaw;
|
+ return this.yaw;
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ public boolean isChunkLoaded() {
|
||||||
|
+ return world.isChunkLoaded((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4);
|
||||||
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
|
|
||||||
public Entity(EntityTypes<?> entitytypes, World world) {
|
public Entity(EntityTypes<?> entitytypes, World world) {
|
||||||
this.id = Entity.entityCount.incrementAndGet();
|
this.id = Entity.entityCount.incrementAndGet();
|
||||||
@@ -204,6 +263,12 @@
|
@@ -204,6 +267,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setPose(EntityPose entitypose) {
|
protected void setPose(EntityPose entitypose) {
|
||||||
@ -88,7 +92,7 @@
|
|||||||
this.datawatcher.set(Entity.POSE, entitypose);
|
this.datawatcher.set(Entity.POSE, entitypose);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +277,33 @@
|
@@ -212,6 +281,33 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setYawPitch(float f, float f1) {
|
protected void setYawPitch(float f, float f1) {
|
||||||
@ -122,7 +126,7 @@
|
|||||||
this.yaw = f % 360.0F;
|
this.yaw = f % 360.0F;
|
||||||
this.pitch = f1 % 360.0F;
|
this.pitch = f1 % 360.0F;
|
||||||
}
|
}
|
||||||
@@ -224,6 +316,7 @@
|
@@ -224,6 +320,7 @@
|
||||||
float f1 = this.size.height;
|
float f1 = this.size.height;
|
||||||
|
|
||||||
this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f));
|
this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f));
|
||||||
@ -130,7 +134,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
@@ -234,6 +327,15 @@
|
@@ -234,6 +331,15 @@
|
||||||
this.entityBaseTick();
|
this.entityBaseTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +150,7 @@
|
|||||||
public void entityBaseTick() {
|
public void entityBaseTick() {
|
||||||
this.world.getMethodProfiler().enter("entityBaseTick");
|
this.world.getMethodProfiler().enter("entityBaseTick");
|
||||||
if (this.isPassenger() && this.getVehicle().dead) {
|
if (this.isPassenger() && this.getVehicle().dead) {
|
||||||
@@ -250,7 +352,7 @@
|
@@ -250,7 +356,7 @@
|
||||||
this.lastZ = this.locZ;
|
this.lastZ = this.locZ;
|
||||||
this.lastPitch = this.pitch;
|
this.lastPitch = this.pitch;
|
||||||
this.lastYaw = this.yaw;
|
this.lastYaw = this.yaw;
|
||||||
@ -155,7 +159,7 @@
|
|||||||
this.az();
|
this.az();
|
||||||
this.m();
|
this.m();
|
||||||
if (this.world.isClientSide) {
|
if (this.world.isClientSide) {
|
||||||
@@ -300,12 +402,44 @@
|
@@ -300,12 +406,44 @@
|
||||||
|
|
||||||
protected void burnFromLava() {
|
protected void burnFromLava() {
|
||||||
if (!this.isFireProof()) {
|
if (!this.isFireProof()) {
|
||||||
@ -201,7 +205,7 @@
|
|||||||
int j = i * 20;
|
int j = i * 20;
|
||||||
|
|
||||||
if (this instanceof EntityLiving) {
|
if (this instanceof EntityLiving) {
|
||||||
@@ -401,6 +535,28 @@
|
@@ -401,6 +539,28 @@
|
||||||
block1.a((IBlockAccess) this.world, this);
|
block1.a((IBlockAccess) this.world, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +234,7 @@
|
|||||||
if (this.playStepSound() && (!this.onGround || !this.isSneaking() || !(this instanceof EntityHuman)) && !this.isPassenger()) {
|
if (this.playStepSound() && (!this.onGround || !this.isSneaking() || !(this instanceof EntityHuman)) && !this.isPassenger()) {
|
||||||
double d0 = vec3d1.x;
|
double d0 = vec3d1.x;
|
||||||
double d1 = vec3d1.y;
|
double d1 = vec3d1.y;
|
||||||
@@ -454,7 +610,14 @@
|
@@ -454,7 +614,14 @@
|
||||||
if (!flag) {
|
if (!flag) {
|
||||||
++this.fireTicks;
|
++this.fireTicks;
|
||||||
if (this.fireTicks == 0) {
|
if (this.fireTicks == 0) {
|
||||||
@ -246,7 +250,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,7 +728,7 @@
|
@@ -565,7 +732,7 @@
|
||||||
VoxelShape voxelshape = this.world.getWorldBorder().a();
|
VoxelShape voxelshape = this.world.getWorldBorder().a();
|
||||||
Stream<VoxelShape> stream = VoxelShapes.c(voxelshape, VoxelShapes.a(axisalignedbb.shrink(1.0E-7D)), OperatorBoolean.AND) ? Stream.empty() : Stream.of(voxelshape);
|
Stream<VoxelShape> stream = VoxelShapes.c(voxelshape, VoxelShapes.a(axisalignedbb.shrink(1.0E-7D)), OperatorBoolean.AND) ? Stream.empty() : Stream.of(voxelshape);
|
||||||
AxisAlignedBB axisalignedbb1 = axisalignedbb.a(vec3d).g(1.0E-7D);
|
AxisAlignedBB axisalignedbb1 = axisalignedbb.a(vec3d).g(1.0E-7D);
|
||||||
@ -255,7 +259,7 @@
|
|||||||
return !this.x(entity);
|
return !this.x(entity);
|
||||||
}).flatMap((entity) -> {
|
}).flatMap((entity) -> {
|
||||||
return Stream.of(entity.ap(), this.j(entity));
|
return Stream.of(entity.ap(), this.j(entity));
|
||||||
@@ -649,6 +812,7 @@
|
@@ -649,6 +816,7 @@
|
||||||
this.locX = (axisalignedbb.minX + axisalignedbb.maxX) / 2.0D;
|
this.locX = (axisalignedbb.minX + axisalignedbb.maxX) / 2.0D;
|
||||||
this.locY = axisalignedbb.minY;
|
this.locY = axisalignedbb.minY;
|
||||||
this.locZ = (axisalignedbb.minZ + axisalignedbb.maxZ) / 2.0D;
|
this.locZ = (axisalignedbb.minZ + axisalignedbb.maxZ) / 2.0D;
|
||||||
@ -263,7 +267,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected SoundEffect getSoundSwim() {
|
protected SoundEffect getSoundSwim() {
|
||||||
@@ -820,7 +984,7 @@
|
@@ -820,7 +988,7 @@
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +276,7 @@
|
|||||||
if (!this.isFireProof()) {
|
if (!this.isFireProof()) {
|
||||||
this.damageEntity(DamageSource.FIRE, (float) i);
|
this.damageEntity(DamageSource.FIRE, (float) i);
|
||||||
}
|
}
|
||||||
@@ -1053,6 +1217,13 @@
|
@@ -1053,6 +1221,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spawnIn(World world) {
|
public void spawnIn(World world) {
|
||||||
@ -286,7 +290,7 @@
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1078,6 +1249,7 @@
|
@@ -1078,6 +1253,7 @@
|
||||||
this.lastYaw -= 360.0F;
|
this.lastYaw -= 360.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +298,7 @@
|
|||||||
this.setPosition(this.locX, this.locY, this.locZ);
|
this.setPosition(this.locX, this.locY, this.locZ);
|
||||||
this.setYawPitch(f, f1);
|
this.setYawPitch(f, f1);
|
||||||
}
|
}
|
||||||
@@ -1246,7 +1418,7 @@
|
@@ -1246,7 +1422,7 @@
|
||||||
public boolean c(NBTTagCompound nbttagcompound) {
|
public boolean c(NBTTagCompound nbttagcompound) {
|
||||||
String s = this.getSaveID();
|
String s = this.getSaveID();
|
||||||
|
|
||||||
@ -303,7 +307,7 @@
|
|||||||
nbttagcompound.setString("id", s);
|
nbttagcompound.setString("id", s);
|
||||||
this.save(nbttagcompound);
|
this.save(nbttagcompound);
|
||||||
return true;
|
return true;
|
||||||
@@ -1265,15 +1437,33 @@
|
@@ -1265,15 +1441,33 @@
|
||||||
Vec3D vec3d = this.getMot();
|
Vec3D vec3d = this.getMot();
|
||||||
|
|
||||||
nbttagcompound.set("Motion", this.a(vec3d.x, vec3d.y, vec3d.z));
|
nbttagcompound.set("Motion", this.a(vec3d.x, vec3d.y, vec3d.z));
|
||||||
@ -338,7 +342,7 @@
|
|||||||
IChatBaseComponent ichatbasecomponent = this.getCustomName();
|
IChatBaseComponent ichatbasecomponent = this.getCustomName();
|
||||||
|
|
||||||
if (ichatbasecomponent != null) {
|
if (ichatbasecomponent != null) {
|
||||||
@@ -1331,6 +1521,11 @@
|
@@ -1331,6 +1525,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +354,7 @@
|
|||||||
return nbttagcompound;
|
return nbttagcompound;
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
CrashReport crashreport = CrashReport.a(throwable, "Saving entity NBT");
|
CrashReport crashreport = CrashReport.a(throwable, "Saving entity NBT");
|
||||||
@@ -1371,7 +1566,7 @@
|
@@ -1371,7 +1570,7 @@
|
||||||
this.setAirTicks(nbttagcompound.getShort("Air"));
|
this.setAirTicks(nbttagcompound.getShort("Air"));
|
||||||
this.onGround = nbttagcompound.getBoolean("OnGround");
|
this.onGround = nbttagcompound.getBoolean("OnGround");
|
||||||
if (nbttagcompound.hasKey("Dimension")) {
|
if (nbttagcompound.hasKey("Dimension")) {
|
||||||
@ -359,7 +363,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.invulnerable = nbttagcompound.getBoolean("Invulnerable");
|
this.invulnerable = nbttagcompound.getBoolean("Invulnerable");
|
||||||
@@ -1414,6 +1609,42 @@
|
@@ -1414,6 +1613,42 @@
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Entity has invalid position");
|
throw new IllegalStateException("Entity has invalid position");
|
||||||
}
|
}
|
||||||
@ -402,7 +406,7 @@
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
CrashReport crashreport = CrashReport.a(throwable, "Loading entity NBT");
|
CrashReport crashreport = CrashReport.a(throwable, "Loading entity NBT");
|
||||||
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being loaded");
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being loaded");
|
||||||
@@ -1489,9 +1720,22 @@
|
@@ -1489,9 +1724,22 @@
|
||||||
} else if (this.world.isClientSide) {
|
} else if (this.world.isClientSide) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@ -425,7 +429,7 @@
|
|||||||
this.world.addEntity(entityitem);
|
this.world.addEntity(entityitem);
|
||||||
return entityitem;
|
return entityitem;
|
||||||
}
|
}
|
||||||
@@ -1595,7 +1839,7 @@
|
@@ -1595,7 +1843,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.vehicle = entity;
|
this.vehicle = entity;
|
||||||
@ -434,7 +438,7 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1620,15 +1864,36 @@
|
@@ -1620,15 +1868,36 @@
|
||||||
Entity entity = this.vehicle;
|
Entity entity = this.vehicle;
|
||||||
|
|
||||||
this.vehicle = null;
|
this.vehicle = null;
|
||||||
@ -473,7 +477,7 @@
|
|||||||
if (!this.world.isClientSide && entity instanceof EntityHuman && !(this.getRidingPassenger() instanceof EntityHuman)) {
|
if (!this.world.isClientSide && entity instanceof EntityHuman && !(this.getRidingPassenger() instanceof EntityHuman)) {
|
||||||
this.passengers.add(0, entity);
|
this.passengers.add(0, entity);
|
||||||
} else {
|
} else {
|
||||||
@@ -1636,15 +1901,33 @@
|
@@ -1636,15 +1905,33 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -508,7 +512,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean q(Entity entity) {
|
protected boolean q(Entity entity) {
|
||||||
@@ -1687,11 +1970,17 @@
|
@@ -1687,11 +1974,17 @@
|
||||||
int i = this.ab();
|
int i = this.ab();
|
||||||
|
|
||||||
if (this.ai) {
|
if (this.ai) {
|
||||||
@ -528,7 +532,7 @@
|
|||||||
this.world.getMethodProfiler().exit();
|
this.world.getMethodProfiler().exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1771,6 +2060,13 @@
|
@@ -1771,6 +2064,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSwimming(boolean flag) {
|
public void setSwimming(boolean flag) {
|
||||||
@ -542,7 +546,7 @@
|
|||||||
this.setFlag(4, flag);
|
this.setFlag(4, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1831,16 +2127,56 @@
|
@@ -1831,16 +2131,56 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAirTicks(int i) {
|
public void setAirTicks(int i) {
|
||||||
@ -577,8 +581,9 @@
|
|||||||
+ this.setOnFire(entityCombustEvent.getDuration(), false);
|
+ this.setOnFire(entityCombustEvent.getDuration(), false);
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+ }
|
}
|
||||||
+
|
|
||||||
|
- this.damageEntity(DamageSource.LIGHTNING, 5.0F);
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ if (thisBukkitEntity instanceof Hanging) {
|
+ if (thisBukkitEntity instanceof Hanging) {
|
||||||
+ HangingBreakByEntityEvent hangingEvent = new HangingBreakByEntityEvent((Hanging) thisBukkitEntity, stormBukkitEntity);
|
+ HangingBreakByEntityEvent hangingEvent = new HangingBreakByEntityEvent((Hanging) thisBukkitEntity, stormBukkitEntity);
|
||||||
@ -587,9 +592,8 @@
|
|||||||
+ if (hangingEvent.isCancelled()) {
|
+ if (hangingEvent.isCancelled()) {
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
}
|
+ }
|
||||||
|
+
|
||||||
- this.damageEntity(DamageSource.LIGHTNING, 5.0F);
|
|
||||||
+ if (this.isFireProof()) {
|
+ if (this.isFireProof()) {
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
@ -602,7 +606,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void j(boolean flag) {
|
public void j(boolean flag) {
|
||||||
@@ -1988,20 +2324,33 @@
|
@@ -1988,20 +2328,33 @@
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Entity a(DimensionManager dimensionmanager) {
|
public Entity a(DimensionManager dimensionmanager) {
|
||||||
@ -639,7 +643,7 @@
|
|||||||
if (dimensionmanager1 == DimensionManager.THE_END && dimensionmanager == DimensionManager.OVERWORLD) {
|
if (dimensionmanager1 == DimensionManager.THE_END && dimensionmanager == DimensionManager.OVERWORLD) {
|
||||||
blockposition = worldserver1.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver1.getSpawn());
|
blockposition = worldserver1.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver1.getSpawn());
|
||||||
} else if (dimensionmanager == DimensionManager.THE_END) {
|
} else if (dimensionmanager == DimensionManager.THE_END) {
|
||||||
@@ -2039,6 +2388,25 @@
|
@@ -2039,6 +2392,25 @@
|
||||||
vec3d = shapedetector_c.b;
|
vec3d = shapedetector_c.b;
|
||||||
f = (float) shapedetector_c.c;
|
f = (float) shapedetector_c.c;
|
||||||
}
|
}
|
||||||
@ -665,7 +669,7 @@
|
|||||||
|
|
||||||
this.world.getMethodProfiler().exitEnter("reloading");
|
this.world.getMethodProfiler().exitEnter("reloading");
|
||||||
Entity entity = this.getEntityType().a((World) worldserver1);
|
Entity entity = this.getEntityType().a((World) worldserver1);
|
||||||
@@ -2048,6 +2416,14 @@
|
@@ -2048,6 +2420,14 @@
|
||||||
entity.setPositionRotation(blockposition, entity.yaw + f, entity.pitch);
|
entity.setPositionRotation(blockposition, entity.yaw + f, entity.pitch);
|
||||||
entity.setMot(vec3d);
|
entity.setMot(vec3d);
|
||||||
worldserver1.addEntityTeleport(entity);
|
worldserver1.addEntityTeleport(entity);
|
||||||
@ -680,7 +684,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.dead = true;
|
this.dead = true;
|
||||||
@@ -2239,7 +2615,26 @@
|
@@ -2239,7 +2619,26 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void a(AxisAlignedBB axisalignedbb) {
|
public void a(AxisAlignedBB axisalignedbb) {
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
--- a/net/minecraft/server/PlayerChunk.java
|
--- a/net/minecraft/server/PlayerChunk.java
|
||||||
+++ b/net/minecraft/server/PlayerChunk.java
|
+++ b/net/minecraft/server/PlayerChunk.java
|
||||||
|
@@ -23,7 +23,7 @@
|
||||||
|
private volatile CompletableFuture<Either<Chunk, PlayerChunk.Failure>> tickingFuture;
|
||||||
|
private volatile CompletableFuture<Either<Chunk, PlayerChunk.Failure>> entityTickingFuture;
|
||||||
|
private CompletableFuture<IChunkAccess> chunkSave;
|
||||||
|
- private int oldTicketLevel;
|
||||||
|
+ public int oldTicketLevel; // CraftBukkit - public
|
||||||
|
private int ticketLevel;
|
||||||
|
private int n;
|
||||||
|
private final ChunkCoordIntPair location;
|
||||||
@@ -43,7 +43,7 @@
|
@@ -43,7 +43,7 @@
|
||||||
this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||||
this.tickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
this.tickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||||
@ -9,7 +18,31 @@
|
|||||||
this.dirtyBlocks = new short[64];
|
this.dirtyBlocks = new short[64];
|
||||||
this.location = chunkcoordintpair;
|
this.location = chunkcoordintpair;
|
||||||
this.lightEngine = lightengine;
|
this.lightEngine = lightengine;
|
||||||
@@ -76,9 +76,9 @@
|
@@ -55,6 +55,14 @@
|
||||||
|
this.a(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ public Chunk getFullChunk() {
|
||||||
|
+ CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> statusFuture = this.getStatusFuture(ChunkStatus.FULL);
|
||||||
|
+ Either<IChunkAccess, PlayerChunk.Failure> either = (Either<IChunkAccess, PlayerChunk.Failure>) statusFuture.getNow(null);
|
||||||
|
+ return either == null ? null : (Chunk) either.left().orElse(null);
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
+
|
||||||
|
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) {
|
||||||
|
CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> completablefuture = (CompletableFuture) this.statusFutures.get(chunkstatus.c());
|
||||||
|
|
||||||
|
@@ -62,7 +70,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFuture(ChunkStatus chunkstatus) {
|
||||||
|
- return b(this.ticketLevel).b(chunkstatus) ? this.getStatusFutureUnchecked(chunkstatus) : PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE;
|
||||||
|
+ return b(this.oldTicketLevel).b(chunkstatus) ? this.getStatusFutureUnchecked(chunkstatus) : PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE; // CraftBukkit using oldTicketLevel for isLoaded checks
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Either<Chunk, PlayerChunk.Failure>> a() {
|
||||||
|
@@ -76,9 +84,9 @@
|
||||||
@Nullable
|
@Nullable
|
||||||
public Chunk getChunk() {
|
public Chunk getChunk() {
|
||||||
CompletableFuture<Either<Chunk, PlayerChunk.Failure>> completablefuture = this.a();
|
CompletableFuture<Either<Chunk, PlayerChunk.Failure>> completablefuture = this.a();
|
||||||
@ -21,7 +54,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<IChunkAccess> getChunkSave() {
|
public CompletableFuture<IChunkAccess> getChunkSave() {
|
||||||
@@ -201,7 +201,7 @@
|
@@ -201,7 +209,7 @@
|
||||||
CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> completablefuture = (CompletableFuture) this.statusFutures.get(i);
|
CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> completablefuture = (CompletableFuture) this.statusFutures.get(i);
|
||||||
|
|
||||||
if (completablefuture != null) {
|
if (completablefuture != null) {
|
||||||
@ -30,23 +63,29 @@
|
|||||||
|
|
||||||
if (either == null || either.left().isPresent()) {
|
if (either == null || either.left().isPresent()) {
|
||||||
return completablefuture;
|
return completablefuture;
|
||||||
@@ -213,6 +213,15 @@
|
@@ -256,6 +264,21 @@
|
||||||
|
boolean flag1 = this.ticketLevel <= PlayerChunkMap.GOLDEN_TICKET;
|
||||||
this.a(completablefuture1);
|
PlayerChunk.State playerchunk_state = c(this.oldTicketLevel);
|
||||||
this.statusFutures.set(i, completablefuture1);
|
PlayerChunk.State playerchunk_state1 = c(this.ticketLevel);
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ if (chunkstatus == ChunkStatus.FULL) {
|
+ // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins.
|
||||||
+ completablefuture1.thenAccept((either) -> {
|
+ if (playerchunk_state.a(PlayerChunk.State.BORDER) && !playerchunk_state1.a(PlayerChunk.State.BORDER)) { // PAIL oldChunkState, newChunkState, isAtLeast
|
||||||
+ Chunk chunk = (Chunk) either.left().get();
|
+ this.getStatusFutureUnchecked(ChunkStatus.FULL).thenAccept((either) -> {
|
||||||
+
|
+ either.ifLeft((chunkAccess) -> {
|
||||||
+ chunk.loadCallback();
|
+ Chunk chunk = (Chunk) chunkAccess;
|
||||||
|
+ // Minecraft will apply the chunks tick lists to the world once the chunk got loaded, and then store the tick
|
||||||
|
+ // lists again inside the chunk once the chunk becomes inaccessible and set the chunk's needsSaving flag.
|
||||||
|
+ // These actions may however happen deferred, so we manually set the needsSaving flag already here.
|
||||||
|
+ chunk.setNeedsSaving(true);
|
||||||
|
+ chunk.unloadCallback();
|
||||||
+ });
|
+ });
|
||||||
+ }
|
+ });
|
||||||
+ // CraftBukkit end
|
+ }
|
||||||
return completablefuture1;
|
+ // CraftBukkit end
|
||||||
} else {
|
|
||||||
return completablefuture == null ? PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE : completablefuture;
|
if (flag1) {
|
||||||
@@ -294,7 +303,7 @@
|
for (int i = flag ? chunkstatus.c() + 1 : 0; i <= chunkstatus1.c(); ++i) {
|
||||||
|
@@ -294,7 +317,7 @@
|
||||||
if (flag2 && !flag3) {
|
if (flag2 && !flag3) {
|
||||||
completablefuture = this.fullChunkFuture;
|
completablefuture = this.fullChunkFuture;
|
||||||
this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||||
@ -55,3 +94,21 @@
|
|||||||
playerchunkmap.getClass();
|
playerchunkmap.getClass();
|
||||||
return either1.ifLeft(playerchunkmap::a);
|
return either1.ifLeft(playerchunkmap::a);
|
||||||
}));
|
}));
|
||||||
|
@@ -332,6 +355,17 @@
|
||||||
|
|
||||||
|
this.w.a(this.location, this::j, this.ticketLevel, this::d);
|
||||||
|
this.oldTicketLevel = this.ticketLevel;
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ // ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins.
|
||||||
|
+ if (!playerchunk_state.a(PlayerChunk.State.BORDER) && playerchunk_state1.a(PlayerChunk.State.BORDER)) { // PAIL oldChunkState, newChunkState, isAtLeast
|
||||||
|
+ this.getStatusFutureUnchecked(ChunkStatus.FULL).thenAccept((either) -> {
|
||||||
|
+ either.ifLeft((chunkAccess) -> {
|
||||||
|
+ Chunk chunk = (Chunk) chunkAccess;
|
||||||
|
+ chunk.loadCallback();
|
||||||
|
+ });
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChunkStatus b(int i) {
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
--- a/net/minecraft/server/PlayerChunkMap.java
|
--- a/net/minecraft/server/PlayerChunkMap.java
|
||||||
+++ b/net/minecraft/server/PlayerChunkMap.java
|
+++ b/net/minecraft/server/PlayerChunkMap.java
|
||||||
@@ -35,6 +35,10 @@
|
@@ -35,6 +35,7 @@
|
||||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
+// CraftBukkit start
|
+import org.bukkit.entity.Player; // CraftBukkit
|
||||||
+import org.bukkit.entity.Player;
|
|
||||||
+import org.bukkit.event.world.ChunkUnloadEvent;
|
|
||||||
+// CraftBukkit end
|
|
||||||
|
|
||||||
public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||||
|
|
||||||
@@ -181,9 +185,12 @@
|
@@ -181,9 +182,12 @@
|
||||||
|
|
||||||
return completablefuture1.thenApply((list1) -> {
|
return completablefuture1.thenApply((list1) -> {
|
||||||
List<IChunkAccess> list2 = Lists.newArrayList();
|
List<IChunkAccess> list2 = Lists.newArrayList();
|
||||||
@ -26,7 +23,7 @@
|
|||||||
final Either<IChunkAccess, PlayerChunk.Failure> either = (Either) iterator.next();
|
final Either<IChunkAccess, PlayerChunk.Failure> either = (Either) iterator.next();
|
||||||
Optional<IChunkAccess> optional = either.left();
|
Optional<IChunkAccess> optional = either.left();
|
||||||
|
|
||||||
@@ -279,7 +286,7 @@
|
@@ -279,7 +283,7 @@
|
||||||
PlayerChunkMap.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.x.getName());
|
PlayerChunkMap.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.x.getName());
|
||||||
} else {
|
} else {
|
||||||
this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).forEach((playerchunk) -> {
|
this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).forEach((playerchunk) -> {
|
||||||
@ -35,7 +32,7 @@
|
|||||||
|
|
||||||
if (ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk) {
|
if (ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk) {
|
||||||
this.saveChunk(ichunkaccess);
|
this.saveChunk(ichunkaccess);
|
||||||
@@ -290,7 +297,6 @@
|
@@ -290,7 +294,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -43,27 +40,7 @@
|
|||||||
protected void unloadChunks(BooleanSupplier booleansupplier) {
|
protected void unloadChunks(BooleanSupplier booleansupplier) {
|
||||||
GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler();
|
GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler();
|
||||||
|
|
||||||
@@ -330,9 +336,19 @@
|
@@ -416,7 +419,7 @@
|
||||||
if (this.loadedChunks.remove(i) && ichunkaccess instanceof Chunk) {
|
|
||||||
Chunk chunk = (Chunk) ichunkaccess;
|
|
||||||
|
|
||||||
+ // CraftBukkit start
|
|
||||||
+ ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk, chunk.isNeedsSaving());
|
|
||||||
+ this.world.getServer().getPluginManager().callEvent(event);
|
|
||||||
+ this.saveChunk(ichunkaccess, event.isSaveChunk());
|
|
||||||
+ // CraftBukkit end
|
|
||||||
+
|
|
||||||
chunk.setLoaded(false);
|
|
||||||
this.world.unloadChunk(chunk);
|
|
||||||
+ // CraftBukkit start
|
|
||||||
+ } else {
|
|
||||||
+ this.saveChunk(ichunkaccess);
|
|
||||||
}
|
|
||||||
+ // CraftBukkit end
|
|
||||||
|
|
||||||
this.lightEngine.a(ichunkaccess.getPos());
|
|
||||||
this.lightEngine.queueUpdate();
|
|
||||||
@@ -416,7 +432,7 @@
|
|
||||||
return CompletableFuture.completedFuture(Either.right(playerchunk_failure));
|
return CompletableFuture.completedFuture(Either.right(playerchunk_failure));
|
||||||
});
|
});
|
||||||
}, (runnable) -> {
|
}, (runnable) -> {
|
||||||
@ -72,7 +49,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,7 +514,7 @@
|
@@ -498,7 +501,7 @@
|
||||||
long i = playerchunk.h().pair();
|
long i = playerchunk.h().pair();
|
||||||
|
|
||||||
playerchunk.getClass();
|
playerchunk.getClass();
|
||||||
@ -81,7 +58,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,7 +531,7 @@
|
@@ -515,7 +518,7 @@
|
||||||
return Either.left(chunk);
|
return Either.left(chunk);
|
||||||
});
|
});
|
||||||
}, (runnable) -> {
|
}, (runnable) -> {
|
||||||
@ -90,7 +67,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
completablefuture1.thenAcceptAsync((either) -> {
|
completablefuture1.thenAcceptAsync((either) -> {
|
||||||
@@ -529,7 +545,7 @@
|
@@ -529,7 +532,7 @@
|
||||||
return Either.left(chunk);
|
return Either.left(chunk);
|
||||||
});
|
});
|
||||||
}, (runnable) -> {
|
}, (runnable) -> {
|
||||||
@ -99,7 +76,7 @@
|
|||||||
});
|
});
|
||||||
return completablefuture1;
|
return completablefuture1;
|
||||||
}
|
}
|
||||||
@@ -543,7 +559,7 @@
|
@@ -543,7 +546,7 @@
|
||||||
return chunk;
|
return chunk;
|
||||||
});
|
});
|
||||||
}, (runnable) -> {
|
}, (runnable) -> {
|
||||||
@ -108,23 +85,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,8 +568,14 @@
|
@@ -607,9 +610,10 @@
|
||||||
}
|
|
||||||
|
|
||||||
public boolean saveChunk(IChunkAccess ichunkaccess) {
|
|
||||||
+ // CraftBukkit start
|
|
||||||
+ return this.saveChunk(ichunkaccess, ichunkaccess.isNeedsSaving());
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public boolean saveChunk(IChunkAccess ichunkaccess, boolean save) {
|
|
||||||
+ // CraftBukkit end
|
|
||||||
this.n.a(ichunkaccess.getPos());
|
|
||||||
- if (!ichunkaccess.isNeedsSaving()) {
|
|
||||||
+ if (!save) { // CraftBukkit
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
@@ -607,9 +629,10 @@
|
|
||||||
ChunkCoordIntPair chunkcoordintpair = playerchunk.h();
|
ChunkCoordIntPair chunkcoordintpair = playerchunk.h();
|
||||||
Packet<?>[] apacket = new Packet[2];
|
Packet<?>[] apacket = new Packet[2];
|
||||||
|
|
||||||
@ -136,7 +97,7 @@
|
|||||||
boolean flag1 = i1 <= this.viewDistance;
|
boolean flag1 = i1 <= this.viewDistance;
|
||||||
|
|
||||||
this.sendChunk(entityplayer, chunkcoordintpair, apacket, flag, flag1);
|
this.sendChunk(entityplayer, chunkcoordintpair, apacket, flag, flag1);
|
||||||
@@ -664,7 +687,7 @@
|
@@ -664,7 +668,7 @@
|
||||||
private NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException {
|
private NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException {
|
||||||
NBTTagCompound nbttagcompound = this.read(chunkcoordintpair);
|
NBTTagCompound nbttagcompound = this.read(chunkcoordintpair);
|
||||||
|
|
||||||
@ -145,7 +106,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean d(ChunkCoordIntPair chunkcoordintpair) {
|
boolean d(ChunkCoordIntPair chunkcoordintpair) {
|
||||||
@@ -984,7 +1007,7 @@
|
@@ -984,7 +988,7 @@
|
||||||
public final Set<EntityPlayer> trackedPlayers = Sets.newHashSet();
|
public final Set<EntityPlayer> trackedPlayers = Sets.newHashSet();
|
||||||
|
|
||||||
public EntityTracker(Entity entity, int i, int j, boolean flag) {
|
public EntityTracker(Entity entity, int i, int j, boolean flag) {
|
||||||
@ -154,7 +115,7 @@
|
|||||||
this.tracker = entity;
|
this.tracker = entity;
|
||||||
this.trackingDistance = i;
|
this.trackingDistance = i;
|
||||||
this.e = SectionPosition.a(entity);
|
this.e = SectionPosition.a(entity);
|
||||||
@@ -1053,6 +1076,17 @@
|
@@ -1053,6 +1057,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +93,9 @@ public class CraftChunk implements Chunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Entity[] getEntities() {
|
public Entity[] getEntities() {
|
||||||
|
if (!isLoaded()) {
|
||||||
|
getWorld().getChunkAt(x, z); // Transient load for this tick
|
||||||
|
}
|
||||||
int count = 0, index = 0;
|
int count = 0, index = 0;
|
||||||
net.minecraft.server.Chunk chunk = getHandle();
|
net.minecraft.server.Chunk chunk = getHandle();
|
||||||
|
|
||||||
@ -118,6 +121,9 @@ public class CraftChunk implements Chunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState[] getTileEntities() {
|
public BlockState[] getTileEntities() {
|
||||||
|
if (!isLoaded()) {
|
||||||
|
getWorld().getChunkAt(x, z); // Transient load for this tick
|
||||||
|
}
|
||||||
int index = 0;
|
int index = 0;
|
||||||
net.minecraft.server.Chunk chunk = getHandle();
|
net.minecraft.server.Chunk chunk = getHandle();
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ public class CraftWorld implements World {
|
|||||||
@Override
|
@Override
|
||||||
public boolean isChunkLoaded(int x, int z) {
|
public boolean isChunkLoaded(int x, int z) {
|
||||||
net.minecraft.server.Chunk chunk = world.getChunkProvider().getChunkAt(x, z, false);
|
net.minecraft.server.Chunk chunk = world.getChunkProvider().getChunkAt(x, z, false);
|
||||||
return chunk != null && chunk.loaded;
|
return chunk != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -345,8 +345,7 @@ public class CraftWorld implements World {
|
|||||||
@Override
|
@Override
|
||||||
public Chunk[] getLoadedChunks() {
|
public Chunk[] getLoadedChunks() {
|
||||||
Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks = world.getChunkProvider().playerChunkMap.visibleChunks;
|
Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks = world.getChunkProvider().playerChunkMap.visibleChunks;
|
||||||
|
return chunks.values().stream().map(PlayerChunk::getFullChunk).filter(Objects::nonNull).map(net.minecraft.server.Chunk::getBukkitChunk).toArray(Chunk[]::new);
|
||||||
return chunks.values().stream().map(PlayerChunk::getChunk).filter(Objects::nonNull).filter((chunk) -> chunk.loaded).map(net.minecraft.server.Chunk::getBukkitChunk).toArray(Chunk[]::new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -530,7 +530,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return entity.isAlive() && entity.valid;
|
return entity.isAlive() && entity.valid && entity.isChunkLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren