Merge remote-tracking branch 'upstream/main'
This commit is contained in:
@@ -354,7 +354,7 @@ index 0000000000000000000000000000000000000000..ae2bb9a73106febfe5f0d090abd4252b
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 7b5ed00c9b2f22af5cbc44171192d674936dc7d7..5fe3c9a159908785e08fa874982bc1a82283bb1d 100644
|
||||
index d51645b115780dac9ff6010806e8bd62dedc8e9f..3faf1b5556c55f3468182f75b2dbff4aaa3aae3a 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableList;
|
||||
@@ -484,7 +484,7 @@ index c70a58f5f633fa8e255f74c42f5e87c96b7b013a..ec20a5a6d7c8f65abda528fec36bec7b
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index f961540a00bfb5e1c8eb0e739f8ae535e9eee8f3..7453ddb09f349b7836f966573e4933646a75cba6 100644
|
||||
index 75f81a6bc156a6455a616b8de0d7701fd2255a2d..b3d951670b3a097d04cfe347d7df496b1d0a0e09 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -409,6 +409,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -661,10 +661,10 @@ index 3f780276be6766ef253c50212e06fd93a96b0caa..7e70c7bee633c54497d1cd2854dd60f4
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index 548d7c8dc517da6c4db86b11f579ae63e6db56cf..a29860af4c37b2b45df49f9ba18f7e38921dfb02 100644
|
||||
index fca31bbab8e7830933ceffcf992ff56ccc84414c..51804b611f469f2ab53e455e8c633b867b00cc88 100644
|
||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -121,6 +121,29 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
@@ -129,6 +129,29 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
return 0.04;
|
||||
}
|
||||
|
||||
@@ -695,7 +695,7 @@ index 548d7c8dc517da6c4db86b11f579ae63e6db56cf..a29860af4c37b2b45df49f9ba18f7e38
|
||||
public void tick() {
|
||||
if (this.getItem().isEmpty()) {
|
||||
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
|
||||
index b0607f4a9b35570b319423c7876bb904d5154e8e..98c8653647dc52059d8becfe38a74d4e62edf08f 100644
|
||||
index ef8347329b440833b45a54be2b6e4204ac0a425e..43f16df230f87a43e249a58fc10ef2da517f22ee 100644
|
||||
--- a/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -269,11 +269,35 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
@@ -838,7 +838,7 @@ index 52acc72841f0c6980f5f3f8ef21d0b29dd472ce3..41a6ec508a10a49a37539d2f10171d15
|
||||
+
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index d26e4d85d8fd8bd4f0c7de30b50a2ce370b37bf5..bab28e7afb7b1249d40631aabff16fc18cf95ea0 100644
|
||||
index 06069d3ac598f5f12feab038de4f1199794298f6..980eaba27ce2616c1573a4760cf4acc2dd251190 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -143,6 +143,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Anti-Xray
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java
|
||||
index 55cc0dec4a88baea17f160e95d5d8316e0bb7a50..338dc0fb07cdba5f7350cca332fa3e942c622bfb 100644
|
||||
index 811a8e5141f2061a185b53b63d951646141c0c7d..33d3eb510c5844e72bbc382bd24641aae080962d 100644
|
||||
--- a/io/papermc/paper/FeatureHooks.java
|
||||
+++ b/io/papermc/paper/FeatureHooks.java
|
||||
@@ -40,20 +40,25 @@ public final class FeatureHooks {
|
||||
@@ -45,20 +45,25 @@ public final class FeatureHooks {
|
||||
}
|
||||
|
||||
public static LevelChunkSection createSection(final Registry<Biome> biomeRegistry, final Level level, final ChunkPos chunkPos, final int chunkSection) {
|
||||
|
||||
@@ -14,17 +14,17 @@ movement will load only the chunk the player enters anyways and avoids loading
|
||||
massive amounts of surrounding chunks due to large AABB lookups.
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 7453ddb09f349b7836f966573e4933646a75cba6..58eda0d6426f30cda604f4120f1ddb012316c108 100644
|
||||
index 23dfc87db1d5e90099270627197abc0f787a4393..27a01fd28ea565221768f31df02f0a2ddf242fce 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -229,6 +229,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
// Paper end - Share random for entities to make them more random
|
||||
@@ -230,6 +230,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
public @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason
|
||||
|
||||
private volatile @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; // Paper - Folia schedulers - volatile
|
||||
+ public boolean collisionLoadChunks = false; // Paper
|
||||
private @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity;
|
||||
|
||||
public org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntity() {
|
||||
if (this.bukkitEntity == null) {
|
||||
diff --git a/net/minecraft/world/level/BlockCollisions.java b/net/minecraft/world/level/BlockCollisions.java
|
||||
index ed6e4f9fd0c7ad1219e66bc1cb4038191dd6edd8..45a20dbb935b12d429153463dba5d6fd3385dd7a 100644
|
||||
--- a/net/minecraft/world/level/BlockCollisions.java
|
||||
|
||||
@@ -32481,7 +32481,7 @@ index 0000000000000000000000000000000000000000..b028017b9c44821a8a313a04e0b10f5d
|
||||
+ }
|
||||
+}
|
||||
diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
index 0c611598a6912b692a7639301811ee557e2304f1..6f65564f6a6e99d6549de9a23a031b1f4a8a9798 100644
|
||||
index e4f0653c575c33b1ef8160b6c88e29ee9fb44508..b6a34796d33f1593301c3a67a013fa7e812cb329 100644
|
||||
--- a/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
@@ -211,6 +211,43 @@ public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHo
|
||||
@@ -32542,7 +32542,7 @@ index 6536dc08c80170f5679acedd65cd2b9f6ad3fb3a..294cd15a796ad25823c8ccf98fbfae46
|
||||
return structureTemplate.save(new CompoundTag());
|
||||
}
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 794a01ee70a2a30d91550f5265f774ba73828cf9..c716521fb1497dc8a22d827ddb50fc1cc21a05f4 100644
|
||||
index 2d597e50dcd957bd566c4da384fac5f36b5362f7..75aba65cbe1a943f21c7464ff9465e64f63e8e5b 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -305,6 +305,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -32585,10 +32585,10 @@ index 8c1417c659ea0e079e99b9bfa79e1cf6ba9b712b..a8a32edea080f32fd25c9e009d4efa41
|
||||
if (stopBelowZero) {
|
||||
chunkData.putString("Status", net.minecraft.core.registries.BuiltInRegistries.CHUNK_STATUS.getKey(net.minecraft.world.level.chunk.status.ChunkStatus.SPAWN).toString());
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
|
||||
index 6be673172548c1382c7402ec4e1ec6ef51f702d3..18750f1ea3101b6c0ab0b8e33c304eb7fa1ed04d 100644
|
||||
index 6be673172548c1382c7402ec4e1ec6ef51f702d3..49be43ac896d60587511a97445c53c10c587a341 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
|
||||
@@ -32,13 +32,30 @@ public class SimpleRegionStorage implements AutoCloseable {
|
||||
@@ -32,13 +32,32 @@ public class SimpleRegionStorage implements AutoCloseable {
|
||||
return this.worker.store(chunkPos, data);
|
||||
}
|
||||
|
||||
@@ -32609,7 +32609,9 @@ index 6be673172548c1382c7402ec4e1ec6ef51f702d3..18750f1ea3101b6c0ab0b8e33c304eb7
|
||||
- return this.dataFixType.updateToCurrentVersion(this.fixerUpper, tag, dataVersion);
|
||||
+ // Paper start - rewrite data conversion system
|
||||
+ final int dataVer = NbtUtils.getDataVersion(tag, version);
|
||||
+ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(this.getDataConverterType(), tag, dataVer, ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion());
|
||||
+ final CompoundTag ret = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(this.getDataConverterType(), tag, dataVer, ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion());
|
||||
+ NbtUtils.addCurrentDataVersion(ret); // Fix MC-299110
|
||||
+ return ret;
|
||||
+ // Paper end - rewrite data conversion system
|
||||
}
|
||||
|
||||
|
||||
@@ -23061,7 +23061,7 @@ index 0000000000000000000000000000000000000000..f1f72a051083b61273202cb4e67ecb11
|
||||
+ private SaveUtil() {}
|
||||
+}
|
||||
diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java
|
||||
index 338dc0fb07cdba5f7350cca332fa3e942c622bfb..e1fe49e4bf014e2405708270efd81bab4e1512da 100644
|
||||
index b1a7af2dd3a3e166b1e58125f13ce08b9ec6d9ff..df6fbb35e5023b42de0b97434712e04a6b3e66a3 100644
|
||||
--- a/io/papermc/paper/FeatureHooks.java
|
||||
+++ b/io/papermc/paper/FeatureHooks.java
|
||||
@@ -1,6 +1,9 @@
|
||||
@@ -23074,8 +23074,13 @@ index 338dc0fb07cdba5f7350cca332fa3e942c622bfb..e1fe49e4bf014e2405708270efd81bab
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import it.unimi.dsi.fastutil.longs.LongSets;
|
||||
@@ -31,12 +34,16 @@ import org.bukkit.World;
|
||||
public final class FeatureHooks {
|
||||
@@ -32,16 +35,20 @@ public final class FeatureHooks {
|
||||
|
||||
// this includes non-accessible entities
|
||||
public static Iterable<Entity> getAllEntities(final net.minecraft.server.level.ServerLevel world) {
|
||||
- return ((net.minecraft.world.level.entity.LevelEntityGetterAdapter<Entity>)world.getEntities()).sectionStorage.getAllEntities();
|
||||
+ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup)world.getEntities()).getAllMapped(); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
public static void setPlayerChunkUnloadDelay(final long ticks) {
|
||||
+ ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.setUnloadDelay(ticks); // Paper - rewrite chunk system
|
||||
@@ -23091,7 +23096,7 @@ index 338dc0fb07cdba5f7350cca332fa3e942c622bfb..e1fe49e4bf014e2405708270efd81bab
|
||||
}
|
||||
|
||||
public static LevelChunkSection createSection(final Registry<Biome> biomeRegistry, final Level level, final ChunkPos chunkPos, final int chunkSection) {
|
||||
@@ -62,111 +69,58 @@ public final class FeatureHooks {
|
||||
@@ -67,111 +74,58 @@ public final class FeatureHooks {
|
||||
}
|
||||
|
||||
public static Set<Long> getSentChunkKeys(final ServerPlayer player) {
|
||||
@@ -23224,7 +23229,7 @@ index 338dc0fb07cdba5f7350cca332fa3e942c622bfb..e1fe49e4bf014e2405708270efd81bab
|
||||
|
||||
org.bukkit.Chunk chunk = null;
|
||||
for (net.minecraft.server.level.Ticket ticket : tickets) {
|
||||
@@ -186,15 +140,15 @@ public final class FeatureHooks {
|
||||
@@ -191,15 +145,15 @@ public final class FeatureHooks {
|
||||
}
|
||||
|
||||
public static int getViewDistance(net.minecraft.server.level.ServerLevel world) {
|
||||
@@ -23243,7 +23248,7 @@ index 338dc0fb07cdba5f7350cca332fa3e942c622bfb..e1fe49e4bf014e2405708270efd81bab
|
||||
}
|
||||
|
||||
public static void setViewDistance(net.minecraft.server.level.ServerLevel world, int distance) {
|
||||
@@ -212,35 +166,31 @@ public final class FeatureHooks {
|
||||
@@ -217,35 +171,31 @@ public final class FeatureHooks {
|
||||
}
|
||||
|
||||
public static void setSendViewDistance(net.minecraft.server.level.ServerLevel world, int distance) {
|
||||
@@ -23286,6 +23291,7 @@ index 338dc0fb07cdba5f7350cca332fa3e942c622bfb..e1fe49e4bf014e2405708270efd81bab
|
||||
}
|
||||
|
||||
}
|
||||
\ No newline at end of file
|
||||
diff --git a/io/papermc/paper/command/subcommands/ChunkDebugCommand.java b/io/papermc/paper/command/subcommands/ChunkDebugCommand.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2dca7afbd93cfbb8686f336fcd3b45dd01fba0fc
|
||||
@@ -23861,7 +23867,7 @@ index 46de98a6bbbae48c4837e1e588ba198a363d2dde..fd3553bdc1c3cdbf6aa3dc00e0a4987f
|
||||
thread1 -> {
|
||||
DedicatedServer dedicatedServer1 = new DedicatedServer(
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787fb963eef4 100644
|
||||
index 75aba65cbe1a943f21c7464ff9465e64f63e8e5b..32475c0958fd7e0f1f9b494b0cc78a4a718d12b8 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -173,7 +173,7 @@ import net.minecraft.world.phys.Vec2;
|
||||
@@ -23960,7 +23966,7 @@ index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787f
|
||||
this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(serverLevel.getWorld()));
|
||||
}
|
||||
|
||||
@@ -844,6 +915,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -845,6 +916,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public abstract boolean shouldRconBroadcast();
|
||||
|
||||
public boolean saveAllChunks(boolean suppressLog, boolean flush, boolean forced) {
|
||||
@@ -23972,7 +23978,7 @@ index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787f
|
||||
boolean flag = false;
|
||||
|
||||
for (ServerLevel serverLevel : this.getAllLevels()) {
|
||||
@@ -851,7 +927,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -852,7 +928,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
LOGGER.info("Saving chunks for level '{}'/{}", serverLevel, serverLevel.dimension().location());
|
||||
}
|
||||
|
||||
@@ -23981,7 +23987,7 @@ index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787f
|
||||
flag = true;
|
||||
}
|
||||
|
||||
@@ -944,7 +1020,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -945,7 +1021,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23990,7 +23996,7 @@ index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787f
|
||||
this.nextTickTimeNanos = Util.getNanos() + TimeUtil.NANOSECONDS_PER_MILLISECOND;
|
||||
|
||||
for (ServerLevel serverLevelx : this.getAllLevels()) {
|
||||
@@ -954,18 +1030,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -955,18 +1031,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
this.waitUntilNextTick();
|
||||
}
|
||||
@@ -24016,7 +24022,7 @@ index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787f
|
||||
|
||||
this.isSaving = false;
|
||||
this.resources.close();
|
||||
@@ -985,6 +1057,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -986,6 +1058,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.getProfileCache().save(false); // Paper - Perf: Async GameProfileCache saving
|
||||
}
|
||||
// Spigot end
|
||||
@@ -24031,7 +24037,7 @@ index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787f
|
||||
// Paper start - Improved watchdog support - move final shutdown items here
|
||||
Util.shutdownExecutors();
|
||||
try {
|
||||
@@ -1169,6 +1249,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1170,6 +1250,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
profilerFiller.push("tick");
|
||||
this.tickFrame.start();
|
||||
this.tickServer(flag ? () -> false : this::haveTime);
|
||||
@@ -24045,7 +24051,7 @@ index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787f
|
||||
this.tickFrame.end();
|
||||
profilerFiller.popPush("nextTickWait");
|
||||
this.mayHaveDelayedTasks = true;
|
||||
@@ -1339,6 +1426,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1340,6 +1427,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
private boolean pollTaskInternal() {
|
||||
if (super.pollTask()) {
|
||||
@@ -24053,7 +24059,7 @@ index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787f
|
||||
return true;
|
||||
} else {
|
||||
boolean ret = false; // Paper - force execution of all worlds, do not just bias the first
|
||||
@@ -2468,6 +2556,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -2478,6 +2566,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24067,7 +24073,7 @@ index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787f
|
||||
// CraftBukkit start
|
||||
public boolean isDebugging() {
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 5db176be3bd31eb886a541eeaee922ee30ee9908..5fea5e2e9fc10d348fa3e65cd354ef6a4a717a4d 100644
|
||||
index 4488d0a2f05ef07afab0f9a1483f54b21757b29e..98927d4a5fba2a0dcdb147ac10b82c3286ccdc6b 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -391,7 +391,33 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
@@ -27685,7 +27691,7 @@ index 49008b4cbaead8a66a93d2b0d4b50b335a6c3eed..f9c96bbdc54e68b9216b7f8662bfae03
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 69dbff3f62e3a9ba7090156380f842bb44deebf8..c0b74d408340101bc3aac4cb4b7232c5cc78b08a 100644
|
||||
index 6f7f92cc43c56a7453b289f205502d089474ef6d..b390ba657b8b880e431c84e9dd948ac9c84af2fd 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -193,7 +193,7 @@ import net.minecraft.world.scores.Team;
|
||||
@@ -28722,7 +28728,7 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896
|
||||
+ // Paper end - block counting
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index fa2ffc44336c3ddfe576b202154f14ef91a301b9..7546ff4c5ffc62d93a3f874519db8fef1e3bfbcb 100644
|
||||
index 06d07f93e42edcfdd7d69df0b52efe2a58e7dfc1..da880f52920b1101f23ef94f3fd0dbdea218c373 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -147,7 +147,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
|
||||
@@ -29430,7 +29436,7 @@ index fa2ffc44336c3ddfe576b202154f14ef91a301b9..7546ff4c5ffc62d93a3f874519db8fef
|
||||
if (!checkPosition(this, x, y, z)) {
|
||||
return;
|
||||
}
|
||||
@@ -4828,6 +5135,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -4818,6 +5125,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
|
||||
@Override
|
||||
public final void setRemoved(Entity.RemovalReason removalReason, @Nullable org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { // CraftBukkit - add Bukkit remove cause
|
||||
@@ -29443,7 +29449,7 @@ index fa2ffc44336c3ddfe576b202154f14ef91a301b9..7546ff4c5ffc62d93a3f874519db8fef
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit
|
||||
final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers
|
||||
if (this.removalReason == null) {
|
||||
@@ -4838,7 +5151,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -4828,7 +5141,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.stopRiding();
|
||||
}
|
||||
|
||||
@@ -29452,7 +29458,7 @@ index fa2ffc44336c3ddfe576b202154f14ef91a301b9..7546ff4c5ffc62d93a3f874519db8fef
|
||||
this.levelCallback.onRemove(removalReason);
|
||||
this.onRemoval(removalReason);
|
||||
// Paper start - Folia schedulers
|
||||
@@ -4872,7 +5185,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -4862,7 +5175,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
public boolean shouldBeSaved() {
|
||||
return (this.removalReason == null || this.removalReason.shouldSave())
|
||||
&& !this.isPassenger()
|
||||
@@ -34311,7 +34317,7 @@ index 15417fab103feec3c1f7d5bd5b332e89d3ace3f5..2e6263d8b466e0f61bc72eb818044734
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
|
||||
index 18750f1ea3101b6c0ab0b8e33c304eb7fa1ed04d..bf708ff89ea1f2c7279e48c41c4f44abc77ceebb 100644
|
||||
index 49be43ac896d60587511a97445c53c10c587a341..1b070cf7e3612dbcb170cf5d954eba5f5b3c777c 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
|
||||
@@ -14,7 +14,7 @@ import net.minecraft.util.datafix.DataFixTypes;
|
||||
@@ -36675,10 +36681,10 @@ index c634d795644be86ad85395ffa39fbac33bf7418b..66d0a6390febe929ef774b0a78133290
|
||||
|
||||
for (SavedTick<T> savedTick : this.pendingTicks) {
|
||||
diff --git a/net/minecraft/world/waypoints/WaypointTransmitter.java b/net/minecraft/world/waypoints/WaypointTransmitter.java
|
||||
index b579839c03b371d408e3750ec09af7da1d7bc9a0..9b41c62afc861847571ad739d1dd848b8276230c 100644
|
||||
index 47382efcd50f29601a6623876be50c4d047336c5..5d1c933dfa862d0733777d305563a89ea7827f07 100644
|
||||
--- a/net/minecraft/world/waypoints/WaypointTransmitter.java
|
||||
+++ b/net/minecraft/world/waypoints/WaypointTransmitter.java
|
||||
@@ -31,7 +31,10 @@ public interface WaypointTransmitter extends Waypoint {
|
||||
@@ -32,7 +32,10 @@ public interface WaypointTransmitter extends Waypoint {
|
||||
}
|
||||
|
||||
static boolean isChunkVisible(ChunkPos pos, ServerPlayer player) {
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Incremental chunk and player saving
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 80442494db670fec34df310390ea787fb963eef4..2dd512565ab901bf853f34b384155902b0fe8120 100644
|
||||
index 338ef549efe82c250c74365c1c1071986920c8c9..39581095ccc69d113d954ed835bdfa32d25b5489 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -954,7 +954,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -955,7 +955,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
boolean var4;
|
||||
try {
|
||||
this.isSaving = true;
|
||||
@@ -17,7 +17,7 @@ index 80442494db670fec34df310390ea787fb963eef4..2dd512565ab901bf853f34b384155902
|
||||
var4 = this.saveAllChunks(suppressLog, flush, forced);
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
@@ -1533,9 +1533,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1534,9 +1534,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
this.ticksUntilAutosave--;
|
||||
|
||||
@@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..24a2090e068ad3c0d08705050944abdf
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 2dd512565ab901bf853f34b384155902b0fe8120..d6dcb6d146d89a8fb96e7c669e5deb802223abd6 100644
|
||||
index cff9d761dfee8a90b19fb2f3e678f99a39fc000c..0a260fdf6b198a8ab52e60bf6db2fb5eab719c48 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1708,6 +1708,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1718,6 +1718,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
serverLevel.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
|
||||
serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent
|
||||
serverLevel.updateLagCompensationTick(); // Paper - lag compensation
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Tue, 24 Jun 2025 03:41:38 -0700
|
||||
Subject: [PATCH] Improve keepalive ping system
|
||||
|
||||
Send more keepalives, record all transactions within the last minute.
|
||||
We send more keepalives so that the latency calculation is more
|
||||
accurate. Since we send more keepalives, we track all pending
|
||||
keepalives in case multiple end up in flight.
|
||||
|
||||
Additionally, replace the latency calculation with a true
|
||||
average over the last 5 seconds of keepalive transactions.
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 53f038e1b5e7a13a08a0c925c8bd3f8a40868195..f3eca351021c37b64315872d075bd0a84aeee267 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -461,6 +461,70 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
return this.viewDistanceHolder;
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
+ // Paper start - improve keepalives
|
||||
+ public long lastKeepAliveTx = System.nanoTime();
|
||||
+ public static final record KeepAliveResponse(long txTimeNS, long rxTimeNS) {
|
||||
+ public long latencyNS() {
|
||||
+ return this.rxTimeNS - this.txTimeNS;
|
||||
+ }
|
||||
+ }
|
||||
+ public static final record PendingKeepAlive(long txTimeNS, long challengeId) {}
|
||||
+
|
||||
+ public final ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue<PendingKeepAlive> pendingKeepAlives = new ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue<>();
|
||||
+
|
||||
+ public final PingCalculator pingCalculator1m = new PingCalculator(java.util.concurrent.TimeUnit.MINUTES.toNanos(1L));
|
||||
+ public final PingCalculator pingCalculator5s = new PingCalculator(java.util.concurrent.TimeUnit.SECONDS.toNanos(5L));
|
||||
+
|
||||
+ public static final class PingCalculator {
|
||||
+
|
||||
+ private final long intervalNS;
|
||||
+ private final ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue<KeepAliveResponse> responses = new ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue<>();
|
||||
+
|
||||
+ private long timeSumNS;
|
||||
+ private int timeSumCount;
|
||||
+ private volatile long lastAverageNS;
|
||||
+
|
||||
+ public PingCalculator(long intervalNS) {
|
||||
+ this.intervalNS = intervalNS;
|
||||
+ }
|
||||
+
|
||||
+ public void update(KeepAliveResponse response) {
|
||||
+ long currTime = response.txTimeNS;
|
||||
+
|
||||
+ this.responses.add(response);
|
||||
+
|
||||
+ ++this.timeSumCount;
|
||||
+ this.timeSumNS += response.latencyNS();
|
||||
+
|
||||
+ // remove out-of-window times
|
||||
+ KeepAliveResponse removed;
|
||||
+ while ((removed = this.responses.pollIf((ka) -> (currTime - ka.txTimeNS) > this.intervalNS)) != null) {
|
||||
+ --this.timeSumCount;
|
||||
+ this.timeSumNS -= removed.latencyNS();
|
||||
+ }
|
||||
+
|
||||
+ this.lastAverageNS = this.timeSumNS / (long)this.timeSumCount;
|
||||
+ }
|
||||
+
|
||||
+ public int getAvgLatencyMS() {
|
||||
+ return (int)java.util.concurrent.TimeUnit.NANOSECONDS.toMillis(this.getAvgLatencyNS());
|
||||
+ }
|
||||
+
|
||||
+ public long getAvgLatencyNS() {
|
||||
+ return this.lastAverageNS;
|
||||
+ }
|
||||
+
|
||||
+ public it.unimi.dsi.fastutil.longs.LongArrayList getAllNS() {
|
||||
+ it.unimi.dsi.fastutil.longs.LongArrayList ret = new it.unimi.dsi.fastutil.longs.LongArrayList();
|
||||
+
|
||||
+ for (KeepAliveResponse response : this.responses) {
|
||||
+ ret.add(response.latencyNS());
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - improve keepalives
|
||||
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) {
|
||||
super(level, gameProfile);
|
||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index 85e01c3a1536b41a0301a5a6506e058ff9633a4a..43f70a5561d6cc62aaeba6d1e39598ecb382e369 100644
|
||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -38,12 +38,12 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
protected final MinecraftServer server;
|
||||
public final Connection connection; // Paper
|
||||
private final boolean transferred;
|
||||
- private long keepAliveTime;
|
||||
- private boolean keepAlivePending;
|
||||
- private long keepAliveChallenge;
|
||||
+ //private long keepAliveTime; // Paper - improve keepalives
|
||||
+ //private boolean keepAlivePending; // Paper - improve keepalives
|
||||
+ //private long keepAliveChallenge; // Paper - improve keepalives
|
||||
private long closedListenerTime;
|
||||
private boolean closed = false;
|
||||
- private int latency;
|
||||
+ private volatile int latency; // Paper - improve keepalives - make volatile
|
||||
private volatile boolean suspendFlushingOnServerThread = false;
|
||||
// CraftBukkit start
|
||||
protected final net.minecraft.server.level.ServerPlayer player;
|
||||
@@ -57,7 +57,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie, net.minecraft.server.level.ServerPlayer player) { // CraftBukkit
|
||||
this.server = server;
|
||||
this.connection = connection;
|
||||
- this.keepAliveTime = Util.getMillis();
|
||||
+ //this.keepAliveTime = Util.getMillis(); // Paper - improve keepalives
|
||||
this.latency = cookie.latency();
|
||||
this.transferred = cookie.transferred();
|
||||
// CraftBukkit start - add fields and methods
|
||||
@@ -120,13 +120,41 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
|
||||
@Override
|
||||
public void handleKeepAlive(ServerboundKeepAlivePacket packet) {
|
||||
- if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) {
|
||||
- int i = (int)(Util.getMillis() - this.keepAliveTime);
|
||||
- this.latency = (this.latency * 3 + i) / 4;
|
||||
- this.keepAlivePending = false;
|
||||
- } else if (!this.isSingleplayerOwner()) {
|
||||
- this.disconnectAsync(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - add proper async disconnect
|
||||
+ // Paper start - improve keepalives
|
||||
+ long now = System.nanoTime();
|
||||
+ net.minecraft.server.level.ServerPlayer.PendingKeepAlive pending = this.player.pendingKeepAlives.peek();
|
||||
+ if (pending != null && pending.challengeId() == packet.getId()) {
|
||||
+ this.player.pendingKeepAlives.remove(pending);
|
||||
+
|
||||
+ net.minecraft.server.level.ServerPlayer.KeepAliveResponse response = new net.minecraft.server.level.ServerPlayer.KeepAliveResponse(pending.txTimeNS(), now);
|
||||
+
|
||||
+ this.player.pingCalculator1m.update(response);
|
||||
+ this.player.pingCalculator5s.update(response);
|
||||
+
|
||||
+ this.latency = this.player.pingCalculator5s.getAvgLatencyMS();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (java.util.Iterator<net.minecraft.server.level.ServerPlayer.PendingKeepAlive> itr = this.player.pendingKeepAlives.iterator(); itr.hasNext();) {
|
||||
+ net.minecraft.server.level.ServerPlayer.PendingKeepAlive ka = itr.next();
|
||||
+ if (ka.challengeId() == packet.getId()) {
|
||||
+ itr.remove();
|
||||
+
|
||||
+ if (!this.processedDisconnect) {
|
||||
+ LOGGER.info("Disconnecting " + this.player.getScoreboardName() + " for sending keepalive response (" + packet.getId() + ") out-of-order!");
|
||||
+ this.disconnectAsync(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT);
|
||||
+ return;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (!this.processedDisconnect) {
|
||||
+ LOGGER.info("Disconnecting " + this.player.getScoreboardName() + " for sending keepalive response (" + packet.getId() + ") without matching challenge!");
|
||||
+ this.disconnectAsync(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - improve keepalives
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,20 +275,23 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
protected void keepConnectionAlive() {
|
||||
Profiler.get().push("keepAlive");
|
||||
long millis = Util.getMillis();
|
||||
- // Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
||||
- // This should effectively place the keepalive handling back to "as it was" before 1.12.2
|
||||
- final long elapsedTime = millis - this.keepAliveTime;
|
||||
- if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // use vanilla's 15000L between keep alive packets
|
||||
- if (this.keepAlivePending) {
|
||||
- if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
|
||||
- this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause
|
||||
- }
|
||||
- // Paper end - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
||||
- } else if (this.checkIfClosed(millis)) {
|
||||
- this.keepAlivePending = true;
|
||||
- this.keepAliveTime = millis;
|
||||
- this.keepAliveChallenge = millis;
|
||||
- this.send(new ClientboundKeepAlivePacket(this.keepAliveChallenge));
|
||||
+ // Paper start - improve keepalives
|
||||
+ if (this.checkIfClosed(millis) && !this.processedDisconnect) {
|
||||
+ long currTime = System.nanoTime();
|
||||
+
|
||||
+ if ((currTime - this.player.lastKeepAliveTx) >= java.util.concurrent.TimeUnit.SECONDS.toNanos(1L)) {
|
||||
+ this.player.lastKeepAliveTx = currTime;
|
||||
+
|
||||
+ net.minecraft.server.level.ServerPlayer.PendingKeepAlive pka = new net.minecraft.server.level.ServerPlayer.PendingKeepAlive(currTime, millis);
|
||||
+ this.player.pendingKeepAlives.add(pka);
|
||||
+ this.send(new ClientboundKeepAlivePacket(pka.challengeId()));
|
||||
+ }
|
||||
+
|
||||
+ net.minecraft.server.level.ServerPlayer.PendingKeepAlive oldest = this.player.pendingKeepAlives.peek();
|
||||
+ if (oldest != null && (currTime - oldest.txTimeNS()) > java.util.concurrent.TimeUnit.MILLISECONDS.toNanos(KEEPALIVE_LIMIT)) {
|
||||
+ LOGGER.warn(this.player.getScoreboardName() + " was kicked due to keepalive timeout!");
|
||||
+ this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT);
|
||||
+ // Paper end - improve keepalives
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Tue, 24 Jun 2025 07:05:51 -0700
|
||||
Subject: [PATCH] Optimise EntityScheduler ticking
|
||||
|
||||
The vast majority of the time, there are no tasks scheduled to
|
||||
the EntityScheduler. We can avoid iterating the entire entity list
|
||||
by tracking which schedulers have any tasks scheduled.
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java
|
||||
index 5f2deeb5cc01d8bbeb7449bd4e59c466b3dfdf57..82824ae7ffbced513a8bcace684af94916135e84 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java
|
||||
@@ -96,6 +96,7 @@ public final class ServerEntityLookup extends EntityLookup {
|
||||
if (entity instanceof ThrownEnderpearl enderpearl) {
|
||||
this.addEnderPearl(CoordinateUtils.getChunkKey(enderpearl.chunkPosition()));
|
||||
}
|
||||
+ entity.registerScheduler(); // Paper - optimise Folia entity scheduler
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 0a260fdf6b198a8ab52e60bf6db2fb5eab719c48..52fa5112cd90ba766c94512a02401dd3aee82cc9 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1654,33 +1654,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
+ public final io.papermc.paper.threadedregions.EntityScheduler.EntitySchedulerTickList entitySchedulerTickList = new io.papermc.paper.threadedregions.EntityScheduler.EntitySchedulerTickList(); // Paper - optimise Folia entity scheduler
|
||||
+
|
||||
protected void tickChildren(BooleanSupplier hasTimeLeft) {
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing());
|
||||
this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit
|
||||
- // Paper start - Folia scheduler API
|
||||
- ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) org.bukkit.Bukkit.getGlobalRegionScheduler()).tick();
|
||||
- for (ServerPlayer player : this.playerList.players) {
|
||||
- if (!this.playerList.players.contains(player)) {
|
||||
+ // Paper start - optimise Folia entity scheduler
|
||||
+ ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler)org.bukkit.Bukkit.getGlobalRegionScheduler()).tick();
|
||||
+ for (io.papermc.paper.threadedregions.EntityScheduler scheduler : this.entitySchedulerTickList.getAllSchedulers()) {
|
||||
+ if (scheduler.isRetired()) {
|
||||
continue;
|
||||
}
|
||||
- final org.bukkit.craftbukkit.entity.CraftEntity bukkit = player.getBukkitEntityRaw();
|
||||
- if (bukkit != null) {
|
||||
- bukkit.taskScheduler.executeTick();
|
||||
- }
|
||||
+
|
||||
+ scheduler.executeTick();
|
||||
}
|
||||
- getAllLevels().forEach(level -> {
|
||||
- for (final net.minecraft.world.entity.Entity entity : io.papermc.paper.FeatureHooks.getAllEntities(level)) {
|
||||
- if (entity.isRemoved() || entity instanceof ServerPlayer) {
|
||||
- continue;
|
||||
- }
|
||||
- final org.bukkit.craftbukkit.entity.CraftEntity bukkit = entity.getBukkitEntityRaw();
|
||||
- if (bukkit != null) {
|
||||
- bukkit.taskScheduler.executeTick();
|
||||
- }
|
||||
- }
|
||||
- });
|
||||
- // Paper end - Folia scheduler API
|
||||
+ // Paper end - optimise Folia entity scheduler
|
||||
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper
|
||||
profilerFiller.push("commandFunctions");
|
||||
this.getFunctions().tick();
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index da880f52920b1101f23ef94f3fd0dbdea218c373..3d2c0a4d3a1f9d3e5cc6cd0cdb988ae1205de821 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -5165,6 +5165,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.getBukkitEntity().taskScheduler.retire();
|
||||
}
|
||||
// Paper end - Folia schedulers
|
||||
+ // Paper start - optimise Folia entity scheduler
|
||||
+ public final void registerScheduler() {
|
||||
+ this.getBukkitEntity().taskScheduler.registerTo(net.minecraft.server.MinecraftServer.getServer().entitySchedulerTickList);
|
||||
+ }
|
||||
+ // Paper end - optimise Folia entity scheduler
|
||||
|
||||
@Override
|
||||
public void setLevelCallback(EntityInLevelCallback levelCallback) {
|
||||
@@ -1,6 +1,6 @@
|
||||
--- /dev/null
|
||||
+++ b/io/papermc/paper/FeatureHooks.java
|
||||
@@ -1,0 +_,241 @@
|
||||
@@ -1,0 +_,246 @@
|
||||
+package io.papermc.paper;
|
||||
+
|
||||
+import io.papermc.paper.command.PaperSubcommand;
|
||||
@@ -33,6 +33,11 @@
|
||||
+
|
||||
+public final class FeatureHooks {
|
||||
+
|
||||
+ // this includes non-accessible entities
|
||||
+ public static Iterable<Entity> getAllEntities(final net.minecraft.server.level.ServerLevel world) {
|
||||
+ return ((net.minecraft.world.level.entity.LevelEntityGetterAdapter<Entity>)world.getEntities()).sectionStorage.getAllEntities();
|
||||
+ }
|
||||
+
|
||||
+ public static void setPlayerChunkUnloadDelay(final long ticks) {
|
||||
+ }
|
||||
+
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -176,6 +_,11 @@
|
||||
@@ -170,12 +_,18 @@
|
||||
|
||||
@Override
|
||||
public boolean isRestricted(CommandNode<CommandSourceStack> node) {
|
||||
+ if (node.getRequirement() instanceof PermissionSource.RestrictedMarker) return true; // Paper - restricted api
|
||||
return node.getRequirement() instanceof PermissionCheck<?> permissionCheck && permissionCheck.requiredLevel() > 0;
|
||||
}
|
||||
};
|
||||
private final CommandDispatcher<CommandSourceStack> dispatcher = new CommandDispatcher<>();
|
||||
|
||||
public Commands(Commands.CommandSelection selection, CommandBuildContext context) {
|
||||
@@ -55,76 +62,29 @@
|
||||
this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer());
|
||||
}
|
||||
|
||||
@@ -289,9 +_,41 @@
|
||||
return new ParseResults<>(commandContextBuilder, parseResults.getReader(), parseResults.getExceptions());
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ public void dispatchServerCommand(CommandSourceStack sender, String command) {
|
||||
+ com.google.common.base.Joiner joiner = com.google.common.base.Joiner.on(" ");
|
||||
+ if (command.startsWith("/")) {
|
||||
+ command = command.substring(1);
|
||||
+ }
|
||||
+
|
||||
+ org.bukkit.event.server.ServerCommandEvent event = new org.bukkit.event.server.ServerCommandEvent(sender.getBukkitSender(), command);
|
||||
+ org.bukkit.Bukkit.getPluginManager().callEvent(event);
|
||||
+ if (event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ command = event.getCommand();
|
||||
+
|
||||
+ String[] args = command.split(" ");
|
||||
+ if (args.length == 0) return; // Paper - empty commands shall not be dispatched
|
||||
+
|
||||
+ // Paper - Fix permission levels for command blocks
|
||||
+
|
||||
+ // Handle vanilla commands; // Paper - handled in CommandNode/CommandDispatcher
|
||||
+
|
||||
+ String newCommand = joiner.join(args);
|
||||
+ this.performPrefixedCommand(sender, newCommand, newCommand);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
public void performPrefixedCommand(CommandSourceStack source, String command) {
|
||||
+ // CraftBukkit start
|
||||
+ this.performPrefixedCommand(source, command, command);
|
||||
+ }
|
||||
+
|
||||
+ public void performPrefixedCommand(CommandSourceStack source, String command, String label) {
|
||||
command = trimOptionalPrefix(command);
|
||||
- this.performCommand(this.dispatcher.parse(command, source), command);
|
||||
+ this.performCommand(this.dispatcher.parse(command, source), command, label);
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public static String trimOptionalPrefix(String command) {
|
||||
@@ -299,9 +_,20 @@
|
||||
@@ -299,6 +_,13 @@
|
||||
}
|
||||
|
||||
public void performCommand(ParseResults<CommandSourceStack> parseResults, String command) {
|
||||
+ // CraftBukkit start
|
||||
+ this.performCommand(parseResults, command, command);
|
||||
+ // Paper start
|
||||
+ this.performCommand(parseResults, command, false);
|
||||
+ }
|
||||
+
|
||||
+ public void performCommand(ParseResults<CommandSourceStack> parseResults, String command, String label) {
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start
|
||||
+ this.performCommand(parseResults, command, label, false);
|
||||
+ }
|
||||
+ public void performCommand(ParseResults<CommandSourceStack> parseResults, String command, String label, boolean throwCommandError) {
|
||||
+ public void performCommand(ParseResults<CommandSourceStack> parseResults, String command, boolean throwCommandError) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Cannot perform command async");
|
||||
+ // Paper end
|
||||
CommandSourceStack commandSourceStack = parseResults.getContext().getSource();
|
||||
Profiler.get().push(() -> "/" + command);
|
||||
- ContextChain<CommandSourceStack> contextChain = finishParsing(parseResults, command, commandSourceStack);
|
||||
+ ContextChain contextChain = this.finishParsing(parseResults, command, commandSourceStack, label); // CraftBukkit // Paper - Add UnknownCommandEvent
|
||||
|
||||
try {
|
||||
if (contextChain != null) {
|
||||
@@ -313,9 +_,10 @@
|
||||
ContextChain<CommandSourceStack> contextChain = finishParsing(parseResults, command, commandSourceStack);
|
||||
@@ -312,10 +_,13 @@
|
||||
)
|
||||
);
|
||||
}
|
||||
} catch (Exception var12) {
|
||||
+ if (throwCommandError) throw var12; // Paper
|
||||
- } catch (Exception var12) {
|
||||
+ // Paper start
|
||||
+ } catch (Throwable var12) { // always gracefully handle it, no matter how bad:tm:
|
||||
+ if (throwCommandError) throw var12; // rethrow directly if requested
|
||||
+ // Paper end
|
||||
MutableComponent mutableComponent = Component.literal(var12.getMessage() == null ? var12.getClass().getName() : var12.getMessage());
|
||||
- if (LOGGER.isDebugEnabled()) {
|
||||
- LOGGER.error("Command exception: /{}", command, var12);
|
||||
@@ -133,12 +93,12 @@
|
||||
StackTraceElement[] stackTrace = var12.getStackTrace();
|
||||
|
||||
for (int i = 0; i < Math.min(stackTrace.length, 3); i++) {
|
||||
@@ -341,18 +_,22 @@
|
||||
@@ -341,13 +_,17 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
- private static ContextChain<CommandSourceStack> finishParsing(ParseResults<CommandSourceStack> parseResults, String command, CommandSourceStack source) {
|
||||
+ private ContextChain<CommandSourceStack> finishParsing(ParseResults<CommandSourceStack> parseResults, String command, CommandSourceStack source, String label) { // CraftBukkit // Paper - Add UnknownCommandEvent
|
||||
+ private ContextChain<CommandSourceStack> finishParsing(ParseResults<CommandSourceStack> parseResults, String command, CommandSourceStack source) {
|
||||
try {
|
||||
validateParseResults(parseResults);
|
||||
return ContextChain.tryFlatten(parseResults.getContext().build(command))
|
||||
@@ -153,12 +113,6 @@
|
||||
if (var7.getInput() != null && var7.getCursor() >= 0) {
|
||||
int min = Math.min(var7.getInput().length(), var7.getCursor());
|
||||
MutableComponent mutableComponent = Component.empty()
|
||||
.withStyle(ChatFormatting.GRAY)
|
||||
- .withStyle(style -> style.withClickEvent(new ClickEvent.SuggestCommand("/" + command)));
|
||||
+ .withStyle(style -> style.withClickEvent(new ClickEvent.SuggestCommand("/" + label))); // CraftBukkit // Paper
|
||||
if (min > 10) {
|
||||
mutableComponent.append(CommonComponents.ELLIPSIS);
|
||||
}
|
||||
@@ -364,7 +_,17 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
--- a/net/minecraft/commands/PermissionSource.java
|
||||
+++ b/net/minecraft/commands/PermissionSource.java
|
||||
@@ -9,9 +_,20 @@
|
||||
@@ -9,9 +_,22 @@
|
||||
return this.hasPermission(2);
|
||||
}
|
||||
|
||||
- public record Check<T extends PermissionSource>(@Override int requiredLevel) implements PermissionCheck<T> {
|
||||
+ public record Check<T extends PermissionSource>(@Override int requiredLevel, java.util.concurrent.atomic.AtomicReference<com.mojang.brigadier.tree.CommandNode<CommandSourceStack>> vanillaNode) implements PermissionCheck<T> { // Paper
|
||||
+ // Paper start - Vanilla Command permission checking
|
||||
+ // Paper start - Vanilla Command permission checking & expose restricted API
|
||||
+ interface RestrictedMarker { }
|
||||
+
|
||||
+ public record Check<T extends PermissionSource>(@Override int requiredLevel, java.util.concurrent.atomic.AtomicReference<com.mojang.brigadier.tree.CommandNode<CommandSourceStack>> vanillaNode) implements PermissionCheck<T> {
|
||||
+ public Check(int requiredLevel) {
|
||||
+ this(requiredLevel, new java.util.concurrent.atomic.AtomicReference<>());
|
||||
+ }
|
||||
+ // Paper end - Vanilla Command permission checking
|
||||
+ // Paper end - Vanilla Command permission checking & expose restricted API
|
||||
@Override
|
||||
public boolean test(T source) {
|
||||
+ // Paper start - Vanilla Command permission checking
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/protocol/game/VecDeltaCodec.java
|
||||
+++ b/net/minecraft/network/protocol/game/VecDeltaCodec.java
|
||||
@@ -5,16 +_,16 @@
|
||||
@@ -5,7 +_,7 @@
|
||||
|
||||
public class VecDeltaCodec {
|
||||
private static final double TRUNCATION_STEPS = 4096.0;
|
||||
@@ -9,14 +9,3 @@
|
||||
|
||||
@VisibleForTesting
|
||||
static long encode(double value) {
|
||||
- return Math.round(value * 4096.0);
|
||||
+ return Math.round(value * 4096.0); // Paper - Fix MC-4; diff on change
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static double decode(long value) {
|
||||
- return value / 4096.0;
|
||||
+ return value / 4096.0; // Paper - Fix MC-4; diff on change
|
||||
}
|
||||
|
||||
public Vec3 decode(long x, long y, long z) {
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
if (profiledDuration != null) {
|
||||
profiledDuration.finish(true);
|
||||
}
|
||||
@@ -364,25 +_,265 @@
|
||||
@@ -364,25 +_,266 @@
|
||||
protected void forceDifficulty() {
|
||||
}
|
||||
|
||||
@@ -439,6 +439,7 @@
|
||||
+ if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins
|
||||
+ io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setValid(); // Paper - reset invalid state for event fire below
|
||||
+ io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.callReloadableRegistrarEvent(io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents.COMMANDS, io.papermc.paper.command.brigadier.PaperCommands.INSTANCE, org.bukkit.plugin.Plugin.class, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); // Paper - call commands event for regular plugins
|
||||
+ this.server.getCommandMap().registerServerAliases(); // Paper - relocate initial CommandMap#registerServerAliases() call
|
||||
+ ((org.bukkit.craftbukkit.help.SimpleHelpMap) this.server.getHelpMap()).initializeCommands();
|
||||
+ this.server.getPluginManager().callEvent(new org.bukkit.event.server.ServerLoadEvent(org.bukkit.event.server.ServerLoadEvent.LoadType.STARTUP));
|
||||
+ this.connection.acceptConnections();
|
||||
@@ -983,16 +984,25 @@
|
||||
ObjectArrayList<GameProfile> list = new ObjectArrayList<>(min);
|
||||
int randomInt = Mth.nextInt(this.random, 0, players.size() - min);
|
||||
|
||||
@@ -1040,17 +_,66 @@
|
||||
@@ -1040,17 +_,75 @@
|
||||
protected void tickChildren(BooleanSupplier hasTimeLeft) {
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing());
|
||||
+ this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit
|
||||
+ // Paper start - Folia scheduler API
|
||||
+ ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) org.bukkit.Bukkit.getGlobalRegionScheduler()).tick();
|
||||
+ for (ServerPlayer player : this.playerList.players) {
|
||||
+ if (!this.playerList.players.contains(player)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ final org.bukkit.craftbukkit.entity.CraftEntity bukkit = player.getBukkitEntityRaw();
|
||||
+ if (bukkit != null) {
|
||||
+ bukkit.taskScheduler.executeTick();
|
||||
+ }
|
||||
+ }
|
||||
+ getAllLevels().forEach(level -> {
|
||||
+ for (final net.minecraft.world.entity.Entity entity : level.getEntities().getAll()) {
|
||||
+ if (entity.isRemoved()) {
|
||||
+ for (final net.minecraft.world.entity.Entity entity : io.papermc.paper.FeatureHooks.getAllEntities(level)) {
|
||||
+ if (entity.isRemoved() || entity instanceof ServerPlayer) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ final org.bukkit.craftbukkit.entity.CraftEntity bukkit = entity.getBukkitEntityRaw();
|
||||
|
||||
@@ -273,7 +273,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -291,13 +_,23 @@
|
||||
@@ -291,12 +_,20 @@
|
||||
}
|
||||
|
||||
public void handleConsoleInput(String msg, CommandSourceStack source) {
|
||||
@@ -284,23 +284,19 @@
|
||||
public void handleConsoleInputs() {
|
||||
- while (!this.consoleInput.isEmpty()) {
|
||||
- ConsoleInput consoleInput = this.consoleInput.remove(0);
|
||||
- this.getCommands().performPrefixedCommand(consoleInput.source, consoleInput.msg);
|
||||
+ // Paper start - Perf: use proper queue
|
||||
+ ConsoleInput servercommand;
|
||||
+ while ((servercommand = this.serverCommandQueue.poll()) != null) {
|
||||
+ ConsoleInput consoleInput;
|
||||
+ while ((consoleInput = this.serverCommandQueue.poll()) != null) {
|
||||
+ // Paper end - Perf: use proper queue
|
||||
+ // CraftBukkit start - ServerCommand for preprocessing
|
||||
+ org.bukkit.event.server.ServerCommandEvent event = new org.bukkit.event.server.ServerCommandEvent(this.console, servercommand.msg);
|
||||
+ org.bukkit.event.server.ServerCommandEvent event = new org.bukkit.event.server.ServerCommandEvent(this.console, consoleInput.msg);
|
||||
+ this.server.getPluginManager().callEvent(event);
|
||||
+ if (event.isCancelled()) continue;
|
||||
+ servercommand = new ConsoleInput(event.getCommand(), servercommand.source);
|
||||
+
|
||||
+ // this.getCommands().performPrefixedCommand(servercommand.source, servercommand.msg); // Called in dispatchServerCommand
|
||||
+ this.server.dispatchServerCommand(this.console, servercommand);
|
||||
+ consoleInput = new ConsoleInput(event.getCommand(), consoleInput.source);
|
||||
+ // CraftBukkit end
|
||||
this.getCommands().performPrefixedCommand(consoleInput.source, consoleInput.msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,7 +_,11 @@
|
||||
@Override
|
||||
public boolean enforceSecureProfile() {
|
||||
@@ -314,7 +310,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -515,14 +_,54 @@
|
||||
@@ -515,14 +_,53 @@
|
||||
|
||||
@Override
|
||||
public String getPluginNames() {
|
||||
@@ -365,8 +361,7 @@
|
||||
+ if (event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ ConsoleInput serverCommand = new ConsoleInput(event.getCommand(), wrapper);
|
||||
+ this.server.dispatchServerCommand(event.getSender(), serverCommand);
|
||||
+ this.getCommands().performPrefixedCommand(wrapper, event.getCommand());
|
||||
+ });
|
||||
+ return rconConsoleSource.getCommandResponse();
|
||||
+ // CraftBukkit end
|
||||
|
||||
@@ -1334,7 +1334,8 @@
|
||||
if (traceItem) {
|
||||
- ItemStack itemStack = itemEntity != null ? itemEntity.getItem() : ItemStack.EMPTY;
|
||||
if (!itemStack.isEmpty()) {
|
||||
this.awardStat(Stats.ITEM_DROPPED.get(itemStack.getItem()), droppedItem.getCount());
|
||||
- this.awardStat(Stats.ITEM_DROPPED.get(itemStack.getItem()), droppedItem.getCount());
|
||||
+ this.awardStat(Stats.ITEM_DROPPED.get(itemStack.getItem()), itemStack.getCount()); // Paper - use size from dropped item
|
||||
this.awardStat(Stats.DROP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -29,30 +_,67 @@
|
||||
@@ -29,14 +_,14 @@
|
||||
import net.minecraft.util.profiling.Profiler;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
- protected final Connection connection;
|
||||
+ public final Connection connection; // Paper
|
||||
private final boolean transferred;
|
||||
- private long keepAliveTime;
|
||||
+ private long keepAliveTime = Util.getMillis(); // Paper
|
||||
private long keepAliveTime;
|
||||
private boolean keepAlivePending;
|
||||
private long keepAliveChallenge;
|
||||
private long closedListenerTime;
|
||||
@@ -45,14 +_,51 @@
|
||||
private boolean closed = false;
|
||||
private int latency;
|
||||
private volatile boolean suspendFlushingOnServerThread = false;
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
|
||||
rootVehicle.absSnapTo(d, d1, d2, f, f1);
|
||||
+ // CraftBukkit start - fire PlayerMoveEvent TODO: this should be removed.
|
||||
+ this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // Paper - TODO: This breaks alot of stuff
|
||||
+ this.player.absSnapTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // Paper - TODO: This breaks alot of stuff
|
||||
+ org.bukkit.entity.Player player = this.getCraftPlayer();
|
||||
+ if (!this.hasMoved) {
|
||||
+ this.lastPosX = prevX;
|
||||
@@ -1146,8 +1146,7 @@
|
||||
|
||||
return;
|
||||
case RELEASE_USE_ITEM:
|
||||
- this.player.releaseUsingItem();
|
||||
+ if (this.player.getUseItem() == this.player.getItemInHand(this.player.getUsedItemHand())) this.player.releaseUsingItem(); // Paper - validate use item before processing release
|
||||
this.player.releaseUsingItem();
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
|
||||
return;
|
||||
case START_DESTROY_BLOCK:
|
||||
@@ -2610,7 +2609,7 @@
|
||||
if (!this.receivedMovementThisTick) {
|
||||
this.player.setKnownMovement(Vec3.ZERO);
|
||||
}
|
||||
@@ -2078,4 +_,17 @@
|
||||
@@ -2078,4 +_,29 @@
|
||||
interface EntityInteraction {
|
||||
InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand);
|
||||
}
|
||||
@@ -2627,4 +2626,16 @@
|
||||
+ return event;
|
||||
+ }
|
||||
+ // Paper end - Add fail move event
|
||||
+
|
||||
+ // Paper start - Implement click callbacks with custom click action
|
||||
+ @Override
|
||||
+ public void handleCustomClickAction(final net.minecraft.network.protocol.common.ServerboundCustomClickActionPacket packet) {
|
||||
+ super.handleCustomClickAction(packet);
|
||||
+ if (packet.id().equals(io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CLICK_CALLBACK_RESOURCE_LOCATION)) {
|
||||
+ packet.payload().ifPresent(tag ->
|
||||
+ io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.tryRunCallback(this.player.getBukkitEntity(), tag)
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Implement click callbacks with custom click action
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
+ // Paper end - Share random for entities to make them more random
|
||||
+ public @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason
|
||||
+
|
||||
+ private @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity;
|
||||
+ private volatile @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; // Paper - Folia schedulers - volatile
|
||||
+
|
||||
+ public org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntity() {
|
||||
+ if (this.bukkitEntity == null) {
|
||||
@@ -1786,7 +1786,7 @@
|
||||
}
|
||||
|
||||
public void addDeltaMovement(Vec3 addend) {
|
||||
@@ -3661,9 +_,45 @@
|
||||
@@ -3661,9 +_,35 @@
|
||||
return this.getZ((2.0 * this.random.nextDouble() - 1.0) * scale);
|
||||
}
|
||||
|
||||
@@ -1815,16 +1815,6 @@
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Block invalid positions and bounding box
|
||||
+ // Paper start - Fix MC-4
|
||||
+ if (this instanceof ItemEntity) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.fixEntityPositionDesync) {
|
||||
+ // encode/decode from VecDeltaCodec todo computation changed?
|
||||
+ x = Mth.lfloor(x * 4096.0) * (1 / 4096.0);
|
||||
+ y = Mth.lfloor(y * 4096.0) * (1 / 4096.0);
|
||||
+ z = Mth.lfloor(z * 4096.0) * (1 / 4096.0);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Fix MC-4
|
||||
if (this.position.x != x || this.position.y != y || this.position.z != z) {
|
||||
+ synchronized (this.posLock) { // Paper - detailed watchdog information
|
||||
this.position = new Vec3(x, y, z);
|
||||
|
||||
@@ -27,3 +27,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +_,12 @@
|
||||
return this.level().getBlockState(this.pos).is(BlockTags.FENCES);
|
||||
}
|
||||
|
||||
+ // Paper start - Track if a knot was created
|
||||
public static LeashFenceKnotEntity getOrCreateKnot(Level level, BlockPos pos) {
|
||||
+ return getOrCreateKnot(level, pos, null);
|
||||
+ }
|
||||
+ public static LeashFenceKnotEntity getOrCreateKnot(Level level, BlockPos pos, @Nullable org.apache.commons.lang3.mutable.MutableBoolean created) {
|
||||
+ // Paper end - Track if a knot was created
|
||||
int x = pos.getX();
|
||||
int y = pos.getY();
|
||||
int z = pos.getZ();
|
||||
@@ -134,7 +_,7 @@
|
||||
}
|
||||
|
||||
LeashFenceKnotEntity leashFenceKnotEntity1 = new LeashFenceKnotEntity(level, pos);
|
||||
- level.addFreshEntity(leashFenceKnotEntity1);
|
||||
+ if (level.addFreshEntity(leashFenceKnotEntity1) && created != null) { created.setTrue(); } // Paper - Track if a knot was created
|
||||
return leashFenceKnotEntity1;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,21 @@
|
||||
}
|
||||
|
||||
public ItemEntity(Level level, double posX, double posY, double posZ, ItemStack itemStack, double deltaX, double deltaY, double deltaZ) {
|
||||
@@ -79,6 +_,14 @@
|
||||
this.bobOffs = other.bobOffs;
|
||||
}
|
||||
|
||||
+ // Paper start - Require item entities to send their location precisely (Fixes MC-4)
|
||||
+ {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.sendFullPosForItemEntities) {
|
||||
+ this.setRequiresPrecisePosition(true);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Require item entities to send their location precisely (Fixes MC-4)
|
||||
+
|
||||
@Override
|
||||
public boolean dampensVibrations() {
|
||||
return this.getItem().is(ItemTags.DAMPENS_VIBRATIONS);
|
||||
@@ -116,7 +_,7 @@
|
||||
@Override
|
||||
public void tick() {
|
||||
|
||||
@@ -43,23 +43,36 @@
|
||||
if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
|
||||
LocalDate localDate = LocalDate.now();
|
||||
int i = localDate.get(ChronoField.DAY_OF_MONTH);
|
||||
@@ -196,9 +_,19 @@
|
||||
@@ -188,7 +_,8 @@
|
||||
|
||||
@Override
|
||||
public void performRangedAttack(LivingEntity target, float distanceFactor) {
|
||||
- ItemStack itemInHand = this.getItemInHand(ProjectileUtil.getWeaponHoldingHand(this, Items.BOW));
|
||||
+ net.minecraft.world.InteractionHand hand = ProjectileUtil.getWeaponHoldingHand(this, Items.BOW); // Paper - call EntityShootBowEvent
|
||||
+ ItemStack itemInHand = this.getItemInHand(hand); // Paper - call EntityShootBowEvent
|
||||
ItemStack projectile = this.getProjectile(itemInHand);
|
||||
AbstractArrow arrow = this.getArrow(projectile, distanceFactor, itemInHand);
|
||||
double d = target.getX() - this.getX();
|
||||
@@ -196,9 +_,21 @@
|
||||
double d2 = target.getZ() - this.getZ();
|
||||
double squareRoot = Math.sqrt(d * d + d2 * d2);
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), arrow.getPickupItem(), arrow, net.minecraft.world.InteractionHand.MAIN_HAND, distanceFactor, true); // Paper - improve entity shoot bow event, add arrow stack to event
|
||||
- Projectile.spawnProjectileUsingShoot(
|
||||
+ Projectile.Delayed<AbstractArrow> delayedEntity = Projectile.spawnProjectileUsingShootDelayed( // Paper - delayed
|
||||
arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4
|
||||
);
|
||||
+
|
||||
+ // Paper start - call EntityShootBowEvent
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, itemInHand, arrow.getPickupItem(), arrow, hand, distanceFactor, true);
|
||||
+ if (event.isCancelled()) {
|
||||
+ event.getProjectile().remove();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (event.getProjectile() == arrow.getBukkitEntity()) {
|
||||
+ // CraftBukkit end
|
||||
Projectile.spawnProjectileUsingShoot(
|
||||
arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4
|
||||
);
|
||||
+ } // CraftBukkit
|
||||
+ delayedEntity.spawn();
|
||||
+ }
|
||||
+ // Paper end - call EntityShootBowEvent
|
||||
}
|
||||
|
||||
this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
@@ -1,22 +1,35 @@
|
||||
--- a/net/minecraft/world/entity/monster/Illusioner.java
|
||||
+++ b/net/minecraft/world/entity/monster/Illusioner.java
|
||||
@@ -180,9 +_,19 @@
|
||||
@@ -172,7 +_,8 @@
|
||||
|
||||
@Override
|
||||
public void performRangedAttack(LivingEntity target, float distanceFactor) {
|
||||
- ItemStack itemInHand = this.getItemInHand(ProjectileUtil.getWeaponHoldingHand(this, Items.BOW));
|
||||
+ net.minecraft.world.InteractionHand hand = ProjectileUtil.getWeaponHoldingHand(this, Items.BOW); // Paper - call EntityShootBowEvent
|
||||
+ ItemStack itemInHand = this.getItemInHand(hand); // Paper - call EntityShootBowEvent
|
||||
ItemStack projectile = this.getProjectile(itemInHand);
|
||||
AbstractArrow mobArrow = ProjectileUtil.getMobArrow(this, projectile, distanceFactor, itemInHand);
|
||||
double d = target.getX() - this.getX();
|
||||
@@ -180,9 +_,21 @@
|
||||
double d2 = target.getZ() - this.getZ();
|
||||
double squareRoot = Math.sqrt(d * d + d2 * d2);
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
+ // Paper start - EntityShootBowEvent
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), mobArrow.getPickupItem(), mobArrow, target.getUsedItemHand(), distanceFactor, true);
|
||||
- Projectile.spawnProjectileUsingShoot(
|
||||
+ Projectile.Delayed<AbstractArrow> delayedEntity = Projectile.spawnProjectileUsingShootDelayed( // Paper - delayed
|
||||
mobArrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4
|
||||
);
|
||||
+
|
||||
+ // Paper start - call EntityShootBowEvent
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, itemInHand, mobArrow.getPickupItem(), mobArrow, hand, distanceFactor, true);
|
||||
+ if (event.isCancelled()) {
|
||||
+ event.getProjectile().remove();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (event.getProjectile() == mobArrow.getBukkitEntity()) {
|
||||
Projectile.spawnProjectileUsingShoot(
|
||||
mobArrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4
|
||||
);
|
||||
+ delayedEntity.spawn();
|
||||
+ }
|
||||
+ // Paper end - EntityShootBowEvent
|
||||
+ // Paper end - call EntityShootBowEvent
|
||||
}
|
||||
|
||||
this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/item/LeadItem.java
|
||||
+++ b/net/minecraft/world/item/LeadItem.java
|
||||
@@ -26,24 +_,43 @@
|
||||
@@ -26,24 +_,46 @@
|
||||
if (blockState.is(BlockTags.FENCES)) {
|
||||
Player player = context.getPlayer();
|
||||
if (!level.isClientSide && player != null) {
|
||||
@@ -22,15 +22,19 @@
|
||||
+ for (java.util.Iterator<Leashable> iterator = list.iterator(); iterator.hasNext();) { // Paper - use iterator to remove
|
||||
+ Leashable leashable = iterator.next(); // Paper - use iterator to remove
|
||||
if (leashFenceKnotEntity == null) {
|
||||
leashFenceKnotEntity = LeashFenceKnotEntity.getOrCreateKnot(level, pos);
|
||||
- leashFenceKnotEntity = LeashFenceKnotEntity.getOrCreateKnot(level, pos);
|
||||
+ // CraftBukkit start - fire HangingPlaceEvent
|
||||
+ org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(interactionHand);
|
||||
+ org.bukkit.event.hanging.HangingPlaceEvent event = new org.bukkit.event.hanging.HangingPlaceEvent((org.bukkit.entity.Hanging) leashFenceKnotEntity.getBukkitEntity(), player != null ? (org.bukkit.entity.Player) player.getBukkitEntity() : null, org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), org.bukkit.block.BlockFace.SELF, hand);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ org.apache.commons.lang3.mutable.MutableBoolean created = new org.apache.commons.lang3.mutable.MutableBoolean(false);
|
||||
+ leashFenceKnotEntity = LeashFenceKnotEntity.getOrCreateKnot(level, pos, created);
|
||||
+ if (created.booleanValue()) {
|
||||
+ org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(interactionHand);
|
||||
+ org.bukkit.event.hanging.HangingPlaceEvent event = new org.bukkit.event.hanging.HangingPlaceEvent((org.bukkit.entity.Hanging) leashFenceKnotEntity.getBukkitEntity(), player != null ? (org.bukkit.entity.Player) player.getBukkitEntity() : null, org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), org.bukkit.block.BlockFace.SELF, hand);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ leashFenceKnotEntity.discard(null); // CraftBukkit - add Bukkit remove cause
|
||||
+ return InteractionResult.PASS;
|
||||
+ if (event.isCancelled()) {
|
||||
+ leashFenceKnotEntity.discard(null); // CraftBukkit - add Bukkit remove cause
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
leashFenceKnotEntity.playPlacementSound();
|
||||
|
||||
@@ -12,12 +12,18 @@
|
||||
|
||||
public int getSuccessCount() {
|
||||
return this.successCount;
|
||||
@@ -108,7 +_,7 @@
|
||||
@@ -108,7 +_,13 @@
|
||||
this.successCount++;
|
||||
}
|
||||
});
|
||||
- server.getCommands().performPrefixedCommand(commandSourceStack, this.command);
|
||||
+ server.getCommands().dispatchServerCommand(commandSourceStack, this.command); // CraftBukkit
|
||||
+ // Paper start - ServerCommandEvent
|
||||
+ org.bukkit.event.server.ServerCommandEvent event = new org.bukkit.event.server.ServerCommandEvent(commandSourceStack.getBukkitSender(), net.minecraft.commands.Commands.trimOptionalPrefix(this.command));
|
||||
+ if (!event.callEvent()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ server.getCommands().performPrefixedCommand(commandSourceStack, event.getCommand());
|
||||
+ // Paper end - ServerCommandEvent
|
||||
} catch (Throwable var6) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var6, "Executing command block");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Command to be executed");
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
- builder.withParameter(LootContextParams.EXPLOSION_RADIUS, explosion.radius());
|
||||
+ // CraftBukkit start - add yield
|
||||
+ if (explosion instanceof net.minecraft.world.level.ServerExplosion serverExplosion && serverExplosion.yield < 1.0F) {
|
||||
+ builder.withParameter(LootContextParams.EXPLOSION_RADIUS, serverExplosion.yield == 0 ? 0 : 1.0F / serverExplosion.yield);
|
||||
+ builder.withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0F / serverExplosion.yield);
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
--- a/net/minecraft/world/level/entity/EntitySection.java
|
||||
+++ b/net/minecraft/world/level/entity/EntitySection.java
|
||||
@@ -19,6 +_,12 @@
|
||||
this.storage = new ClassInstanceMultiMap<>(entityClazz);
|
||||
}
|
||||
|
||||
+ // Paper start - support retrieving all entities, regardless of whether they are accessible
|
||||
+ public void getEntities(java.util.List<T> into) {
|
||||
+ into.addAll(this.storage);
|
||||
+ }
|
||||
+ // Paper end - support retrieving all entities, regardless of whether they are accessible
|
||||
+
|
||||
public void add(T entity) {
|
||||
this.storage.add(entity);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
--- a/net/minecraft/world/level/entity/EntitySectionStorage.java
|
||||
+++ b/net/minecraft/world/level/entity/EntitySectionStorage.java
|
||||
@@ -34,6 +_,16 @@
|
||||
this.intialSectionVisibility = initialSectionVisibility;
|
||||
}
|
||||
|
||||
+ // Paper start - support retrieving all entities, regardless of whether they are accessible
|
||||
+ public Iterable<T> getAllEntities() {
|
||||
+ java.util.List<T> ret = new java.util.ArrayList<>();
|
||||
+ for (EntitySection<T> section : this.sections.values()) {
|
||||
+ section.getEntities(ret);
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+ // Paper end - support retrieving all entities, regardless of whether they are accessible
|
||||
+
|
||||
public void forEachAccessibleNonEmptySection(AABB boundingBox, AbortableIterationConsumer<EntitySection<T>> consumer) {
|
||||
int sectionPosCoord = SectionPos.posToSectionCoord(boundingBox.minX - 2.0);
|
||||
int sectionPosCoord1 = SectionPos.posToSectionCoord(boundingBox.minY - 4.0);
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/world/level/entity/LevelEntityGetterAdapter.java
|
||||
+++ b/net/minecraft/world/level/entity/LevelEntityGetterAdapter.java
|
||||
@@ -8,7 +_,7 @@
|
||||
|
||||
public class LevelEntityGetterAdapter<T extends EntityAccess> implements LevelEntityGetter<T> {
|
||||
private final EntityLookup<T> visibleEntities;
|
||||
- private final EntitySectionStorage<T> sectionStorage;
|
||||
+ public final EntitySectionStorage<T> sectionStorage; // Paper - public
|
||||
|
||||
public LevelEntityGetterAdapter(EntityLookup<T> visibleEntities, EntitySectionStorage<T> sectionStorage) {
|
||||
this.visibleEntities = visibleEntities;
|
||||
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/world/waypoints/WaypointTransmitter.java
|
||||
+++ b/net/minecraft/world/waypoints/WaypointTransmitter.java
|
||||
@@ -20,6 +_,7 @@
|
||||
Waypoint.Icon waypointIcon();
|
||||
|
||||
static boolean doesSourceIgnoreReceiver(LivingEntity entity, ServerPlayer player) {
|
||||
+ if (!player.getBukkitEntity().canSee(entity.getBukkitEntity())) return true; // Paper - ignore if entity is hidden from player
|
||||
if (player.isSpectator()) {
|
||||
return false;
|
||||
} else if (!entity.isSpectator() && !entity.hasIndirectPassenger(player)) {
|
||||
Reference in New Issue
Block a user