[ci skip] Add more identifying patch comments, merge related patches

This commit is contained in:
Nassim Jahnke 2024-01-19 12:30:04 +01:00
parent 864f4072c1
commit b5b92e90d8
38 changed files with 181 additions and 229 deletions

View file

@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ net.minecraft.world.item.SpawnEggItem eggItem = net.minecraft.world.item.SpawnEggItem.byId(nmsType);
+ return eggItem == null ? null : new net.minecraft.world.item.ItemStack(eggItem).asBukkitMirror();
+ }
+ // Paper end
+ // Paper end - old getSpawnEgg API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View file

@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.passengers = ImmutableList.copyOf(pass);
+ return result;
+ }
+ // Paper end
+ // Paper end - Entity serialization api
public boolean save(CompoundTag nbt) {
return this.isPassenger() ? false : this.saveAsPassenger(nbt);
}

View file

@ -33,7 +33,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ pitch = event.getTo().getPitch();
+ velocity = org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getAfter());
+ }
+ // Paper end
+ // Paper end - Call EntityPortalExitEvent
if (worldserver == this.level) {
// SPIGOT-6782: Just move the entity if a plugin changed the world to the one the entity is already in
this.moveTo(shapedetectorshape.pos.x, shapedetectorshape.pos.y, shapedetectorshape.pos.z, shapedetectorshape.yRot, shapedetectorshape.xRot);
@ -43,8 +43,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
entity.restoreFrom(this);
- entity.moveTo(shapedetectorshape.pos.x, shapedetectorshape.pos.y, shapedetectorshape.pos.z, shapedetectorshape.yRot, entity.getXRot());
- entity.setDeltaMovement(shapedetectorshape.speed);
+ entity.moveTo(position.x, position.y, position.z, yaw, pitch); // Paper - use EntityPortalExitEvent values
+ entity.setDeltaMovement(velocity); // Paper - use EntityPortalExitEvent values
+ entity.moveTo(position.x, position.y, position.z, yaw, pitch); // Paper - EntityPortalExitEvent
+ entity.setDeltaMovement(velocity); // Paper - EntityPortalExitEvent
// CraftBukkit start - Don't spawn the new entity if the current entity isn't spawned
if (this.inWorld) {
worldserver.addDuringTeleport(entity);

View file

@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.critical = critical;
+ return this;
+ }
+ // Paper end
+ // Paper end - add critical damage API
}
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity;
+ boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity; // Paper - Add critical damage API - conflict on change
+ boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity; // Paper - Add critical damage API; diff on change
flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper
flag2 = flag2 && !this.isSprinting();

View file

@ -14,11 +14,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
protected BlockPos findLightningTargetAround(BlockPos pos) {
+ // Paper start
+ // Paper start - Add methods to find targets for lightning strikes
+ return this.findLightningTargetAround(pos, false);
+ }
+ public BlockPos findLightningTargetAround(BlockPos pos, boolean returnNullWhenNoTarget) {
+ // Paper end
+ // Paper end - Add methods to find targets for lightning strikes
BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
Optional<BlockPos> optional = this.findLightningRod(blockposition1);
@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!list.isEmpty()) {
return ((LivingEntity) list.get(this.random.nextInt(list.size()))).blockPosition();
} else {
+ if (returnNullWhenNoTarget) return null; // Paper
+ if (returnNullWhenNoTarget) return null; // Paper - Add methods to find targets for lightning strikes
if (blockposition1.getY() == this.getMinBuildHeight() - 1) {
blockposition1 = blockposition1.above(2);
}
@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return (LightningStrike) lightning.getBukkitEntity();
}
+ // Paper start
+ // Paper start - Add methods to find targets for lightning strikes
+ @Override
+ public Location findLightningRod(Location location) {
+ return this.world.findLightningRod(io.papermc.paper.util.MCUtil.toBlockPosition(location))
@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final BlockPos pos = this.world.findLightningTargetAround(io.papermc.paper.util.MCUtil.toBlockPosition(location), true);
+ return pos == null ? null : io.papermc.paper.util.MCUtil.toLocation(this.world, pos);
+ }
+ // Paper end
+ // Paper end - Add methods to find targets for lightning strikes
+
@Override
public boolean generateTree(Location loc, TreeType type) {

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
@Override
public int getSpawnLimit(SpawnCategory spawnCategory) {
// Paper start
// Paper start - Add mobcaps commands
+ Preconditions.checkArgument(spawnCategory != null, "SpawnCategory cannot be null");
+ Preconditions.checkArgument(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " does not have a spawn limit.");
return this.getSpawnLimitUnsafe(spawnCategory);

View file

@ -91,7 +91,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final boolean hidden;
private float x;
private float y;
+ public final io.papermc.paper.advancement.AdvancementDisplay paper = new io.papermc.paper.advancement.PaperAdvancementDisplay(this); // Paper
+ public final io.papermc.paper.advancement.AdvancementDisplay paper = new io.papermc.paper.advancement.PaperAdvancementDisplay(this); // Paper - Add more advancement API
public DisplayInfo(ItemStack icon, Component title, Component description, Optional<ResourceLocation> background, AdvancementType frame, boolean showToast, boolean announceToChat, boolean hidden) {
this.title = title;
@ -103,7 +103,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return Collections.unmodifiableCollection(this.handle.value().criteria().keySet());
}
+ // Paper start
+ // Paper start - Add more advancement API
@Override
- public AdvancementDisplay getDisplay() {
- if (this.handle.value().display().isEmpty()) {
@ -149,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final net.minecraft.advancements.AdvancementNode advancementNode = net.minecraft.server.MinecraftServer.getServer().getAdvancements().tree().get(this.handle);
+ return java.util.Objects.requireNonNull(advancementNode, "could not find internal advancement node for advancement " + this.handle.id()).root().holder().toBukkit();
}
+ // Paper end
+ // Paper end - Add more advancement API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View file

@ -264,7 +264,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
world.getProfiler().pop();
}
+ // Paper start
+ // Paper start - Add mobcaps commands
+ public static int globalLimitForCategory(final ServerLevel level, final MobCategory category, final int spawnableChunkCount) {
+ final int categoryLimit = level.getWorld().getSpawnLimitUnsafe(CraftSpawnCategory.toBukkit(category));
+ if (categoryLimit < 1) {
@ -272,7 +272,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ return categoryLimit * spawnableChunkCount / NaturalSpawner.MAGIC_NUMBER;
+ }
+ // Paper end
+ // Paper end - Add mobcaps commands
+
public static void spawnCategoryForChunk(MobCategory group, ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner) {
// Paper start - add parameters and int ret type
@ -285,11 +285,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public int getSpawnLimit(SpawnCategory spawnCategory) {
+ // Paper start
+ // Paper start - Add mobcaps commands
+ return this.getSpawnLimitUnsafe(spawnCategory);
+ }
+ public int getSpawnLimitUnsafe(final SpawnCategory spawnCategory) {
+ // Paper end
+ // Paper end - Add mobcaps commands
return this.spawnCategoryLimit.getOrDefault(spawnCategory, -1);
}
@ -301,7 +301,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Preconditions.checkArgument(spawnCategory != null, "SpawnCategory cannot be null");
Preconditions.checkArgument(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory.%s are not supported", spawnCategory);
+ // Paper start
+ // Paper start - Add mobcaps commands
+ return this.getSpawnLimitUnsafe(spawnCategory);
+ }
+ public final int getSpawnLimitUnsafe(final SpawnCategory spawnCategory) {
@ -309,7 +309,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (limit < 0) {
- limit = this.server.getSpawnLimit(spawnCategory);
+ limit = this.server.getSpawnLimitUnsafe(spawnCategory);
+ // Paper end
+ // Paper end - Add mobcaps commands
}
return limit;
}

View file

@ -72,7 +72,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ DedicatedServer.LOGGER.warn("FOR MORE INFORMATION, SEE https://madelinemiller.dev/blog/root-minecraft-server/");
+ DedicatedServer.LOGGER.warn("****************************");
+ }
+ // Paper end
+ // Paper end - detect running as root
+
DedicatedServer.LOGGER.info("Loading properties");
DedicatedServerProperties dedicatedserverproperties = this.settings.getProperties();

View file

@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
@@ -0,0 +0,0 @@ public class ServerConnectionListener {
ServerConnectionListener.LOGGER.info("Paper: Using " + com.velocitypowered.natives.util.Natives.cipher.getLoadedVariant() + " cipher from Velocity.");
// Paper end
// Paper end - Use Velocity cipher
+ // Paper start - Add support for proxy protocol
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.proxyProtocol) {

View file

@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import org.slf4j.Logger;
public class ChunkSerializer {
+ // Paper start
+ // Paper start - Attempt to recalculate regionfile header if it is corrupt
+ // TODO: Check on update
+ public static long getLastWorldSaveTime(CompoundTag chunkData) {
+ final int dataVersion = ChunkStorage.getVersion(chunkData);
@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return chunkData.getLong("LastUpdate");
+ }
+ }
+ // Paper end
+ // Paper end - Attempt to recalculate regionfile header if it is corrupt
public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), null); // Paper - Anti-Xray - Add preset block states
private static final Logger LOGGER = LogUtils.getLogger();
@ -50,7 +50,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper start - async chunk io
// remove IO worker
- this.regionFileCache = new RegionFileStorage(directory, dsync); // Paper - nuke IOWorker
+ this.regionFileCache = new RegionFileStorage(directory, dsync, true); // Paper - nuke IOWorker // Paper
+ this.regionFileCache = new RegionFileStorage(directory, dsync, true); // Paper - nuke IOWorker // Paper - Attempt to recalculate regionfile header if it is corrupt
// Paper end - async chunk io
}
@ -62,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class RegionBitmap {
private final BitSet used = new BitSet();
+ // Paper start
+ // Paper start - Attempt to recalculate regionfile header if it is corrupt
+ public final void copyFrom(RegionBitmap other) {
+ BitSet thisBitset = this.used;
+ BitSet otherBitset = other.used;
@ -81,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ bitset.set(from, from + length);
+ return true;
+ }
+ // Paper end
+ // Paper end - Attempt to recalculate regionfile header if it is corrupt
+
public void force(int start, int size) {
this.used.set(start, start + size);
@ -94,7 +94,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(); // Paper
public final Path regionFile; // Paper
+ // Paper start - try to recover from RegionFile header corruption
+ // Paper start - Attempt to recalculate regionfile header if it is corrupt
+ private static long roundToSectors(long bytes) {
+ long sectors = bytes >>> 12; // 4096 = 2^12
+ long remainingBytes = bytes & 4095;
@ -441,7 +441,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ final boolean canRecalcHeader; // final forces compile fail on new constructor
+ // Paper end
+ // Paper end - Attempt to recalculate regionfile header if it is corrupt
+
// Paper start - Cache chunk status
private final net.minecraft.world.level.chunk.ChunkStatus[] statuses = new net.minecraft.world.level.chunk.ChunkStatus[32 * 32];

View file

@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} catch (final CommandSyntaxException ignored) {
}
+ }
+ // Paper end
+ // Paper end - Don't suggest if the requirement isn't met
futures[i++] = future;
}

View file

@ -27,14 +27,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
};
- seededrandom.setFeatureSeed(i, l1, l);
+ // Paper start - change populationSeed used in random
+ // Paper start - Configurable feature seeds; change populationSeed used in random
+ long featurePopulationSeed = i;
+ final long configFeatureSeed = generatoraccessseed.getMinecraftWorld().paperConfig().featureSeeds.features.getLong(placedfeature.feature());
+ if (configFeatureSeed != -1) {
+ featurePopulationSeed = seededrandom.setDecorationSeed(configFeatureSeed, blockposition.getX(), blockposition.getZ()); // See seededrandom.setDecorationSeed from above
+ }
+ seededrandom.setFeatureSeed(featurePopulationSeed, l1, l);
+ // Paper end
+ // Paper end - Configurable feature seeds
try {
generatoraccessseed.setCurrentlyGenerating(supplier1);

View file

@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
+ ((org.bukkit.craftbukkit.entity.CraftHumanEntity)h).getHandle().closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
}
+ // Paper end
+ // Paper end - this area looks like it can load chunks, change the behavior
}
}
// Spigot End

View file

@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start
private boolean check(ServerChunkCache cps, int x, int z) {
+ if (true) return true; // Paper - this isn't even needed anymore, light is purged updating to 1.14+, why are we holding up the conversion process reading chunk data off disk - return true, we need to set light populated to true so the converter recognizes the chunk as being "full"
+ if (true) return true; // Paper - Perf: this isn't even needed anymore, light is purged updating to 1.14+, why are we holding up the conversion process reading chunk data off disk - return true, we need to set light populated to true so the converter recognizes the chunk as being "full"
ChunkPos pos = new ChunkPos(x, z);
if (cps != null) {
//com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread"); // Paper - this function is now MT-Safe

View file

@ -1,8 +1,9 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 10 May 2020 22:12:46 -0400
Subject: [PATCH] Ensure Entity AABB's are never invalid
Subject: [PATCH] Ensure Entity position and AABB are never invalid
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
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
@ -14,20 +15,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void setPos(double x, double y, double z) {
- this.setPosRaw(x, y, z);
- this.setBoundingBox(this.makeBoundingBox());
+ this.setPosRaw(x, y, z, true); // Paper - force bounding box update
+ // this.setBoundingBox(this.makeBoundingBox()); // Paper - move into setPositionRaw
+ this.setPosRaw(x, y, z, true); // Paper - Block invalid positions and bounding box; force update
+ // this.setBoundingBox(this.makeBoundingBox()); // Paper - Block invalid positions and bounding box; move into setPosRaw
}
protected AABB makeBoundingBox() {
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
return this.getZ((2.0D * this.random.nextDouble() - 1.0D) * widthScale);
}
+ // Paper start - Block invalid positions and bounding box
+ public static boolean checkPosition(Entity entity, double newX, double newY, double newZ) {
+ if (Double.isFinite(newX) && Double.isFinite(newY) && Double.isFinite(newZ)) {
+ return true;
+ }
+
+ String entityInfo;
+ try {
+ entityInfo = entity.toString();
+ } catch (Exception ex) {
+ entityInfo = "[Entity info unavailable] ";
+ }
+ LOGGER.error("New entity position is invalid! Tried to set invalid position ({},{},{}) for entity {} located at {}, entity info: {}", newX, newY, newZ, entity.getClass().getName(), entity.position, entityInfo, new Throwable());
+ return false;
+ }
public final void setPosRaw(double x, double y, double z) {
+ // Paper start
+ this.setPosRaw(x, y, z, false);
+ }
+ public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
+ // Paper end
+ if (!checkPosition(this, x, y, z)) {
+ return;
+ }
+ // Paper end - Block invalid positions and bounding box
// Paper start - rewrite chunk system
if (this.updatingSectionStatus) {
LOGGER.error("Refusing to update position for entity " + this + " to position " + new Vec3(x, y, z) + " since it is processing a section status update", new Throwable());
@ -35,12 +54,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.levelCallback.onMove();
}
+ // Paper start - never allow AABB to become desynced from position
+ // Paper start - Block invalid positions and bounding box; don't allow desync of pos and AABB
+ // hanging has its own special logic
+ if (!(this instanceof net.minecraft.world.entity.decoration.HangingEntity) && (forceBoundingBoxUpdate || this.position.x != x || this.position.y != y || this.position.z != z)) {
+ this.setBoundingBox(this.makeBoundingBox());
+ }
+ // Paper end
+ // Paper end - Block invalid positions and bounding box
}
public void checkDespawn() {}

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- if (persistVehicle && entity1 != null && entity != this && entity.hasExactlyOnePlayerPassenger()) {
+ if (persistVehicle && entity1 != null && entity != this && entity.hasExactlyOnePlayerPassenger() && !entity.isRemoved()) { // Paper
+ if (persistVehicle && entity1 != null && entity != this && entity.hasExactlyOnePlayerPassenger() && !entity.isRemoved()) { // Paper - Ensure valid vehicle status
// CraftBukkit end
CompoundTag nbttagcompound2 = new CompoundTag();
CompoundTag nbttagcompound3 = new CompoundTag();

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void place(TreeDecorator.Context generator) {
+ if (generator.logs().isEmpty()) return; // Paper
+ if (generator.logs().isEmpty()) return; // Paper - Fix crash when trying to generate without logs
RandomSource randomSource = generator.random();
if (!(randomSource.nextFloat() >= this.probability)) {
List<BlockPos> list = generator.logs();

View file

@ -14,10 +14,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Nullable
private Executor executor;
+ // Paper start
+ // Paper start - Fix GameProfileCache concurrency
+ protected final java.util.concurrent.locks.ReentrantLock stateLock = new java.util.concurrent.locks.ReentrantLock();
+ protected final java.util.concurrent.locks.ReentrantLock lookupLock = new java.util.concurrent.locks.ReentrantLock();
+ // Paper end
+ // Paper end - Fix GameProfileCache concurrency
+
public GameProfileCache(GameProfileRepository profileRepository, File cacheFile) {
this.profileRepository = profileRepository;
@ -26,13 +26,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
private void safeAdd(GameProfileCache.GameProfileInfo entry) {
+ try { this.stateLock.lock(); // Paper - allow better concurrency
+ try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
GameProfile gameprofile = entry.getProfile();
entry.setLastAccess(this.getNextOperation());
this.profilesByName.put(gameprofile.getName().toLowerCase(Locale.ROOT), entry);
this.profilesByUUID.put(gameprofile.getId(), entry);
+ } finally { this.stateLock.unlock(); } // Paper - allow better concurrency
+ } finally { this.stateLock.unlock(); } // Paper - Fix GameProfileCache concurrency
}
private static Optional<GameProfile> lookupGameProfile(GameProfileRepository repository, String name) {
@ -40,20 +40,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper start
public @Nullable GameProfile getProfileIfCached(String name) {
+ try { this.stateLock.lock(); // Paper - allow better concurrency
+ try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
GameProfileCache.GameProfileInfo entry = this.profilesByName.get(name.toLowerCase(Locale.ROOT));
if (entry == null) {
return null;
}
entry.setLastAccess(this.getNextOperation());
return entry.getProfile();
+ } finally { this.stateLock.unlock(); } // Paper - allow better concurrency
+ } finally { this.stateLock.unlock(); } // Paper - Fix GameProfileCache concurrency
}
// Paper end
public Optional<GameProfile> get(String name) {
String s1 = name.toLowerCase(Locale.ROOT);
+ boolean stateLocked = true; try { this.stateLock.lock(); // Paper - allow better concurrency
+ boolean stateLocked = true; try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByName.get(s1);
boolean flag = false;
@ -61,12 +61,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (usercache_usercacheentry != null) {
usercache_usercacheentry.setLastAccess(this.getNextOperation());
optional = Optional.of(usercache_usercacheentry.getProfile());
+ stateLocked = false; this.stateLock.unlock(); // Paper - allow better concurrency
+ stateLocked = false; this.stateLock.unlock(); // Paper - Fix GameProfileCache concurrency
} else {
+ stateLocked = false; this.stateLock.unlock(); // Paper - allow better concurrency
+ try { this.lookupLock.lock(); // Paper - allow better concurrency
+ stateLocked = false; this.stateLock.unlock(); // Paper - Fix GameProfileCache concurrency
+ try { this.lookupLock.lock(); // Paper - Fix GameProfileCache concurrency
optional = GameProfileCache.lookupGameProfile(this.profileRepository, name); // CraftBukkit - use correct case for offline players
+ } finally { this.lookupLock.unlock(); } // Paper - allow better concurrency
+ } finally { this.lookupLock.unlock(); } // Paper - Fix GameProfileCache concurrency
if (optional.isPresent()) {
this.add((GameProfile) optional.get());
flag = false;
@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
return optional;
+ } finally { if (stateLocked) { this.stateLock.unlock(); } } // Paper - allow better concurrency
+ } finally { if (stateLocked) { this.stateLock.unlock(); } } // Paper - Fix GameProfileCache concurrency
}
public CompletableFuture<Optional<GameProfile>> getAsync(String username) {
@ -82,7 +82,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public Optional<GameProfile> get(UUID uuid) {
+ try { this.stateLock.lock(); // Paper - allow better concurrency
+ try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByUUID.get(uuid);
if (usercache_usercacheentry == null) {
@ -90,7 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
usercache_usercacheentry.setLastAccess(this.getNextOperation());
return Optional.of(usercache_usercacheentry.getProfile());
}
+ } finally { this.stateLock.unlock(); } // Paper - allow better concurrency
+ } finally { this.stateLock.unlock(); } // Paper - Fix GameProfileCache concurrency
}
public void setExecutor(Executor executor) {
@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
DateFormat dateformat = GameProfileCache.createDateFormat();
- this.getTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot
+ this.listTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot // Paper - allow better concurrency
+ this.listTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot // Paper - Fix GameProfileCache concurrency
jsonarray.add(GameProfileCache.writeGameProfile(usercache_usercacheentry, dateformat));
});
String s = this.gson.toJson(jsonarray);
@ -108,7 +108,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private Stream<GameProfileCache.GameProfileInfo> getTopMRUProfiles(int limit) {
- return ImmutableList.copyOf(this.profilesByUUID.values()).stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit((long) limit);
+ // Paper start - allow better concurrency
+ // Paper start - Fix GameProfileCache concurrency
+ return this.listTopMRUProfiles(limit).stream();
+ }
+
@ -120,7 +120,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.stateLock.unlock();
+ }
}
+ // Paper end
+ // Paper end - Fix GameProfileCache concurrency
private static JsonElement writeGameProfile(GameProfileCache.GameProfileInfo entry, DateFormat dateFormat) {
JsonObject jsonobject = new JsonObject();

View file

@ -13,15 +13,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected void doFreezeConversion() {
- this.convertTo(EntityType.STRAY, true, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons
+ Stray stray = this.convertTo(EntityType.STRAY, true, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons // Paper - track result of conversion
+ Stray stray = this.convertTo(EntityType.STRAY, true, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons // Paper - Fix issues with mob conversion
if (!this.isSilent()) {
this.level().levelEvent((Player) null, 1048, this.blockPosition(), 0);
}
+ // Paper start - reset conversion time to prevent event spam
+ // Paper start - Fix issues with mob conversion; reset conversion time to prevent event spam
+ if (stray == null) {
+ this.conversionTime = 300;
+ }
+ // Paper end
+ // Paper end - Fix issues with mob conversion
}
@ -33,11 +33,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (zoglin != null) {
zoglin.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0));
}
+ // Paper start - reset to prevent event spam
+ // Paper start - Fix issues with mob conversion; reset to prevent event spam
+ else {
+ this.timeInOverworld = 0;
+ }
+ // Paper end
+ // Paper end - Fix issues with mob conversion
}
@ -49,11 +49,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (entitypigzombie != null) {
entitypigzombie.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0));
}
+ // Paper start - reset to prevent event spam
+ // Paper start - Fix issues with mob conversion; reset to prevent event spam
+ else {
+ this.timeInOverworld = 0;
+ }
+ // Paper end
+ // Paper end - Fix issues with mob conversion
}

View file

@ -12,11 +12,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Spigot end
// Spigot Start
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
+ // Paper start
+ // Paper start - Fix merchant inventory not closing on entity removal
+ if (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) {
+ merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED);
+ }
+ // Paper end
+ // Paper end - Fix merchant inventory not closing on entity removal
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) {
h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
}

View file

@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ brain.eraseMemory(MemoryModuleType.TEMPTING_PLAYER);
+ brain.setActiveActivityIfPossible(net.minecraft.world.entity.schedule.Activity.RAM);
+ }
+ // Paper end
+ // Paper end - Goat ram API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View file

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 31 Mar 2022 05:18:28 -0700
Subject: [PATCH] Guard against invalid entity positions
Anything not finite should be blocked and logged
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 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
return this.getZ((2.0D * this.random.nextDouble() - 1.0D) * widthScale);
}
+ // Paper start - block invalid positions
+ public static boolean checkPosition(Entity entity, double newX, double newY, double newZ) {
+ if (Double.isFinite(newX) && Double.isFinite(newY) && Double.isFinite(newZ)) {
+ return true;
+ }
+
+ String entityInfo = null;
+ try {
+ entityInfo = entity.toString();
+ } catch (Exception ex) {
+ entityInfo = "[Entity info unavailable] ";
+ }
+ LOGGER.error("New entity position is invalid! Tried to set invalid position (" + newX + "," + newY + "," + newZ + ") for entity " + entity.getClass().getName() + " located at " + entity.position + ", entity info: " + entityInfo, new Throwable());
+ return false;
+ }
+ // Paper end - block invalid positions
+
public final void setPosRaw(double x, double y, double z) {
// Paper start
this.setPosRaw(x, y, z, false);
}
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
+ // Paper start - block invalid positions
+ if (!checkPosition(this, x, y, z)) {
+ return;
+ }
+ // Paper end - block invalid positions
// Paper end
// Paper start - rewrite chunk system
if (this.updatingSectionStatus) {

View file

@ -11,8 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public final class CraftItemFactory implements ItemFactory {
return eggItem == null ? null : new net.minecraft.world.item.ItemStack(eggItem).asBukkitMirror();
}
// Paper end
+
// Paper end - old getSpawnEgg API
+ // Paper start - enchantWithLevels API
+ @Override
+ public ItemStack enchantWithLevels(ItemStack itemStack, int levels, boolean allowTreasure, java.util.Random random) {

View file

@ -9,11 +9,14 @@ type and we are not using its capabilities.
Set thread priorities so main thread has above normal priority over
server threads
Allow usage of a single thread executor by not using ForkJoin so single core CPU's.
Allow usage of a single thread executor by not using ForkJoin so single core CPU's
and reduce worldgen thread worker count for low core count CPUs.
== AT ==
public net.minecraft.Util onThreadException(Ljava/lang/Thread;Ljava/lang/Throwable;)V
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
diff --git a/src/main/java/io/papermc/paper/util/ServerWorkerThread.java b/src/main/java/io/papermc/paper/util/ServerWorkerThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@ -54,11 +57,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- private static ExecutorService makeExecutor(String name) {
- int i = Mth.clamp(Runtime.getRuntime().availableProcessors() - 1, 1, getMaxThreads());
+ private static ExecutorService makeExecutor(String s, int priorityModifier) { // Paper - add priority
+ // Paper start - use simpler thread pool that allows 1 thread
+ int i = Math.min(8, Math.max(Runtime.getRuntime().availableProcessors() - 2, 1));
+ // Paper start - use simpler thread pool that allows 1 thread and reduce worldgen thread worker count for low core count CPUs
+ int cpus = Runtime.getRuntime().availableProcessors() / 2;
+ int i;
+ if (cpus <= 4) {
+ i = cpus <= 2 ? 1 : 2;
+ } else if (cpus <= 8) {
+ // [5, 8]
+ i = Math.max(3, cpus - 2);
+ } else {
+ i = cpus * 2 / 3;
+ }
+ i = Math.min(8, i);
+ i = Integer.getInteger("Paper.WorkerThreadCount", i);
ExecutorService executorService;
+
if (i <= 0) {
executorService = MoreExecutors.newDirectExecutorService();
} else {

View file

@ -9,9 +9,6 @@ previous getChunkAt method which had inlined logic for loaded
chunks did get inlined, but the standard CPS.getChunkAt
method was not inlined.
Paper recently reverted this optimisation, so it's been reintroduced
here.
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
@ -20,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public final LevelChunk getChunk(int chunkX, int chunkZ) { // Paper - final to help inline
+ // Paper start - make sure loaded chunks get the inlined variant of this function
+ // Paper start - Perf: make sure loaded chunks get the inlined variant of this function
+ net.minecraft.server.level.ServerChunkCache cps = ((ServerLevel)this).getChunkSource();
+ if (cps.mainThread == Thread.currentThread()) {
+ LevelChunk ifLoaded = cps.getChunkAtIfLoadedMainThread(chunkX, chunkZ);
@ -28,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return ifLoaded;
+ }
+ }
+ // Paper end - make sure loaded chunks get the inlined variant of this function
+ // Paper end - Perf: make sure loaded chunks get the inlined variant of this function
return (LevelChunk) this.getChunk(chunkX, chunkZ, ChunkStatus.FULL, true); // Paper - avoid a method jump
}

View file

@ -26,21 +26,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public BlockPos.MutableBlockPos setX(int i) {
- super.setX(i);
+ this.x = i; // Paper
+ this.x = i; // Paper - force line
return this;
}
@Override
public BlockPos.MutableBlockPos setY(int i) {
- super.setY(i);
+ this.y = i; // Paper
+ this.y = i; // Paper - force line
return this;
}
@Override
public BlockPos.MutableBlockPos setZ(int i) {
- super.setZ(i);
+ this.z = i; // Paper
+ this.z = i; // Paper - force line
return this;
}
@ -55,9 +55,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- private int x;
- private int y;
- private int z;
+ protected int x; // Paper - protected
+ protected int y; // Paper - protected
+ protected int z; // Paper - protected
+ protected int x; // Paper - force line; protected
+ protected int y; // Paper - force line; protected
+ protected int z; // Paper - force line; protected
public static Codec<Vec3i> offsetCodec(int maxAbsValue) {
return ExtraCodecs.validate(CODEC, (vec) -> {

View file

@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
}
}
+ } finally { thread.setName(nameBefore); } // Paper - name worker thread according
+ } finally { thread.setName(nameBefore); } // Paper - name threads according to running plugin
}
LinkedList<BukkitWorker> getWorkers() {

View file

@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final int range;
SectionPos lastSectionPos;
- public final Set<ServerPlayerConnection> seenBy = Sets.newIdentityHashSet();
+ public final Set<ServerPlayerConnection> seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - optimise map impl
+ public final Set<ServerPlayerConnection> seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
public TrackedEntity(Entity entity, int i, int j, boolean flag) {
this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit

View file

@ -21,7 +21,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- do {
- if (!iterator.hasNext()) {
- return false;
+ // Paper start - remove abstract block iteration
+ // Paper start - Perf: remove abstract block iteration
+ int xOff = pos.getX();
+ int yOff = pos.getY();
+ int zOff = pos.getZ();
@ -46,6 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
-
- return true;
+ return false;
+ // Paper end - Perf: remove abstract block iteration
}
@Override

View file

@ -12,10 +12,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.hasEffect(MobEffects.JUMP) ? 0.1F * ((float) this.getEffect(MobEffects.JUMP).getAmplifier() + 1.0F) : 0.0F;
}
+ protected long lastJumpTime = 0L; // Paper
+ protected long lastJumpTime = 0L; // Paper - Prevent excessive velocity through repeated crits
protected void jumpFromGround() {
Vec3 vec3d = this.getDeltaMovement();
+ // Paper start
+ // Paper start - Prevent excessive velocity through repeated crits
+ long time = System.nanoTime();
+ boolean canCrit = true;
+ if (this instanceof net.minecraft.world.entity.player.Player) {
@ -25,13 +25,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ canCrit = true;
+ }
+ }
+ // Paper end
+ // Paper end - Prevent excessive velocity through repeated crits
this.setDeltaMovement(vec3d.x, (double) this.getJumpPower(), vec3d.z);
if (this.isSprinting()) {
float f = this.getYRot() * 0.017453292F;
+ if (canCrit) // Paper
+ if (canCrit) // Paper - Prevent excessive velocity through repeated crits
this.setDeltaMovement(this.getDeltaMovement().add((double) (-Mth.sin(f) * 0.2F), 0.0D, (double) (Mth.cos(f) * 0.2F)));
}

View file

@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (this.portalLocation.getY() <= this.level.getMinBuildHeight()) {
+ this.portalLocation = this.portalLocation.atY(this.level.getMinBuildHeight() + 1);
+ }
+ // Paper end
+ // Paper end - Prevent "softlocked" exit portal generation
if (worldgenendtrophy.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), this.portalLocation)) {
int i = Mth.positiveCeilDiv(4, 16);

View file

@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 30 Aug 2021 04:26:40 -0700
Subject: [PATCH] Reduce worldgen thread worker count for low core count CPUs
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -0,0 +0,0 @@ public class Util {
private static ExecutorService makeExecutor(String s, int priorityModifier) { // Paper - add priority
// Paper start - use simpler thread pool that allows 1 thread
- int i = Math.min(8, Math.max(Runtime.getRuntime().availableProcessors() - 2, 1));
+ // Paper start - also try to avoid suffocating the system with the worldgen workers
+ int cpus = Runtime.getRuntime().availableProcessors() / 2;
+ int i;
+ if (cpus <= 4) {
+ i = cpus <= 2 ? 1 : 2;
+ } else if (cpus <= 8) {
+ // [5, 8]
+ i = Math.max(3, cpus - 2);
+ } else {
+ i = cpus * 2 / 3;
+ }
+ i = Math.min(8, i);
+ // Paper end - also try to avoid suffocating the system with the worldgen workers
i = Integer.getInteger("Paper.WorkerThreadCount", i);
ExecutorService executorService;

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private static String assertValidNamespace(String namespace, String path) {
if (!isValidNamespace(namespace)) {
- throw new ResourceLocationException("Non [a-z0-9_.-] character in namespace of location: " + namespace + ":" + path);
+ throw new ResourceLocationException("Non [a-z0-9_.-] character in namespace of location: " + org.apache.commons.lang3.StringUtils.normalizeSpace(namespace) + ":" + org.apache.commons.lang3.StringUtils.normalizeSpace(path)); // Paper
+ throw new ResourceLocationException("Non [a-z0-9_.-] character in namespace of location: " + org.apache.commons.lang3.StringUtils.normalizeSpace(namespace) + ":" + org.apache.commons.lang3.StringUtils.normalizeSpace(path)); // Paper - Sanitize ResourceLocation error logging
} else {
return namespace;
}
@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private static String assertValidPath(String namespace, String path) {
if (!isValidPath(path)) {
- throw new ResourceLocationException("Non [a-z0-9/._-] character in path of location: " + namespace + ":" + path);
+ throw new ResourceLocationException("Non [a-z0-9/._-] character in path of location: " + namespace + ":" + org.apache.commons.lang3.StringUtils.normalizeSpace(path)); // Paper
+ throw new ResourceLocationException("Non [a-z0-9/._-] character in path of location: " + namespace + ":" + org.apache.commons.lang3.StringUtils.normalizeSpace(path)); // Paper - Sanitize ResourceLocation error logging
} else {
return path;
}

View file

@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ implementation("com.velocitypowered:velocity-native:3.1.2-SNAPSHOT") {
+ isTransitive = false
+ }
+ // Paper end
+ // Paper end - Use Velocity cipher
runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6")
runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
@ -29,17 +29,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class CipherDecoder extends MessageToMessageDecoder<ByteBuf> {
- private final CipherBase cipher;
+ private final com.velocitypowered.natives.encryption.VelocityCipher cipher; // Paper
+ private final com.velocitypowered.natives.encryption.VelocityCipher cipher; // Paper - Use Velocity cipher
- public CipherDecoder(Cipher cipher) {
- this.cipher = new CipherBase(cipher);
+ public CipherDecoder(com.velocitypowered.natives.encryption.VelocityCipher cipher) { // Paper
+ this.cipher = cipher; // Paper
+ public CipherDecoder(com.velocitypowered.natives.encryption.VelocityCipher cipher) { // Paper - Use Velocity cipher
+ this.cipher = cipher; // Paper - Use Velocity cipher
}
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
- list.add(this.cipher.decipher(channelHandlerContext, byteBuf));
+ // Paper start
+ // Paper start - Use Velocity cipher
+ ByteBuf compatible = com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible(channelHandlerContext.alloc(), cipher, byteBuf);
+ try {
+ cipher.process(compatible);
@ -48,15 +48,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ compatible.release(); // compatible will never be used if we throw an exception
+ throw e;
+ }
+ // Paper end
+ // Paper end - Use Velocity cipher
}
+
+ // Paper start
+ // Paper start - Use Velocity cipher
+ @Override
+ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
+ cipher.close();
+ }
+ // Paper end
+ // Paper end - Use Velocity cipher
}
diff --git a/src/main/java/net/minecraft/network/CipherEncoder.java b/src/main/java/net/minecraft/network/CipherEncoder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@ -70,19 +70,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
-public class CipherEncoder extends MessageToByteEncoder<ByteBuf> {
- private final CipherBase cipher;
+public class CipherEncoder extends io.netty.handler.codec.MessageToMessageEncoder<ByteBuf> { // Paper - change superclass
+ private final com.velocitypowered.natives.encryption.VelocityCipher cipher; // Paper
+public class CipherEncoder extends io.netty.handler.codec.MessageToMessageEncoder<ByteBuf> { // Paper - Use Velocity cipher; change superclass
+ private final com.velocitypowered.natives.encryption.VelocityCipher cipher; // Paper - Use Velocity cipher
- public CipherEncoder(Cipher cipher) {
- this.cipher = new CipherBase(cipher);
+ public CipherEncoder(com.velocitypowered.natives.encryption.VelocityCipher cipher) { // Paper
+ this.cipher = cipher; // Paper
+ public CipherEncoder(com.velocitypowered.natives.encryption.VelocityCipher cipher) { // Paper - Use Velocity cipher
+ this.cipher = cipher; // Paper - Use Velocity cipher
}
- protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, ByteBuf byteBuf2) throws Exception {
- this.cipher.encipher(byteBuf, byteBuf2);
+ protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
+ // Paper start
+ // Paper start - Use Velocity cipher
+ ByteBuf compatible = com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible(channelHandlerContext.alloc(), cipher, byteBuf);
+ try {
+ cipher.process(compatible);
@ -91,15 +91,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ compatible.release(); // compatible will never be used if we throw an exception
+ throw e;
+ }
+ // Paper end
+ // Paper end - Use Velocity cipher
}
+
+ // Paper start
+ // Paper start - Use Velocity cipher
+ @Override
+ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
+ cipher.close();
+ }
+ // Paper end
+ // Paper end - Use Velocity cipher
}
diff --git a/src/main/java/net/minecraft/network/CompressionDecoder.java b/src/main/java/net/minecraft/network/CompressionDecoder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@ -109,11 +109,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public static final int MAXIMUM_COMPRESSED_LENGTH = 2097152;
public static final int MAXIMUM_UNCOMPRESSED_LENGTH = 8388608;
private final Inflater inflater;
+ private final com.velocitypowered.natives.compression.VelocityCompressor compressor; // Paper
+ private final com.velocitypowered.natives.compression.VelocityCompressor compressor; // Paper - Use Velocity cipher
private int threshold;
private boolean validateDecompressed;
+ // Paper start
+ // Paper start - Use Velocity cipher
public CompressionDecoder(int compressionThreshold, boolean rejectsBadPackets) {
+ this(null, compressionThreshold, rejectsBadPackets);
+ }
@ -123,7 +123,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- this.inflater = new Inflater();
+ this.inflater = compressor == null ? new Inflater() : null;
+ this.compressor = compressor;
+ // Paper end
+ // Paper end - Use Velocity cipher
}
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
@ -131,15 +131,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
}
+ if (inflater != null) { // Paper - use velocity compression - fallback to vanilla inflater
+ if (inflater != null) { // Paper - Use Velocity cipher; fallback to vanilla inflater
this.setupInflaterInput(byteBuf);
ByteBuf byteBuf2 = this.inflate(channelHandlerContext, i);
this.inflater.reset();
list.add(byteBuf2);
+ return; // Paper - use velocity compression
+ return; // Paper - Use Velocity cipher
+ } // Paper - use velocity compression
+
+ // Paper start - use velocity compression
+ // Paper start - Use Velocity cipher
+ int claimedUncompressedSize = i; // OBFHELPER
+ ByteBuf compatibleIn = com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible(channelHandlerContext.alloc(), this.compressor, byteBuf);
+ ByteBuf uncompressed = com.velocitypowered.natives.util.MoreByteBufUtils.preferredBuffer(channelHandlerContext.alloc(), this.compressor, claimedUncompressedSize);
@ -153,19 +153,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } finally {
+ compatibleIn.release();
+ }
+ // Paper end - use velocity compression
+ // Paper end - Use Velocity cipher
}
}
}
+ // Paper start
+ // Paper start - Use Velocity cipher
+ @Override
+ public void handlerRemoved0(ChannelHandlerContext ctx) throws Exception {
+ if (this.compressor != null) {
+ this.compressor.close();
+ }
+ }
+ // Paper end
+ // Paper end - Use Velocity cipher
+
private void setupInflaterInput(ByteBuf buf) {
ByteBuffer byteBuffer;
@ -179,12 +179,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class CompressionEncoder extends MessageToByteEncoder<ByteBuf> {
- private final byte[] encodeBuf = new byte[8192];
+ private final byte[] encodeBuf; // Paper
+ private final byte[] encodeBuf; // Paper - Use Velocity cipher
private final Deflater deflater;
+ private final com.velocitypowered.natives.compression.VelocityCompressor compressor; // Paper
+ private final com.velocitypowered.natives.compression.VelocityCompressor compressor; // Paper - Use Velocity cipher
private int threshold;
+ // Paper start
+ // Paper start - Use Velocity cipher
public CompressionEncoder(int compressionThreshold) {
+ this(null, compressionThreshold);
+ }
@ -199,17 +199,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.deflater = null;
+ }
+ this.compressor = compressor;
+ // Paper end
+ // Paper end - Use Velocity cipher
}
- protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, ByteBuf byteBuf2) {
+ protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, ByteBuf byteBuf2) throws Exception { // Paper
+ protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, ByteBuf byteBuf2) throws Exception { // Paper - Use Velocity cipher
int i = byteBuf.readableBytes();
if (i < this.threshold) {
VarInt.write(byteBuf2, 0);
byteBuf2.writeBytes(byteBuf);
} else {
+ // Paper start
+ // Paper start - Use Velocity cipher
+ if (this.deflater != null) {
byte[] bs = new byte[i];
byteBuf.readBytes(bs);
@ -228,12 +228,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } finally {
+ compatibleIn.release();
+ }
+ // Paper end
+ // Paper end - Use Velocity cipher
}
}
+ // Paper start
+ // Paper start - Use Velocity cipher
+ @Override
+ protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, ByteBuf msg, boolean preferDirect) throws Exception{
+ if (this.compressor != null) {
@ -258,7 +258,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.compressor.close();
+ }
+ }
+ // Paper end
+ // Paper end - Use Velocity cipher
+
public int getThreshold() {
return this.threshold;
@ -275,7 +275,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- this.encrypted = true;
- this.channel.pipeline().addBefore("splitter", "decrypt", new CipherDecoder(decryptionCipher));
- this.channel.pipeline().addBefore("prepender", "encrypt", new CipherEncoder(encryptionCipher));
+ // Paper start
+ // Paper start - Use Velocity cipher
+// public void setEncryptionKey(Cipher decryptionCipher, Cipher encryptionCipher) {
+// this.encrypted = true;
+// this.channel.pipeline().addBefore("splitter", "decrypt", new CipherDecoder(decryptionCipher));
@ -296,7 +296,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
}
+ // Paper end
+ // Paper end - Use Velocity cipher
public boolean isEncrypted() {
return this.encrypted;
@ -304,19 +304,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void setupCompression(int compressionThreshold, boolean rejectsBadPackets) {
if (compressionThreshold >= 0) {
+ com.velocitypowered.natives.compression.VelocityCompressor compressor = com.velocitypowered.natives.util.Natives.compress.get().create(io.papermc.paper.configuration.GlobalConfiguration.get().misc.compressionLevel.or(-1)); // Paper
+ com.velocitypowered.natives.compression.VelocityCompressor compressor = com.velocitypowered.natives.util.Natives.compress.get().create(io.papermc.paper.configuration.GlobalConfiguration.get().misc.compressionLevel.or(-1)); // Paper - Use Velocity cipher
if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder) {
((CompressionDecoder) this.channel.pipeline().get("decompress")).setThreshold(compressionThreshold, rejectsBadPackets);
} else {
- this.channel.pipeline().addBefore("decoder", "decompress", new CompressionDecoder(compressionThreshold, rejectsBadPackets));
+ this.channel.pipeline().addBefore("decoder", "decompress", new CompressionDecoder(compressor, compressionThreshold, rejectsBadPackets)); // Paper
+ this.channel.pipeline().addBefore("decoder", "decompress", new CompressionDecoder(compressor, compressionThreshold, rejectsBadPackets)); // Paper - Use Velocity cipher
}
if (this.channel.pipeline().get("compress") instanceof CompressionEncoder) {
((CompressionEncoder) this.channel.pipeline().get("compress")).setThreshold(compressionThreshold);
} else {
- this.channel.pipeline().addBefore("encoder", "compress", new CompressionEncoder(compressionThreshold));
+ this.channel.pipeline().addBefore("encoder", "compress", new CompressionEncoder(compressor, compressionThreshold)); // Paper
+ this.channel.pipeline().addBefore("encoder", "compress", new CompressionEncoder(compressor, compressionThreshold)); // Paper - Use Velocity cipher
}
this.channel.pipeline().fireUserEventTriggered(io.papermc.paper.network.ConnectionEvent.COMPRESSION_THRESHOLD_SET); // Paper
} else {
@ -328,10 +328,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ServerConnectionListener.LOGGER.info("Using default channel type");
}
+ // Paper start - indicate Velocity natives in use
+ // Paper start - Use Velocity cipher
+ ServerConnectionListener.LOGGER.info("Paper: Using " + com.velocitypowered.natives.util.Natives.compress.getLoadedVariant() + " compression from Velocity.");
+ ServerConnectionListener.LOGGER.info("Paper: Using " + com.velocitypowered.natives.util.Natives.cipher.getLoadedVariant() + " cipher from Velocity.");
+ // Paper end
+ // Paper end - Use Velocity cipher
+
this.channels.add(((ServerBootstrap) ((ServerBootstrap) (new ServerBootstrap()).channel(oclass)).childHandler(new ChannelInitializer<Channel>() {
protected void initChannel(Channel channel) {
@ -346,15 +346,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
SecretKey secretkey = packet.getSecretKey(privatekey);
- Cipher cipher = Crypt.getCipher(2, secretkey);
- Cipher cipher1 = Crypt.getCipher(1, secretkey);
+ // Paper start
+ // Paper start - Use Velocity cipher
+// Cipher cipher = Crypt.getCipher(2, secretkey);
+// Cipher cipher1 = Crypt.getCipher(1, secretkey);
+ // Paper end
+ // Paper end - Use Velocity cipher
s = (new BigInteger(Crypt.digestData("", this.server.getKeyPair().getPublic(), secretkey))).toString(16);
this.state = ServerLoginPacketListenerImpl.State.AUTHENTICATING;
- this.connection.setEncryptionKey(cipher, cipher1);
+ this.connection.setupEncryption(secretkey); // Paper
+ this.connection.setupEncryption(secretkey); // Paper - Use Velocity cipher
} catch (CryptException cryptographyexception) {
throw new IllegalStateException("Protocol error", cryptographyexception);
}

View file

@ -17,18 +17,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import java.util.function.Predicate;
public abstract class ArgumentBuilder<S, T extends ArgumentBuilder<S, T>> {
+ // Paper start
+ // Paper start - Vanilla command permission fixes
+ private static final Predicate<Object> DEFAULT_REQUIREMENT = s -> true;
+
+ @SuppressWarnings("unchecked")
+ public static <S> Predicate<S> defaultRequirement() {
+ return (Predicate<S>) DEFAULT_REQUIREMENT;
+ }
+ // Paper end
+ // Paper end - Vanilla command permission fixes
private final RootCommandNode<S> arguments = new RootCommandNode<>();
private Command<S> command;
- private Predicate<S> requirement = s -> true;
+ private Predicate<S> requirement = defaultRequirement(); // Paper
+ private Predicate<S> requirement = defaultRequirement(); // Paper - Vanilla command permission fixes
private CommandNode<S> target;
private RedirectModifier<S> modifier = null;
private boolean forks;
@ -40,13 +40,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
this.vanillaCommandNodes.addAll(this.dispatcher.getRoot().getChildren()); // Paper
+ // Paper start
+ // Paper start - Vanilla command permission fixes
+ for (final CommandNode<CommandSourceStack> node : this.dispatcher.getRoot().getChildren()) {
+ if (node.getRequirement() == com.mojang.brigadier.builder.ArgumentBuilder.<CommandSourceStack>defaultRequirement()) {
+ node.requirement = stack -> stack.source == CommandSource.NULL || stack.getBukkitSender().hasPermission(org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(node));
+ }
+ }
+ // Paper end
+ // Paper end - Vanilla command permission fixes
// CraftBukkit start
}
@ -59,7 +59,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public static String getPermission(CommandNode<CommandSourceStack> vanillaCommand) {
- return "minecraft.command." + ((vanillaCommand.getRedirect() == null) ? vanillaCommand.getName() : vanillaCommand.getRedirect().getName());
+ // Paper start
+ // Paper start - Vanilla command permission fixes
+ final String commandName;
+ if (vanillaCommand.getRedirect() == null) {
+ commandName = vanillaCommand.getName();
@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return maybeNamespaced.substring(prefix.length());
+ }
+ return maybeNamespaced;
+ // Paper end
+ // Paper end - Vanilla command permission fixes
}
private String toDispatcher(String[] args, String name) {

View file

@ -12,12 +12,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public <T> Optional<T> evaluate(BiFunction<Level, BlockPos, T> getter) {
return Optional.empty();
}
+ // Paper start
+ // Paper start - fix menus with empty level accesses
+ @Override
+ public org.bukkit.Location getLocation() {
+ return null;
+ }
+ // Paper end
+ // Paper end - fix menus with empty level accesses
};
static ContainerLevelAccess create(final Level world, final BlockPos pos) {

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (!world.isClientSide && player.canUseGameMasterBlocks()) {
+ if (player.getItemInHand(hand).getItem() != Items.LIGHT || !player.mayInteract(world, pos) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return InteractionResult.FAIL; } // Paper
+ if (player.getItemInHand(hand).getItem() != Items.LIGHT || !player.mayInteract(world, pos) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return InteractionResult.FAIL; } // Paper - Prevent unintended light block manipulation
world.setBlock(pos, state.cycle(LEVEL), 2);
return InteractionResult.SUCCESS;
} else {