mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-01 04:31:58 +01:00
abba3d113b
Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: bb813f6f SPIGOT-4605: Warn against hacking physics CraftBukkit Changes:2ced0233
Don't handle sync packets for kicked playersd5e96882
SPIGOT-4602: Cache reflection in decompile error workaround Spigot Changes: b0f4c22b SPIGOT-4605: Catch more physics problems
160 lines
6.9 KiB
Diff
160 lines
6.9 KiB
Diff
From d51c2d868e810811a350508026017fd96949c0b7 Mon Sep 17 00:00:00 2001
|
|
From: Byteflux <byte@byteflux.net>
|
|
Date: Wed, 2 Mar 2016 11:59:48 -0600
|
|
Subject: [PATCH] Optimize explosions
|
|
|
|
The process of determining an entity's exposure from explosions can be
|
|
expensive when there are hundreds or more entities in range.
|
|
|
|
This patch adds a per-tick cache that is used for storing and retrieving
|
|
an entity's exposure during an explosion.
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
index 5aee23dce..2ec3d9355 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
@@ -144,4 +144,10 @@ public class PaperWorldConfig {
|
|
disableEndCredits = getBoolean("game-mechanics.disable-end-credits", false);
|
|
log("End credits disabled: " + disableEndCredits);
|
|
}
|
|
+
|
|
+ public boolean optimizeExplosions;
|
|
+ private void optimizeExplosions() {
|
|
+ optimizeExplosions = getBoolean("optimize-explosions", false);
|
|
+ log("Optimize explosions: " + optimizeExplosions);
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
|
|
index c4db6367e..3e44b2d54 100644
|
|
--- a/src/main/java/net/minecraft/server/Explosion.java
|
|
+++ b/src/main/java/net/minecraft/server/Explosion.java
|
|
@@ -137,7 +137,7 @@ public class Explosion {
|
|
d8 /= d11;
|
|
d9 /= d11;
|
|
d10 /= d11;
|
|
- double d12 = (double) this.world.a(vec3d, entity.getBoundingBox());
|
|
+ double d12 = this.getBlockDensity(vec3d, entity.getBoundingBox()); // Paper - Optimize explosions
|
|
double d13 = (1.0D - d7) * d12;
|
|
|
|
// CraftBukkit start
|
|
@@ -313,4 +313,85 @@ public class Explosion {
|
|
public List<BlockPosition> getBlocks() {
|
|
return this.blocks;
|
|
}
|
|
+
|
|
+ // Paper start - Optimize explosions
|
|
+ private float getBlockDensity(Vec3D vec3d, AxisAlignedBB aabb) {
|
|
+ if (!this.world.paperConfig.optimizeExplosions) {
|
|
+ return this.world.a(vec3d, aabb);
|
|
+ }
|
|
+ CacheKey key = new CacheKey(this, aabb);
|
|
+ Float blockDensity = this.world.explosionDensityCache.get(key);
|
|
+ if (blockDensity == null) {
|
|
+ blockDensity = this.world.a(vec3d, aabb);
|
|
+ this.world.explosionDensityCache.put(key, blockDensity);
|
|
+ }
|
|
+
|
|
+ return blockDensity;
|
|
+ }
|
|
+
|
|
+ static class CacheKey {
|
|
+ private final World world;
|
|
+ private final double posX, posY, posZ;
|
|
+ private final double minX, minY, minZ;
|
|
+ private final double maxX, maxY, maxZ;
|
|
+
|
|
+ public CacheKey(Explosion explosion, AxisAlignedBB aabb) {
|
|
+ this.world = explosion.world;
|
|
+ this.posX = explosion.posX;
|
|
+ this.posY = explosion.posY;
|
|
+ this.posZ = explosion.posZ;
|
|
+ this.minX = aabb.minX;
|
|
+ this.minY = aabb.minY;
|
|
+ this.minZ = aabb.minZ;
|
|
+ this.maxX = aabb.maxX;
|
|
+ this.maxY = aabb.maxY;
|
|
+ this.maxZ = aabb.maxZ;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(Object o) {
|
|
+ if (this == o) return true;
|
|
+ if (o == null || getClass() != o.getClass()) return false;
|
|
+
|
|
+ CacheKey cacheKey = (CacheKey) o;
|
|
+
|
|
+ if (Double.compare(cacheKey.posX, posX) != 0) return false;
|
|
+ if (Double.compare(cacheKey.posY, posY) != 0) return false;
|
|
+ if (Double.compare(cacheKey.posZ, posZ) != 0) return false;
|
|
+ if (Double.compare(cacheKey.minX, minX) != 0) return false;
|
|
+ if (Double.compare(cacheKey.minY, minY) != 0) return false;
|
|
+ if (Double.compare(cacheKey.minZ, minZ) != 0) return false;
|
|
+ if (Double.compare(cacheKey.maxX, maxX) != 0) return false;
|
|
+ if (Double.compare(cacheKey.maxY, maxY) != 0) return false;
|
|
+ if (Double.compare(cacheKey.maxZ, maxZ) != 0) return false;
|
|
+ return world.equals(cacheKey.world);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int hashCode() {
|
|
+ int result;
|
|
+ long temp;
|
|
+ result = world.hashCode();
|
|
+ temp = Double.doubleToLongBits(posX);
|
|
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
+ temp = Double.doubleToLongBits(posY);
|
|
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
+ temp = Double.doubleToLongBits(posZ);
|
|
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
+ temp = Double.doubleToLongBits(minX);
|
|
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
+ temp = Double.doubleToLongBits(minY);
|
|
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
+ temp = Double.doubleToLongBits(minZ);
|
|
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
+ temp = Double.doubleToLongBits(maxX);
|
|
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
+ temp = Double.doubleToLongBits(maxY);
|
|
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
+ temp = Double.doubleToLongBits(maxZ);
|
|
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
+ return result;
|
|
+ }
|
|
+ }
|
|
+ // Paper end
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index 00f1c36e9..f488c37f7 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -1055,6 +1055,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
|
worldserver.getTracker().updatePlayers();
|
|
this.methodProfiler.exit();
|
|
this.methodProfiler.exit();
|
|
+ worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index c9ba98d89..5788ec6f6 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -22,6 +22,7 @@ import org.apache.logging.log4j.Logger;
|
|
// CraftBukkit start
|
|
import com.google.common.collect.Maps;
|
|
import java.util.ArrayList;
|
|
+import java.util.HashMap; // Paper
|
|
import java.util.Map;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.block.BlockState;
|
|
@@ -139,6 +140,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
|
private org.spigotmc.TickLimiter entityLimiter;
|
|
private org.spigotmc.TickLimiter tileLimiter;
|
|
private int tileTickPosition;
|
|
+ public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
|
|
|
|
public CraftWorld getWorld() {
|
|
return this.world;
|
|
--
|
|
2.20.1
|
|
|