From 7c7f8b83abeab860159293b13089b67f2a4b3d0d Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 18 Mar 2016 23:55:31 -0400 Subject: [PATCH] Optimized Light Level Comparisons Use an optimized method to test if a block position meets a desired light level. This method benefits from returning as soon as the desired light level matches. Also Optimize Grass more --- .../0040-Disable-explosion-knockback.patch | 12 +- Spigot-Server-Patches/0057-Timings-v2.patch | 18 +-- ...working-with-arrows-stuck-in-living-.patch | 8 +- .../0093-Add-World-Util-Methods.patch | 97 +++++++++++++ ...94-Optimized-Light-Level-Comparisons.patch | 135 ++++++++++++++++++ 5 files changed, 251 insertions(+), 19 deletions(-) create mode 100644 Spigot-Server-Patches/0093-Add-World-Util-Methods.patch create mode 100644 Spigot-Server-Patches/0094-Optimized-Light-Level-Comparisons.patch diff --git a/Spigot-Server-Patches/0040-Disable-explosion-knockback.patch b/Spigot-Server-Patches/0040-Disable-explosion-knockback.patch index 470046c3b..23b8d3f59 100644 --- a/Spigot-Server-Patches/0040-Disable-explosion-knockback.patch +++ b/Spigot-Server-Patches/0040-Disable-explosion-knockback.patch @@ -1,4 +1,4 @@ -From af80def89b8b7064581e872b121842e79a182369 Mon Sep 17 00:00:00 2001 +From 79f474e20de6c1d0267e736b5310a2054523816f Mon Sep 17 00:00:00 2001 From: Sudzzy Date: Wed, 2 Mar 2016 14:48:03 -0600 Subject: [PATCH] Disable explosion knockback @@ -19,10 +19,10 @@ index 78a1e59..6fce2b3 100644 + } } diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index b864c5a..f3fdd4c 100644 +index 8122cae..d24987b 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -853,12 +853,14 @@ public abstract class EntityLiving extends Entity { +@@ -854,12 +854,14 @@ public abstract class EntityLiving extends Entity { } } @@ -37,7 +37,7 @@ index b864c5a..f3fdd4c 100644 this.world.broadcastEntityEffect(this, (byte) 2); } -@@ -882,6 +884,8 @@ public abstract class EntityLiving extends Entity { +@@ -883,6 +885,8 @@ public abstract class EntityLiving extends Entity { } } @@ -47,7 +47,7 @@ index b864c5a..f3fdd4c 100644 SoundEffect soundeffect = this.bS(); diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java -index afe402e..cd2fb14 100644 +index 5bb2510..418ee29 100644 --- a/src/main/java/net/minecraft/server/Explosion.java +++ b/src/main/java/net/minecraft/server/Explosion.java @@ -145,7 +145,7 @@ public class Explosion { @@ -69,5 +69,5 @@ index afe402e..cd2fb14 100644 } } -- -2.7.3 +2.7.4 diff --git a/Spigot-Server-Patches/0057-Timings-v2.patch b/Spigot-Server-Patches/0057-Timings-v2.patch index 37fa6c10b..341e8f8c7 100644 --- a/Spigot-Server-Patches/0057-Timings-v2.patch +++ b/Spigot-Server-Patches/0057-Timings-v2.patch @@ -1,4 +1,4 @@ -From 1630cb02eea11c5c6a1d5b71c2ec173a5f4d7cc0 Mon Sep 17 00:00:00 2001 +From 9f7f98e15f55f83febc8e32b4e98f89f516109b2 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 3 Mar 2016 04:00:11 -0600 Subject: [PATCH] Timings v2 @@ -328,7 +328,7 @@ index cf58f74..38bc9c0 100644 public void recalcPosition() { diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index f3fdd4c..d2f7cc2 100644 +index d24987b..1d5ea58 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -24,7 +24,7 @@ import org.bukkit.event.entity.EntityRegainHealthEvent; @@ -340,7 +340,7 @@ index f3fdd4c..d2f7cc2 100644 public abstract class EntityLiving extends Entity { -@@ -1688,7 +1688,6 @@ public abstract class EntityLiving extends Entity { +@@ -1693,7 +1693,6 @@ public abstract class EntityLiving extends Entity { } public void m() { @@ -348,7 +348,7 @@ index f3fdd4c..d2f7cc2 100644 super.m(); this.cu(); if (!this.world.isClientSide) { -@@ -1761,9 +1760,7 @@ public abstract class EntityLiving extends Entity { +@@ -1766,9 +1765,7 @@ public abstract class EntityLiving extends Entity { } } @@ -358,7 +358,7 @@ index f3fdd4c..d2f7cc2 100644 double d0 = this.locX - this.lastX; double d1 = this.locZ - this.lastZ; float f = (float) (d0 * d0 + d1 * d1); -@@ -1832,8 +1829,6 @@ public abstract class EntityLiving extends Entity { +@@ -1837,8 +1834,6 @@ public abstract class EntityLiving extends Entity { } else { this.bo = 0; } @@ -367,7 +367,7 @@ index f3fdd4c..d2f7cc2 100644 } protected float h(float f, float f1) { -@@ -1898,7 +1893,6 @@ public abstract class EntityLiving extends Entity { +@@ -1903,7 +1898,6 @@ public abstract class EntityLiving extends Entity { } this.world.methodProfiler.a("ai"); @@ -375,7 +375,7 @@ index f3fdd4c..d2f7cc2 100644 if (this.cf()) { this.bc = false; this.bd = 0.0F; -@@ -1909,7 +1903,6 @@ public abstract class EntityLiving extends Entity { +@@ -1914,7 +1908,6 @@ public abstract class EntityLiving extends Entity { this.doTick(); this.world.methodProfiler.b(); } @@ -383,7 +383,7 @@ index f3fdd4c..d2f7cc2 100644 this.world.methodProfiler.b(); this.world.methodProfiler.a("jump"); -@@ -1932,14 +1925,10 @@ public abstract class EntityLiving extends Entity { +@@ -1937,14 +1930,10 @@ public abstract class EntityLiving extends Entity { this.be *= 0.98F; this.bf *= 0.9F; this.r(); @@ -528,7 +528,7 @@ index d898428..f579d28 100644 private static Map> f = Maps.newHashMap(); private static Map, String> g = Maps.newHashMap(); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 1815f79..21b0986 100644 +index fc38527..98df4f4 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -18,11 +18,11 @@ import com.google.common.collect.Maps; diff --git a/Spigot-Server-Patches/0080-Add-methods-for-working-with-arrows-stuck-in-living-.patch b/Spigot-Server-Patches/0080-Add-methods-for-working-with-arrows-stuck-in-living-.patch index ae485788d..1f6a597ac 100644 --- a/Spigot-Server-Patches/0080-Add-methods-for-working-with-arrows-stuck-in-living-.patch +++ b/Spigot-Server-Patches/0080-Add-methods-for-working-with-arrows-stuck-in-living-.patch @@ -1,14 +1,14 @@ -From fe207a679722e373b467c738106f8a5566bb9b8c Mon Sep 17 00:00:00 2001 +From cb235b47d0b86defc04f886883da0a4cdae9ab81 Mon Sep 17 00:00:00 2001 From: mrapple Date: Sun, 25 Nov 2012 13:43:39 -0600 Subject: [PATCH] Add methods for working with arrows stuck in living entities diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index d2f7cc2..e5d1fe0 100644 +index 1d5ea58..34abdd4 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -1265,10 +1265,12 @@ public abstract class EntityLiving extends Entity { +@@ -1270,10 +1270,12 @@ public abstract class EntityLiving extends Entity { return (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue(); } @@ -43,5 +43,5 @@ index 6f25d18..693d5cb 100644 + // Paper end } -- -2.7.2 +2.7.4 diff --git a/Spigot-Server-Patches/0093-Add-World-Util-Methods.patch b/Spigot-Server-Patches/0093-Add-World-Util-Methods.patch new file mode 100644 index 000000000..f732d1d2e --- /dev/null +++ b/Spigot-Server-Patches/0093-Add-World-Util-Methods.patch @@ -0,0 +1,97 @@ +From 965df3c371af6bc8f0725dbaa14200f65cf61785 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Fri, 18 Mar 2016 20:16:03 -0400 +Subject: [PATCH] Add World Util Methods + +Methods that can be used for other patches to help improve logic. + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index b356aa6..dafe3b2 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -156,6 +156,12 @@ public abstract class World implements IBlockAccess { + return (CraftServer) Bukkit.getServer(); + } + ++ // Paper start ++ public Chunk getChunkIfLoaded(BlockPosition blockposition) { ++ return ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); ++ } ++ // Paper end ++ + public Chunk getChunkIfLoaded(int x, int z) { + return ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(x, z); + } +@@ -628,6 +634,41 @@ public abstract class World implements IBlockAccess { + } + } + ++ // Paper start - test if meets light level, return faster ++ // logic copied from below ++ public boolean isLightLevel(BlockPosition blockposition, int level) { ++ if (isValidLocation(blockposition)) { ++ if (this.getType(blockposition).f()) { ++ if (this.c(blockposition.up(), false) >= level) { ++ return true; ++ } ++ if (this.c(blockposition.east(), false) >= level) { ++ return true; ++ } ++ if (this.c(blockposition.west(), false) >= level) { ++ return true; ++ } ++ if (this.c(blockposition.south(), false) >= level) { ++ return true; ++ } ++ if (this.c(blockposition.north(), false) >= level) { ++ return true; ++ } ++ return false; ++ } else { ++ if (blockposition.getY() >= 256) { ++ blockposition = new BlockPosition(blockposition.getX(), 255, blockposition.getZ()); ++ } ++ ++ Chunk chunk = this.getChunkAtWorldCoords(blockposition); ++ return chunk.a(blockposition, this.J) >= level; ++ } ++ } else { ++ return true; ++ } ++ } ++ // Paper end ++ + public int getLightLevel(BlockPosition blockposition) { + return this.c(blockposition, true); + } +@@ -742,6 +783,27 @@ public abstract class World implements IBlockAccess { + return this.worldProvider.n()[this.getLightLevel(blockposition)]; + } + ++ // Paper start - reduces need to do isLoaded before getType ++ public IBlockData getTypeIfLoaded(BlockPosition blockposition) { ++ // CraftBukkit start - tree generation ++ if (captureTreeGeneration) { ++ Iterator it = capturedBlockStates.iterator(); ++ while (it.hasNext()) { ++ BlockState previous = it.next(); ++ if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) { ++ return CraftMagicNumbers.getBlock(previous.getTypeId()).fromLegacyData(previous.getRawData()); ++ } ++ } ++ } ++ // CraftBukkit end ++ Chunk chunk = this.getChunkIfLoaded(blockposition); ++ if (chunk != null) { ++ return this.isValidLocation(blockposition) ? chunk.getBlockData(blockposition) : Blocks.AIR.getBlockData(); ++ } ++ return null; ++ } ++ // Paper end ++ + public IBlockData getType(BlockPosition blockposition) { + // CraftBukkit start - tree generation + if (captureTreeGeneration) { +-- +2.7.4 + diff --git a/Spigot-Server-Patches/0094-Optimized-Light-Level-Comparisons.patch b/Spigot-Server-Patches/0094-Optimized-Light-Level-Comparisons.patch new file mode 100644 index 000000000..0fa222b09 --- /dev/null +++ b/Spigot-Server-Patches/0094-Optimized-Light-Level-Comparisons.patch @@ -0,0 +1,135 @@ +From d2745c17b2cd8c0c9edf0d6cc7adeee17cdd4432 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Fri, 18 Mar 2016 21:22:56 -0400 +Subject: [PATCH] Optimized Light Level Comparisons + +Use an optimized method to test if a block position meets a desired light level. + +This method benefits from returning as soon as the desired light level matches. + +diff --git a/src/main/java/net/minecraft/server/BlockCrops.java b/src/main/java/net/minecraft/server/BlockCrops.java +index 7c909d8..5d6e6cb 100644 +--- a/src/main/java/net/minecraft/server/BlockCrops.java ++++ b/src/main/java/net/minecraft/server/BlockCrops.java +@@ -48,7 +48,7 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + super.b(world, blockposition, iblockdata, random); +- if (world.getLightLevel(blockposition.up()) >= 9) { ++ if (world.isLightLevel(blockposition.up(), 9)) { // Paper + int i = this.x(iblockdata); + + if (i < this.g()) { +diff --git a/src/main/java/net/minecraft/server/BlockGrass.java b/src/main/java/net/minecraft/server/BlockGrass.java +index fe55848..8fc736d 100644 +--- a/src/main/java/net/minecraft/server/BlockGrass.java ++++ b/src/main/java/net/minecraft/server/BlockGrass.java +@@ -29,7 +29,8 @@ public class BlockGrass extends Block implements IBlockFragilePlantElement { + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { +- if (world.getLightLevel(blockposition.up()) < 4 && world.getType(blockposition.up()).c() > 2) { ++ int lightLevel = -1; // Paper ++ if (world.getType(blockposition.up()).c() > 2 && (lightLevel = world.getLightLevel(blockposition.up())) < 4) { // Paper - move light check to end to avoid unneeded light lookups + // CraftBukkit start + // world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); + org.bukkit.World bworld = world.getWorld(); +@@ -44,18 +45,25 @@ public class BlockGrass extends Block implements IBlockFragilePlantElement { + } + // CraftBukkit end + } else { +- if (world.getLightLevel(blockposition.up()) >= 9) { ++ // Paper start ++ // If light was calculated above, reuse it, else grab it ++ if (lightLevel == -1) { ++ lightLevel = world.getLightLevel(blockposition.up()); ++ } ++ if (lightLevel >= 9) { ++ // Paper end + for (int i = 0; i < 4; ++i) { + BlockPosition blockposition1 = blockposition.a(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1); + +- if (blockposition1.getY() >= 0 && blockposition1.getY() < 256 && !world.isLoaded(blockposition1)) { ++ IBlockData iblockdata2 = world.getTypeIfLoaded(blockposition1); // Paper - moved up ++ if (iblockdata2 == null) { // Paper + return; + } + + IBlockData iblockdata1 = world.getType(blockposition1.up()); +- IBlockData iblockdata2 = world.getType(blockposition1); ++ //IBlockData iblockdata2 = world.getTypeIfLoaded(blockposition1); // Paper - moved up + +- if (iblockdata2.getBlock() == Blocks.DIRT && iblockdata2.get(BlockDirt.VARIANT) == BlockDirt.EnumDirtVariant.DIRT && world.getLightLevel(blockposition1.up()) >= 4 && iblockdata1.c() <= 2) { ++ if (iblockdata2.getBlock() == Blocks.DIRT && iblockdata2.get(BlockDirt.VARIANT) == BlockDirt.EnumDirtVariant.DIRT && iblockdata1.c() <= 2 && world.isLightLevel(blockposition1.up(), 4)) { // Paper - move last check before isLightLevel to avoid unneeded light checks + // CraftBukkit start + // world.setTypeUpdate(blockposition1, Blocks.GRASS.getBlockData()); + org.bukkit.World bworld = world.getWorld(); +diff --git a/src/main/java/net/minecraft/server/BlockSapling.java b/src/main/java/net/minecraft/server/BlockSapling.java +index 8b34250..b6de103 100644 +--- a/src/main/java/net/minecraft/server/BlockSapling.java ++++ b/src/main/java/net/minecraft/server/BlockSapling.java +@@ -34,7 +34,7 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + super.b(world, blockposition, iblockdata, random); +- if (world.getLightLevel(blockposition.up()) >= 9 && random.nextInt(Math.max(2, (int) (((100 / world.spigotConfig.saplingModifier) * 7) + 0.5F))) == 0) { // Spigot ++ if (world.isLightLevel(blockposition.up(), 9) && random.nextInt(Math.max(2, (int) (((100 / world.spigotConfig.saplingModifier) * 7) + 0.5F))) == 0) { // Spigot // Paper + // CraftBukkit start + world.captureTreeGeneration = true; + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/server/BlockStem.java b/src/main/java/net/minecraft/server/BlockStem.java +index 097d11e..d0fa4ae 100644 +--- a/src/main/java/net/minecraft/server/BlockStem.java ++++ b/src/main/java/net/minecraft/server/BlockStem.java +@@ -47,7 +47,7 @@ public class BlockStem extends BlockPlant implements IBlockFragilePlantElement { + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + super.b(world, blockposition, iblockdata, random); +- if (world.getLightLevel(blockposition.up()) >= 9) { ++ if (world.isLightLevel(blockposition.up(), 9)) { // Paper + float f = BlockCrops.a((Block) this, world, blockposition); + + if (random.nextInt((int) ((100 / (this == Blocks.PUMPKIN_STEM ? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier)) * (25.0F / f)) + 1) == 0) { // Spigot +diff --git a/src/main/java/net/minecraft/server/EntityMonster.java b/src/main/java/net/minecraft/server/EntityMonster.java +index 64f4754..6dc21fb 100644 +--- a/src/main/java/net/minecraft/server/EntityMonster.java ++++ b/src/main/java/net/minecraft/server/EntityMonster.java +@@ -118,17 +118,17 @@ public abstract class EntityMonster extends EntityCreature implements IMonster { + if (this.world.b(EnumSkyBlock.SKY, blockposition) > this.random.nextInt(32)) { + return false; + } else { +- int i = this.world.getLightLevel(blockposition); +- ++ //int i = this.world.getLightLevel(blockposition); // Paper ++ boolean passes; // Paper + if (this.world.V()) { + int j = this.world.af(); + + this.world.c(10); +- i = this.world.getLightLevel(blockposition); ++ passes = world.isLightLevel(blockposition, this.random.nextInt(8)); // Paper + this.world.c(j); +- } ++ } else { passes = world.isLightLevel(blockposition, this.random.nextInt(8)); } // Paper + +- return i <= this.random.nextInt(8); ++ return passes; // Paper + } + } + +diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java +index 949452c..d6c07a2 100644 +--- a/src/main/java/net/minecraft/server/EntityZombie.java ++++ b/src/main/java/net/minecraft/server/EntityZombie.java +@@ -194,7 +194,7 @@ public class EntityZombie extends EntityMonster { + int j1 = j + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1); + int k1 = k + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1); + +- if (this.world.getType(new BlockPosition(i1, j1 - 1, k1)).q() && this.world.getLightLevel(new BlockPosition(i1, j1, k1)) < 10) { ++ if (this.world.getType(new BlockPosition(i1, j1 - 1, k1)).q() && !this.world.isLightLevel(new BlockPosition(i1, j1, k1), 10)) { // Paper + entityzombie.setPosition((double) i1, (double) j1, (double) k1); + if (!this.world.isPlayerNearby((double) i1, (double) j1, (double) k1, 7.0D) && this.world.a(entityzombie.getBoundingBox(), (Entity) entityzombie) && this.world.getCubes(entityzombie, entityzombie.getBoundingBox()).isEmpty() && !this.world.containsLiquid(entityzombie.getBoundingBox())) { + this.world.addEntity(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit +-- +2.7.4 +