mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 23:38:25 +01:00
more patches
This commit is contained in:
parent
6358589ae3
commit
7dd2ea0897
30 changed files with 615 additions and 995 deletions
|
@ -1,89 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Wed, 2 Mar 2016 02:17:54 -0600
|
||||
Subject: [PATCH] Generator Settings
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
|
||||
private void perPlayerMobSpawns() {
|
||||
perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false);
|
||||
}
|
||||
+
|
||||
+ public boolean generateFlatBedrock;
|
||||
+ private void generatorSettings() {
|
||||
+ generateFlatBedrock = getBoolean("generator-settings.flat-bedrock", false);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
@@ -0,0 +0,0 @@ import org.apache.logging.log4j.LogManager;
|
||||
|
||||
public interface ChunkAccess extends BlockGetter, FeatureAccess {
|
||||
|
||||
+ // Paper start
|
||||
+ default boolean generateFlatBedrock() {
|
||||
+ if (this instanceof ProtoChunk) {
|
||||
+ return ((ProtoChunk)this).world.paperConfig.generateFlatBedrock;
|
||||
+ } else if (this instanceof LevelChunk) {
|
||||
+ return ((LevelChunk)this).world.paperConfig.generateFlatBedrock;
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
BlockState getType(final int x, final int y, final int z); // Paper
|
||||
@Nullable
|
||||
BlockState setBlockState(BlockPos pos, BlockState state, boolean moved);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
@@ -0,0 +0,0 @@ public class ProtoChunk implements ChunkAccess {
|
||||
private long inhabitedTime;
|
||||
private final Map<GenerationStep.Carving, BitSet> carvingMasks;
|
||||
private volatile boolean isLightCorrect;
|
||||
- private final Level world; // Paper - Anti-Xray - Add world
|
||||
+ final Level world; // Paper - Anti-Xray - Add world // Paper - private -> default
|
||||
|
||||
// Paper start - Anti-Xray - Add world
|
||||
@Deprecated public ProtoChunk(ChunkPos pos, UpgradeData upgradeData) { this(pos, upgradeData, null); } // Notice for updates: Please make sure this constructor isn't used anywhere
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
@@ -0,0 +0,0 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
int i = chunk.getPos().getMinBlockX();
|
||||
int j = chunk.getPos().getMinBlockZ();
|
||||
NoiseGeneratorSettings generatorsettingbase = (NoiseGeneratorSettings) this.settings.get();
|
||||
- int k = generatorsettingbase.getBedrockFloorPosition();
|
||||
- int l = this.height - 1 - generatorsettingbase.getBedrockRoofPosition();
|
||||
+ int k = generatorsettingbase.getBedrockFloorPosition(); final int floorHeight = k; // Paper
|
||||
+ int l = this.height - 1 - generatorsettingbase.getBedrockRoofPosition(); final int roofHeight = l; // Paper
|
||||
boolean flag = true;
|
||||
boolean flag1 = l + 4 >= 0 && l < this.height;
|
||||
boolean flag2 = k + 4 >= 0 && k < this.height;
|
||||
@@ -0,0 +0,0 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
|
||||
if (flag1) {
|
||||
for (i1 = 0; i1 < 5; ++i1) {
|
||||
- if (i1 <= random.nextInt(5)) {
|
||||
+ if (i1 <= (chunk.generateFlatBedrock() ? roofHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock roof
|
||||
chunk.setBlockState(blockposition_mutableblockposition.set(blockposition.getX(), l - i1, blockposition.getZ()), Blocks.BEDROCK.defaultBlockState(), false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
|
||||
if (flag2) {
|
||||
for (i1 = 4; i1 >= 0; --i1) {
|
||||
- if (i1 <= random.nextInt(5)) {
|
||||
+ if (i1 <= (chunk.generateFlatBedrock() ? floorHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock floor
|
||||
chunk.setBlockState(blockposition_mutableblockposition.set(blockposition.getX(), k + i1, blockposition.getZ()), Blocks.BEDROCK.defaultBlockState(), false);
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: wea_ondara <wea_ondara@alpenblock.net>
|
||||
Date: Thu, 10 Oct 2019 11:29:42 +0200
|
||||
Subject: [PATCH] Performance improvement for Chunk.getEntities
|
||||
|
||||
This patch aims to reduce performance cost used by collecting the
|
||||
entities of a chunk. Previously the entitySlices were copied into an
|
||||
extra array with List.toArray() with is a costly and unneccessary
|
||||
operation. This patch will reduce the load of plugins which for example
|
||||
implement custom moblimits and depend on Chunk.getEntities().
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
Entity[] entities = new Entity[count];
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
-
|
||||
- for (Object obj : chunk.entitySlices[i].toArray()) {
|
||||
- if (!(obj instanceof net.minecraft.world.entity.Entity)) {
|
||||
+ // Paper start - speed up (was with chunk.entitySlices[i].toArray() and cast checks which costs a lot of performance if called often)
|
||||
+ for (net.minecraft.world.entity.Entity entity : chunk.entitySlices[i]) {
|
||||
+ if (entity == null) {
|
||||
continue;
|
||||
}
|
||||
-
|
||||
- entities[index++] = ((net.minecraft.world.entity.Entity) obj).getBukkitEntity();
|
||||
+ entities[index++] = entity.getBukkitEntity();
|
||||
}
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
return entities;
|
|
@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
|
||||
// Modelled off EntityHuman#hasBlock
|
||||
if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) {
|
||||
net.minecraft.world.level.block.Block.dropResources(iblockdata, world.getLevel(), position, world.getBlockEntity(position), null, nmsItem);
|
||||
net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), position, this.world.getBlockEntity(position), null, nmsItem);
|
||||
+ if (triggerEffect) world.levelEvent(org.bukkit.Effect.STEP_SOUND.getId(), position, net.minecraft.world.level.block.Block.getId(block.defaultBlockState())); // Paper
|
||||
result = true;
|
||||
}
|
|
@ -18,6 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ disablePillagerPatrols = getBoolean("game-mechanics.disable-pillager-patrols", disablePillagerPatrols);
|
||||
+ }
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java
|
|
@ -17,16 +17,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java
|
||||
@@ -0,0 +0,0 @@ public class DoubleBlockCombiner {
|
||||
return new DoubleBlockCombiner.NeighborCombineResult.Single<>(s0);
|
||||
return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity);
|
||||
} else {
|
||||
BlockPos blockposition1 = pos.relative((Direction) function1.apply(state));
|
||||
- BlockState iblockdata1 = world.getBlockState(blockposition1);
|
||||
BlockPos blockPos = pos.relative(function.apply(state));
|
||||
- BlockState blockState = world.getBlockState(blockPos);
|
||||
+ // Paper start
|
||||
+ BlockState iblockdata1 = world.getTypeIfLoaded(blockposition1);
|
||||
+ if (iblockdata1 == null) {
|
||||
+ return new DoubleBlockCombiner.NeighborCombineResult.Single<>(s0);
|
||||
+ BlockState blockState = world.getTypeIfLoaded(blockPos);
|
||||
+ if (blockState == null) {
|
||||
+ return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
if (iblockdata1.is(state.getBlock())) {
|
||||
DoubleBlockCombiner.BlockType doubleblockfinder_blocktype1 = (DoubleBlockCombiner.BlockType) typeMapper.apply(iblockdata1);
|
||||
if (blockState.is(state.getBlock())) {
|
||||
DoubleBlockCombiner.BlockType blockType2 = typeMapper.apply(blockState);
|
||||
if (blockType2 != DoubleBlockCombiner.BlockType.SINGLE && blockType != blockType2 && blockState.getValue(directionProperty) == state.getValue(directionProperty)) {
|
|
@ -17,108 +17,117 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/mai
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
++TimingHistory.entityTicks; // Paper - timings
|
||||
// Spigot start
|
||||
co.aikar.timings.Timing timer; // Paper
|
||||
- if (!org.spigotmc.ActivationRange.checkIfActive(entity)) {
|
||||
- entity.tickCount++;
|
||||
- timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings
|
||||
+ /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below
|
||||
+ entity.ticksLived++;
|
||||
+ timer = entity.getEntityType().inactiveTickTimer.startTiming(); try { // Paper - timings
|
||||
entity.inactiveTick();
|
||||
} finally { timer.stopTiming(); } // Paper
|
||||
return;
|
||||
- }
|
||||
+ }*/ // Paper - comment out EAR 2
|
||||
// Spigot end
|
||||
// Paper start- timings
|
||||
- TimingHistory.activatedEntityTicks++;
|
||||
- timer = entity.getVehicle() != null ? entity.getType().passengerTickTimer.startTiming() : entity.getType().tickTimer.startTiming();
|
||||
+ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity);
|
||||
+ timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper
|
||||
try {
|
||||
// Paper end - timings
|
||||
entity.setPosAndOldPos(entity.getX(), entity.getY(), entity.getZ());
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
return Registry.ENTITY_TYPE.getKey(entity.getType()).toString();
|
||||
});
|
||||
gameprofilerfiller.incrementCounter("tickNonPassenger");
|
||||
+ if (isActive) { // Paper - EAR 2
|
||||
+ TimingHistory.activatedEntityTicks++; // Paper
|
||||
entity.tick();
|
||||
entity.postTick(); // CraftBukkit
|
||||
+ } else { entity.inactiveTick(); } // Paper - EAR 2
|
||||
gameprofilerfiller.pop();
|
||||
}
|
||||
|
||||
this.updateChunkPos(entity);
|
||||
+ } finally { timer.stopTiming(); } // Paper - timings
|
||||
if (entity.inChunk) {
|
||||
Iterator iterator = entity.getPassengers().iterator();
|
||||
@@ -0,0 +0,0 @@ package net.minecraft.server.level;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import co.aikar.timings.TimingHistory; // Paper
|
||||
-import co.aikar.timings.Timings; // Paper
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
@@ -0,0 +0,0 @@ import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import it.unimi.dsi.fastutil.longs.LongSets;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
-import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.chunk.storage.EntityStorage;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.end.EndDragonFight;
|
||||
-import net.minecraft.world.level.entity.EntityAccess;
|
||||
import net.minecraft.world.level.entity.EntityPersistentStorage;
|
||||
import net.minecraft.world.level.entity.EntityTickList;
|
||||
import net.minecraft.world.level.entity.EntityTypeTest;
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
this.tickPassenger(entity, entity1);
|
||||
}
|
||||
}
|
||||
- } finally { timer.stopTiming(); } // Paper - timings
|
||||
+ //} finally { timer.stopTiming(); } // Paper - timings - move up
|
||||
++TimingHistory.entityTicks; // Paper - timings
|
||||
// Spigot start
|
||||
co.aikar.timings.Timing timer; // Paper
|
||||
- if (!org.spigotmc.ActivationRange.checkIfActive(entity)) {
|
||||
+ /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below
|
||||
entity.tickCount++;
|
||||
timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings
|
||||
entity.inactiveTick();
|
||||
} finally { timer.stopTiming(); } // Paper
|
||||
return;
|
||||
- }
|
||||
+ }*/ // Paper - comment out EAR 2
|
||||
// Spigot end
|
||||
// Paper start- timings
|
||||
- TimingHistory.activatedEntityTicks++;
|
||||
- timer = entity.getVehicle() != null ? entity.getType().passengerTickTimer.startTiming() : entity.getType().tickTimer.startTiming();
|
||||
+ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity);
|
||||
+ timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper
|
||||
try {
|
||||
// Paper end - timings
|
||||
entity.isInLava();
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
return Registry.ENTITY_TYPE.getKey(entity.getType()).toString();
|
||||
});
|
||||
gameprofilerfiller.incrementCounter("tickNonPassenger");
|
||||
+ if (isActive) { // Paper - EAR 2
|
||||
+ TimingHistory.activatedEntityTicks++;
|
||||
entity.tick();
|
||||
entity.postTick(); // CraftBukkit
|
||||
+ } else { entity.inactiveTick(); } // Paper - EAR 2
|
||||
this.getProfiler().pop();
|
||||
+ } finally { timer.stopTiming(); } // Paper - timings
|
||||
Iterator iterator = entity.getPassengers().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
this.tickPassenger(entity, entity1);
|
||||
}
|
||||
|
||||
- } finally { timer.stopTiming(); } // Paper - timings
|
||||
+ // } finally { timer.stopTiming(); } // Paper - timings - move up
|
||||
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
public void tickPassenger(Entity vehicle, Entity passenger) {
|
||||
if (!passenger.removed && passenger.getVehicle() == vehicle) {
|
||||
if (passenger instanceof Player || this.getChunkSource().isEntityTickingChunk(passenger)) {
|
||||
|
||||
private void tickPassenger(Entity vehicle, Entity passenger) {
|
||||
if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) {
|
||||
if (passenger instanceof Player || this.entityTickList.contains(passenger)) {
|
||||
+ // Paper - EAR 2
|
||||
+ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger);
|
||||
+ co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper
|
||||
+ try {
|
||||
+ // Paper end
|
||||
passenger.setPosAndOldPos(passenger.getX(), passenger.getY(), passenger.getZ());
|
||||
passenger.yRotO = passenger.yRot;
|
||||
passenger.xRotO = passenger.xRot;
|
||||
passenger.setOldPosAndRot();
|
||||
++passenger.tickCount;
|
||||
ProfilerFiller gameprofilerfiller = this.getProfiler();
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
return Registry.ENTITY_TYPE.getKey(passenger.getType()).toString();
|
||||
});
|
||||
gameprofilerfiller.incrementCounter("tickPassenger");
|
||||
+ // Paper start - EAR 2
|
||||
+ if (isActive) {
|
||||
passenger.rideTick();
|
||||
passenger.postTick(); // CraftBukkit
|
||||
+ } else {
|
||||
+ passenger.setDeltaMovement(Vec3.ZERO);
|
||||
+ passenger.inactiveTick();
|
||||
+ // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary
|
||||
+ vehicle.syncPositionOf(passenger);
|
||||
+ }
|
||||
+ // Paper end - EAR 2
|
||||
gameprofilerfiller.pop();
|
||||
return Registry.ENTITY_TYPE.getKey(passenger.getType()).toString();
|
||||
});
|
||||
gameprofilerfiller.incrementCounter("tickPassenger");
|
||||
+ // Paper start - EAR 2
|
||||
+ if (isActive) {
|
||||
passenger.rideTick();
|
||||
passenger.postTick(); // CraftBukkit
|
||||
+ } else {
|
||||
+ passenger.setDeltaMovement(Vec3.ZERO);
|
||||
+ passenger.inactiveTick();
|
||||
+ // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary
|
||||
+ vehicle.positionRider(passenger);
|
||||
+ }
|
||||
+ // Paper end - EAR 2
|
||||
gameprofilerfiller.pop();
|
||||
Iterator iterator = passenger.getPassengers().iterator();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
this.tickPassenger(passenger, entity2);
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
|
||||
this.tickPassenger(passenger, entity2);
|
||||
}
|
||||
- }
|
||||
+ } } finally { timer.stopTiming(); } // Paper - EAR2 timings
|
||||
|
||||
+ } finally { timer.stopTiming(); }// Paper - EAR2 timings
|
||||
}
|
||||
} else {
|
||||
passenger.stopRiding();
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.entity.animal.AbstractFish;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
+import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
import net.minecraft.world.entity.vehicle.Boat;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
public boolean noCulling;
|
||||
public boolean hasImpulse;
|
||||
public int portalCooldown;
|
||||
|
@ -127,7 +136,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
protected int portalTime;
|
||||
protected BlockPos portalEntrancePos;
|
||||
private boolean invulnerable;
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
|
||||
public final boolean defaultActivationState;
|
||||
public long activatedTick = Integer.MIN_VALUE;
|
||||
|
@ -135,51 +144,35 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
|
||||
protected int numCollisions = 0; // Paper
|
||||
public void inactiveTick() { }
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
this.setLocationFromBoundingbox();
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
} else {
|
||||
if (type == MoverType.PISTON) {
|
||||
this.wasOnFire = this.isOnFire();
|
||||
if (movementType == MoverType.PISTON) {
|
||||
+ this.activatedTick = MinecraftServer.currentTick + 20; // Paper
|
||||
movement = this.limitPistonMovement(movement);
|
||||
if (movement.equals(Vec3.ZERO)) {
|
||||
return;
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
this.stuckSpeedMultiplier = Vec3.ZERO;
|
||||
this.setDeltaMovement(Vec3.ZERO);
|
||||
}
|
||||
+ // Paper start - ignore movement changes while inactive.
|
||||
+ if (isTemporarilyActive && !(this instanceof ItemEntity || this instanceof AbstractMinecart) && movement == getDeltaMovement() && type == MoverType.SELF) {
|
||||
+ if (isTemporarilyActive && !(this instanceof ItemEntity || this instanceof net.minecraft.world.entity.vehicle.AbstractMinecart) && movement == getDeltaMovement() && movementType == MoverType.SELF) {
|
||||
+ setDeltaMovement(Vec3.ZERO);
|
||||
+ this.level.getProfiler().pop();
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
movement = this.maybeBackOffFromEdge(movement, type);
|
||||
movement = this.maybeBackOffFromEdge(movement, movementType);
|
||||
Vec3 vec3d1 = this.collide(movement);
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
}
|
||||
}
|
||||
|
||||
+ public void syncPositionOf(Entity entity) { positionRider(entity); } // Paper - OBFHELPER
|
||||
public void positionRider(Entity passenger) {
|
||||
this.positionRider(passenger, Entity::setPos);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
return this.stringUUID;
|
||||
}
|
||||
|
||||
+ public final boolean isPushedByWater() { return this.isPushedByFluid(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it!
|
||||
public boolean isPushedByFluid() {
|
||||
// Paper start
|
||||
return this.pushedByWater();
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
protected float rotOffs;
|
||||
protected int deathScore;protected int getKillCount() { return this.deathScore; } // Paper - OBFHELPER
|
||||
protected int deathScore;
|
||||
public float lastHurt;
|
||||
- protected boolean jumping;
|
||||
+ public boolean jumping; // Paper protected -> public
|
||||
|
@ -231,51 +224,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
protected PathfinderMob(EntityType<? extends PathfinderMob> type, Level world) {
|
||||
super(type, world);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Goal {
|
||||
|
||||
public void start() {}
|
||||
|
||||
- public void stop() {}
|
||||
+ public void stop() {
|
||||
+ onTaskReset(); // Paper
|
||||
+ }
|
||||
+ public void onTaskReset() {} // Paper
|
||||
|
||||
public void tick() {}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
@@ -0,0 +0,0 @@ public class GoalSelector {
|
||||
}
|
||||
};
|
||||
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap(Goal.Flag.class);
|
||||
- private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet();
|
||||
+ private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet(); private Set<WrappedGoal> getTasks() { return availableGoals; }// Paper - OBFHELPER
|
||||
private final Supplier<ProfilerFiller> profiler;
|
||||
private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class);
|
||||
- private int newGoalRate = 3;
|
||||
+ private int newGoalRate = 3;private int getTickRate() { return newGoalRate; } // Paper - OBFHELPER
|
||||
+ private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO
|
||||
private int tickCount;
|
||||
private int newGoalRate = 3;
|
||||
+ private int curRate;
|
||||
|
||||
public GoalSelector(Supplier<ProfilerFiller> profiler) {
|
||||
this.profiler = profiler;
|
||||
@@ -0,0 +0,0 @@ public class GoalSelector {
|
||||
this.availableGoals.add(new WrappedGoal(priority, goal));
|
||||
this.availableGoals.clear();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public boolean inactiveTick() {
|
||||
+ incRate();
|
||||
+ return getCurRate() % getTickRate() == 0;
|
||||
+ this.curRate++;
|
||||
+ return this.curRate % this.newGoalRate == 0;
|
||||
+ }
|
||||
+ public boolean hasTasks() {
|
||||
+ for (WrappedGoal task : getTasks()) {
|
||||
+ for (WrappedGoal task : this.availableGoals) {
|
||||
+ if (task.isRunning()) {
|
||||
+ return true;
|
||||
+ }
|
||||
|
@ -283,26 +254,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public void removeGoal(Goal goal) {
|
||||
this.availableGoals.stream().filter((pathfindergoalwrapped) -> {
|
||||
return pathfindergoalwrapped.getGoal() == goal;
|
||||
this.availableGoals.stream().filter((wrappedGoal) -> {
|
||||
return wrappedGoal.getGoal() == goal;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.LevelReader;
|
||||
|
||||
public abstract class MoveToBlockGoal extends Goal {
|
||||
|
||||
- protected final PathfinderMob mob;
|
||||
+ protected final PathfinderMob mob;public PathfinderMob getEntity() { return mob; } // Paper - OBFHELPER
|
||||
public final double speedModifier;
|
||||
@@ -0,0 +0,0 @@ public abstract class MoveToBlockGoal extends Goal {
|
||||
protected int nextStartTick;
|
||||
protected int tryTicks;
|
||||
private int maxStayTicks;
|
||||
- protected BlockPos blockPos;public final BlockPos getTargetPosition() { return this.blockPos; } // Paper - OBFHELPER
|
||||
+ protected BlockPos blockPos; public final BlockPos getTargetPosition() { return this.blockPos; } public void setTargetPosition(BlockPos pos) { this.blockPos = pos; getEntity().movingTarget = pos != BlockPos.ZERO ? pos : null; } // Paper - OBFHELPER
|
||||
- protected BlockPos blockPos = BlockPos.ZERO; public final BlockPos getTargetPosition() { return this.blockPos; } // Paper - OBFHELPER
|
||||
+ protected BlockPos blockPos = BlockPos.ZERO; public final BlockPos getTargetPosition() { return this.blockPos; } public void setTargetPosition(BlockPos pos) { this.blockPos = pos; mob.movingTarget = pos != BlockPos.ZERO ? pos : null; } // Paper - OBFHELPER
|
||||
private boolean reachedTarget;
|
||||
private final int searchRange;
|
||||
private final int verticalSearchRange;
|
||||
|
@ -312,63 +276,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
+ // Paper start - activation range improvements
|
||||
+ @Override
|
||||
+ public void onTaskReset() {
|
||||
+ super.onTaskReset();
|
||||
+ public void stop() {
|
||||
+ super.stop();
|
||||
+ setTargetPosition(BlockPos.ZERO);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public MoveToBlockGoal(PathfinderMob mob, double speed, int range, int maxYDifference) {
|
||||
this.blockPos = BlockPos.ZERO;
|
||||
this.mob = mob;
|
||||
@@ -0,0 +0,0 @@ public abstract class MoveToBlockGoal extends Goal {
|
||||
blockposition_mutableblockposition.setWithOffset((Vec3i) blockposition, i1, k - 1, j1);
|
||||
if (this.mob.isWithinRestriction((BlockPos) blockposition_mutableblockposition) && this.isValidTarget(this.mob.level, blockposition_mutableblockposition)) {
|
||||
this.blockPos = blockposition_mutableblockposition;
|
||||
+ setTargetPosition(blockposition_mutableblockposition.immutable()); // Paper
|
||||
mutableBlockPos.setWithOffset(blockPos, m, k - 1, n);
|
||||
if (this.mob.isWithinRestriction(mutableBlockPos) && this.isValidTarget(this.mob.level, mutableBlockPos)) {
|
||||
this.blockPos = mutableBlockPos;
|
||||
+ setTargetPosition(mutableBlockPos.immutable()); // Paper
|
||||
return true;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java
|
||||
@@ -0,0 +0,0 @@ public class WrappedGoal extends Goal {
|
||||
return this.goal.getFlags();
|
||||
}
|
||||
|
||||
+ public boolean isRunning() { return this.isRunning(); } // Paper - OBFHELPER
|
||||
public boolean isRunning() {
|
||||
return this.isRunning;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
|
||||
@@ -0,0 +0,0 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
|
||||
return this.caravanTail != null;
|
||||
}
|
||||
|
||||
+ public final boolean inCaravan() { return this.inCaravan(); } // Paper - OBFHELPER
|
||||
public boolean inCaravan() {
|
||||
return this.caravanHead != null;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractVillager extends AgableMob implements Npc, Merchan
|
||||
return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData, entityTag);
|
||||
}
|
||||
|
||||
+ public final int getUnhappy() { return getUnhappyCounter(); } // Paper - OBFHELPER
|
||||
public int getUnhappyCounter() {
|
||||
return (Integer) this.entityData.get(AbstractVillager.DATA_UNHAPPY_COUNTER);
|
||||
}
|
||||
|
||||
+ public final void setUnhappy(int i) { setUnhappyCounter(i); } // Paper - OBFHELPER
|
||||
public void setUnhappyCounter(int ticks) {
|
||||
this.entityData.set(AbstractVillager.DATA_UNHAPPY_COUNTER, ticks);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
|
@ -380,17 +303,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- if (level.spigotConfig.tickInactiveVillagers && this.isEffectiveAi()) {
|
||||
- this.customServerAiStep();
|
||||
+ // Paper start
|
||||
+ if (this.getUnhappy() > 0) {
|
||||
+ this.setUnhappy(this.getUnhappy() - 1);
|
||||
}
|
||||
+ if (this.getUnhappyCounter() > 0) {
|
||||
+ this.setUnhappyCounter(this.getUnhappyCounter() - 1);
|
||||
+ }
|
||||
+ if (this.isEffectiveAi()) {
|
||||
+ if (level.spigotConfig.tickInactiveVillagers) {
|
||||
+ this.customServerAiStep();
|
||||
+ } else {
|
||||
+ this.mobTick(true);
|
||||
+ }
|
||||
+ }
|
||||
+ doReputationTick();
|
||||
}
|
||||
+ maybeDecayGossip();
|
||||
+ // Paper end
|
||||
+
|
||||
super.inactiveTick();
|
||||
|
@ -424,14 +347,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
super.customServerAiStep();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
}
|
||||
}
|
||||
|
||||
+ private void doReputationTick() { maybeDecayGossip(); } // Paper - OBFHELPER
|
||||
private void maybeDecayGossip() {
|
||||
long i = this.level.getGameTime();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
|
@ -456,11 +371,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@
|
||||
package org.spigotmc;
|
||||
|
||||
import java.util.Collection;
|
||||
-import java.util.Collection;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.entity.FlyingMob;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
|
@ -478,7 +392,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
||||
import net.minecraft.world.entity.boss.wither.WitherBoss;
|
||||
+import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||
import net.minecraft.world.entity.item.PrimedTnt;
|
||||
import net.minecraft.world.entity.monster.Creeper;
|
||||
-import net.minecraft.world.entity.monster.Monster;
|
||||
|
@ -497,7 +410,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+import co.aikar.timings.MinecraftTimings;
|
||||
+import net.minecraft.world.entity.schedule.Activity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
-import co.aikar.timings.MinecraftTimings;
|
||||
|
||||
|
@ -590,15 +502,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|| entity instanceof Player
|
||||
|| entity instanceof ThrowableProjectile
|
||||
|| entity instanceof EnderDragon
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
|| entity instanceof AbstractHurtingProjectile
|
||||
|| entity instanceof LightningBolt
|
||||
|| entity instanceof PrimedTnt
|
||||
- || entity instanceof EntityFallingBlock // Paper - Always tick falling blocks
|
||||
+ || entity instanceof FallingBlockEntity // Paper - Always tick falling blocks
|
||||
|| entity instanceof EndCrystal
|
||||
|| entity instanceof FireworkRocketEntity
|
||||
|| entity instanceof ThrownTrident )
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
final int raiderActivationRange = world.spigotConfig.raiderActivationRange;
|
||||
final int animalActivationRange = world.spigotConfig.animalActivationRange;
|
||||
|
@ -635,45 +538,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ ActivationType.VILLAGER.boundingBox = player.getBoundingBox().inflate( villagerActivationRange, 256, waterActivationRange );
|
||||
+ // Paper end
|
||||
|
||||
int i = Mth.floor( maxBB.minX / 16.0D );
|
||||
int j = Mth.floor( maxBB.maxX / 16.0D );
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
{
|
||||
for ( int j1 = k; j1 <= l; ++j1 )
|
||||
{
|
||||
- LevelChunk chunk = (LevelChunk) world.getChunkIfLoadedImmediately( i1, j1 );
|
||||
+ LevelChunk chunk = chunkProvider.getChunkAtIfLoadedMainThreadNoCache( i1, j1 ); // Paper
|
||||
if ( chunk != null )
|
||||
{
|
||||
activateChunkEntities( chunk );
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
*/
|
||||
private static void activateChunkEntities(LevelChunk chunk)
|
||||
{
|
||||
- for ( java.util.List<Entity> slice : chunk.entitySlices )
|
||||
- {
|
||||
- for ( Entity entity : (Collection<Entity>) slice )
|
||||
+ // Paper start
|
||||
+ Entity[] rawData = chunk.entities.getRawData();
|
||||
+ for (int i = 0; i < chunk.entities.size(); i++) {
|
||||
+ Entity entity = rawData[i];
|
||||
+ //for ( Entity entity : (Collection<Entity>) slice )
|
||||
+ // Paper end
|
||||
{
|
||||
- if ( MinecraftServer.currentTick > entity.activatedTick )
|
||||
- {
|
||||
- if ( entity.defaultActivationState )
|
||||
- {
|
||||
- entity.activatedTick = MinecraftServer.currentTick;
|
||||
- continue;
|
||||
- }
|
||||
- if ( entity.activationType.boundingBox.intersects( entity.getBoundingBox() ) )
|
||||
- {
|
||||
+ if (MinecraftServer.currentTick > entity.activatedTick) {
|
||||
+ if (entity.defaultActivationState || entity.activationType.boundingBox.intersects(entity.getBoundingBox())) { // Paper
|
||||
entity.activatedTick = MinecraftServer.currentTick;
|
||||
}
|
||||
}
|
||||
world.getEntities().get(maxBB, ActivationRange::activateEntity);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
* @param entity
|
||||
* @return
|
||||
|
@ -694,7 +560,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
// quick checks.
|
||||
- if ( entity.wasTouchingWater || entity.remainingFireTicks > 0 )
|
||||
+ if ( (entity.activationType != ActivationType.WATER && entity.wasTouchingWater && entity.isPushedByWater()) ) // Paper
|
||||
+ if ( (entity.activationType != ActivationType.WATER && entity.wasTouchingWater && entity.isPushedByFluid()) ) // Paper
|
||||
{
|
||||
- return true;
|
||||
+ return 100; // Paper
|
||||
|
@ -780,7 +646,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if (entity instanceof Creeper && ((Creeper) entity).isIgnited()) { // isExplosive
|
||||
- return true;
|
||||
+ return 20; // Paper
|
||||
}
|
||||
+ }
|
||||
+ // Paper start
|
||||
+ if (entity instanceof Mob && ((Mob) entity).targetSelector.hasTasks() ) {
|
||||
+ return 0;
|
||||
|
@ -788,7 +654,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if (entity instanceof Pillager) {
|
||||
+ Pillager pillager = (Pillager) entity;
|
||||
+ // TODO:?
|
||||
+ }
|
||||
}
|
||||
+ // Paper end
|
||||
}
|
||||
- return false;
|
||||
|
@ -797,7 +663,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
/**
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
if ( !entity.inChunk || entity instanceof FireworkRocketEntity ) {
|
||||
if ( entity instanceof FireworkRocketEntity ) {
|
||||
return true;
|
||||
}
|
||||
+ // Paper start - special case always immunities
|
||||
|
@ -821,7 +687,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if ( ( MinecraftServer.currentTick - entity.activatedTick - 1 ) % 20 == 0 )
|
||||
{
|
||||
// Check immunities every 20 ticks.
|
||||
- if ( checkEntityImmunities( entity ) )
|
||||
- if ( ActivationRange.checkEntityImmunities( entity ) )
|
||||
- {
|
||||
- // Triggered some sort of immunity, give 20 full ticks before we check again.
|
||||
- entity.activatedTick = MinecraftServer.currentTick + 20;
|
||||
|
@ -837,8 +703,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
}
|
||||
// Add a little performance juice to active entities. Skip 1/4 if not immune.
|
||||
- } else if ( !entity.defaultActivationState && entity.tickCount % 4 == 0 && !checkEntityImmunities( entity ) )
|
||||
+ } else if (entity.tickCount % 4 == 0 && checkEntityImmunities( entity) < 0 ) // Paper
|
||||
- } else if ( !entity.defaultActivationState && entity.tickCount % 4 == 0 && !ActivationRange.checkEntityImmunities( entity ) )
|
||||
+ } else if ( entity.tickCount % 4 == 0 && ActivationRange.checkEntityImmunities( entity ) < 0 ) // Paper
|
||||
{
|
||||
isActive = false;
|
||||
}
|
||||
|
@ -873,36 +739,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public boolean tickInactiveVillagers = true;
|
||||
private void activationRange()
|
||||
{
|
||||
+ boolean hasAnimalsConfig = config.getInt("entity-activation-range.animals", animalActivationRange) != animalActivationRange; // Paper
|
||||
animalActivationRange = getInt( "entity-activation-range.animals", animalActivationRange );
|
||||
monsterActivationRange = getInt( "entity-activation-range.monsters", monsterActivationRange );
|
||||
raiderActivationRange = getInt( "entity-activation-range.raiders", raiderActivationRange );
|
||||
miscActivationRange = getInt( "entity-activation-range.misc", miscActivationRange );
|
||||
+ boolean hasAnimalsConfig = config.getInt("entity-activation-range.animals", this.animalActivationRange) != this.animalActivationRange; // Paper
|
||||
this.animalActivationRange = this.getInt( "entity-activation-range.animals", this.animalActivationRange );
|
||||
this.monsterActivationRange = this.getInt( "entity-activation-range.monsters", this.monsterActivationRange );
|
||||
this.raiderActivationRange = this.getInt( "entity-activation-range.raiders", this.raiderActivationRange );
|
||||
this.miscActivationRange = this.getInt( "entity-activation-range.misc", this.miscActivationRange );
|
||||
+ // Paper start
|
||||
+ waterActivationRange = getInt( "entity-activation-range.water", waterActivationRange );
|
||||
+ villagerActivationRange = getInt( "entity-activation-range.villagers", hasAnimalsConfig ? animalActivationRange : villagerActivationRange );
|
||||
+ flyingMonsterActivationRange = getInt( "entity-activation-range.flying-monsters", flyingMonsterActivationRange );
|
||||
+ this.waterActivationRange = this.getInt( "entity-activation-range.water", this.waterActivationRange );
|
||||
+ this.villagerActivationRange = this.getInt( "entity-activation-range.villagers", hasAnimalsConfig ? this.animalActivationRange : this.villagerActivationRange );
|
||||
+ this.flyingMonsterActivationRange = this.getInt( "entity-activation-range.flying-monsters", this.flyingMonsterActivationRange );
|
||||
+
|
||||
+ wakeUpInactiveAnimals = getInt("entity-activation-range.wake-up-inactive.animals-max-per-tick", wakeUpInactiveAnimals);
|
||||
+ wakeUpInactiveAnimalsEvery = getInt("entity-activation-range.wake-up-inactive.animals-every", wakeUpInactiveAnimalsEvery);
|
||||
+ wakeUpInactiveAnimalsFor = getInt("entity-activation-range.wake-up-inactive.animals-for", wakeUpInactiveAnimalsFor);
|
||||
+ this.wakeUpInactiveAnimals = this.getInt("entity-activation-range.wake-up-inactive.animals-max-per-tick", this.wakeUpInactiveAnimals);
|
||||
+ this.wakeUpInactiveAnimalsEvery = this.getInt("entity-activation-range.wake-up-inactive.animals-every", this.wakeUpInactiveAnimalsEvery);
|
||||
+ this.wakeUpInactiveAnimalsFor = this.getInt("entity-activation-range.wake-up-inactive.animals-for", this.wakeUpInactiveAnimalsFor);
|
||||
+
|
||||
+ wakeUpInactiveMonsters = getInt("entity-activation-range.wake-up-inactive.monsters-max-per-tick", wakeUpInactiveMonsters);
|
||||
+ wakeUpInactiveMonstersEvery = getInt("entity-activation-range.wake-up-inactive.monsters-every", wakeUpInactiveMonstersEvery);
|
||||
+ wakeUpInactiveMonstersFor = getInt("entity-activation-range.wake-up-inactive.monsters-for", wakeUpInactiveMonstersFor);
|
||||
+ this.wakeUpInactiveMonsters = this.getInt("entity-activation-range.wake-up-inactive.monsters-max-per-tick", this.wakeUpInactiveMonsters);
|
||||
+ this.wakeUpInactiveMonstersEvery = this.getInt("entity-activation-range.wake-up-inactive.monsters-every", this.wakeUpInactiveMonstersEvery);
|
||||
+ this.wakeUpInactiveMonstersFor = this.getInt("entity-activation-range.wake-up-inactive.monsters-for", this.wakeUpInactiveMonstersFor);
|
||||
+
|
||||
+ wakeUpInactiveVillagers = getInt("entity-activation-range.wake-up-inactive.villagers-max-per-tick", wakeUpInactiveVillagers);
|
||||
+ wakeUpInactiveVillagersEvery = getInt("entity-activation-range.wake-up-inactive.villagers-every", wakeUpInactiveVillagersEvery);
|
||||
+ wakeUpInactiveVillagersFor = getInt("entity-activation-range.wake-up-inactive.villagers-for", wakeUpInactiveVillagersFor);
|
||||
+ this.wakeUpInactiveVillagers = this.getInt("entity-activation-range.wake-up-inactive.villagers-max-per-tick", this.wakeUpInactiveVillagers);
|
||||
+ this.wakeUpInactiveVillagersEvery = this.getInt("entity-activation-range.wake-up-inactive.villagers-every", this.wakeUpInactiveVillagersEvery);
|
||||
+ this.wakeUpInactiveVillagersFor = this.getInt("entity-activation-range.wake-up-inactive.villagers-for", this.wakeUpInactiveVillagersFor);
|
||||
+
|
||||
+ wakeUpInactiveFlying = getInt("entity-activation-range.wake-up-inactive.flying-monsters-max-per-tick", wakeUpInactiveFlying);
|
||||
+ wakeUpInactiveFlyingEvery = getInt("entity-activation-range.wake-up-inactive.flying-monsters-every", wakeUpInactiveFlyingEvery);
|
||||
+ wakeUpInactiveFlyingFor = getInt("entity-activation-range.wake-up-inactive.flying-monsters-for", wakeUpInactiveFlyingFor);
|
||||
+ this.wakeUpInactiveFlying = this.getInt("entity-activation-range.wake-up-inactive.flying-monsters-max-per-tick", this.wakeUpInactiveFlying);
|
||||
+ this.wakeUpInactiveFlyingEvery = this.getInt("entity-activation-range.wake-up-inactive.flying-monsters-every", this.wakeUpInactiveFlyingEvery);
|
||||
+ this.wakeUpInactiveFlyingFor = this.getInt("entity-activation-range.wake-up-inactive.flying-monsters-for", this.wakeUpInactiveFlyingFor);
|
||||
+
|
||||
+ villagersWorkImmunityAfter = getInt( "entity-activation-range.villagers-work-immunity-after", villagersWorkImmunityAfter );
|
||||
+ villagersWorkImmunityFor = getInt( "entity-activation-range.villagers-work-immunity-for", villagersWorkImmunityFor );
|
||||
+ villagersActiveForPanic = getBoolean( "entity-activation-range.villagers-active-for-panic", villagersActiveForPanic );
|
||||
+ this.villagersWorkImmunityAfter = this.getInt( "entity-activation-range.villagers-work-immunity-after", this.villagersWorkImmunityAfter );
|
||||
+ this.villagersWorkImmunityFor = this.getInt( "entity-activation-range.villagers-work-immunity-for", this.villagersWorkImmunityFor );
|
||||
+ this.villagersActiveForPanic = this.getBoolean( "entity-activation-range.villagers-active-for-panic", this.villagersActiveForPanic );
|
||||
+ // Paper end
|
||||
tickInactiveVillagers = getBoolean( "entity-activation-range.tick-inactive-villagers", tickInactiveVillagers );
|
||||
log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Ra " + raiderActivationRange + " / Mi " + miscActivationRange + " / Tiv " + tickInactiveVillagers );
|
||||
this.tickInactiveVillagers = this.getBoolean( "entity-activation-range.tick-inactive-villagers", this.tickInactiveVillagers );
|
||||
this.log( "Entity Activation Range: An " + this.animalActivationRange + " / Mo " + this.monsterActivationRange + " / Ra " + this.raiderActivationRange + " / Mi " + this.miscActivationRange + " / Tiv " + this.tickInactiveVillagers );
|
||||
}
|
|
@ -10,7 +10,7 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524
|
||||
return;
|
||||
}
|
||||
|
@ -21,15 +21,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
InteractionResult enuminteractionresult = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand);
|
||||
|
||||
if (enuminteractionresult.shouldSwing()) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
return predicate.test(this.getMainHandItem().getItem()) || predicate.test(this.getOffhandItem().getItem());
|
||||
}
|
||||
|
||||
+ public final ItemStack getItemInHand(InteractionHand enumhand) { return this.getItemInHand(enumhand); } // Paper - OBFHELPER
|
||||
public ItemStack getItemInHand(InteractionHand hand) {
|
||||
if (hand == InteractionHand.MAIN_HAND) {
|
||||
return this.getItemBySlot(EquipmentSlot.MAINHAND);
|
|
@ -10,28 +10,16 @@ diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
@@ -0,0 +0,0 @@ import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
-import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
-import net.minecraft.server.MCUtil;
|
||||
+import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
|
@ -40,8 +28,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
@@ -0,0 +0,0 @@ import java.io.PrintStream;
|
||||
import java.io.StringWriter;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
+import java.util.ArrayDeque;
|
||||
|
@ -57,14 +43,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
public class PaperCommand extends Command {
|
||||
private static final String BASE_PERM = "bukkit.command.paper.";
|
||||
- private static final ImmutableSet<String> SUBCOMMANDS = ImmutableSet.<String>builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo", "dumpwaiting", "syncloadinfo").build();
|
||||
+ private static final ImmutableSet<String> SUBCOMMANDS = ImmutableSet.<String>builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo", "dumpwaiting", "syncloadinfo", "fixlight").build();
|
||||
- private static final ImmutableSet<String> SUBCOMMANDS = ImmutableSet.<String>builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo").build();
|
||||
+ private static final ImmutableSet<String> SUBCOMMANDS = ImmutableSet.<String>builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo", "fixlight").build();
|
||||
|
||||
public PaperCommand(String name) {
|
||||
super(name);
|
||||
@@ -0,0 +0,0 @@ public class PaperCommand extends Command {
|
||||
case "syncloadinfo":
|
||||
this.doSyncLoadInfo(sender, args);
|
||||
case "chunkinfo":
|
||||
doChunkInfo(sender, args);
|
||||
break;
|
||||
+ case "fixlight":
|
||||
+ this.doFixLight(sender, args);
|
||||
|
@ -73,9 +59,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if (!testPermission(sender, "version")) break; // "ver" needs a special check because it's an alias. All other commands are checked up before the switch statement (because they are present in the SUBCOMMANDS set)
|
||||
case "version":
|
||||
@@ -0,0 +0,0 @@ public class PaperCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Paper config reload complete.");
|
||||
}
|
||||
+ private void doFixLight(CommandSender sender, String[] args) {
|
||||
+ if (!(sender instanceof Player)) {
|
||||
+ sender.sendMessage("Only players can use this command");
|
||||
|
@ -97,7 +83,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ ServerLevel world = (ServerLevel) handle.level;
|
||||
+ ThreadedLevelLightEngine lightengine = world.getChunkSource().getLightEngine();
|
||||
+
|
||||
+ BlockPos center = MCUtil.toBlockPosition(player.getLocation());
|
||||
+ net.minecraft.core.BlockPos center = MCUtil.toBlockPosition(player.getLocation());
|
||||
+ Deque<ChunkPos> queue = new ArrayDeque<>(MCUtil.getSpiralOutChunks(center, radius));
|
||||
+ updateLight(sender, world, lightengine, queue);
|
||||
+ }
|
||||
|
@ -114,7 +100,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ updateLight(sender, world, lightengine, queue);
|
||||
+ return;
|
||||
+ }
|
||||
+ LevelChunk chunk = (LevelChunk) either.left().orElse(null);
|
||||
+ net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk) either.left().orElse(null);
|
||||
+ if (chunk == null) {
|
||||
+ updateLight(sender, world, lightengine, queue);
|
||||
+ return;
|
||||
|
@ -126,7 +112,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ for (int y = 0; y < world.getHeight(); y++) {
|
||||
+ for (int x = 0; x < 16; x++) {
|
||||
+ for (int z = 0; z < 16; z++) {
|
||||
+ BlockPos pos = new BlockPos(cx + x, y, cz + z);
|
||||
+ net.minecraft.core.BlockPos pos = new net.minecraft.core.BlockPos(cx + x, y, cz + z);
|
||||
+ lightengine.checkBlock(pos);
|
||||
+ }
|
||||
+ }
|
||||
|
@ -136,7 +122,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if (visibleChunk != null) {
|
||||
+ world.getChunkSource().chunkMap.addLightTask(visibleChunk, () -> {
|
||||
+ MinecraftServer.getServer().processQueue.add(() -> {
|
||||
+ visibleChunk.sendPacketToTrackedPlayers(new ClientboundLightUpdatePacket(chunk.getPos(), lightengine, true), false);
|
||||
+ visibleChunk.broadcast(new net.minecraft.network.protocol.game.ClientboundLightUpdatePacket(chunk.getPos(), lightengine, null, null, true), false);
|
||||
+ updateLight(sender, world, lightengine, queue);
|
||||
+ });
|
||||
+ });
|
||||
|
@ -146,10 +132,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ lightengine.setTaskPerBatch(world.paperConfig.lightQueueSize);
|
||||
+ }, MinecraftServer.getServer());
|
||||
+ }
|
||||
+
|
||||
private void doSyncLoadInfo(CommandSender sender, String[] args) {
|
||||
if (!SyncLoadFinder.ENABLED) {
|
||||
sender.sendMessage(ChatColor.RED + "This command requires the server startup flag '-Dpaper.debug-sync-loads=true' to be set.");
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
|
@ -158,25 +141,39 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
}
|
||||
|
||||
+ public void sendPacketToTrackedPlayers(Packet<?> packet, boolean flag) { broadcast(packet, flag); } // Paper - OBFHELPER
|
||||
private void broadcast(Packet<?> packet, boolean onlyOnWatchDistanceEdge) {
|
||||
// Paper start - per player view distance
|
||||
// there can be potential desync with player's last mapped section and the view distance map, so use the
|
||||
- private void broadcast(Packet<?> packet, boolean onlyOnWatchDistanceEdge) {
|
||||
+ public void broadcast(Packet<?> packet, boolean onlyOnWatchDistanceEdge) { // Paper - private -> public
|
||||
this.playerProvider.getPlayers(this.pos, onlyOnWatchDistanceEdge).forEach((entityplayer) -> {
|
||||
entityplayer.connection.send(packet);
|
||||
});
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
ProcessorHandle<Runnable> mailbox = ProcessorHandle.of("main", mainThreadExecutor::tell);
|
||||
private final ChunkTaskPriorityQueueSorter queueSorter;
|
||||
private final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> worldgenMailbox;
|
||||
private final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> mainThreadMailbox;
|
||||
+ // Paper start
|
||||
+ final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> mailboxLight;
|
||||
+ public void addLightTask(ChunkHolder playerchunk, Runnable run) {
|
||||
+ this.mailboxLight.tell(ChunkTaskPriorityQueueSorter.message(playerchunk, run));
|
||||
+ }
|
||||
+ // Paper end
|
||||
public final ChunkProgressListener progressListener;
|
||||
private final ChunkStatusUpdateListener chunkStatusListener;
|
||||
public final ChunkMap.ChunkDistanceManager distanceManager;
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
this.progressListener = worldGenerationProgressListener;
|
||||
- ProcessorMailbox<Runnable> threadedmailbox1 = ProcessorMailbox.create(workerExecutor, "light");
|
||||
+ ProcessorMailbox<Runnable> lightthreaded; ProcessorMailbox<Runnable> threadedmailbox1 = lightthreaded = ProcessorMailbox.create(workerExecutor, "light"); // Paper
|
||||
this.chunkStatusListener = chunkStatusChangeListener;
|
||||
- ProcessorMailbox<Runnable> threadedmailbox1 = ProcessorMailbox.create(executor, "light");
|
||||
+ ProcessorMailbox<Runnable> lightthreaded; ProcessorMailbox<Runnable> threadedmailbox1 = lightthreaded = ProcessorMailbox.create(executor, "light"); // Paper
|
||||
|
||||
this.queueSorter = new ChunkTaskPriorityQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), workerExecutor, Integer.MAX_VALUE);
|
||||
this.queueSorter = new ChunkTaskPriorityQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), executor, Integer.MAX_VALUE);
|
||||
this.worldgenMailbox = this.queueSorter.getProcessor(threadedmailbox, false);
|
||||
this.mainThreadMailbox = this.queueSorter.getProcessor(mailbox, false);
|
||||
+ this.mailboxLight = this.queueSorter.getProcessor(lightthreaded, false);// Paper
|
||||
this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), threadedmailbox1, this.queueSorter.getProcessor(threadedmailbox1, false));
|
||||
this.distanceManager = new ChunkMap.ChunkDistanceManager(workerExecutor, mainThreadExecutor); this.distanceManager.chunkMap = this; // Paper
|
||||
this.overworldDataStorage = supplier;
|
||||
this.distanceManager = new ChunkMap.ChunkDistanceManager(executor, mainThreadExecutor);
|
||||
this.overworldDataStorage = persistentStateManagerFactory;
|
|
@ -16,8 +16,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
- return this.horseContainer.stillValid(player) && this.horse.isAlive() && this.horse.distanceTo((Entity) player) < 8.0F;
|
||||
+ return this.horseContainer.stillValid(player) && (this.horse.isAlive() && this.horse.valid) && this.horse.distanceTo((Entity) player) < 8.0F; // Paper - Fix MC-161754
|
||||
- return !this.horse.hasInventoryChanged(this.horseContainer) && this.horseContainer.stillValid(player) && this.horse.isAlive() && this.horse.distanceTo((Entity) player) < 8.0F;
|
||||
+ return !this.horse.hasInventoryChanged(this.horseContainer) && this.horseContainer.stillValid(player) && (this.horse.isAlive() && this.horse.valid) && this.horse.distanceTo((Entity) player) < 8.0F; // Paper - Fix MC-161754
|
||||
}
|
||||
|
||||
@Override
|
||||
private boolean hasChest(AbstractHorse entityhorseabstract) {
|
|
@ -22,8 +22,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
}
|
||||
|
||||
- if (!this.onGround || getHorizontalDistanceSqr(this.getDeltaMovement()) > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) {
|
||||
+ if (!this.onGround || getHorizontalDistanceSqr(this.getDeltaMovement()) > 9.999999747378752E-6D || this.tickCount % 4 == 0) { // Paper - Ensure checking item movement is always offset from Spigot's entity activation range check
|
||||
- if (!this.onGround || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) {
|
||||
+ if (!this.onGround || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || this.tickCount % 4 == 0) { // Paper - Ensure checking item movement is always offset from Spigot's entity activation range check
|
||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
float f1 = 0.98F;
|
||||
|
|
@ -22,4 +22,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
for (BlockFace dir : faces) {
|
||||
net.minecraft.world.level.block.state.BlockState nmsBlock = world.getBlockState(pos.relative(CraftBlock.blockFaceToNotch(dir)));
|
||||
net.minecraft.world.level.block.state.BlockState nmsBlock = this.world.getBlockState(pos.relative(CraftBlock.blockFaceToNotch(dir)));
|
|
@ -8,11 +8,11 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
|
||||
+ setShiftKeyDown(false); // Paper - fix MC-10657
|
||||
+ setShiftKeyDown(false); // Paper - fix MC-10657
|
||||
+
|
||||
// CraftBukkit start
|
||||
PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver1.getWorld());
|
165
patches/server/Generator-Settings.patch
Normal file
165
patches/server/Generator-Settings.patch
Normal file
|
@ -0,0 +1,165 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Wed, 2 Mar 2016 02:17:54 -0600
|
||||
Subject: [PATCH] Generator Settings
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
|
||||
private void disableRelativeProjectileVelocity() {
|
||||
disableRelativeProjectileVelocity = getBoolean("game-mechanics.disable-relative-projectile-velocity", false);
|
||||
}
|
||||
+
|
||||
+ public boolean generateFlatBedrock;
|
||||
+ private void generatorSettings() {
|
||||
+ generateFlatBedrock = getBoolean("generator-settings.flat-bedrock", false);
|
||||
+ }
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
this.markPositionReplaceable(pos);
|
||||
- return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level));
|
||||
+ return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level, this.level)); // Paper - add level
|
||||
// Paper start - Async chunk io
|
||||
};
|
||||
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> ret = new CompletableFuture<>();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
@@ -0,0 +0,0 @@ public interface ChunkAccess extends BlockGetter, FeatureAccess {
|
||||
return GameEventDispatcher.NOOP;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ default boolean generateFlatBedrock() {
|
||||
+ if (this instanceof ProtoChunk) {
|
||||
+ return ((ProtoChunk)this).level.paperConfig.generateFlatBedrock;
|
||||
+ } else if (this instanceof LevelChunk) {
|
||||
+ return ((LevelChunk)this).level.paperConfig.generateFlatBedrock;
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
BlockState getType(final int x, final int y, final int z); // Paper
|
||||
@Nullable
|
||||
BlockState setBlockState(BlockPos pos, BlockState state, boolean moved);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
|
||||
@@ -0,0 +0,0 @@ public class ImposterProtoChunk extends ProtoChunk {
|
||||
private final LevelChunk wrapped;
|
||||
|
||||
public ImposterProtoChunk(LevelChunk wrapped) {
|
||||
- super(wrapped.getPos(), UpgradeData.EMPTY, wrapped);
|
||||
+ super(wrapped.getPos(), UpgradeData.EMPTY, wrapped, wrapped.level); // Paper - add level
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
@@ -0,0 +0,0 @@ public class ProtoChunk implements ChunkAccess {
|
||||
private long inhabitedTime;
|
||||
private final Map<GenerationStep.Carving, BitSet> carvingMasks = new Object2ObjectArrayMap<>();
|
||||
private volatile boolean isLightCorrect;
|
||||
+ final net.minecraft.world.level.Level level; // Paper - Add level
|
||||
|
||||
- public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor world) {
|
||||
+ // Paper start - add level
|
||||
+ @Deprecated public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor world) { this(pos, upgradeData, world, null); }
|
||||
+ public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor world, net.minecraft.server.level.ServerLevel level) {
|
||||
+ // Paper end
|
||||
this(pos, upgradeData, (LevelChunkSection[])null, new ProtoTickList<>((block) -> {
|
||||
return block == null || block.defaultBlockState().isAir();
|
||||
}, pos, world), new ProtoTickList<>((fluid) -> {
|
||||
return fluid == null || fluid == Fluids.EMPTY;
|
||||
- }, pos, world), world);
|
||||
+ }, pos, world), world, level); // Paper - add level
|
||||
}
|
||||
|
||||
- public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, @Nullable LevelChunkSection[] levelChunkSections, ProtoTickList<Block> blockTickScheduler, ProtoTickList<Fluid> fluidTickScheduler, LevelHeightAccessor world) {
|
||||
+ // Paper start - add level
|
||||
+ @Deprecated public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, @Nullable LevelChunkSection[] levelChunkSections, ProtoTickList<Block> blockTickScheduler, ProtoTickList<Fluid> fluidTickScheduler, LevelHeightAccessor world) { this(pos, upgradeData, levelChunkSections, blockTickScheduler, fluidTickScheduler, world, null); }
|
||||
+ public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, @Nullable LevelChunkSection[] levelChunkSections, ProtoTickList<Block> blockTickScheduler, ProtoTickList<Fluid> fluidTickScheduler, LevelHeightAccessor world, net.minecraft.server.level.ServerLevel level) {
|
||||
+ this.level = level;
|
||||
+ // Paper end
|
||||
this.chunkPos = pos;
|
||||
this.upgradeData = upgradeData;
|
||||
this.blockTicks = blockTickScheduler;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||
// CraftBukkit end
|
||||
});
|
||||
} else {
|
||||
- ProtoChunk protochunk = new ProtoChunk(pos, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, world);
|
||||
+ ProtoChunk protochunk = new ProtoChunk(pos, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, world, world); // Paper - add level
|
||||
|
||||
protochunk.setBiomes(biomestorage);
|
||||
object = protochunk;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
@@ -0,0 +0,0 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
int j = chunk.getPos().getMinBlockZ();
|
||||
NoiseGeneratorSettings noiseGeneratorSettings = this.settings.get();
|
||||
int k = noiseGeneratorSettings.noiseSettings().minY();
|
||||
- int l = k + noiseGeneratorSettings.getBedrockFloorPosition();
|
||||
- int m = this.height - 1 + k - noiseGeneratorSettings.getBedrockRoofPosition();
|
||||
+ int l = k + noiseGeneratorSettings.getBedrockFloorPosition(); final int floorHeight = k; // Paper
|
||||
+ int m = this.height - 1 + k - noiseGeneratorSettings.getBedrockRoofPosition(); final int roofHeight = l; // Paper
|
||||
int n = 5;
|
||||
int o = chunk.getMinBuildHeight();
|
||||
int p = chunk.getMaxBuildHeight();
|
||||
@@ -0,0 +0,0 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
for(BlockPos blockPos : BlockPos.betweenClosed(i, 0, j, i + 15, 0, j + 15)) {
|
||||
if (bl) {
|
||||
for(int q = 0; q < 5; ++q) {
|
||||
- if (q <= random.nextInt(5)) {
|
||||
+ if (q <= (chunk.generateFlatBedrock() ? roofHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock roof
|
||||
chunk.setBlockState(mutableBlockPos.set(blockPos.getX(), m - q, blockPos.getZ()), Blocks.BEDROCK.defaultBlockState(), false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
|
||||
if (bl2) {
|
||||
for(int r = 4; r >= 0; --r) {
|
||||
- if (r <= random.nextInt(5)) {
|
||||
+ if (r <= (chunk.generateFlatBedrock() ? roofHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock floor
|
||||
chunk.setBlockState(mutableBlockPos.set(blockPos.getX(), l + r, blockPos.getZ()), Blocks.BEDROCK.defaultBlockState(), false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
if (l <= 0) {
|
||||
return CompletableFuture.completedFuture(chunk);
|
||||
} else {
|
||||
- int m = chunk.getSectionIndex(l * this.cellHeight - 1 + i);
|
||||
+ int mStart = chunk.getSectionIndex(l * this.cellHeight - 1 + i); // Paper - decompile fix
|
||||
int n = chunk.getSectionIndex(i);
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Set<LevelChunkSection> set = Sets.newHashSet();
|
||||
|
||||
ChunkAccess var16;
|
||||
try {
|
||||
- for(int m = m; m >= n; --m) {
|
||||
+ for(int m = mStart; m >= n; --m) { // Paper - decompile fix
|
||||
LevelChunkSection levelChunkSection = chunk.getOrCreateSection(m);
|
||||
levelChunkSection.acquire();
|
||||
set.add(levelChunkSection);
|
|
@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public ChunkSerializer() {}
|
||||
|
||||
+ // Paper start - guard against serializing mismatching coordinates
|
||||
+ // TODO Note: This needs to be re-checked each update
|
||||
|
@ -25,38 +25,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||
// Paper end
|
||||
ChunkGenerator chunkgenerator = worldserver.getChunkSource().getGenerator();
|
||||
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
|
||||
BiomeSource worldchunkmanager = chunkgenerator.getBiomeSource();
|
||||
- CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Level");
|
||||
- CompoundTag nbttagcompound1 = nbt.getCompound("Level");
|
||||
- ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos"));
|
||||
+ CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Level"); // Paper - diff on change, see ChunkRegionLoader#getChunkCoordinate
|
||||
+ ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); // Paper - diff on change, see ChunkRegionLoader#getChunkCoordinate
|
||||
+ CompoundTag nbttagcompound1 = nbt.getCompound("Level"); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate
|
||||
+ ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate
|
||||
|
||||
if (!Objects.equals(chunkcoordintpair, chunkcoordintpair1)) {
|
||||
ChunkSerializer.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", chunkcoordintpair, chunkcoordintpair, chunkcoordintpair1);
|
||||
if (!Objects.equals(pos, chunkcoordintpair1)) {
|
||||
ChunkSerializer.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", pos, pos, chunkcoordintpair1);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.SharedConstants;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
+import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.datafix.DataFixTypes;
|
||||
@@ -0,0 +0,0 @@ public class ChunkStorage implements AutoCloseable {
|
||||
|
||||
public void write(ChunkPos chunkcoordintpair, CompoundTag nbttagcompound) throws IOException { write(chunkcoordintpair, nbttagcompound); } // Paper OBFHELPER
|
||||
public void write(ChunkPos chunkcoordintpair, CompoundTag nbttagcompound) throws IOException { // Paper - OBFHELPER - (Switched around for safety)
|
||||
// Paper start - async chunk io
|
||||
public void write(ChunkPos chunkPos, CompoundTag nbt) throws IOException {
|
||||
+ // Paper start
|
||||
+ if (!chunkcoordintpair.equals(ChunkSerializer.getChunkCoordinate(nbttagcompound))) {
|
||||
+ String world = (this instanceof ChunkMap) ? ((ChunkMap)this).level.getWorld().getName() : null;
|
||||
+ throw new IllegalArgumentException("Chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + chunkcoordintpair.toString()
|
||||
+ + " but compound says coordinate is " + ChunkSerializer.getChunkCoordinate(nbttagcompound).toString() + (world == null ? " for an unknown world" : (" for world: " + world)));
|
||||
+ if (!chunkPos.equals(ChunkSerializer.getChunkCoordinate(nbt))) {
|
||||
+ String world = (this instanceof net.minecraft.server.level.ChunkMap) ? ((net.minecraft.server.level.ChunkMap)this).level.getWorld().getName() : null;
|
||||
+ throw new IllegalArgumentException("Chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + chunkPos.toString()
|
||||
+ + " but compound says coordinate is " + ChunkSerializer.getChunkCoordinate(nbt).toString() + (world == null ? " for an unknown world" : (" for world: " + world)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.regionFileCache.write(chunkcoordintpair, nbttagcompound);
|
||||
this.regionFileCache.write(chunkPos, nbt);
|
||||
// Paper end - Async chunk loading
|
||||
if (this.legacyStructureHandler != null) {
|
||||
synchronized (this.persistentDataLock) { // Paper - Async chunk loading
|
|
@ -18,8 +18,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
|
||||
private void zombieVillagerInfectionChance() {
|
||||
zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance);
|
||||
disableHopperMoveEvents = getBoolean("hopper.disable-move-event", disableHopperMoveEvents);
|
||||
log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled"));
|
||||
}
|
||||
+
|
||||
+ public int lightQueueSize = 20;
|
||||
|
@ -27,6 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ lightQueueSize = getInt("light-queue-size", lightQueueSize);
|
||||
+ }
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@ -10,15 +10,6 @@ diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/ma
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
private int noJumpDelay;
|
||||
private float absorptionAmount;
|
||||
public ItemStack useItem; // Paper - public
|
||||
- protected int useItemRemaining;
|
||||
+ protected int useItemRemaining; protected final int getEatTimeTicks() { return this.useItemRemaining; } protected final void setEatTimeTicks(int value) { this.useItemRemaining = value; } // Paper - OBFHELPER
|
||||
protected int fallFlyTicks;
|
||||
private BlockPos lastPos;
|
||||
private Optional<BlockPos> lastClimbablePos;
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
|
||||
}
|
||||
|
@ -32,19 +23,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if (this.isUsingItem()) {
|
||||
if (ItemStack.isSameIgnoreDurability(this.getItemInHand(this.getUsedItemHand()), this.useItem)) {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
this.triggerItemUseEffects(this.useItem, 5);
|
||||
}
|
||||
if (this.shouldTriggerItemUseEffects()) {
|
||||
this.triggerItemUseEffects(stack, 5);
|
||||
}
|
||||
-
|
||||
- if (--this.useItemRemaining == 0 && !this.level.isClientSide && !stack.useOnRelease()) {
|
||||
+ // Paper start - lag compensate eating
|
||||
+ // we add 1 to the expected time to avoid lag compensating when we should not
|
||||
+ boolean shouldLagCompensate = this.useItem.getItem().isEdible() && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1 + this.totalEatTimeTicks) * 50 * (1000 * 1000));
|
||||
+ if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !this.level.isClientSide && !this.useItem.useOnRelease()) {
|
||||
+ this.useItemRemaining = 0;
|
||||
+ // Paper end
|
||||
this.completeUsingItem();
|
||||
}
|
||||
|
||||
- if (--this.useItemRemaining == 0 && !this.level.isClientSide && !this.useItem.useOnRelease()) {
|
||||
+ // Paper start - lag compensate eating
|
||||
+ // we add 1 to the expected time to avoid lag compensating when we should not
|
||||
+ boolean shouldLagCompensate = this.useItem.getItem().isEdible() && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1 + this.totalEatTimeTicks) * 50 * (1000 * 1000));
|
||||
+ if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !this.level.isClientSide && !this.useItem.useOnRelease()) {
|
||||
+ this.setEatTimeTicks(0);
|
||||
+ // Paper end
|
||||
this.completeUsingItem();
|
||||
}
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
|
||||
if (!itemstack.isEmpty() && !this.isUsingItem() || forceUpdate) { // Paper use override flag
|
|
@ -18,6 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ entitiesTargetWithFollowRange = getBoolean("entities-target-with-follow-range", entitiesTargetWithFollowRange);
|
||||
+ }
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java
|
||||
|
@ -25,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public class NearestAttackableTargetGoal<T extends LivingEntity> extends TargetG
|
||||
this.randomInterval = reciprocalChance;
|
||||
this.setFlags(EnumSet.of(Goal.Flag.TARGET));
|
||||
this.targetConditions = (new TargetingConditions()).range(this.getFollowDistance()).selector(targetPredicate);
|
||||
this.targetConditions = TargetingConditions.forCombat().range(this.getFollowDistance()).selector(targetPredicate);
|
||||
+ if (mob.level.paperConfig.entitiesTargetWithFollowRange) this.targetConditions.useFollowRange(); // Paper
|
||||
}
|
||||
|
||||
|
@ -34,24 +35,15 @@ diff --git a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingCond
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
|
||||
@@ -0,0 +0,0 @@ import java.util.function.Predicate;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
+import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
+import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
|
||||
public class TargetingConditions {
|
||||
|
||||
@@ -0,0 +0,0 @@ public class TargetingConditions {
|
||||
|
||||
if (this.range > 0.0D) {
|
||||
double d0 = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D;
|
||||
- double d1 = Math.max(this.range * d0, 2.0D);
|
||||
+ double d1 = Math.max((useFollowRange ? getFollowRange(baseEntity) : this.range) * d0, 2.0D); // Paper
|
||||
double d2 = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ());
|
||||
|
||||
if (d2 > d1 * d1) {
|
||||
double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D;
|
||||
- double e = Math.max(this.range * d, 2.0D);
|
||||
+ double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0D); // Paper
|
||||
double f = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ());
|
||||
if (f > e * e) {
|
||||
return false;
|
||||
@@ -0,0 +0,0 @@ public class TargetingConditions {
|
||||
return true;
|
||||
}
|
||||
|
@ -66,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ private double getFollowRange(LivingEntity entityliving) {
|
||||
+ AttributeInstance attributeinstance = entityliving.getAttribute(Attributes.FOLLOW_RANGE);
|
||||
+ net.minecraft.world.entity.ai.attributes.AttributeInstance attributeinstance = entityliving.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.FOLLOW_RANGE);
|
||||
+ return attributeinstance == null ? 16.0D : attributeinstance.getValue();
|
||||
+ }
|
||||
+ // Paper end
|
|
@ -16,9 +16,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
pair("gamerules", toObjectMapper(world.getWorld().getGameRules(), rule -> {
|
||||
return pair(rule, world.getWorld().getGameRuleValue(rule));
|
||||
})),
|
||||
- pair("ticking-distance", world.getChunkProvider().playerChunkMap.getEffectiveViewDistance())
|
||||
+ pair("ticking-distance", world.getChunkProvider().playerChunkMap.getEffectiveViewDistance()),
|
||||
+ pair("notick-viewdistance", world.getChunkProvider().playerChunkMap.getEffectiveNoTickViewDistance())
|
||||
- pair("ticking-distance", world.getChunkSource().chunkMap.getEffectiveViewDistance())
|
||||
+ pair("ticking-distance", world.getChunkSource().chunkMap.getEffectiveViewDistance()),
|
||||
+ pair("notick-viewdistance", world.getChunkSource().chunkMap.getEffectiveNoTickViewDistance())
|
||||
));
|
||||
}));
|
||||
|
||||
|
@ -27,8 +27,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
|
||||
phantomIgnoreCreative = getBoolean("phantoms-do-not-spawn-on-creative-players", phantomIgnoreCreative);
|
||||
phantomOnlyAttackInsomniacs = getBoolean("phantoms-only-attack-insomniacs", phantomOnlyAttackInsomniacs);
|
||||
private void lightQueueSize() {
|
||||
lightQueueSize = getInt("light-queue-size", lightQueueSize);
|
||||
}
|
||||
+
|
||||
+ public int noTickViewDistance;
|
||||
|
@ -36,6 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ this.noTickViewDistance = this.getInt("viewdistances.no-tick-view-distance", -1);
|
||||
+ }
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MCUtil.java
|
||||
|
@ -55,9 +56,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkHolder {
|
||||
}
|
||||
// Paper end - optimise isOutsideOfRange
|
||||
|
||||
boolean isUpdateQueued = false; // Paper
|
||||
private final ChunkMap chunkMap; // Paper
|
||||
+ // Paper start - no-tick view distance
|
||||
+ public final LevelChunk getSendingChunk() {
|
||||
+ // it's important that we use getChunkAtIfLoadedImmediately to mirror the chunk sending logic used
|
||||
|
@ -69,23 +70,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return null;
|
||||
+ }
|
||||
+ // Paper end - no-tick view distance
|
||||
+
|
||||
public ChunkHolder(ChunkPos pos, int level, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
|
||||
|
||||
public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
|
||||
this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
|
||||
this.fullChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
|
||||
@@ -0,0 +0,0 @@ public class ChunkHolder {
|
||||
}
|
||||
|
||||
public void blockChanged(BlockPos blockposition) {
|
||||
public void blockChanged(BlockPos pos) {
|
||||
- LevelChunk chunk = this.getTickingChunk();
|
||||
+ LevelChunk chunk = this.getSendingChunk(); // Paper - no-tick view distance
|
||||
|
||||
if (chunk != null) {
|
||||
byte b0 = (byte) SectionPos.blockToSectionCoord(blockposition.getY());
|
||||
int i = this.levelHeightAccessor.getSectionIndex(pos.getY());
|
||||
@@ -0,0 +0,0 @@ public class ChunkHolder {
|
||||
}
|
||||
|
||||
public void sectionLightChanged(LightLayer type, int y) {
|
||||
public void sectionLightChanged(LightLayer lightType, int y) {
|
||||
- LevelChunk chunk = this.getTickingChunk();
|
||||
+ LevelChunk chunk = this.getSendingChunk(); // Paper - no-tick view distance
|
||||
|
||||
|
@ -94,7 +94,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public class ChunkHolder {
|
||||
}
|
||||
|
||||
private void broadcast(Packet<?> packet, boolean onlyOnWatchDistanceEdge) {
|
||||
public void broadcast(Packet<?> packet, boolean onlyOnWatchDistanceEdge) { // Paper - private -> public
|
||||
- this.playerProvider.getPlayers(this.pos, onlyOnWatchDistanceEdge).forEach((entityplayer) -> {
|
||||
- entityplayer.connection.send(packet);
|
||||
- });
|
||||
|
@ -119,8 +119,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ int viewDistance = viewDistanceMap.getLastViewDistance(player);
|
||||
+ long lastPosition = viewDistanceMap.getLastCoordinate(player);
|
||||
+
|
||||
+ int distX = Math.abs(MCUtil.getCoordinateX(lastPosition) - this.pos.x);
|
||||
+ int distZ = Math.abs(MCUtil.getCoordinateZ(lastPosition) - this.pos.z);
|
||||
+ int distX = Math.abs(net.minecraft.server.MCUtil.getCoordinateX(lastPosition) - this.pos.x);
|
||||
+ int distZ = Math.abs(net.minecraft.server.MCUtil.getCoordinateZ(lastPosition) - this.pos.z);
|
||||
+
|
||||
+ if (Math.max(distX, distZ) == viewDistance) {
|
||||
+ player.connection.send(packet);
|
||||
|
@ -147,40 +147,19 @@ diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/j
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetChunkCacheCenterPacket;
|
||||
+import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
|
||||
import net.minecraft.network.protocol.game.DebugPackets;
|
||||
import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
+import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.util.CsvOutput;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
private boolean modified;
|
||||
private final ChunkTaskPriorityQueueSorter queueSorter;
|
||||
private final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> worldgenMailbox;
|
||||
- private final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> mainThreadMailbox;
|
||||
+ public final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> mainThreadMailbox; // Paper - private -> public
|
||||
+ // Paper start
|
||||
+ final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> mailboxLight;
|
||||
+ public void addLightTask(ChunkHolder playerchunk, Runnable run) {
|
||||
+ this.mailboxLight.tell(ChunkTaskPriorityQueueSorter.message(playerchunk, run));
|
||||
+ }
|
||||
+ // Paper end
|
||||
public final ChunkProgressListener progressListener;
|
||||
public final ChunkMap.ChunkDistanceManager distanceManager; public final DistanceManager getChunkDistanceManager() { return this.distanceManager; } // Paper - OBFHELPER
|
||||
private final AtomicInteger tickingGenerated;
|
||||
// Paper start
|
||||
final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> mailboxLight;
|
||||
public void addLightTask(ChunkHolder playerchunk, Runnable run) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick
|
||||
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap;
|
||||
// Paper end - optimise PlayerChunkMap#isOutsideRange
|
||||
|
||||
// Paper start - distance maps
|
||||
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
|
||||
+ // Paper start - no-tick view distance
|
||||
+ int noTickViewDistance;
|
||||
+ public final int getRawNoTickViewDistance() {
|
||||
|
@ -200,15 +179,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
void addPlayerToDistanceMaps(ServerPlayer player) {
|
||||
int chunkX = MCUtil.getChunkCoordinate(player.getX());
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// Paper start - optimise PlayerChunkMap#isOutsideRange
|
||||
this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE);
|
||||
// Paper end - optimise PlayerChunkMap#isOutsideRange
|
||||
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
|
||||
// Note: players need to be explicitly added to distance maps before they can be updated
|
||||
+ // Paper start - no-tick view distance
|
||||
+ int effectiveTickViewDistance = this.getEffectiveViewDistance();
|
||||
+ int effectiveNoTickViewDistance = Math.max(this.getEffectiveNoTickViewDistance(), effectiveTickViewDistance);
|
||||
+
|
||||
+ if (!this.cannotLoadChunks(player)) {
|
||||
+ if (!this.skipPlayer(player)) {
|
||||
+ this.playerViewDistanceTickMap.add(player, chunkX, chunkZ, effectiveTickViewDistance);
|
||||
+ this.playerViewDistanceNoTickMap.add(player, chunkX, chunkZ, effectiveNoTickViewDistance + 2); // clients need chunk 1 neighbour, and we need another 1 for sending those extra neighbours (as we require neighbours to send)
|
||||
+ }
|
||||
|
@ -220,10 +197,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
void removePlayerFromDistanceMaps(ServerPlayer player) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.playerMobSpawnMap.remove(player);
|
||||
this.playerChunkTickRangeMap.remove(player);
|
||||
// Paper end - optimise PlayerChunkMap#isOutsideRange
|
||||
|
||||
+ // Paper start - no-tick view distance
|
||||
+ this.playerViewDistanceBroadcastMap.remove(player);
|
||||
+ this.playerViewDistanceTickMap.remove(player);
|
||||
|
@ -232,15 +206,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
void updateMaps(ServerPlayer player) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// Paper start - optimise PlayerChunkMap#isOutsideRange
|
||||
this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE);
|
||||
// Paper end - optimise PlayerChunkMap#isOutsideRange
|
||||
int chunkX = MCUtil.getChunkCoordinate(player.getX());
|
||||
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
|
||||
// Note: players need to be explicitly added to distance maps before they can be updated
|
||||
+ // Paper start - no-tick view distance
|
||||
+ int effectiveTickViewDistance = this.getEffectiveViewDistance();
|
||||
+ int effectiveNoTickViewDistance = Math.max(this.getEffectiveNoTickViewDistance(), effectiveTickViewDistance);
|
||||
+
|
||||
+ if (!this.cannotLoadChunks(player)) {
|
||||
+ if (!this.skipPlayer(player)) {
|
||||
+ this.playerViewDistanceTickMap.update(player, chunkX, chunkZ, effectiveTickViewDistance);
|
||||
+ this.playerViewDistanceNoTickMap.update(player, chunkX, chunkZ, effectiveNoTickViewDistance + 2); // clients need chunk 1 neighbour, and we need another 1 for sending those extra neighbours (as we require neighbours to send)
|
||||
+ }
|
||||
|
@ -253,9 +226,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
// Paper end
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
});
|
||||
// Paper end - optimise PlayerChunkMap#isOutsideRange
|
||||
this.overworldDataStorage = persistentStateManagerFactory;
|
||||
this.poiManager = new PoiManager(new File(this.storageFolder, "poi"), dataFixer, dsync, world);
|
||||
this.setViewDistance(viewDistance);
|
||||
+ // Paper start - no-tick view distance
|
||||
+ this.setNoTickViewDistance(this.level.paperConfig.noTickViewDistance);
|
||||
+ this.playerViewDistanceTickMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets,
|
||||
|
@ -297,10 +270,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end - no-tick view distance
|
||||
}
|
||||
|
||||
public void updatePlayerMobTypeMap(Entity entity) {
|
||||
private static double euclideanDistanceSquared(ChunkPos pos, Entity entity) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
completablefuture1.thenAcceptAsync((either) -> {
|
||||
either.mapLeft((chunk) -> {
|
||||
either.ifLeft((chunk) -> {
|
||||
this.tickingGenerated.getAndIncrement();
|
||||
- Packet<?>[] apacket = new Packet[2];
|
||||
-
|
||||
|
@ -308,7 +281,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- this.playerLoadedChunk(entityplayer, apacket, chunk);
|
||||
- });
|
||||
+ // Paper - no-tick view distance - moved to Chunk neighbour update
|
||||
return Either.left(chunk);
|
||||
});
|
||||
}, (runnable) -> {
|
||||
- this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable));
|
||||
|
@ -341,7 +313,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
|
||||
- this.getPlayers(chunkcoordintpair, false).forEach((entityplayer) -> {
|
||||
- int l = checkerboardDistance(chunkcoordintpair, entityplayer, true);
|
||||
- int l = ChunkMap.checkerboardDistance(chunkcoordintpair, entityplayer, true);
|
||||
- boolean flag = l <= k;
|
||||
- boolean flag1 = l <= this.viewDistance;
|
||||
+ // Paper start - no-tick view distance
|
||||
|
@ -356,20 +328,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
+ if (this.level != null && this.level.players != null) { // this can be called from constructor, where these aren't set
|
||||
+ for (ServerPlayer player : this.level.players) {
|
||||
+ ServerGamePacketListenerImpl connection = player.connection;
|
||||
+ net.minecraft.server.network.ServerGamePacketListenerImpl connection = player.connection;
|
||||
+ if (connection != null) {
|
||||
+ // moved in from PlayerList
|
||||
+ connection.send(new ClientboundSetChunkCacheRadiusPacket(loadViewDistance));
|
||||
+ connection.send(new net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket(loadViewDistance));
|
||||
+ }
|
||||
+ this.updateMaps(player);
|
||||
+ // Paper end - no-tick view distance
|
||||
}
|
||||
}
|
||||
-
|
||||
}
|
||||
+ // Paper end - no-tick view distance
|
||||
|
||||
protected void updateChunkTracking(ServerPlayer player, ChunkPos pos, Packet<?>[] packets, boolean withinMaxWatchDistance, boolean withinViewDistance) {
|
||||
if (player.level == this.level) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos.toLong());
|
||||
|
||||
|
@ -379,14 +347,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
if (chunk != null) {
|
||||
this.playerLoadedChunk(player, packets, chunk);
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
// Paper end - optimise isOutsideOfRange
|
||||
|
||||
+ private boolean cannotLoadChunks(ServerPlayer entityplayer) { return this.skipPlayer(entityplayer); } // Paper - OBFHELPER
|
||||
private boolean skipPlayer(ServerPlayer player) {
|
||||
return player.isSpectator() && !this.level.getGameRules().getBoolean(GameRules.RULE_SPECTATORSGENERATECHUNKS);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.removePlayerFromDistanceMaps(player); // Paper - distance maps
|
||||
}
|
||||
|
@ -403,11 +363,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
SectionPos sectionposition = SectionPos.of((Entity) entityplayer);
|
||||
SectionPos sectionposition = SectionPos.of((Entity) player);
|
||||
|
||||
entityplayer.setLastSectionPos(sectionposition);
|
||||
- entityplayer.connection.send(new ClientboundSetChunkCacheCenterPacket(sectionposition.x(), sectionposition.z()));
|
||||
+ // Paper - distance map handles this now
|
||||
player.setLastSectionPos(sectionposition);
|
||||
- player.connection.send(new ClientboundSetChunkCacheCenterPacket(sectionposition.x(), sectionposition.z()));
|
||||
+ // player.connection.send(new ClientboundSetChunkCacheCenterPacket(sectionposition.x(), sectionposition.z())); // Paper - distance map handles this now
|
||||
return sectionposition;
|
||||
}
|
||||
|
||||
|
@ -420,49 +380,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
k1 = Math.min(i, i1) - this.viewDistance;
|
||||
l1 = Math.min(j, j1) - this.viewDistance;
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
for (int k2 = k1; k2 <= i2; ++k2) {
|
||||
for (int l2 = l1; l2 <= j2; ++l2) {
|
||||
- ChunkPos chunkcoordintpair = new ChunkPos(k2, l2);
|
||||
- boolean flag3 = checkerboardDistance(chunkcoordintpair, i1, j1) <= this.viewDistance;
|
||||
- boolean flag4 = checkerboardDistance(chunkcoordintpair, i, j) <= this.viewDistance;
|
||||
+ ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(k2, l2);
|
||||
+ boolean flag3 = a(chunkcoordintpair, i1, j1) <= this.viewDistance;
|
||||
+ boolean flag4 = a(chunkcoordintpair, i, j) <= this.viewDistance;
|
||||
|
||||
- this.updateChunkTracking(player, chunkcoordintpair, new Packet[2], flag3, flag4);
|
||||
+ this.sendChunk(entityplayer, chunkcoordintpair, new Packet[2], flag3, flag4);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- ChunkPos chunkcoordintpair1;
|
||||
+ ChunkCoordIntPair chunkcoordintpair1;
|
||||
boolean flag5;
|
||||
boolean flag6;
|
||||
|
||||
for (k1 = i1 - this.viewDistance; k1 <= i1 + this.viewDistance; ++k1) {
|
||||
for (l1 = j1 - this.viewDistance; l1 <= j1 + this.viewDistance; ++l1) {
|
||||
- chunkcoordintpair1 = new ChunkPos(k1, l1);
|
||||
+ chunkcoordintpair1 = new ChunkCoordIntPair(k1, l1);
|
||||
flag5 = true;
|
||||
flag6 = false;
|
||||
- this.updateChunkTracking(player, chunkcoordintpair1, new Packet[2], true, false);
|
||||
+ this.sendChunk(entityplayer, chunkcoordintpair1, new Packet[2], true, false);
|
||||
}
|
||||
}
|
||||
|
||||
for (k1 = i - this.viewDistance; k1 <= i + this.viewDistance; ++k1) {
|
||||
for (l1 = j - this.viewDistance; l1 <= j + this.viewDistance; ++l1) {
|
||||
- chunkcoordintpair1 = new ChunkPos(k1, l1);
|
||||
+ chunkcoordintpair1 = new ChunkCoordIntPair(k1, l1);
|
||||
flag5 = false;
|
||||
flag6 = true;
|
||||
- this.updateChunkTracking(player, chunkcoordintpair1, new Packet[2], false, true);
|
||||
+ this.sendChunk(entityplayer, chunkcoordintpair1, new Packet[2], false, true);
|
||||
}
|
||||
}
|
||||
- }
|
||||
+ }*/ // Paper end - replaced by distance map
|
||||
}
|
||||
+ */ // Paper end - replaced by distance map
|
||||
|
||||
this.updateMaps(player); // Paper - distance maps
|
||||
|
||||
|
@ -470,14 +391,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
@Override
|
||||
public Stream<ServerPlayer> getPlayers(ChunkPos chunkPos, boolean onlyOnWatchDistanceEdge) {
|
||||
- return this.playerMap.a(chunkPos.toLong()).filter((entityplayer) -> {
|
||||
- int i = b(chunkcoordintpair, entityplayer, true);
|
||||
- return this.playerMap.getPlayers(chunkPos.toLong()).filter((entityplayer) -> {
|
||||
- int i = ChunkMap.checkerboardDistance(chunkPos, entityplayer, true);
|
||||
+ // Paper start - per player view distance
|
||||
+ // there can be potential desync with player's last mapped section and the view distance map, so use the
|
||||
+ // view distance map here.
|
||||
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> inRange = this.playerViewDistanceBroadcastMap.getObjectsInRange(chunkPos);
|
||||
|
||||
- return i > this.viewDistance ? false : !flag || i == this.viewDistance;
|
||||
- return i > this.viewDistance ? false : !onlyOnWatchDistanceEdge || i == this.viewDistance;
|
||||
- });
|
||||
+ if (inRange == null) {
|
||||
+ return Stream.empty();
|
||||
|
@ -516,15 +437,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end - per player view distance
|
||||
}
|
||||
|
||||
public void addEntity(Entity entity) { // Paper - protected -> public
|
||||
protected void addEntity(Entity entity) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
}
|
||||
|
||||
- private final void sendChunk(ServerPlayer entityplayer, Packet<?>[] apacket, LevelChunk chunk) { this.playerLoadedChunk(entityplayer, apacket, chunk); } // Paper - OBFHELPER
|
||||
- private void playerLoadedChunk(ServerPlayer player, Packet<?>[] packets, LevelChunk chunk) {
|
||||
+ // Paper start
|
||||
+ private static int getLightMask(final LevelChunk chunk) {
|
||||
+ final ChunkSection[] chunkSections = chunk.getSections();
|
||||
+ final net.minecraft.world.level.chunk.LevelChunkSection[] chunkSections = chunk.getSections();
|
||||
+ int mask = 0;
|
||||
+
|
||||
+ for (int i = 0; i < chunkSections.length; ++i) {
|
||||
|
@ -535,7 +456,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+Sections go from 0..16. Now whenever a section is not empty, it can potentially change lighting for the section itself, the section below and the section above, hence the bitmask 111b, which is 7d.
|
||||
+
|
||||
+ */
|
||||
+ mask |= (ChunkSection.isEmpty(chunkSections[i]) ? 0 : 7) << i;
|
||||
+ mask |= (net.minecraft.world.level.chunk.LevelChunkSection.isEmpty(chunkSections[i]) ? 0 : 7) << i;
|
||||
+ }
|
||||
+
|
||||
+ return mask;
|
||||
|
@ -563,19 +484,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ public final void sendChunk(ServerPlayer entityplayer, Packet<?>[] apacket, LevelChunk chunk) { this.playerLoadedChunk(entityplayer, apacket, chunk); } // Paper - OBFHELPER
|
||||
private void playerLoadedChunk(ServerPlayer player, Packet<?>[] packets, LevelChunk chunk) {
|
||||
+ public void playerLoadedChunk(ServerPlayer player, Packet<?>[] packets, LevelChunk chunk) { // Paper - private -> public
|
||||
if (packets[0] == null) {
|
||||
packets[0] = new ClientboundLevelChunkPacket(chunk, 65535, chunk.world.chunkPacketBlockController.shouldModify(player, chunk, 65535)); // Paper - Anti-Xray - Bypass
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
ChunkPos chunkcoordintpair = new ChunkPos(this.entity.xChunk, this.entity.zChunk);
|
||||
ChunkHolder playerchunk = ChunkMap.this.getVisibleChunkIfPresent(chunkcoordintpair.toLong());
|
||||
|
||||
- if (playerchunk != null && playerchunk.getTickingChunk() != null) {
|
||||
+ if (playerchunk != null && playerchunk.getSendingChunk() != null) { // Paper - no-tick view distance
|
||||
flag1 = ChunkMap.checkerboardDistance(chunkcoordintpair, player, false) <= ChunkMap.this.viewDistance;
|
||||
}
|
||||
}
|
||||
packets[0] = new ClientboundLevelChunkPacket(chunk);
|
||||
packets[1] = new ClientboundLightUpdatePacket(chunk.getPos(), this.lightEngine, (BitSet) null, (BitSet) null, true);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
|
||||
|
@ -604,15 +516,14 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
|
||||
double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
|
||||
|
||||
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
|
||||
+ boolean needsChunkCenterUpdate; // Paper - no-tick view distance
|
||||
+
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ServerPlayerGameMode interactionManager) {
|
||||
super(world, world.getSpawn(), world.getSharedSpawnAngle(), profile);
|
||||
this.respawnDimension = Level.OVERWORLD;
|
||||
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) {
|
||||
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
|
@ -633,8 +544,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.spigotConfig.viewDistance)); // Spigot
|
||||
+ entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.getChunkSource().chunkMap.getLoadViewDistance())); // Spigot // Paper - no-tick view distance
|
||||
entityplayer1.setLevel(worldserver1);
|
||||
entityplayer1.removed = false;
|
||||
entityplayer1.connection.teleport(new Location(worldserver1.getWorld(), entityplayer1.getX(), entityplayer1.getY(), entityplayer1.getZ(), entityplayer1.yRot, entityplayer1.xRot));
|
||||
entityplayer1.unsetRemoved();
|
||||
entityplayer1.connection.teleport(new Location(worldserver1.getWorld(), entityplayer1.getX(), entityplayer1.getY(), entityplayer1.getZ(), entityplayer1.getYRot(), entityplayer1.getXRot()));
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
|
||||
public void setViewDistance(int viewDistance) {
|
||||
|
@ -667,27 +578,23 @@ diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
+import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
+import net.minecraft.server.level.ChunkMap;
|
||||
+import net.minecraft.server.level.ChunkTaskPriorityQueueSorter;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
|
||||
}
|
||||
|
||||
protected void onNeighbourChange(final long bitsetBefore, final long bitsetAfter) {
|
||||
+ // Paper start - no-tick view distance
|
||||
+ ServerChunkCache chunkProviderServer = ((ServerLevel)this.world).getChunkSource();
|
||||
+ ServerChunkCache chunkProviderServer = ((ServerLevel)this.level).getChunkSource();
|
||||
+ ChunkMap chunkMap = chunkProviderServer.chunkMap;
|
||||
+ // this code handles the addition of ticking tickets - the distance map handles the removal
|
||||
+ if (!areNeighboursLoaded(bitsetBefore, 2) && areNeighboursLoaded(bitsetAfter, 2)) {
|
||||
|
@ -696,7 +603,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ chunkProviderServer.mainThreadProcessor.execute(() -> {
|
||||
+ // double check that this condition still holds.
|
||||
+ if (LevelChunk.this.areNeighboursLoaded(2) && chunkMap.playerViewDistanceTickMap.getObjectsInRange(LevelChunk.this.coordinateKey) != null) {
|
||||
+ chunkProviderServer.addTicketAtLevel(TicketType.PLAYER, LevelChunk.this.chunkPos, 31, LevelChunk.this.chunkPos); // 31 -> entity ticking, TODO check on update
|
||||
+ chunkProviderServer.addTicketAtLevel(net.minecraft.server.level.TicketType.PLAYER, LevelChunk.this.chunkPos, 31, LevelChunk.this.chunkPos); // 31 -> entity ticking, TODO check on update
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
|
@ -711,7 +618,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if (!LevelChunk.this.areNeighboursLoaded(1)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> inRange = chunkMap.playerViewDistanceBroadcastMap.getObjectsInRange(LevelChunk.this.coordinateKey);
|
||||
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<net.minecraft.server.level.ServerPlayer> inRange = chunkMap.playerViewDistanceBroadcastMap.getObjectsInRange(LevelChunk.this.coordinateKey);
|
||||
+ if (inRange == null) {
|
||||
+ return;
|
||||
+ }
|
||||
|
@ -721,11 +628,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ Packet[] chunkPackets = new Packet[2];
|
||||
+ for (int index = 0, len = backingSet.length; index < len; ++index) {
|
||||
+ Object temp = backingSet[index];
|
||||
+ if (!(temp instanceof ServerPlayer)) {
|
||||
+ if (!(temp instanceof net.minecraft.server.level.ServerPlayer)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ ServerPlayer player = (ServerPlayer)temp;
|
||||
+ chunkMap.sendChunk(player, chunkPackets, LevelChunk.this);
|
||||
+ net.minecraft.server.level.ServerPlayer player = (net.minecraft.server.level.ServerPlayer)temp;
|
||||
+ chunkMap.playerLoadedChunk(player, chunkPackets, LevelChunk.this);
|
||||
+ }
|
||||
+ })));
|
||||
+ }
|
||||
|
@ -736,10 +643,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public final boolean isAnyNeighborsLoaded() {
|
||||
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
|
||||
BlockState iblockdata = this.getBlockState(blockposition);
|
||||
BlockState iblockdata1 = Block.updateFromNeighbourShapes(iblockdata, (LevelAccessor) this.world, blockposition);
|
||||
BlockState iblockdata1 = Block.updateFromNeighbourShapes(iblockdata, (LevelAccessor) this.level, blockposition);
|
||||
|
||||
- this.world.setBlock(blockposition, iblockdata1, 20);
|
||||
+ this.world.setBlock(blockposition, iblockdata1, 20 | 2); // Paper - We send chunks before they're ticking ready, so we need to notify here
|
||||
- this.level.setBlock(blockposition, iblockdata1, 20);
|
||||
+ this.level.setBlock(blockposition, iblockdata1, 20 | 2); // Paper - We send chunks before they're ticking ready, so we need to notify here
|
||||
}
|
||||
|
||||
this.postProcessing[i].clear();
|
||||
|
@ -747,14 +654,6 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/jav
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.network.protocol.game.ClientboundLevelEventPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetTimePacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
+import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.Ticket;
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
|
||||
// Spigot start
|
||||
@Override
|
||||
|
@ -770,7 +669,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if (viewDistance < 2 || viewDistance > 32) {
|
||||
+ throw new IllegalArgumentException("View distance " + viewDistance + " is out of range of [2, 32]");
|
||||
+ }
|
||||
+ ChunkMap chunkMap = getHandle().getChunkSource().chunkMap;
|
||||
+ net.minecraft.server.level.ChunkMap chunkMap = getHandle().getChunkSource().chunkMap;
|
||||
+ if (viewDistance != chunkMap.getEffectiveViewDistance()) {
|
||||
+ chunkMap.setViewDistance(viewDistance);
|
||||
+ }
|
||||
|
@ -786,7 +685,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if ((viewDistance < 2 || viewDistance > 32) && viewDistance != -1) {
|
||||
+ throw new IllegalArgumentException("View distance " + viewDistance + " is out of range of [2, 32]");
|
||||
+ }
|
||||
+ ChunkMap chunkMap = getHandle().getChunkSource().chunkMap;
|
||||
+ net.minecraft.server.level.ChunkMap chunkMap = getHandle().getChunkSource().chunkMap;
|
||||
+ if (viewDistance != chunkMap.getRawNoTickViewDistance()) {
|
||||
+ chunkMap.setNoTickViewDistance(viewDistance);
|
||||
+ }
|
||||
|
@ -800,20 +699,12 @@ diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
||||
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
@@ -0,0 +0,0 @@ import java.util.Collection;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.FlyingMob;
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
maxRange = Math.max( maxRange, waterActivationRange );
|
||||
maxRange = Math.max( maxRange, villagerActivationRange );
|
||||
// Paper end
|
||||
- maxRange = Math.min( ( world.spigotConfig.viewDistance << 4 ) - 8, maxRange );
|
||||
+ maxRange = Math.min( ( ((ServerLevel)world).getChunkSource().chunkMap.getEffectiveViewDistance() << 4 ) - 8, maxRange ); // Paper - no-tick view distance
|
||||
+ maxRange = Math.min( ( ((net.minecraft.server.level.ServerLevel)world).getChunkSource().chunkMap.getEffectiveViewDistance() << 4 ) - 8, maxRange ); // Paper - no-tick view distance
|
||||
|
||||
for ( Player player : world.players() )
|
||||
{
|
|
@ -10,35 +10,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
}
|
||||
public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager;
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - optimise getPlayerByUUID
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public Player getPlayerByUUID(UUID uuid) {
|
||||
+ Entity player = this.entitiesByUuid.get(uuid);
|
||||
+ return (player instanceof Player) ? (Player)player : null;
|
||||
+ return this.getServer().getPlayerList().getPlayer(uuid);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
// Add env and gen to constructor, WorldData -> WorldDataServer
|
||||
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, ServerLevelData iworlddataserver, ResourceKey<net.minecraft.world.level.Level> resourcekey, DimensionType dimensionmanager, ChunkProgressListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<CustomSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
super(iworlddataserver, resourcekey, dimensionmanager, minecraftserver::getProfiler, false, flag, i, gen, env, executor); // Paper pass executor
|
||||
diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
@@ -0,0 +0,0 @@ public interface EntityGetter {
|
||||
|
||||
@Nullable
|
||||
default Player getPlayerByUUID(UUID uuid) {
|
||||
+ // Paper start - allow WorldServer to override
|
||||
+ return this.getPlayerByUUID(uuid);
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ default Player getPlayerByUUID(UUID uuid) {
|
||||
+ // Paper end
|
||||
for (int i = 0; i < this.players().size(); ++i) {
|
||||
Player entityhuman = (Player) this.players().get(i);
|
||||
|
||||
// Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error
|
|
@ -30,23 +30,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled"));
|
||||
+ }
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.LevelSettings;
|
||||
import net.minecraft.world.level.biome.BiomeManager;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
+import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraft.world.level.border.WorldBorder;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
while (iterator.hasNext()) {
|
||||
ServerLevel worldserver = (ServerLevel) iterator.next();
|
||||
worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
|
||||
+ HopperBlockEntity.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
|
||||
+ net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
|
||||
|
||||
this.profiler.push(() -> {
|
||||
return worldserver + " " + worldserver.dimension().location();
|
||||
|
@ -70,28 +63,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
itemstack.setPopTime(this.getPopTime());
|
||||
if (this.tag != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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 {
|
||||
return list;
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public <T extends Entity> List<T> getEntitiesOfClass(Class<? extends T> entityClass, AABB box, @Nullable Predicate<? super T> predicate) {
|
||||
+ public <T extends Entity> List<T> getEntities(Class<? extends T> oclass, AABB axisalignedbb, @Nullable Predicate<? super T> predicate) { return getEntitiesOfClass(oclass, axisalignedbb, predicate); } // Paper - OBFHELPER
|
||||
+ @Override public <T extends Entity> List<T> getEntitiesOfClass(Class<? extends T> entityClass, AABB box, @Nullable Predicate<? super T> predicate) {
|
||||
this.getProfiler().incrementCounter("getEntities");
|
||||
int i = Mth.floor((box.minX - 2.0D) / 16.0D);
|
||||
int j = Mth.ceil((box.maxX + 2.0D) / 16.0D);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject {
|
||||
public void setCurrentChunk(LevelChunk chunk) {
|
||||
this.currentChunk = chunk != null ? new java.lang.ref.WeakReference<>(chunk) : null;
|
||||
getMinecraftKey(); // Try to load if it doesn't exists.
|
||||
return tileEntityKeyString;
|
||||
}
|
||||
+ static boolean IGNORE_TILE_UPDATES = false;
|
||||
// Paper end
|
||||
|
@ -102,57 +80,58 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public void setChanged() {
|
||||
if (this.level != null) {
|
||||
+ if (IGNORE_TILE_UPDATES) return; // Paper
|
||||
this.blockState = this.level.getBlockState(this.worldPosition);
|
||||
this.level.blockEntityChanged(this.worldPosition, this);
|
||||
if (!this.blockState.isAir()) {
|
||||
BlockEntity.setChanged(this.level, this.worldPosition, this.blockState);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/Hopper.java b/src/main/java/net/minecraft/world/level/block/entity/Hopper.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/Hopper.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/Hopper.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package net.minecraft.world.level.block.entity;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -0,0 +0,0 @@ public interface Hopper extends Container {
|
||||
return Hopper.SUCK;
|
||||
return SUCK;
|
||||
}
|
||||
|
||||
- @Nullable
|
||||
+ //@Nullable // Paper - it's annoying
|
||||
Level getLevel();
|
||||
+ default BlockPos getBlockPosition() { return new BlockPos(getX(), getY(), getZ()); } // Paper
|
||||
+ net.minecraft.world.level.Level getLevel();
|
||||
+
|
||||
+ default net.minecraft.core.BlockPos getBlockPosition() { return new net.minecraft.core.BlockPos(getLevelX(), getLevelY(), getLevelZ()); } // Paper
|
||||
+
|
||||
double getLevelX();
|
||||
|
||||
- double getLevelX();
|
||||
+ double getLevelX(); default double getX() { return this.getLevelX(); } // Paper - OBFHELPER
|
||||
|
||||
- double getLevelY();
|
||||
+ double getLevelY(); default double getY() { return this.getLevelY(); } // Paper - OBFHELPER
|
||||
|
||||
- double getLevelZ();
|
||||
+ double getLevelZ(); default double getZ() { return this.getLevelZ(); } // Paper - OBFHELPER
|
||||
}
|
||||
double getLevelY();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ package net.minecraft.world.level.block.entity;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.BooleanSupplier;
|
||||
-import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.shapes.BooleanOp;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
-import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
+ // Paper start - Optimize Hoppers
|
||||
+ private static boolean skipPullModeEventFire = false;
|
||||
+ private static boolean skipPushModeEventFire = false;
|
||||
+ public static boolean skipHopperEvents = false;
|
||||
+
|
||||
+ private boolean hopperPush(Container iinventory, Direction enumdirection) {
|
||||
+ private static boolean hopperPush(Level level, BlockPos pos, Container iinventory, Direction enumdirection, HopperBlockEntity hopper) {
|
||||
+ skipPushModeEventFire = skipHopperEvents;
|
||||
+ boolean foundItem = false;
|
||||
+ for (int i = 0; i < this.getContainerSize(); ++i) {
|
||||
+ ItemStack item = this.getItem(i);
|
||||
+ for (int i = 0; i < iinventory.getContainerSize(); ++i) {
|
||||
+ ItemStack item = iinventory.getItem(i);
|
||||
+ if (!item.isEmpty()) {
|
||||
+ foundItem = true;
|
||||
+ ItemStack origItemStack = item;
|
||||
|
@ -165,13 +144,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // We only need to fire the event once to give protection plugins a chance to cancel this event
|
||||
+ // Because nothing uses getItem, every event call should end up the same result.
|
||||
+ if (!skipPushModeEventFire) {
|
||||
+ itemstack = callPushMoveEvent(iinventory, itemstack);
|
||||
+ itemstack = callPushMoveEvent(iinventory, itemstack, hopper);
|
||||
+ if (itemstack == null) { // cancelled
|
||||
+ origItemStack.setCount(origCount);
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ final ItemStack itemstack2 = addItem(this, iinventory, itemstack, enumdirection);
|
||||
+ final ItemStack itemstack2 = addItem(hopper, iinventory, itemstack, enumdirection);
|
||||
+ final int remaining = itemstack2.getCount();
|
||||
+ if (remaining != moved) {
|
||||
+ origItemStack = origItemStack.cloneItemStack(true);
|
||||
|
@ -179,7 +158,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if (!origItemStack.isEmpty()) {
|
||||
+ origItemStack.setCount(origCount - moved + remaining);
|
||||
+ }
|
||||
+ this.setItem(i, origItemStack);
|
||||
+ hopper.setItem(i, origItemStack);
|
||||
+ iinventory.setChanged();
|
||||
+ return true;
|
||||
+ }
|
||||
|
@ -187,7 +166,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ }
|
||||
+ if (foundItem && level.paperConfig.cooldownHopperWhenFull) { // Inventory was full - cooldown
|
||||
+ this.setCooldown(level.spigotConfig.hopperTransfer);
|
||||
+ hopper.setCooldown(level.spigotConfig.hopperTransfer);
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
|
@ -233,16 +212,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private ItemStack callPushMoveEvent(Container iinventory, ItemStack itemstack) {
|
||||
+ private static ItemStack callPushMoveEvent(Container iinventory, ItemStack itemstack, HopperBlockEntity hopper) {
|
||||
+ Inventory destinationInventory = getInventory(iinventory);
|
||||
+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner(false).getInventory(),
|
||||
+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(hopper.getOwner(false).getInventory(),
|
||||
+ CraftItemStack.asCraftMirror(itemstack), destinationInventory, true);
|
||||
+ boolean result = event.callEvent();
|
||||
+ if (!event.calledGetItem && !event.calledSetItem) {
|
||||
+ skipPushModeEventFire = true;
|
||||
+ }
|
||||
+ if (!result) {
|
||||
+ cooldownHopper(this);
|
||||
+ cooldownHopper(hopper);
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
|
@ -296,58 +275,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
private boolean ejectItems() {
|
||||
Container iinventory = this.getAttachedContainer();
|
||||
|
||||
private static boolean a(Level world, BlockPos blockposition, BlockState iblockdata, Container iinventory, HopperBlockEntity hopper) { // CraftBukkit
|
||||
Container iinventory1 = HopperBlockEntity.getAttachedContainer(world, blockposition, iblockdata);
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
if (this.isFullContainer(iinventory, enumdirection)) {
|
||||
if (HopperBlockEntity.isFullContainer(iinventory1, enumdirection)) {
|
||||
return false;
|
||||
} else {
|
||||
- for (int i = 0; i < this.getContainerSize(); ++i) {
|
||||
+ return hopperPush(iinventory, enumdirection); /* // Paper - disable rest
|
||||
+ for (int i = 0; i < this.getSize(); ++i) {
|
||||
if (!this.getItem(i).isEmpty()) {
|
||||
- ItemStack itemstack = this.getItem(i).copy();
|
||||
+ ItemStack itemstack = this.getItem(i).cloneItemStack();
|
||||
// ItemStack itemstack1 = addItem(this, iinventory, this.splitStack(i, 1), enumdirection);
|
||||
|
||||
// CraftBukkit start - Call event when pushing items into other inventories
|
||||
- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.removeItem(i, level.spigotConfig.hopperAmount)); // Spigot
|
||||
+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(i, world.spigotConfig.hopperAmount)); // Spigot
|
||||
|
||||
Inventory destinationInventory;
|
||||
// Have to special case large chests as they work oddly
|
||||
- if (iinventory instanceof CompoundContainer) {
|
||||
- destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory);
|
||||
+ if (iinventory instanceof InventoryLargeChest) {
|
||||
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory);
|
||||
} else {
|
||||
destinationInventory = iinventory.getOwner().getInventory();
|
||||
}
|
||||
|
||||
InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true);
|
||||
- this.getLevel().getCraftServer().getPluginManager().callEvent(event);
|
||||
+ this.getWorld().getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
this.setItem(i, itemstack);
|
||||
- this.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
|
||||
+ this.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
|
||||
return false;
|
||||
}
|
||||
int origCount = event.getItem().getAmount(); // Spigot
|
||||
+ return hopperPush(world, blockposition, iinventory, enumdirection, hopper); /* // Paper - disable rest
|
||||
for (int i = 0; i < iinventory.getContainerSize(); ++i) {
|
||||
if (!iinventory.getItem(i).isEmpty()) {
|
||||
ItemStack itemstack = iinventory.getItem(i).copy();
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
// CraftBukkit end
|
||||
|
||||
if (itemstack1.isEmpty()) {
|
||||
- iinventory.setChanged();
|
||||
+ iinventory.update();
|
||||
return true;
|
||||
}
|
||||
|
||||
- itemstack.shrink(origCount - itemstack1.getCount()); // Spigot
|
||||
+ itemstack.subtract(origCount - itemstack1.getCount()); // Spigot
|
||||
this.setItem(i, itemstack);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,12 +296,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
return inventory instanceof WorldlyContainer ? IntStream.of(((WorldlyContainer) inventory).getSlotsForFace(side)) : IntStream.range(0, inventory.getContainerSize());
|
||||
}
|
||||
|
||||
- private boolean isFullContainer(Container inv, Direction enumdirection) {
|
||||
- return getSlots(inv, enumdirection).allMatch((i) -> {
|
||||
- ItemStack itemstack = inv.getItem(i);
|
||||
private static boolean isFullContainer(Container inventory, Direction direction) {
|
||||
- return HopperBlockEntity.getSlots(inventory, direction).allMatch((i) -> {
|
||||
- ItemStack itemstack = inventory.getItem(i);
|
||||
-
|
||||
- return itemstack.getCount() >= itemstack.getMaxStackSize();
|
||||
- });
|
||||
+ return allMatch(inventory, direction, STACK_SIZE_TEST); // Paper - no streams
|
||||
}
|
||||
|
||||
private static boolean isEmptyContainer(Container inv, Direction facing) {
|
||||
- return HopperBlockEntity.getSlots(inv, facing).allMatch((i) -> {
|
||||
- return inv.getItem(i).isEmpty();
|
||||
- });
|
||||
+ // Paper start
|
||||
+ return allMatch(inv, facing, IS_EMPTY_TEST);
|
||||
+ }
|
||||
+ private static boolean allMatch(Container iinventory, Direction enumdirection, java.util.function.BiPredicate<ItemStack, Integer> test) {
|
||||
+ if (iinventory instanceof WorldlyContainer) {
|
||||
+ for (int i : ((WorldlyContainer) iinventory).getSlotsForFace(enumdirection)) {
|
||||
|
@ -379,10 +330,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
}
|
||||
|
||||
- return itemstack.getCount() >= itemstack.getMaxStackSize();
|
||||
- });
|
||||
+ private static boolean anyMatch(Container iinventory, Direction enumdirection, java.util.function.BiPredicate<ItemStack, Integer> test) {
|
||||
+ if (iinventory instanceof WorldlyContainer) {
|
||||
+ for (int i : ((WorldlyContainer) iinventory).getSlotsForFace(enumdirection)) {
|
||||
|
@ -402,106 +351,48 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ private static final java.util.function.BiPredicate<ItemStack, Integer> STACK_SIZE_TEST = (itemstack, i) -> itemstack.getCount() >= itemstack.getMaxStackSize();
|
||||
+ private static final java.util.function.BiPredicate<ItemStack, Integer> IS_EMPTY_TEST = (itemstack, i) -> itemstack.isEmpty();
|
||||
+
|
||||
+ // Paper end
|
||||
+
|
||||
+ private boolean isFullContainer(Container inv, Direction enumdirection) {
|
||||
+ // Paper start - no streams
|
||||
+ return allMatch(inv, enumdirection, STACK_SIZE_TEST);
|
||||
+ // Paper end
|
||||
}
|
||||
public static boolean suckInItems(Level world, Hopper hopper) {
|
||||
Container iinventory = HopperBlockEntity.getSourceContainer(world, hopper);
|
||||
|
||||
private static boolean isEmptyContainer(Container inv, Direction facing) {
|
||||
- return getSlots(inv, facing).allMatch((i) -> {
|
||||
- return inv.getItem(i).isEmpty();
|
||||
- });
|
||||
+ return allMatch(inv, facing, IS_EMPTY_TEST);
|
||||
}
|
||||
|
||||
public static boolean suckInItems(Hopper hopper) {
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
if (iinventory != null) {
|
||||
Direction enumdirection = Direction.DOWN;
|
||||
|
||||
- return isEmptyContainer(iinventory, enumdirection) ? false : getSlots(iinventory, enumdirection).anyMatch((i) -> {
|
||||
- return tryTakeInItemFromSlot(hopper, iinventory, i, enumdirection);
|
||||
- return HopperBlockEntity.isEmptyContainer(iinventory, enumdirection) ? false : HopperBlockEntity.getSlots(iinventory, enumdirection).anyMatch((i) -> {
|
||||
- return HopperBlockEntity.a(hopper, iinventory, i, enumdirection, world); // Spigot
|
||||
+ // Paper start - optimize hoppers and remove streams
|
||||
+ skipPullModeEventFire = skipHopperEvents;
|
||||
+ return !isEmptyContainer(iinventory, enumdirection) && anyMatch(iinventory, enumdirection, (item, i) -> {
|
||||
+ return !HopperBlockEntity.isEmptyContainer(iinventory, enumdirection) && anyMatch(iinventory, enumdirection, (item, i) -> {
|
||||
+ // Logic copied from below to avoid extra getItem calls
|
||||
+ if (!item.isEmpty() && canTakeItem(iinventory, item, i, enumdirection)) {
|
||||
+ if (!item.isEmpty() && canTakeItemFromContainer(iinventory, item, i, enumdirection)) {
|
||||
+ return hopperPull(hopper, iinventory, item, i);
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
});
|
||||
+ // Paper end
|
||||
} else {
|
||||
Iterator iterator = getItemsAtAndAbove(hopper).iterator();
|
||||
|
||||
Iterator iterator = HopperBlockEntity.getItemsAtAndAbove(world, hopper).iterator();
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
}
|
||||
|
||||
- private static boolean tryTakeInItemFromSlot(Hopper hopper, Container inventory, int slot, Direction side) {
|
||||
+ private static boolean tryTakeInItemFromSlot(Hopper hopper, Container inventory, int slot, Direction side) {// Paper - method unused as logic is inlined above
|
||||
ItemStack itemstack = inventory.getItem(slot);
|
||||
+ // Paper - method unused as logic is inlined above
|
||||
private static boolean a(Hopper ihopper, Container iinventory, int i, Direction enumdirection, Level world) { // Spigot
|
||||
ItemStack itemstack = iinventory.getItem(i);
|
||||
|
||||
- if (!itemstack.isEmpty() && canTakeItemFromContainer(inventory, itemstack, slot, side)) {
|
||||
- ItemStack itemstack1 = itemstack.copy();
|
||||
+ if (!itemstack.isEmpty() && canTakeItemFromContainer(inventory, itemstack, slot, side)) { // If this logic changes, update above. this is left inused incase reflective plugins
|
||||
+ return hopperPull(hopper, inventory, itemstack, slot); /* // Paper - disable rest
|
||||
+ ItemStack itemstack1 = itemstack.cloneItemStack();
|
||||
- if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(iinventory, itemstack, i, enumdirection)) {
|
||||
+ if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(iinventory, itemstack, i, enumdirection)) { // If this logic changes, update above. this is left inused incase reflective plugins
|
||||
+ return hopperPull(ihopper, iinventory, itemstack, i); /* // Paper - disable rest
|
||||
ItemStack itemstack1 = itemstack.copy();
|
||||
// ItemStack itemstack2 = addItem(iinventory, ihopper, iinventory.splitStack(i, 1), (EnumDirection) null);
|
||||
// CraftBukkit start - Call event on collection of items from inventories into the hopper
|
||||
- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(inventory.removeItem(slot, hopper.getLevel().spigotConfig.hopperAmount)); // Spigot
|
||||
+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.splitStack(i, ihopper.getWorld().spigotConfig.hopperAmount)); // Spigot
|
||||
|
||||
Inventory sourceInventory;
|
||||
// Have to special case large chests as they work oddly
|
||||
- if (inventory instanceof CompoundContainer) {
|
||||
- sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) inventory);
|
||||
+ if (iinventory instanceof InventoryLargeChest) {
|
||||
+ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory);
|
||||
} else {
|
||||
- sourceInventory = inventory.getOwner().getInventory();
|
||||
+ sourceInventory = iinventory.getOwner().getInventory();
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
|
||||
- InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), hopper.getOwner().getInventory(), false);
|
||||
+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false);
|
||||
|
||||
- hopper.getLevel().getCraftServer().getPluginManager().callEvent(event);
|
||||
+ ihopper.getWorld().getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
- inventory.setItem(slot, itemstack1);
|
||||
+ iinventory.setItem(i, itemstack1);
|
||||
|
||||
- if (hopper instanceof HopperBlockEntity) {
|
||||
- ((HopperBlockEntity) hopper).setCooldown(hopper.getLevel().spigotConfig.hopperTransfer); // Spigot
|
||||
- } else if (hopper instanceof MinecartHopper) {
|
||||
- ((MinecartHopper) hopper).setCooldown(hopper.getLevel().spigotConfig.hopperTransfer / 2); // Spigot
|
||||
+ if (ihopper instanceof TileEntityHopper) {
|
||||
+ ((TileEntityHopper) ihopper).setCooldown(ihopper.getWorld().spigotConfig.hopperTransfer); // Spigot
|
||||
+ } else if (ihopper instanceof EntityMinecartHopper) {
|
||||
+ ((EntityMinecartHopper) ihopper).setCooldown(ihopper.getWorld().spigotConfig.hopperTransfer / 2); // Spigot
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int origCount = event.getItem().getAmount(); // Spigot
|
||||
- ItemStack itemstack2 = addItem(inventory, hopper, CraftItemStack.asNMSCopy(event.getItem()), null);
|
||||
+ ItemStack itemstack2 = addItem(iinventory, ihopper, CraftItemStack.asNMSCopy(event.getItem()), null);
|
||||
// CraftBukkit end
|
||||
|
||||
if (itemstack2.isEmpty()) {
|
||||
- inventory.setChanged();
|
||||
+ iinventory.update();
|
||||
return true;
|
||||
}
|
||||
|
||||
- itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot
|
||||
- inventory.setItem(slot, itemstack1);
|
||||
+ itemstack1.subtract(origCount - itemstack2.getCount()); // Spigot
|
||||
itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot
|
||||
- iinventory.setItem(i, itemstack1);
|
||||
+ iinventory.setItem(i, itemstack1);*/ // Paper - end commenting out replaced block for Hopper Optimizations
|
||||
}
|
||||
|
||||
|
@ -515,14 +406,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
itemEntity.level.getCraftServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
return !inventory.canPlaceItem(slot, stack) ? false : !(inventory instanceof WorldlyContainer) || ((WorldlyContainer) inventory).canPlaceItemThroughFace(slot, stack, side);
|
||||
}
|
||||
|
||||
+ private static boolean canTakeItem(Container iinventory, ItemStack itemstack, int i, Direction enumdirection) { return canTakeItemFromContainer(iinventory, itemstack, i, enumdirection); } // Paper - OBFHELPER
|
||||
private static boolean canTakeItemFromContainer(Container inv, ItemStack stack, int slot, Direction facing) {
|
||||
return !(inv instanceof WorldlyContainer) || ((WorldlyContainer) inv).canTakeItemThroughFace(slot, stack, facing);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
boolean flag1 = to.isEmpty();
|
||||
|
||||
|
@ -532,51 +415,45 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ IGNORE_TILE_UPDATES = false; // Paper
|
||||
stack = ItemStack.EMPTY;
|
||||
flag = true;
|
||||
} else if (canMergeItems(itemstack1, stack)) {
|
||||
} else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
|
||||
public static List<ItemEntity> getItemsAtAndAbove(Hopper ihopper) {
|
||||
- return (List) ihopper.getSuckShape().toAabbs().stream().flatMap((axisalignedbb) -> {
|
||||
- return ihopper.getLevel().getEntitiesOfClass(ItemEntity.class, axisalignedbb.move(ihopper.getLevelX() - 0.5D, ihopper.getLevelY() - 0.5D, ihopper.getLevelZ() - 0.5D), EntitySelector.ENTITY_STILL_ALIVE).stream();
|
||||
public static List<ItemEntity> getItemsAtAndAbove(Level world, Hopper hopper) {
|
||||
- return (List) hopper.getSuckShape().toAabbs().stream().flatMap((axisalignedbb) -> {
|
||||
- return world.getEntitiesOfClass(ItemEntity.class, axisalignedbb.move(hopper.getLevelX() - 0.5D, hopper.getLevelY() - 0.5D, hopper.getLevelZ() - 0.5D), EntitySelector.ENTITY_STILL_ALIVE).stream();
|
||||
- }).collect(Collectors.toList());
|
||||
+ // Paper start - Optimize item suck in. remove streams, restore 1.12 checks. Seriously checking the bowl?!
|
||||
+ Level world = ihopper.getLevel();
|
||||
+ double d0 = ihopper.getX();
|
||||
+ double d1 = ihopper.getY();
|
||||
+ double d2 = ihopper.getZ();
|
||||
+ double d0 = hopper.getLevelX();
|
||||
+ double d1 = hopper.getLevelY();
|
||||
+ double d2 = hopper.getLevelZ();
|
||||
+ AABB bb = new AABB(d0 - 0.5D, d1, d2 - 0.5D, d0 + 0.5D, d1 + 1.5D, d2 + 0.5D);
|
||||
+ return world.getEntities(ItemEntity.class, bb, Entity::isAlive);
|
||||
+ return world.getEntitiesOfClass(ItemEntity.class, bb, Entity::isAlive);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Container getContainerAt(Level world, BlockPos blockposition) {
|
||||
- return getContainerAt(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D);
|
||||
+ return a(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, true); // Paper
|
||||
public static Container getContainerAt(Level world, BlockPos pos) {
|
||||
- return HopperBlockEntity.getContainerAt(world, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D);
|
||||
+ return HopperBlockEntity.getContainerAt(world, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, true); // Paper
|
||||
}
|
||||
|
||||
+ public static Container getContainerAt(Level world, double x, double y, double z) { return getContainerAt(world, x, y, z, false); } // Paper - overload to default false
|
||||
@Nullable
|
||||
- public static Container getContainerAt(Level world, double x, double y, double z) {
|
||||
+ public static Container getContainerAt(Level world, double x, double y, double z) { return a(world, x, y, z, false); } // Paper - overload to default false
|
||||
+ public static Container a(Level world, double d0, double d1, double d2, boolean optimizeEntities) { // Paper
|
||||
- private static Container getContainerAt(Level world, double x, double y, double z) {
|
||||
+ private static Container getContainerAt(Level world, double x, double y, double z, boolean optimizeEntities) {
|
||||
Object object = null;
|
||||
- BlockPos blockposition = new BlockPos(x, y, z);
|
||||
+ BlockPos blockposition = new BlockPos(d0, d1, d2);
|
||||
BlockPos blockposition = new BlockPos(x, y, z);
|
||||
if ( !world.hasChunkAt( blockposition ) ) return null; // Spigot
|
||||
BlockState iblockdata = world.getBlockState(blockposition);
|
||||
Block block = iblockdata.getBlock();
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
}
|
||||
|
||||
- if (object == null) {
|
||||
- List<Entity> list = world.getEntities((Entity) null, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR);
|
||||
+ if (object == null && (!optimizeEntities || !org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(block).isOccluding())) { // Paper
|
||||
+ List<Entity> list = world.getEntities((Entity) null, new AABB(d0 - 0.5D, d1 - 0.5D, d2 - 0.5D, d0 + 0.5D, d1 + 0.5D, d2 + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR);
|
||||
List<Entity> list = world.getEntities((Entity) null, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR);
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
object = (Container) list.get(world.random.nextInt(list.size()));
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
|
@ -584,7 +461,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
this.unpackLootTable((Player) null);
|
||||
this.unpackLootTable((Player)null);
|
||||
- return this.getItems().stream().allMatch(ItemStack::isEmpty);
|
||||
+ // Paper start
|
||||
+ for (ItemStack itemStack : this.getItems()) {
|
||||
|
@ -598,8 +475,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
@Override
|
||||
public ItemStack getItem(int slot) {
|
||||
- this.unpackLootTable((Player) null);
|
||||
- this.unpackLootTable((Player)null);
|
||||
+ if (slot == 0) this.unpackLootTable((Player) null); // Paper
|
||||
return (ItemStack) this.getItems().get(slot);
|
||||
return this.getItems().get(slot);
|
||||
}
|
||||
|
|
@ -14,6 +14,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
BlockState iblockdata = this.level.getBlockState(blockposition);
|
||||
- FluidState fluid = this.level.getFluidState(blockposition);
|
||||
+ FluidState fluid = iblockdata.getFluidState(); // Paper
|
||||
Optional<Float> optional = this.damageCalculator.a(this, this.level, blockposition, iblockdata, fluid);
|
||||
|
||||
if (optional.isPresent()) {
|
||||
if (!this.level.isInWorldBounds(blockposition)) {
|
||||
break;
|
|
@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
this.tellNeutralMobsThatIDied();
|
||||
}
|
||||
// SPIGOT-5478 must be called manually now
|
||||
|
@ -16,4 +16,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ if (event.shouldDropExperience()) this.dropExperience(); // Paper - tie to event
|
||||
// we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
|
||||
if (!event.getKeepInventory()) {
|
||||
// Paper start - replace logic
|
||||
this.getInventory().clearContent();
|
|
@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
}
|
||||
|
||||
- BlockState iblockdata = world.getBlockState(globalpos.getBlockPosition());
|
||||
+ BlockState iblockdata = world.getTypeIfLoaded(globalpos.getBlockPosition()); // Paper
|
||||
+ if (iblockdata == null) { return false; } // Paper
|
||||
|
||||
return globalpos.getBlockPosition().a((Position) entity.position(), 2.0D) && iblockdata.getBlock().is((Tag) BlockTags.BEDS) && !(Boolean) iblockdata.getValue(BedBlock.OCCUPIED);
|
||||
- BlockState blockState = world.getBlockState(globalPos.pos());
|
||||
+ BlockState blockState = world.getTypeIfLoaded(globalPos.pos()); // Paper
|
||||
+ if (blockState == null) { return false; } // Paper
|
||||
return globalPos.pos().closerThan(entity.position(), 2.0D) && blockState.is(BlockTags.BEDS) && !blockState.getValue(BedBlock.OCCUPIED);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue