diff --git a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch index 4277482fd4..22addd69a6 100644 --- a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch @@ -555,15 +555,17 @@ if (!iworlddataserver.isInitialized()) { try { -@@ -427,30 +717,8 @@ - iworlddataserver.setInitialized(true); - } +@@ -425,32 +715,10 @@ + } + iworlddataserver.setInitialized(true); +- } +- - this.getPlayerList().addWorldborderListener(worldserver); - if (this.worldData.getCustomBossEvents() != null) { - this.getCustomBossEvents().load(this.worldData.getCustomBossEvents(), this.registryAccess()); -- } -- + } + - RandomSequences randomsequences = worldserver.getRandomSequences(); - Iterator iterator = iregistry.entrySet().iterator(); - @@ -672,7 +674,7 @@ + worldloadlistener.stop(); + // CraftBukkit start + // this.updateMobSpawningFlags(); -+ worldserver.setSpawnSettings(this.isSpawningMonsters()); ++ worldserver.setSpawnSettings(worldserver.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && ((DedicatedServer) this).settings.getProperties().spawnMonsters); // Paper - per level difficulty (from setDifficulty(ServerLevel, Difficulty, boolean)) + + this.forceTicks = false; + // CraftBukkit end @@ -698,12 +700,10 @@ if (flush) { Iterator iterator1 = this.getAllLevels().iterator(); -@@ -626,20 +925,47 @@ - @Override - public void close() { +@@ -628,18 +927,45 @@ this.stopServer(); -+ } -+ + } + + // CraftBukkit start + private boolean hasStopped = false; + private boolean hasLoggedStop = false; // Paper - Debugging @@ -712,9 +712,9 @@ + synchronized (this.stopLock) { + return this.hasStopped; + } - } ++ } + // CraftBukkit end - ++ public void stopServer() { + // CraftBukkit start - prevent double stopping on multiple threads + synchronized(this.stopLock) { @@ -916,24 +916,22 @@ this.onServerExit(); } -@@ -889,9 +1325,16 @@ +@@ -889,7 +1325,14 @@ } private boolean haveTime() { - return this.runningTask() || Util.getNanos() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTimeNanos : this.nextTickTimeNanos); + // CraftBukkit start + return this.forceTicks || this.runningTask() || Util.getNanos() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTimeNanos : this.nextTickTimeNanos); - } - ++ } ++ + private void executeModerately() { + this.runAllTasks(); + java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L); + // CraftBukkit end -+ } -+ - public static boolean throwIfFatalException() { - RuntimeException runtimeexception = (RuntimeException) MinecraftServer.fatalException.get(); + } + public static boolean throwIfFatalException() { @@ -903,7 +1346,7 @@ } @@ -1136,7 +1134,36 @@ } public KeyPair getKeyPair() { -@@ -1481,10 +1986,20 @@ +@@ -1385,11 +1890,14 @@ + } + } + +- public void setDifficulty(Difficulty difficulty, boolean forceUpdate) { +- if (forceUpdate || !this.worldData.isDifficultyLocked()) { +- this.worldData.setDifficulty(this.worldData.isHardcore() ? Difficulty.HARD : difficulty); +- this.updateMobSpawningFlags(); +- this.getPlayerList().getPlayers().forEach(this::sendDifficultyUpdate); ++ // Paper start - per level difficulty ++ public void setDifficulty(ServerLevel level, Difficulty difficulty, boolean forceUpdate) { ++ PrimaryLevelData worldData = level.serverLevelData; ++ if (forceUpdate || !worldData.isDifficultyLocked()) { ++ worldData.setDifficulty(worldData.isHardcore() ? Difficulty.HARD : difficulty); ++ level.setSpawnSettings(worldData.getDifficulty() != Difficulty.PEACEFUL && ((DedicatedServer) this).settings.getProperties().spawnMonsters); ++ // this.getPlayerList().getPlayers().forEach(this::sendDifficultyUpdate); ++ // Paper end - per level difficulty + } + } + +@@ -1403,7 +1911,7 @@ + while (iterator.hasNext()) { + ServerLevel worldserver = (ServerLevel) iterator.next(); + +- worldserver.setSpawnSettings(this.isSpawningMonsters()); ++ worldserver.setSpawnSettings(worldserver.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && ((DedicatedServer) this).settings.getProperties().spawnMonsters); // Paper - per level difficulty (from setDifficulty(ServerLevel, Difficulty, boolean)) + } + + } +@@ -1481,10 +1989,20 @@ @Override public String getMotd() { @@ -1158,7 +1185,7 @@ this.motd = motd; } -@@ -1507,7 +2022,7 @@ +@@ -1507,7 +2025,7 @@ } public ServerConnectionListener getConnection() { @@ -1167,7 +1194,7 @@ } public boolean isReady() { -@@ -1634,11 +2149,11 @@ +@@ -1634,11 +2152,11 @@ public CompletableFuture reloadResources(Collection dataPacks) { CompletableFuture completablefuture = CompletableFuture.supplyAsync(() -> { @@ -1181,7 +1208,7 @@ }, this).thenCompose((immutablelist) -> { MultiPackResourceManager resourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, immutablelist); List> list = TagLoader.loadTagsForExistingRegistries(resourcemanager, this.registries.compositeAccess()); -@@ -1654,6 +2169,7 @@ +@@ -1654,6 +2172,7 @@ }).thenAcceptAsync((minecraftserver_reloadableresources) -> { this.resources.close(); this.resources = minecraftserver_reloadableresources; @@ -1189,7 +1216,7 @@ this.packRepository.setSelected(dataPacks); WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(MinecraftServer.getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()); -@@ -1952,7 +2468,7 @@ +@@ -1952,7 +2471,7 @@ final List list = Lists.newArrayList(); final GameRules gamerules = this.getGameRules(); @@ -1198,7 +1225,7 @@ @Override public > void visit(GameRules.Key key, GameRules.Type type) { list.add(String.format(Locale.ROOT, "%s=%s\n", key.getId(), gamerules.getRule(key))); -@@ -2058,7 +2574,7 @@ +@@ -2058,7 +2577,7 @@ try { label51: { @@ -1207,18 +1234,15 @@ try { arraylist = Lists.newArrayList(NativeModuleLister.listModules()); -@@ -2105,9 +2621,24 @@ - if (bufferedwriter != null) { - bufferedwriter.close(); - } -+ -+ } +@@ -2108,6 +2627,21 @@ + + } + // CraftBukkit start + public boolean isDebugging() { + return false; - } - ++ } ++ + public static MinecraftServer getServer() { + return SERVER; // Paper + } @@ -1232,7 +1256,7 @@ private ProfilerFiller createProfiler() { if (this.willStartRecordingMetrics) { this.metricsRecorder = ActiveMetricsRecorder.createStarted(new ServerMetricsSamplersProvider(Util.timeSource, this.isDedicatedServer()), Util.timeSource, Util.ioPool(), new MetricsPersister("server"), this.onMetricsRecordingStopped, (path) -> { -@@ -2225,18 +2756,24 @@ +@@ -2225,18 +2759,24 @@ } public void logChatMessage(Component message, ChatType.Bound params, @Nullable String prefix) { @@ -1261,15 +1285,17 @@ } public boolean logIPs() { -@@ -2379,4 +2916,30 @@ - public static record ServerResourcePackInfo(UUID id, String url, String hash, boolean isRequired, @Nullable Component prompt) { - +@@ -2377,6 +2917,32 @@ } + + public static record ServerResourcePackInfo(UUID id, String url, String hash, boolean isRequired, @Nullable Component prompt) { ++ ++ } + + // Paper start - Add tick times API and /mspt command + public static class TickTimes { + private final long[] times; -+ + + public TickTimes(int length) { + times = new long[length]; + } @@ -1289,6 +1315,6 @@ + } + return ((double) total / (double) times.length) * 1.0E-6D; + } -+ } + } + // Paper end - Add tick times API and /mspt command } diff --git a/paper-server/patches/sources/net/minecraft/server/commands/DifficultyCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/DifficultyCommand.java.patch index 2dc65ce607..0898d7e23d 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/DifficultyCommand.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/DifficultyCommand.java.patch @@ -11,7 +11,7 @@ throw DifficultyCommand.ERROR_ALREADY_DIFFICULT.create(difficulty.getKey()); } else { - minecraftserver.setDifficulty(difficulty, true); -+ worldServer.serverLevelData.setDifficulty(difficulty); // CraftBukkit ++ minecraftserver.setDifficulty(worldServer, difficulty, true); // Paper - per level difficulty; don't skip other difficulty-changing logic (fix upstream's fix) source.sendSuccess(() -> { return Component.translatable("commands.difficulty.success", difficulty.getDisplayName()); }, true); diff --git a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch index d671bef36b..27912d744c 100644 --- a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -250,6 +250,15 @@ @Override public boolean isSpawningMonsters() { return this.settings.getProperties().spawnMonsters && super.isSpawningMonsters(); +@@ -227,7 +337,7 @@ + + @Override + public void forceDifficulty() { +- this.setDifficulty(this.getProperties().difficulty, true); ++ // this.setDifficulty(this.getProperties().difficulty, true); // Paper - per level difficulty; Don't overwrite level.dat's difficulty, keep current + } + + @Override @@ -286,13 +396,14 @@ } diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index c9ce7c1a0a..4f3a33bb29 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -629,8 +629,8 @@ + if (i > Math.max(this.allowedPlayerTicks, 5)) { ServerGamePacketListenerImpl.LOGGER.debug("{} is sending move packets too frequently ({} packets since last tick)", this.player.getName().getString(), i); i = 1; -+ } -+ + } + + if (packet.hasRot || d10 > 0) { + this.allowedPlayerTicks -= 1; + } else { @@ -646,9 +646,9 @@ + if (this.player.level().paperConfig().chunks.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position())))) { + this.internalTeleport(PositionMoveRotation.of(this.player), Collections.emptySet()); + return; - } ++ } + // Paper end - Prevent moving into unloaded chunks - ++ if (this.shouldCheckPlayerMovement(flag)) { float f2 = flag ? 300.0F : 100.0F; @@ -1002,12 +1002,10 @@ if (this.player.hasClientLoaded()) { this.ackBlockChangesUpTo(packet.getSequence()); ServerLevel worldserver = this.player.serverLevel(); -@@ -1294,8 +1861,49 @@ - - if (f1 != this.player.getXRot() || f != this.player.getYRot()) { +@@ -1296,6 +1863,47 @@ this.player.absRotateTo(f, f1); -+ } -+ + } + + // CraftBukkit start + // Raytrace to look for 'rogue armswings' + double d0 = this.player.getX(); @@ -1038,8 +1036,8 @@ + cancelled = event.useItemInHand() == Event.Result.DENY; + } + this.player.gameMode.firedInteract = false; - } - ++ } ++ + if (cancelled) { + this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524 + return; @@ -1587,12 +1585,12 @@ + entity.getBukkitEntity().update(ServerGamePacketListenerImpl.this.player); + ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); + } - ++ + if (triggerLeashUpdate && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) { + // Refresh the current leash state + ServerGamePacketListenerImpl.this.send(new ClientboundSetEntityLinkPacket(entity, ((Mob) entity).getLeashHolder())); + } -+ + + if (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem) { + // Refresh the current entity metadata + entity.refreshEntityData(ServerGamePacketListenerImpl.this.player); @@ -2182,6 +2180,15 @@ if (this.player.isModelPartShown(PlayerModelPart.HAT) != flag) { this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player)); } +@@ -2012,7 +3366,7 @@ + public void handleChangeDifficulty(ServerboundChangeDifficultyPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + if (this.player.hasPermissions(2) || this.isSingleplayerOwner()) { +- this.server.setDifficulty(packet.getDifficulty(), false); ++ // this.server.setDifficulty(packet.getDifficulty(), false); // Paper - per level difficulty; don't allow clients to change this + } + } + @@ -2058,7 +3412,7 @@ if (!this.waitingForSwitchToConfig) { throw new IllegalStateException("Client acknowledged config, but none was requested"); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index ca8eb3216c..9905555f24 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1000,8 +1000,8 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); for (ServerLevel world : this.console.getAllLevels()) { - world.serverLevelData.setDifficulty(config.difficulty); - world.setSpawnSettings(config.spawnMonsters); + // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty + world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean)) for (SpawnCategory spawnCategory : SpawnCategory.values()) { if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index c310a8bae8..031c46e8cf 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1170,7 +1170,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setDifficulty(Difficulty difficulty) { - this.getHandle().serverLevelData.setDifficulty(net.minecraft.world.Difficulty.byId(difficulty.getValue())); + this.getHandle().getServer().setDifficulty(this.getHandle(), net.minecraft.world.Difficulty.byId(difficulty.getValue()), true); // Paper - per level difficulty; don't skip other difficulty-changing logic } @Override