More more work

This commit is contained in:
Nassim Jahnke 2023-12-05 20:39:26 +01:00
parent 0e154a1701
commit ed4ff79ac7
35 changed files with 53 additions and 57 deletions

View File

@ -9,7 +9,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
} }
public void checkBelowWorld() { public void checkBelowWorld() {

View File

@ -12,10 +12,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (entity instanceof LivingEntity) { if (entity instanceof LivingEntity) {
LivingEntity entityliving = (LivingEntity) entity; LivingEntity entityliving = (LivingEntity) entity;
- d14 = ProtectionEnchantment.getExplosionKnockbackAfterDampener(entityliving, d13); - d13 = ProtectionEnchantment.getExplosionKnockbackAfterDampener(entityliving, d12);
+ d14 = entity instanceof Player && level.paperConfig().environment.disableExplosionKnockback ? 0 : ProtectionEnchantment.getExplosionKnockbackAfterDampener(entityliving, d13); // Paper - disable explosion knockback + d13 = entity instanceof Player && level.paperConfig().environment.disableExplosionKnockback ? 0 : ProtectionEnchantment.getExplosionKnockbackAfterDampener(entityliving, d12); // Paper - disable explosion knockback
} else { } else {
d14 = d13; d13 = d12;
} }
@@ -0,0 +0,0 @@ public class Explosion { @@ -0,0 +0,0 @@ public class Explosion {
if (entity instanceof Player) { if (entity instanceof Player) {

View File

@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (!this.paperConfig().environment.disableIceAndSnow) { // Paper + if (!this.paperConfig().environment.disableIceAndSnow) { // Paper
for (int l = 0; l < randomTickSpeed; ++l) { for (int l = 0; l < randomTickSpeed; ++l) {
if (this.random.nextInt(48) == 0) { if (this.random.nextInt(48) == 0) {
this.tickIceAndSnow(flag, this.getBlockRandomPos(j, 0, k, 15)); this.tickPrecipitation(this.getBlockRandomPos(j, 0, k, 15));
} }
} }
+ } // Paper + } // Paper

View File

@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/Level.java --- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
// Spigot start boolean flag = this.tickRateManager().runsNormally();
// Iterator iterator = this.blockEntityTickers.iterator();
int tilesThisCycle = 0; int tilesThisCycle = 0;
- for (this.tileLimiter.initTick(); - for (this.tileLimiter.initTick();
- tilesThisCycle < this.blockEntityTickers.size() && (tilesThisCycle % 10 != 0 || this.tileLimiter.shouldContinue()); - tilesThisCycle < this.blockEntityTickers.size() && (tilesThisCycle % 10 != 0 || this.tileLimiter.shouldContinue());

View File

@ -28,7 +28,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
public long activatedTick = Integer.MIN_VALUE; public long activatedTick = Integer.MIN_VALUE;
public void inactiveTick() { } public void inactiveTick() { }
// Spigot end // Spigot end
@ -56,23 +56,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public float getBukkitYaw() { public float getBukkitYaw() {
return this.yRot; return this.yRot;
} }
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
this.bukkitEntity.storeBukkitValues(nbt); this.bukkitEntity.storeBukkitValues(nbttagcompound);
} }
// CraftBukkit end // CraftBukkit end
+ // Paper start - Save the entity's origin location + // Paper start - Save the entity's origin location
+ if (this.origin != null) { + if (this.origin != null) {
+ UUID originWorld = this.originWorld != null ? this.originWorld : this.level != null ? this.level.getWorld().getUID() : null; + UUID originWorld = this.originWorld != null ? this.originWorld : this.level != null ? this.level.getWorld().getUID() : null;
+ if (originWorld != null) { + if (originWorld != null) {
+ nbt.putUUID("Paper.OriginWorld", originWorld); + nbttagcompound.putUUID("Paper.OriginWorld", originWorld);
+ } + }
+ nbt.put("Paper.Origin", this.newDoubleList(origin.getX(), origin.getY(), origin.getZ())); + nbttagcompound.put("Paper.Origin", this.newDoubleList(origin.getX(), origin.getY(), origin.getZ()));
+ } + }
+ // Paper end + // Paper end
return nbt; return nbttagcompound;
} catch (Throwable throwable) { } catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT");
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
} }
// CraftBukkit end // CraftBukkit end
@ -117,9 +117,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
@@ -0,0 +0,0 @@ public class PrimedTnt extends Entity implements TraceableEntity { @@ -0,0 +0,0 @@ public class PrimedTnt extends Entity implements TraceableEntity {
@Override this.setBlockState(NbtUtils.readBlockState(this.level().holderLookup(Registries.BLOCK), nbt.getCompound("block_state")));
protected void readAdditionalSaveData(CompoundTag nbt) { }
this.setFuse(nbt.getShort("Fuse"));
+ // Paper start - Try and load origin location from the old NBT tags for backwards compatibility + // Paper start - Try and load origin location from the old NBT tags for backwards compatibility
+ if (nbt.contains("SourceLoc_x")) { + if (nbt.contains("SourceLoc_x")) {
+ int srcX = nbt.getInt("SourceLoc_x"); + int srcX = nbt.getInt("SourceLoc_x");

View File

@ -95,32 +95,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Spigot start // Spigot start
Arrays.fill( this.recentTps, 20 ); Arrays.fill( this.recentTps, 20 );
- long curTime, tickSection = Util.getMillis(), tickCount = 1; - long tickSection = Util.getMillis(), tickCount = 1;
+ long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop + long tickSection = Util.getNanos(), curTime, tickCount = 1; // Paper
+ lastTick = start - TICK_TIME; // Paper
while (this.running) { while (this.running) {
// Paper start - rewrite chunk system // Paper start - rewrite chunk system
// guarantee that nothing can stop the server from halting if it can at least still tick // guarantee that nothing can stop the server from halting if it can at least still tick
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
throw this.chunkSystemCrash;
} }
// Paper end - rewrite chunk system // Spigot start
- long i = (curTime = Util.getMillis()) - this.nextTickTime;
+ long i = ((curTime = System.nanoTime()) / (1000L * 1000L)) - this.nextTickTime; // Paper
if (i > 5000L && this.nextTickTime - this.lastOverloadWarning >= 30000L) { // CraftBukkit
long j = i / 50L;
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
++MinecraftServer.currentTickLong; // Paper ++MinecraftServer.currentTickLong; // Paper
- if ( tickCount++ % MinecraftServer.SAMPLE_INTERVAL == 0 ) - if ( tickCount++ % MinecraftServer.SAMPLE_INTERVAL == 0 )
+ if ( ++MinecraftServer.currentTick % MinecraftServer.SAMPLE_INTERVAL == 0 ) + if ( ++MinecraftServer.currentTick % MinecraftServer.SAMPLE_INTERVAL == 0 ) // Paper
{ {
- long curTime = Util.getMillis();
- double currentTps = 1E3 / ( curTime - tickSection ) * MinecraftServer.SAMPLE_INTERVAL; - double currentTps = 1E3 / ( curTime - tickSection ) * MinecraftServer.SAMPLE_INTERVAL;
- this.recentTps[0] = MinecraftServer.calcTps( this.recentTps[0], 0.92, currentTps ); // 1/exp(5sec/1min) - this.recentTps[0] = MinecraftServer.calcTps( this.recentTps[0], 0.92, currentTps ); // 1/exp(5sec/1min)
- this.recentTps[1] = MinecraftServer.calcTps( this.recentTps[1], 0.9835, currentTps ); // 1/exp(5sec/5min) - this.recentTps[1] = MinecraftServer.calcTps( this.recentTps[1], 0.9835, currentTps ); // 1/exp(5sec/5min)
- this.recentTps[2] = MinecraftServer.calcTps( this.recentTps[2], 0.9945, currentTps ); // 1/exp(5sec/15min) - this.recentTps[2] = MinecraftServer.calcTps( this.recentTps[2], 0.9945, currentTps ); // 1/exp(5sec/15min)
+ // Paper start
+ curTime = Util.getNanos();
+ final long diff = curTime - tickSection; + final long diff = curTime - tickSection;
+ java.math.BigDecimal currentTps = TPS_BASE.divide(new java.math.BigDecimal(diff), 30, java.math.RoundingMode.HALF_UP); + java.math.BigDecimal currentTps = TPS_BASE.divide(new java.math.BigDecimal(diff), 30, java.math.RoundingMode.HALF_UP);
+ tps1.add(currentTps, diff); + tps1.add(currentTps, diff);
@ -132,8 +125,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.recentTps[2] = tps15.getAverage(); + this.recentTps[2] = tps15.getAverage();
+ // Paper end + // Paper end
tickSection = curTime; tickSection = curTime;
} - }
+ } else curTime = Util.getNanos(); // Paper
// Spigot end // Spigot end
boolean flag = i == 0L;
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount); this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount);
} }
@ -141,7 +137,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit - MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit
+ //MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit // Paper - don't overwrite current tick time + //MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit // Paper - don't overwrite current tick time
+ lastTick = curTime; + lastTick = curTime;
this.nextTickTime += 50L; this.nextTickTimeNanos += i;
this.startMetricsRecordingTick(); this.startMetricsRecordingTick();
this.profiler.push("tick"); this.profiler.push("tick");
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java

View File

@ -26,14 +26,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/Explosion.java --- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -0,0 +0,0 @@ public class Explosion { @@ -0,0 +0,0 @@ public class Explosion {
d8 /= d11; // CraftBukkit end
d9 /= d11; }
d10 /= d11;
- double d12 = (double) Explosion.getSeenPercent(vec3d, entity);
+ double d12 = this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions
double d13 = (1.0D - d7) * d12;
// CraftBukkit start - double d12 = (1.0D - d7) * (double) Explosion.getSeenPercent(vec3d, entity);
+ double d12 = (1.0D - d7) * this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions
double d13;
if (entity instanceof LivingEntity) {
@@ -0,0 +0,0 @@ public class Explosion { @@ -0,0 +0,0 @@ public class Explosion {
private BlockInteraction() {} private BlockInteraction() {}

View File

@ -16717,7 +16717,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- while (this.levels.values().stream().anyMatch((worldserver1) -> { - while (this.levels.values().stream().anyMatch((worldserver1) -> {
- return worldserver1.getChunkSource().chunkMap.hasWork(); - return worldserver1.getChunkSource().chunkMap.hasWork();
- })) { - })) {
- this.nextTickTime = Util.getMillis() + 1L; - this.nextTickTimeNanos = Util.getNanos() + TimeUtil.NANOSECONDS_PER_MILLISECOND;
- iterator = this.getAllLevels().iterator(); - iterator = this.getAllLevels().iterator();
- -
- while (iterator.hasNext()) { - while (iterator.hasNext()) {
@ -16768,7 +16768,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!this.initServer()) { if (!this.initServer()) {
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
Arrays.fill( this.recentTps, 20 ); Arrays.fill( this.recentTps, 20 );
long curTime, tickSection = Util.getMillis(), tickCount = 1; long tickSection = Util.getMillis(), tickCount = 1;
while (this.running) { while (this.running) {
+ // Paper start - rewrite chunk system + // Paper start - rewrite chunk system
+ // guarantee that nothing can stop the server from halting if it can at least still tick + // guarantee that nothing can stop the server from halting if it can at least still tick
@ -16776,9 +16776,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ throw this.chunkSystemCrash; + throw this.chunkSystemCrash;
+ } + }
+ // Paper end - rewrite chunk system + // Paper end - rewrite chunk system
long i = (curTime = Util.getMillis()) - this.nextTickTime; long i;
if (i > 5000L && this.nextTickTime - this.lastOverloadWarning >= 30000L) { // CraftBukkit if (!this.isPaused() && this.tickRateManager.isSprinting() && this.tickRateManager.checkShouldSprintThisTick()) {
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} }
@ -16790,7 +16790,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end + // Paper end
// CraftBukkit start // CraftBukkit start
if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
return this.forceTicks || this.runningTask() || Util.getMillis() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTime : this.nextTickTime); return this.forceTicks || this.runningTask() || Util.getNanos() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTimeNanos : this.nextTickTimeNanos);
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// CraftBukkit start // CraftBukkit start
@Override @Override
@ -19497,7 +19497,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.chunkMap.level.playerChunkLoader.tick(); // Paper - replace player chunk loader - this is mostly required to account for view distance changes + this.chunkMap.level.playerChunkLoader.tick(); // Paper - replace player chunk loader - this is mostly required to account for view distance changes
this.tickChunks(); this.tickChunks();
this.level.timings.chunks.stopTiming(); // Paper - timings this.level.timings.chunks.stopTiming(); // Paper - timings
} this.chunkMap.tick();
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos);
@ -20646,7 +20646,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
} }
// Paper end // Paper end
@ -20705,7 +20705,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public Entity(EntityType<?> type, Level world) { public Entity(EntityType<?> type, Level world) {
this.id = Entity.ENTITY_COUNTER.incrementAndGet(); this.id = Entity.ENTITY_COUNTER.incrementAndGet();
this.passengers = ImmutableList.of(); this.passengers = ImmutableList.of();
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
return InteractionResult.PASS; return InteractionResult.PASS;
} }
@ -20719,8 +20719,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return false; return false;
} }
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
}; }).count();
} }
+ // Paper start - rewrite chunk system + // Paper start - rewrite chunk system
@ -20734,9 +20734,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - rewrite chunk system + // Paper end - rewrite chunk system
+ +
public boolean hasExactlyOnePlayerPassenger() { public boolean hasExactlyOnePlayerPassenger() {
return this.getIndirectPassengersStream().filter((entity) -> { return this.countPlayerPassengers() == 1;
return entity instanceof Player; }
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
} }
public final void setPosRaw(double x, double y, double z) { public final void setPosRaw(double x, double y, double z) {
@ -20749,7 +20749,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (this.position.x != x || this.position.y != y || this.position.z != z) { if (this.position.x != x || this.position.y != y || this.position.z != z) {
this.position = new Vec3(x, y, z); this.position = new Vec3(x, y, z);
int i = Mth.floor(x); int i = Mth.floor(x);
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
@Override @Override
public final void setRemoved(Entity.RemovalReason reason) { public final void setRemoved(Entity.RemovalReason reason) {
@ -20763,7 +20763,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (this.removalReason == null) { if (this.removalReason == null) {
this.removalReason = reason; this.removalReason = reason;
} }
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
this.stopRiding(); this.stopRiding();
} }
@ -20772,7 +20772,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.levelCallback.onRemove(reason); this.levelCallback.onRemove(reason);
} }
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
@Override @Override
public boolean shouldBeSaved() { public boolean shouldBeSaved() {

View File

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