mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 20:07:41 +01:00
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:
parent
cfd598512a
commit
bc5acdddad
@ -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>
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
@ -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())) {
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
@ -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)));
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 ***");
|
||||
|
@ -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);
|
||||
|
@ -60,4 +60,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+
|
||||
@Override
|
||||
public void reloadData() {
|
||||
console.reload();
|
||||
CommandReload.reload(console);
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user