more work work work

This commit is contained in:
Aurora 2021-06-14 12:42:08 +02:00
parent d2cb88db9c
commit 8ca5a642ef
No known key found for this signature in database
GPG key ID: 89839F67B53656AD
32 changed files with 267 additions and 264 deletions

View file

@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JRoy <joshroy126@gmail.com>
Date: Wed, 15 Jul 2020 21:42:52 -0400
Subject: [PATCH] Fix SPIGOT-5989
Before this fix, if a player was respawning to a respawn anchor and
the respawn location was modified away from the anchor with the
PlayerRespawnEvent, the anchor would still lose some charge.
This fixes that by checking if the modified spawn location is
still at a respawn anchor.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 66735bbc2528c5812c9df14ef7cd91cb69d903b2..9c594c0f142ca10b7c1df50faf45ccb3f7468ba9 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -77,6 +77,7 @@ import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.block.RespawnAnchorBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.border.BorderChangeListener;
import net.minecraft.world.level.border.WorldBorder;
@@ -821,6 +822,7 @@ public abstract class PlayerList {
// Paper start
boolean isBedSpawn = false;
boolean isRespawn = false;
+ boolean isLocAltered = false; // Paper - Fix SPIGOT-5989
// Paper end
// CraftBukkit start - fire PlayerRespawnEvent
@@ -831,7 +833,7 @@ public abstract class PlayerList {
Optional optional;
if (blockposition != null) {
- optional = net.minecraft.world.entity.player.Player.findRespawnPositionAndUseSpawnBlock(worldserver1, blockposition, f, flag1, flag);
+ optional = net.minecraft.world.entity.player.Player.findRespawnPositionAndUseSpawnBlock(worldserver1, blockposition, f, flag1, true); // Paper - Fix SPIGOT-5989
} else {
optional = Optional.empty();
}
@@ -874,7 +876,12 @@ public abstract class PlayerList {
}
// Spigot End
- location = respawnEvent.getRespawnLocation();
+ // Paper start - Fix SPIGOT-5989
+ if (!location.equals(respawnEvent.getRespawnLocation()) ) {
+ location = respawnEvent.getRespawnLocation();
+ isLocAltered = true;
+ }
+ // Paper end
if (!flag) entityplayer.reset(); // SPIGOT-4785
isRespawn = true; // Paper
} else {
@@ -911,8 +918,12 @@ public abstract class PlayerList {
}
// entityplayer1.syncInventory();
entityplayer1.setHealth(entityplayer1.getHealth());
- if (flag2) {
- entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 1.0F, 1.0F));
+ // Paper start - Fix SPIGOT-5989
+ if (flag2 && !isLocAltered) {
+ BlockState data = worldserver1.getBlockState(blockposition);
+ worldserver1.setBlock(blockposition, data.setValue(RespawnAnchorBlock.CHARGE, data.getValue(RespawnAnchorBlock.CHARGE) - 1), 3);
+ entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) location.getX(), (double) location.getY(), (double) location.getZ(), 1.0F, 1.0F));
+ // Paper end
}
// Added from changeDimension
this.sendAllPlayerInfo(entityplayer); // Update health, etc...

View file

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Fri, 10 Jul 2020 13:12:33 -0500
Subject: [PATCH] Fix SPIGOT-5824 Bukkit world-container is not used
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
index 7ce854edba32ffcafaa5268d4bb2822a5233e40b..3d6e09a3f028e50c08cbbb6b426f5b044c7b9e67 100644
--- a/src/main/java/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java
@@ -129,11 +129,20 @@ public class Main {
return;
}
- File file = (File) optionset.valueOf("universe"); // CraftBukkit
+ // Paper start - fix SPIGOT-5824
+ File file;
+ File userCacheFile = new File("usercache.json");
+ if (optionset.has("universe")) {
+ file = (File) optionset.valueOf("universe"); // CraftBukkit
+ userCacheFile = new File(file, "usercache.json");
+ } else {
+ file = new File(bukkitConfiguration.getString("settings.world-container", "."));
+ }
+ // Paper end - fix SPIGOT-5824
YggdrasilAuthenticationService yggdrasilauthenticationservice = new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY); // Paper
MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService();
GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository();
- GameProfileCache usercache = new GameProfileCache(gameprofilerepository, new File(file, MinecraftServer.USERID_CACHE_FILE.getName()));
+ GameProfileCache usercache = new GameProfileCache(gameprofilerepository, userCacheFile); // Paper - only move usercache.json into folder if --universe is used, not world-container
// CraftBukkit start
String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName);
LevelStorageSource convertable = LevelStorageSource.createDefault(file.toPath());

View file

@ -0,0 +1,18 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Fri, 10 Jul 2020 12:38:12 -0500
Subject: [PATCH] Fix SPIGOT-5885 Unable to disable advancements
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
index 3d6e09a3f028e50c08cbbb6b426f5b044c7b9e67..ea136b9ad3a2a07076e12b8656c68f63aa4718c8 100644
--- a/src/main/java/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java
@@ -129,6 +129,7 @@ public class Main {
return;
}
+ org.spigotmc.SpigotConfig.disabledAdvancements = spigotConfiguration.getStringList("advancements.disabled"); // Paper - fix SPIGOT-5885, must be set early in init
// Paper start - fix SPIGOT-5824
File file;
File userCacheFile = new File("usercache.json");

View file

@ -0,0 +1,82 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Mon, 13 Jul 2020 06:22:54 -0700
Subject: [PATCH] Fix AdvancementDataPlayer leak due from quitting early in
login
Move the criterion storage to the AdvancementDataPlayer object
itself, so the criterion object stores no references - and thus
needs no cleanup.
diff --git a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
index 584f48aba7bfec07a75b5a37da4ba7439610543c..c25c1cfca010ed625b6faf310be2edeccd6667bc 100644
--- a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
+++ b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
@@ -14,22 +14,24 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.storage.loot.LootContext;
public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerInstance> implements CriterionTrigger<T> {
- private final Map<PlayerAdvancements, Set<CriterionTrigger.Listener<T>>> players = Maps.newIdentityHashMap();
+ //private final Map<PlayerAdvancements, Set<CriterionTrigger.Listener<T>>> players = Maps.newIdentityHashMap(); // Paper - moved into AdvancementDataPlayer to fix memory leak
+
+ public SimpleCriterionTrigger() {}
@Override
public final void addPlayerListener(PlayerAdvancements manager, CriterionTrigger.Listener<T> conditions) {
- this.players.computeIfAbsent(manager, (managerx) -> {
+ manager.criterionData.computeIfAbsent(this, (managerx) -> { // Paper - fix AdvancementDataPlayer leak
return Sets.newHashSet();
}).add(conditions);
}
@Override
public final void removePlayerListener(PlayerAdvancements manager, CriterionTrigger.Listener<T> conditions) {
- Set<CriterionTrigger.Listener<T>> set = this.players.get(manager);
+ Set<CriterionTrigger.Listener<T>> set = (Set) manager.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
if (set != null) {
set.remove(conditions);
if (set.isEmpty()) {
- this.players.remove(manager);
+ manager.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
}
}
@@ -37,7 +39,7 @@ public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerI
@Override
public final void removePlayerListeners(PlayerAdvancements tracker) {
- this.players.remove(tracker);
+ tracker.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
}
protected abstract T createInstance(JsonObject obj, EntityPredicate.Composite playerPredicate, DeserializationContext predicateDeserializer);
@@ -50,7 +52,7 @@ public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerI
protected void trigger(ServerPlayer player, Predicate<T> tester) {
PlayerAdvancements playerAdvancements = player.getAdvancements();
- Set<CriterionTrigger.Listener<T>> set = this.players.get(playerAdvancements);
+ Set<CriterionTrigger.Listener<T>> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
if (set != null && !set.isEmpty()) {
LootContext lootContext = EntityPredicate.createContext(player, player);
List<CriterionTrigger.Listener<T>> list = null;
diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java
index ce02a467c1c3434f2cdb112ceb9794196069a820..e05e5710c81b7dbb648afbfe16f843e7ae310752 100644
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
+++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java
@@ -39,6 +39,7 @@ import net.minecraft.advancements.Criterion;
import net.minecraft.advancements.CriterionProgress;
import net.minecraft.advancements.CriterionTrigger;
import net.minecraft.advancements.CriterionTriggerInstance;
+import net.minecraft.advancements.critereon.SimpleCriterionTrigger;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.network.protocol.game.ClientboundSelectAdvancementsTabPacket;
@@ -70,6 +71,8 @@ public class PlayerAdvancements {
private Advancement lastSelectedTab;
private boolean isFirstPacket = true;
+ public final Map<SimpleCriterionTrigger, Set<CriterionTrigger.Listener>> criterionData = Maps.newIdentityHashMap(); // Paper - fix advancement data player leakage
+
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerManager, ServerAdvancementManager advancementLoader, File advancementFile, ServerPlayer owner) {
this.dataFixer = dataFixer;
this.playerList = playerManager;

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sun, 26 Jul 2020 12:11:39 +0100
Subject: [PATCH] Add missing strikeLighting call to
World#spigot()#strikeLightningEffect
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index f72471ac82907a0d5112598b3289689495285944..d79a711d4080ad8acb2c240870be9d99a0b84cea 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -2623,6 +2623,7 @@ public class CraftWorld implements World {
lightning.moveTo( loc.getX(), loc.getY(), loc.getZ() );
lightning.visualOnly = true;
lightning.isSilent = isSilent;
+ world.strikeLightning( lightning );
return (LightningStrike) lightning.getBukkitEntity();
}
};

View file

@ -0,0 +1,94 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Fri, 24 Jul 2020 15:56:05 -0700
Subject: [PATCH] Fix some rails connecting improperly
diff --git a/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java b/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
index 41c23abf78c2ca95c26633860adb9360139b3ceb..1242eb55996bca8a63bd7b95d01d0299fb36d105 100644
--- a/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
@@ -65,6 +65,7 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl
state = this.updateDir(world, pos, state, true);
if (this.isStraight) {
state.neighborChanged(world, pos, this, pos, notify);
+ state = world.getBlockState(pos); // Paper - don't desync, update again
}
return state;
diff --git a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
index 2335e7af6bc16a0d65c7818c316f3194c680c69d..63c7f2cf530ac9562960ae5a3cbc6e511a009377 100644
--- a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
@@ -70,6 +70,7 @@ public class DetectorRailBlock extends BaseRailBlock {
private void checkPressed(Level world, BlockPos pos, BlockState state) {
if (this.canSurvive(state, world, pos)) {
+ if (state.getBlock() != this) { return; } // Paper - not our block, don't do anything
boolean flag = (Boolean) state.getValue(DetectorRailBlock.POWERED);
boolean flag1 = false;
List<AbstractMinecart> list = this.getInteractingMinecartOfType(world, pos, AbstractMinecart.class, (entity) -> {
diff --git a/src/main/java/net/minecraft/world/level/block/RailState.java b/src/main/java/net/minecraft/world/level/block/RailState.java
index a205e04bce8706302e4a077646749d05dee98251..0f24187dc3f1340d142f88cbac64c4f5c333e5b8 100644
--- a/src/main/java/net/minecraft/world/level/block/RailState.java
+++ b/src/main/java/net/minecraft/world/level/block/RailState.java
@@ -10,13 +10,19 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.RailShape;
public class RailState {
- private final Level level;
- private final BlockPos pos;
+ private final Level level; public final Level getWorld() { return this.level; } // Paper - OBFHELPER
+ private final BlockPos pos; public final BlockPos getPos() { return this.pos; } // Paper - OBFHELPER
private final BaseRailBlock block;
- private BlockState state;
+ private BlockState state; public final BlockState getRailState() { return this.state; } // Paper - OBFHELPER
private final boolean isStraight;
private final List<BlockPos> connections = Lists.newArrayList();
+ // Paper start - prevent desync
+ public boolean isValid() {
+ return this.getWorld().getBlockState(this.getPos()).getBlock() == this.getRailState().getBlock();
+ }
+ // Paper end - prevent desync
+
public RailState(Level world, BlockPos pos, BlockState state) {
this.level = world;
this.pos = pos;
@@ -143,6 +149,11 @@ public class RailState {
}
private void connectTo(RailState placementHelper) {
+ // Paper start - prevent desync
+ if (!this.isValid() || !placementHelper.isValid()) {
+ return;
+ }
+ // Paper end - prevent desync
this.connections.add(placementHelper.pos);
BlockPos blockPos = this.pos.north();
BlockPos blockPos2 = this.pos.south();
@@ -333,10 +344,15 @@ public class RailState {
this.state = this.state.setValue(this.block.getShapeProperty(), railShape2);
if (forceUpdate || this.level.getBlockState(this.pos) != this.state) {
this.level.setBlock(this.pos, this.state, 3);
+ // Paper start - prevent desync
+ if (!this.isValid()) {
+ return this;
+ }
+ // Paper end - prevent desync
for(int i = 0; i < this.connections.size(); ++i) {
RailState railState = this.getRail(this.connections.get(i));
- if (railState != null) {
+ if (railState != null && railState.isValid()) { // Paper - prevent desync
railState.removeSoftConnections();
if (railState.canConnectTo(this)) {
railState.connectTo(this);
@@ -349,6 +365,6 @@ public class RailState {
}
public BlockState getState() {
- return this.state;
+ return this.getWorld().getBlockState(this.getPos()); // Paper - prevent desync
}
}

View file

@ -0,0 +1,104 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 9 Aug 2020 08:59:25 +0300
Subject: [PATCH] Incremental player saving
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index b67ba8f75e4a3358d7c2462918b85b0bf9b5a922..fdbd8b89bb8bf3b61f60b812b90483c98a3d5ccb 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -440,4 +440,15 @@ public class PaperConfig {
allowPistonDuplication = getBoolean("settings.unsupported-settings.allow-piston-duplication", config.getBoolean("settings.unsupported-settings.allow-tnt-duplication", false));
set("settings.unsupported-settings.allow-tnt-duplication", null);
}
+
+ public static int playerAutoSaveRate = -1;
+ public static int maxPlayerAutoSavePerTick = 10;
+ private static void playerAutoSaveRate() {
+ playerAutoSaveRate = getInt("settings.player-auto-save-rate", -1);
+ maxPlayerAutoSavePerTick = getInt("settings.max-player-auto-save-per-tick", -1);
+ if (maxPlayerAutoSavePerTick == -1) { // -1 Automatic / "Recommended"
+ // 10 should be safe for everyone unless you mass spamming player auto save
+ maxPlayerAutoSavePerTick = (playerAutoSaveRate == -1 || playerAutoSaveRate > 100) ? 10 : 20;
+ }
+ }
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 1feda8b44364c748497174944b26abc4f058f354..1889de77a5e3d9371005b6bd451e2c0e57e96a93 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -955,7 +955,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
if (this.playerList != null) {
MinecraftServer.LOGGER.info("Saving players");
- this.playerList.saveAll();
this.playerList.removeAll(this.isRestarting); // Paper
try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets
}
@@ -1415,9 +1414,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// if (this.autosavePeriod > 0 && this.tickCount % this.autosavePeriod == 0) { // CraftBukkit // Paper - move down
// MinecraftServer.LOGGER.debug("Autosave started"); // Paper
serverAutoSave = (autosavePeriod > 0 && this.tickCount % autosavePeriod == 0); // Paper
+ // Paper start
+ int playerSaveInterval = com.destroystokyo.paper.PaperConfig.playerAutoSaveRate;
+ if (playerSaveInterval < 0) {
+ playerSaveInterval = autosavePeriod;
+ }
+ // Paper end
this.profiler.push("save");
- if (this.autosavePeriod > 0 && this.tickCount % this.autosavePeriod == 0) { // Paper - moved from above
- this.playerList.saveAll();
+ if (playerSaveInterval > 0) { // Paper
+ this.playerList.savePlayers(playerSaveInterval); // Paper
// this.saveAllChunks(true, false, false); // Paper - saved incrementally below
} // Paper start
for (ServerLevel level : this.getAllLevels()) {
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index cd34b5aa61c78d8138500a93f0a9714bedd7ed86..b49fa995973f860a95d937c98e2821435262ce25 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -169,6 +169,7 @@ public class ServerPlayer extends Player {
public final int getViewDistance() { return this.getLevel().getChunkSource().chunkMap.viewDistance - 1; } // Paper - placeholder
private static final Logger LOGGER = LogManager.getLogger();
+ public long lastSave = MinecraftServer.currentTick; // Paper
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
public ServerGamePacketListenerImpl connection;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 9c594c0f142ca10b7c1df50faf45ccb3f7468ba9..8c62367888af566dd9be4bb5cd301c26e0248e46 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -561,6 +561,7 @@ public abstract class PlayerList {
protected void save(ServerPlayer player) {
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
if (!player.didPlayerJoinEvent) return; // Paper - If we never fired PJE, we disconnected during login. Data has not changed, and additionally, our saved vehicle is not loaded! If we save now, we will lose our vehicle (CraftBukkit bug)
+ player.lastSave = MinecraftServer.currentTick; // Paper
this.playerIo.save(player);
ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit
@@ -1198,10 +1199,21 @@ public abstract class PlayerList {
}
public void saveAll() {
- net.minecraft.server.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
+ // Paper start - incremental player saving
+ savePlayers(null);
+ }
+ public void savePlayers(Integer interval) {
+ MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
MinecraftTimings.savePlayers.startTiming(); // Paper
+ int numSaved = 0;
+ long now = MinecraftServer.currentTick;
for (int i = 0; i < this.players.size(); ++i) {
- this.save(this.players.get(i));
+ ServerPlayer entityplayer = this.players.get(i);
+ if (interval == null || now - entityplayer.lastSave >= interval) {
+ this.save(entityplayer);
+ if (interval != null && ++numSaved <= com.destroystokyo.paper.PaperConfig.maxPlayerAutoSavePerTick) { break; }
+ }
+ // Paper end
}
MinecraftTimings.savePlayers.stopTiming(); // Paper
return null; }); // Paper - ensure main

View file

@ -0,0 +1,18 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Fri, 14 Aug 2020 23:41:19 +0200
Subject: [PATCH] Don't mark null chunk sections for block updates
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
index 1f67c9c5f7161ea687983e7ae0ec7d259da9acd3..32bcc55ce15d832e2182d89acecd715947b1667d 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -315,6 +315,7 @@ public class ChunkHolder {
this.a(world, blockposition, iblockdata);
} else {
LevelChunkSection chunksection = chunk.getSections()[j];
+ if (chunksection == null) chunksection = new LevelChunkSection(sectionposition.getY(), chunk, world, true); // Paper - make a new chunk section if none was found
ClientboundSectionBlocksUpdatePacket packetplayoutmultiblockchange = new ClientboundSectionBlocksUpdatePacket(sectionposition, shortset, chunksection, this.resendLight);
this.broadcast(packetplayoutmultiblockchange, false);

View file

@ -0,0 +1,51 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 15 Aug 2020 08:04:49 -0500
Subject: [PATCH] Fix MC-187716 Use configured height
diff --git a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherCappedSurfaceBuilder.java b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherCappedSurfaceBuilder.java
index 5ad6e0ef718a1775a2310925b8273120687230b1..88fbd8a925d84184116051082514ef4d45c98acf 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherCappedSurfaceBuilder.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherCappedSurfaceBuilder.java
@@ -1,4 +1,5 @@
package net.minecraft.world.level.levelgen.surfacebuilders;
+<<<<<<< found
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -42,7 +43,7 @@ public abstract class NetherCappedSurfaceBuilder extends SurfaceBuilder<SurfaceB
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
BlockState blockState3 = chunk.getBlockState(mutableBlockPos.set(k, 128, m));
- for(int p = 127; p >= i; --p) {
+ for(int p = height; p >= i; --p) { // Paper - fix MC-187716 - use configured height
mutableBlockPos.set(k, p, m);
BlockState blockState4 = chunk.getBlockState(mutableBlockPos);
if (blockState3.is(defaultBlock.getBlock()) && (blockState4.isAir() || blockState4 == defaultFluid)) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherForestSurfaceBuilder.java b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherForestSurfaceBuilder.java
index fbb756504609285d96e01c4079be06561f75331e..aa6be90ac272c7e1186d177768230b7f52371e68 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherForestSurfaceBuilder.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherForestSurfaceBuilder.java
@@ -34,7 +34,7 @@ public class NetherForestSurfaceBuilder extends SurfaceBuilder<SurfaceBuilderBas
int o = -1;
BlockState blockState = surfaceBuilderBaseConfiguration.getUnderMaterial();
- for(int p = 127; p >= i; --p) {
+ for(int p = height; p >= i; --p) { // Paper - fix MC-187716 - use configured height
mutableBlockPos.set(k, p, m);
BlockState blockState2 = surfaceBuilderBaseConfiguration.getTopMaterial();
BlockState blockState3 = chunk.getBlockState(mutableBlockPos);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherSurfaceBuilder.java b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherSurfaceBuilder.java
index 0cdb3a1ca76375fc69d1709cdd34d4176a99a617..206f74305a01604892ff98ece0c8344cc5582d14 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherSurfaceBuilder.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherSurfaceBuilder.java
@@ -36,7 +36,7 @@ public class NetherSurfaceBuilder extends SurfaceBuilder<SurfaceBuilderBaseConfi
BlockState blockState = surfaceBuilderBaseConfiguration.getTopMaterial();
BlockState blockState2 = surfaceBuilderBaseConfiguration.getUnderMaterial();
- for(int p = 127; p >= i; --p) {
+ for(int p = height; p >= i; --p) { // Paper - fix MC-187716 - use configured height
mutableBlockPos.set(k, p, m);
BlockState blockState3 = chunk.getBlockState(mutableBlockPos);
if (blockState3.isAir()) {

View file

@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: mbax <matt@phozop.net>
Date: Mon, 17 Aug 2020 12:17:37 -0400
Subject: [PATCH] Fix regex mistake in CB NBT int deserialization
The existing regex is too open and allows for the absence of any actual
number data, detecting an NBT entry of just the letter "i" in upper or
lower case. This causes a single-character NBT entry to be processed as
an integer ending in "i", passing an empty String to to Integer.parseInt,
triggering an exception in loading the item.
This commit forces numbers to be present prior to the ending "i"
letter.
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java b/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java
index a7f4054002bd176fccf8357e9a23de66dd9e0dc5..207e4302161b3abe2ade56c9dc9c31820010fa42 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java
@@ -19,7 +19,7 @@ import net.minecraft.nbt.TagParser;
public class CraftNBTTagConfigSerializer {
private static final Pattern ARRAY = Pattern.compile("^\\[.*]");
- private static final Pattern INTEGER = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)?i", Pattern.CASE_INSENSITIVE);
+ private static final Pattern INTEGER = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)i", Pattern.CASE_INSENSITIVE); // Paper - fix regex
private static final Pattern DOUBLE = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", Pattern.CASE_INSENSITIVE);
private static final TagParser MOJANGSON_PARSER = new TagParser(new StringReader(""));

View file

@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach@zachbr.io>
Date: Tue, 23 Jul 2019 20:44:47 -0500
Subject: [PATCH] Do not let the server load chunks from newer versions
If the server attempts to load a chunk generated by a newer version of
the game, immediately stop the server to prevent data corruption.
You can override this functionality at your own peril.
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index b4246524dd11ad1e1dc94c56eee966c5a54d9ecc..fad795c67829f89b21d78e822c7b15f2ea560184 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -98,10 +98,25 @@ public class ChunkSerializer {
holder.tasks.forEach(Runnable::run);
return holder.protoChunk;
}
+
+ // Paper start
+ private static final int CURRENT_DATA_VERSION = SharedConstants.getCurrentVersion().getWorldVersion();
+ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion");
+ // Paper end
+
public static InProgressChunkHolder loadChunk(ServerLevel world, StructureManager structureManager, PoiManager poiStorage, ChunkPos pos, CompoundTag nbt, boolean distinguish) {
java.util.ArrayDeque<Runnable> tasksToExecuteOnMain = new java.util.ArrayDeque<>();
// Paper end
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
+ // Paper start - Do NOT attempt to load chunks saved with newer versions
+ if (nbt.contains("DataVersion", 99)) {
+ int dataVersion = nbt.getInt("DataVersion");
+ if (!JUST_CORRUPT_IT && dataVersion > CURRENT_DATA_VERSION) {
+ new RuntimeException("Server attempted to load chunk saved with newer version of minecraft! " + dataVersion + " > " + CURRENT_DATA_VERSION).printStackTrace();
+ System.exit(1);
+ }
+ }
+ // Paper end
BiomeSource worldchunkmanager = chunkgenerator.getBiomeSource();
CompoundTag nbttagcompound1 = nbt.getCompound("Level"); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate
ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate

View file

@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DigitalRegent <misterwener@gmail.com>
Date: Sat, 11 Apr 2020 13:10:58 +0200
Subject: [PATCH] Brand support
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 99a16a2f0c2dc227dd45db1964c2d47ffdcda73e..0176b85a031b33cb2a12bb75079f5e3111f4f2b7 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
import com.google.common.primitives.Floats;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.StringReader;
+import io.netty.buffer.Unpooled;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry;
@@ -38,6 +39,7 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.Connection;
+import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
@@ -259,6 +261,8 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
private static final int MAX_SIGN_LINE_LENGTH = Integer.getInteger("Paper.maxSignLength", 80);
private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
+ private String clientBrandName = null; // Paper - Brand name
+
public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player) {
this.server = server;
this.connection = connection;
@@ -3000,6 +3004,8 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
private static final ResourceLocation CUSTOM_REGISTER = new ResourceLocation("register");
private static final ResourceLocation CUSTOM_UNREGISTER = new ResourceLocation("unregister");
+ private static final ResourceLocation MINECRAFT_BRAND = new ResourceLocation("brand"); // Paper - Brand support
+
@Override
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
@@ -3027,6 +3033,15 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
try {
byte[] data = new byte[packet.data.readableBytes()];
packet.data.readBytes(data);
+ // Paper start - Brand support
+ if (packet.identifier.equals(MINECRAFT_BRAND)) {
+ try {
+ this.clientBrandName = new FriendlyByteBuf(Unpooled.copiedBuffer(data)).readUtf(256);
+ } catch (StringIndexOutOfBoundsException ex) {
+ this.clientBrandName = "illegal";
+ }
+ }
+ // Paper end
this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), packet.identifier.toString(), data);
} catch (Exception ex) {
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex);
@@ -3036,6 +3051,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
}
+ // Paper start - brand support
+ public String getClientBrandName() {
+ return clientBrandName;
+ }
+ // Paper end
+
public final boolean isDisconnected() {
return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 0a6d6ea67eaf8b2a59ec45fb3ffb85096f509997..b277c87c0834ddcefcfaebd85c9e69d8d389b59e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2386,6 +2386,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
// Paper end
};
+ // Paper start - brand support
+ @Override
+ public String getClientBrandName() {
+ return getHandle().connection != null ? getHandle().connection.getClientBrandName() : null;
+ }
+ // Paper end
+
public Player.Spigot spigot()
{
return this.spigot;

View file

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sat, 22 Aug 2020 23:59:30 +0200
Subject: [PATCH] Add #setMaxPlayers API
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 8c62367888af566dd9be4bb5cd301c26e0248e46..2f73f1f770e5e1fa422bec9c27e5bd10e86b7538 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -142,7 +142,7 @@ public abstract class PlayerList {
public final PlayerDataStorage playerIo;
private boolean doWhiteList;
private final RegistryAccess.RegistryHolder registryHolder;
- protected final int maxPlayers;
+ protected int maxPlayers; public final void setMaxPlayers(int maxPlayers) { this.maxPlayers = maxPlayers; } // Paper - remove final and add setter
private int viewDistance;
private boolean allowCheatsForAllPlayers;
private static final boolean ALLOW_LOGOUTIVATOR = false;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index df2c41d18377d8519d5537186d529ecc1901f58a..74de169828d7e1e55d15546eb637a87268610700 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -616,6 +616,13 @@ public final class CraftServer implements Server {
return this.playerList.getMaxPlayers();
}
+ // Paper start
+ @Override
+ public void setMaxPlayers(int maxPlayers) {
+ this.playerList.setMaxPlayers(maxPlayers);
+ }
+ // Paper end
+
// NOTE: These are dependent on the corresponding call in MinecraftServer
// so if that changes this will need to as well
@Override

View file

@ -0,0 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 23 Aug 2020 19:36:22 +0200
Subject: [PATCH] Add playPickupItemAnimation to LivingEntity
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index a7a6757b83c94a0c0926097021015815f8f18b8e..c01eae70fe12970e9f617bf14e542b33572bcf4c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -806,5 +806,10 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
((Mob) getHandle()).getJumpControl().jump();
}
}
+
+ @Override
+ public void playPickupItemAnimation(org.bukkit.entity.Item item, int quantity) {
+ getHandle().take(((CraftItem) item).getHandle(), quantity);
+ }
// Paper end
}

View file

@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sun, 23 Aug 2020 19:01:04 +0200
Subject: [PATCH] Don't require FACING data
diff --git a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
index 0c286d7254f653bc855b1cb329fa76e3c1669b3c..05c0f0049421bc897f8e722331e30a6756ebbeea 100644
--- a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
@@ -14,20 +14,22 @@ import org.bukkit.event.block.BlockDispenseEvent;
// CraftBukkit end
public class DefaultDispenseItemBehavior implements DispenseItemBehavior {
+ private Direction enumdirection; // Paper
public DefaultDispenseItemBehavior() {}
@Override
public final ItemStack dispense(BlockSource pointer, ItemStack stack) {
+ enumdirection = pointer.getBlockState().getValue(DispenserBlock.FACING); // Paper - cache facing direction
ItemStack itemstack1 = this.execute(pointer, stack);
this.playSound(pointer);
- this.playAnimation(pointer, (Direction) pointer.getBlockState().getValue(DispenserBlock.FACING));
+ this.playAnimation(pointer, enumdirection); // Paper - cache facing direction
return itemstack1;
}
protected ItemStack execute(BlockSource pointer, ItemStack stack) {
- Direction enumdirection = (Direction) pointer.getBlockState().getValue(DispenserBlock.FACING);
+ // Paper - cached enum direction
Position iposition = DispenserBlock.getDispensePosition(pointer);
ItemStack itemstack1 = stack.split(1);

View file

@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 22 Aug 2020 23:36:21 +0200
Subject: [PATCH] Fix SpawnChangeEvent not firing for all use-cases
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index bdabcdb60dbfb803ead13c42c8dd5e100b37dc00..4ae56444d258cdf44a02256315d6aae84e2f53be 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1679,12 +1679,14 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
}
// Paper end
+ public final void setSpawn(BlockPos blockposition, float f) { this.setDefaultSpawnPos(blockposition, f); } // Paper - OBFHELPER
public void setDefaultSpawnPos(BlockPos pos, float angle) {
// Paper - configurable spawn radius
BlockPos prevSpawn = this.getSharedSpawnPos();
//ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(this.worldData.a(), 0, this.worldData.c()));
this.levelData.setSpawn(pos, angle);
+ new org.bukkit.event.world.SpawnChangeEvent(getWorld(), MCUtil.toLocation(this, prevSpawn)).callEvent(); // Paper
if (this.keepSpawnInMemory) {
// if this keepSpawnInMemory is false a plugin has already removed our tickets, do not re-add
this.removeTicketsForSpawn(this.paperConfig.keepLoadedRange, prevSpawn);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index d79a711d4080ad8acb2c240870be9d99a0b84cea..4ca674fac0e1ed354a0c49284c21ca2b117dd852 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -386,11 +386,13 @@ public class CraftWorld implements World {
public boolean setSpawnLocation(int x, int y, int z, float angle) {
try {
Location previousLocation = this.getSpawnLocation();
- world.levelData.setSpawn(new BlockPos(x, y, z), angle);
+ world.setSpawn(new BlockPos(x, y, z), angle); // Paper - use WorldServer#setSpawn
+ // Paper start - move to nms.World
// Notify anyone who's listening.
- SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation);
- this.server.getPluginManager().callEvent(event);
+ // SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation);
+ // server.getPluginManager().callEvent(event);
+ // Paper end
return true;
} catch (Exception e) {

View file

@ -0,0 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <Blake.Galbreath@GMail.com>
Date: Sun, 23 Aug 2020 16:32:11 +0200
Subject: [PATCH] Add moon phase API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 4ca674fac0e1ed354a0c49284c21ca2b117dd852..d0b2de0f0a37554eb812aa8c7c20f1067807dc40 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -325,6 +325,11 @@ public class CraftWorld implements World {
public int getPlayerCount() {
return world.players().size();
}
+
+ @Override
+ public io.papermc.paper.world.MoonPhase getMoonPhase() {
+ return io.papermc.paper.world.MoonPhase.getPhase(getFullTime() / 24000L);
+ }
// Paper end
private static final Random rand = new Random();

View file

@ -0,0 +1,74 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: commandblockguy <commandblockguy1@gmail.com>
Date: Fri, 14 Aug 2020 14:44:14 -0500
Subject: [PATCH] Prevent headless pistons from being created
Prevent headless pistons from being created by explosions or tree/mushroom growth.
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index fdbd8b89bb8bf3b61f60b812b90483c98a3d5ccb..faa1b775e45563b93ac1d5b904938b1f5ad8d80c 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -441,6 +441,12 @@ public class PaperConfig {
set("settings.unsupported-settings.allow-tnt-duplication", null);
}
+ public static boolean allowHeadlessPistons;
+ private static void allowHeadlessPistons() {
+ config.set("settings.unsupported-settings.allow-headless-pistons-readme", "This setting controls if players should be able to create headless pistons.");
+ allowHeadlessPistons = getBoolean("settings.unsupported-settings.allow-headless-pistons", false);
+ }
+
public static int playerAutoSaveRate = -1;
public static int maxPlayerAutoSavePerTick = 10;
private static void playerAutoSaveRate() {
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index a12af10e28f2d023ba6f916b5e7a53539416713f..822a8dbfaea0a312c4eb2849f2386ecd401b13e9 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -15,6 +15,7 @@ import java.util.Random;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
@@ -35,6 +36,8 @@ import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.piston.PistonHeadBlock;
+import net.minecraft.world.level.block.piston.PistonMovingBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.material.FluidState;
@@ -189,6 +192,15 @@ public class Explosion {
if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f) && blockposition.getY() < 256 && blockposition.getY() >= 0) { // CraftBukkit - don't wrap explosions
set.add(blockposition);
+ // Paper start - prevent headless pistons from forming
+ if (!com.destroystokyo.paper.PaperConfig.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) {
+ BlockEntity extension = this.level.getBlockEntity(blockposition);
+ if (extension instanceof PistonMovingBlockEntity && ((PistonMovingBlockEntity) extension).isHead()) {
+ Direction direction = iblockdata.getValue(PistonHeadBlock.FACING);
+ set.add(blockposition.relative(direction.getOpposite()));
+ }
+ }
+ // Paper end
}
d4 += d0 * 0.30000001192092896D;
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
index 87bedba9ab495edcce289c6665271d92b7165944..985f1112963c3b644a88788a6b4f8a9bd5f5c11a 100644
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -66,6 +66,8 @@ public class PistonMovingBlockEntity extends BlockEntity {
return this.direction;
}
+ public final boolean isHead() { return this.isSourcePiston(); } // Paper - OBFHELPER
+
public boolean isSourcePiston() {
return this.isSourcePiston;
}