Current non compilable status of all patches - THIS IS NOT READY

THERE IS STILL NO ETA. GOBLINS WILL EAT YOU.
This commit is contained in:
Aikar 2020-06-25 21:58:00 -04:00
parent cfd598512a
commit bc5acdddad
43 changed files with 316 additions and 1533 deletions

View File

@ -10,7 +10,7 @@
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-mojangapi</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version>
<version>1.16.1-R0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Paper-MojangAPI</name>

View File

@ -66,11 +66,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (movingobjectposition != null) {
+ // Paper end
this.a(movingobjectposition);
// CraftBukkit start
if (this.dead) {
org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition);
}
// CraftBukkit end
+ } // Paper
}

View File

@ -41,8 +41,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start
Location enter = this.getBukkitEntity().getLocation();
Location exit = (worldserver == null) ? null : new Location(worldserver.getWorld(), d0, d1, d2, f1, f);
- PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, resourcekey == World.THE_END ? 0 : 16);
+ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, worldserver.paperConfig.portalSearchRadius, true, resourcekey == World.THE_END ? 0 : worldserver.paperConfig.portalCreateRadius);
- PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, resourcekey == DimensionManager.THE_END ? 0 : 16);
+ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, worldserver.paperConfig.portalSearchRadius, true, resourcekey == DimensionManager.THE_END ? 0 : worldserver.paperConfig.portalCreateRadius);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled() || event.getTo() == null) {
return null;

View File

@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sat, 16 May 2020 10:05:30 +0200
Subject: [PATCH] Add permission for command blocks
diff --git a/src/main/java/net/minecraft/server/BlockCommand.java b/src/main/java/net/minecraft/server/BlockCommand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockCommand.java
+++ b/src/main/java/net/minecraft/server/BlockCommand.java
@@ -0,0 +0,0 @@ public class BlockCommand extends BlockTileEntity {
public EnumInteractionResult interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) {
TileEntity tileentity = world.getTileEntity(blockposition);
- if (tileentity instanceof TileEntityCommand && entityhuman.isCreativeAndOp()) {
+ if (tileentity instanceof TileEntityCommand && (entityhuman.isCreativeAndOp() || (entityhuman.isCreative() && entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission
entityhuman.a((TileEntityCommand) tileentity);
return EnumInteractionResult.SUCCESS;
} else {
diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
+++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
@@ -0,0 +0,0 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener {
}
public boolean a(EntityHuman entityhuman) {
- if (!entityhuman.isCreativeAndOp()) {
+ if (!entityhuman.isCreativeAndOp() && !entityhuman.isCreative() && !entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
return false;
} else {
if (entityhuman.getWorld().isClientSide) {
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandblock, this, this.player.getWorldServer());
if (!this.minecraftServer.getEnableCommandBlock()) {
this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0]));
- } else if (!this.player.isCreativeAndOp()) {
+ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0]));
} else {
CommandBlockListenerAbstract commandblocklistenerabstract = null;
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandminecart, this, this.player.getWorldServer());
if (!this.minecraftServer.getEnableCommandBlock()) {
this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0]));
- } else if (!this.player.isCreativeAndOp()) {
+ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0]));
} else {
CommandBlockListenerAbstract commandblocklistenerabstract = packetplayinsetcommandminecart.a(this.player.world);
diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
@@ -0,0 +0,0 @@ public class PlayerInteractManager {
TileEntity tileentity = this.world.getTileEntity(blockposition);
Block block = iblockdata.getBlock();
- if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp()) {
+ if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp() && !(block instanceof BlockCommand && (this.player.isCreative() && this.player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission
this.world.notify(blockposition, iblockdata, iblockdata, 3);
return false;
} else if (this.player.a((World) this.world, blockposition, this.gamemode)) {
diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
@@ -0,0 +0,0 @@ public final class CraftDefaultPermissions {
DefaultPermissions.registerPermission(ROOT + ".nbt.copy", "Gives the user the ability to copy NBT in creative", org.bukkit.permissions.PermissionDefault.TRUE, parent);
DefaultPermissions.registerPermission(ROOT + ".debugstick", "Gives the user the ability to use the debug stick in creative", org.bukkit.permissions.PermissionDefault.OP, parent);
DefaultPermissions.registerPermission(ROOT + ".debugstick.always", "Gives the user the ability to use the debug stick in all game modes", org.bukkit.permissions.PermissionDefault.FALSE, parent);
+ DefaultPermissions.registerPermission(ROOT + ".commandblock", "Gives the user the ability to use command blocks.", org.bukkit.permissions.PermissionDefault.OP, parent); // Paper
// Spigot end
parent.recalculatePermissibles();
}

View File

@ -24,12 +24,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/EntityVillager.java
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
@@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
this.bL = 0;
this.bK = 0;
}
+ public Reputation getReputation() { return this.eN(); } // Paper - OBFHELPER
public Reputation eN() {
return this.bG;
+ public Reputation getReputation() { return this.fj(); } // Paper - OBFHELPER
public Reputation fj() {
return this.bF;
}
diff --git a/src/main/java/net/minecraft/server/Reputation.java b/src/main/java/net/minecraft/server/Reputation.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -85,12 +85,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public int compareTo(Ticket<?> ticket) {
@@ -0,0 +0,0 @@ public final class Ticket<T> implements Comparable<Ticket<?>> {
return this.b;
}
+ protected void setCurrentTick(long i) { a(i); } // Paper - OBFHELPER
protected void a(long i) {
this.d = i;
}
protected boolean b(long i) {

View File

@ -1,55 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 10 May 2020 22:12:46 -0400
Subject: [PATCH] Ensure Entity AABB's are never invalid
If anything used setPositionRaw, it left potential for an AABB
to be left stale at their old location, which could cause massive
AABB boxes if movement ever then got called on the new position.
This guarantees any time we set the entities position, we also
update their AABB.
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public void setPosition(double d0, double d1, double d2) {
this.setPositionRaw(d0, d1, d2);
- float f = this.size.width / 2.0F;
- 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));
+ // Paper start - move into setPositionRaw
+ //float f = this.size.width / 2.0F;
+ //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));
+ // Paper end
if (valid) ((WorldServer) world).chunkCheck(this); // CraftBukkit
}
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return new AxisAlignedBB(vec3d, vec3d1);
}
+ public final void setBoundingBox(AxisAlignedBB axisalignedbb) { a(axisalignedbb); } // Paper - OBFHELPER
public void a(AxisAlignedBB axisalignedbb) {
// CraftBukkit start - block invalid bounding boxes
double minX = axisalignedbb.minX,
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
public void setPositionRaw(double d0, double d1, double d2) {
+ // Paper start - never allow AABB to become desynced from position
+ // hanging has its own special logic
+ if (!(this instanceof EntityHanging) && (locX != d0 || locY != d1 || locZ != d2)) {
+ float f = this.size.width / 2.0F;
+ float f1 = this.size.height;
+ this.setBoundingBox(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f));
+ }
+ // Paper end
this.locX = d0;
this.locY = d1;
this.locZ = d2;

View File

@ -23,7 +23,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public boolean a() {
+ if (!getRaider().world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) || !getRaider().canPickupLoot()) return false; // Paper - respect game and entity rules for picking up items
+
Raid raid = this.b.eE();
Raid raid = this.b.fb();
if (this.b.eF() && !this.b.eE().a() && this.b.es() && !ItemStack.matches(this.b.getEquipment(EnumItemSlot.HEAD), Raid.s())) {
if (this.b.fc() && !this.b.fb().a() && this.b.eO() && !ItemStack.matches(this.b.getEquipment(EnumItemSlot.HEAD), Raid.s())) {

View File

@ -14,16 +14,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
List<Entity> list = this.world.a(Entity.class, new AxisAlignedBB(this.getPosition()));
-
- if (!list.isEmpty()) {
- this.a(((Entity) list.get(0)).getRootVehicle());
- }
+ // Paper start
+ for (Entity entity : list) {
+ if (!entity.isPassenger() && !entity.isVehicle() && entity.canPortal()) {
+ this.a(entity);
+ break;
+ }
- this.a((Entity) list.get(this.world.random.nextInt(list.size())));
+ // Paper start
+ for (Entity entity : list) {
+ if (!entity.isPassenger() && !entity.isVehicle() && entity.canPortal()) {
+ this.a(entity);
+ break;
+ }
+ // Paper end
}
+ // Paper end
if (this.age % 2400L == 0L) {
this.h();

View File

@ -75,14 +75,6 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ import net.minecraft.server.GeneratorAccess;
import net.minecraft.server.IBlockData;
import net.minecraft.server.IChatBaseComponent;
import net.minecraft.server.IInventory;
+import net.minecraft.server.IProjectile;
import net.minecraft.server.ItemActionContext;
import net.minecraft.server.ItemStack;
import net.minecraft.server.Items;
@@ -0,0 +0,0 @@ public class CraftEventFactory {
/**
* EntityShootBowEvent

View File

@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EntityArrow.java
+++ b/src/main/java/net/minecraft/server/EntityArrow.java
@@ -0,0 +0,0 @@ public abstract class EntityArrow extends Entity implements IProjectile {
@@ -0,0 +0,0 @@ public abstract class EntityArrow extends IProjectile {
}
}

View File

@ -1,124 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 8 May 2020 20:30:58 -0400
Subject: [PATCH] Fix CraftServer.unloadWorld Leak
The dimension manager was still registered which leaked the entire World
diff --git a/src/main/java/net/minecraft/server/DimensionManager.java b/src/main/java/net/minecraft/server/DimensionManager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/DimensionManager.java
+++ b/src/main/java/net/minecraft/server/DimensionManager.java
@@ -0,0 +0,0 @@ public class DimensionManager implements MinecraftSerializable {
private final boolean hasSkyLight;
private final GenLayerZoomer genLayerZoomer;
+ // Paper start
+ public static void unregister(String s, DimensionManager dimensionmanager) {
+ if (dimensionmanager == OVERWORLD || dimensionmanager == NETHER || dimensionmanager == THE_END) { return; } // do not unregister the default worlds
+ MCUtil.MAIN_EXECUTOR.execute(() -> {
+ RegistryMaterials<DimensionManager> registry = (RegistryMaterials<DimensionManager>) IRegistry.DIMENSION_TYPE;
+ registry.deleteValue(new MinecraftKey(s), dimensionmanager);
+ });
+ }
+ // Paper end
public static DimensionManager register(String s, DimensionManager dimensionmanager) {
return (DimensionManager) IRegistry.a(IRegistry.DIMENSION_TYPE, dimensionmanager.id, s, dimensionmanager);
}
diff --git a/src/main/java/net/minecraft/server/RegistryID.java b/src/main/java/net/minecraft/server/RegistryID.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/RegistryID.java
+++ b/src/main/java/net/minecraft/server/RegistryID.java
@@ -0,0 +0,0 @@ import javax.annotation.Nullable;
public class RegistryID<K> implements Registry<K> {
private static final Object a = null;
- private K[] b;
+ private K[] b; // Paper - diff below
private int[] c;
- private K[] d;
+ private K[] d; // Paper - diff below
private int e;
private int f;
private java.util.BitSet usedIds; // Paper
+ // Paper start
+ public void removeValue(K value) {
+ removeValue(value, this.b);
+ removeValue(value, this.d);
+ rehash(this.b.length);
+ }
+ public void removeValue(K value, K[] arr) {
+ for (int i = 0; i < arr.length; i++) {
+ K k = arr[i];
+ if (k == value) {
+ arr[i] = null;
+ }
+ }
+ }
public RegistryID(int i) {
i = (int) ((float) i / 0.8F);
@@ -0,0 +0,0 @@ public class RegistryID<K> implements Registry<K> {
return this.e;
}
+ private void rehash(int i) { d(i); } // Paper - OBFHELPER
private void d(int i) {
K[] ak = this.b;
int[] aint = this.c;
diff --git a/src/main/java/net/minecraft/server/RegistryMaterials.java b/src/main/java/net/minecraft/server/RegistryMaterials.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/RegistryMaterials.java
+++ b/src/main/java/net/minecraft/server/RegistryMaterials.java
@@ -0,0 +0,0 @@ public class RegistryMaterials<T> extends IRegistryWritable<T> {
private int V;
public RegistryMaterials() {}
+ public T deleteValue(MinecraftKey minecraftkey, T value) {
+ this.b.removeValue(value); // Diff 1
+ this.d = null; // Diff 2
+ return this.c.remove(minecraftkey); // Diff 3
+ }
@Override
public <V extends T> V a(int i, MinecraftKey minecraftkey, V v0) {
- this.b.a(v0, i);
+ this.b.a(v0, i); // Paper - diff above 1
Validate.notNull(minecraftkey);
Validate.notNull(v0);
- this.d = null;
+ this.d = null; // Diff 2
if (this.c.containsKey(minecraftkey)) {
RegistryMaterials.LOGGER.debug("Adding duplicate key '{}' to registry", minecraftkey);
}
- this.c.put(minecraftkey, v0);
+ this.c.put(minecraftkey, v0); // Paper - diff3
if (this.V <= i) {
this.V = i + 1;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -0,0 +0,0 @@ import net.minecraft.server.EntityPlayer;
import net.minecraft.server.EnumDifficulty;
import net.minecraft.server.EnumGamemode;
import net.minecraft.server.IRecipe;
+import net.minecraft.server.IRegistry;
import net.minecraft.server.Item;
import net.minecraft.server.ItemWorldMap;
import net.minecraft.server.Items;
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
}
worlds.remove(world.getName().toLowerCase(java.util.Locale.ENGLISH));
- console.worldServer.remove(handle.getWorldProvider().getDimensionManager());
+ // Paper start
+ DimensionManager dimensionManager = handle.getWorldProvider().getDimensionManager();
+ DimensionManager.unregister(world.getName().toLowerCase(java.util.Locale.ENGLISH), dimensionManager);
+ console.worldServer.remove(dimensionManager);
+ // Paper end
return true;
}

View File

@ -161,6 +161,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.mailboxWorldGen = this.p.a(threadedmailbox, false);
this.mailboxMain = this.p.a(mailbox, false);
+ this.mailboxLight = this.p.a(lightthreaded, false);// Paper
this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().f(), threadedmailbox1, this.p.a(threadedmailbox1, false));
this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false));
this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); this.chunkDistanceManager.chunkMap = this; // Paper
this.l = supplier;

View File

@ -11,27 +11,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java
@@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
public float bx;
public float by;
public boolean bz;
- public int bA;
+ public int bA; public final int getDeathTicks() { return this.bA; } public final void setDeathTicks(final int value) { this.bA = value; } // Paper
public float bB;
@Nullable
public EntityEnderCrystal currentEnderCrystal;
@@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
public void b(NBTTagCompound nbttagcompound) {
super.b(nbttagcompound);
nbttagcompound.setInt("DragonPhase", this.bO.a().getControllerPhase().b());
+ nbttagcompound.setInt("Paper.DeathTick", this.getDeathTicks()); // Paper
public void saveData(NBTTagCompound nbttagcompound) {
super.saveData(nbttagcompound);
nbttagcompound.setInt("DragonPhase", this.bN.a().getControllerPhase().b());
+ nbttagcompound.setInt("Paper.DeathTick", this.deathAnimationTicks); // Paper
}
@Override
@@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
if (nbttagcompound.hasKey("DragonPhase")) {
this.bO.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase")));
this.bN.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase")));
}
+ this.setDeathTicks(nbttagcompound.getInt("Paper.DeathTick")); // Paper
+ this.deathAnimationTicks = nbttagcompound.getInt("Paper.DeathTick"); // Paper
}

View File

@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
if (blockposition == null) { // CraftBukkit
if (this.world.getDimensionKey() == World.THE_END && worldserver.getDimensionKey() == World.OVERWORLD) {
if (this.world.getTypeKey() == DimensionManager.THE_END && worldserver.getTypeKey() == DimensionManager.OVERWORLD) { // CraftBukkit
+ // Paper start - Ensure spawn chunk is always loaded before calculating Y coordinate
+ this.world.getChunkAtWorldCoords(this.world.getSpawn());
+ // Paper end

View File

@ -63,20 +63,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
blockposition3 = blockposition3.shift(enumdirection1);
map.remove(blockposition3);
world.setTypeAndData(blockposition3, (IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPiston.FACING, enumdirection), 68);
- world.setTileEntity(blockposition3, BlockPistonMoving.a((IBlockData) list1.get(k), enumdirection, flag, false));
+ // Paper start - fix a variety of piston desync dupes
+ if (!allowDesync) {
+ iblockdata1 = world.getType(oldPos);
+ map.replace(oldPos, iblockdata1);
+ }
+ world.setTileEntity(blockposition3, BlockPistonMoving.a(allowDesync ? list1.get(k) : iblockdata1, enumdirection, flag, false));
world.setTileEntity(blockposition3, BlockPistonMoving.a((IBlockData) list1.get(k), enumdirection, flag, false));
+ if (!allowDesync) {
+ world.setTypeAndData(oldPos, Blocks.AIR.getBlockData(), 2 | 4 | 16 | 1024); // set air to prevent later physics updates from seeing this block
+ }
+ // Paper end - fix a variety of piston desync dupes
--j;
aiblockdata[j] = iblockdata1;
aiblockdata[j++] = iblockdata1;
}
diff --git a/src/main/java/net/minecraft/server/TileEntityPiston.java b/src/main/java/net/minecraft/server/TileEntityPiston.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/TileEntityPiston.java
@ -89,4 +88,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.world.setTypeAndData(this.position, this.a, com.destroystokyo.paper.PaperConfig.allowPistonDuplication ? 84 : (84 | 2)); // Paper - force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air
Block.a(this.a, iblockdata, this.world, this.position, 3);
} else {
if (iblockdata.b((IBlockState) BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C)) {
if (iblockdata.b(BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C)) {

View File

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -0,0 +0,0 @@ public class Main {
Calendar deadline = Calendar.getInstance();
deadline.add(Calendar.DAY_OF_YEAR, -3);
deadline.add(Calendar.DAY_OF_YEAR, -1);
if (buildDate.before(deadline.getTime())) {
- System.err.println("*** Error, this build is outdated ***");
+ // Paper start - This is some stupid bullshit

View File

@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public final BlockPosition asPosition() { return l(); } // Paper - OBFHELPER
public BlockPosition l() {
return new BlockPosition(this.x << 4, 0, this.z << 4);
return new BlockPosition(this.d(), 0, this.e());
}
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@ -113,8 +113,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
}
private static int a(ArraySetSorted<Ticket<?>> arraysetsorted) {
+ AsyncCatcher.catchOp("ChunkMapDistance::getHighestTicketLevel"); // Paper
private static int getLowestTicketLevel(ArraySetSorted<Ticket<?>> arraysetsorted) {
+ AsyncCatcher.catchOp("ChunkMapDistance::getLowestTicketLevel"); // Paper
return !arraysetsorted.isEmpty() ? ((Ticket) arraysetsorted.b()).b() : PlayerChunkMap.GOLDEN_TICKET + 1;
}
@ -122,9 +122,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean a(PlayerChunkMap playerchunkmap) {
//this.f.a(); // Paper - no longer used
+ AsyncCatcher.catchOp("DistanceManagerTick");
+ AsyncCatcher.catchOp("DistanceManagerTick"); // Paper
this.g.a();
int i = Integer.MAX_VALUE - this.e.a(Integer.MAX_VALUE);
int i = Integer.MAX_VALUE - this.ticketLevelTracker.a(Integer.MAX_VALUE);
boolean flag = i != 0;
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
@ -149,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private boolean addTicket(long i, Ticket<?> ticket) { // CraftBukkit - void -> boolean
+ AsyncCatcher.catchOp("ChunkMapDistance::addTicket"); // Paper
ArraySetSorted<Ticket<?>> arraysetsorted = this.e(i);
int j = a(arraysetsorted);
int j = getLowestTicketLevel(arraysetsorted);
Ticket<?> ticket1 = (Ticket) arraysetsorted.a(ticket); // CraftBukkit - decompile error
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
}
@ -157,18 +157,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private boolean removeTicket(long i, Ticket<?> ticket) { // CraftBukkit - void -> boolean
+ AsyncCatcher.catchOp("ChunkMapDistance::removeTicket"); // Paper
ArraySetSorted<Ticket<?>> arraysetsorted = this.e(i);
+ int oldLevel = a(arraysetsorted); // Paper
+ int oldLevel = getLowestTicketLevel(arraysetsorted); // Paper
boolean removed = false; // CraftBukkit
if (arraysetsorted.remove(ticket)) {
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
if (arraysetsorted.isEmpty()) {
this.tickets.remove(i);
}
-
- this.e.b(i, a(arraysetsorted), false);
+ int newLevel = a(arraysetsorted); // Paper
+ if (newLevel > oldLevel) this.e.b(i, newLevel, false); // Paper
- this.ticketLevelTracker.update(i, getLowestTicketLevel(arraysetsorted), false);
+ int newLevel = getLowestTicketLevel(arraysetsorted); // Paper
+ if (newLevel > oldLevel) this.ticketLevelTracker.update(i, newLevel, false); // Paper
return removed; // CraftBukkit
}
@ -317,6 +316,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Ticket<?> ticket = new Ticket<>(TicketType.PLAYER, 33, coords); // Paper - no-tick view distance
if (flag1) {
- ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> {
+ scheduleChunkLoad(i, MinecraftServer.currentTick, j, (priority) -> { // Paper - smarter ticket delay based on frustum and distance
+ // Paper start - recheck its still valid if not cancel
+ if (!isChunkInRange(i)) {
@ -337,16 +337,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return;
+ }
+ // Paper end
ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
+ ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
ChunkMapDistance.this.m.execute(() -> {
- if (this.c(this.c(i))) {
+ if (isChunkInRange(i)) { if (!hasPlayerTicket(coords, 33)) { // Paper - high priority might of already added it
ChunkMapDistance.this.addTicket(i, ticket);
ChunkMapDistance.this.l.add(i);
- } else {
+ }
+ } else { // Paper
ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
- ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> {
+ }} else { // Paper
+ ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
}, i, false));
}
@ -357,7 +357,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}));
+ }); // Paper
} else {
ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> {
ChunkMapDistance.this.m.execute(() -> {
ChunkMapDistance.this.removeTicket(i, ticket);
+ ChunkMapDistance.this.clearPriorityTickets(coords); // Paper
@ -562,11 +562,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private boolean a(@Nullable PlayerChunk playerchunk, int i) {
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
return this.serverThreadQueue.executeNext();
}
- private boolean tickDistanceManager() {
+ public boolean tickDistanceManager() { // Paper - public
public boolean tickDistanceManager() { // Paper - private -> public
+ if (chunkMapDistance.delayDistanceManagerTick) return false; // Paper
boolean flag = this.chunkMapDistance.a(this.playerChunkMap);
boolean flag1 = this.playerChunkMap.b();
@ -611,7 +609,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Yes, this doesn't match Vanilla, but it's the best we can do for now.
// If this is an issue, PRs are welcome
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
if (valid && (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this)))) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
if (valid && !this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
super.tick();
}
+ if (valid && isAlive() && playerConnection != null) ((WorldServer)world).getChunkProvider().playerChunkMap.checkHighPriorityChunks(this); // Paper
@ -844,11 +842,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// note: Here is a very good place to add callbacks to logic waiting on this.
Chunk entityTickingChunk = either.left().get();
@@ -0,0 +0,0 @@ public class PlayerChunk {
this.entityTickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage
this.entityTickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
}
-
- this.w.a(this.location, this::k, this.ticketLevel, this::d);
- this.v.a(this.location, this::k, this.ticketLevel, this::d);
+ // Paper start - raise IO/load priority if priority changes, use our preferred priority
+ priorityBoost = chunkMap.chunkDistanceManager.getChunkPriority(location);
+ int priority = getDemandedPriority();
@ -862,7 +859,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ chunkMap.world.asyncChunkTaskManager.raisePriority(location.x, location.z, ioPriority);
+ }
+ if (getCurrentPriority() != priority) {
+ this.w.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
+ this.v.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
+ int neighborsPriority = getNeighborsPriority();
+ this.neighbors.forEach((neighbor, neighborDesired) -> neighbor.setNeighborPriority(this, neighborsPriority));
+ }
@ -896,6 +893,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public final WorldServer world;
private final LightEngineThreaded lightEngine;
private final IAsyncTaskHandler<Runnable> executor;
+ final java.util.concurrent.Executor mainInvokingExecutor; // Paper
public final ChunkGenerator chunkGenerator;
private final Supplier<WorldPersistentData> l; public final Supplier<WorldPersistentData> getWorldPersistentDataSupplier() { return this.l; } // Paper - OBFHELPER
private final VillagePlace m;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Override
@ -912,6 +917,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (queued == null) {
return;
}
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.world = worldserver;
this.chunkGenerator = chunkgenerator;
this.executor = iasynctaskhandler;
+ // Paper start
+ this.mainInvokingExecutor = (run) -> {
+ if (MCUtil.isMainThread()) {
+ run.run();
+ } else {
+ iasynctaskhandler.execute(run);
+ }
+ };
+ // Paper end
ThreadedMailbox<Runnable> threadedmailbox = ThreadedMailbox.a(executor, "worldgen");
iasynctaskhandler.getClass();
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.playerViewDistanceTickMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets,
(EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
@ -1105,8 +1126,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
long i = playerchunk.i().pair();
playerchunk.getClass();
- mailbox.a(ChunkTaskQueueSorter.a(runnable, i, playerchunk::getTicketLevel)); // CraftBukkit - decompile error
+ mailbox.a(ChunkTaskQueueSorter.a(runnable, i, () -> 1)); // CraftBukkit - decompile error // Paper - final loads are always urgent!
- mailbox.a(ChunkTaskQueueSorter.a(runnable, i, playerchunk::getTicketLevel));
+ mailbox.a(ChunkTaskQueueSorter.a(runnable, i, () -> 1)); // Paper - final loads are always urgent!
});
}
@ -1138,7 +1159,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (updatingChunk != null) {
return updatingChunk.getEntityTickingFuture();
@@ -0,0 +0,0 @@ public abstract class PlayerList {
entityplayer, finalWorldserver, networkmanager, playerconnection,
entityplayer, finalWorldserver, finalWorldserver1, networkmanager, playerconnection,
nbttagcompound, networkmanager.getSocketAddress().toString(), lastKnownName
);
- //playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair());
@ -1148,7 +1169,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class PlayerList {
SocketAddress socketaddress = loginlistener.networkManager.getSocketAddress();
EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(DimensionManager.OVERWORLD), gameprofile, new PlayerInteractManager(this.server.getWorldServer(DimensionManager.OVERWORLD)));
EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(World.OVERWORLD), gameprofile, new PlayerInteractManager(this.server.getWorldServer(World.OVERWORLD)));
+ entity.isRealPlayer = true; // Paper
Player player = entity.getBukkitEntity();
PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.networkManager.getRawAddress()).getAddress());
@ -1158,7 +1179,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
worldserver.getChunkProvider().addTicket(TicketType.POST_TELEPORT, new ChunkCoordIntPair(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
+ entityplayer1.forceCheckHighPriority(); // Player
while (avoidSuffocation && !worldserver.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) {
while (avoidSuffocation && !worldserver1.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) {
entityplayer1.setPosition(entityplayer1.locX(), entityplayer1.locY() + 1.0D, entityplayer1.locZ());
}
diff --git a/src/main/java/net/minecraft/server/Ticket.java b/src/main/java/net/minecraft/server/Ticket.java
@ -1173,6 +1194,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected Ticket(TicketType<T> tickettype, int i, T t0) {
this.a = tickettype;
@@ -0,0 +0,0 @@ public final class Ticket<T> implements Comparable<Ticket<?>> {
return this.b;
}
+ public final void setCurrentTick(long i) { this.a(i); } // Paper - OBFHELPER
protected void a(long i) {
this.d = i;
}
diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/TicketType.java

View File

@ -1,101 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JellySquid <jellysquid+atwork@protonmail.com>
Date: Sat, 9 May 2020 16:25:21 -0400
Subject: [PATCH] Implement JellySquid's Entity Collision optimisations patch
Optimizes Full Block voxel collisions, and removes streams from Entity collisions
Original code by JellySquid, licensed under GNU Lesser General Public License v3.0
you can find the original code on https://github.com/jellysquid3/lithium-fabric/tree/1.15.x/fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision);
- VoxelShape voxelshape3 = voxelshape2.a((double) k1, (double) l1, (double) i2);
- if (VoxelShapes.c(voxelshape, voxelshape3, OperatorBoolean.AND)) {
- consumer.accept(voxelshape3);
- return true;
+ // Paper start - Lithium Collision Optimizations
+ if (voxelshape2 == VoxelShapes.empty()) {
+ continue;
+ }
+
+ if (voxelshape2 == VoxelShapes.fullCube()) {
+ if (axisalignedbb.intersects(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D)) {
+ consumer.accept(voxelshape2.offset(x, y, z));
+ return true;
+ }
+ } else {
+ VoxelShape shape = voxelshape2.offset(x, y, z);
+ if (VoxelShapes.applyOperation(shape, voxelshape, OperatorBoolean.AND)) {
+ consumer.accept(shape);
+ return true;
+ }
+ // Paper end
}
}
}
diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/IEntityAccess.java
+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
@@ -0,0 +0,0 @@ public interface IEntityAccess {
// Paper end - optimise hard collision
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
- if (axisalignedbb.a() < 1.0E-7D) {
+ // Paper start - remove streams from entity collision
+ if (axisalignedbb.getAverageSideLength() < 1.0E-7D) {
return Stream.empty();
- } else {
- AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D);
- Stream<AxisAlignedBB> stream = ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb) : this.getHardCollidingEntities(entity, axisalignedbb1)).stream().filter((entity1) -> { // Paper - decompile fix // Paper - optimise hard collision
- return !set.contains(entity1);
- }).filter((entity1) -> {
- return entity == null || !entity.isSameVehicle(entity1);
- }).flatMap((entity1) -> {
- return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); // Paper - optimise hard collision - diff on change, these are the methods that only hard colliding entities override
- }).filter(Objects::nonNull);
-
- return stream.filter(axisalignedbb1::c).map(VoxelShapes::a);
+
}
+ AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D);
+ List<Entity> entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection);
+ List<VoxelShape> shapes = new java.util.ArrayList<>();
+
+ for (Entity otherEntity : entities) {
+ if (!set.isEmpty() && set.contains(otherEntity)) {
+ continue;
+ }
+
+ if (entity != null && entity.isSameVehicle(otherEntity)) {
+ continue;
+ }
+
+ AxisAlignedBB otherEntityBox = otherEntity.getCollisionBox();
+
+ if (otherEntityBox != null && selection.intersects(otherEntityBox)) {
+ shapes.add(VoxelShapes.of(otherEntityBox));
+ }
+
+ if (entity != null) {
+ AxisAlignedBB otherEntityHardBox = entity.getHardCollisionBox(otherEntity);
+
+ if (otherEntityHardBox != null && selection.intersects(otherEntityHardBox)) {
+ shapes.add(VoxelShapes.of(otherEntityHardBox));
+ }
+ }
+ }
+
+ return shapes.stream();
+ // Paper end
}
@Nullable

View File

@ -25,6 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(getBukkitEntity(), packetplayinsettings.locale);
this.server.server.getPluginManager().callEvent(event);
}
this.locale = packetplayinsettings.locale;
this.clientViewDistance = packetplayinsettings.viewDistance;
// CraftBukkit end
+ // Paper start - add PlayerLocaleChangeEvent

View File

@ -57,30 +57,6 @@ diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/j
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public final WorldServer world;
private final LightEngineThreaded lightEngine;
private final IAsyncTaskHandler<Runnable> executor;
+ final java.util.concurrent.Executor mainInvokingExecutor; // Paper
public final ChunkGenerator<?> chunkGenerator;
private final Supplier<WorldPersistentData> l; public final Supplier<WorldPersistentData> getWorldPersistentDataSupplier() { return this.l; } // Paper - OBFHELPER
private final VillagePlace m;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.world = worldserver;
this.chunkGenerator = chunkgenerator;
this.executor = iasynctaskhandler;
+ // Paper start - optimize chunk status progression without jumping through thread pool
+ this.mainInvokingExecutor = (run) -> {
+ if (MCUtil.isMainThread()) {
+ run.run();
+ } else {
+ iasynctaskhandler.execute(run);
+ }
+ };
+ // Paper end
ThreadedMailbox<Runnable> threadedmailbox = ThreadedMailbox.a(executor, "worldgen");
iasynctaskhandler.getClass();
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return either.mapLeft((list) -> {
return (Chunk) list.get(list.size() / 2);
@ -118,6 +94,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return;
+ }
+ // Paper end
this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error
this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable));
});
}

View File

@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 9 May 2020 12:11:47 -0400
Subject: [PATCH] MC-183249: Don't generate Carving Masks BitSet unless needed
This was using SIGNIFICANT amounts of memory allocating many
long[]'s for BitSets for every ProtoChunk in the cache that had
been unloaded and reloaded.
This will result in a nice memory reduction.
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -0,0 +0,0 @@ public class ChunkRegionLoader {
for (int l = 0; l < k; ++l) {
WorldGenStage.Features worldgenstage_features = aworldgenstage_features[l];
- nbttagcompound3.setByteArray(worldgenstage_features.toString(), ichunkaccess.a(worldgenstage_features).toByteArray());
+ // Paper start - don't create carving mask bitsets if not even at that chunk status yet
+ BitSet mask = protochunk.getCarvingMaskIfSet(worldgenstage_features);
+ if (mask != null) {
+ nbttagcompound3.setByteArray(worldgenstage_features.toString(), mask.toByteArray());
+ }
+ // Paper end
}
nbttagcompound1.set("CarvingMasks", nbttagcompound3);
diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/ProtoChunk.java
+++ b/src/main/java/net/minecraft/server/ProtoChunk.java
@@ -0,0 +0,0 @@ public class ProtoChunk implements IChunkAccess {
private final ProtoChunkTickList<Block> q;
private final ProtoChunkTickList<FluidType> r;
private long s;
- private final Map<WorldGenStage.Features, BitSet> t;
+ private final Map<WorldGenStage.Features, BitSet> t;public BitSet getCarvingMaskIfSet(WorldGenStage.Features worldgenstage_features) { return this.t.get(worldgenstage_features); } // Paper
+ // Paper end
private volatile boolean u;
private final World world; // Paper - Anti-Xray - Add world

View File

@ -10,8 +10,8 @@ diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/ja
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockPosition.java
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
return dynamicops.createIntList(IntStream.of(new int[]{this.getX(), this.getY(), this.getZ()}));
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition {
this(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
}
+ public static long getAdjacent(int baseX, int baseY, int baseZ, EnumDirection enumdirection) { return asLong(baseX + enumdirection.getAdjacentX(), baseY + enumdirection.getAdjacentY(), baseZ + enumdirection.getAdjacentZ()); } // Paper
@ -25,17 +25,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public static int b(long i) {
- return (int) (i << 64 - BlockPosition.k - BlockPosition.c >> 64 - BlockPosition.c);
- return (int) (i << 64 - BlockPosition.m - BlockPosition.f >> 64 - BlockPosition.f);
+ return (int) (i >> 38); // Paper - simplify/inline
}
public static int c(long i) {
- return (int) (i << 64 - BlockPosition.f >> 64 - BlockPosition.f);
+ return (int) ((i << 52) >> 52); // Paper - simplify/inline
- return (int) (i << 64 - BlockPosition.h >> 64 - BlockPosition.h);
+ return (int) ((i << 26) >> 38); // Paper - simplify/inline
}
public static int d(long i) {
- return (int) (i << 64 - BlockPosition.j - BlockPosition.d >> 64 - BlockPosition.d);
- return (int) (i << 64 - BlockPosition.l - BlockPosition.g >> 64 - BlockPosition.g);
+ return (int) ((i << 26) >> 38); // Paper - simplify/inline
}
@ -44,13 +44,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return new BlockPosition((int) (i >> 38), (int) ((i << 52) >> 52), (int) ((i << 26) >> 38)); // Paper - simplify/inline
}
public long asLong() {
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition {
public static long asLong(int x, int y, int z) { return a(x, y, z); } // Paper - OBFHELPER
public static long a(int i, int j, int k) {
- long l = 0L;
-
- l |= ((long) i & BlockPosition.g) << BlockPosition.k;
- l |= ((long) j & BlockPosition.h) << 0;
- l |= ((long) k & BlockPosition.i) << BlockPosition.j;
- l |= ((long) i & BlockPosition.i) << BlockPosition.m;
- l |= ((long) j & BlockPosition.j) << 0;
- l |= ((long) k & BlockPosition.k) << BlockPosition.l;
- return l;
+ return (((long) i & (long) 67108863) << 38) | (((long) j & (long) 4095)) | (((long) k & (long) 67108863) << 12); // Paper - inline constants and simplify
}
@ -104,75 +107,35 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- int k = b(blockposition.getZ());
-
- return (short) (i << 8 | k << 4 | j);
+ return (short) ((blockposition.x & 15) << 8 | (blockposition.z & 15) << 4 | blockposition.y & 15); // Paper - simplify/inline
+ return (short) ((blockposition.getX() & 15) << 8 | (blockposition.getZ() & 15) << 4 | blockposition.getY() & 15); // Paper - simplify/inline
}
public static int c(int i) {
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
}
public static int b(long i) {
- return (int) (i << 0 >> 42);
+ return (int) (i >> 42); // Paper
}
public static int c(long i) {
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
return (int) (i << 22 >> 42);
}
- public int a() {
- return this.getX();
+ public final int a() { // Paper
+ return x; // Paper
}
- public int b() {
- return this.getY();
+ public final int b() { // Paper
+ return y; // Paper
}
- public int c() {
- return this.getZ();
+ public final int c() { // Paper
+ return z; // Paper
return this.getZ();
}
- public int d() {
- return this.a() << 4;
+ public final int d() { // Paper
+ return x << 4; // Paper
+ return this.getX() << 4; // Paper
}
- public int e() {
- return this.b() << 4;
+ public final int e() { // Paper
+ return y << 4; // Paper
+ return this.getY() << 4; // Paper
}
- public int f() {
- return this.c() << 4;
+ public final int f() { // Paper
+ return z << 4; // Paper
+ return this.getZ() << 4; // Paper
}
- public int g() {
- return (this.a() << 4) + 15;
+ public final int g() { // Paper
+ return (x << 4) + 15; // Paper
}
- public int h() {
- return (this.b() << 4) + 15;
+ public final int h() { // Paper
+ return (y << 4) + 15; // Paper
}
- public int r() {
- return (this.c() << 4) + 15;
+ public final int r() { // Paper
+ return (z << 4) + 15; // Paper
public int g() {
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
return (this.c() << 4) + 15;
}
+ public static long blockToSection(long i) { return e(i); } // Paper - OBFHELPER
@ -183,15 +146,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public static long f(long i) {
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
}
public BlockPosition s() {
- return new BlockPosition(c(this.a()), c(this.b()), c(this.c()));
+ return new BlockPosition(x << 4, y << 4, z << 4); // Paper
}
public BlockPosition t() {
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
return new ChunkCoordIntPair(this.a(), this.c());
}
@ -212,14 +166,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return (((long) i & 4194303L) << 42) | (((long) j & 1048575L)) | (((long) k & 4194303L) << 20); // Paper - Simplify to reduce instruction count
}
public long v() {
public long s() {
- return b(this.a(), this.b(), this.c());
+ return (((long) x & 4194303L) << 42) | (((long) y & 1048575L)) | (((long) z & 4194303L) << 20); // Paper - Simplify to reduce instruction count
+ return (((long) getX() & 4194303L) << 42) | (((long) getY() & 1048575L)) | (((long) getZ() & 4194303L) << 20); // Paper - Simplify to reduce instruction count
}
public Stream<BlockPosition> w() {
- return BlockPosition.a(this.d(), this.e(), this.f(), this.g(), this.h(), this.r());
+ return BlockPosition.a(x << 4, y << 4, z << 4, (x << 4) + 15, (y << 4) + 15, (z << 4) + 15); // Paper - simplify/inline
public Stream<BlockPosition> t() {
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
}
public static Stream<SectionPosition> a(SectionPosition sectionposition, int i) {
@ -228,7 +181,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- int l = sectionposition.c();
-
- return a(j - i, k - i, l - i, j + i, k + i, l + i);
+ return a(sectionposition.x - i, sectionposition.y - i, sectionposition.z - i, sectionposition.x + i, sectionposition.y + i, sectionposition.z + i); // Paper - simplify/inline
+ return a(sectionposition.getX() - i, sectionposition.getY() - i, sectionposition.getZ() - i, sectionposition.getX() + i, sectionposition.getY() + i, sectionposition.getZ() + i); // Paper - simplify/inline
}
public static Stream<SectionPosition> b(ChunkCoordIntPair chunkcoordintpair, int i) {

View File

@ -24,19 +24,6 @@ Massive update to light to improve performance and chunk loading/generation.
7) Buffer non urgent tasks even if queueUpdate is called multiple times to improve efficiency.
8) Fix NPE risk that crashes server in getting nibble data
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -0,0 +0,0 @@ public class Block implements IMaterial {
return false;
}
- @Deprecated
+ public final boolean canOcclude(IBlockData blockData) { return n(blockData); } @Deprecated // Paper - OBFHELPER
public final boolean n(IBlockData iblockdata) {
return this.j;
}
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
@ -50,46 +37,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return super.executeNext() || execChunkTask; // Paper
}
} finally {
diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/IBlockData.java
+++ b/src/main/java/net/minecraft/server/IBlockData.java
@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
private final boolean e;
private final boolean isAir; // Paper
private final boolean isTicking; // Paper
+ private final boolean canOcclude; // Paper
public IBlockData(Block block, ImmutableMap<IBlockState<?>, Comparable<?>> immutablemap) {
super(block, immutablemap);
@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
this.e = block.o(this);
this.isAir = this.getBlock().isAir(this); // Paper
this.isTicking = this.getBlock().isTicking(this); // Paper
+ this.canOcclude = this.getBlock().canOcclude(this); // Paper
}
public void c() {
@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
return this.c == null || this.c.h;
}
- public boolean g() {
+ public final boolean g() { // Paper
return this.e;
}
@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
return this.c != null ? this.c.c : this.getBlock().k(this, iblockaccess, blockposition);
}
- public boolean o() {
- return this.c != null ? this.c.b : this.getBlock().n(this);
+ public final boolean o() { // Paper
+ return canOcclude; // Paper
}
public VoxelShape getShape(IBlockAccess iblockaccess, BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/server/LightEngineBlock.java b/src/main/java/net/minecraft/server/LightEngineBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/LightEngineBlock.java
@ -277,8 +224,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- private final IBlockAccess[] h = new IBlockAccess[2];
+ private final IChunkAccess[] h = new IChunkAccess[2]; // Paper
+ // Paper start - see fully commented out method below (look for Bedrock)
+ // optimized method with less branching for when scenarios arent needed.
+ // avoid using mutable version if can
+ protected final IBlockData getBlockOptimized(int x, int y, int z, MutableInt mutableint) {
+ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4);
+
+ if (iblockaccess == null) {
+ mutableint.setValue(16);
+ return Blocks.BEDROCK.getBlockData();
+ } else {
+ this.pos.setValues(x, y, z);
+ IBlockData iblockdata = iblockaccess.getType(x, y, z);
+ mutableint.setValue(iblockdata.b(this.a.getWorld(), this.pos));
+ return iblockdata.l() && iblockdata.e() ? iblockdata : Blocks.AIR.getBlockData();
+ }
+ }
+ protected final IBlockData getBlockOptimized(int x, int y, int z) {
+ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4);
+
+ if (iblockaccess == null) {
+ return Blocks.BEDROCK.getBlockData();
+ } else {
+ IBlockData iblockdata = iblockaccess.getType(x, y, z);
+ return iblockdata.l() && iblockdata.e() ? iblockdata : Blocks.AIR.getBlockData();
+ }
+ }
+ // Paper end
public LightEngineLayer(ILightAccess ilightaccess, EnumSkyBlock enumskyblock, S s0) {
super(16, 256, 8192);
this.a = ilightaccess;
@@ -0,0 +0,0 @@ public abstract class LightEngineLayer<M extends LightEngineStorageArray<M>, S e
}
@ -308,7 +283,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- }
-
- return Blocks.AIR.getBlockData();
+ // Paper start - unused, optimized versions below, comment out to detect changes
- } else {
- int j = SectionPosition.a(BlockPosition.b(i));
- int k = SectionPosition.a(BlockPosition.d(i));
- IBlockAccess iblockaccess = this.a(j, k);
-
- if (iblockaccess == null) {
- if (mutableint != null) {
- mutableint.setValue(16);
- }
-
- return Blocks.BEDROCK.getBlockData();
- } else {
- this.d.g(i);
- IBlockData iblockdata = iblockaccess.getType(this.d);
- boolean flag = iblockdata.l() && iblockdata.e();
-
- if (mutableint != null) {
- mutableint.setValue(iblockdata.b(this.a.getWorld(), (BlockPosition) this.d));
- }
-
- return flag ? iblockdata : Blocks.AIR.getBlockData();
- }
- }
- }
+ // Paper start - comment out, see getBlockOptimized
+// protected IBlockData a(long i, @Nullable MutableInt mutableint) {
+// if (i == Long.MAX_VALUE) {
+// if (mutableint != null) {
@ -330,7 +329,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+// } else {
+// this.d.g(i);
+// IBlockData iblockdata = iblockaccess.getType(this.d);
+// boolean flag = iblockdata.o() && iblockdata.g();
+// boolean flag = iblockdata.l() && iblockdata.e();
+//
+// if (mutableint != null) {
+// mutableint.setValue(iblockdata.b(this.a.getWorld(), (BlockPosition) this.d));
@ -340,55 +339,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+// }
+// }
+// }
+ // optimized method with less branching for when scenarios arent needed.
+ // avoid using mutable version if can
+ protected final IBlockData getBlockOptimized(int x, int y, int z, MutableInt mutableint) {
+ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4);
+
+ if (iblockaccess == null) {
+ mutableint.setValue(16);
+ return Blocks.BEDROCK.getBlockData();
} else {
- int j = SectionPosition.a(BlockPosition.b(i));
- int k = SectionPosition.a(BlockPosition.d(i));
- IBlockAccess iblockaccess = this.a(j, k);
-
- if (iblockaccess == null) {
- if (mutableint != null) {
- mutableint.setValue(16);
- }
-
- return Blocks.BEDROCK.getBlockData();
- } else {
- this.d.g(i);
- IBlockData iblockdata = iblockaccess.getType(this.d);
- boolean flag = iblockdata.o() && iblockdata.g();
-
- if (mutableint != null) {
- mutableint.setValue(iblockdata.b(this.a.getWorld(), (BlockPosition) this.d));
- }
+ this.pos.setValues(x, y, z);
+ IBlockData iblockdata = iblockaccess.getType(x, y, z);
+ mutableint.setValue(iblockdata.b(this.a.getWorld(), this.pos));
+ return iblockdata.o() && iblockdata.g() ? iblockdata : Blocks.AIR.getBlockData();
+ }
+ }
+ protected final IBlockData getBlockOptimized(int x, int y, int z) {
+ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4);
- return flag ? iblockdata : Blocks.AIR.getBlockData();
- }
+ if (iblockaccess == null) {
+ return Blocks.BEDROCK.getBlockData();
+ } else {
+ IBlockData iblockdata = iblockaccess.getType(x, y, z);
+ return iblockdata.o() && iblockdata.g() ? iblockdata : Blocks.AIR.getBlockData();
}
}
+ // Paper end
protected VoxelShape a(IBlockData iblockdata, long i, EnumDirection enumdirection) {
return iblockdata.o() ? iblockdata.a(this.a.getWorld(), this.d.g(i), enumdirection) : VoxelShapes.a();
return iblockdata.l() ? iblockdata.a(this.a.getWorld(), this.d.g(i), enumdirection) : VoxelShapes.a();
@@ -0,0 +0,0 @@ public abstract class LightEngineLayer<M extends LightEngineStorageArray<M>, S e
return i == Long.MAX_VALUE ? 0 : 15 - this.c.i(i);
}
@ -583,6 +537,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected final Long2ObjectMap<NibbleArray> i = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap());
private final LongSet n = new LongOpenHashSet();
private final LongSet o = new LongOpenHashSet();
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
protected volatile boolean j;
protected LightEngineStorage(EnumSkyBlock enumskyblock, ILightAccess ilightaccess, M m0) {
@ -696,12 +651,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
if (k >= 2 && j != 2) {
- if (this.o.contains(i)) {
- this.o.remove(i);
- if (this.p.contains(i)) {
- this.p.remove(i);
- } else {
+ if (!this.o.remove(i)) { // Paper - remove useless contains - credit to JellySquid
+ //this.o.remove(i); // Paper
+ //} else { // Pape
+ if (!this.p.remove(i)) { // Paper - remove useless contains - credit to JellySquid
+ //this.p.remove(i); // Paper
+ //} else { // Paper
this.f.a(i, this.j(i));
this.g.add(i);
this.k(i);
@ -746,7 +701,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
NibbleArray nibblearray1 = (NibbleArray) this.i.remove(i);
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
longiterator = this.o.iterator();
longiterator = this.p.iterator();
while (longiterator.hasNext()) {
- i = (Long) longiterator.next();
@ -754,16 +709,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.l(i);
}
this.o.clear();
this.j = false;
- ObjectIterator objectiterator = this.i.long2ObjectEntrySet().iterator();
+ ObjectIterator<Long2ObjectMap.Entry<NibbleArray>> objectiterator = Long2ObjectMaps.fastIterator(this.i); // Paper
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
Entry entry;
long j;
+ NibbleArray test = null; // Paper
+ LongSet propagating = new LongOpenHashSet(); // Paper - credit JellySquid for idea to move this up
while (objectiterator.hasNext()) {
entry = (Entry) objectiterator.next();
j = entry.getLongKey();
@ -775,66 +725,48 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.a(lightenginelayer, j);
this.f.a(j, nibblearray);
this.g.add(j);
}
+ if (!flag1) propagating.add(j); // Paper
+ objectiterator.remove(); // Paper
}
}
this.f.c();
- if (!flag1) {
- longiterator = this.i.keySet().iterator();
+ if (!flag1) {// Paper - diff on change, change propagating add a few lines up
+ longiterator = propagating.iterator(); // Paper
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
longiterator = this.i.keySet().iterator();
while (longiterator.hasNext()) {
- i = (Long) longiterator.next();
- if (this.g(i)) {
- int k = SectionPosition.c(SectionPosition.b(i));
- int l = SectionPosition.c(SectionPosition.c(i));
- int i1 = SectionPosition.c(SectionPosition.d(i));
+ // Paper start
+ i = longiterator.nextLong();
+ if (true) { // don't check hasLight, this iterator is filtered already
+ int secX = (int) (i >> 42);
+ int secY = (int) (i << 44 >> 44);
+ int secZ = (int) (i << 22 >> 42);
+ int k = secX << 4; // baseX
+ int l = secY << 4; // baseY
+ int i1 = secZ << 4; // baseZ
+ // Paper end
EnumDirection[] aenumdirection = LightEngineStorage.k;
int j1 = aenumdirection.length;
+ i = longiterator.nextLong(); // Paper
this.b(lightenginelayer, i);
}
} else {
longiterator = this.n.iterator();
for (int k1 = 0; k1 < j1; ++k1) {
EnumDirection enumdirection = aenumdirection[k1];
- long l1 = SectionPosition.a(i, enumdirection);
-
- if (!this.i.containsKey(l1) && this.g(l1)) {
+ long l1 = SectionPosition.getAdjacentFromSectionPos(secX, secY, secZ, enumdirection); // Paper - avoid extra unpacking
+ if (!propagating.contains(l1) && this.g(l1)) { // Paper - use propagating
for (int i2 = 0; i2 < 16; ++i2) {
for (int j2 = 0; j2 < 16; ++j2) {
long k2;
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
while (longiterator.hasNext()) {
- i = (Long) longiterator.next();
+ i = longiterator.nextLong(); // Paper
this.b(lightenginelayer, i);
}
}
+ // Paper start - moved above - Credit JellySquid for idea
+ /*
objectiterator = this.i.long2ObjectEntrySet().iterator();
while (objectiterator.hasNext()) {
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
if (this.g(j)) {
objectiterator.remove();
}
- }
+ }*/
+ // Paper end
}
}
private void b(LightEngineLayer<M, ?> lightenginelayer, long i) {
if (this.g(i)) {
- int j = SectionPosition.c(SectionPosition.b(i));
- int k = SectionPosition.c(SectionPosition.c(i));
- int l = SectionPosition.c(SectionPosition.d(i));
+ // Paper start
+ int secX = (int) (i >> 42);
+ int secY = (int) (i << 44 >> 44);
+ int secZ = (int) (i << 22 >> 42);
+ int j = secX << 4; // baseX
+ int k = secY << 4; // baseY
+ int l = secZ << 4; // baseZ
+ // Paper end
EnumDirection[] aenumdirection = LightEngineStorage.k;
int i1 = aenumdirection.length;
for (int j1 = 0; j1 < i1; ++j1) {
EnumDirection enumdirection = aenumdirection[j1];
- long k1 = SectionPosition.a(i, enumdirection);
+ long k1 = SectionPosition.getAdjacentFromSectionPos(secX, secY, secZ, enumdirection); // Paper - avoid extra unpacking
if (!this.i.containsKey(k1) && this.g(k1)) {
for (int l1 = 0; l1 < 16; ++l1) {
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageArray.java b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/LightEngineStorageArray.java
@ -1211,7 +1143,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) {
this.e.a(ChunkTaskQueueSorter.a(() -> { // Paper - decompile error
this.e.a(ChunkTaskQueueSorter.a(() -> {
- this.c.add(Pair.of(lightenginethreaded_update, runnable));
- if (this.c.size() >= this.f) {
+ // Paper start
@ -1347,7 +1279,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ chunkMap.world.getChunkProvider().getLightEngine().changePriority(location.pair(), getCurrentPriority(), priority);
}
if (getCurrentPriority() != priority) {
this.w.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
this.v.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
@ -1378,7 +1310,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
}
gameprofilerfiller.exit();
timings.chunkTicksBlocks.stopTiming(); // Paper

View File

@ -41,10 +41,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected void a(LightEngineLayer<?, ?> lightenginelayer, long i) {
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
protected void a(long i, @Nullable NibbleArray nibblearray) {
protected void a(long i, @Nullable NibbleArray nibblearray, boolean flag) {
if (nibblearray != null) {
- this.i.put(i, nibblearray);
+ NibbleArray remove = this.i.put(i, nibblearray); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed
if (!flag) {
this.n.add(i);
}
} else {
- this.i.remove(i);
+ NibbleArray remove = this.i.remove(i); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed
@ -248,8 +251,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java
@@ -0,0 +0,0 @@ public class PacketPlayOutLightUpdate implements Packet<PacketListenerPlayOut> {
private List<byte[]> g;
private List<byte[]> h;
private boolean i;
+ // Paper start
+ java.lang.Runnable cleaner1;
@ -282,9 +285,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end
public PacketPlayOutLightUpdate() {}
public PacketPlayOutLightUpdate(ChunkCoordIntPair chunkcoordintpair, LightEngine lightengine) {
public PacketPlayOutLightUpdate(ChunkCoordIntPair chunkcoordintpair, LightEngine lightengine, boolean flag) {
this.a = chunkcoordintpair.x;
this.b = chunkcoordintpair.z;
this.i = flag;
- this.g = Lists.newArrayList();
- this.h = Lists.newArrayList();
+ this.g = Lists.newArrayList();cleaner1 = MCUtil.registerListCleaner(this, this.g, NibbleArray::releaseBytes); // Paper
@ -311,7 +315,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
}
@@ -0,0 +0,0 @@ public class PacketPlayOutLightUpdate implements Packet<PacketListenerPlayOut> {
this.b = chunkcoordintpair.z;
this.i = flag;
this.c = i;
this.d = j;
- this.g = Lists.newArrayList();

View File

@ -1,162 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 11 May 2020 04:18:54 -0400
Subject: [PATCH] Optimize Pathfinder - Remove Streams / Optimized collections
I utilized the IDE to convert streams to non streams code, so shouldn't
be any risk of behavior change. Only did minor optimization of the
generated code set to remove unnecessary things.
I expect us to just drop this patch on next major update and re-apply
it with the IDE again and re-apply the collections optimization.
Optimize collection by creating a list instead of a set of the key and value.
This lets us get faster foreach iteration, as well as avoids map lookups on
the values when needed.
diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Pathfinder.java
+++ b/src/main/java/net/minecraft/server/Pathfinder.java
@@ -0,0 +0,0 @@ public class Pathfinder {
this.a.a();
this.e.a(chunkcache, entityinsentient);
PathPoint pathpoint = this.e.b();
- Map<PathDestination, BlockPosition> map = (Map) set.stream().collect(Collectors.toMap((blockposition) -> {
- return this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
- }, Function.identity()));
+ // Paper start - remove streams - and optimize collection
+ List<Map.Entry<PathDestination, BlockPosition>> map = new java.util.ArrayList<>();
+ for (BlockPosition blockposition : set) {
+ // cast is important
+ //noinspection RedundantCast
+ PathDestination path = this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
+ map.add(new java.util.AbstractMap.SimpleEntry<>(path, blockposition));
+ }
+ // Paper end
PathEntity pathentity = this.a(pathpoint, map, f, i, f1);
this.e.a();
@@ -0,0 +0,0 @@ public class Pathfinder {
}
@Nullable
- private PathEntity a(PathPoint pathpoint, Map<PathDestination, BlockPosition> map, float f, int i, float f1) {
- Set<PathDestination> set = map.keySet();
+ private PathEntity a(PathPoint pathpoint, java.util.List<java.util.Map.Entry<PathDestination, BlockPosition>> list, float f, int i, float f1) { // Paper - list instead of set
+ //Set<PathDestination> set = map.keySet(); // Paper
pathpoint.e = 0.0F;
- pathpoint.f = this.a(pathpoint, set);
+ pathpoint.f = this.a(pathpoint, list); // Paper - list instead of map
pathpoint.g = pathpoint.f;
this.a.a();
this.b.clear();
@@ -0,0 +0,0 @@ public class Pathfinder {
PathPoint pathpoint1 = this.a.c();
pathpoint1.i = true;
- set.stream().filter((pathdestination) -> {
- return pathpoint1.c((PathPoint) pathdestination) <= (float) i;
- }).forEach(PathDestination::e);
- if (set.stream().anyMatch(PathDestination::f)) {
+ // Paper start - remove streams
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
+ PathDestination pathdestination = list.get(i1).getKey();
+ if (pathpoint1.c(pathdestination) <= (float) i) {
+ pathdestination.e();
+ }
+ }
+ boolean result = false;
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
+ PathDestination pathdestination = list.get(i1).getKey();
+ if (pathdestination.f()) {
+ result = true;
+ break;
+ }
+ }
+ if (result) {
+ // Paper end
break;
}
@@ -0,0 +0,0 @@ public class Pathfinder {
if (pathpoint2.j < f && (!pathpoint2.c() || f3 < pathpoint2.e)) {
pathpoint2.h = pathpoint1;
pathpoint2.e = f3;
- pathpoint2.f = this.a(pathpoint2, set) * 1.5F;
+ pathpoint2.f = this.a(pathpoint2, list) * 1.5F; // Paper - use list instead of map
if (pathpoint2.c()) {
this.a.a(pathpoint2, pathpoint2.e + pathpoint2.f);
} else {
@@ -0,0 +0,0 @@ public class Pathfinder {
}
}
- Stream stream;
- if (set.stream().anyMatch(PathDestination::f)) {
- stream = set.stream().filter(PathDestination::f).map((pathdestination) -> {
- return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), true);
- }).sorted(Comparator.comparingInt(PathEntity::e));
- } else {
- stream = set.stream().map((pathdestination) -> {
- return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), false);
- }).sorted(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e));
+ // Paper start - remove streams
+ boolean result = false;
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
+ PathDestination pathDestination = list.get(i1).getKey(); // Paper
+ if (pathDestination.f()) {
+ result = true;
+ break;
+ }
}
-
- Optional<PathEntity> optional = stream.findFirst();
-
- if (!optional.isPresent()) {
- return null;
+ List<PathEntity> candidates = new java.util.ArrayList<>();
+ if (result) {
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
+ Map.Entry<PathDestination, BlockPosition> entry = list.get(i1);
+ PathDestination pathdestination = entry.getKey();
+ if (pathdestination.f()) {
+ PathEntity pathEntity = this.a(pathdestination.d(), entry.getValue(), true);
+ candidates.add(pathEntity);
+ }
+ }
+ if (candidates.isEmpty()) return null;
+ candidates.sort(Comparator.comparingInt(PathEntity::e));
} else {
- PathEntity pathentity = (PathEntity) optional.get();
-
- return pathentity;
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
+ Map.Entry<PathDestination, BlockPosition> entry = list.get(i1);
+ PathDestination pathdestination = entry.getKey();
+ PathEntity pathEntity = this.a(pathdestination.d(), entry.getValue(), false);
+ candidates.add(pathEntity);
+ }
+ if (candidates.isEmpty()) return null;
+ candidates.sort(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e));
}
+ return candidates.get(0);
+ // Paper end
}
- private float a(PathPoint pathpoint, Set<PathDestination> set) {
+ private float a(PathPoint pathpoint, java.util.List<java.util.Map.Entry<PathDestination, BlockPosition>> list) {
float f = Float.MAX_VALUE;
float f1;
- for (Iterator iterator = set.iterator(); iterator.hasNext(); f = Math.min(f1, f)) {
- PathDestination pathdestination = (PathDestination) iterator.next();
+ for (int i = 0, listSize = list.size(); i < listSize; f = Math.min(f1, f), i++) { // Paper
+ PathDestination pathdestination = list.get(i).getKey(); // Paper
f1 = pathpoint.a(pathdestination);
pathdestination.a(f1, pathpoint);

View File

@ -1,273 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 26 May 2020 21:32:05 -0400
Subject: [PATCH] Optimize Villagers
This change reimplements the entire BehaviorFindPosition method to
get rid of all of the streams, and implement the logic in a more sane way.
We keep vanilla behavior 100% the same with this change, just wrote more
optimal, as we can abort iterating POI's as soon as we find a match....
One slight change is that Minecraft adds a random delay before a POI is
attempted again. I've increased the amount of that delay based on the distance
to said POI, so farther POI's will not be attempted as often.
Additionally, we spiral out, so we favor local POI's before we ever favor farther POI's.
We also try to pathfind 1 POI at a time instead of collecting multiple POI's then tossing them
all to the pathfinder, so that once we get a match we can return before even looking at other
POI's.
This benefits us in that ideally, a villager will constantly find the near POI's and
not even try to pathfind to the farther POI. Trying to pathfind to distant POI's is
what causes significant lag.
Other improvements here is to stop spamming the POI manager with empty nullables.
Vanilla used them to represent if they needed to load POI data off disk or not.
Well, we load POI data async on chunk load, so we have it, and we surely do not ever
want to load POI data sync either for unloaded chunks!
So this massively reduces object count in the POI hashmaps, resulting in less hash collions,
and also less memory use.
Additionally, unemployed villagers were using significant time due to major ineffeciency in
the code rebuilding data that is static every single invocation for every POI type...
So we cache that and only rebuild it if professions change, which should be never unless
a plugin manipulates and adds custom professions, which it will handle by rebuilding.
diff --git a/src/main/java/net/minecraft/server/BehaviorFindPosition.java b/src/main/java/net/minecraft/server/BehaviorFindPosition.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BehaviorFindPosition.java
+++ b/src/main/java/net/minecraft/server/BehaviorFindPosition.java
@@ -0,0 +0,0 @@ public class BehaviorFindPosition extends Behavior<EntityCreature> {
protected void a(WorldServer worldserver, EntityCreature entitycreature, long i) {
this.f = 0;
- this.d = worldserver.getTime() + (long) worldserver.getRandom().nextInt(20);
+ this.d = worldserver.getTime() + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Paper
VillagePlace villageplace = worldserver.B();
+
+ // Paper start - replace implementation completely
+ BlockPosition blockposition2 = new BlockPosition(entitycreature);
+ int dist = 48;
+ int requiredDist = dist * dist;
+ int cdist = Math.floorDiv(dist, 16);
+ Predicate<VillagePlaceType> predicate = this.a.c();
+ int maxPoiAttempts = 4;
+ int poiAttempts = 0;
+ OUT:
+ for (ChunkCoordIntPair chunkcoordintpair : MCUtil.getSpiralOutChunks(blockposition2, cdist)) {
+ for (int i1 = 0; i1 < 16; i1++) {
+ java.util.Optional<VillagePlaceSection> section = villageplace.getSection(SectionPosition.a(chunkcoordintpair, i1).v());
+ if (section == null || !section.isPresent()) continue;
+ for (java.util.Map.Entry<VillagePlaceType, java.util.Set<VillagePlaceRecord>> e : section.get().getRecords().entrySet()) {
+ if (!predicate.test(e.getKey())) continue;
+ for (VillagePlaceRecord record : e.getValue()) {
+ if (!record.hasVacancy()) continue;
+
+ BlockPosition pos = record.getPosition();
+ long key = pos.asLong();
+ if (this.e.containsKey(key)) {
+ continue;
+ }
+ double poiDist = pos.distanceSquared(blockposition2);
+ if (poiDist <= (double) requiredDist) {
+ this.e.put(key, (long) (this.d + Math.sqrt(poiDist) * 4)); // use dist instead of 40 to blacklist longer if farther distance
+ ++poiAttempts;
+ PathEntity pathentity = entitycreature.getNavigation().a(com.google.common.collect.ImmutableSet.of(pos), 8, false, this.a.d());
+
+ if (pathentity != null && pathentity.h()) {
+ record.decreaseVacancy();
+ GlobalPos globalPos = GlobalPos.create(worldserver.getWorldProvider().getDimensionManager(), pos);
+ entitycreature.getBehaviorController().setMemory(this.b, globalPos);
+ break OUT;
+ }
+ if (poiAttempts >= maxPoiAttempts) {
+ break OUT;
+ }
+ }
+ }
+ }
+ }
+ }
+ // Clean up - vanilla does this only when it runs out, but that would push it to try farther POI's...
+ this.e.long2LongEntrySet().removeIf((entry) -> entry.getLongValue() < this.d);
+ /*
Predicate<BlockPosition> predicate = (blockposition) -> {
long j = blockposition.asLong();
@@ -0,0 +0,0 @@ public class BehaviorFindPosition extends Behavior<EntityCreature> {
return entry.getLongValue() < this.d;
});
}
-
+ */ // Paper end
}
}
diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/RegionFileSection.java
+++ b/src/main/java/net/minecraft/server/RegionFileSection.java
@@ -0,0 +0,0 @@ public class RegionFileSection<R extends MinecraftSerializable> extends RegionFi
@Nullable
protected Optional<R> c(long i) {
- return (Optional) this.c.get(i);
+ return this.c.getOrDefault(i, Optional.empty()); // Paper
}
+ protected final Optional<R> getSection(long i) { return d(i); } // Paper - OBFHELPER
protected Optional<R> d(long i) {
- SectionPosition sectionposition = SectionPosition.a(i);
-
- if (this.b(sectionposition)) {
- return Optional.empty();
- } else {
- Optional<R> optional = this.c(i);
-
- if (optional != null) {
- return optional;
- } else {
- this.b(sectionposition.u());
- optional = this.c(i);
- if (optional == null) {
- throw (IllegalStateException) SystemUtils.c(new IllegalStateException());
- } else {
- return optional;
- }
- }
- }
+ // Paper start - replace method - never load POI data sync, we load this in chunk load already, reduce ops
+ // If it's an unloaded chunk, well too bad.
+ return this.c(i);
+ // Paper end
}
protected boolean b(SectionPosition sectionposition) {
@@ -0,0 +0,0 @@ public class RegionFileSection<R extends MinecraftSerializable> extends RegionFi
private <T> void a(ChunkCoordIntPair chunkcoordintpair, DynamicOps<T> dynamicops, @Nullable T t0) {
if (t0 == null) {
for (int i = 0; i < 16; ++i) {
- this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty());
+ //this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty()); // Paper - NO!!!
}
} else {
Dynamic<T> dynamic = new Dynamic(dynamicops, t0);
@@ -0,0 +0,0 @@ public class RegionFileSection<R extends MinecraftSerializable> extends RegionFi
}, dynamic2);
});
- this.c.put(i1, optional);
+ if (optional.isPresent()) this.c.put(i1, optional); // Paper - NO!!!
optional.ifPresent((minecraftserializable) -> {
this.b(i1);
if (flag) {
@@ -0,0 +0,0 @@ public class RegionFileSection<R extends MinecraftSerializable> extends RegionFi
if (optional != null && optional.isPresent()) {
this.d.add(i);
} else {
- RegionFileSection.LOGGER.warn("No data for position: {}", SectionPosition.a(i));
+ //RegionFileSection.LOGGER.warn("No data for position: {}", SectionPosition.a(i)); // Paper - hush
}
}
diff --git a/src/main/java/net/minecraft/server/VillagePlaceRecord.java b/src/main/java/net/minecraft/server/VillagePlaceRecord.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/VillagePlaceRecord.java
+++ b/src/main/java/net/minecraft/server/VillagePlaceRecord.java
@@ -0,0 +0,0 @@ public class VillagePlaceRecord implements MinecraftSerializable {
return dynamicops.createMap(ImmutableMap.of(dynamicops.createString("pos"), this.a.a(dynamicops), dynamicops.createString("type"), dynamicops.createString(IRegistry.POINT_OF_INTEREST_TYPE.getKey(this.b).toString()), dynamicops.createString("free_tickets"), dynamicops.createInt(this.c)));
}
+ protected final boolean decreaseVacancy() { return b(); } // Paper - OBFHELPER
protected boolean b() {
if (this.c <= 0) {
return false;
@@ -0,0 +0,0 @@ public class VillagePlaceRecord implements MinecraftSerializable {
}
}
+ protected final boolean increaseVacancy() { return c(); } // Paper - OBFHELPER
protected boolean c() {
if (this.c >= this.b.b()) {
return false;
@@ -0,0 +0,0 @@ public class VillagePlaceRecord implements MinecraftSerializable {
}
}
+ public final boolean hasVacancy() { return d(); } // Paper - OBFHELPER
public boolean d() {
return this.c > 0;
}
+ public final boolean isOccupied() { return e(); } // Paper - OBFHELPER
public boolean e() {
return this.c != this.b.b();
}
+ public final BlockPosition getPosition() { return f(); } // Paper
public BlockPosition f() {
return this.a;
}
diff --git a/src/main/java/net/minecraft/server/VillagePlaceSection.java b/src/main/java/net/minecraft/server/VillagePlaceSection.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/VillagePlaceSection.java
+++ b/src/main/java/net/minecraft/server/VillagePlaceSection.java
@@ -0,0 +0,0 @@ public class VillagePlaceSection implements MinecraftSerializable {
private static final Logger LOGGER = LogManager.getLogger();
private final Short2ObjectMap<VillagePlaceRecord> b = new Short2ObjectOpenHashMap();
- private final Map<VillagePlaceType, Set<VillagePlaceRecord>> c = Maps.newHashMap();
+ private final Map<VillagePlaceType, Set<VillagePlaceRecord>> c = Maps.newHashMap(); public final Map<VillagePlaceType, Set<VillagePlaceRecord>> getRecords() { return c; } // Paper - OBFHELPER
private final Runnable d;
private boolean e;
diff --git a/src/main/java/net/minecraft/server/VillagePlaceType.java b/src/main/java/net/minecraft/server/VillagePlaceType.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/VillagePlaceType.java
+++ b/src/main/java/net/minecraft/server/VillagePlaceType.java
@@ -0,0 +0,0 @@ import java.util.stream.Stream;
public class VillagePlaceType {
+ static Set<VillagePlaceType> professionCache; // Paper
private static final Predicate<VillagePlaceType> v = (villageplacetype) -> {
- return ((Set) IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet())).contains(villageplacetype);
+ // Paper start
+ if (professionCache == null) {
+ professionCache = IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet());
+ }
+ return professionCache.contains(villageplacetype);
+ // Paper end
};
public static final Predicate<VillagePlaceType> a = (villageplacetype) -> {
return true;
@@ -0,0 +0,0 @@ public class VillagePlaceType {
}
private static VillagePlaceType a(String s, Set<IBlockData> set, int i, int j) {
- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, j))));
+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, j)))); // Paper - decompile error
}
private static VillagePlaceType a(String s, Set<IBlockData> set, int i, Predicate<VillagePlaceType> predicate, int j) {
- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, predicate, j))));
+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, predicate, j)))); // Paper - decompile error
}
private static VillagePlaceType a(VillagePlaceType villageplacetype) {
diff --git a/src/main/java/net/minecraft/server/VillagerProfession.java b/src/main/java/net/minecraft/server/VillagerProfession.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/VillagerProfession.java
+++ b/src/main/java/net/minecraft/server/VillagerProfession.java
@@ -0,0 +0,0 @@ public class VillagerProfession {
}
static VillagerProfession a(String s, VillagePlaceType villageplacetype, ImmutableSet<Item> immutableset, ImmutableSet<Block> immutableset1, @Nullable SoundEffect soundeffect) {
+ VillagePlaceType.professionCache = null; // Paper
return (VillagerProfession) IRegistry.a((IRegistry) IRegistry.VILLAGER_PROFESSION, new MinecraftKey(s), (Object) (new VillagerProfession(s, villageplacetype, immutableset, immutableset1, soundeffect)));
}
}

View File

@ -1,61 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 10 May 2020 22:49:05 -0400
Subject: [PATCH] Optimize WorldBorder collision checks and air
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
AxisAlignedBB axisalignedbb = this.getBoundingBox();
VoxelShapeCollision voxelshapecollision = VoxelShapeCollision.a(this);
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 = !this.world.getWorldBorder().isInBounds(axisalignedbb) ? Stream.empty() : Stream.of(this.world.getWorldBorder().a()); // Paper
Stream<VoxelShape> stream1 = this.world.b(this, axisalignedbb.a(vec3d), (Set) ImmutableSet.of());
StreamAccumulator<VoxelShape> streamaccumulator = new StreamAccumulator<>(Stream.concat(stream1, stream));
Vec3D vec3d1 = vec3d.g() == 0.0D ? vec3d : a(this, vec3d, axisalignedbb, this.world, voxelshapecollision, streamaccumulator);
diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
if (true) { //public boolean tryAdvance(Consumer<? super VoxelShape> consumer) {*/ // Paper
if (entity != null) {
// Paper end
- VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a();
- boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND);
- boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND);
+ //VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a(); // Paper - only make if collides
+ boolean flag = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().shrink(1.0E-7D)); // Paper
+ boolean flag1 = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().g(1.0E-7D)); // Paper
if (!flag && flag1) {
- collisions.add(voxelshape1);// Paper
+ collisions.add(ICollisionAccess.this.getWorldBorder().a());// Paper
if (returnFast) return collisions;
}
}
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
//IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up
// Paper end
- if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
+ if (!iblockdata.isAir() && (j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { // Paper - fast track air
VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision);
// Paper start - Lithium Collision Optimizations
diff --git a/src/main/java/net/minecraft/server/WorldBorder.java b/src/main/java/net/minecraft/server/WorldBorder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldBorder.java
+++ b/src/main/java/net/minecraft/server/WorldBorder.java
@@ -0,0 +0,0 @@ public class WorldBorder {
return (double) chunkcoordintpair.f() > this.c() && (double) chunkcoordintpair.d() < this.e() && (double) chunkcoordintpair.g() > this.d() && (double) chunkcoordintpair.e() < this.f();
}
+ public final boolean isInBounds(AxisAlignedBB aabb) { return this.a(aabb); } // Paper - OBFHELPER
public boolean a(AxisAlignedBB axisalignedbb) {
return axisalignedbb.maxX > this.c() && axisalignedbb.minX < this.e() && axisalignedbb.maxZ > this.d() && axisalignedbb.minZ < this.f();
}

View File

@ -15,59 +15,49 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList {
world = (WorldServer) entityhuman.world;
}
}
- List<? extends EntityHuman> players1 = world == null ? players : world.players;
- for (int j = 0; j < players1.size(); ++j) {
- EntityHuman entity = players1.get(j);
- if (!(entity instanceof EntityPlayer)) continue;
- EntityPlayer entityplayer = (EntityPlayer) entity;
public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, ResourceKey<World> resourcekey, Packet<?> packet) {
- for (int i = 0; i < this.players.size(); ++i) {
- EntityPlayer entityplayer = (EntityPlayer) this.players.get(i);
+ WorldServer world = null;
+ if (entityhuman != null && entityhuman.world instanceof WorldServer) {
+ world = (WorldServer) entityhuman.world;
+ }
- // CraftBukkit start - Test if player receiving packet can see the source of the packet
- if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) {
- continue;
+ // Paper start
+ if ((world == null || world.chunkProvider == null) && dimensionmanager != null) {
+ world = dimensionmanager.world;
+ }
+ if (world == null) {
+ LOGGER.error("Sending packet to invalid world" + entityhuman + " " + dimensionmanager + " - " + packet.getClass().getName(), new Throwable());
+ return; // ??? shouldn't happen...
+ world = server.getWorldServer(resourcekey);
+ }
+ PlayerChunkMap chunkMap = world.chunkMap;
+ PlayerChunkMap chunkMap = world != null ? world.getChunkProvider().playerChunkMap : null;
+ Object[] backingSet;
+ if (chunkMap == null) {
+ // Really shouldn't happen...
+ backingSet = world.players.toArray();
+ backingSet = world != null ? world.players.toArray() : players.toArray();
+ } else {
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> nearbyPlayers = chunkMap.playerViewDistanceBroadcastMap.getObjectsInRange(MCUtil.fastFloor(d0) >> 4, MCUtil.fastFloor(d2) >> 4);
+ if (nearbyPlayers == null) {
+ return;
+ }
}
+ backingSet = nearbyPlayers.getBackingSet();
+ }
+
+ for (Object object : backingSet) {
+ if (!(object instanceof EntityPlayer)) continue;
+ EntityPlayer entityplayer = (EntityPlayer) object;
// Paper end
+ // Paper end
+
+ // CraftBukkit start - Test if player receiving packet can see the source of the packet
+ //if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { // Paper
+ //continue; // Paper
+ //} // Paper
// CraftBukkit end
// CraftBukkit start - Test if player receiving packet can see the source of the packet
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {
}
}
// Paper end
+ public final PlayerChunkMap chunkMap; // Paper
private final MinecraftServer server;
private final WorldNBTStorage dataManager;
public boolean savingDisabled;
@@ -0,0 +0,0 @@ public class WorldServer extends World {
}, gameprofilerfiller, false, gen, env);
this.pvpMode = minecraftserver.getPVP();
worlddata.world = this;
+ if (chunkProvider == null) { chunkMap = null; new Throwable("World created without a ChunkProvider!").printStackTrace(); } // Paper - figure out if something weird happened here
+ else chunkMap = ((ChunkProviderServer) chunkProvider).playerChunkMap;
// CraftBukkit end
if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) {
this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { // Paper - optimise TickListServer
- if (entityplayer != entityhuman && entityplayer.world.getDimensionKey() == resourcekey) {
+ if (entityplayer != entityhuman && entityplayer.world.getDimensionKey() == resourcekey && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { // Paper
double d4 = d0 - entityplayer.locX();
double d5 = d1 - entityplayer.locY();
double d6 = d2 - entityplayer.locZ();

View File

@ -201,7 +201,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Date buildDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(Main.class.getPackage().getImplementationVendor()); // Paper
Calendar deadline = Calendar.getInstance();
deadline.add(Calendar.DAY_OF_YEAR, -3);
deadline.add(Calendar.DAY_OF_YEAR, -1);
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java

View File

@ -12,20 +12,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
return null;
return getHandle().sleepTicks;
}
+ // Paper start - Potential bed api
+ @Override
+ public Location getPotentialBedLocation() {
+ BlockPosition bed = getHandle().getBed();
+ EntityPlayer handle = (EntityPlayer) getHandle();
+ BlockPosition bed = handle.getSpawn();
+ if (bed == null) {
+ return null;
+ }
+ return new Location(getServer().getWorld(getHandle().spawnWorld), bed.getX(), bed.getY(), bed.getZ());
+
+ net.minecraft.server.WorldServer worldServer = handle.server.getWorldServer(handle.getSpawnDimension());
+ if (worldServer == null) {
+ return null;
+ }
+ return new Location(worldServer.getWorld(), bed.getX(), bed.getY(), bed.getZ());
+ }
+ // Paper end
+
@Override
public void setBedSpawnLocation(Location location) {
setBedSpawnLocation(location, false);
public boolean sleep(Location location, boolean force) {
Preconditions.checkArgument(location != null, "Location cannot be null");

View File

@ -43,8 +43,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
String title = container.getBukkitView().getTitle();
- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title)));
+ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); // Paper
- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0]));
+ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper
getHandle().activeContainer = container;
getHandle().activeContainer.addSlotListener(player);
}
@ -52,8 +52,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Now open the window
Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory.getTopInventory());
String title = inventory.getTitle();
- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title)));
+ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); // Paper
- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0]));
+ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper
player.activeContainer = container;
player.activeContainer.addSlotListener(player);
}

View File

@ -26,6 +26,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return; // ... thanks Mojang for letting move calls teleport across dimensions.
+ }
+ // Paper end - prevent position desync
this.player.onGround = packetplayinflying.b();
double d12 = d8;
d7 = d4 - this.player.locX();

View File

@ -31,9 +31,9 @@ diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/m
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -0,0 +0,0 @@ public class Block implements IMaterial {
protected final SoundEffectType stepSound;
protected final Material material;
@@ -0,0 +0,0 @@ public class Block extends BlockBase implements IMaterial {
protected final BlockStateList<Block, IBlockData> blockStateList;
private IBlockData blockData;
// Paper start
+ public final boolean isDestroyable() {
+ return com.destroystokyo.paper.PaperConfig.allowBlockPermanentBreakingExploits ||
@ -46,7 +46,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public co.aikar.timings.Timing timing;
public co.aikar.timings.Timing getTiming() {
if (timing == null) {
@@ -0,0 +0,0 @@ public class Block implements IMaterial {
diff --git a/src/main/java/net/minecraft/server/BlockBase.java b/src/main/java/net/minecraft/server/BlockBase.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockBase.java
+++ b/src/main/java/net/minecraft/server/BlockBase.java
@@ -0,0 +0,0 @@ public abstract class BlockBase {
@Deprecated
public boolean a(IBlockData iblockdata, BlockActionContext blockactioncontext) {
@ -55,15 +59,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
@Deprecated
@@ -0,0 +0,0 @@ public class Block implements IMaterial {
@@ -0,0 +0,0 @@ public abstract class BlockBase {
public Block getBlock() {
return (Block) this.c;
}
-
+ // Paper start
+ public final boolean isDestroyable() {
+ return getBlock().isDestroyable();
+ }
+ // Paper end
public Material getMaterial() {
return this.g;
}
@@ -0,0 +0,0 @@ public abstract class BlockBase {
}
@Deprecated
public EnumPistonReaction getPushReaction(IBlockData iblockdata) {
- return this.material.getPushReaction();
+ return !blockData.isDestroyable() ? EnumPistonReaction.BLOCK : this.material.getPushReaction(); // Paper
}
public EnumPistonReaction getPushReaction() {
- return this.getBlock().getPushReaction(this.p());
+ return !isDestroyable() ? EnumPistonReaction.BLOCK : this.getBlock().getPushReaction(this.p()); // Paper
}
public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) {
public boolean i(IBlockAccess iblockaccess, BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockPiston.java
@ -82,14 +99,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!world.isClientSide) {
boolean flag = this.a(world, blockposition, enumdirection);
@@ -0,0 +0,0 @@ public class BlockPiston extends BlockDirectional {
}
IBlockData iblockdata1 = (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT);
world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT), 3);
world.setTypeAndData(blockposition, iblockdata1, 20);
- world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true));
+ world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true)); // Paper - diff on change, j is facing direction
+ world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true)); // Paper - diff on change, j is facing direction - copy this above
world.update(blockposition, iblockdata1.getBlock());
iblockdata1.a(world, blockposition, 2);
if (this.sticky) {
BlockPosition blockposition1 = blockposition.b(enumdirection.getAdjacentX() * 2, enumdirection.getAdjacentY() * 2, enumdirection.getAdjacentZ() * 2);
IBlockData iblockdata1 = world.getType(blockposition1);
@@ -0,0 +0,0 @@ public class BlockPiston extends BlockDirectional {
}
}
@ -116,8 +133,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
IBlockData iblockdata = this.world.getType(blockposition);
+ if (!iblockdata.isDestroyable()) continue; // Paper
Fluid fluid = iblockdata.getFluid(); // Paper
Optional<Float> optional = this.k.a(this, this.world, blockposition, iblockdata, fluid);
if (!iblockdata.isAir() || !fluid.isEmpty()) {
@@ -0,0 +0,0 @@ public class Explosion {
IBlockData iblockdata = this.world.getType(blockposition);
Block block = iblockdata.getBlock();
@ -127,28 +144,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BlockPosition blockposition1 = blockposition.immutableCopy();
this.world.getMethodProfiler().enter("explosion_blocks");
diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/IBlockData.java
+++ b/src/main/java/net/minecraft/server/IBlockData.java
@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
return (CraftBlockData) cachedCraftBlockData.clone();
}
// Paper end
+ // Paper start
+ public final boolean isDestroyable() {
+ return getBlock().isDestroyable();
+ }
+ // Paper end
public Material getMaterial() {
return this.getBlock().k(this);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) {
public boolean a(BlockPosition blockposition, IBlockData iblockdata, int i, int j) {
// CraftBukkit start - tree generation
if (this.captureTreeGeneration) {
+ // Paper start

View File

@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - remove allocation of Vec3D here
boolean flag4 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L;
if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.onGround) {
if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.isOnGround()) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java

View File

@ -1,178 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 9 May 2020 18:36:27 -0400
Subject: [PATCH] Remove some Streams usage in Entity Collision
While there is more down the collision system, remove some of the wrapping
Spliterator stuff as even this wrapper stream has shown up in profiling.
With other collision optimizations, we might also even avoid inner streams too.
diff --git a/src/main/java/net/minecraft/server/GeneratorAccess.java b/src/main/java/net/minecraft/server/GeneratorAccess.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/GeneratorAccess.java
+++ b/src/main/java/net/minecraft/server/GeneratorAccess.java
@@ -0,0 +0,0 @@ public interface GeneratorAccess extends IEntityAccess, IWorldReader, VirtualLev
this.a((EntityHuman) null, i, blockposition, j);
}
+ @Override default java.util.List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) {return IEntityAccess.super.getEntityCollisions(entity, axisalignedbb, set, returnFast); } // Paper
@Override
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
return IEntityAccess.super.b(entity, axisalignedbb, set);
diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
try { if (entity != null) entity.collisionLoadChunks = true; // Paper
- return this.c(entity, axisalignedbb, set).allMatch(VoxelShape::isEmpty);
+ // Paper start - reduce stream usage
+ java.util.List<VoxelShape> blockCollisions = getBlockCollision(entity, axisalignedbb, true);
+ for (int i = 0; i < blockCollisions.size(); i++) {
+ VoxelShape blockCollision = blockCollisions.get(i);
+ if (!blockCollision.isEmpty()) {
+ return false;
+ }
+ }
+ return getEntityCollisions(entity, axisalignedbb, set, true).isEmpty();
+ // Paper end
} finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper
}
+ default java.util.List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) { return java.util.Collections.emptyList(); } // Paper
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
return Stream.empty();
}
default Stream<VoxelShape> c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
- return Streams.concat(new Stream[]{this.b(entity, axisalignedbb), this.b(entity, axisalignedbb, set)});
+ // Paper start - reduce stream usage
+ java.util.List<VoxelShape> blockCollisions = getBlockCollision(entity, axisalignedbb, false);
+ java.util.List<VoxelShape> entityCollisions = getEntityCollisions(entity, axisalignedbb, set, false);
+ return Stream.concat(blockCollisions.stream(), entityCollisions.stream());
+ // Paper end
}
default Stream<VoxelShape> b(@Nullable final Entity entity, AxisAlignedBB axisalignedbb) {
+ // Paper start - reduce stream usage
+ java.util.List<VoxelShape> collision = getBlockCollision(entity, axisalignedbb, false);
+ return !collision.isEmpty() ? collision.stream() : Stream.empty();
+ }
+
+ default java.util.List<VoxelShape> getBlockCollision(@Nullable final Entity entity, AxisAlignedBB axisalignedbb, boolean returnFast) {
+ // Paper end
int i = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 1;
int j = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 1;
int k = MathHelper.floor(axisalignedbb.minY - 1.0E-7D) - 1;
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
final BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
final VoxelShape voxelshape = VoxelShapes.a(axisalignedbb);
- return StreamSupport.stream(new AbstractSpliterator<VoxelShape>(Long.MAX_VALUE, 1280) {
- boolean a = entity == null;
-
- public boolean tryAdvance(Consumer<? super VoxelShape> consumer) {
- if (!this.a) {
- this.a = true;
+ // Paper start - reduce stream usage (this part done by Aikar)
+ java.util.List<VoxelShape> collisions = new java.util.ArrayList<>();
+ if (true) {//return StreamSupport.stream(new AbstractSpliterator<VoxelShape>(Long.MAX_VALUE, 1280) {
+ if (true) { //public boolean tryAdvance(Consumer<? super VoxelShape> consumer) {*/ // Paper
+ if (entity != null) {
+ // Paper end
VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a();
boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND);
boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND);
if (!flag && flag1) {
- consumer.accept(voxelshape1);
- return true;
+ collisions.add(voxelshape1);// Paper
+ if (returnFast) return collisions;
}
}
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
);
if (iblockdata == null) {
if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) {
- VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z)));
- consumer.accept(voxelshape3);
- return true;
+ collisions.add(VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z))));
+ if (returnFast) return collisions;
}
} else {
//blockposition_mutableblockposition.d(k1, l1, i2); // moved up
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
if (voxelshape2 == VoxelShapes.fullCube()) {
if (axisalignedbb.intersects(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D)) {
- consumer.accept(voxelshape2.offset(x, y, z));
- return true;
+ collisions.add(voxelshape2.offset(x, y, z));
+ if (returnFast) return collisions;
}
} else {
VoxelShape shape = voxelshape2.offset(x, y, z);
if (VoxelShapes.applyOperation(shape, voxelshape, OperatorBoolean.AND)) {
- consumer.accept(shape);
- return true;
+ collisions.add(shape);
+ if (returnFast) return collisions;
}
// Paper end
}
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
}
}
- return false;
+ //return false; // Paper
}
- }, false);
+ } //}, false);
+ return collisions; // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/IEntityAccess.java
+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
@@ -0,0 +0,0 @@ public interface IEntityAccess {
// Paper start - remove streams from entity collision
if (axisalignedbb.getAverageSideLength() < 1.0E-7D) {
return Stream.empty();
-
}
+ return getEntityCollisions(entity, axisalignedbb, set, false).stream();
+ }
+ default List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) {
AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D);
List<Entity> entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection);
List<VoxelShape> shapes = new java.util.ArrayList<>();
@@ -0,0 +0,0 @@ public interface IEntityAccess {
if (otherEntityBox != null && selection.intersects(otherEntityBox)) {
shapes.add(VoxelShapes.of(otherEntityBox));
+ if (returnFast) return shapes;
}
if (entity != null) {
@@ -0,0 +0,0 @@ public interface IEntityAccess {
if (otherEntityHardBox != null && selection.intersects(otherEntityHardBox)) {
shapes.add(VoxelShapes.of(otherEntityHardBox));
+ if (returnFast) return shapes;
}
}
}
- return shapes.stream();
+ return shapes;
// Paper end
}

View File

@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -0,0 +0,0 @@ public class Main {
deadline.add(Calendar.DAY_OF_YEAR, -3);
deadline.add(Calendar.DAY_OF_YEAR, -1);
if (buildDate.before(deadline.getTime())) {
System.err.println("*** Error, this build is outdated ***");
- System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/go/outdated-spigot ***");

View File

@ -22,13 +22,12 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
this.worldDataServer.setThundering(flag1);
}
// CraftBukkit end
- @Override
- public BiomeBase a(int i, int j, int k) {
+
+ public BiomeBase getBiomeBySeed(int i, int j, int k) { return a(i, j, k); } // Paper - OBFHELPER
+ @Override public BiomeBase a(int i, int j, int k) {
return this.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(i, j, k);

View File

@ -60,4 +60,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
@Override
public void reloadData() {
console.reload();
CommandReload.reload(console);

View File

@ -102,8 +102,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ apacket = new Packet[10];
+ }
+ // Paper end
apacket[0] = new PacketPlayOutMapChunk(chunk, 65535);
apacket[1] = new PacketPlayOutLightUpdate(chunk.getPos(), this.lightEngine);
apacket[0] = new PacketPlayOutMapChunk(chunk, 65535, true);
apacket[1] = new PacketPlayOutLightUpdate(chunk.getPos(), this.lightEngine, true);
+
+ // Paper start - Fix MC-162253
+ final int lightMask = getLightMask(chunk);
@ -127,7 +127,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ continue;
+ }
+
+ apacket[i] = new PacketPlayOutLightUpdate(new ChunkCoordIntPair(chunk.getPos().x + x, chunk.getPos().z + z), lightEngine, updateLightMask, 0);
+ apacket[i] = new PacketPlayOutLightUpdate(new ChunkCoordIntPair(chunk.getPos().x + x, chunk.getPos().z + z), lightEngine, updateLightMask, 0, true);
+ }
+ }
+ }

@ -1 +1 @@
Subproject commit 6f3c5f4a5a0867ef265df9d58b48bdc43079e3dd
Subproject commit 8edeffe67d1821afd48d16cd0ec2572251f24ee8

@ -1 +1 @@
Subproject commit 3f0c333870ba74705e98d19322174d6f0c10c900
Subproject commit d1fb662ec53c4fd8bc718039b76a3e9a11346371

@ -1 +1 @@
Subproject commit 758abbeee4e12f5ff65470999dd9955d0ebb49cd
Subproject commit 8fc58f10ab171ca1979afa2065909214a0ffab32