More 1.14 work
This commit is contained in:
parent
36873bf2d6
commit
b4b181a1fb
73 changed files with 936 additions and 936 deletions
410
removed/1.14/0115-Activation-Range-Improvements.patch
Normal file
410
removed/1.14/0115-Activation-Range-Improvements.patch
Normal file
|
@ -0,0 +1,410 @@
|
|||
From 537b37247849b22c5058f77c9c5134fd7b25a5cf Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 13 May 2016 01:38:06 -0400
|
||||
Subject: [PATCH] Activation Range Improvements
|
||||
|
||||
Optimizes performance of Activation Range
|
||||
|
||||
Fixes and adds new Immunities to improve gameplay behavior
|
||||
|
||||
Adds water Mobs to activation range config and nerfs fish
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
index bc364ce371..80e13dfb2e 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
@@ -387,6 +387,7 @@ public class BlockPosition extends BaseBlockPosition {
|
||||
this.c = i;
|
||||
}
|
||||
|
||||
+ public BlockPosition toBlockPosition() { return h(); } // Paper - OBFHELPER
|
||||
public BlockPosition h() {
|
||||
return new BlockPosition(this);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
||||
index 82994db643..462f94ed18 100644
|
||||
--- a/src/main/java/net/minecraft/server/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/server/Entity.java
|
||||
@@ -592,6 +592,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
||||
this.recalcPosition();
|
||||
} else {
|
||||
if (enummovetype == EnumMoveType.PISTON) {
|
||||
+ this.activatedTick = MinecraftServer.currentTick + 20; // Paper
|
||||
long i = this.world.getTime();
|
||||
|
||||
if (i != this.aM) {
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java
|
||||
index 20b7c2c6dc..d659c57dbe 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityCreature.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityCreature.java
|
||||
@@ -7,6 +7,7 @@ import org.bukkit.event.entity.EntityUnleashEvent;
|
||||
public abstract class EntityCreature extends EntityInsentient {
|
||||
|
||||
public org.bukkit.craftbukkit.entity.CraftCreature getBukkitCreature() { return (org.bukkit.craftbukkit.entity.CraftCreature) super.getBukkitEntity(); } // Paper
|
||||
+ public BlockPosition movingTarget = null; public BlockPosition getMovingTarget() { return movingTarget; } // Paper
|
||||
private BlockPosition a;
|
||||
private float b;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java
|
||||
index e5322de974..c530824596 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
|
||||
@@ -105,6 +105,17 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||
return this.lookController;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void inactiveTick() {
|
||||
+ super.inactiveTick();
|
||||
+ this.goalSelector.inactiveTick();
|
||||
+ if (this.targetSelector.inactiveTick()) {
|
||||
+ this.targetSelector.doTick();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public ControllerMove getControllerMove() {
|
||||
return this.moveController;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
index e8f2f11c4d..c0ef0c51f1 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
@@ -74,7 +74,7 @@ public abstract class EntityLiving extends Entity {
|
||||
public float aT;
|
||||
public float aU;
|
||||
public EntityHuman killer;
|
||||
- protected int lastDamageByPlayerTime;
|
||||
+ public int lastDamageByPlayerTime; // Paper - public
|
||||
protected boolean killed;
|
||||
protected int ticksFarFromPlayer;
|
||||
protected float aZ;
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java
|
||||
index b19bd2b99a..5e19768710 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityLlama.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLlama.java
|
||||
@@ -363,6 +363,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
|
||||
return this.bR != null;
|
||||
}
|
||||
|
||||
+ public boolean inCaravan() { return this.em(); } // Paper - OBFHELPER
|
||||
public boolean em() {
|
||||
return this.bQ != null;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java
|
||||
index a146a8b459..a19853463c 100644
|
||||
--- a/src/main/java/net/minecraft/server/PathfinderGoal.java
|
||||
+++ b/src/main/java/net/minecraft/server/PathfinderGoal.java
|
||||
@@ -18,7 +18,10 @@ public abstract class PathfinderGoal {
|
||||
|
||||
public void c() {}
|
||||
|
||||
- public void d() {}
|
||||
+ public void d() {
|
||||
+ onTaskReset(); // Paper
|
||||
+ }
|
||||
+ public void onTaskReset() {} // Paper
|
||||
|
||||
public void e() {}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java
|
||||
index d5c08aa7cb..756d63239c 100644
|
||||
--- a/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java
|
||||
+++ b/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java
|
||||
@@ -2,12 +2,12 @@ package net.minecraft.server;
|
||||
|
||||
public abstract class PathfinderGoalGotoTarget extends PathfinderGoal {
|
||||
|
||||
- private final EntityCreature f;
|
||||
+ private final EntityCreature f;public EntityCreature getEntity() { return f; } // Paper - OBFHELPER
|
||||
public double a;
|
||||
protected int b;
|
||||
protected int c;
|
||||
private int g;
|
||||
- protected BlockPosition d;
|
||||
+ protected BlockPosition d; public BlockPosition getTarget() { return d; } public void setTarget(BlockPosition pos) { this.d = pos; getEntity().movingTarget = pos != BlockPosition.ZERO ? pos : null; } // Paper - OBFHELPER
|
||||
private boolean h;
|
||||
private final int i;
|
||||
private final int j;
|
||||
@@ -16,6 +16,13 @@ public abstract class PathfinderGoalGotoTarget extends PathfinderGoal {
|
||||
public PathfinderGoalGotoTarget(EntityCreature entitycreature, double d0, int i) {
|
||||
this(entitycreature, d0, i, 1);
|
||||
}
|
||||
+ // Paper start - activation range improvements
|
||||
+ @Override
|
||||
+ public void onTaskReset() {
|
||||
+ super.onTaskReset();
|
||||
+ setTarget(BlockPosition.ZERO);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public PathfinderGoalGotoTarget(EntityCreature entitycreature, double d0, int i, int j) {
|
||||
this.d = BlockPosition.ZERO;
|
||||
@@ -94,6 +101,7 @@ public abstract class PathfinderGoalGotoTarget extends PathfinderGoal {
|
||||
blockposition_mutableblockposition.g(blockposition).d(i1, k - 1, j1);
|
||||
if (this.f.f((BlockPosition) blockposition_mutableblockposition) && this.a(this.f.world, blockposition_mutableblockposition)) {
|
||||
this.d = blockposition_mutableblockposition;
|
||||
+ setTarget(blockposition_mutableblockposition.toBlockPosition()); // Paper
|
||||
return true;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
||||
index f3df91181f..3e2f9c749b 100644
|
||||
--- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
||||
+++ b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
||||
@@ -11,10 +11,10 @@ public class PathfinderGoalSelector {
|
||||
|
||||
private static final Logger a = LogManager.getLogger();
|
||||
private final Set<PathfinderGoalSelector.PathfinderGoalSelectorItem> b = Sets.newLinkedHashSet();
|
||||
- private final Set<PathfinderGoalSelector.PathfinderGoalSelectorItem> c = Sets.newLinkedHashSet();
|
||||
+ private final Set<PathfinderGoalSelector.PathfinderGoalSelectorItem> c = Sets.newLinkedHashSet();private Set<PathfinderGoalSelector.PathfinderGoalSelectorItem> getExecutingTasks() { return c; }// Paper - OBFHELPER
|
||||
private final MethodProfiler d;
|
||||
- private int e;
|
||||
- private int f = 3;
|
||||
+ private int e;private int getCurRate() { return e; } private void incRate() { this.e++; }// Paper - OBFHELPER
|
||||
+ private int f = 3;private int getTickRate() { return f; } // Paper - OBFHELPER
|
||||
private int g;
|
||||
|
||||
public PathfinderGoalSelector(MethodProfiler methodprofiler) {
|
||||
@@ -25,6 +25,20 @@ public class PathfinderGoalSelector {
|
||||
this.b.add(new PathfinderGoalSelector.PathfinderGoalSelectorItem(i, pathfindergoal));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public boolean inactiveTick() {
|
||||
+ if (getCurRate() % getTickRate() != 0) {
|
||||
+ incRate();
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ public boolean hasTasks() {
|
||||
+ return !getExecutingTasks().isEmpty();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public void a(PathfinderGoal pathfindergoal) {
|
||||
Iterator iterator = this.b.iterator();
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
index 09df00e94b..d08ef3fe10 100644
|
||||
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
||||
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
@@ -2,6 +2,8 @@ package org.spigotmc;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
+
|
||||
+import co.aikar.timings.MinecraftTimings;
|
||||
import net.minecraft.server.AxisAlignedBB;
|
||||
import net.minecraft.server.Chunk;
|
||||
import net.minecraft.server.Entity;
|
||||
@@ -13,25 +15,29 @@ import net.minecraft.server.EntityCreature;
|
||||
import net.minecraft.server.EntityCreeper;
|
||||
import net.minecraft.server.EntityEnderCrystal;
|
||||
import net.minecraft.server.EntityEnderDragon;
|
||||
-import net.minecraft.server.EntityFallingBlock; // Paper
|
||||
+import net.minecraft.server.EntityFallingBlock;
|
||||
import net.minecraft.server.EntityFireball;
|
||||
import net.minecraft.server.EntityFireworks;
|
||||
+import net.minecraft.server.EntityFish;
|
||||
import net.minecraft.server.EntityHuman;
|
||||
+import net.minecraft.server.EntityInsentient;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
+import net.minecraft.server.EntityLlama;
|
||||
import net.minecraft.server.EntityMonster;
|
||||
import net.minecraft.server.EntityProjectile;
|
||||
import net.minecraft.server.EntitySheep;
|
||||
-import net.minecraft.server.EntitySlice;
|
||||
import net.minecraft.server.EntitySlime;
|
||||
import net.minecraft.server.EntityTNTPrimed;
|
||||
import net.minecraft.server.EntityThrownTrident;
|
||||
import net.minecraft.server.EntityVillager;
|
||||
+import net.minecraft.server.EntityWaterAnimal;
|
||||
import net.minecraft.server.EntityWeather;
|
||||
import net.minecraft.server.EntityWither;
|
||||
+import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.MathHelper;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.NavigationGuardian;
|
||||
import net.minecraft.server.World;
|
||||
-import co.aikar.timings.MinecraftTimings;
|
||||
|
||||
public class ActivationRange
|
||||
{
|
||||
@@ -39,6 +45,7 @@ public class ActivationRange
|
||||
static AxisAlignedBB maxBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
|
||||
static AxisAlignedBB miscBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
|
||||
static AxisAlignedBB animalBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
|
||||
+ static AxisAlignedBB waterBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 ); // Paper
|
||||
static AxisAlignedBB monsterBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
|
||||
|
||||
/**
|
||||
@@ -50,6 +57,7 @@ public class ActivationRange
|
||||
*/
|
||||
public static byte initializeEntityActivationType(Entity entity)
|
||||
{
|
||||
+ if (entity instanceof EntityWaterAnimal) { return 4; } // Paper
|
||||
if ( entity instanceof EntityMonster || entity instanceof EntitySlime )
|
||||
{
|
||||
return 1; // Monster
|
||||
@@ -74,6 +82,7 @@ public class ActivationRange
|
||||
if ( ( entity.activationType == 3 && config.miscActivationRange == 0 )
|
||||
|| ( entity.activationType == 2 && config.animalActivationRange == 0 )
|
||||
|| ( entity.activationType == 1 && config.monsterActivationRange == 0 )
|
||||
+ || ( entity.activationType == 4 && config.waterActivationRange == 0 ) // Paper
|
||||
|| entity instanceof EntityHuman
|
||||
|| entity instanceof EntityProjectile
|
||||
|| entity instanceof EntityEnderDragon
|
||||
@@ -105,11 +114,13 @@ public class ActivationRange
|
||||
final int miscActivationRange = world.spigotConfig.miscActivationRange;
|
||||
final int animalActivationRange = world.spigotConfig.animalActivationRange;
|
||||
final int monsterActivationRange = world.spigotConfig.monsterActivationRange;
|
||||
+ final int waterActivationRange = world.spigotConfig.waterActivationRange; // Paper
|
||||
|
||||
int maxRange = Math.max( monsterActivationRange, animalActivationRange );
|
||||
maxRange = Math.max( maxRange, miscActivationRange );
|
||||
//maxRange = Math.min( ( world.spigotConfig.viewDistance << 4 ) - 8, maxRange ); Paper - Use player view distance API below instead
|
||||
|
||||
+ Chunk chunk; // Paper
|
||||
for ( EntityHuman player : world.players )
|
||||
{
|
||||
int playerMaxRange = maxRange = Math.min( ( player.getViewDistance() << 4 ) - 8, maxRange ); // Paper - Use player view distance API
|
||||
@@ -117,6 +128,7 @@ public class ActivationRange
|
||||
maxBB = player.getBoundingBox().grow( playerMaxRange, 256, playerMaxRange ); // Paper - Use player view distance API
|
||||
miscBB = player.getBoundingBox().grow( miscActivationRange, 256, miscActivationRange );
|
||||
animalBB = player.getBoundingBox().grow( animalActivationRange, 256, animalActivationRange );
|
||||
+ waterBB = player.getBoundingBox().grow( waterActivationRange, 256, waterActivationRange ); // Paper
|
||||
monsterBB = player.getBoundingBox().grow( monsterActivationRange, 256, monsterActivationRange );
|
||||
|
||||
int i = MathHelper.floor( maxBB.minX / 16.0D );
|
||||
@@ -128,9 +140,9 @@ public class ActivationRange
|
||||
{
|
||||
for ( int j1 = k; j1 <= l; ++j1 )
|
||||
{
|
||||
- if ( world.getWorld().isChunkLoaded( i1, j1 ) )
|
||||
+ if ( (chunk = world.getChunkIfLoaded(i1, j1 )) != null ) // Paper
|
||||
{
|
||||
- activateChunkEntities( world.getChunkAt( i1, j1 ) );
|
||||
+ activateChunkEntities( chunk ); // Paper
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,6 +182,14 @@ public class ActivationRange
|
||||
entity.activatedTick = MinecraftServer.currentTick;
|
||||
}
|
||||
break;
|
||||
+ // Paper start
|
||||
+ case 4:
|
||||
+ if ( waterBB.c( entity.getBoundingBox() ) )
|
||||
+ {
|
||||
+ entity.activatedTick = MinecraftServer.currentTick;
|
||||
+ }
|
||||
+ break;
|
||||
+ // Paper end
|
||||
case 3:
|
||||
default:
|
||||
if ( miscBB.c( entity.getBoundingBox() ) )
|
||||
@@ -191,11 +211,17 @@ public class ActivationRange
|
||||
*/
|
||||
public static boolean checkEntityImmunities(Entity entity)
|
||||
{
|
||||
- // quick checks.
|
||||
- if ( entity.inWater || entity.fireTicks > 0 )
|
||||
- {
|
||||
+ // Paper start - optimize Water cases
|
||||
+ if (entity instanceof EntityFish) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (entity.inWater && (!(entity instanceof EntityInsentient) || !(((EntityInsentient) entity).getNavigation() instanceof NavigationGuardian))) {
|
||||
return true;
|
||||
}
|
||||
+ if (entity.fireTicks > 0) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if ( !( entity instanceof EntityArrow ) )
|
||||
{
|
||||
if ( !entity.onGround || !entity.passengers.isEmpty() || entity.isPassenger() )
|
||||
@@ -210,18 +236,29 @@ public class ActivationRange
|
||||
if ( entity instanceof EntityLiving )
|
||||
{
|
||||
EntityLiving living = (EntityLiving) entity;
|
||||
- if ( /*TODO: Missed mapping? living.attackTicks > 0 || */ living.hurtTicks > 0 || living.effects.size() > 0 )
|
||||
+ if ( living.lastDamageByPlayerTime > 0 || living.hurtTicks > 0 || living.effects.size() > 0 ) // Paper
|
||||
{
|
||||
return true;
|
||||
}
|
||||
- if ( entity instanceof EntityCreature && ( (EntityCreature) entity ).getGoalTarget() != null )
|
||||
+ if ( entity instanceof EntityCreature )
|
||||
{
|
||||
- return true;
|
||||
+ // Paper start
|
||||
+ EntityCreature creature = (EntityCreature) entity;
|
||||
+ if (creature.getGoalTarget() != null || creature.getMovingTarget() != null) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
if ( entity instanceof EntityVillager && ( (EntityVillager) entity ).isInLove() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
+ // Paper start
|
||||
+ if ( entity instanceof EntityLlama && ( (EntityLlama ) entity ).inCaravan() )
|
||||
+ {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if ( entity instanceof EntityAnimal )
|
||||
{
|
||||
EntityAnimal animal = (EntityAnimal) entity;
|
||||
@@ -268,16 +305,20 @@ public class ActivationRange
|
||||
entity.activatedTick = MinecraftServer.currentTick + 20;
|
||||
}
|
||||
isActive = true;
|
||||
+ // Paper start
|
||||
+ } else if (entity instanceof EntityInsentient && ((EntityInsentient) entity).targetSelector.hasTasks()) {
|
||||
+ isActive = true;
|
||||
}
|
||||
+ // Paper end
|
||||
// Add a little performance juice to active entities. Skip 1/4 if not immune.
|
||||
- } else if ( !entity.defaultActivationState && entity.ticksLived % 4 == 0 && !checkEntityImmunities( entity ) )
|
||||
+ } else if ( !entity.defaultActivationState && entity.ticksLived % 4 == 0 && !(entity instanceof EntityInsentient && ((EntityInsentient) entity).targetSelector.hasTasks()) && !checkEntityImmunities( entity ) ) // Paper - add targetSelector.hasTasks
|
||||
{
|
||||
isActive = false;
|
||||
}
|
||||
- int x = MathHelper.floor( entity.locX );
|
||||
- int z = MathHelper.floor( entity.locZ );
|
||||
+ //int x = MathHelper.floor( entity.locX ); // Paper
|
||||
+ //int z = MathHelper.floor( entity.locZ ); // Paper
|
||||
// Make sure not on edge of unloaded chunk
|
||||
- Chunk chunk = entity.world.getChunkIfLoaded( x >> 4, z >> 4 );
|
||||
+ Chunk chunk = entity.getChunkAtLocation(); // Paper
|
||||
if ( isActive && !( chunk != null && chunk.areNeighborsLoaded( 1 ) ) )
|
||||
{
|
||||
isActive = false;
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
index d3c2abc398..1d222eaff7 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
@@ -150,12 +150,14 @@ public class SpigotWorldConfig
|
||||
public int animalActivationRange = 32;
|
||||
public int monsterActivationRange = 32;
|
||||
public int miscActivationRange = 16;
|
||||
+ public int waterActivationRange = 16; // Paper
|
||||
public boolean tickInactiveVillagers = true;
|
||||
private void activationRange()
|
||||
{
|
||||
animalActivationRange = getInt( "entity-activation-range.animals", animalActivationRange );
|
||||
monsterActivationRange = getInt( "entity-activation-range.monsters", monsterActivationRange );
|
||||
miscActivationRange = getInt( "entity-activation-range.misc", miscActivationRange );
|
||||
+ waterActivationRange = getInt( "entity-activation-range.water", waterActivationRange ); // Paper
|
||||
tickInactiveVillagers = getBoolean( "entity-activation-range.tick-inactive-villagers", tickInactiveVillagers );
|
||||
log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Mi " + miscActivationRange + " / Tiv " + tickInactiveVillagers );
|
||||
}
|
||||
--
|
||||
2.21.0
|
||||
|
47
removed/1.14/0120-Ensure-Chunks-never-ever-load-async.patch
Normal file
47
removed/1.14/0120-Ensure-Chunks-never-ever-load-async.patch
Normal file
|
@ -0,0 +1,47 @@
|
|||
From 036c518050a0972307568a014156d59bb90bf54c Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 27 May 2016 21:41:26 -0400
|
||||
Subject: [PATCH] Ensure Chunks never ever load async
|
||||
|
||||
Safely pushes the operation to main thread, then back to the posting thread
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java
|
||||
index e4fd9bc604..7ffb8f6172 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java
|
||||
@@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.chunkio;
|
||||
import net.minecraft.server.Chunk;
|
||||
import net.minecraft.server.ChunkProviderServer;
|
||||
import net.minecraft.server.ChunkRegionLoader;
|
||||
+import net.minecraft.server.MCUtil; // Paper
|
||||
import net.minecraft.server.World;
|
||||
import org.bukkit.craftbukkit.util.AsynchronousExecutor;
|
||||
|
||||
@@ -13,7 +14,7 @@ public class ChunkIOExecutor {
|
||||
private static final AsynchronousExecutor<QueuedChunk, Chunk, Runnable, RuntimeException> instance = new AsynchronousExecutor<QueuedChunk, Chunk, Runnable, RuntimeException>(new ChunkIOProvider(), BASE_THREADS);
|
||||
|
||||
public static Chunk syncChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z) {
|
||||
- return instance.getSkipQueue(new QueuedChunk(x, z, loader, world, provider));
|
||||
+ return MCUtil.ensureMain("Async Chunk Load", () -> instance.getSkipQueue(new QueuedChunk(x, z, loader, world, provider))); // Paper
|
||||
}
|
||||
|
||||
public static void queueChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z, Runnable runnable) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
|
||||
index 52a8c48fa4..4cfe24df15 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
|
||||
@@ -35,9 +35,9 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChu
|
||||
|
||||
// sync stuff
|
||||
public void callStage2(QueuedChunk queuedChunk, Chunk chunk) throws RuntimeException {
|
||||
- if (chunk == null) {
|
||||
+ if (chunk == null || queuedChunk.provider.chunks.containsKey(ChunkCoordIntPair.a(queuedChunk.x, queuedChunk.z))) { // Paper - also call original if it was already loaded
|
||||
// If the chunk loading failed just do it synchronously (may generate)
|
||||
- // queuedChunk.provider.originalGetChunkAt(queuedChunk.x, queuedChunk.z);
|
||||
+ queuedChunk.provider.getChunkAt(queuedChunk.x, queuedChunk.z, true, true); // Paper - actually call original if it was already loaded
|
||||
return;
|
||||
}
|
||||
try (Timing ignored = queuedChunk.provider.world.timings.chunkIOStage2.startTimingIfSync()) { // Paper
|
||||
--
|
||||
2.21.0
|
||||
|
224
removed/1.14/0123-Delay-Chunk-Unloads-based-on-Player-Movement.patch
Executable file
224
removed/1.14/0123-Delay-Chunk-Unloads-based-on-Player-Movement.patch
Executable file
|
@ -0,0 +1,224 @@
|
|||
From 2fbf2c556d7840198741959940696a14c7e3c26a Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 18 Jun 2016 23:22:12 -0400
|
||||
Subject: [PATCH] Delay Chunk Unloads based on Player Movement
|
||||
|
||||
When players are moving in the world, doing things such as building or exploring,
|
||||
they will commonly go back and forth in a small area. This causes a ton of chunk load
|
||||
and unload activity on the edge chunks of their view distance.
|
||||
|
||||
A simple back and forth movement in 6 blocks could spam a chunk to thrash a
|
||||
loading and unload cycle over and over again.
|
||||
|
||||
This is very wasteful. This system introduces a delay of inactivity on a chunk
|
||||
before it actually unloads, which is maintained separately from ChunkGC.
|
||||
|
||||
This allows servers with smaller worlds who do less long distance exploring to stop
|
||||
wasting cpu cycles on saving/unloading/reloading chunks repeatedly.
|
||||
|
||||
This also makes the Chunk GC System useless, by auto scheduling unload as soon as
|
||||
a spare chunk is added to the server thats outside of view distance.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index bcc2ecaa3a..c70771614d 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -310,4 +310,18 @@ public class PaperWorldConfig {
|
||||
preventTntFromMovingInWater = getBoolean("prevent-tnt-from-moving-in-water", false);
|
||||
log("Prevent TNT from moving in water: " + preventTntFromMovingInWater);
|
||||
}
|
||||
+
|
||||
+ public long delayChunkUnloadsBy;
|
||||
+ private void delayChunkUnloadsBy() {
|
||||
+ delayChunkUnloadsBy = PaperConfig.getSeconds(getString("delay-chunk-unloads-by", "10s"));
|
||||
+ if (delayChunkUnloadsBy > 0) {
|
||||
+ log("Delaying chunk unloads by " + delayChunkUnloadsBy + " seconds");
|
||||
+ delayChunkUnloadsBy *= 1000;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public boolean skipEntityTickingInChunksScheduledForUnload = true;
|
||||
+ private void skipEntityTickingInChunksScheduledForUnload() {
|
||||
+ skipEntityTickingInChunksScheduledForUnload = getBoolean("skip-entity-ticking-in-chunks-scheduled-for-unload", skipEntityTickingInChunksScheduledForUnload);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
||||
index c74176daa5..bdf922db50 100644
|
||||
--- a/src/main/java/net/minecraft/server/Chunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
||||
@@ -40,6 +40,7 @@ public class Chunk implements IChunkAccess {
|
||||
private boolean i;public boolean isLoaded() { return i; } // Paper - OBFHELPER
|
||||
public final World world;
|
||||
public final Map<HeightMap.Type, HeightMap> heightMap;
|
||||
+ public Long scheduledForUnload; // Paper - delay chunk unloads
|
||||
public final int locX;
|
||||
public final int locZ;
|
||||
private boolean l;
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkMap.java b/src/main/java/net/minecraft/server/ChunkMap.java
|
||||
index 8b3738c8f7..2021c0d02e 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkMap.java
|
||||
@@ -48,6 +48,15 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
|
||||
}
|
||||
}
|
||||
}
|
||||
+ // Paper start - if this is a spare chunk (not part of any players view distance), go ahead and queue it for unload.
|
||||
+ if (!((WorldServer)chunk.world).getPlayerChunkMap().isChunkInUse(chunk.locX, chunk.locZ)) {
|
||||
+ if (chunk.world.paperConfig.delayChunkUnloadsBy > 0) {
|
||||
+ chunk.scheduledForUnload = System.currentTimeMillis();
|
||||
+ } else {
|
||||
+ ((WorldServer) chunk.world).getChunkProvider().unload(chunk);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
chunk.world.timings.syncChunkLoadPostTimer.stopTiming(); // Paper
|
||||
// CraftBukkit end
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index c54df45837..d0bf0f72da 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -307,6 +307,19 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
}
|
||||
activityAccountant.endActivity(); // Spigot
|
||||
}
|
||||
+ // Paper start - delayed chunk unloads
|
||||
+ long now = System.currentTimeMillis();
|
||||
+ long unloadAfter = world.paperConfig.delayChunkUnloadsBy;
|
||||
+ if (unloadAfter > 0) {
|
||||
+ //noinspection Convert2streamapi
|
||||
+ for (Chunk chunk : chunks.values()) {
|
||||
+ if (chunk.scheduledForUnload != null && now - chunk.scheduledForUnload > unloadAfter) {
|
||||
+ chunk.scheduledForUnload = null;
|
||||
+ unload(chunk);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
this.chunkScheduler.a(booleansupplier);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index e47aae2f8b..b9d90c4fb8 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -29,8 +29,23 @@ public class PlayerChunk {
|
||||
|
||||
chunkproviderserver.a(i, j);
|
||||
this.chunk = chunkproviderserver.getChunkAt(i, j, true, false);
|
||||
+ markChunkUsed(); // Paper - delay chunk unloads
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private void markChunkUsed() {
|
||||
+ if (chunk == null) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (chunkHasPlayers) {
|
||||
+ chunk.scheduledForUnload = null;
|
||||
+ } else if (chunk.scheduledForUnload == null) {
|
||||
+ chunk.scheduledForUnload = System.currentTimeMillis();
|
||||
+ }
|
||||
+ }
|
||||
+ private boolean chunkHasPlayers = false;
|
||||
+ // Paper end
|
||||
+
|
||||
public ChunkCoordIntPair a() {
|
||||
return this.location;
|
||||
}
|
||||
@@ -41,6 +56,8 @@ public class PlayerChunk {
|
||||
} else {
|
||||
if (this.players.isEmpty()) {
|
||||
this.i = this.playerChunkMap.getWorld().getTime();
|
||||
+ chunkHasPlayers = true; // Paper - delay chunk unloads
|
||||
+ markChunkUsed(); // Paper - delay chunk unloads
|
||||
}
|
||||
|
||||
this.players.add(entityplayer);
|
||||
@@ -59,6 +76,8 @@ public class PlayerChunk {
|
||||
|
||||
this.players.remove(entityplayer);
|
||||
if (this.players.isEmpty()) {
|
||||
+ chunkHasPlayers = false; // Paper - delay chunk unloads
|
||||
+ markChunkUsed(); // Paper - delay chunk unloads
|
||||
this.playerChunkMap.b(this);
|
||||
}
|
||||
|
||||
@@ -70,6 +89,7 @@ public class PlayerChunk {
|
||||
return true;
|
||||
} else {
|
||||
this.chunk = this.playerChunkMap.getWorld().getChunkProvider().getChunkAt(this.location.x, this.location.z, true, flag);
|
||||
+ markChunkUsed(); // Paper - delay chunk unloads
|
||||
return this.chunk != null;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
index 2064576501..ab4f3b7223 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
@@ -452,7 +452,13 @@ public class PlayerChunkMap {
|
||||
Chunk chunk = playerchunk.f();
|
||||
|
||||
if (chunk != null) {
|
||||
- this.getWorld().getChunkProvider().unload(chunk);
|
||||
+ // Paper start - delay chunk unloads
|
||||
+ if (world.paperConfig.delayChunkUnloadsBy <= 0) {
|
||||
+ this.getWorld().getChunkProvider().unload(chunk);
|
||||
+ } else {
|
||||
+ chunk.scheduledForUnload = System.currentTimeMillis();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 32ee298648..dcff6c8d8a 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -1293,7 +1293,13 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
||||
if (!tileentity.x() && tileentity.hasWorld()) {
|
||||
BlockPosition blockposition = tileentity.getPosition();
|
||||
|
||||
- if (this.isLoaded(blockposition) && this.K.a(blockposition)) {
|
||||
+ // Paper start - Skip ticking in chunks scheduled for unload
|
||||
+ net.minecraft.server.Chunk chunk = this.getChunkIfLoaded(blockposition);
|
||||
+ boolean shouldTick = chunk != null;
|
||||
+ if(this.paperConfig.skipEntityTickingInChunksScheduledForUnload)
|
||||
+ shouldTick = shouldTick && chunk.scheduledForUnload == null;
|
||||
+ if (shouldTick && this.K.a(blockposition)) {
|
||||
+ // Paper end
|
||||
try {
|
||||
this.methodProfiler.a(() -> {
|
||||
return String.valueOf(TileEntityTypes.a(tileentity.C()));
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index a8c7e7931e..f7883e7085 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -1772,7 +1772,7 @@ public class CraftWorld implements World {
|
||||
ChunkProviderServer cps = world.getChunkProvider();
|
||||
for (net.minecraft.server.Chunk chunk : cps.chunks.values()) {
|
||||
// If in use, skip it
|
||||
- if (isChunkInUse(chunk.locX, chunk.locZ)) {
|
||||
+ if (isChunkInUse(chunk.locX, chunk.locZ) || chunk.scheduledForUnload != null) { // Paper - delayed chunk unloads
|
||||
continue;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
index d08ef3fe10..081789a8fe 100644
|
||||
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
||||
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
@@ -323,6 +323,11 @@ public class ActivationRange
|
||||
{
|
||||
isActive = false;
|
||||
}
|
||||
+ // Paper start - Skip ticking in chunks scheduled for unload
|
||||
+ else if (entity.world.paperConfig.skipEntityTickingInChunksScheduledForUnload && (chunk == null || chunk.scheduledForUnload != null)) {
|
||||
+ isActive = false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
return isActive;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.21.0
|
||||
|
234
removed/1.14/0134-Auto-Save-Improvements.patch
Normal file
234
removed/1.14/0134-Auto-Save-Improvements.patch
Normal file
|
@ -0,0 +1,234 @@
|
|||
From e82072ef380eb0d17fb93cee8bf8275fb11f29de Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 19 Sep 2016 23:16:39 -0400
|
||||
Subject: [PATCH] Auto Save Improvements
|
||||
|
||||
Makes Auto Save Rate setting configurable per-world. If the auto save rate is left -1, the global bukkit.yml value will be used.
|
||||
|
||||
Process auto save every tick instead of once per auto tick interval, so that chunk saves will distribute over many ticks instead of all at once.
|
||||
|
||||
Re-introduce a cap per tick for auto save (Spigot disabled the vanilla cap) and make it configurable.
|
||||
|
||||
Adds incremental player auto saving too
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index fb7ada8139..17b4e01aa4 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -269,4 +269,15 @@ public class PaperConfig {
|
||||
flyingKickPlayerMessage = getString("messages.kick.flying-player", flyingKickPlayerMessage);
|
||||
flyingKickVehicleMessage = getString("messages.kick.flying-vehicle", flyingKickVehicleMessage);
|
||||
}
|
||||
+
|
||||
+ public static int playerAutoSaveRate = -1;
|
||||
+ public static int maxPlayerAutoSavePerTick = 10;
|
||||
+ private static void playerAutoSaveRate() {
|
||||
+ playerAutoSaveRate = getInt("settings.player-auto-save-rate", -1);
|
||||
+ maxPlayerAutoSavePerTick = getInt("settings.max-player-auto-save-per-tick", -1);
|
||||
+ if (maxPlayerAutoSavePerTick == -1) { // -1 Automatic / "Recommended"
|
||||
+ // 10 should be safe for everyone unless your mass spamming player auto save
|
||||
+ maxPlayerAutoSavePerTick = (playerAutoSaveRate == -1 || playerAutoSaveRate > 100) ? 10 : 20;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index c70771614d..6e28410c37 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -2,6 +2,7 @@ package com.destroystokyo.paper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.spigotmc.SpigotWorldConfig;
|
||||
|
||||
@@ -324,4 +325,19 @@ public class PaperWorldConfig {
|
||||
private void skipEntityTickingInChunksScheduledForUnload() {
|
||||
skipEntityTickingInChunksScheduledForUnload = getBoolean("skip-entity-ticking-in-chunks-scheduled-for-unload", skipEntityTickingInChunksScheduledForUnload);
|
||||
}
|
||||
+
|
||||
+ public int autoSavePeriod = -1;
|
||||
+ private void autoSavePeriod() {
|
||||
+ autoSavePeriod = getInt("auto-save-interval", -1);
|
||||
+ if (autoSavePeriod > 0) {
|
||||
+ log("Auto Save Interval: " +autoSavePeriod + " (" + (autoSavePeriod / 20) + "s)");
|
||||
+ } else if (autoSavePeriod < 0) {
|
||||
+ autoSavePeriod = MinecraftServer.getServer().autosavePeriod;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public int maxAutoSaveChunksPerTick = 24;
|
||||
+ private void maxAutoSaveChunksPerTick() {
|
||||
+ maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
||||
index bdf922db50..0bf614ce57 100644
|
||||
--- a/src/main/java/net/minecraft/server/Chunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
||||
@@ -53,9 +53,9 @@ public class Chunk implements IChunkAccess {
|
||||
private final TickList<Block> s;
|
||||
private final TickList<FluidType> t;
|
||||
private boolean u;
|
||||
- private boolean v;
|
||||
+ private boolean v;public boolean hasEntities() { return v; } // Paper - OBFHELPER
|
||||
private long lastSaved;
|
||||
- private boolean x;
|
||||
+ private boolean x; public boolean isModified() { return x; } // Paper - OBFHELPER
|
||||
private int y;
|
||||
private long z;
|
||||
private int A;
|
||||
@@ -1071,11 +1071,11 @@ public class Chunk implements IChunkAccess {
|
||||
if (this.v && this.world.getTime() != this.lastSaved || this.x) {
|
||||
return true;
|
||||
}
|
||||
- } else if (this.v && this.world.getTime() >= this.lastSaved + MinecraftServer.getServer().autosavePeriod * 4) { // Spigot - Only save if we've passed 2 auto save intervals without modification
|
||||
- return true;
|
||||
}
|
||||
-
|
||||
- return this.x;
|
||||
+ // Paper start - Make world configurable and incremental
|
||||
+ // This !flag section should say if isModified or hasEntities, then check auto save
|
||||
+ return ((isModified() || hasEntities()) && this.world.getTime() >= this.lastSaved + world.paperConfig.autoSavePeriod);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index d0bf0f72da..fbc69b5ba5 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -243,7 +243,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
this.saveChunk(chunk, false); // Spigot
|
||||
chunk.a(false);
|
||||
++i;
|
||||
- if (i == 24 && !flag && false) { // Spigot
|
||||
+ if (!flag && i >= world.paperConfig.maxAutoSaveChunksPerTick) { // Spigot - // Paper - Incremental Auto Save - cap max
|
||||
return false;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
index 621e79bc53..260fa3e678 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
@@ -34,6 +34,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||||
|
||||
private static final Logger cc = LogManager.getLogger();
|
||||
public String locale = null; // CraftBukkit - lowercase // Paper - default to null
|
||||
+ public long lastSave = MinecraftServer.currentTick; // Paper
|
||||
public PlayerConnection playerConnection;
|
||||
public final MinecraftServer server;
|
||||
public final PlayerInteractManager playerInteractManager;
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 7ffb061414..6283c774d6 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -143,6 +143,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
||||
public org.bukkit.command.RemoteConsoleCommandSender remoteConsole;
|
||||
public ConsoleReader reader;
|
||||
public static int currentTick = 0; // Paper - Further improve tick loop
|
||||
+ public boolean serverAutoSave = false; // Paper
|
||||
public final Thread primaryThread;
|
||||
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
|
||||
public int autosavePeriod;
|
||||
@@ -938,22 +939,30 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
||||
this.m.b().a(agameprofile);
|
||||
}
|
||||
|
||||
- if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
|
||||
this.methodProfiler.enter("save");
|
||||
- this.playerList.savePlayers();
|
||||
+
|
||||
+ serverAutoSave = (autosavePeriod > 0 && this.ticks % autosavePeriod == 0); // Paper
|
||||
+ int playerSaveInterval = com.destroystokyo.paper.PaperConfig.playerAutoSaveRate;
|
||||
+ if (playerSaveInterval < 0) {
|
||||
+ playerSaveInterval = autosavePeriod;
|
||||
+ }
|
||||
+ if (playerSaveInterval > 0) { // CraftBukkit // Paper
|
||||
+ this.playerList.savePlayers(playerSaveInterval);
|
||||
// Spigot Start
|
||||
+ } // Paper - Incremental Auto Saving
|
||||
+
|
||||
// We replace this with saving each individual world as this.saveChunks(...) is broken,
|
||||
// and causes the main thread to sleep for random amounts of time depending on chunk activity
|
||||
// Also pass flag to only save modified chunks
|
||||
server.playerCommandState = true;
|
||||
for (World world : getWorlds()) {
|
||||
- world.getWorld().save(false);
|
||||
+ if (world.paperConfig.autoSavePeriod > 0) world.getWorld().save(false); // Paper - Incremental / Configurable Auto Saving
|
||||
}
|
||||
server.playerCommandState = false;
|
||||
// this.saveChunks(true);
|
||||
// Spigot End
|
||||
this.methodProfiler.exit();
|
||||
- }
|
||||
+ //} // Paper - Incremental Auto Saving
|
||||
|
||||
this.methodProfiler.enter("snooper");
|
||||
if (getSnooperEnabled() && !this.snooper.d() && this.ticks > 100) { // Spigot
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
|
||||
index 79641a73a8..fe6649224a 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerList.java
|
||||
@@ -341,6 +341,7 @@ public abstract class PlayerList {
|
||||
|
||||
protected void savePlayerFile(EntityPlayer entityplayer) {
|
||||
if (!entityplayer.getBukkitEntity().isPersistent()) return; // CraftBukkit
|
||||
+ entityplayer.lastSave = MinecraftServer.currentTick; // Paper
|
||||
this.playerFileData.save(entityplayer);
|
||||
ServerStatisticManager serverstatisticmanager = (ServerStatisticManager) entityplayer.getStatisticManager(); // CraftBukkit
|
||||
|
||||
@@ -1207,13 +1208,25 @@ public abstract class PlayerList {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
public void savePlayers() {
|
||||
+ savePlayers(null);
|
||||
+ }
|
||||
+
|
||||
+ public void savePlayers(Integer interval) {
|
||||
+ long now = MinecraftServer.currentTick;
|
||||
MinecraftTimings.savePlayers.startTiming(); // Paper
|
||||
+ int numSaved = 0; // Paper
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
- this.savePlayerFile((EntityPlayer) this.players.get(i));
|
||||
+ EntityPlayer entityplayer = this.players.get(i);
|
||||
+ if (interval == null || now - entityplayer.lastSave >= interval) {
|
||||
+ this.savePlayerFile(entityplayer);
|
||||
+ if (interval != null && ++numSaved <= com.destroystokyo.paper.PaperConfig.maxPlayerAutoSavePerTick) { break; } // Paper
|
||||
+ }
|
||||
}
|
||||
MinecraftTimings.savePlayers.stopTiming(); // Paper
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
public WhiteList getWhitelist() {
|
||||
return this.whitelist;
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 639068d2dc..49c5b0b5cc 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -855,8 +855,9 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||
ChunkProviderServer chunkproviderserver = this.getChunkProvider();
|
||||
|
||||
if (chunkproviderserver.d()) {
|
||||
- org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
|
||||
+ if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit // Paper - Incremental Auto Saving - Only fire event on full save
|
||||
timings.worldSave.startTiming(); // Paper
|
||||
+ if (flag || server.serverAutoSave) { // Paper
|
||||
if (iprogressupdate != null) {
|
||||
iprogressupdate.a(new ChatMessage("menu.savingLevel", new Object[0]));
|
||||
}
|
||||
@@ -865,6 +866,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||
if (iprogressupdate != null) {
|
||||
iprogressupdate.c(new ChatMessage("menu.savingChunks", new Object[0]));
|
||||
}
|
||||
+ } // Paper
|
||||
|
||||
timings.worldSaveChunks.startTiming(); // Paper
|
||||
chunkproviderserver.a(flag);
|
||||
--
|
||||
2.21.0
|
||||
|
32
removed/1.14/0138-Disable-Vanilla-Chunk-GC.patch
Normal file
32
removed/1.14/0138-Disable-Vanilla-Chunk-GC.patch
Normal file
|
@ -0,0 +1,32 @@
|
|||
From ee210a06121210a6975b810dbbbe28f8f98944d7 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 26 Sep 2016 01:51:30 -0400
|
||||
Subject: [PATCH] Disable Vanilla Chunk GC
|
||||
|
||||
Bukkit has its own system for this.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 49c5b0b5cc..15736f7575 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -872,6 +872,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||
chunkproviderserver.a(flag);
|
||||
timings.worldSaveChunks.stopTiming(); // Paper
|
||||
// CraftBukkit - ArrayList -> Collection
|
||||
+ /* //Paper start - disable vanilla chunk GC
|
||||
java.util.Collection<Chunk> list = chunkproviderserver.a();
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
@@ -881,7 +882,8 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||
if (chunk != null && !this.manager.a(chunk.locX, chunk.locZ)) {
|
||||
chunkproviderserver.unload(chunk);
|
||||
}
|
||||
- }
|
||||
+ }*/
|
||||
+ // Paper end
|
||||
timings.worldSave.stopTiming(); // Paper
|
||||
}
|
||||
}
|
||||
--
|
||||
2.21.0
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
From 266fe023d1d38728ba461724a7f2a23a2ee07cfd Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 3 Nov 2016 21:52:22 -0400
|
||||
Subject: [PATCH] Prevent Auto Save if Save Queue is full
|
||||
|
||||
If the save queue already has 50 (configurable) of chunks pending,
|
||||
then avoid processing auto save (which would add more)
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 7e847af00b..9829b3b64b 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -341,6 +341,11 @@ public class PaperWorldConfig {
|
||||
maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24);
|
||||
}
|
||||
|
||||
+ public int queueSizeAutoSaveThreshold = 50;
|
||||
+ private void queueSizeAutoSaveThreshold() {
|
||||
+ queueSizeAutoSaveThreshold = getInt("save-queue-limit-for-auto-save", 50);
|
||||
+ }
|
||||
+
|
||||
public boolean removeCorruptTEs = false;
|
||||
private void removeCorruptTEs() {
|
||||
removeCorruptTEs = getBoolean("remove-corrupt-tile-entities", false);
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index fbc69b5ba5..9b5908a5b4 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -236,6 +236,13 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
synchronized (this.chunkLoader) {
|
||||
ObjectIterator objectiterator = this.chunks.values().iterator();
|
||||
|
||||
+ // Paper start
|
||||
+ final ChunkRegionLoader chunkLoader = (ChunkRegionLoader) world.getChunkProvider().chunkLoader;
|
||||
+ final int queueSize = chunkLoader.getQueueSize();
|
||||
+ if (!flag && queueSize > world.paperConfig.queueSizeAutoSaveThreshold){
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
while (objectiterator.hasNext()) {
|
||||
Chunk chunk = (Chunk) objectiterator.next();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
|
||||
index a144118f66..adfb5d056f 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
|
||||
@@ -156,6 +156,8 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
|
||||
|
||||
}
|
||||
|
||||
+ public int getQueueSize() { return queue.size(); } // Paper
|
||||
+
|
||||
// CraftBukkit start - Add async variant, provide compatibility
|
||||
@Nullable
|
||||
public Chunk a(GeneratorAccess generatoraccess, int i, int j, Consumer<Chunk> consumer) throws IOException {
|
||||
--
|
||||
2.21.0
|
||||
|
93
removed/1.14/0143-Chunk-Save-Stats-Debug-Option.patch
Normal file
93
removed/1.14/0143-Chunk-Save-Stats-Debug-Option.patch
Normal file
|
@ -0,0 +1,93 @@
|
|||
From 8efbb3a0533a16d6c9e3ac27e41cd03bba1e35d8 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 4 Nov 2016 02:12:10 -0400
|
||||
Subject: [PATCH] Chunk Save Stats Debug Option
|
||||
|
||||
Adds a command line flag to enable stats on how chunk saves are processing.
|
||||
|
||||
Stats on current queue, how many was processed and how many were queued.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index 9b5908a5b4..2997767282 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -28,6 +28,11 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
public final LongSet unloadQueue = new LongOpenHashSet();
|
||||
public final ChunkGenerator<?> chunkGenerator;
|
||||
public final IChunkLoader chunkLoader;
|
||||
+ // Paper start - chunk save stats
|
||||
+ private long lastQueuedSaves = 0L; // Paper
|
||||
+ private long lastProcessedSaves = 0L; // Paper
|
||||
+ private long lastSaveStatPrinted = System.currentTimeMillis();
|
||||
+ // Paper end
|
||||
public final Long2ObjectMap<Chunk> chunks = Long2ObjectMaps.synchronize(new ChunkMap(8192));
|
||||
private Chunk lastChunk;
|
||||
private final ChunkTaskScheduler chunkScheduler;
|
||||
@@ -239,6 +244,29 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
// Paper start
|
||||
final ChunkRegionLoader chunkLoader = (ChunkRegionLoader) world.getChunkProvider().chunkLoader;
|
||||
final int queueSize = chunkLoader.getQueueSize();
|
||||
+
|
||||
+ final long now = System.currentTimeMillis();
|
||||
+ final long timeSince = (now - lastSaveStatPrinted) / 1000;
|
||||
+ final Integer printRateSecs = Integer.getInteger("printSaveStats");
|
||||
+ if (printRateSecs != null && timeSince >= printRateSecs) {
|
||||
+ final String timeStr = "/" + timeSince +"s";
|
||||
+ final long queuedSaves = chunkLoader.getQueuedSaves();
|
||||
+ long queuedDiff = queuedSaves - lastQueuedSaves;
|
||||
+ lastQueuedSaves = queuedSaves;
|
||||
+
|
||||
+ final long processedSaves = chunkLoader.getProcessedSaves();
|
||||
+ long processedDiff = processedSaves - lastProcessedSaves;
|
||||
+ lastProcessedSaves = processedSaves;
|
||||
+
|
||||
+ lastSaveStatPrinted = now;
|
||||
+ if (processedDiff > 0 || queueSize > 0 || queuedDiff > 0) {
|
||||
+ System.out.println("[Chunk Save Stats] " + world.worldData.getName() +
|
||||
+ " - Current: " + queueSize +
|
||||
+ " - Queued: " + queuedDiff + timeStr +
|
||||
+ " - Processed: " +processedDiff + timeStr
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
if (!flag && queueSize > world.paperConfig.queueSizeAutoSaveThreshold){
|
||||
return false;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
|
||||
index adfb5d056f..0fc4d9f520 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
|
||||
@@ -156,7 +156,13 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
|
||||
|
||||
}
|
||||
|
||||
- public int getQueueSize() { return queue.size(); } // Paper
|
||||
+ // Paper start
|
||||
+ private long queuedSaves = 0;
|
||||
+ private final java.util.concurrent.atomic.AtomicLong processedSaves = new java.util.concurrent.atomic.AtomicLong(0L);
|
||||
+ public int getQueueSize() { return queue.size(); }
|
||||
+ public long getQueuedSaves() { return queuedSaves; }
|
||||
+ public long getProcessedSaves() { return processedSaves.longValue(); }
|
||||
+ // Paper end
|
||||
|
||||
// CraftBukkit start - Add async variant, provide compatibility
|
||||
@Nullable
|
||||
@@ -348,6 +354,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
|
||||
protected void a(ChunkCoordIntPair chunkcoordintpair, Supplier<NBTTagCompound> nbttagcompound) { // Spigot
|
||||
this.saveMap.put(chunkcoordintpair.asLong(), nbttagcompound); // Paper
|
||||
queue.add(new QueuedChunk(chunkcoordintpair, nbttagcompound)); // Paper - Chunk queue improvements
|
||||
+ queuedSaves++; // Paper
|
||||
FileIOThread.a().a(this);
|
||||
}
|
||||
|
||||
@@ -375,6 +382,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
|
||||
// Paper end
|
||||
ChunkCoordIntPair chunkcoordintpair = chunk.coords; // Paper - Chunk queue improvements
|
||||
Supplier<NBTTagCompound> nbttagcompound = chunk.compoundSupplier; // Spigot // Paper
|
||||
+ processedSaves.incrementAndGet(); // Paper
|
||||
|
||||
if (nbttagcompound == null) {
|
||||
return true;
|
||||
--
|
||||
2.21.0
|
||||
|
23
removed/1.14/0161-ShulkerBox-Dupe-Prevention.patch
Executable file
23
removed/1.14/0161-ShulkerBox-Dupe-Prevention.patch
Executable file
|
@ -0,0 +1,23 @@
|
|||
From 16ba1e065d52597408a18d8bbb9fa3686271fc6a Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 2 Jan 2017 16:32:56 -0500
|
||||
Subject: [PATCH] ShulkerBox Dupe Prevention
|
||||
|
||||
This ensures that Shulker Boxes can never drop their contents twice, and
|
||||
that the inventory is cleared incase it some how also got saved to the world.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockShulkerBox.java b/src/main/java/net/minecraft/server/BlockShulkerBox.java
|
||||
index ab0ece557c..997ed795b1 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockShulkerBox.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockShulkerBox.java
|
||||
@@ -100,6 +100,7 @@ public class BlockShulkerBox extends BlockTileEntity {
|
||||
}
|
||||
|
||||
a(world, blockposition, itemstack);
|
||||
+ tileentityshulkerbox.clear(); // Paper - This was intended to be called in Vanilla (is checked in the if statement above if has been called) - Fixes dupe issues
|
||||
}
|
||||
}
|
||||
world.updateAdjacentComparators(blockposition, iblockdata.getBlock());
|
||||
--
|
||||
2.21.0
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue