patches ...
This commit is contained in:
parent
bdbdca8a56
commit
5513f8a795
148 changed files with 361 additions and 355 deletions
167
patches/server/0424-incremental-chunk-and-player-saving.patch
Normal file
167
patches/server/0424-incremental-chunk-and-player-saving.patch
Normal file
|
@ -0,0 +1,167 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 9 Jun 2019 03:53:22 +0100
|
||||
Subject: [PATCH] incremental chunk and player saving
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 87e0cc467a2139e763130a375387b6df46336992..a82f7dd2cbc2f6311b810f117f0970a47db85818 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -901,7 +901,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
try {
|
||||
this.isSaving = true;
|
||||
- this.getPlayerList().saveAll();
|
||||
+ this.getPlayerList().saveAll(); // Diff on change
|
||||
flag3 = this.saveAllChunks(suppressLogs, flush, force);
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
@@ -1433,16 +1433,28 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
--this.ticksUntilAutosave;
|
||||
- // CraftBukkit start
|
||||
- if (this.autosavePeriod > 0 && this.ticksUntilAutosave <= 0) {
|
||||
- this.ticksUntilAutosave = this.autosavePeriod;
|
||||
- // CraftBukkit end
|
||||
- MinecraftServer.LOGGER.debug("Autosave started");
|
||||
- this.profiler.push("save");
|
||||
- this.saveEverything(true, false, false);
|
||||
- this.profiler.pop();
|
||||
- MinecraftServer.LOGGER.debug("Autosave finished");
|
||||
+ // Paper start - incremental chunk and player saving
|
||||
+ int playerSaveInterval = io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.rate;
|
||||
+ if (playerSaveInterval < 0) {
|
||||
+ playerSaveInterval = autosavePeriod;
|
||||
}
|
||||
+ this.profiler.push("save");
|
||||
+ final boolean fullSave = autosavePeriod > 0 && this.tickCount % autosavePeriod == 0;
|
||||
+ try {
|
||||
+ this.isSaving = true;
|
||||
+ if (playerSaveInterval > 0) {
|
||||
+ this.playerList.saveAll(playerSaveInterval);
|
||||
+ }
|
||||
+ for (ServerLevel level : this.getAllLevels()) {
|
||||
+ if (level.paperConfig().chunks.autoSaveInterval.value() > 0) {
|
||||
+ level.saveIncrementally(fullSave);
|
||||
+ }
|
||||
+ }
|
||||
+ } finally {
|
||||
+ this.isSaving = false;
|
||||
+ }
|
||||
+ this.profiler.pop();
|
||||
+ // Paper end
|
||||
io.papermc.paper.util.CachedLists.reset(); // Paper
|
||||
// Paper start - move executeAll() into full server tick timing
|
||||
try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 3a8a4757b9b39b48cbedd65620a114130ae6ab1c..e725dd92ae15f62b078bda3572d0663468f37939 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -450,6 +450,15 @@ public class ServerChunkCache extends ChunkSource {
|
||||
} // Paper - Timings
|
||||
}
|
||||
|
||||
+ // Paper start - duplicate save, but call incremental
|
||||
+ public void saveIncrementally() {
|
||||
+ this.runDistanceManagerUpdates();
|
||||
+ try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings
|
||||
+ this.chunkMap.saveIncrementally();
|
||||
+ } // Paper - Timings
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// CraftBukkit start
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 8dc958dca402346d94d84c3d5c073cf00c438cee..d9fafffc52b5db0b55022c02b9321d47a2b49827 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1302,6 +1302,37 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
return !this.server.isUnderSpawnProtection(this, pos, player) && this.getWorldBorder().isWithinBounds(pos);
|
||||
}
|
||||
|
||||
+ // Paper start - derived from below
|
||||
+ public void saveIncrementally(boolean doFull) {
|
||||
+ ServerChunkCache chunkproviderserver = this.getChunkSource();
|
||||
+
|
||||
+ if (doFull) {
|
||||
+ org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld()));
|
||||
+ }
|
||||
+
|
||||
+ try (co.aikar.timings.Timing ignored = this.timings.worldSave.startTiming()) {
|
||||
+ if (doFull) {
|
||||
+ this.saveLevelData();
|
||||
+ }
|
||||
+
|
||||
+ this.timings.worldSaveChunks.startTiming(); // Paper
|
||||
+ if (!this.noSave()) chunkproviderserver.saveIncrementally();
|
||||
+ this.timings.worldSaveChunks.stopTiming(); // Paper
|
||||
+
|
||||
+ // Copied from save()
|
||||
+ // CraftBukkit start - moved from MinecraftServer.saveChunks
|
||||
+ if (doFull) { // Paper
|
||||
+ ServerLevel worldserver1 = this;
|
||||
+
|
||||
+ this.serverLevelData.setWorldBorder(worldserver1.getWorldBorder().createSettings());
|
||||
+ this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save());
|
||||
+ this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData());
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) {
|
||||
// Paper start - rewrite chunk system - add close param
|
||||
this.save(progressListener, flush, savingDisabled, false);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 898403dad5e9bac4b565e1c75871245fe5cd7908..25c5f23b859961c792b2ec08404171eea1aedba7 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -190,6 +190,7 @@ import org.bukkit.inventory.MainHand;
|
||||
public class ServerPlayer extends Player {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.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;
|
||||
private static final int FLY_STAT_RECORDING_SPEED = 25;
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index ac5e83589b812290032773755f51c89107ccb5a4..ccf715d1ddb029ebadbab88be8ef1e914b5220be 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -552,6 +552,7 @@ public abstract class PlayerList {
|
||||
|
||||
protected void save(ServerPlayer player) {
|
||||
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
|
||||
+ player.lastSave = MinecraftServer.currentTick; // Paper
|
||||
this.playerIo.save(player);
|
||||
ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit
|
||||
|
||||
@@ -1149,10 +1150,22 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
+ // Paper start - incremental player saving
|
||||
+ this.saveAll(-1);
|
||||
+ }
|
||||
+
|
||||
+ public void saveAll(int interval) {
|
||||
io.papermc.paper.util.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 == -1 || now - entityplayer.lastSave >= interval) {
|
||||
+ this.save(entityplayer);
|
||||
+ if (interval != -1 && ++numSaved >= io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.maxPerTick()) { break; }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
MinecraftTimings.savePlayers.stopTiming(); // Paper
|
||||
return null; }); // Paper - ensure main
|
63
patches/server/0425-Support-old-UUID-format-for-NBT.patch
Normal file
63
patches/server/0425-Support-old-UUID-format-for-NBT.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 29 Jun 2020 03:26:17 -0400
|
||||
Subject: [PATCH] Support old UUID format for NBT
|
||||
|
||||
We have stored UUID in plenty of places that did not get DFU'd
|
||||
|
||||
So just look for old format and load it if it exists.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/net/minecraft/nbt/CompoundTag.java
|
||||
index 135530bc9d7ecd0348ace6474f4ca6d2e1bad283..e464ada187fd1f15efef29a0e5033aeb0c688059 100644
|
||||
--- a/src/main/java/net/minecraft/nbt/CompoundTag.java
|
||||
+++ b/src/main/java/net/minecraft/nbt/CompoundTag.java
|
||||
@@ -237,6 +237,12 @@ public class CompoundTag implements Tag {
|
||||
}
|
||||
|
||||
public void putUUID(String key, UUID value) {
|
||||
+ // Paper start - support old format
|
||||
+ if (this.contains(key + "Most", 99) && this.contains(key + "Least", 99)) {
|
||||
+ this.tags.remove(key + "Most");
|
||||
+ this.tags.remove(key + "Least");
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.tags.put(key, NbtUtils.createUUID(value));
|
||||
}
|
||||
|
||||
@@ -245,10 +251,20 @@ public class CompoundTag implements Tag {
|
||||
* You must use {@link #hasUUID(String)} before or else it <b>will</b> throw an NPE.
|
||||
*/
|
||||
public UUID getUUID(String key) {
|
||||
+ // Paper start - support old format
|
||||
+ if (!contains(key, 11) && this.contains(key + "Most", 99) && this.contains(key + "Least", 99)) {
|
||||
+ return new UUID(this.getLong(key + "Most"), this.getLong(key + "Least"));
|
||||
+ }
|
||||
+ // Paper end
|
||||
return NbtUtils.loadUUID(this.get(key));
|
||||
}
|
||||
|
||||
public boolean hasUUID(String key) {
|
||||
+ // Paper start - support old format
|
||||
+ if (this.contains(key + "Most", 99) && this.contains(key + "Least", 99)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
Tag tag = this.get(key);
|
||||
return tag != null && tag.getType() == IntArrayTag.TYPE && ((IntArrayTag)tag).getAsIntArray().length == 4;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/nbt/NbtUtils.java b/src/main/java/net/minecraft/nbt/NbtUtils.java
|
||||
index 4388f2a8b05f5ed2f0934c1693299a4c92072adc..b65dcff9812dbc3256c080ac264c4aafd83ce276 100644
|
||||
--- a/src/main/java/net/minecraft/nbt/NbtUtils.java
|
||||
+++ b/src/main/java/net/minecraft/nbt/NbtUtils.java
|
||||
@@ -72,6 +72,11 @@ public final class NbtUtils {
|
||||
@Nullable
|
||||
public static GameProfile readGameProfile(CompoundTag nbt) {
|
||||
UUID uUID = nbt.hasUUID("Id") ? nbt.getUUID("Id") : Util.NIL_UUID;
|
||||
+ // Paper start - support string UUID's
|
||||
+ if (nbt.contains("Id", Tag.TAG_STRING)) {
|
||||
+ uUID = UUID.fromString(nbt.getString("Id"));
|
||||
+ }
|
||||
+ // Paper end
|
||||
String string = nbt.getString("Name");
|
||||
|
||||
try {
|
|
@ -0,0 +1,44 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 1 Jul 2020 04:50:22 -0400
|
||||
Subject: [PATCH] Convert legacy attributes in Item Meta
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
|
||||
index d4dba8c733c7560e5108b8d239b52e593f8debec..ea48f1119a940056c37d1d203437bfbfdf13663b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
|
||||
@@ -9,6 +9,20 @@ import org.bukkit.attribute.AttributeInstance;
|
||||
public class CraftAttributeMap implements Attributable {
|
||||
|
||||
private final AttributeMap handle;
|
||||
+ // Paper start - convert legacy attributes
|
||||
+ private static final com.google.common.collect.ImmutableMap<String, String> legacyNMS = com.google.common.collect.ImmutableMap.<String, String>builder().put("generic.maxHealth", "generic.max_health").put("Max Health", "generic.max_health").put("zombie.spawnReinforcements", "zombie.spawn_reinforcements").put("Spawn Reinforcements Chance", "zombie.spawn_reinforcements").put("horse.jumpStrength", "horse.jump_strength").put("Jump Strength", "horse.jump_strength").put("generic.followRange", "generic.follow_range").put("Follow Range", "generic.follow_range").put("generic.knockbackResistance", "generic.knockback_resistance").put("Knockback Resistance", "generic.knockback_resistance").put("generic.movementSpeed", "generic.movement_speed").put("Movement Speed", "generic.movement_speed").put("generic.flyingSpeed", "generic.flying_speed").put("Flying Speed", "generic.flying_speed").put("generic.attackDamage", "generic.attack_damage").put("generic.attackKnockback", "generic.attack_knockback").put("generic.attackSpeed", "generic.attack_speed").put("generic.armorToughness", "generic.armor_toughness").build();
|
||||
+
|
||||
+ public static String convertIfNeeded(String nms) {
|
||||
+ if (nms == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ nms = legacyNMS.getOrDefault(nms, nms);
|
||||
+ if (!nms.toLowerCase().equals(nms) || nms.indexOf(' ') != -1) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return nms;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public CraftAttributeMap(AttributeMap handle) {
|
||||
this.handle = handle;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index 4e1f436cbe47ba08c731be781fb372b20c497de6..f66104abef112ed1056f6f70b38c1d7865431a6c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -485,7 +485,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
|
||||
AttributeModifier attribMod = CraftAttributeInstance.convert(nmsModifier);
|
||||
|
||||
- String attributeName = entry.getString(CraftMetaItem.ATTRIBUTES_IDENTIFIER.NBT);
|
||||
+ String attributeName = CraftAttributeMap.convertIfNeeded(entry.getString(CraftMetaItem.ATTRIBUTES_IDENTIFIER.NBT)); // Paper
|
||||
if (attributeName == null || attributeName.isEmpty()) {
|
||||
continue;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: JRoy <joshroy126@gmail.com>
|
||||
Date: Mon, 29 Jun 2020 17:03:06 -0400
|
||||
Subject: [PATCH] Remove some streams from structures
|
||||
|
||||
This showed up a lot in the spark profiler, should have a low-medium performance improvement.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java b/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java
|
||||
index bb8d8edb47621665872a5e8fc01512ba40c1b913..5d721dc196a6bde511f46dbdedb2e1d98553ac52 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java
|
||||
@@ -36,9 +36,10 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
|
||||
int j = pos.getMinBlockZ();
|
||||
ObjectList<Beardifier.Rigid> objectList = new ObjectArrayList<>(10);
|
||||
ObjectList<JigsawJunction> objectList2 = new ObjectArrayList<>(32);
|
||||
- world.startsForStructure(pos, (structure) -> {
|
||||
+ // Paper start - replace for each
|
||||
+ for (net.minecraft.world.level.levelgen.structure.StructureStart start : world.startsForStructure(pos, (structure) -> {
|
||||
return structure.terrainAdaptation() != TerrainAdjustment.NONE;
|
||||
- }).forEach((start) -> {
|
||||
+ })) { // Paper end
|
||||
TerrainAdjustment terrainAdjustment = start.getStructure().terrainAdaptation();
|
||||
|
||||
for(StructurePiece structurePiece : start.getPieces()) {
|
||||
@@ -51,9 +52,11 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
|
||||
}
|
||||
|
||||
for(JigsawJunction jigsawJunction : poolElementStructurePiece.getJunctions()) {
|
||||
- int i = jigsawJunction.getSourceX();
|
||||
- int j = jigsawJunction.getSourceZ();
|
||||
- if (i > i - 12 && j > j - 12 && i < i + 15 + 12 && j < j + 15 + 12) {
|
||||
+ // Paper start - decompile fix
|
||||
+ int i2 = jigsawJunction.getSourceX();
|
||||
+ int j2 = jigsawJunction.getSourceZ();
|
||||
+ if (i2 > i - 12 && j2 > j - 12 && i2 < i + 15 + 12 && j2 < j + 15 + 12) {
|
||||
+ // Paper end
|
||||
objectList2.add(jigsawJunction);
|
||||
}
|
||||
}
|
||||
@@ -63,7 +66,7 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
|
||||
}
|
||||
}
|
||||
|
||||
- });
|
||||
+ } // Paper
|
||||
return new Beardifier(objectList.iterator(), objectList2.iterator());
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: JRoy <joshroy126@gmail.com>
|
||||
Date: Wed, 1 Jul 2020 18:01:49 -0400
|
||||
Subject: [PATCH] Remove streams from classes related villager gossip
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java
|
||||
index 76dffb2705e5207db96895f82f1c7c5638f817c6..097007c1c25ba55d9916fc820dd1d1149d81f6f4 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java
|
||||
@@ -61,8 +61,22 @@ public class GossipContainer {
|
||||
});
|
||||
}
|
||||
|
||||
+ // Paper start - Remove streams from reputation
|
||||
+ private List<GossipContainer.GossipEntry> decompress() {
|
||||
+ List<GossipContainer.GossipEntry> list = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
||||
+ for (Map.Entry<UUID, GossipContainer.EntityGossips> entry : this.gossips.entrySet()) {
|
||||
+ for (GossipContainer.GossipEntry cur : entry.getValue().decompress(entry.getKey())) {
|
||||
+ if (cur.weightedValue() != 0) {
|
||||
+ list.add(cur);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return list;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
private Collection<GossipContainer.GossipEntry> selectGossipsForTransfer(RandomSource random, int count) {
|
||||
- List<GossipContainer.GossipEntry> list = this.unpack().toList();
|
||||
+ List<GossipContainer.GossipEntry> list = this.decompress(); // Paper - Remove streams from reputation
|
||||
if (list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
@@ -156,7 +170,7 @@ public class GossipContainer {
|
||||
}
|
||||
|
||||
public <T> T store(DynamicOps<T> ops) {
|
||||
- return GossipContainer.GossipEntry.LIST_CODEC.encodeStart(ops, this.unpack().toList()).resultOrPartial((error) -> {
|
||||
+ return GossipContainer.GossipEntry.LIST_CODEC.encodeStart(ops, this.decompress()).resultOrPartial((error) -> {
|
||||
LOGGER.warn("Failed to serialize gossips: {}", (Object)error);
|
||||
}).orElseGet(ops::emptyList);
|
||||
}
|
||||
@@ -184,11 +198,23 @@ public class GossipContainer {
|
||||
final Object2IntMap<GossipType> entries = new Object2IntOpenHashMap<>();
|
||||
|
||||
public int weightedValue(Predicate<GossipType> gossipTypeFilter) {
|
||||
- return this.entries.object2IntEntrySet().stream().filter((entry) -> {
|
||||
- return gossipTypeFilter.test(entry.getKey());
|
||||
- }).mapToInt((entry) -> {
|
||||
- return entry.getIntValue() * (entry.getKey()).weight;
|
||||
- }).sum();
|
||||
+ // Paper start - Remove streams from reputation
|
||||
+ int weight = 0;
|
||||
+ for (Object2IntMap.Entry<GossipType> entry : entries.object2IntEntrySet()) {
|
||||
+ if (gossipTypeFilter.test(entry.getKey())) {
|
||||
+ weight += entry.getIntValue() * entry.getKey().weight;
|
||||
+ }
|
||||
+ }
|
||||
+ return weight;
|
||||
+ }
|
||||
+
|
||||
+ public List<GossipContainer.GossipEntry> decompress(UUID uuid) {
|
||||
+ List<GossipContainer.GossipEntry> list = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
||||
+ for (Object2IntMap.Entry<GossipType> entry : entries.object2IntEntrySet()) {
|
||||
+ list.add(new GossipContainer.GossipEntry(uuid, entry.getKey(), entry.getIntValue()));
|
||||
+ }
|
||||
+ return list;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public Stream<GossipContainer.GossipEntry> unpack(UUID target) {
|
83
patches/server/0429-Support-components-in-ItemMeta.patch
Normal file
83
patches/server/0429-Support-components-in-ItemMeta.patch
Normal file
|
@ -0,0 +1,83 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MiniDigger <admin@benndorf.dev>
|
||||
Date: Sat, 6 Jun 2020 18:13:42 +0200
|
||||
Subject: [PATCH] Support components in ItemMeta
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index f66104abef112ed1056f6f70b38c1d7865431a6c..9c20c225ba46f2126a43e2f879f4849081cae90a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -879,11 +879,23 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
return CraftChatMessage.fromJSONComponent(this.displayName);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public net.md_5.bungee.api.chat.BaseComponent[] getDisplayNameComponent() {
|
||||
+ return displayName == null ? new net.md_5.bungee.api.chat.BaseComponent[0] : net.md_5.bungee.chat.ComponentSerializer.parse(displayName);
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public final void setDisplayName(String name) {
|
||||
this.displayName = CraftChatMessage.fromStringOrNullToJSON(name);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setDisplayNameComponent(net.md_5.bungee.api.chat.BaseComponent[] component) {
|
||||
+ this.displayName = net.md_5.bungee.chat.ComponentSerializer.toString(component);
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean hasDisplayName() {
|
||||
return this.displayName != null;
|
||||
@@ -1026,6 +1038,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
return this.lore == null ? null : new ArrayList<String>(Lists.transform(this.lore, CraftChatMessage::fromJSONComponent));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public List<net.md_5.bungee.api.chat.BaseComponent[]> getLoreComponents() {
|
||||
+ return this.lore == null ? null : new ArrayList<>(this.lore.stream().map(entry ->
|
||||
+ net.md_5.bungee.chat.ComponentSerializer.parse(entry)
|
||||
+ ).collect(java.util.stream.Collectors.toList()));
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public void setLore(List<String> lore) {
|
||||
if (lore == null || lore.isEmpty()) {
|
||||
@@ -1040,6 +1060,21 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setLoreComponents(List<net.md_5.bungee.api.chat.BaseComponent[]> lore) {
|
||||
+ if (lore == null) {
|
||||
+ this.lore = null;
|
||||
+ } else {
|
||||
+ if (this.lore == null) {
|
||||
+ safelyAdd(lore, this.lore = new ArrayList<>(lore.size()), false);
|
||||
+ } else {
|
||||
+ this.lore.clear();
|
||||
+ safelyAdd(lore, this.lore, false);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean hasCustomModelData() {
|
||||
return this.customModelData != null;
|
||||
@@ -1508,6 +1543,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
}
|
||||
|
||||
for (Object object : addFrom) {
|
||||
+ // Paper start - support components
|
||||
+ if(object instanceof net.md_5.bungee.api.chat.BaseComponent[]) {
|
||||
+ addTo.add(net.md_5.bungee.chat.ComponentSerializer.toString((net.md_5.bungee.api.chat.BaseComponent[]) object));
|
||||
+ } else
|
||||
+ // Paper end
|
||||
if (!(object instanceof String)) {
|
||||
if (object != null) {
|
||||
// SPIGOT-7399: Null check via if is important,
|
|
@ -0,0 +1,48 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 9 Dec 2022 03:10:23 -0800
|
||||
Subject: [PATCH] Improve/fix EntityTargetLivingEntityEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java b/src/main/java/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java
|
||||
index 5aeef564cdaabeed88a52635e56073cca3a9d1f1..fe635e46569c67dac1d3581ee930d1bfa8b4030e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java
|
||||
@@ -47,17 +47,30 @@ public class StopAttackingIfTargetInvalid {
|
||||
if (entityinsentient.canAttack(entityliving) && (!shouldForgetIfTargetUnreachable || !StopAttackingIfTargetInvalid.isTiredOfTryingToReachTarget(entityinsentient, behaviorbuilder_b.tryGet(memoryaccessor1))) && entityliving.isAlive() && entityliving.level() == entityinsentient.level() && !alternativeCondition.test(entityliving)) {
|
||||
return true;
|
||||
} else {
|
||||
+ // Paper start - better track target change reason
|
||||
+ final EntityTargetEvent.TargetReason reason;
|
||||
+ if (!entityinsentient.canAttack(entityliving)) {
|
||||
+ reason = EntityTargetEvent.TargetReason.TARGET_INVALID;
|
||||
+ } else if (shouldForgetIfTargetUnreachable && StopAttackingIfTargetInvalid.isTiredOfTryingToReachTarget(entityinsentient, behaviorbuilder_b.tryGet(memoryaccessor1))) {
|
||||
+ reason = EntityTargetEvent.TargetReason.FORGOT_TARGET;
|
||||
+ } else if (!entityliving.isAlive()) {
|
||||
+ reason = EntityTargetEvent.TargetReason.TARGET_DIED;
|
||||
+ } else if (entityliving.level() != entityinsentient.level()) {
|
||||
+ reason = EntityTargetEvent.TargetReason.TARGET_OTHER_LEVEL;
|
||||
+ } else {
|
||||
+ reason = EntityTargetEvent.TargetReason.TARGET_INVALID;
|
||||
+ }
|
||||
+ // Paper end
|
||||
// CraftBukkit start
|
||||
- LivingEntity old = entityinsentient.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse(null);
|
||||
- EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(entityinsentient, null, (old != null && !old.isAlive()) ? EntityTargetEvent.TargetReason.TARGET_DIED : EntityTargetEvent.TargetReason.FORGOT_TARGET);
|
||||
+ EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(entityinsentient, null, reason); // Paper
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
- if (event.getTarget() == null) {
|
||||
- memoryaccessor.erase();
|
||||
- return true;
|
||||
- }
|
||||
- entityliving = ((CraftLivingEntity) event.getTarget()).getHandle();
|
||||
+ // if (event.getTarget() == null) { // Paper - this is wrong, you are skipping the forgetCallback
|
||||
+ // memoryaccessor.erase();
|
||||
+ // return true;
|
||||
+ // }
|
||||
+ // entityliving = ((CraftLivingEntity) event.getTarget()).getHandle();
|
||||
// CraftBukkit end
|
||||
forgetCallback.accept(entityinsentient, entityliving);
|
||||
memoryaccessor.erase();
|
54
patches/server/0431-Add-entity-liquid-API.patch
Normal file
54
patches/server/0431-Add-entity-liquid-API.patch
Normal file
|
@ -0,0 +1,54 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Thu, 2 Jul 2020 18:11:43 -0500
|
||||
Subject: [PATCH] Add entity liquid API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.Entity isInRain()Z
|
||||
public net.minecraft.world.entity.Entity isInBubbleColumn()Z
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index b06c338ee9205d1f4d562571aba83c83f9abd20b..ded0332f5be000e31962e34033e69d17eed51280 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -1372,5 +1372,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason getEntitySpawnReason() {
|
||||
return getHandle().spawnReason;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isUnderWater() {
|
||||
+ return getHandle().isUnderWater();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isInRain() {
|
||||
+ return getHandle().isInRain();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isInBubbleColumn() {
|
||||
+ return getHandle().isInBubbleColumn();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isInWaterOrRain() {
|
||||
+ return getHandle().isInWaterOrRain();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isInWaterOrBubbleColumn() {
|
||||
+ return getHandle().isInWaterOrBubble();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isInWaterOrRainOrBubbleColumn() {
|
||||
+ return getHandle().isInWaterRainOrBubble();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isInLava() {
|
||||
+ return getHandle().isInLava();
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Wed, 1 Jul 2020 11:57:40 -0500
|
||||
Subject: [PATCH] Update itemstack legacy name and lore
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 19e8d10727fc4838cd8261dfec92f3828ea5b09f..b5080861a4aa34a95618bcee7723bd3ec34b09c4 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -195,6 +195,44 @@ public final class ItemStack {
|
||||
list.sort((java.util.Comparator<? super net.minecraft.nbt.Tag>) enchantSorter); // Paper
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
+
|
||||
+ private void processText() {
|
||||
+ CompoundTag display = getTagElement("display");
|
||||
+ if (display != null) {
|
||||
+ if (display.contains("Name", 8)) {
|
||||
+ String json = display.getString("Name");
|
||||
+ if (json != null && json.contains("\u00A7")) {
|
||||
+ try {
|
||||
+ display.put("Name", convert(json));
|
||||
+ } catch (com.google.gson.JsonParseException jsonparseexception) {
|
||||
+ display.remove("Name");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (display.contains("Lore", 9)) {
|
||||
+ ListTag list = display.getList("Lore", 8);
|
||||
+ for (int index = 0; index < list.size(); index++) {
|
||||
+ String json = list.getString(index);
|
||||
+ if (json != null && json.contains("\u00A7")) { // Only try if it has legacy in the unparsed json
|
||||
+ try {
|
||||
+ list.set(index, convert(json));
|
||||
+ } catch (com.google.gson.JsonParseException e) {
|
||||
+ list.set(index, net.minecraft.nbt.StringTag.valueOf(org.bukkit.craftbukkit.util.CraftChatMessage.toJSON(net.minecraft.network.chat.Component.literal(""))));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private net.minecraft.nbt.StringTag convert(String json) {
|
||||
+ Component component = Component.Serializer.fromJson(json);
|
||||
+ if (component.getContents() instanceof net.minecraft.network.chat.contents.LiteralContents literalContents && literalContents.text().contains("\u00A7") && component.getSiblings().isEmpty()) {
|
||||
+ // Only convert if the root component is a single comp with legacy in it, don't convert already normal components
|
||||
+ component = org.bukkit.craftbukkit.util.CraftChatMessage.fromString(literalContents.text())[0];
|
||||
+ }
|
||||
+ return net.minecraft.nbt.StringTag.valueOf(org.bukkit.craftbukkit.util.CraftChatMessage.toJSON(component));
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
public ItemStack(ItemLike item) {
|
||||
@@ -244,6 +282,7 @@ public final class ItemStack {
|
||||
if (nbttagcompound.contains("tag", 10)) {
|
||||
this.tag = nbttagcompound.getCompound("tag").copy();
|
||||
this.processEnchantOrder(this.tag); // Paper
|
||||
+ this.processText(); // Paper
|
||||
this.getItem().verifyTagAfterLoad(this.tag);
|
||||
}
|
||||
|
165
patches/server/0433-Add-PrepareResultEvent.patch
Normal file
165
patches/server/0433-Add-PrepareResultEvent.patch
Normal file
|
@ -0,0 +1,165 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 3 Jul 2020 11:58:56 -0500
|
||||
Subject: [PATCH] Add PrepareResultEvent
|
||||
|
||||
Adds a new event for all crafting stations that generate a result slot item
|
||||
|
||||
Anvil, Grindstone and Smithing now extend this event
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
index e97953e3dad164862d7e2f86bd86a6eff5b80ae2..f00638e9d7baf8b803dd610f2bf6250da34efab3 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
@@ -338,6 +338,7 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
}
|
||||
|
||||
this.createResult();
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareResultEvent(this, RESULT_SLOT); // Paper
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
index fe1ce65b35e83ee0ada77e44b080729346bb3c2d..819187dbcf468d9278ce33bd97688476aab53f8e 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
@@ -150,6 +150,7 @@ public class CartographyTableMenu extends AbstractContainerMenu {
|
||||
this.setupResultSlot(itemstack, itemstack1, itemstack2);
|
||||
}
|
||||
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareResultEvent(this, RESULT_SLOT); // Paper
|
||||
}
|
||||
|
||||
private void setupResultSlot(ItemStack map, ItemStack item, ItemStack oldResult) {
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
index 45242f0ed5a0f98953df5f27fb76874d2d9e3473..811d7415ae843347da374d73b4edfe89642d518a 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
@@ -159,6 +159,7 @@ public class GrindstoneMenu extends AbstractContainerMenu {
|
||||
super.slotsChanged(inventory);
|
||||
if (inventory == this.repairSlots) {
|
||||
this.createResult();
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareResultEvent(this, RESULT_SLOT); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
index 4087e381b2250be387b608d8742f6a6009a52879..ff770b9ce68a62418de0c7ed389650626fa1dcb2 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
@@ -110,6 +110,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
||||
super.slotsChanged(inventory);
|
||||
if (inventory == this.inputSlots) {
|
||||
this.createResult();
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareResultEvent(this, this instanceof SmithingMenu ? 3 : 2); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/LoomMenu.java b/src/main/java/net/minecraft/world/inventory/LoomMenu.java
|
||||
index 5c209a3d81db5326f63c506077fa0bfd241b4b12..757ee83a0ec5d381eb328f31f3bef636a9b72d57 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/LoomMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/LoomMenu.java
|
||||
@@ -248,7 +248,8 @@ public class LoomMenu extends AbstractContainerMenu {
|
||||
this.resultSlot.set(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
- this.broadcastChanges();
|
||||
+ // this.broadcastChanges(); // Paper - done below
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareResultEvent(this, 3); // Paper
|
||||
} else {
|
||||
this.resultSlot.set(ItemStack.EMPTY);
|
||||
this.selectablePatterns = List.of();
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/SmithingMenu.java b/src/main/java/net/minecraft/world/inventory/SmithingMenu.java
|
||||
index 59d9f990a87ab5214fa51e3a6e933bf5ae71b613..857f65be8c4d9ec3a0586017b3f3e8e35cb78b97 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/SmithingMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/SmithingMenu.java
|
||||
@@ -115,6 +115,7 @@ public class SmithingMenu extends ItemCombinerMenu {
|
||||
}
|
||||
}
|
||||
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareResultEvent(this, RESULT_SLOT); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
||||
index 9c2fe69ced7a46bbd8b0fbe10fa67d0a39b0f375..70ecc3f673ebd56b65ad901e10f40c28368cbfac 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
||||
@@ -181,6 +181,7 @@ public class StonecutterMenu extends AbstractContainerMenu {
|
||||
this.setupRecipeList(inventory, itemstack);
|
||||
}
|
||||
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareResultEvent(this, RESULT_SLOT); // Paper
|
||||
}
|
||||
|
||||
private void setupRecipeList(Container input, ItemStack stack) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 839deebc72a575eea5db4decd82c8c8b1884e621..ce0d05009a9b88607a143ad40421d70148491817 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1717,26 +1717,53 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
- public static PrepareAnvilEvent callPrepareAnvilEvent(InventoryView view, ItemStack item) {
|
||||
- PrepareAnvilEvent event = new PrepareAnvilEvent(view, CraftItemStack.asCraftMirror(item).clone());
|
||||
- event.getView().getPlayer().getServer().getPluginManager().callEvent(event);
|
||||
+ // Paper start - disable this method, handled below
|
||||
+ public static void callPrepareAnvilEvent(InventoryView view, ItemStack item) { // Paper - verify nothing uses return - handled below in PrepareResult
|
||||
+ PrepareAnvilEvent event = new PrepareAnvilEvent(view, CraftItemStack.asCraftMirror(item)); // Paper - remove clone
|
||||
+ //event.getView().getPlayer().getServer().getPluginManager().callEvent(event); // Paper - disable event
|
||||
event.getInventory().setItem(2, event.getResult());
|
||||
- return event;
|
||||
+ //return event; // Paper
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
- public static PrepareGrindstoneEvent callPrepareGrindstoneEvent(InventoryView view, ItemStack item) {
|
||||
- PrepareGrindstoneEvent event = new PrepareGrindstoneEvent(view, CraftItemStack.asCraftMirror(item).clone());
|
||||
- event.getView().getPlayer().getServer().getPluginManager().callEvent(event);
|
||||
+ // Paper start - disable this method, handled below
|
||||
+ public static void callPrepareGrindstoneEvent(InventoryView view, ItemStack item) {
|
||||
+ PrepareGrindstoneEvent event = new PrepareGrindstoneEvent(view, CraftItemStack.asCraftMirror(item)); // Paper - remove clone
|
||||
+ // event.getView().getPlayer().getServer().getPluginManager().callEvent(event); // Paper - disable event
|
||||
event.getInventory().setItem(2, event.getResult());
|
||||
- return event;
|
||||
+ // return event; // Paper
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
- public static PrepareSmithingEvent callPrepareSmithingEvent(InventoryView view, ItemStack item) {
|
||||
- PrepareSmithingEvent event = new PrepareSmithingEvent(view, CraftItemStack.asCraftMirror(item).clone());
|
||||
- event.getView().getPlayer().getServer().getPluginManager().callEvent(event);
|
||||
+ // Paper start - disable this method, handled in callPrepareResultEvent
|
||||
+ public static void callPrepareSmithingEvent(InventoryView view, ItemStack item) { // Paper - verify nothing uses return - handled below in PrepareResult
|
||||
+ PrepareSmithingEvent event = new PrepareSmithingEvent(view, CraftItemStack.asCraftMirror(item)); // Paper - remove clone
|
||||
+ //event.getView().getPlayer().getServer().getPluginManager().callEvent(event); // Paper - disable event
|
||||
event.getInventory().setResult(event.getResult());
|
||||
- return event;
|
||||
+ //return event; // Paper
|
||||
}
|
||||
+ // Paper end
|
||||
+
|
||||
+ // Paper start - support specific overrides for prepare result
|
||||
+ public static void callPrepareResultEvent(AbstractContainerMenu container, int resultSlot) {
|
||||
+ com.destroystokyo.paper.event.inventory.PrepareResultEvent event;
|
||||
+ InventoryView view = container.getBukkitView();
|
||||
+ org.bukkit.inventory.ItemStack origItem = view.getTopInventory().getItem(resultSlot);
|
||||
+ CraftItemStack result = origItem != null ? CraftItemStack.asCraftCopy(origItem) : null;
|
||||
+ if (view.getTopInventory() instanceof org.bukkit.inventory.AnvilInventory) {
|
||||
+ event = new PrepareAnvilEvent(view, result);
|
||||
+ } else if (view.getTopInventory() instanceof org.bukkit.inventory.GrindstoneInventory) {
|
||||
+ event = new PrepareGrindstoneEvent(view, result);
|
||||
+ } else if (view.getTopInventory() instanceof org.bukkit.inventory.SmithingInventory) {
|
||||
+ event = new PrepareSmithingEvent(view, result);
|
||||
+ } else {
|
||||
+ event = new com.destroystokyo.paper.event.inventory.PrepareResultEvent(view, result);
|
||||
+ }
|
||||
+ event.callEvent();
|
||||
+ event.getInventory().setItem(resultSlot, event.getResult());
|
||||
+ container.broadcastChanges();;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Mob spawner event.
|
|
@ -0,0 +1,19 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 5 Jul 2020 14:59:31 -0400
|
||||
Subject: [PATCH] Don't check chunk for portal on world gen entity add
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 4b1366a456e7132d438fc99bd62e1dd77e35b35f..90c66f87e721ef34bf3f47b601456fece3064225 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3510,7 +3510,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
Entity entity = this.getVehicle();
|
||||
|
||||
super.stopRiding(suppressCancellation); // Paper - suppress
|
||||
- if (entity != null && entity != this.getVehicle() && !this.level().isClientSide) {
|
||||
+ if (entity != null && entity != this.getVehicle() && !this.level().isClientSide && entity.valid) { // Paper - don't process on world gen
|
||||
this.dismountVehicle(entity);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Wed, 8 Jul 2020 11:24:30 -0500
|
||||
Subject: [PATCH] Fix arrows never despawning MC-125757
|
||||
|
||||
This forces the despawn counter to start ticking regardless of
|
||||
state after the arrow has been alive for 200 ticks (10 seconds)
|
||||
instead of getting stuck in a never despawn state (bubble columns,
|
||||
etc).
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
index 385cbee1d30735152cccb0d85a77a12fabfd9427..004c130fc03dc01ef75fabdb4ef1ef711e33cb95 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -207,6 +207,7 @@ public abstract class AbstractArrow extends Projectile {
|
||||
|
||||
++this.inGroundTime;
|
||||
} else {
|
||||
+ if (tickCount > 200) this.tickDespawn(); // Paper - tick despawnCounter regardless after 10 seconds
|
||||
this.inGroundTime = 0;
|
||||
Vec3 vec3d2 = this.position();
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 11 Jul 2020 03:54:28 -0400
|
||||
Subject: [PATCH] Thread Safe Vanilla Command permission checking
|
||||
|
||||
Datapacks check this on load and are built concurrently. This was breaking them badly due
|
||||
to race conditions.
|
||||
|
||||
Plus, .canUse we want to be safe for async anyways.
|
||||
|
||||
diff --git a/src/main/java/com/mojang/brigadier/tree/CommandNode.java b/src/main/java/com/mojang/brigadier/tree/CommandNode.java
|
||||
index 20a7cdf87f307878d66922aaac0c60cff218e46c..39844531b03eb8a6c70700b4ecbf0ff1a557424d 100644
|
||||
--- a/src/main/java/com/mojang/brigadier/tree/CommandNode.java
|
||||
+++ b/src/main/java/com/mojang/brigadier/tree/CommandNode.java
|
||||
@@ -75,10 +75,10 @@ public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
|
||||
public synchronized boolean canUse(final S source) {
|
||||
if (source instanceof CommandSourceStack) {
|
||||
try {
|
||||
- ((CommandSourceStack) source).currentCommand = this;
|
||||
+ ((CommandSourceStack) source).currentCommand.put(Thread.currentThread(), this); // Paper
|
||||
return this.requirement.test(source);
|
||||
} finally {
|
||||
- ((CommandSourceStack) source).currentCommand = null;
|
||||
+ ((CommandSourceStack) source).currentCommand.remove(Thread.currentThread()); // Paper
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
index 75b7b3cf90d1d67203ae19dc3302f06a57470f92..e58c2844356c71973d81b460a21aab795b506d77 100644
|
||||
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
@@ -64,7 +64,7 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
|
||||
private final Vec2 rotation;
|
||||
private final CommandSigningContext signingContext;
|
||||
private final TaskChainer chatMessageChainer;
|
||||
- public volatile CommandNode currentCommand; // CraftBukkit
|
||||
+ public java.util.Map<Thread, CommandNode> currentCommand = new java.util.concurrent.ConcurrentHashMap<>(); // CraftBukkit // Paper
|
||||
public boolean bypassSelectorPermissions = false; // Paper
|
||||
|
||||
public CommandSourceStack(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String name, Component displayName, MinecraftServer server, @Nullable Entity entity) {
|
||||
@@ -193,9 +193,11 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
|
||||
@Override
|
||||
public boolean hasPermission(int level) {
|
||||
// CraftBukkit start
|
||||
- CommandNode currentCommand = this.currentCommand;
|
||||
+ // Paper start - fix concurrency issue
|
||||
+ CommandNode currentCommand = this.currentCommand.get(Thread.currentThread());
|
||||
if (currentCommand != null) {
|
||||
return this.hasPermission(level, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand));
|
||||
+ // Paper end
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
63
patches/server/0437-Fix-SPIGOT-5989.patch
Normal file
63
patches/server/0437-Fix-SPIGOT-5989.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
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 ccf715d1ddb029ebadbab88be8ef1e914b5220be..7f05a1c3847c36699d3c9acbb1d7cd05363c94c5 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -808,6 +808,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
|
||||
@@ -818,7 +819,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();
|
||||
}
|
||||
@@ -862,7 +863,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 {
|
||||
@@ -901,8 +907,14 @@ public abstract class PlayerList {
|
||||
}
|
||||
// entityplayer1.initInventoryMenu();
|
||||
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, worldserver1.getRandom().nextLong()));
|
||||
+ // Paper start - Fix SPIGOT-5989
|
||||
+ if (flag2 && !isLocAltered) {
|
||||
+ if (!flag1) {
|
||||
+ BlockState data = worldserver1.getBlockState(blockposition);
|
||||
+ worldserver1.setBlock(blockposition, data.setValue(net.minecraft.world.level.block.RespawnAnchorBlock.CHARGE, data.getValue(net.minecraft.world.level.block.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, worldserver1.getRandom().nextLong()));
|
||||
+ // Paper end
|
||||
}
|
||||
// Added from changeDimension
|
||||
this.sendAllPlayerInfo(entityplayer); // Update health, etc...
|
|
@ -0,0 +1,50 @@
|
|||
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 22f53d722f8e567554d2f7ed6c683e76cd74a1ef..49553615418bcbb6f3e4be6f38a9ecd0a650502b 100644
|
||||
--- a/src/main/java/net/minecraft/server/Main.java
|
||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||
@@ -175,8 +175,17 @@ public class Main {
|
||||
return;
|
||||
}
|
||||
|
||||
- File file = (File) optionset.valueOf("universe"); // CraftBukkit
|
||||
- Services services = Services.create(new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY), file, optionset); // Paper
|
||||
+ // Paper start - fix SPIGOT-5824
|
||||
+ File file;
|
||||
+ File userCacheFile = new File(Services.USERID_CACHE_FILE);
|
||||
+ if (optionset.has("universe")) {
|
||||
+ file = (File) optionset.valueOf("universe"); // CraftBukkit
|
||||
+ userCacheFile = new File(file, Services.USERID_CACHE_FILE);
|
||||
+ } else {
|
||||
+ file = new File(bukkitConfiguration.getString("settings.world-container", "."));
|
||||
+ }
|
||||
+ // Paper end - fix SPIGOT-5824
|
||||
+ Services services = Services.create(new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY), file, userCacheFile, optionset); // Paper
|
||||
// CraftBukkit start
|
||||
String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName);
|
||||
LevelStorageSource convertable = LevelStorageSource.createDefault(file.toPath());
|
||||
diff --git a/src/main/java/net/minecraft/server/Services.java b/src/main/java/net/minecraft/server/Services.java
|
||||
index 92d1ad919c1b3e27af9cc74ada19f1e9c4f3471f..a5450eeeab5a6b0ab273810063806d11107d6b26 100644
|
||||
--- a/src/main/java/net/minecraft/server/Services.java
|
||||
+++ b/src/main/java/net/minecraft/server/Services.java
|
||||
@@ -22,12 +22,12 @@ public record Services(MinecraftSessionService sessionService, ServicesKeySet se
|
||||
return java.util.Objects.requireNonNull(this.paperConfigurations);
|
||||
}
|
||||
// Paper end
|
||||
- private static final String USERID_CACHE_FILE = "usercache.json";
|
||||
+ public static final String USERID_CACHE_FILE = "usercache.json"; // Paper - private -> public
|
||||
|
||||
- public static Services create(YggdrasilAuthenticationService authenticationService, File rootDirectory, joptsimple.OptionSet optionSet) throws Exception { // Paper
|
||||
+ public static Services create(YggdrasilAuthenticationService authenticationService, File rootDirectory, File userCacheFile, joptsimple.OptionSet optionSet) throws Exception { // Paper
|
||||
MinecraftSessionService minecraftSessionService = authenticationService.createMinecraftSessionService();
|
||||
GameProfileRepository gameProfileRepository = authenticationService.createProfileRepository();
|
||||
- GameProfileCache gameProfileCache = new GameProfileCache(gameProfileRepository, new File(rootDirectory, "usercache.json"));
|
||||
+ GameProfileCache gameProfileCache = new GameProfileCache(gameProfileRepository, userCacheFile); // Paper
|
||||
// Paper start
|
||||
final java.nio.file.Path legacyConfigPath = ((File) optionSet.valueOf("paper-settings")).toPath();
|
||||
final java.nio.file.Path configDirPath = ((File) optionSet.valueOf("paper-settings-directory")).toPath();
|
|
@ -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 49553615418bcbb6f3e4be6f38a9ecd0a650502b..0cb453b03977e90addc26f71d0518f134af3c36a 100644
|
||||
--- a/src/main/java/net/minecraft/server/Main.java
|
||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||
@@ -175,6 +175,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(Services.USERID_CACHE_FILE);
|
|
@ -0,0 +1,68 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
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 5450734060428426981e2c1f1025b1aa5aa4d271..0a22ed467d04c6421f4f8ef227a665ae135a5b0b 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
||||
@@ -15,22 +15,22 @@ import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public abstract class SimpleCriterionTrigger<T extends SimpleCriterionTrigger.SimpleInstance> 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
|
||||
|
||||
@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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,12 +38,12 @@ public abstract class SimpleCriterionTrigger<T extends SimpleCriterionTrigger.Si
|
||||
|
||||
@Override
|
||||
public final void removePlayerListeners(PlayerAdvancements tracker) {
|
||||
- this.players.remove(tracker);
|
||||
+ tracker.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
|
||||
}
|
||||
|
||||
protected void trigger(ServerPlayer player, Predicate<T> predicate) {
|
||||
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 f6daa77856f5d57b1a3b38e709bff47214372973..f29ddc244cfa5eba9b2903d40d8509731fc18287 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java
|
||||
@@ -63,6 +63,7 @@ public class PlayerAdvancements {
|
||||
private AdvancementHolder lastSelectedTab;
|
||||
private boolean isFirstPacket = true;
|
||||
private final Codec<PlayerAdvancements.Data> codec;
|
||||
+ public final Map<net.minecraft.advancements.critereon.SimpleCriterionTrigger<?>, Set<CriterionTrigger.Listener<?>>> criterionData = new java.util.IdentityHashMap<>(); // Paper - fix advancement data player leakage
|
||||
|
||||
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerManager, ServerAdvancementManager advancementLoader, Path filePath, ServerPlayer owner) {
|
||||
this.playerList = playerManager;
|
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Steinborn <git@steinborn.me>
|
||||
Date: Sun, 5 Jul 2020 22:38:18 -0400
|
||||
Subject: [PATCH] Optimize NetworkManager Exception Handling
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/ConnectionProtocol.java b/src/main/java/net/minecraft/network/ConnectionProtocol.java
|
||||
index ac1aa37329bd4d411964ea34ea8147f6db945b9a..41899d6c141895fc6c2c5da763bbe36864d557f7 100644
|
||||
--- a/src/main/java/net/minecraft/network/ConnectionProtocol.java
|
||||
+++ b/src/main/java/net/minecraft/network/ConnectionProtocol.java
|
||||
@@ -341,6 +341,7 @@ public enum ConnectionProtocol {
|
||||
|
||||
@Nullable
|
||||
public Packet<?> createPacket(int id, FriendlyByteBuf buf) {
|
||||
+ if (id < 0 || id >= this.idToDeserializer.size()) return null; // Paper
|
||||
Function<FriendlyByteBuf, ? extends Packet<? super T>> function = this.idToDeserializer.get(id);
|
||||
return function != null ? function.apply(buf) : null;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/network/Varint21FrameDecoder.java b/src/main/java/net/minecraft/network/Varint21FrameDecoder.java
|
||||
index 00c170a16a57f41f881c6b282cba474ce485b34c..1f71357a4caef4b2cbff95b560d0f3df268b3621 100644
|
||||
--- a/src/main/java/net/minecraft/network/Varint21FrameDecoder.java
|
||||
+++ b/src/main/java/net/minecraft/network/Varint21FrameDecoder.java
|
||||
@@ -39,6 +39,12 @@ public class Varint21FrameDecoder extends ByteToMessageDecoder {
|
||||
}
|
||||
|
||||
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) {
|
||||
+ // Paper start - if channel is not active just discard the packet
|
||||
+ if (!channelHandlerContext.channel().isActive()) {
|
||||
+ byteBuf.skipBytes(byteBuf.readableBytes());
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - if channel is not active just discard the packet
|
||||
byteBuf.markReaderIndex();
|
||||
this.helperBuf.clear();
|
||||
if (!copyVarint(byteBuf, this.helperBuf)) {
|
|
@ -0,0 +1,84 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
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 d8dd9f26fe4344541d0544e35bbc66c5d567a80b..dcf49e21208c78b471e6c38cdb0746a0c88fe5a7 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
|
||||
@@ -68,6 +68,7 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl
|
||||
state = this.updateDir(world, pos, state, true);
|
||||
if (this.isStraight) {
|
||||
world.neighborChanged(state, 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 41452abc7b761858ff2f3ff6a833b09c16fded4f..8eff69cb70ba094f9dcc0849f0436d4a3498fceb 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
|
||||
@@ -77,6 +77,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 0cbfad97371b59de95963a09aa16f3dad7a37222..d873625c1b8439a727d39ce207b5e84a1d86e5eb 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/RailState.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/RailState.java
|
||||
@@ -17,6 +17,12 @@ public class RailState {
|
||||
private final boolean isStraight;
|
||||
private final List<BlockPos> connections = Lists.newArrayList();
|
||||
|
||||
+ // Paper start - prevent desync
|
||||
+ public boolean isValid() {
|
||||
+ return this.level.getBlockState(this.pos).getBlock() == this.state.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.level.getBlockState(this.pos); // Paper - prevent desync
|
||||
}
|
||||
}
|
|
@ -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 2cfa312aec7fe513b9f0e517fa935cd8aceeb868..eea35e63fcbb598b6c89625e69160a46891ceb5f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java
|
||||
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
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(""));
|
||||
|
76
patches/server/0444-Brand-support.patch
Normal file
76
patches/server/0444-Brand-support.patch
Normal file
|
@ -0,0 +1,76 @@
|
|||
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/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 25c5f23b859961c792b2ec08404171eea1aedba7..478abaffd1a80949b96f1c1774c98134be92e5ac 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -278,6 +278,7 @@ public class ServerPlayer extends Player {
|
||||
public boolean isRealPlayer; // Paper
|
||||
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
|
||||
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
|
||||
+ public @Nullable String clientBrandName = null; // Paper - Brand name
|
||||
|
||||
// Paper start - replace player chunk loader
|
||||
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index 6b53e65308fb4118ef2d78ec9d171722ba2301f5..2d0ce31011ce1dbbf3c86f09bbf9a41a6e4a158f 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -54,6 +54,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
private int latency;
|
||||
private volatile boolean suspendFlushingOnServerThread = false;
|
||||
private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
|
||||
+ protected static final ResourceLocation MINECRAFT_BRAND = new ResourceLocation("brand"); // Paper - Brand support
|
||||
|
||||
public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection networkmanager, CommonListenerCookie commonlistenercookie, ServerPlayer player) { // CraftBukkit
|
||||
this.server = minecraftserver;
|
||||
@@ -109,6 +110,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
|
||||
@Override
|
||||
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
|
||||
+ // Paper start - handle brand payload packet
|
||||
+ if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload brandPayload) {
|
||||
+ this.player.clientBrandName = brandPayload.brand();
|
||||
+ }
|
||||
+ // Paper end - handle brand payload
|
||||
if (!(packet.payload() instanceof ServerboundCustomPayloadPacket.UnknownPayload)) {
|
||||
return;
|
||||
}
|
||||
@@ -140,6 +146,15 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
try {
|
||||
byte[] data = new byte[payload.readableBytes()];
|
||||
payload.readBytes(data);
|
||||
+ // Paper start - Brand support - Retain this incase upstream decides to 'break' the new mechanism in favour of backwards compat...
|
||||
+ if (identifier.equals(MINECRAFT_BRAND)) {
|
||||
+ try {
|
||||
+ this.player.clientBrandName = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.copiedBuffer(data)).readUtf(256);
|
||||
+ } catch (StringIndexOutOfBoundsException ex) {
|
||||
+ this.player.clientBrandName = "illegal";
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), identifier.toString(), data);
|
||||
} catch (Exception ex) {
|
||||
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index e00e595677ce0b4e9e1e12883b06f99f55af7d31..16476b8d20619d8526658db24ed3de60a151ffcf 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -3026,6 +3026,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
// Paper end
|
||||
};
|
||||
|
||||
+ // Paper start - brand support
|
||||
+ @Override
|
||||
+ public String getClientBrandName() {
|
||||
+ return getHandle().clientBrandName;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public Player.Spigot spigot()
|
||||
{
|
||||
return this.spigot;
|
|
@ -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 f5b9d1fe0d672e11b6295aefc9e182606dbebf88..95406737a6c72fd118a0022e07cdf15936e3911a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -925,5 +925,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
|
||||
}
|
37
patches/server/0446-Don-t-require-FACING-data.patch
Normal file
37
patches/server/0446-Don-t-require-FACING-data.patch
Normal file
|
@ -0,0 +1,37 @@
|
|||
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 b6c5976278f08c454492e0fabe6fac6c1a881d00..379890ae05b2fb4bd81b2fa907413d3736ba1169 100644
|
||||
--- a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
|
||||
+++ b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
|
||||
@@ -14,6 +14,7 @@ import org.bukkit.event.block.BlockDispenseEvent;
|
||||
// CraftBukkit end
|
||||
|
||||
public class DefaultDispenseItemBehavior implements DispenseItemBehavior {
|
||||
+ private Direction enumdirection; // Paper
|
||||
|
||||
// CraftBukkit start
|
||||
private boolean dropper;
|
||||
@@ -27,15 +28,16 @@ public class DefaultDispenseItemBehavior implements DispenseItemBehavior {
|
||||
|
||||
@Override
|
||||
public final ItemStack dispense(BlockSource pointer, ItemStack stack) {
|
||||
+ enumdirection = pointer.state().getValue(DispenserBlock.FACING); // Paper - cache facing direction
|
||||
ItemStack itemstack1 = this.execute(pointer, stack);
|
||||
|
||||
this.playSound(pointer);
|
||||
- this.playAnimation(pointer, (Direction) pointer.state().getValue(DispenserBlock.FACING));
|
||||
+ this.playAnimation(pointer, enumdirection); // Paper - cache facing direction
|
||||
return itemstack1;
|
||||
}
|
||||
|
||||
protected ItemStack execute(BlockSource pointer, ItemStack stack) {
|
||||
- Direction enumdirection = (Direction) pointer.state().getValue(DispenserBlock.FACING);
|
||||
+ // Paper - cached enum direction
|
||||
Position iposition = DispenserBlock.getDispensePosition(pointer);
|
||||
ItemStack itemstack1 = stack.split(1);
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
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 d9fafffc52b5db0b55022c02b9321d47a2b49827..a9a724f1e586c7e04e88bc1ff8dff442d83aaf16 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2020,9 +2020,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
public void setDefaultSpawnPos(BlockPos pos, float angle) {
|
||||
// Paper - configurable spawn radius
|
||||
BlockPos prevSpawn = this.getSharedSpawnPos();
|
||||
+ Location prevSpawnLoc = this.getWorld().getSpawnLocation(); // Paper
|
||||
//ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(this.worldData.a(), 0, this.worldData.c()));
|
||||
|
||||
this.levelData.setSpawn(pos, angle);
|
||||
+ new org.bukkit.event.world.SpawnChangeEvent(this.getWorld(), prevSpawnLoc).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().spawn.keepSpawnLoadedRange * 16, prevSpawn);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 2d90be2537faf281adc50f856daf3b4e8b842568..16df867ff996d33dc08831200d172633c9d68612 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -263,12 +263,14 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@Override
|
||||
public boolean setSpawnLocation(int x, int y, int z, float angle) {
|
||||
try {
|
||||
- Location previousLocation = this.getSpawnLocation();
|
||||
- this.world.levelData.setSpawn(new BlockPos(x, y, z), angle);
|
||||
+ // Location previousLocation = this.getSpawnLocation(); // Paper - moved to nms.ServerLevel
|
||||
+ this.world.setDefaultSpawnPos(new BlockPos(x, y, z), angle); // Paper - use ServerLevel#setDefaultSpawnPos
|
||||
|
||||
+ // Paper start - move to nms.ServerLevel
|
||||
// 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) {
|
22
patches/server/0448-Add-moon-phase-API.patch
Normal file
22
patches/server/0448-Add-moon-phase-API.patch
Normal 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/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
index 53385eb0fb6c79052f508f8feeff7cbd8559c19f..6433ac4053e7c39aa4ec73db4159422e501c9d21 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -1015,4 +1015,11 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
|
||||
throw new IllegalArgumentException("Cannot spawn an entity for " + clazz.getName());
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public io.papermc.paper.world.MoonPhase getMoonPhase() {
|
||||
+ return io.papermc.paper.world.MoonPhase.getPhase(this.getHandle().dayTime() / 24000L);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
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 02beedb84a8bec001270116c6ce496db012e6b8a..19b35d1c07c75b27cef9a53258a68ec5d9f721d5 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
|
||||
@@ -124,8 +124,20 @@ public class ChunkSerializer {
|
||||
InProgressChunkHolder holder = loadChunk(world, poiStorage, chunkPos, nbt, true);
|
||||
return holder.protoChunk;
|
||||
}
|
||||
+ // Paper start
|
||||
+ private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion();
|
||||
+ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion");
|
||||
+ // Paper end
|
||||
|
||||
public static InProgressChunkHolder loadChunk(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt, boolean distinguish) {
|
||||
+ // 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
|
||||
ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
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/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
index b7cf13fe4a0af243c0e76d75439b28d5018dadb9..4f3b04e62de66c4b18e5e9a988dea7c3e7b85aa1 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
@@ -206,6 +206,15 @@ public class Explosion {
|
||||
|
||||
if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) {
|
||||
set.add(blockposition);
|
||||
+ // Paper start - prevent headless pistons from forming
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) {
|
||||
+ BlockEntity extension = this.level.getBlockEntity(blockposition);
|
||||
+ if (extension instanceof net.minecraft.world.level.block.piston.PistonMovingBlockEntity blockEntity && blockEntity.isSourcePiston()) {
|
||||
+ net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING);
|
||||
+ set.add(blockposition.relative(direction.getOpposite()));
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
d4 += d0 * 0.30000001192092896D;
|
25
patches/server/0451-Add-BellRingEvent.patch
Normal file
25
patches/server/0451-Add-BellRingEvent.patch
Normal file
|
@ -0,0 +1,25 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eearslya Sleiarion <eearslya@gmail.com>
|
||||
Date: Sun, 23 Aug 2020 13:04:02 +0200
|
||||
Subject: [PATCH] Add BellRingEvent
|
||||
|
||||
Add a new event, BellRingEvent, to trigger whenever a player rings a
|
||||
village bell. Passes along the bell block and the player who rang it.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index ce0d05009a9b88607a143ad40421d70148491817..bb7ec8b5a76155ec5a6bfa29eda4e395cf3f23d2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -369,10 +369,11 @@ public class CraftEventFactory {
|
||||
return tradeSelectEvent;
|
||||
}
|
||||
|
||||
+ @SuppressWarnings("deprecation") // Paper use deprecated event to maintain compat (it extends modern event)
|
||||
public static boolean handleBellRingEvent(Level world, BlockPos position, Direction direction, Entity entity) {
|
||||
Block block = CraftBlock.at(world, position);
|
||||
BlockFace bukkitDirection = CraftBlock.notchToBlockFace(direction);
|
||||
- BellRingEvent event = new BellRingEvent(block, bukkitDirection, (entity != null) ? entity.getBukkitEntity() : null);
|
||||
+ BellRingEvent event = new io.papermc.paper.event.block.BellRingEvent(block, bukkitDirection, (entity != null) ? entity.getBukkitEntity() : null); // Paper - deprecated BellRingEvent
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
return !event.isCancelled();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 23 Aug 2020 15:47:34 +0200
|
||||
Subject: [PATCH] Add zombie targets turtle egg config
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
index 93ca1016806103fe688379c99afc57cb02635f65..f99e4382b4b191d9bd673a4307c6641857b836ca 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
@@ -109,7 +109,7 @@ public class Zombie extends Monster {
|
||||
|
||||
@Override
|
||||
protected void registerGoals() {
|
||||
- this.goalSelector.addGoal(4, new Zombie.ZombieAttackTurtleEggGoal(this, 1.0D, 3));
|
||||
+ if (this.level().paperConfig().entities.behavior.zombiesTargetTurtleEggs) this.goalSelector.addGoal(4, new Zombie.ZombieAttackTurtleEggGoal(this, 1.0D, 3)); // Paper
|
||||
this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 8.0F));
|
||||
this.goalSelector.addGoal(8, new RandomLookAroundGoal(this));
|
||||
this.addBehaviourGoals();
|
43
patches/server/0453-Buffer-joins-to-world.patch
Normal file
43
patches/server/0453-Buffer-joins-to-world.patch
Normal file
|
@ -0,0 +1,43 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Wed, 19 Aug 2020 05:05:54 +0100
|
||||
Subject: [PATCH] Buffer joins to world
|
||||
|
||||
This patch buffers the number of logins which will attempt to join
|
||||
the world per tick, this attempts to reduce the impact that join floods
|
||||
has on the server
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 36a78cc103ddf1cc7ccddefc0b3fd6cef987f67d..f9d7fec242a059a3b056c569ffaf214a361716d6 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -498,14 +498,29 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
// Paper end - Optimize network
|
||||
|
||||
+ private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper
|
||||
+ private static int joinAttemptsThisTick; // Paper
|
||||
+ private static int currTick; // Paper
|
||||
public void tick() {
|
||||
this.flushQueue();
|
||||
+ // Paper start
|
||||
+ if (Connection.currTick != net.minecraft.server.MinecraftServer.currentTick) {
|
||||
+ Connection.currTick = net.minecraft.server.MinecraftServer.currentTick;
|
||||
+ Connection.joinAttemptsThisTick = 0;
|
||||
+ }
|
||||
+ // Paper end
|
||||
PacketListener packetlistener = this.packetListener;
|
||||
|
||||
if (packetlistener instanceof TickablePacketListener) {
|
||||
TickablePacketListener tickablepacketlistener = (TickablePacketListener) packetlistener;
|
||||
|
||||
+ // Paper start - limit the number of joins which can be processed each tick
|
||||
+ if (!(this.packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginPacketListener)
|
||||
+ || loginPacketListener.state != net.minecraft.server.network.ServerLoginPacketListenerImpl.State.VERIFYING
|
||||
+ || Connection.joinAttemptsThisTick++ < MAX_PER_TICK) {
|
||||
tickablepacketlistener.tick();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
if (!this.isConnected() && !this.disconnectionHandled) {
|
1143
patches/server/0454-Eigencraft-redstone-implementation.patch
Normal file
1143
patches/server/0454-Eigencraft-redstone-implementation.patch
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,39 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: JRoy <joshroy126@gmail.com>
|
||||
Date: Thu, 27 Aug 2020 16:57:25 -0400
|
||||
Subject: [PATCH] Fix hex colors not working in some kick messages
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
index e8cf9eafe0908bc9b716d9b6ead97828a43413ec..2ee5c884571228a353120f658f1a2d39373ea4ca 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
@@ -77,12 +77,12 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (packet.protocolVersion() != SharedConstants.getCurrentVersion().getProtocolVersion()) {
|
||||
- MutableComponent ichatmutablecomponent;
|
||||
+ Component ichatmutablecomponent; // Paper - Fix hex colors not working in some kick messages
|
||||
|
||||
if (packet.protocolVersion() < 754) {
|
||||
- ichatmutablecomponent = Component.literal( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName() ) ); // Spigot
|
||||
+ ichatmutablecomponent = org.bukkit.craftbukkit.util.CraftChatMessage.fromString( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName() ) )[0]; // Spigot // Paper - Fix hex colors not working in some kick messages
|
||||
} else {
|
||||
- ichatmutablecomponent = Component.literal( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName() ) ); // Spigot
|
||||
+ ichatmutablecomponent = org.bukkit.craftbukkit.util.CraftChatMessage.fromString( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName() ) )[0]; // Spigot // Paper - Fix hex colors not working in some kick messages
|
||||
}
|
||||
|
||||
this.connection.send(new ClientboundLoginDisconnectPacket(ichatmutablecomponent));
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 615fb00e50f3c434809f8e1b201d457b9beae8fd..c58fc7d950ea2aa136c3922fb14e4f183f45f2d3 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -99,7 +99,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
// CraftBukkit start
|
||||
@Deprecated
|
||||
public void disconnect(String s) {
|
||||
- this.disconnect(Component.literal(s));
|
||||
+ this.disconnect(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(s, true)[0]); // Paper - Fix hex colors not working in some kick messages
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mariell Hoversholm <proximyst@proximyst.com>
|
||||
Date: Fri, 21 Aug 2020 20:57:54 +0200
|
||||
Subject: [PATCH] PortalCreateEvent needs to know its entity
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index b5080861a4aa34a95618bcee7723bd3ec34b09c4..385b7e907c535a153d86fbec11eb3070edf66dd4 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -478,7 +478,7 @@ public final class ItemStack {
|
||||
net.minecraft.world.level.block.state.BlockState block = world.getBlockState(newblockposition);
|
||||
|
||||
if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically
|
||||
- block.getBlock().onPlace(block, world, newblockposition, oldBlock, true);
|
||||
+ block.getBlock().onPlace(block, world, newblockposition, oldBlock, true, context); // Paper - pass context
|
||||
}
|
||||
|
||||
world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java b/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java
|
||||
index e707553bbddf84bc48ec7186da00c3eb0632946d..0e56fbe8836020a0e36c0b6df01ae82d0aa8cf38 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java
|
||||
@@ -142,20 +142,23 @@ public abstract class BaseFireBlock extends Block {
|
||||
super.entityInside(state, world, pos, entity);
|
||||
}
|
||||
|
||||
+ // Paper start - ItemActionContext param
|
||||
+ @Override public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { this.onPlace(state, world, pos, oldState, notify, null); }
|
||||
@Override
|
||||
- public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
- if (!oldState.is(state.getBlock())) {
|
||||
+ public void onPlace(BlockState iblockdata, Level world, BlockPos blockposition, BlockState iblockdata1, boolean flag, net.minecraft.world.item.context.UseOnContext itemActionContext) {
|
||||
+ // Paper end
|
||||
+ if (!iblockdata1.is(iblockdata.getBlock())) {
|
||||
if (BaseFireBlock.inPortalDimension(world)) {
|
||||
- Optional<PortalShape> optional = PortalShape.findEmptyPortalShape(world, pos, Direction.Axis.X);
|
||||
+ Optional<PortalShape> optional = PortalShape.findEmptyPortalShape(world, blockposition, Direction.Axis.X);
|
||||
|
||||
if (optional.isPresent()) {
|
||||
- ((PortalShape) optional.get()).createPortalBlocks();
|
||||
+ ((PortalShape) optional.get()).createPortalBlocks(itemActionContext); // Paper - pass ItemActionContext param
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
- if (!state.canSurvive(world, pos)) {
|
||||
- this.fireExtinguished(world, pos); // CraftBukkit - fuel block broke
|
||||
+ if (!iblockdata.canSurvive(world, blockposition)) {
|
||||
+ fireExtinguished(world, blockposition); // CraftBukkit - fuel block broke
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
index 8fce3ad36a6ee8166f4abd9e0e369b641d487af9..3fb197ee3bfd3f36881b7d67f7a37f035bb27daf 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
@@ -14,6 +14,7 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.BiomeTags;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
+import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -368,9 +369,11 @@ public class FireBlock extends BaseFireBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
- super.onPlace(state, world, pos, oldState, notify);
|
||||
- world.scheduleTick(pos, (Block) this, FireBlock.getFireTickDelay(world.random));
|
||||
+ // Paper start - ItemActionContext param
|
||||
+ public void onPlace(BlockState iblockdata, Level world, BlockPos blockposition, BlockState iblockdata1, boolean flag, UseOnContext itemActionContext) {
|
||||
+ super.onPlace(iblockdata, world, blockposition, iblockdata1, flag, itemActionContext);
|
||||
+ // Paper end
|
||||
+ world.scheduleTick(blockposition, this, getFireTickDelay(world.random));
|
||||
}
|
||||
|
||||
private static int getFireTickDelay(RandomSource random) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index c64213fe3ec0bd34cd1b31ae18eff1fecbcf63d6..31dc96c371953eb7ca3d3b444b123ade1f24c909 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -43,6 +43,7 @@ import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
+import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.EmptyBlockGetter;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
@@ -163,6 +164,12 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
DebugPackets.sendNeighborsUpdatePacket(world, pos);
|
||||
}
|
||||
|
||||
+ // Paper start - add ItemActionContext param
|
||||
+ @Deprecated
|
||||
+ public void onPlace(BlockState iblockdata, Level world, BlockPos blockposition, BlockState iblockdata1, boolean flag, UseOnContext itemActionContext) {
|
||||
+ this.onPlace(iblockdata, world, blockposition, iblockdata1, flag);
|
||||
+ }
|
||||
+ // Paper end
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/portal/PortalShape.java b/src/main/java/net/minecraft/world/level/portal/PortalShape.java
|
||||
index 9fc4997277dd199cf6cffccceb3a9735398c5356..590cd053a1b1c2a489772a2879998725fe0d783c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/portal/PortalShape.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/portal/PortalShape.java
|
||||
@@ -11,6 +11,7 @@ import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityDimensions;
|
||||
+import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.NetherPortalBlock;
|
||||
@@ -190,7 +191,10 @@ public class PortalShape {
|
||||
}
|
||||
|
||||
// CraftBukkit start - return boolean
|
||||
- public boolean createPortalBlocks() {
|
||||
+ // Paper start - ItemActionContext param
|
||||
+ @Deprecated public boolean createPortalBlocks() { return this.createPortalBlocks(null); }
|
||||
+ public boolean createPortalBlocks(UseOnContext itemActionContext) {
|
||||
+ // Paper end
|
||||
org.bukkit.World bworld = this.level.getMinecraftWorld().getWorld();
|
||||
|
||||
// Copy below for loop
|
||||
@@ -200,7 +204,7 @@ public class PortalShape {
|
||||
this.blocks.setBlock(blockposition, iblockdata, 18);
|
||||
});
|
||||
|
||||
- PortalCreateEvent event = new PortalCreateEvent((java.util.List<org.bukkit.block.BlockState>) (java.util.List) this.blocks.getList(), bworld, null, PortalCreateEvent.CreateReason.FIRE);
|
||||
+ PortalCreateEvent event = new PortalCreateEvent((java.util.List<org.bukkit.block.BlockState>) (java.util.List) blocks.getList(), bworld, itemActionContext == null || itemActionContext.getPlayer() == null ? null : itemActionContext.getPlayer().getBukkitEntity(), PortalCreateEvent.CreateReason.FIRE); // Paper - pass entity param
|
||||
this.level.getMinecraftWorld().getServer().server.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
38
patches/server/0457-Add-more-Evoker-API.patch
Normal file
38
patches/server/0457-Add-more-Evoker-API.patch
Normal file
|
@ -0,0 +1,38 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 23 Aug 2020 15:28:35 +0200
|
||||
Subject: [PATCH] Add more Evoker API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.monster.Evoker setWololoTarget(Lnet/minecraft/world/entity/animal/Sheep;)V
|
||||
public net.minecraft.world.entity.monster.Evoker getWololoTarget()Lnet/minecraft/world/entity/animal/Sheep;
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java
|
||||
index 93ffe2ac37b03aa289881f5f12c7aa7f1d835eda..b66dd5c5c5d98c9285e0d0a4ad4b99a66419f732 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
+import net.minecraft.world.entity.animal.Sheep;
|
||||
import net.minecraft.world.entity.monster.SpellcasterIllager;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Evoker;
|
||||
@@ -29,4 +30,17 @@ public class CraftEvoker extends CraftSpellcaster implements Evoker {
|
||||
public void setCurrentSpell(Evoker.Spell spell) {
|
||||
this.getHandle().setIsCastingSpell(spell == null ? SpellcasterIllager.IllagerSpell.NONE : SpellcasterIllager.IllagerSpell.byId(spell.ordinal()));
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.Sheep getWololoTarget() {
|
||||
+ Sheep sheep = getHandle().getWololoTarget();
|
||||
+ return sheep == null ? null : (org.bukkit.entity.Sheep) sheep.getBukkitEntity();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWololoTarget(org.bukkit.entity.Sheep sheep) {
|
||||
+ getHandle().setWololoTarget(sheep == null ? null : ((org.bukkit.craftbukkit.entity.CraftSheep) sheep).getHandle());
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
143
patches/server/0458-Add-methods-to-get-translation-keys.patch
Normal file
143
patches/server/0458-Add-methods-to-get-translation-keys.patch
Normal file
|
@ -0,0 +1,143 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 11 Aug 2020 19:16:09 +0200
|
||||
Subject: [PATCH] Add methods to get translation keys
|
||||
|
||||
== AT ==
|
||||
public org.bukkit.craftbukkit.inventory.CraftMetaFirework
|
||||
public org.bukkit.craftbukkit.inventory.CraftMetaFirework getNBT(Lorg/bukkit/FireworkEffect$Type;)I
|
||||
|
||||
Co-authored-by: MeFisto94 <MeFisto94@users.noreply.github.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
index d0b1a419c9bc73066d79459dc3e5998160f8038b..a7783474afef0a2bab7e99e475c6d130bb88b01c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
@@ -669,5 +669,10 @@ public class CraftBlock implements Block {
|
||||
public org.bukkit.SoundGroup getBlockSoundGroup() {
|
||||
return org.bukkit.craftbukkit.CraftSoundGroup.getSoundGroup(this.getNMS().getSoundType());
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public String translationKey() {
|
||||
+ return this.getNMS().getBlock().getDescriptionId();
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
|
||||
index b54bd4e85042955448a2e76b379d370eefdff383..e8f03a40db4505c1e7f2aeb8946c207833acd416 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
|
||||
@@ -161,6 +161,11 @@ public class CraftEnchantment extends Enchantment {
|
||||
public net.kyori.adventure.text.Component displayName(int level) {
|
||||
return io.papermc.paper.adventure.PaperAdventure.asAdventure(getHandle().getFullname(level));
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public String translationKey() {
|
||||
+ return this.target.getDescriptionId();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@Override
|
||||
diff --git a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
|
||||
index 7f8b6462d2a1bbd39a870d2543bebc135f7eb45b..dbd1dc4453bd26fb6116b62f6ccbf69e92e09fc4 100644
|
||||
--- a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
|
||||
+++ b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
|
||||
@@ -1,12 +1,27 @@
|
||||
package io.papermc.paper.world;
|
||||
|
||||
import com.destroystokyo.paper.ClientOption;
|
||||
+import java.util.Map;
|
||||
+import net.minecraft.core.registries.BuiltInRegistries;
|
||||
+import net.minecraft.network.chat.contents.TranslatableContents;
|
||||
+import net.minecraft.resources.ResourceKey;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.ChatVisiblity;
|
||||
+import net.minecraft.world.level.GameType;
|
||||
+import net.minecraft.world.level.biome.Biome;
|
||||
import org.bukkit.Difficulty;
|
||||
+import org.bukkit.FireworkEffect;
|
||||
+import org.bukkit.GameMode;
|
||||
+import org.bukkit.GameRule;
|
||||
+import org.bukkit.MusicInstrument;
|
||||
+import org.bukkit.attribute.Attribute;
|
||||
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
+import org.bukkit.support.AbstractTestingBase;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
+import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
-public class TranslationKeyTest {
|
||||
+public class TranslationKeyTest extends AbstractTestingBase {
|
||||
|
||||
@Test
|
||||
public void testChatVisibilityKeys() {
|
||||
@@ -15,4 +30,67 @@ public class TranslationKeyTest {
|
||||
Assertions.assertEquals(ChatVisiblity.valueOf(chatVisibility.name()).getKey(), chatVisibility.translationKey(), chatVisibility + "'s translation key doesn't match");
|
||||
}
|
||||
}
|
||||
+
|
||||
+ @Test
|
||||
+ public void testDifficultyKeys() {
|
||||
+ for (Difficulty bukkitDifficulty : Difficulty.values()) {
|
||||
+ Assertions.assertEquals(((TranslatableContents) net.minecraft.world.Difficulty.byId(bukkitDifficulty.ordinal()).getDisplayName().getContents()).getKey(), bukkitDifficulty.translationKey(), bukkitDifficulty + "'s translation key doesn't match");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testGameruleKeys() {
|
||||
+ for (GameRule<?> rule : GameRule.values()) {
|
||||
+ Assertions.assertEquals(org.bukkit.craftbukkit.CraftWorld.getGameRulesNMS().get(rule.getName()).getDescriptionId(), rule.translationKey(), rule.getName() + "'s translation doesn't match");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testAttributeKeys() {
|
||||
+ for (Attribute attribute : Attribute.values()) {
|
||||
+ Assertions.assertEquals(org.bukkit.craftbukkit.attribute.CraftAttribute.bukkitToMinecraft(attribute).getDescriptionId(), attribute.translationKey(), "translation key mismatch for " + attribute);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testFireworkEffectType() {
|
||||
+ for (FireworkEffect.Type type : FireworkEffect.Type.values()) {
|
||||
+ Assertions.assertEquals(net.minecraft.world.item.FireworkRocketItem.Shape.byId(org.bukkit.craftbukkit.inventory.CraftMetaFirework.getNBT(type)).getName(), org.bukkit.FireworkEffect.Type.NAMES.key(type), "translation key mismatch for " + type);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ @Disabled // TODO fix
|
||||
+ public void testCreativeCategory() {
|
||||
+ // for (CreativeModeTab tab : CreativeModeTabs.tabs()) {
|
||||
+ // CreativeCategory category = Objects.requireNonNull(CraftCreativeCategory.fromNMS(tab));
|
||||
+ // Assertions.assertEquals("translation key mismatch for " + category, ((TranslatableContents) tab.getDisplayName().getContents()).getKey(), category.translationKey());
|
||||
+ // }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testGameMode() {
|
||||
+ for (GameType nms : GameType.values()) {
|
||||
+ GameMode bukkit = GameMode.getByValue(nms.getId());
|
||||
+ Assertions.assertNotNull(bukkit);
|
||||
+ Assertions.assertEquals(((TranslatableContents) nms.getLongDisplayName().getContents()).getKey(), bukkit.translationKey(), "translation key mismatch for " + bukkit);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testBiome() {
|
||||
+ for (Map.Entry<ResourceKey<Biome>, Biome> nms : AbstractTestingBase.BIOMES.entrySet()) {
|
||||
+ org.bukkit.block.Biome bukkit = org.bukkit.block.Biome.valueOf(nms.getKey().location().getPath().toUpperCase());
|
||||
+ Assertions.assertEquals(nms.getKey().location().toLanguageKey("biome"), bukkit.translationKey(), "translation key mismatch for " + bukkit);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testMusicInstrument() {
|
||||
+ for (final ResourceLocation nms : BuiltInRegistries.INSTRUMENT.keySet()) {
|
||||
+ final MusicInstrument bukkit = MusicInstrument.getByKey(CraftNamespacedKey.fromMinecraft(nms));
|
||||
+ Assertions.assertNotNull(bukkit, "Missing bukkit instrument for " + nms);
|
||||
+ Assertions.assertEquals(nms.toLanguageKey("instrument"), bukkit.translationKey(), "translation key mismatch for " + bukkit);
|
||||
+ }
|
||||
+ }
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: ysl3000 <yannicklamprecht@live.de>
|
||||
Date: Mon, 6 Jul 2020 22:18:04 +0200
|
||||
Subject: [PATCH] Create HoverEvent from ItemStack Entity
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
index b6f5e63c7e7e45dd3eb15bad5c6bee9d5417311e..866106d0d773e407a0cdd8614818cba4ab910040 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -533,4 +533,41 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
return nms != null ? net.minecraft.locale.Language.getInstance().getOrDefault(nms.getItem().getDescriptionId(nms)) : null;
|
||||
}
|
||||
// Paper end - add getI18NDisplayName
|
||||
+
|
||||
+ // Paper start - bungee hover events
|
||||
+ @Override
|
||||
+ public net.md_5.bungee.api.chat.hover.content.Content hoverContentOf(ItemStack itemStack) {
|
||||
+ net.md_5.bungee.api.chat.ItemTag itemTag = net.md_5.bungee.api.chat.ItemTag.ofNbt(CraftItemStack.asNMSCopy(itemStack).getOrCreateTag().toString());
|
||||
+ return new net.md_5.bungee.api.chat.hover.content.Item(
|
||||
+ itemStack.getType().getKey().toString(),
|
||||
+ itemStack.getAmount(),
|
||||
+ itemTag);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.md_5.bungee.api.chat.hover.content.Content hoverContentOf(org.bukkit.entity.Entity entity) {
|
||||
+ return hoverContentOf(entity, org.apache.commons.lang3.StringUtils.isBlank(entity.getCustomName()) ? null : new net.md_5.bungee.api.chat.TextComponent(entity.getCustomName()));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.md_5.bungee.api.chat.hover.content.Content hoverContentOf(org.bukkit.entity.Entity entity, String customName) {
|
||||
+ return hoverContentOf(entity, org.apache.commons.lang3.StringUtils.isBlank(customName) ? null : new net.md_5.bungee.api.chat.TextComponent(customName));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.md_5.bungee.api.chat.hover.content.Content hoverContentOf(org.bukkit.entity.Entity entity, net.md_5.bungee.api.chat.BaseComponent customName) {
|
||||
+ return new net.md_5.bungee.api.chat.hover.content.Entity(
|
||||
+ entity.getType().getKey().toString(),
|
||||
+ entity.getUniqueId().toString(),
|
||||
+ customName);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.md_5.bungee.api.chat.hover.content.Content hoverContentOf(org.bukkit.entity.Entity entity, net.md_5.bungee.api.chat.BaseComponent[] customName) {
|
||||
+ return new net.md_5.bungee.api.chat.hover.content.Entity(
|
||||
+ entity.getType().getKey().toString(),
|
||||
+ entity.getUniqueId().toString(),
|
||||
+ new net.md_5.bungee.api.chat.TextComponent(customName));
|
||||
+ }
|
||||
+ // Paper end - bungee hover events
|
||||
}
|
62
patches/server/0460-Cache-block-data-strings.patch
Normal file
62
patches/server/0460-Cache-block-data-strings.patch
Normal file
|
@ -0,0 +1,62 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: miclebrick <miclebrick@outlook.com>
|
||||
Date: Thu, 6 Dec 2018 19:52:50 -0500
|
||||
Subject: [PATCH] Cache block data strings
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index a82f7dd2cbc2f6311b810f117f0970a47db85818..2616d771a8a95dac4440b74933c8aa7b83a9bbd1 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2148,6 +2148,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.getPlayerList().reloadResources();
|
||||
this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
|
||||
this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager);
|
||||
+ org.bukkit.craftbukkit.block.data.CraftBlockData.reloadCache(); // Paper - cache block data strings, they can be defined by datapacks so refresh it here
|
||||
}, this);
|
||||
|
||||
if (this.isSameThread()) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index ebe02507a394563ba51a207db8b24760467d936e..c673e311a5508c7264a8765c266892f9d346d39a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -535,9 +535,39 @@ public class CraftBlockData implements BlockData {
|
||||
Preconditions.checkState(CraftBlockData.MAP.put(nms, bukkit) == null, "Duplicate mapping %s->%s", nms, bukkit);
|
||||
}
|
||||
|
||||
+ // Paper start - cache block data strings
|
||||
+ private static Map<String, CraftBlockData> stringDataCache = new java.util.concurrent.ConcurrentHashMap<>();
|
||||
+
|
||||
+ static {
|
||||
+ // cache all of the default states at startup, will not cache ones with the custom states inside of the
|
||||
+ // brackets in a different order, though
|
||||
+ reloadCache();
|
||||
+ }
|
||||
+
|
||||
+ public static void reloadCache() {
|
||||
+ stringDataCache.clear();
|
||||
+ Block.BLOCK_STATE_REGISTRY.forEach(blockData -> stringDataCache.put(blockData.toString(), blockData.createCraftBlockData()));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static CraftBlockData newData(Material material, String data) {
|
||||
Preconditions.checkArgument(material == null || material.isBlock(), "Cannot get data for not block %s", material);
|
||||
|
||||
+ // Paper start - cache block data strings
|
||||
+ if (material != null) {
|
||||
+ Block block = CraftMagicNumbers.getBlock(material);
|
||||
+ if (block != null) {
|
||||
+ net.minecraft.resources.ResourceLocation key = BuiltInRegistries.BLOCK.getKey(block);
|
||||
+ data = data == null ? key.toString() : key + data;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ CraftBlockData cached = stringDataCache.computeIfAbsent(data, s -> createNewData(null, s));
|
||||
+ return (CraftBlockData) cached.clone();
|
||||
+ }
|
||||
+
|
||||
+ private static CraftBlockData createNewData(Material material, String data) {
|
||||
+ // Paper end - cache block data strings
|
||||
net.minecraft.world.level.block.state.BlockState blockData;
|
||||
Block block = CraftMagicNumbers.getBlock(material);
|
||||
Map<Property<?>, Comparable<?>> parsed = null;
|
|
@ -0,0 +1,83 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 25 Aug 2020 20:45:36 -0400
|
||||
Subject: [PATCH] Fix Entity Teleportation and cancel velocity if teleported
|
||||
|
||||
Uses correct setPositionRotation for Entity teleporting instead of setLocation
|
||||
as this is how Vanilla teleports entities.
|
||||
|
||||
Cancel any pending motion when teleported.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 110456e28adeeef790940b9281801d9926244b37..2663d2e433946c2c9a36d223cb7e704272716a80 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -660,7 +660,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
return;
|
||||
}
|
||||
|
||||
- this.player.absMoveTo(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot());
|
||||
+ this.player.moveTo(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot()); // Paper - use proper moveTo for teleportation
|
||||
this.lastGoodX = this.awaitingPositionFromClient.x;
|
||||
this.lastGoodY = this.awaitingPositionFromClient.y;
|
||||
this.lastGoodZ = this.awaitingPositionFromClient.z;
|
||||
@@ -1584,7 +1584,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
// CraftBukkit end
|
||||
|
||||
this.awaitingTeleportTime = this.tickCount;
|
||||
- this.player.absMoveTo(d0, d1, d2, f, f1);
|
||||
+ this.player.moveTo(d0, d1, d2, f, f1); // Paper - use proper moveTo for teleportation
|
||||
this.player.connection.send(new ClientboundPlayerPositionPacket(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.awaitingTeleport));
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 76a1803f806d3bf1a54dae15d8155d6a0920cf07..2693057247bc2640c043db1baf50c579d4058a68 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -160,6 +160,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
|
||||
// CraftBukkit start
|
||||
private static final int CURRENT_LEVEL = 2;
|
||||
+ public boolean preserveMotion = true; // Paper - keep initial motion on first setPositionRotation
|
||||
static boolean isLevelAtLeast(CompoundTag tag, int level) {
|
||||
return tag.contains("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
|
||||
}
|
||||
@@ -1869,6 +1870,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
}
|
||||
|
||||
public void moveTo(double x, double y, double z, float yaw, float pitch) {
|
||||
+ // Paper - cancel entity velocity if teleported
|
||||
+ if (!preserveMotion) {
|
||||
+ this.deltaMovement = Vec3.ZERO;
|
||||
+ } else {
|
||||
+ this.preserveMotion = false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.setPosRaw(x, y, z);
|
||||
this.setYRot(yaw);
|
||||
this.setXRot(pitch);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
index 41f549f16f69f9bc50a004096e6c3c0f6e4d4eaf..9ec83d6eeff22c2ce25374a83f581a675d4fd067 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -169,6 +169,7 @@ public abstract class BaseSpawner {
|
||||
return;
|
||||
}
|
||||
|
||||
+ entity.preserveMotion = true; // Paper - preserve entity motion from tag
|
||||
entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), randomsource.nextFloat() * 360.0F, 0.0F);
|
||||
if (entity instanceof Mob) {
|
||||
Mob entityinsentient = (Mob) entity;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index ded0332f5be000e31962e34033e69d17eed51280..370011b7de936a427f211edf306a5b6f3b8ea1a0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -586,7 +586,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
}
|
||||
|
||||
// entity.setLocation() throws no event, and so cannot be cancelled
|
||||
- this.entity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
+ entity.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); // Paper - use proper moveTo, as per vanilla teleporting
|
||||
// SPIGOT-619: Force sync head rotation also
|
||||
this.entity.setYHeadRot(location.getYaw());
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: JRoy <joshroy126@gmail.com>
|
||||
Date: Wed, 26 Aug 2020 02:12:31 -0400
|
||||
Subject: [PATCH] Add additional open container api to HumanEntity
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 9541ebf81c3c2c282c6d04f5e51b309e69d0802e..2609da834c014e82d0038de580d50163dd0c5687 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -462,6 +462,70 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
return this.getHandle().containerMenu.getBukkitView();
|
||||
}
|
||||
|
||||
+ // Paper start - Add additional containers
|
||||
+ @Override
|
||||
+ public InventoryView openAnvil(Location location, boolean force) {
|
||||
+ return this.openInventory(location, force, Material.ANVIL);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InventoryView openCartographyTable(Location location, boolean force) {
|
||||
+ return this.openInventory(location, force, Material.CARTOGRAPHY_TABLE);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InventoryView openGrindstone(Location location, boolean force) {
|
||||
+ return this.openInventory(location, force, Material.GRINDSTONE);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InventoryView openLoom(Location location, boolean force) {
|
||||
+ return this.openInventory(location, force, Material.LOOM);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InventoryView openSmithingTable(Location location, boolean force) {
|
||||
+ return this.openInventory(location, force, Material.SMITHING_TABLE);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InventoryView openStonecutter(Location location, boolean force) {
|
||||
+ return this.openInventory(location, force, Material.STONECUTTER);
|
||||
+ }
|
||||
+
|
||||
+ private InventoryView openInventory(Location location, boolean force, Material material) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("open" + material);
|
||||
+ if (location == null) {
|
||||
+ location = this.getLocation();
|
||||
+ }
|
||||
+ if (!force) {
|
||||
+ Block block = location.getBlock();
|
||||
+ if (block.getType() != material) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ }
|
||||
+ net.minecraft.world.level.block.Block block;
|
||||
+ if (material == Material.ANVIL) {
|
||||
+ block = Blocks.ANVIL;
|
||||
+ } else if (material == Material.CARTOGRAPHY_TABLE) {
|
||||
+ block = Blocks.CARTOGRAPHY_TABLE;
|
||||
+ } else if (material == Material.GRINDSTONE) {
|
||||
+ block = Blocks.GRINDSTONE;
|
||||
+ } else if (material == Material.LOOM) {
|
||||
+ block = Blocks.LOOM;
|
||||
+ } else if (material == Material.SMITHING_TABLE) {
|
||||
+ block = Blocks.SMITHING_TABLE;
|
||||
+ } else if (material == Material.STONECUTTER) {
|
||||
+ block = Blocks.STONECUTTER;
|
||||
+ } else {
|
||||
+ throw new IllegalArgumentException("Unsupported inventory type: " + material);
|
||||
+ }
|
||||
+ this.getHandle().openMenu(block.getMenuProvider(null, this.getHandle().level(), new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())));
|
||||
+ this.getHandle().containerMenu.checkReachable = !force;
|
||||
+ return this.getHandle().containerMenu.getBukkitView();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void closeInventory() {
|
||||
// Paper start
|
|
@ -0,0 +1,54 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 12 Sep 2020 17:21:38 -0400
|
||||
Subject: [PATCH] Cache DataFixerUpper Rewrite Rules on demand
|
||||
|
||||
Mojang precaches every single potential rewrite rule that could ever
|
||||
exist on server startup. This includes rules from all the way back to versions from 6+ years ago.
|
||||
|
||||
This is the source of why the server hogs every CPU core at 100% every start.
|
||||
|
||||
For anyone who hard resets for updates or has force upgraded their entire world, this
|
||||
results in completely wasted cpu cycles.
|
||||
|
||||
This massive CPU usage also delays server startup time.
|
||||
|
||||
We improve this by making "min version to precache" that defaults to a future version
|
||||
so that no rewrite rules are precached.
|
||||
|
||||
someone who expects to be converting a lot chunks could theoretically set
|
||||
-DPaper.minPrecachedDatafixVersion=<dataVersionConvertingFrom> as a startup
|
||||
parameter and only build from that point on.
|
||||
|
||||
However this will likely never be needed as the server will still run
|
||||
the same cache logic on demand when it's actually needed. The only
|
||||
cost would be some delay on the FIRST chunk conversion, but paper already
|
||||
runs chunk conversions on another thread so this will likely never be
|
||||
a concern for TPS.
|
||||
|
||||
This patch will significantly reduce CPU use on startup, reduce memory usage,
|
||||
and improve server startup time.
|
||||
|
||||
diff --git a/src/main/java/com/mojang/datafixers/DataFixerBuilder.java b/src/main/java/com/mojang/datafixers/DataFixerBuilder.java
|
||||
index cd812f3fe362de5ddc414862dedab2e9727ca776..f6598fcf4ed1bd61e1c87cd7107869d49ffe4566 100644
|
||||
--- a/src/main/java/com/mojang/datafixers/DataFixerBuilder.java
|
||||
+++ b/src/main/java/com/mojang/datafixers/DataFixerBuilder.java
|
||||
@@ -30,8 +30,10 @@ public class DataFixerBuilder {
|
||||
private final Int2ObjectSortedMap<Schema> schemas = new Int2ObjectAVLTreeMap<>();
|
||||
private final List<DataFix> globalList = Lists.newArrayList();
|
||||
private final IntSortedSet fixerVersions = new IntAVLTreeSet();
|
||||
+ private final int minDataFixPrecacheVersion; // Paper
|
||||
|
||||
public DataFixerBuilder(final int dataVersion) {
|
||||
+ minDataFixPrecacheVersion = Integer.getInteger("Paper.minPrecachedDatafixVersion", dataVersion+1) * 10; // Paper - default to precache nothing - mojang stores versions * 10 to allow for 'sub versions'
|
||||
this.dataVersion = dataVersion;
|
||||
}
|
||||
|
||||
@@ -78,6 +80,7 @@ public class DataFixerBuilder {
|
||||
final IntBidirectionalIterator iterator = fixerUpper.fixerVersions().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final int versionKey = iterator.nextInt();
|
||||
+ if (versionKey < minDataFixPrecacheVersion) continue; // Paper
|
||||
final Schema schema = schemas.get(versionKey);
|
||||
for (final String typeName : schema.types()) {
|
||||
if (!requiredTypeNames.contains(typeName)) {
|
|
@ -0,0 +1,43 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Thu, 17 Sep 2020 00:36:05 +0100
|
||||
Subject: [PATCH] Extend block drop capture to capture all items added to the
|
||||
world
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index a9a724f1e586c7e04e88bc1ff8dff442d83aaf16..2ce0a851bc0989bb0fe294b92a9aa428c38ba266 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1528,6 +1528,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit
|
||||
return false;
|
||||
} else {
|
||||
+ // Paper start - capture all item additions to the world
|
||||
+ if (captureDrops != null && entity instanceof net.minecraft.world.entity.item.ItemEntity) {
|
||||
+ captureDrops.add((net.minecraft.world.entity.item.ItemEntity) entity);
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
// SPIGOT-6415: Don't call spawn event when reason is null. For example when an entity teleports to a new world.
|
||||
if (spawnReason != null && !CraftEventFactory.doEntityAddEventCalling(this, entity, spawnReason)) {
|
||||
return false;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index a9ede0d719e866655ab48fb5d0263c7d1bdcff60..c61754976fab6654f55b1403d769eb1721871dca 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -431,10 +431,12 @@ public class ServerPlayerGameMode {
|
||||
// return true; // CraftBukkit
|
||||
}
|
||||
// CraftBukkit start
|
||||
+ java.util.List<net.minecraft.world.entity.item.ItemEntity> itemsToDrop = this.level.captureDrops; // Paper - store current list
|
||||
+ this.level.captureDrops = null; // Paper - Remove this earlier so that we can actually drop stuff
|
||||
if (event.isDropItems()) {
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, this.level.captureDrops);
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, itemsToDrop); // Paper - use stored ref
|
||||
}
|
||||
- this.level.captureDrops = null;
|
||||
+ //this.level.captureDrops = null; // Paper - move up
|
||||
|
||||
// Drop event experience
|
||||
if (flag && event != null) {
|
|
@ -0,0 +1,38 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MeFisto94 <MeFisto94@users.noreply.github.com>
|
||||
Date: Fri, 28 Aug 2020 01:41:26 +0200
|
||||
Subject: [PATCH] Expose the Entity Counter to allow plugins to use valid and
|
||||
non-conflicting Entity Ids
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 2693057247bc2640c043db1baf50c579d4058a68..fa48ed90623106065f4b84f2ffbf889ae70842eb 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -4493,4 +4493,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
|
||||
void accept(Entity entity, double x, double y, double z);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public static int nextEntityId() {
|
||||
+ return ENTITY_COUNTER.incrementAndGet();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index a394298df60ddd0aa709f9e250520da9db8c9589..5d1df87177b3d6a5f4c4b1f12bbbba7b597f2911 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -504,6 +504,11 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
Preconditions.checkArgument(dataVersion <= getDataVersion(), "Newer version! Server downgrades are not supported!");
|
||||
return compound;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public int nextEntityId() {
|
||||
+ return net.minecraft.world.entity.Entity.nextEntityId();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
/**
|
|
@ -0,0 +1,76 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Steinborn <git@steinborn.me>
|
||||
Date: Sat, 3 Oct 2020 04:15:09 -0400
|
||||
Subject: [PATCH] Lazily track plugin scoreboards by default
|
||||
|
||||
On servers with plugins that constantly churn through scoreboards, there is a risk of
|
||||
degraded GC performance due to the number of scoreboards held on by weak references.
|
||||
Most plugins don't even need the (vanilla) functionality that requires all plugin
|
||||
scoreboards to be tracked by the server. Instead, only track scoreboards when an
|
||||
objective is added with a non-dummy criteria.
|
||||
|
||||
This is a breaking change, however the change is a much more sensible default. In case
|
||||
this breaks your workflow you can always force all scoreboards to be tracked with
|
||||
settings.track-plugin-scoreboards in paper.yml.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java
|
||||
index 7791fb5b39702798fc0006fcff9c6041980eb191..885addfdbae3730626b4f6b9781945496783c389 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java
|
||||
@@ -20,6 +20,7 @@ import org.bukkit.scoreboard.Team;
|
||||
|
||||
public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
|
||||
final Scoreboard board;
|
||||
+ boolean registeredGlobally = false; // Paper
|
||||
|
||||
CraftScoreboard(Scoreboard board) {
|
||||
this.board = board;
|
||||
@@ -52,6 +53,12 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
|
||||
Preconditions.checkArgument(renderType != null, "RenderType cannot be null");
|
||||
Preconditions.checkArgument(name.length() <= Short.MAX_VALUE, "The name '%s' is longer than the limit of 32767 characters (%s)", name, name.length());
|
||||
Preconditions.checkArgument(this.board.getObjective(name) == null, "An objective of name '%s' already exists", name);
|
||||
+ // Paper start - lazily track plugin scoreboards
|
||||
+ if (((CraftCriteria) criteria).criteria != net.minecraft.world.scores.criteria.ObjectiveCriteria.DUMMY && !this.registeredGlobally) {
|
||||
+ net.minecraft.server.MinecraftServer.getServer().server.getScoreboardManager().registerScoreboardForVanilla(this);
|
||||
+ this.registeredGlobally = true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
net.minecraft.world.scores.Objective objective = this.board.addObjective(name, ((CraftCriteria) criteria).criteria, io.papermc.paper.adventure.PaperAdventure.asVanilla(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType), true, null);
|
||||
return new CraftObjective(this, objective);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
|
||||
index 40e348cae063bc1a814f8fcc3a2688c135f23bb5..c7ca6210d6ae37fe95068c9baa5fb654f95307e0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
|
||||
@@ -30,6 +30,7 @@ public final class CraftScoreboardManager implements ScoreboardManager {
|
||||
|
||||
public CraftScoreboardManager(MinecraftServer minecraftserver, net.minecraft.world.scores.Scoreboard scoreboardServer) {
|
||||
this.mainScoreboard = new CraftScoreboard(scoreboardServer);
|
||||
+ mainScoreboard.registeredGlobally = true; // Paper
|
||||
this.server = minecraftserver;
|
||||
this.scoreboards.add(this.mainScoreboard);
|
||||
}
|
||||
@@ -43,10 +44,22 @@ public final class CraftScoreboardManager implements ScoreboardManager {
|
||||
public CraftScoreboard getNewScoreboard() {
|
||||
org.spigotmc.AsyncCatcher.catchOp("scoreboard creation"); // Spigot
|
||||
CraftScoreboard scoreboard = new CraftScoreboard(new ServerScoreboard(this.server));
|
||||
- this.scoreboards.add(scoreboard);
|
||||
+ // Paper start
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().scoreboards.trackPluginScoreboards) {
|
||||
+ scoreboard.registeredGlobally = true;
|
||||
+ scoreboards.add(scoreboard);
|
||||
+ }
|
||||
+ // Paper end
|
||||
return scoreboard;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public void registerScoreboardForVanilla(CraftScoreboard scoreboard) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("scoreboard registration");
|
||||
+ scoreboards.add(scoreboard);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
// CraftBukkit method
|
||||
public CraftScoreboard getPlayerBoard(CraftPlayer player) {
|
||||
CraftScoreboard board = this.playerBoards.get(player);
|
35
patches/server/0467-Entity-isTicking.patch
Normal file
35
patches/server/0467-Entity-isTicking.patch
Normal file
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 3 Oct 2020 21:39:16 -0500
|
||||
Subject: [PATCH] Entity#isTicking
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index fa48ed90623106065f4b84f2ffbf889ae70842eb..f0158217eceeaf73555a741957324ce0258fa6b2 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -4498,5 +4498,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
public static int nextEntityId() {
|
||||
return ENTITY_COUNTER.incrementAndGet();
|
||||
}
|
||||
+
|
||||
+ public boolean isTicking() {
|
||||
+ return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this);
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 370011b7de936a427f211edf306a5b6f3b8ea1a0..2979678d8640324f5c28e4051bbb3b61b81a1e71 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -1407,5 +1407,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
public boolean isInLava() {
|
||||
return getHandle().isInLava();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isTicking() {
|
||||
+ return getHandle().isTicking();
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 3 Oct 2020 22:00:27 -0500
|
||||
Subject: [PATCH] Fix deop kicking non-whitelisted player when white list is
|
||||
not enabled
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 2616d771a8a95dac4440b74933c8aa7b83a9bbd1..f73ad3b85ed46913c10891edd3a52b9ad694e5e2 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2231,13 +2231,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (this.isEnforceWhitelist()) {
|
||||
PlayerList playerlist = source.getServer().getPlayerList();
|
||||
UserWhiteList whitelist = playerlist.getWhiteList();
|
||||
+ if (!((DedicatedServer)getServer()).getProperties().whiteList.get()) return; // Paper - white list not enabled
|
||||
List<ServerPlayer> list = Lists.newArrayList(playerlist.getPlayers());
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
|
||||
|
||||
- if (!whitelist.isWhiteListed(entityplayer.getGameProfile())) {
|
||||
+ if (!whitelist.isWhiteListed(entityplayer.getGameProfile()) && !this.getPlayerList().isOp(entityplayer.getGameProfile())) { // Paper - Fix kicking ops when whitelist is reloaded (MC-171420)
|
||||
entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.not_whitelisted"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 6 Jul 2020 18:36:41 -0400
|
||||
Subject: [PATCH] Fix Concurrency issue in ShufflingList
|
||||
|
||||
if multiple threads from worldgen sort at same time, it will crash.
|
||||
So make a copy of the list for sorting purposes.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
|
||||
index 419eadbe31b86b7192fd7a63268d547705e7c7ce..b45c4f50705f80163d44d9e588f86a5770f5be38 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
|
||||
@@ -17,7 +17,7 @@ public class GateBehavior<E extends LivingEntity> implements BehaviorControl<E>
|
||||
private final Set<MemoryModuleType<?>> exitErasedMemories;
|
||||
private final GateBehavior.OrderPolicy orderPolicy;
|
||||
private final GateBehavior.RunningPolicy runningPolicy;
|
||||
- private final ShufflingList<BehaviorControl<? super E>> behaviors = new ShufflingList<>();
|
||||
+ private final ShufflingList<BehaviorControl<? super E>> behaviors = new ShufflingList<>(false); // Paper - don't use a clone
|
||||
private Behavior.Status status = Behavior.Status.STOPPED;
|
||||
|
||||
public GateBehavior(Map<MemoryModuleType<?>, MemoryStatus> requiredMemoryState, Set<MemoryModuleType<?>> memoriesToForgetWhenStopped, GateBehavior.OrderPolicy order, GateBehavior.RunningPolicy runMode, List<Pair<? extends BehaviorControl<? super E>, Integer>> tasks) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java
|
||||
index 9fb20cd00568aeea25284ea0e80fe52cb1c3eede..731ef21dbbd25d6924717de42f4569a9b5935643 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java
|
||||
@@ -16,12 +16,25 @@ import net.minecraft.util.RandomSource;
|
||||
public class ShufflingList<U> implements Iterable<U> {
|
||||
protected final List<ShufflingList.WeightedEntry<U>> entries;
|
||||
private final RandomSource random = RandomSource.create();
|
||||
+ private final boolean isUnsafe; // Paper
|
||||
|
||||
public ShufflingList() {
|
||||
+ // Paper start
|
||||
+ this(true);
|
||||
+ }
|
||||
+ public ShufflingList(boolean isUnsafe) {
|
||||
+ this.isUnsafe = isUnsafe;
|
||||
+ // Paper end
|
||||
this.entries = Lists.newArrayList();
|
||||
}
|
||||
|
||||
private ShufflingList(List<ShufflingList.WeightedEntry<U>> list) {
|
||||
+ // Paper start
|
||||
+ this(list, true);
|
||||
+ }
|
||||
+ private ShufflingList(List<ShufflingList.WeightedEntry<U>> list, boolean isUnsafe) {
|
||||
+ this.isUnsafe = isUnsafe;
|
||||
+ // Paper end
|
||||
this.entries = Lists.newArrayList(list);
|
||||
}
|
||||
|
||||
@@ -37,11 +50,12 @@ public class ShufflingList<U> implements Iterable<U> {
|
||||
}
|
||||
|
||||
public ShufflingList<U> shuffle() {
|
||||
- this.entries.forEach((entry) -> {
|
||||
- entry.setRandom(this.random.nextFloat());
|
||||
- });
|
||||
- this.entries.sort(Comparator.comparingDouble(ShufflingList.WeightedEntry::getRandWeight));
|
||||
- return this;
|
||||
+ // Paper start - make concurrent safe, work off a clone of the list
|
||||
+ List<ShufflingList.WeightedEntry<U>> list = this.isUnsafe ? Lists.newArrayList(this.entries) : this.entries;
|
||||
+ list.forEach(entry -> entry.setRandom(this.random.nextFloat()));
|
||||
+ list.sort(Comparator.comparingDouble(ShufflingList.WeightedEntry::getRandWeight));
|
||||
+ return this.isUnsafe ? new ShufflingList<>(list, this.isUnsafe) : this;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public Stream<U> stream() {
|
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 1 Jun 2016 23:29:17 -0400
|
||||
Subject: [PATCH] Reset Ender Crystals on Dragon Spawn
|
||||
|
||||
Crystals can end up in a bad state in certain conditions which causes
|
||||
an exception on the expected number of crystals going negative.
|
||||
|
||||
This ensures the crystals/pillars are in expected state when the dragon spawns.
|
||||
|
||||
See #3522
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
index e70273664b4a38ef4ba803c60409a24a07d5bed7..7be3405a93fbb9f43075983825d1ac9299cbe7b9 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -472,6 +472,7 @@ public class EndDragonFight {
|
||||
entityenderdragon.moveTo((double) this.origin.getX(), (double) (128 + this.origin.getY()), (double) this.origin.getZ(), this.level.random.nextFloat() * 360.0F, 0.0F);
|
||||
this.level.addFreshEntity(entityenderdragon);
|
||||
this.dragonUUID = entityenderdragon.getUUID();
|
||||
+ this.resetSpikeCrystals(); // Paper
|
||||
}
|
||||
|
||||
return entityenderdragon;
|
|
@ -0,0 +1,92 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 17 May 2020 23:47:33 -0700
|
||||
Subject: [PATCH] Fix for large move vectors crashing server
|
||||
|
||||
Check movement distance also based on current position.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 2663d2e433946c2c9a36d223cb7e704272716a80..bace3a1d8e2e4b2b36f1b4cb80bb5c3bb473ad47 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -467,9 +467,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
|
||||
if (entity != this.player && entity.getControllingPassenger() == this.player && entity == this.lastVehicle) {
|
||||
ServerLevel worldserver = this.player.serverLevel();
|
||||
- double d0 = entity.getX();
|
||||
- double d1 = entity.getY();
|
||||
- double d2 = entity.getZ();
|
||||
+ double d0 = entity.getX();final double fromX = d0; // Paper - OBFHELPER
|
||||
+ double d1 = entity.getY();final double fromY = d1; // Paper - OBFHELPER
|
||||
+ double d2 = entity.getZ();final double fromZ = d2; // Paper - OBFHELPER
|
||||
double d3 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX()); final double toX = d3; // Paper - OBFHELPER
|
||||
double d4 = ServerGamePacketListenerImpl.clampVertical(packet.getY()); final double toY = d4; // Paper - OBFHELPER
|
||||
double d5 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ()); final double toZ = d5; // Paper - OBFHELPER
|
||||
@@ -479,8 +479,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
double d7 = d4 - this.vehicleFirstGoodY;
|
||||
double d8 = d5 - this.vehicleFirstGoodZ;
|
||||
double d9 = entity.getDeltaMovement().lengthSqr();
|
||||
- double d10 = d6 * d6 + d7 * d7 + d8 * d8;
|
||||
-
|
||||
+ // Paper start - fix large move vectors killing the server
|
||||
+ double currDeltaX = toX - fromX;
|
||||
+ double currDeltaY = toY - fromY;
|
||||
+ double currDeltaZ = toZ - fromZ;
|
||||
+ double d10 = Math.max(d6 * d6 + d7 * d7 + d8 * d8, (currDeltaX * currDeltaX + currDeltaY * currDeltaY + currDeltaZ * currDeltaZ) - 1);
|
||||
+ // Paper end - fix large move vectors killing the server
|
||||
+
|
||||
+ // Paper start - fix large move vectors killing the server
|
||||
+ double otherFieldX = d3 - this.vehicleLastGoodX;
|
||||
+ double otherFieldY = d4 - this.vehicleLastGoodY - 1.0E-6D;
|
||||
+ double otherFieldZ = d5 - this.vehicleLastGoodZ;
|
||||
+ d10 = Math.max(d10, (otherFieldX * otherFieldX + otherFieldY * otherFieldY + otherFieldZ * otherFieldZ) - 1);
|
||||
+ // Paper end - fix large move vectors killing the server
|
||||
|
||||
// CraftBukkit start - handle custom speeds and skipped ticks
|
||||
this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick;
|
||||
@@ -526,9 +537,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
|
||||
boolean flag = worldserver.noCollision(entity, entity.getBoundingBox().deflate(0.0625D));
|
||||
|
||||
- d6 = d3 - this.vehicleLastGoodX;
|
||||
- d7 = d4 - this.vehicleLastGoodY - 1.0E-6D;
|
||||
- d8 = d5 - this.vehicleLastGoodZ;
|
||||
+ d6 = d3 - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
+ d7 = d4 - this.vehicleLastGoodY - 1.0E-6D; // Paper - diff on change, used for checking large move vectors above
|
||||
+ d8 = d5 - this.vehicleLastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
boolean flag1 = entity.verticalCollisionBelow;
|
||||
|
||||
if (entity instanceof LivingEntity) {
|
||||
@@ -1274,7 +1285,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
double d7 = d1 - this.firstGoodY;
|
||||
double d8 = d2 - this.firstGoodZ;
|
||||
double d9 = this.player.getDeltaMovement().lengthSqr();
|
||||
- double d10 = d6 * d6 + d7 * d7 + d8 * d8;
|
||||
+ // Paper start - fix large move vectors killing the server
|
||||
+ double currDeltaX = toX - prevX;
|
||||
+ double currDeltaY = toY - prevY;
|
||||
+ double currDeltaZ = toZ - prevZ;
|
||||
+ double d10 = Math.max(d6 * d6 + d7 * d7 + d8 * d8, (currDeltaX * currDeltaX + currDeltaY * currDeltaY + currDeltaZ * currDeltaZ) - 1);
|
||||
+ // Paper end - fix large move vectors killing the server
|
||||
+ // Paper start - fix large move vectors killing the server
|
||||
+ double otherFieldX = d0 - this.lastGoodX;
|
||||
+ double otherFieldY = d1 - this.lastGoodY;
|
||||
+ double otherFieldZ = d2 - this.lastGoodZ;
|
||||
+ d10 = Math.max(d10, (otherFieldX * otherFieldX + otherFieldY * otherFieldY + otherFieldZ * otherFieldZ) - 1);
|
||||
+ // Paper end - fix large move vectors killing the server
|
||||
|
||||
if (this.player.isSleeping()) {
|
||||
if (d10 > 1.0D) {
|
||||
@@ -1328,9 +1350,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
|
||||
AABB axisalignedbb = this.player.getBoundingBox();
|
||||
|
||||
- d6 = d0 - this.lastGoodX;
|
||||
- d7 = d1 - this.lastGoodY;
|
||||
- d8 = d2 - this.lastGoodZ;
|
||||
+ d6 = d0 - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
+ d7 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
+ d8 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
boolean flag = d7 > 0.0D;
|
||||
|
||||
if (this.player.onGround() && !packet.isOnGround() && flag) {
|
94
patches/server/0472-Optimise-getType-calls.patch
Normal file
94
patches/server/0472-Optimise-getType-calls.patch
Normal file
|
@ -0,0 +1,94 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Wed, 3 Jun 2020 11:37:13 -0700
|
||||
Subject: [PATCH] Optimise getType calls
|
||||
|
||||
Remove the map lookup for converting from Block->Bukkit Material
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockState.java b/src/main/java/net/minecraft/world/level/block/state/BlockState.java
|
||||
index da878e180c6b94f98dc82c6e8395f63ecc9b2c1e..a9b0f5950b6f97ea4c2a1075946b92008b62c9d9 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/BlockState.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockState.java
|
||||
@@ -10,6 +10,17 @@ import net.minecraft.world.level.block.state.properties.Property;
|
||||
public class BlockState extends BlockBehaviour.BlockStateBase {
|
||||
public static final Codec<BlockState> CODEC = codec(BuiltInRegistries.BLOCK.byNameCodec(), Block::defaultBlockState).stable();
|
||||
|
||||
+ // Paper start - optimise getType calls
|
||||
+ org.bukkit.Material cachedMaterial;
|
||||
+
|
||||
+ public final org.bukkit.Material getBukkitMaterial() {
|
||||
+ if (this.cachedMaterial == null) {
|
||||
+ this.cachedMaterial = org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(this.getBlock());
|
||||
+ }
|
||||
+
|
||||
+ return this.cachedMaterial;
|
||||
+ }
|
||||
+ // Paper end - optimise getType calls
|
||||
public BlockState(Block block, ImmutableMap<Property<?>, Comparable<?>> propertyMap, MapCodec<BlockState> codec) {
|
||||
super(block, propertyMap, codec);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
|
||||
index 089f2a4780a0e3515c032d08a1bb2ea375ebdce1..30f6d74e867869b0070de83fe988672a74580043 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
|
||||
@@ -98,7 +98,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
|
||||
public Material getBlockType(int x, int y, int z) {
|
||||
this.validateChunkCoordinates(x, y, z);
|
||||
|
||||
- return CraftMagicNumbers.getMaterial(this.blockids[this.getSectionIndex(y)].get(x, y & 0xF, z).getBlock());
|
||||
+ return this.blockids[this.getSectionIndex(y)].get(x, y & 0xF, z).getBukkitMaterial(); // Paper - optimise getType calls
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
index a7783474afef0a2bab7e99e475c6d130bb88b01c..aa644231425b9622437538b5c092d4064a40cced 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
@@ -220,7 +220,7 @@ public class CraftBlock implements Block {
|
||||
|
||||
@Override
|
||||
public Material getType() {
|
||||
- return CraftMagicNumbers.getMaterial(this.world.getBlockState(this.position).getBlock());
|
||||
+ return this.world.getBlockState(this.position).getBukkitMaterial(); // Paper - optimise getType calls
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
|
||||
index a193583f596c0a587cd0c2d6eac994226ee4fde0..aca63719790429d3d7c7c59a1931a98221c70fc0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
|
||||
@@ -170,7 +170,7 @@ public class CraftBlockState implements BlockState {
|
||||
|
||||
@Override
|
||||
public Material getType() {
|
||||
- return CraftMagicNumbers.getMaterial(this.data.getBlock());
|
||||
+ return this.data.getBukkitMaterial(); // Paper - optimise getType calls
|
||||
}
|
||||
|
||||
public void setFlag(int flag) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index c673e311a5508c7264a8765c266892f9d346d39a..d6ba9030b0736afda9f7d2effa95d6d63e983b34 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -59,7 +59,7 @@ public class CraftBlockData implements BlockData {
|
||||
|
||||
@Override
|
||||
public Material getMaterial() {
|
||||
- return CraftMagicNumbers.getMaterial(this.state.getBlock());
|
||||
+ return this.state.getBukkitMaterial(); // Paper - optimise getType calls
|
||||
}
|
||||
|
||||
public net.minecraft.world.level.block.state.BlockState getState() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java
|
||||
index 35cf747196b43a0f1d9237fdc12424288962f8bd..54c7877f1da51ff8be467fac5e0a37b1fd573d37 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java
|
||||
@@ -95,7 +95,7 @@ public final class CraftChunkData implements ChunkGenerator.ChunkData {
|
||||
|
||||
@Override
|
||||
public Material getType(int x, int y, int z) {
|
||||
- return CraftMagicNumbers.getMaterial(this.getTypeId(x, y, z).getBlock());
|
||||
+ return this.getTypeId(x, y, z).getBukkitMaterial(); // Paper - optimise getType calls
|
||||
}
|
||||
|
||||
@Override
|
40
patches/server/0473-Villager-resetOffers.patch
Normal file
40
patches/server/0473-Villager-resetOffers.patch
Normal file
|
@ -0,0 +1,40 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Mon, 7 Oct 2019 00:15:37 -0500
|
||||
Subject: [PATCH] Villager#resetOffers
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
index 0ded8ee2deb51bea7506a8fa2d21f5e160694d54..66b7a2c9a7dc18a98bf2c3aac863a10cbc3ae9f9 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
@@ -114,6 +114,13 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa
|
||||
return this.tradingPlayer != null;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public void resetOffers() {
|
||||
+ this.offers = new MerchantOffers();
|
||||
+ this.updateTrades();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public MerchantOffers getOffers() {
|
||||
if (this.offers == null) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java
|
||||
index 19833c1fc6ee85e031e3c6aac3b00f44730c5e02..8db2c70d3600555bcb419260cafd56409478b227 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java
|
||||
@@ -70,4 +70,11 @@ public class CraftAbstractVillager extends CraftAgeable implements AbstractVilla
|
||||
public HumanEntity getTrader() {
|
||||
return this.getMerchant().getTrader();
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void resetOffers() {
|
||||
+ getHandle().resetOffers();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Fri, 7 Aug 2020 04:27:56 -0700
|
||||
Subject: [PATCH] Retain block place order when capturing blockstates
|
||||
|
||||
Fixes twisted vines not connecting properly when grown via
|
||||
bonemeal by a player.
|
||||
|
||||
In general, look at making this logic more robust (i.e properly handling
|
||||
cases where a captured entry is overriden) - but for now this will do.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 121f82c3e27d0c1e935871ab0e7c994393e73398..bdf11c543fe8904585eda72dc92206ac22daff58 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -160,7 +160,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public boolean captureBlockStates = false;
|
||||
public boolean captureTreeGeneration = false;
|
||||
public Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
|
||||
- public Map<BlockPos, BlockEntity> capturedTileEntities = new HashMap<>();
|
||||
+ public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper
|
||||
public List<ItemEntity> captureDrops;
|
||||
public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<SpawnCategory> ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>();
|
||||
// Paper start
|
|
@ -0,0 +1,28 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sat, 25 Apr 2020 17:10:55 -0700
|
||||
Subject: [PATCH] Reduce blockpos allocation from pathfinding
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
index 8e90b284fb576738b834626bb52c9962ccbc5ad2..2aca9b193db5dadc4fb90b8d7548277b698924aa 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
@@ -479,7 +479,7 @@ public class WalkNodeEvaluator extends NodeEvaluator {
|
||||
return BlockPathTypes.DANGER_FIRE;
|
||||
}
|
||||
|
||||
- if (world.getFluidState(pos).is(FluidTags.WATER)) {
|
||||
+ if (blockState.getFluidState().is(FluidTags.WATER)) {
|
||||
return BlockPathTypes.WATER_BORDER;
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ public class WalkNodeEvaluator extends NodeEvaluator {
|
||||
} else if (blockState.is(Blocks.COCOA)) {
|
||||
return BlockPathTypes.COCOA;
|
||||
} else if (!blockState.is(Blocks.WITHER_ROSE) && !blockState.is(Blocks.POINTED_DRIPSTONE)) {
|
||||
- FluidState fluidState = world.getFluidState(pos);
|
||||
+ FluidState fluidState = blockState.getFluidState(); // Paper - remove another getFluidState call
|
||||
if (fluidState.is(FluidTags.LAVA)) {
|
||||
return BlockPathTypes.LAVA;
|
||||
} else if (isBurningBlock(blockState)) {
|
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 3 Oct 2020 20:32:25 -0500
|
||||
Subject: [PATCH] Fix item locations dropped from campfires
|
||||
|
||||
Fixes #4259 by not flooring the blockposition among other weirdness
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
|
||||
index c4cf6abf0a962794ddbb4d7a691406054062ffee..24e2063db933bfbc8fc1f34edb8106ae4d7c633c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
|
||||
@@ -82,7 +82,11 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable {
|
||||
result = blockCookEvent.getResult();
|
||||
itemstack1 = CraftItemStack.asNMSCopy(result);
|
||||
// CraftBukkit end
|
||||
- Containers.dropItemStack(world, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), itemstack1);
|
||||
+ // Paper start
|
||||
+ net.minecraft.world.entity.item.ItemEntity droppedItem = new net.minecraft.world.entity.item.ItemEntity(world, pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, itemstack1.split(world.random.nextInt(21) + 10));
|
||||
+ droppedItem.setDeltaMovement(world.random.nextGaussian() * 0.05D, world.random.nextGaussian() * 0.05D + 0.2D, world.random.nextGaussian() * 0.05D);
|
||||
+ world.addFreshEntity(droppedItem);
|
||||
+ // Paper end
|
||||
campfire.items.set(i, ItemStack.EMPTY);
|
||||
world.sendBlockUpdated(pos, state, state, 3);
|
||||
world.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state));
|
39
patches/server/0477-Fixed-TileEntityBell-memory-leak.patch
Normal file
39
patches/server/0477-Fixed-TileEntityBell-memory-leak.patch
Normal file
|
@ -0,0 +1,39 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: giacomo <32515303+giacomozama@users.noreply.github.com>
|
||||
Date: Sat, 10 Oct 2020 12:15:33 +0200
|
||||
Subject: [PATCH] Fixed TileEntityBell memory leak
|
||||
|
||||
TileEntityBell has a list of entities (entitiesAtRing) that was not being cleared at the right time, causing leaks whenever a bell would be rung near a crowd of entities.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java
|
||||
index 30e9d4b20005dc6d20baf578f2ae958bdfcea02a..b446d6549922f3dabaaa05793d8ee3eb45566ac3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java
|
||||
@@ -63,6 +63,11 @@ public class BellBlockEntity extends BlockEntity {
|
||||
|
||||
if (blockEntity.ticks >= 50) {
|
||||
blockEntity.shaking = false;
|
||||
+ // Paper start
|
||||
+ if (!blockEntity.resonating) {
|
||||
+ blockEntity.nearbyEntities.clear();
|
||||
+ }
|
||||
+ // Paper end
|
||||
blockEntity.ticks = 0;
|
||||
}
|
||||
|
||||
@@ -76,6 +81,7 @@ public class BellBlockEntity extends BlockEntity {
|
||||
++blockEntity.resonationTicks;
|
||||
} else {
|
||||
bellEffect.run(world, pos, blockEntity.nearbyEntities);
|
||||
+ blockEntity.nearbyEntities.clear(); // Paper
|
||||
blockEntity.resonating = false;
|
||||
}
|
||||
}
|
||||
@@ -125,6 +131,7 @@ public class BellBlockEntity extends BlockEntity {
|
||||
}
|
||||
}
|
||||
|
||||
+ this.nearbyEntities.removeIf(e -> !e.isAlive()); // Paper
|
||||
}
|
||||
|
||||
private static boolean areRaidersNearby(BlockPos pos, List<LivingEntity> hearingEntities) {
|
|
@ -0,0 +1,46 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Toon Schoenmakers <nighteyes1993@gmail.com>
|
||||
Date: Fri, 23 Oct 2020 15:01:44 +0200
|
||||
Subject: [PATCH] Avoid error bubbling up when item stack is empty in fishing
|
||||
loot
|
||||
|
||||
This can realistically only happen if there's custom loot active on fishing
|
||||
which can return 0 items. This would disconnect the player who's fishing.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 5c77992e0c49eb217dd66657b35164225b400518..a9eaa079a43bc8a5e81deaf6df5ce2f9c53cb319 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -503,9 +503,15 @@ public class FishingHook extends Projectile {
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
ItemStack itemstack1 = (ItemStack) iterator.next();
|
||||
- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack1);
|
||||
+ // Paper start, new EntityItem would throw if for whatever reason (mostly shitty datapacks) the itemstack1 turns out to be empty
|
||||
+ // if the item stack is empty we instead just have our entityitem as null
|
||||
+ ItemEntity entityitem = null;
|
||||
+ if (!itemstack1.isEmpty()) {
|
||||
+ entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack1);
|
||||
+ }
|
||||
+ // Paper end
|
||||
// CraftBukkit start
|
||||
- PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem.getBukkitEntity(), (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH);
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem != null ? entityitem.getBukkitEntity() : null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH); // Paper - entityitem may be null
|
||||
playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1);
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
|
||||
@@ -518,8 +524,12 @@ public class FishingHook extends Projectile {
|
||||
double d2 = entityhuman.getZ() - this.getZ();
|
||||
double d3 = 0.1D;
|
||||
|
||||
- entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D);
|
||||
- this.level().addFreshEntity(entityitem);
|
||||
+ // Paper start, entity item can be null, so we need to check against this
|
||||
+ if (entityitem != null) {
|
||||
+ entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D);
|
||||
+ this.level().addFreshEntity(entityitem);
|
||||
+ }
|
||||
+ // Paper end
|
||||
// CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop()
|
||||
if (playerFishEvent.getExpToDrop() > 0) {
|
||||
entityhuman.level().addFreshEntity(new ExperienceOrb(entityhuman.level(), entityhuman.getX(), entityhuman.getY() + 0.5D, entityhuman.getZ() + 0.5D, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.getPlayerOwner(), this)); // Paper
|
|
@ -0,0 +1,39 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: oxygencraft <21054297+oxygencraft@users.noreply.github.com>
|
||||
Date: Sun, 25 Oct 2020 18:34:50 +1100
|
||||
Subject: [PATCH] Add getOfflinePlayerIfCached(String)
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index d355b46f23201163b70995a883994fcea1ac1689..561436bdff6b1a46b37cad519885c952da7e5b5d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1909,6 +1909,28 @@ public final class CraftServer implements Server {
|
||||
return result;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ @Nullable
|
||||
+ public OfflinePlayer getOfflinePlayerIfCached(String name) {
|
||||
+ Preconditions.checkArgument(name != null, "Name cannot be null");
|
||||
+ Preconditions.checkArgument(!name.isEmpty(), "Name cannot be empty");
|
||||
+
|
||||
+ OfflinePlayer result = getPlayerExact(name);
|
||||
+ if (result == null) {
|
||||
+ GameProfile profile = console.getProfileCache().getProfileIfCached(name);
|
||||
+
|
||||
+ if (profile != null) {
|
||||
+ result = getOfflinePlayer(profile);
|
||||
+ }
|
||||
+ } else {
|
||||
+ offlinePlayers.remove(result.getUniqueId());
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public OfflinePlayer getOfflinePlayer(UUID id) {
|
||||
Preconditions.checkArgument(id != null, "UUID id cannot be null");
|
154
patches/server/0480-Add-ignore-discounts-API.patch
Normal file
154
patches/server/0480-Add-ignore-discounts-API.patch
Normal file
|
@ -0,0 +1,154 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mariell Hoversholm <proximyst@proximyst.com>
|
||||
Date: Mon, 9 Nov 2020 20:44:51 +0100
|
||||
Subject: [PATCH] Add ignore discounts API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
index c0aa370367856a159412dd141f683b7d51e11c8b..363d1f469862c2e980624ff69f74be015c19412d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -508,6 +508,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
MerchantOffer merchantrecipe = (MerchantOffer) iterator.next();
|
||||
+ if (merchantrecipe.ignoreDiscounts) continue; // Paper
|
||||
|
||||
merchantrecipe.addToSpecialPriceDiff(-Mth.floor((float) i * merchantrecipe.getPriceMultiplier()));
|
||||
}
|
||||
@@ -520,6 +521,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
|
||||
while (iterator1.hasNext()) {
|
||||
MerchantOffer merchantrecipe1 = (MerchantOffer) iterator1.next();
|
||||
+ if (merchantrecipe1.ignoreDiscounts) continue; // Paper
|
||||
double d0 = 0.3D + 0.0625D * (double) j;
|
||||
int k = (int) Math.floor(d0 * (double) merchantrecipe1.getBaseCostA().getCount());
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java
|
||||
index 1d755d04515f20dbd69931084b4cc894e52d35c9..4f7457578ab3118d10e0d5dfc23d79c9b20c2f44 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java
|
||||
@@ -19,6 +19,7 @@ public class MerchantOffer {
|
||||
public int demand;
|
||||
public float priceMultiplier;
|
||||
public int xp;
|
||||
+ public boolean ignoreDiscounts; // Paper
|
||||
// CraftBukkit start
|
||||
private CraftMerchantRecipe bukkitHandle;
|
||||
|
||||
@@ -31,7 +32,15 @@ public class MerchantOffer {
|
||||
}
|
||||
|
||||
public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, int demand, CraftMerchantRecipe bukkit) {
|
||||
- this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, demand);
|
||||
+ // Paper start - add ignoreDiscounts param
|
||||
+ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, demand, false, bukkit);
|
||||
+ }
|
||||
+ public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, boolean ignoreDiscounts, CraftMerchantRecipe bukkit) {
|
||||
+ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, 0, ignoreDiscounts, bukkit);
|
||||
+ }
|
||||
+ public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, int demand, boolean ignoreDiscounts, CraftMerchantRecipe bukkit) {
|
||||
+ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, demand, ignoreDiscounts);
|
||||
+ // Paper end
|
||||
this.bukkitHandle = bukkit;
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -63,6 +72,7 @@ public class MerchantOffer {
|
||||
|
||||
this.specialPriceDiff = nbt.getInt("specialPrice");
|
||||
this.demand = nbt.getInt("demand");
|
||||
+ this.ignoreDiscounts = nbt.getBoolean("Paper.IgnoreDiscounts"); // Paper
|
||||
}
|
||||
|
||||
public MerchantOffer(ItemStack buyItem, ItemStack sellItem, int maxUses, int merchantExperience, float priceMultiplier) {
|
||||
@@ -74,10 +84,19 @@ public class MerchantOffer {
|
||||
}
|
||||
|
||||
public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier) {
|
||||
- this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, merchantExperience, priceMultiplier, 0);
|
||||
+ // Paper start - add ignoreDiscounts param
|
||||
+ this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, merchantExperience, priceMultiplier, false);
|
||||
+ }
|
||||
+ public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier, boolean ignoreDiscounts) {
|
||||
+ this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, merchantExperience, priceMultiplier, 0, ignoreDiscounts);
|
||||
}
|
||||
|
||||
public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier, int demandBonus) {
|
||||
+ this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, merchantExperience, priceMultiplier, demandBonus, false);
|
||||
+ }
|
||||
+ public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier, int demandBonus, boolean ignoreDiscounts) {
|
||||
+ this.ignoreDiscounts = ignoreDiscounts;
|
||||
+ // Paper end
|
||||
this.rewardExp = true;
|
||||
this.xp = 1;
|
||||
this.baseCostA = firstBuyItem;
|
||||
@@ -210,6 +229,7 @@ public class MerchantOffer {
|
||||
nbttagcompound.putFloat("priceMultiplier", this.priceMultiplier);
|
||||
nbttagcompound.putInt("specialPrice", this.specialPriceDiff);
|
||||
nbttagcompound.putInt("demand", this.demand);
|
||||
+ nbttagcompound.putBoolean("Paper.IgnoreDiscounts", this.ignoreDiscounts); // Paper
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java
|
||||
index c015b34d2b13a759783da7c0c06dd0563d35fc88..5741a233fb1dd8ad0f83a09b44476a4b88e6aa16 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java
|
||||
@@ -18,11 +18,19 @@ public class CraftMerchantRecipe extends MerchantRecipe {
|
||||
|
||||
@Deprecated
|
||||
public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier) {
|
||||
- this(result, uses, maxUses, experienceReward, experience, priceMultiplier, 0, 0);
|
||||
+ // Paper start - add ignoreDiscounts param
|
||||
+ this(result, uses, maxUses, experienceReward, experience, priceMultiplier, 0, 0, false);
|
||||
+ }
|
||||
+ public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier, boolean ignoreDiscounts) {
|
||||
+ this(result, uses, maxUses, experienceReward, experience, priceMultiplier, 0, 0, ignoreDiscounts);
|
||||
}
|
||||
|
||||
public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier, int demand, int specialPrice) {
|
||||
- super(result, uses, maxUses, experienceReward, experience, priceMultiplier, demand, specialPrice);
|
||||
+ this(result, uses, maxUses, experienceReward, experience, priceMultiplier, demand, specialPrice, false);
|
||||
+ }
|
||||
+ public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier, int demand, int specialPrice, boolean ignoreDiscounts) {
|
||||
+ super(result, uses, maxUses, experienceReward, experience, priceMultiplier, demand, specialPrice, ignoreDiscounts);
|
||||
+ // Paper end
|
||||
this.handle = new net.minecraft.world.item.trading.MerchantOffer(
|
||||
net.minecraft.world.item.ItemStack.EMPTY,
|
||||
net.minecraft.world.item.ItemStack.EMPTY,
|
||||
@@ -32,6 +40,7 @@ public class CraftMerchantRecipe extends MerchantRecipe {
|
||||
experience,
|
||||
priceMultiplier,
|
||||
demand,
|
||||
+ ignoreDiscounts, // Paper - add ignoreDiscounts param
|
||||
this
|
||||
);
|
||||
this.setSpecialPrice(specialPrice);
|
||||
@@ -108,6 +117,18 @@ public class CraftMerchantRecipe extends MerchantRecipe {
|
||||
this.handle.priceMultiplier = priceMultiplier;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean shouldIgnoreDiscounts() {
|
||||
+ return this.handle.ignoreDiscounts;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setIgnoreDiscounts(boolean ignoreDiscounts) {
|
||||
+ this.handle.ignoreDiscounts = ignoreDiscounts;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public net.minecraft.world.item.trading.MerchantOffer toMinecraft() {
|
||||
List<ItemStack> ingredients = this.getIngredients();
|
||||
Preconditions.checkState(!ingredients.isEmpty(), "No offered ingredients");
|
||||
@@ -122,7 +143,7 @@ public class CraftMerchantRecipe extends MerchantRecipe {
|
||||
if (recipe instanceof CraftMerchantRecipe) {
|
||||
return (CraftMerchantRecipe) recipe;
|
||||
} else {
|
||||
- CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier(), recipe.getDemand(), recipe.getSpecialPrice());
|
||||
+ CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier(), recipe.getDemand(), recipe.getSpecialPrice(), recipe.shouldIgnoreDiscounts()); // Paper - shouldIgnoreDiscounts
|
||||
craft.setIngredients(recipe.getIngredients());
|
||||
|
||||
return craft;
|
|
@ -0,0 +1,19 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mariell Hoversholm <proximyst@proximyst.com>
|
||||
Date: Wed, 30 Sep 2020 22:49:14 +0200
|
||||
Subject: [PATCH] Toggle for removing existing dragon
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
index 7be3405a93fbb9f43075983825d1ac9299cbe7b9..7741b27816636aaa48277b2fe14fd7b88cd3d78a 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -209,7 +209,7 @@ public class EndDragonFight {
|
||||
this.dragonUUID = entityenderdragon.getUUID();
|
||||
EndDragonFight.LOGGER.info("Found that there's a dragon still alive ({})", entityenderdragon);
|
||||
this.dragonKilled = false;
|
||||
- if (!flag) {
|
||||
+ if (!flag && this.level.paperConfig().entities.behavior.shouldRemoveDragon) {
|
||||
EndDragonFight.LOGGER.info("But we didn't have a portal, let's remove it.");
|
||||
entityenderdragon.discard();
|
||||
this.dragonUUID = null;
|
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Sat, 31 Oct 2020 11:49:01 -0700
|
||||
Subject: [PATCH] Fix client lag on advancement loading
|
||||
|
||||
When new advancements are added via the UnsafeValues#loadAdvancement
|
||||
API, it triggers a full datapack reload when this is not necessary. The
|
||||
advancement is already loaded directly into the advancement registry,
|
||||
and the point of saving the advancement to the Bukkit datapack seems to
|
||||
be for persistence. By removing the call to reload datapacks when an
|
||||
advancement is loaded, the client no longer completely freezes up when
|
||||
adding a new advancement.
|
||||
To ensure the client still receives the updated advancement data, we
|
||||
manually reload the advancement data for all players, which
|
||||
normally takes place as a part of the datapack reloading.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 5d1df87177b3d6a5f4c4b1f12bbbba7b597f2911..5930cc6af2d73e6301b0ebe59ea53e0a7ea2098a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -329,7 +329,13 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Error saving advancement " + key, ex);
|
||||
}
|
||||
|
||||
- MinecraftServer.getServer().getPlayerList().reloadResources();
|
||||
+ // Paper start
|
||||
+ //MinecraftServer.getServer().getPlayerList().reload();
|
||||
+ MinecraftServer.getServer().getPlayerList().getPlayers().forEach(player -> {
|
||||
+ player.getAdvancements().reload(MinecraftServer.getServer().getAdvancements());
|
||||
+ player.getAdvancements().flushDirty(player);
|
||||
+ });
|
||||
+ // Paper end
|
||||
|
||||
return bukkit;
|
||||
}
|
49
patches/server/0483-Item-no-age-no-player-pickup.patch
Normal file
49
patches/server/0483-Item-no-age-no-player-pickup.patch
Normal file
|
@ -0,0 +1,49 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alfie Smith <alfie@alfiesmith.net>
|
||||
Date: Sat, 7 Nov 2020 01:20:33 +0000
|
||||
Subject: [PATCH] Item no age & no player pickup
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
index 4456b7c438cadb4bfabad030b6871b3a8a7fd439..cbdac5a439795d429a1364a7eafc4783cff51d54 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
@@ -9,6 +9,11 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class CraftItem extends CraftEntity implements Item {
|
||||
|
||||
+ // Paper start
|
||||
+ private final static int NO_AGE_TIME = (int) Short.MIN_VALUE;
|
||||
+ private final static int NO_PICKUP_TIME = (int) Short.MAX_VALUE;
|
||||
+ // Paper end
|
||||
+
|
||||
public CraftItem(CraftServer server, ItemEntity entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
@@ -73,6 +78,26 @@ public class CraftItem extends CraftEntity implements Item {
|
||||
public void setCanMobPickup(boolean canMobPickup) {
|
||||
this.getHandle().canMobPickup = canMobPickup;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canPlayerPickup() {
|
||||
+ return this.getHandle().pickupDelay != NO_PICKUP_TIME;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanPlayerPickup(boolean canPlayerPickup) {
|
||||
+ this.getHandle().pickupDelay = canPlayerPickup ? 0 : NO_PICKUP_TIME;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean willAge() {
|
||||
+ return this.getHandle().age != NO_AGE_TIME;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWillAge(boolean willAge) {
|
||||
+ this.getHandle().age = willAge ? 0 : NO_AGE_TIME;
|
||||
+ }
|
||||
// Paper End
|
||||
|
||||
@Override
|
|
@ -0,0 +1,135 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 4 Aug 2020 22:24:15 +0200
|
||||
Subject: [PATCH] Optimize Pathfinder - Remove Streams / Optimized collections
|
||||
|
||||
1.17 Update: Please do this k thx bb
|
||||
I utilized the IDE to convert streams to non streams code, so shouldn't
|
||||
be any risk of behavior change. Only did minor optimization of the
|
||||
generated code set to remove unnecessary things.
|
||||
|
||||
I expect us to just drop this patch on next major update and re-apply
|
||||
it with the IDE again and re-apply the collections optimization.
|
||||
|
||||
Optimize collection by creating a list instead of a set of the key and value.
|
||||
|
||||
This lets us get faster foreach iteration, as well as avoids map lookups on
|
||||
the values when needed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
|
||||
index 8519383a9abd45434c1e9888e77548941a80c79c..d23481453717f715124156b5d83f6448f720d049 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
|
||||
@@ -38,9 +38,12 @@ public class PathFinder {
|
||||
if (node == null) {
|
||||
return null;
|
||||
} else {
|
||||
- Map<Target, BlockPos> map = positions.stream().collect(Collectors.toMap((pos) -> {
|
||||
- return this.nodeEvaluator.getGoal((double)pos.getX(), (double)pos.getY(), (double)pos.getZ());
|
||||
- }, Function.identity()));
|
||||
+ // Paper start - remove streams - and optimize collection
|
||||
+ List<Map.Entry<Target, BlockPos>> map = Lists.newArrayList();
|
||||
+ for (BlockPos pos : positions) {
|
||||
+ map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getGoal(pos.getX(), pos.getY(), pos.getZ()), pos));
|
||||
+ }
|
||||
+ // Paper end
|
||||
Path path = this.findPath(world.getProfiler(), node, map, followRange, distance, rangeMultiplier);
|
||||
this.nodeEvaluator.done();
|
||||
return path;
|
||||
@@ -48,18 +51,19 @@ public class PathFinder {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
- private Path findPath(ProfilerFiller profiler, Node startNode, Map<Target, BlockPos> positions, float followRange, int distance, float rangeMultiplier) {
|
||||
+ // Paper start - optimize collection
|
||||
+ private Path findPath(ProfilerFiller profiler, Node startNode, List<Map.Entry<Target, BlockPos>> positions, float followRange, int distance, float rangeMultiplier) {
|
||||
profiler.push("find_path");
|
||||
profiler.markForCharting(MetricCategory.PATH_FINDING);
|
||||
- Set<Target> set = positions.keySet();
|
||||
+ // Set<Target> set = positions.keySet();
|
||||
startNode.g = 0.0F;
|
||||
- startNode.h = this.getBestH(startNode, set);
|
||||
+ startNode.h = this.getBestH(startNode, positions); // Paper - optimize collection
|
||||
startNode.f = startNode.h;
|
||||
this.openSet.clear();
|
||||
this.openSet.insert(startNode);
|
||||
- Set<Node> set2 = ImmutableSet.of();
|
||||
+ // Set<Node> set2 = ImmutableSet.of(); // Paper - unused - diff on change
|
||||
int i = 0;
|
||||
- Set<Target> set3 = Sets.newHashSetWithExpectedSize(set.size());
|
||||
+ List<Map.Entry<Target, BlockPos>> entryList = Lists.newArrayListWithExpectedSize(positions.size()); // Paper - optimize collection
|
||||
int j = (int)((float)this.maxVisitedNodes * rangeMultiplier);
|
||||
|
||||
while(!this.openSet.isEmpty()) {
|
||||
@@ -71,14 +75,18 @@ public class PathFinder {
|
||||
Node node = this.openSet.pop();
|
||||
node.closed = true;
|
||||
|
||||
- for(Target target : set) {
|
||||
+ // Paper start - optimize collection
|
||||
+ for(int i1 = 0; i1 < positions.size(); i1++) {
|
||||
+ final Map.Entry<Target, BlockPos> entry = positions.get(i1);
|
||||
+ Target target = entry.getKey();
|
||||
if (node.distanceManhattan(target) <= (float)distance) {
|
||||
target.setReached();
|
||||
- set3.add(target);
|
||||
+ entryList.add(entry);
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
- if (!set3.isEmpty()) {
|
||||
+ if (!entryList.isEmpty()) { // Paper - rename variable
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -93,7 +101,7 @@ public class PathFinder {
|
||||
if (node2.walkedDistance < followRange && (!node2.inOpenSet() || g < node2.g)) {
|
||||
node2.cameFrom = node;
|
||||
node2.g = g;
|
||||
- node2.h = this.getBestH(node2, set) * 1.5F;
|
||||
+ node2.h = this.getBestH(node2, positions) * 1.5F; // Paper - list instead of set
|
||||
if (node2.inOpenSet()) {
|
||||
this.openSet.changeCost(node2, node2.g + node2.h);
|
||||
} else {
|
||||
@@ -105,23 +113,31 @@ public class PathFinder {
|
||||
}
|
||||
}
|
||||
|
||||
- Optional<Path> optional = !set3.isEmpty() ? set3.stream().map((node) -> {
|
||||
- return this.reconstructPath(node.getBestNode(), positions.get(node), true);
|
||||
- }).min(Comparator.comparingInt(Path::getNodeCount)) : set.stream().map((target) -> {
|
||||
- return this.reconstructPath(target.getBestNode(), positions.get(target), false);
|
||||
- }).min(Comparator.comparingDouble(Path::getDistToTarget).thenComparingInt(Path::getNodeCount));
|
||||
- profiler.pop();
|
||||
- return optional.isEmpty() ? null : optional.get();
|
||||
+ // Paper start - remove streams - and optimize collection
|
||||
+ Path best = null;
|
||||
+ boolean entryListIsEmpty = entryList.isEmpty();
|
||||
+ Comparator<Path> comparator = entryListIsEmpty ? Comparator.comparingInt(Path::getNodeCount)
|
||||
+ : Comparator.comparingDouble(Path::getDistToTarget).thenComparingInt(Path::getNodeCount);
|
||||
+ for (Map.Entry<Target, BlockPos> entry : entryListIsEmpty ? positions : entryList) {
|
||||
+ Path path = this.reconstructPath(entry.getKey().getBestNode(), entry.getValue(), !entryListIsEmpty);
|
||||
+ if (best == null || comparator.compare(path, best) < 0)
|
||||
+ best = path;
|
||||
+ }
|
||||
+ return best;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
protected float distance(Node a, Node b) {
|
||||
return a.distanceTo(b);
|
||||
}
|
||||
|
||||
- private float getBestH(Node node, Set<Target> targets) {
|
||||
+ private float getBestH(Node node, List<Map.Entry<Target, BlockPos>> targets) { // Paper - optimize collection - Set<Target> -> List<Map.Entry<Target, BlockPos>>
|
||||
float f = Float.MAX_VALUE;
|
||||
|
||||
- for(Target target : targets) {
|
||||
+ // Paper start - optimize collection
|
||||
+ for (int i = 0, targetsSize = targets.size(); i < targetsSize; i++) {
|
||||
+ final Target target = targets.get(i).getKey();
|
||||
+ // Paper end
|
||||
float g = node.distanceTo(target);
|
||||
target.updateBest(g, node);
|
||||
f = Math.min(g, f);
|
131
patches/server/0485-Beacon-API-custom-effect-ranges.patch
Normal file
131
patches/server/0485-Beacon-API-custom-effect-ranges.patch
Normal file
|
@ -0,0 +1,131 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 24 Jun 2020 12:39:08 -0600
|
||||
Subject: [PATCH] Beacon API - custom effect ranges
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
index cd28ee0cbc69713a641a21c9a626c694a4bcbfc9..3a50fe20294048a1c818ae717a918bb1aed74dea 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
@@ -82,6 +82,26 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
return (BeaconBlockEntity.hasSecondaryEffect(this.levels, this.primaryPower, this.secondaryPower)) ? CraftPotionUtil.toBukkit(new MobEffectInstance(this.secondaryPower, BeaconBlockEntity.getLevel(this.levels), BeaconBlockEntity.getAmplification(this.levels, this.primaryPower, this.secondaryPower), true, true)) : null;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - add field/methods for custom range
|
||||
+ private final String PAPER_RANGE_TAG = "Paper.Range";
|
||||
+ private double effectRange = -1;
|
||||
+
|
||||
+ public double getEffectRange() {
|
||||
+ if (this.effectRange < 0) {
|
||||
+ return this.levels * 10 + 10;
|
||||
+ } else {
|
||||
+ return effectRange;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void setEffectRange(double range) {
|
||||
+ this.effectRange = range;
|
||||
+ }
|
||||
+
|
||||
+ public void resetEffectRange() {
|
||||
+ this.effectRange = -1;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Nullable
|
||||
static MobEffect filterEffect(@Nullable MobEffect effect) {
|
||||
@@ -197,7 +217,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
}
|
||||
|
||||
if (blockEntity.levels > 0 && !blockEntity.beamSections.isEmpty()) {
|
||||
- BeaconBlockEntity.applyEffects(world, pos, blockEntity.levels, blockEntity.primaryPower, blockEntity.secondaryPower);
|
||||
+ BeaconBlockEntity.applyEffects(world, pos, blockEntity.levels, blockEntity.primaryPower, blockEntity.secondaryPower, blockEntity); // Paper
|
||||
BeaconBlockEntity.playSound(world, pos, SoundEvents.BEACON_AMBIENT);
|
||||
}
|
||||
}
|
||||
@@ -283,8 +303,13 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
}
|
||||
|
||||
public static List getHumansInRange(Level world, BlockPos blockposition, int i) {
|
||||
+ // Paper start
|
||||
+ return BeaconBlockEntity.getHumansInRange(world, blockposition, i, null);
|
||||
+ }
|
||||
+ public static List getHumansInRange(Level world, BlockPos blockposition, int i, @Nullable BeaconBlockEntity blockEntity) {
|
||||
+ // Paper end
|
||||
{
|
||||
- double d0 = (double) (i * 10 + 10);
|
||||
+ double d0 = blockEntity != null ? blockEntity.getEffectRange() : (i * 10 + 10);// Paper - custom beacon ranges
|
||||
|
||||
AABB axisalignedbb = (new AABB(blockposition)).inflate(d0).expandTowards(0.0D, (double) world.getHeight(), 0.0D);
|
||||
List<Player> list = world.getEntitiesOfClass(Player.class, axisalignedbb);
|
||||
@@ -325,12 +350,17 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
}
|
||||
|
||||
private static void applyEffects(Level world, BlockPos pos, int beaconLevel, @Nullable MobEffect primaryEffect, @Nullable MobEffect secondaryEffect) {
|
||||
+ // Paper start
|
||||
+ BeaconBlockEntity.applyEffects(world, pos, beaconLevel, primaryEffect, secondaryEffect, null);
|
||||
+ }
|
||||
+ private static void applyEffects(Level world, BlockPos pos, int beaconLevel, @Nullable MobEffect primaryEffect, @Nullable MobEffect secondaryEffect, @Nullable BeaconBlockEntity blockEntity) {
|
||||
+ // Paper end
|
||||
if (!world.isClientSide && primaryEffect != null) {
|
||||
double d0 = (double) (beaconLevel * 10 + 10);
|
||||
byte b0 = BeaconBlockEntity.getAmplification(beaconLevel, primaryEffect, secondaryEffect);
|
||||
|
||||
int j = BeaconBlockEntity.getLevel(beaconLevel);
|
||||
- List list = BeaconBlockEntity.getHumansInRange(world, pos, beaconLevel);
|
||||
+ List list = BeaconBlockEntity.getHumansInRange(world, pos, beaconLevel, blockEntity); // Paper
|
||||
|
||||
BeaconBlockEntity.applyEffect(list, primaryEffect, j, b0, true, pos); // Paper - BeaconEffectEvent
|
||||
|
||||
@@ -393,6 +423,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
}
|
||||
|
||||
this.lockKey = LockCode.fromTag(nbt);
|
||||
+ this.effectRange = nbt.contains(PAPER_RANGE_TAG, 6) ? nbt.getDouble(PAPER_RANGE_TAG) : -1; // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -406,6 +437,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
}
|
||||
|
||||
this.lockKey.addToTag(nbt);
|
||||
+ nbt.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper
|
||||
}
|
||||
|
||||
public void setCustomName(@Nullable Component customName) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java
|
||||
index c4890927419e27fd35e4e373fb09dcb182234fbf..7d90360bac08d6ec796ba44f1809793f3a3c1b3f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java
|
||||
@@ -32,7 +32,7 @@ public class CraftBeacon extends CraftBlockEntityState<BeaconBlockEntity> implem
|
||||
if (tileEntity instanceof BeaconBlockEntity) {
|
||||
BeaconBlockEntity beacon = (BeaconBlockEntity) tileEntity;
|
||||
|
||||
- Collection<Player> nms = BeaconBlockEntity.getHumansInRange(beacon.getLevel(), beacon.getBlockPos(), beacon.levels);
|
||||
+ Collection<Player> nms = BeaconBlockEntity.getHumansInRange(beacon.getLevel(), beacon.getBlockPos(), beacon.levels, beacon); // Paper
|
||||
Collection<LivingEntity> bukkit = new ArrayList<LivingEntity>(nms.size());
|
||||
|
||||
for (Player human : nms) {
|
||||
@@ -114,4 +114,21 @@ public class CraftBeacon extends CraftBlockEntityState<BeaconBlockEntity> implem
|
||||
public CraftBeacon copy() {
|
||||
return new CraftBeacon(this);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public double getEffectRange() {
|
||||
+ return this.getSnapshot().getEffectRange();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setEffectRange(double range) {
|
||||
+ this.getSnapshot().setEffectRange(range);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetEffectRange() {
|
||||
+ this.getSnapshot().resetEffectRange();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
63
patches/server/0486-Add-API-for-quit-reason.patch
Normal file
63
patches/server/0486-Add-API-for-quit-reason.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mariell Hoversholm <proximyst@proximyst.com>
|
||||
Date: Sat, 14 Nov 2020 16:19:52 +0100
|
||||
Subject: [PATCH] Add API for quit reason
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index f9d7fec242a059a3b056c569ffaf214a361716d6..33a3c657bd390b9e8bc23af93c1107f5327181b2 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -183,12 +183,15 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
|
||||
this.handlingFault = true;
|
||||
if (this.channel.isOpen()) {
|
||||
+ net.minecraft.server.level.ServerPlayer player = this.getPlayer(); // Paper
|
||||
if (throwable instanceof TimeoutException) {
|
||||
Connection.LOGGER.debug("Timeout", throwable);
|
||||
+ if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.TIMED_OUT; // Paper
|
||||
this.disconnect(Component.translatable("disconnect.timeout"));
|
||||
} else {
|
||||
MutableComponent ichatmutablecomponent = Component.translatable("disconnect.genericReason", "Internal Exception: " + throwable);
|
||||
|
||||
+ if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.ERRONEOUS_STATE; // Paper
|
||||
if (flag) {
|
||||
Connection.LOGGER.debug("Failed to sent packet", throwable);
|
||||
if (this.getSending() == PacketFlow.CLIENTBOUND) {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 478abaffd1a80949b96f1c1774c98134be92e5ac..063742400f3065ace62b64b42d952517ae00ea1f 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -279,6 +279,7 @@ public class ServerPlayer extends Player {
|
||||
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
|
||||
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
|
||||
public @Nullable String clientBrandName = null; // Paper - Brand name
|
||||
+ public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event
|
||||
|
||||
// Paper start - replace player chunk loader
|
||||
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index 2d0ce31011ce1dbbf3c86f09bbf9a41a6e4a158f..156e49d682be26f0962cae960acaef613bd6ebba 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -302,6 +302,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
final Component ichatbasecomponent = io.papermc.paper.adventure.PaperAdventure.asVanilla(event.reason()); // Paper - Adventure
|
||||
// CraftBukkit end
|
||||
|
||||
+ this.player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.KICKED; // Paper
|
||||
this.connection.send(new ClientboundDisconnectPacket(ichatbasecomponent), PacketSendListener.thenRun(() -> {
|
||||
this.connection.disconnect(ichatbasecomponent);
|
||||
}));
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 7f05a1c3847c36699d3c9acbb1d7cd05363c94c5..f57be0d9111582b279f5ee6988f56068b9b63968 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -579,7 +579,7 @@ public abstract class PlayerList {
|
||||
entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper
|
||||
}
|
||||
|
||||
- PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName()))); // Paper - Adventure
|
||||
+ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())), entityplayer.quitReason); // Paper - Adventure & quit reason
|
||||
this.cserver.getPluginManager().callEvent(playerQuitEvent);
|
||||
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Thu, 20 Aug 2020 11:20:12 -0700
|
||||
Subject: [PATCH] Add Wandering Trader spawn rate config options
|
||||
|
||||
Adds config options for modifying the spawn rates of Wandering Traders.
|
||||
These values are all easy to understand and configure after a quick read of this
|
||||
page on the Minecraft wiki: https://minecraft.wiki/wiki/Wandering_Trader#Spawning
|
||||
Usages of the vanilla WanderingTraderSpawnDelay and WanderingTraderSpawnChance values
|
||||
in IWorldServerData are removed as they were only used in certain places, with hardcoded
|
||||
values used in other places.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
|
||||
index 83d0db5a9f03ee3ead10d9f61e5f425330eae0e9..5d199fe497bd852827d3d18fb7566a09e70331a3 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
|
||||
@@ -40,43 +40,53 @@ public class WanderingTraderSpawner implements CustomSpawner {
|
||||
|
||||
public WanderingTraderSpawner(ServerLevelData properties) {
|
||||
this.serverLevelData = properties;
|
||||
- this.tickDelay = 1200;
|
||||
- this.spawnDelay = properties.getWanderingTraderSpawnDelay();
|
||||
- this.spawnChance = properties.getWanderingTraderSpawnChance();
|
||||
- if (this.spawnDelay == 0 && this.spawnChance == 0) {
|
||||
- this.spawnDelay = 24000;
|
||||
- properties.setWanderingTraderSpawnDelay(this.spawnDelay);
|
||||
- this.spawnChance = 25;
|
||||
- properties.setWanderingTraderSpawnChance(this.spawnChance);
|
||||
- }
|
||||
+ // Paper start
|
||||
+ this.tickDelay = Integer.MIN_VALUE;
|
||||
+ //this.spawnDelay = properties.getWanderingTraderSpawnDelay(); // Paper - This value is read from the world file only for the first spawn, after which vanilla uses a hardcoded value
|
||||
+ //this.spawnChance = properties.getWanderingTraderSpawnChance(); // Paper - This value is read from the world file only for the first spawn, after which vanilla uses a hardcoded value
|
||||
+ //if (this.spawnDelay == 0 && this.spawnChance == 0) {
|
||||
+ // this.spawnDelay = 24000;
|
||||
+ // properties.setWanderingTraderSpawnDelay(this.spawnDelay);
|
||||
+ // this.spawnChance = 25;
|
||||
+ // properties.setWanderingTraderSpawnChance(this.spawnChance);
|
||||
+ //}
|
||||
+ // Paper end
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int tick(ServerLevel world, boolean spawnMonsters, boolean spawnAnimals) {
|
||||
+ // Paper start
|
||||
+ if (this.tickDelay == Integer.MIN_VALUE) {
|
||||
+ this.tickDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength;
|
||||
+ this.spawnDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnDayLength;
|
||||
+ this.spawnChance = world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin;
|
||||
+ }
|
||||
if (!world.getGameRules().getBoolean(GameRules.RULE_DO_TRADER_SPAWNING)) {
|
||||
return 0;
|
||||
- } else if (--this.tickDelay > 0) {
|
||||
+ } else if (this.tickDelay - 1 > 0) {
|
||||
+ this.tickDelay = this.tickDelay - 1;
|
||||
return 0;
|
||||
} else {
|
||||
- this.tickDelay = 1200;
|
||||
- this.spawnDelay -= 1200;
|
||||
- this.serverLevelData.setWanderingTraderSpawnDelay(this.spawnDelay);
|
||||
+ this.tickDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength;
|
||||
+ this.spawnDelay = this.spawnDelay - world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength;
|
||||
+ //this.serverLevelData.setWanderingTraderSpawnDelay(this.spawnDelay); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways
|
||||
if (this.spawnDelay > 0) {
|
||||
return 0;
|
||||
} else {
|
||||
- this.spawnDelay = 24000;
|
||||
+ this.spawnDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnDayLength;
|
||||
if (!world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
|
||||
return 0;
|
||||
} else {
|
||||
int i = this.spawnChance;
|
||||
|
||||
- this.spawnChance = Mth.clamp(this.spawnChance + 25, 25, 75);
|
||||
- this.serverLevelData.setWanderingTraderSpawnChance(this.spawnChance);
|
||||
+ // this.serverLevelData.setWanderingTraderSpawnChance(this.spawnChance); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways
|
||||
+ this.spawnChance = Mth.clamp(i + world.paperConfig().entities.spawning.wanderingTrader.spawnChanceFailureIncrement, world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin, world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMax);
|
||||
if (this.random.nextInt(100) > i) {
|
||||
return 0;
|
||||
} else if (this.spawn(world)) {
|
||||
- this.spawnChance = 25;
|
||||
+ this.spawnChance = world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin;
|
||||
+ // Paper end
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
19
patches/server/0488-Expose-world-spawn-angle.patch
Normal file
19
patches/server/0488-Expose-world-spawn-angle.patch
Normal file
|
@ -0,0 +1,19 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Tue, 17 Nov 2020 19:13:09 +0200
|
||||
Subject: [PATCH] Expose world spawn angle
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index f57be0d9111582b279f5ee6988f56068b9b63968..5d1af62e7d06f1fbcfe1eec0293ca3065a88454f 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -851,7 +851,7 @@ public abstract class PlayerList {
|
||||
if (location == null) {
|
||||
worldserver1 = this.server.getLevel(Level.OVERWORLD);
|
||||
blockposition = entityplayer1.getSpawnPoint(worldserver1);
|
||||
- location = CraftLocation.toBukkit(blockposition, worldserver1.getWorld()).add(0.5F, 0.1F, 0.5F);
|
||||
+ location = CraftLocation.toBukkit(blockposition, worldserver1.getWorld(), worldserver1.levelData.getSpawnAngle(), 0.0F).add(0.5F, 0.1F, 0.5F); // Paper - use world spawn angle
|
||||
}
|
||||
|
||||
Player respawnPlayer = entityplayer1.getBukkitEntity();
|
31
patches/server/0489-Add-Destroy-Speed-API.patch
Normal file
31
patches/server/0489-Add-Destroy-Speed-API.patch
Normal file
|
@ -0,0 +1,31 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ineusia <ineusia@yahoo.com>
|
||||
Date: Mon, 26 Oct 2020 11:48:06 -0500
|
||||
Subject: [PATCH] Add Destroy Speed API
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index d6ba9030b0736afda9f7d2effa95d6d63e983b34..79c469d461ce9df0994214ebc8b157a095a4c848 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -696,4 +696,19 @@ public class CraftBlockData implements BlockData {
|
||||
public BlockState createBlockState() {
|
||||
return CraftBlockStates.getBlockState(this.state, null);
|
||||
}
|
||||
+
|
||||
+ // Paper start - destroy speed API
|
||||
+ @Override
|
||||
+ public float getDestroySpeed(final ItemStack itemStack, final boolean considerEnchants) {
|
||||
+ net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.unwrap(itemStack);
|
||||
+ float speed = nmsItemStack.getDestroySpeed(this.state);
|
||||
+ if (speed > 1.0F && considerEnchants) {
|
||||
+ int enchantLevel = net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.BLOCK_EFFICIENCY, nmsItemStack);
|
||||
+ if (enchantLevel > 0) {
|
||||
+ speed += enchantLevel * enchantLevel + 1;
|
||||
+ }
|
||||
+ }
|
||||
+ return speed;
|
||||
+ }
|
||||
+ // Paper end - destroy speed API
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Esophose <esophose@gmail.com>
|
||||
Date: Sat, 3 Oct 2020 18:57:47 -0600
|
||||
Subject: [PATCH] Fix Player spawnParticle x/y/z precision loss
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 16476b8d20619d8526658db24ed3de60a151ffcf..3c0295db596da4fd743730fc5a74f1b4c5b60a98 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -2541,7 +2541,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
if (data != null) {
|
||||
Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
|
||||
}
|
||||
- ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.createParticleParam(particle, data), true, (float) x, (float) y, (float) z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count);
|
||||
+ ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.createParticleParam(particle, data), true, x, y, z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count); // Paper - Fix x/y/z coordinate precision loss
|
||||
this.getHandle().connection.send(packetplayoutworldparticles);
|
||||
|
||||
}
|
24
patches/server/0491-Add-LivingEntity-clearActiveItem.patch
Normal file
24
patches/server/0491-Add-LivingEntity-clearActiveItem.patch
Normal file
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anrza <andrzejrzeczycki314@gmail.com>
|
||||
Date: Wed, 15 Jul 2020 12:08:49 +0200
|
||||
Subject: [PATCH] Add LivingEntity#clearActiveItem
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 95406737a6c72fd118a0022e07cdf15936e3911a..66c762c13a70f917e06795dcee85cae66cd316d4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -892,6 +892,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
return getHandle().getUseItem().asBukkitMirror();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void clearActiveItem() {
|
||||
+ getHandle().stopUsingItem();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public int getItemUseRemainingTime() {
|
||||
return getHandle().getUseItemRemainingTicks();
|
27
patches/server/0492-Add-PlayerItemCooldownEvent.patch
Normal file
27
patches/server/0492-Add-PlayerItemCooldownEvent.patch
Normal file
|
@ -0,0 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Tue, 25 Aug 2020 13:48:33 +0200
|
||||
Subject: [PATCH] Add PlayerItemCooldownEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java b/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java
|
||||
index 47283d2a49209839002212e663a503a82ea86587..ce026600b3b5c846d991a0dfe599708caf2a2962 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java
|
||||
@@ -10,6 +10,16 @@ public class ServerItemCooldowns extends ItemCooldowns {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void addCooldown(Item item, int duration) {
|
||||
+ io.papermc.paper.event.player.PlayerItemCooldownEvent event = new io.papermc.paper.event.player.PlayerItemCooldownEvent(this.player.getBukkitEntity(), org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(item), duration);
|
||||
+ if (event.callEvent()) {
|
||||
+ super.addCooldown(item, event.getCooldown());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
protected void onCooldownStarted(Item item, int duration) {
|
||||
super.onCooldownStarted(item, duration);
|
|
@ -0,0 +1,63 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SuperCoder7979 <25208576+SuperCoder7979@users.noreply.github.com>
|
||||
Date: Tue, 3 Nov 2020 23:48:05 -0600
|
||||
Subject: [PATCH] Significantly improve performance of the end generation
|
||||
|
||||
This patch implements a noise cache for the end which significantly reduces the computation time of generation. This results in about a 3x improvement.
|
||||
|
||||
Original code by SuperCoder7979 and Gegy in Lithium, licensed under LGPL-3.0 (Source: https://github.com/jellysquid3/lithium-fabric)
|
||||
|
||||
Co-authored-by: Gegy <gegy1000@gmail.com>
|
||||
Co-authored-by: Dylan Xaldin <Puremin0rez515@gmail.com>
|
||||
Co-authored-by: pop4959 <pop4959@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java b/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java
|
||||
index fac92f37c32e0398ebc05d9a0378446fcabaef1a..1beacd84bb0eee1f3e8f451fc1c514e23cc62826 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/DensityFunctions.java
|
||||
@@ -490,6 +490,16 @@ public final class DensityFunctions {
|
||||
public static final KeyDispatchDataCodec<DensityFunctions.EndIslandDensityFunction> CODEC = KeyDispatchDataCodec.of(MapCodec.unit(new DensityFunctions.EndIslandDensityFunction(0L)));
|
||||
private static final float ISLAND_THRESHOLD = -0.9F;
|
||||
private final SimplexNoise islandNoise;
|
||||
+ // Paper start
|
||||
+ private static final class NoiseCache {
|
||||
+ public long[] keys = new long[8192];
|
||||
+ public float[] values = new float[8192];
|
||||
+ public NoiseCache() {
|
||||
+ java.util.Arrays.fill(keys, Long.MIN_VALUE);
|
||||
+ }
|
||||
+ }
|
||||
+ private static final ThreadLocal<java.util.Map<SimplexNoise, NoiseCache>> noiseCache = ThreadLocal.withInitial(java.util.WeakHashMap::new);
|
||||
+ // Paper end
|
||||
|
||||
public EndIslandDensityFunction(long seed) {
|
||||
RandomSource randomSource = new LegacyRandomSource(seed);
|
||||
@@ -505,12 +515,26 @@ public final class DensityFunctions {
|
||||
float f = 100.0F - Mth.sqrt((long) x * (long) x + (long) z * (long) z) * 8.0F; // Paper - cast ints to long to avoid integer overflow
|
||||
f = Mth.clamp(f, -100.0F, 80.0F);
|
||||
|
||||
+ NoiseCache cache = noiseCache.get().computeIfAbsent(sampler, noiseKey -> new NoiseCache()); // Paper
|
||||
for(int m = -12; m <= 12; ++m) {
|
||||
for(int n = -12; n <= 12; ++n) {
|
||||
long o = (long)(i + m);
|
||||
long p = (long)(j + n);
|
||||
- if (o * o + p * p > 4096L && sampler.getValue((double)o, (double)p) < (double)-0.9F) {
|
||||
- float g = (Mth.abs((float)o) * 3439.0F + Mth.abs((float)p) * 147.0F) % 13.0F + 9.0F;
|
||||
+ // Paper start - Significantly improve end generation performance by using a noise cache
|
||||
+ long key = net.minecraft.world.level.ChunkPos.asLong((int) o, (int) p);
|
||||
+ int index = (int) it.unimi.dsi.fastutil.HashCommon.mix(key) & 8191;
|
||||
+ float g = Float.MIN_VALUE;
|
||||
+ if (cache.keys[index] == key) {
|
||||
+ g = cache.values[index];
|
||||
+ } else {
|
||||
+ if (o * o + p * p > 4096L && sampler.getValue((double)o, (double)p) < (double)-0.9F) {
|
||||
+ g = (Mth.abs((float) o) * 3439.0F + Mth.abs((float) p) * 147.0F) % 13.0F + 9.0F;
|
||||
+ }
|
||||
+ cache.keys[index] = key;
|
||||
+ cache.values[index] = g;
|
||||
+ }
|
||||
+ if (g != Float.MIN_VALUE) {
|
||||
+ // Paper end
|
||||
float h = (float)(k - m * 2);
|
||||
float q = (float)(l - n * 2);
|
||||
float r = 100.0F - Mth.sqrt(h * h + q * q) * g;
|
37
patches/server/0494-More-lightning-API.patch
Normal file
37
patches/server/0494-More-lightning-API.patch
Normal file
|
@ -0,0 +1,37 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Sun, 26 Jul 2020 14:44:09 +0200
|
||||
Subject: [PATCH] More lightning API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.LightningBolt life
|
||||
public net.minecraft.world.entity.LightningBolt flashes
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
|
||||
index 849c7d1e4eabfaea491b6c9004f764307ad1b9c6..cd9bd7f06e55e970b7791e635610bb5e7491d102 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
|
||||
@@ -66,4 +66,23 @@ public class CraftLightningStrike extends CraftEntity implements LightningStrike
|
||||
return this.spigot;
|
||||
}
|
||||
// Spigot end
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getFlashCount() {
|
||||
+ return getHandle().flashes;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setFlashCount(int flashes) {
|
||||
+ com.google.common.base.Preconditions.checkArgument(flashes >= 0, "Flashes has to be a positive number!");
|
||||
+ getHandle().flashes = flashes;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Entity getCausingEntity() {
|
||||
+ final var cause = this.getHandle().getCause();
|
||||
+ return cause == null ? null : cause.getBukkitEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Sun, 23 Aug 2020 20:59:00 +0200
|
||||
Subject: [PATCH] Climbing should not bypass cramming gamerule
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index f0158217eceeaf73555a741957324ce0258fa6b2..90621d3dfe8660f9b389ed292a3582a5dbb726bd 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2062,6 +2062,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
}
|
||||
|
||||
public boolean isPushable() {
|
||||
+ // Paper start
|
||||
+ return isCollidable(false);
|
||||
+ }
|
||||
+
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) {
|
||||
+ // Paper end
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
index 68e4440765636295a74ea942862d772d47282ad6..93a41156a01a1638f3ef469b1518a07e7961f378 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
@@ -46,11 +46,16 @@ public final class EntitySelector {
|
||||
}
|
||||
|
||||
public static Predicate<Entity> pushableBy(Entity entity) {
|
||||
+ // Paper start - ignoreClimbing param
|
||||
+ return pushable(entity, false);
|
||||
+ }
|
||||
+ public static Predicate<Entity> pushable(Entity entity, boolean ignoreClimbing) {
|
||||
+ // Paper end
|
||||
PlayerTeam scoreboardteam = entity.getTeam();
|
||||
Team.CollisionRule scoreboardteambase_enumteampush = scoreboardteam == null ? Team.CollisionRule.ALWAYS : scoreboardteam.getCollisionRule();
|
||||
|
||||
return (Predicate) (scoreboardteambase_enumteampush == Team.CollisionRule.NEVER ? Predicates.alwaysFalse() : EntitySelector.NO_SPECTATORS.and((entity1) -> {
|
||||
- if (!entity1.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(entity1)) { // CraftBukkit - collidable API
|
||||
+ if (!entity1.isCollidable(ignoreClimbing) || !entity1.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(entity1)) { // CraftBukkit - collidable API // Paper - isCollidable
|
||||
return false;
|
||||
} else if (entity.level().isClientSide && (!(entity1 instanceof Player) || !((Player) entity1).isLocalPlayer())) {
|
||||
return false;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 90c66f87e721ef34bf3f47b601456fece3064225..bf617621c88c68198709d1ed238622c3fcec89bd 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3426,7 +3426,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
return;
|
||||
}
|
||||
// Paper end - don't run getEntities if we're not going to use its result
|
||||
- List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this));
|
||||
+ List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushable(this, this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule)); // Paper - fix climbing bypassing cramming rule
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
// Paper - moved up
|
||||
@@ -3616,9 +3616,16 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
return !this.isRemoved() && this.collides; // CraftBukkit
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
@Override
|
||||
public boolean isPushable() {
|
||||
- return this.isAlive() && !this.isSpectator() && !this.onClimbable() && this.collides; // CraftBukkit
|
||||
+ return this.isCollidable(this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) {
|
||||
+ return this.isAlive() && !this.isSpectator() && (ignoreClimbing || !this.onClimbable()) && this.collides; // CraftBukkit
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// CraftBukkit start - collidable API
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
|
||||
index bc9a710a92662b1f69b0f5b289780fe0a0d5ed32..6b614818b14ecfc8fc82b523eeb7e21fdf9bf1ba 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
|
||||
@@ -90,7 +90,7 @@ public class Bat extends AmbientCreature {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean isPushable() {
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Parrot.java b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
|
||||
index fbad0e512b990c3d6885ecf92766ba6fd851cc20..4c34edc55fa0e136ccf49a3aef001f413274dfac 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
|
||||
@@ -383,8 +383,8 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder<Parrot
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean isPushable() {
|
||||
- return super.isPushable(); // CraftBukkit - collidable API
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
|
||||
+ return super.isCollidable(ignoreClimbing); // CraftBukkit - collidable API // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
||||
index 6b7453281e32aae20778f26b4098df418401c45b..a13a1725356ca4430f1f0a6d121fc08679de62db 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
||||
@@ -286,7 +286,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean isPushable() {
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
|
||||
return !this.isVehicle();
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 17b6649a7e36fc9322f857e83551d8a99f4f288d..483d8c627a60e04f66f0135a8d64e6d5366e0997 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -343,7 +343,7 @@ public class ArmorStand extends LivingEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean isPushable() {
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
|
||||
index b09c4e2a36f653ff6aa0e2c0bc927a8fd7e41ae0..bf9963eb59269223a9e322773f3543640645ae9f 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
|
||||
@@ -172,7 +172,7 @@ public abstract class AbstractMinecart extends VehicleEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean isPushable() {
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
|
||||
return true;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
|
||||
index e6a7bf9a27fb66d8c2210678dbe8afa8bbf5e7c8..6b0ec9da5a368775924f5b97c74acc5bfd609fa1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
|
||||
@@ -157,7 +157,7 @@ public class Boat extends VehicleEntity implements VariantHolder<Boat.Type> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean isPushable() {
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Mon, 16 Nov 2020 12:01:52 -0800
|
||||
Subject: [PATCH] Added missing default perms for commands
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java
|
||||
index a9ea2e38e4673686c9994a58c94ad19e59fd423c..ea732f8fe7b5dd56aab5d3a061a1cad19c49ae0b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java
|
||||
@@ -24,13 +24,73 @@ public final class CommandPermissions {
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "stop", "Allows the user to stop the server", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "list", "Allows the user to list all online players", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "gamemode", "Allows the user to change the gamemode of another player", PermissionDefault.OP, commands);
|
||||
- DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "xp", "Allows the user to give themselves or others arbitrary values of experience", PermissionDefault.OP, commands);
|
||||
- DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "toggledownfall", "Allows the user to toggle rain on/off for a given world", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "experience", "Allows the user to give themselves or others arbitrary values of experience", PermissionDefault.OP, commands); // Paper - wrong permission; redirects are de-redirected and the root literal name is used, so xp -> experience
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "defaultgamemode", "Allows the user to change the default gamemode of the server", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "seed", "Allows the user to view the seed of the world", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "effect", "Allows the user to add/remove effects on players", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "selector", "Allows the use of selectors", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "trigger", "Allows the use of the trigger command", PermissionDefault.TRUE, commands);
|
||||
+ // Paper start
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "attribute", "Allows the user to query, add, remove or set an entity attribute", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "advancement", "Allows the user to give, remove, or check player advancements", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ban", "Allows the user to add players to the ban list", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ban-ip", "Allows the user to add ip address to the ban list", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "banlist", "Allows the user to display the ban list", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "bossbar", "Allows the user to create and modify bossbars", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "clear", "Allows the user to clear items from player inventory", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "clone", "Allows the user to copy blocks from one place to another", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "damage", "Allows the user to use the damage command to damage entities", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "data", "Allows the user to get, merge, modify, and remove block entity and entity NBT data", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "datapack", "Allows the user to control loaded data packs", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "debug", "Allows the user to start or stop a debugging session", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "deop", "Allows the user to revoke operator status from a player", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "difficulty", "Allows the user to set the difficulty level", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "enchant", "Allows the user to enchant a player item", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "execute", "Allows the user to execute another command", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "fill", "Allows the user to fill a region with a specific block", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "fillbiome", "Allows the user to fill a region with a specific biome", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "forceload", "Allows the user to force chunks to be constantly loaded or not", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "function", "Allows the user to run a function", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "gamerule", "Allows a user to set or query a game rule value", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "jfr", "Allows a user to use the vanilla Java FlightRecorder profiling system", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "locate", "Allows the user to locate the closest structure", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "loot", "Allows the user to drop items from an inventory slot onto the ground", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "op", "Allows the user to grant operator status to a player", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "pardon", "Allows the user to remove entries from the player ban list", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "pardon-ip", "Allows the user to remove entries from the ip address ban list", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "particle", "Allows the user to create particles", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "perf", "Allows the user to start/stop the vanilla performance metrics capture", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "playsound", "Allows the user to play a sound", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ride", "Allows the user to use the /ride command to control passengers", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "recipe", "Allows the user to give or take recipes", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "reload", "Allows the user to reload loot tables, advancements, and functions from disk", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "item", "Allows the user to replace items in inventories", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "save-all", "Allows the user to save the server to disk", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "save-off", "Allows the user disable automatic server saves", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "save-on", "Allows the user enable automatic server saves", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "schedule", "Allows the user to delay the execution of a function", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "scoreboard", "Allows the user manage scoreboard objectives and players", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "setblock", "Allows the user to change a block to another block", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "setidletimeout", "Allows the user to set the time before idle players are kicked", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "setworldspawn", "Allows the user to set the world spawn", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "spawnpoint", "Allows the user to set the spawn point for a player", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "spectate", "Allows the user to make one player in spectator mode spectate an entity", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "spreadplayers", "Allows the user to teleport entities to random locations", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "stopsound", "Allows the user to stop a sound", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "summon", "Allows the user to summon an entity", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "tag", "Allows the user to control entity tags", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "team", "Allows the user to control teams", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "teammsg", "Allows the user to specify the message to send to team", PermissionDefault.TRUE, commands); // defaults to all players
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "tellraw", "Allows the user to display a JSON message to players", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "time", "Allows the user to change or query the world's game time", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "title", "Allows the user to manage screen titles", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "weather", "Allows the user to set the weather", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "whitelist", "Allows the user to manage the server whitelist", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "worldborder", "Allows the user to manage the world border", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "place", "Allows the user to place features and structures", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "return", "Allows the user to use the /return command", PermissionDefault.OP, commands);
|
||||
+ DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "random", "Allows the user to generate a random number", PermissionDefault.OP, commands);
|
||||
+ // Paper end
|
||||
|
||||
DefaultPermissions.registerPermission("minecraft.admin.command_feedback", "Receive command broadcasts when sendCommandFeedback is true", PermissionDefault.OP, commands);
|
||||
|
||||
diff --git a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..afeb4271fffb7546209f1e651214065187c88302
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
|
||||
@@ -0,0 +1,82 @@
|
||||
+package io.papermc.paper.permissions;
|
||||
+
|
||||
+import com.mojang.brigadier.tree.CommandNode;
|
||||
+import com.mojang.brigadier.tree.RootCommandNode;
|
||||
+import net.minecraft.commands.CommandBuildContext;
|
||||
+import net.minecraft.commands.CommandSourceStack;
|
||||
+import net.minecraft.commands.Commands;
|
||||
+import net.minecraft.server.Bootstrap;
|
||||
+import net.minecraft.world.flag.FeatureFlags;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.craftbukkit.command.VanillaCommandWrapper;
|
||||
+import org.bukkit.craftbukkit.util.permissions.CraftDefaultPermissions;
|
||||
+import org.bukkit.permissions.Permission;
|
||||
+import org.bukkit.support.AbstractTestingBase;
|
||||
+import org.junit.jupiter.api.AfterAll;
|
||||
+import org.junit.jupiter.api.BeforeAll;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import java.io.PrintStream;
|
||||
+import java.util.HashSet;
|
||||
+import java.util.LinkedHashSet;
|
||||
+import java.util.List;
|
||||
+import java.util.Set;
|
||||
+import java.util.TreeSet;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
+
|
||||
+public class MinecraftCommandPermissionsTest extends AbstractTestingBase {
|
||||
+
|
||||
+ private static PrintStream old;
|
||||
+ @BeforeAll
|
||||
+ public static void before() {
|
||||
+ old = System.out;
|
||||
+ System.setOut(Bootstrap.STDOUT);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void test() {
|
||||
+ CraftDefaultPermissions.registerCorePermissions();
|
||||
+ Set<String> perms = collectMinecraftCommandPerms();
|
||||
+
|
||||
+ Commands commands = new Commands(Commands.CommandSelection.DEDICATED, CommandBuildContext.configurable(AbstractTestingBase.REGISTRY_CUSTOM, FeatureFlags.VANILLA_SET));
|
||||
+ RootCommandNode<CommandSourceStack> root = commands.getDispatcher().getRoot();
|
||||
+ Set<String> missing = new LinkedHashSet<>();
|
||||
+ Set<String> foundPerms = new HashSet<>();
|
||||
+ for (CommandNode<CommandSourceStack> child : root.getChildren()) {
|
||||
+ final String vanillaPerm = VanillaCommandWrapper.getPermission(child);
|
||||
+ if (!perms.contains(vanillaPerm)) {
|
||||
+ missing.add("Missing permission for " + child.getName() + " (" + vanillaPerm + ") command");
|
||||
+ } else {
|
||||
+ foundPerms.add(vanillaPerm);
|
||||
+ }
|
||||
+ }
|
||||
+ assertTrue(missing.isEmpty(), "Commands missing permissions: \n" + String.join("\n", missing));
|
||||
+ perms.removeAll(foundPerms);
|
||||
+ assertTrue(perms.isEmpty(), "Extra permissions not associated with a command: \n" + String.join("\n", perms));
|
||||
+ }
|
||||
+
|
||||
+ private static final List<String> TO_SKIP = List.of(
|
||||
+ "minecraft.command.selector"
|
||||
+ );
|
||||
+
|
||||
+ private static Set<String> collectMinecraftCommandPerms() {
|
||||
+ Set<String> perms = new TreeSet<>();
|
||||
+ for (Permission perm : Bukkit.getPluginManager().getPermissions()) {
|
||||
+ if (perm.getName().startsWith("minecraft.command.")) {
|
||||
+ if (TO_SKIP.contains(perm.getName())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ perms.add(perm.getName());
|
||||
+ }
|
||||
+ }
|
||||
+ return perms;
|
||||
+ }
|
||||
+
|
||||
+ @AfterAll
|
||||
+ public static void after() {
|
||||
+ if (old != null) {
|
||||
+ System.setOut(old);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
70
patches/server/0497-Add-PlayerShearBlockEvent.patch
Normal file
70
patches/server/0497-Add-PlayerShearBlockEvent.patch
Normal file
|
@ -0,0 +1,70 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: JRoy <joshroy126@gmail.com>
|
||||
Date: Thu, 27 Aug 2020 15:02:48 -0400
|
||||
Subject: [PATCH] Add PlayerShearBlockEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
|
||||
index 44e72176a0da08a77fa192ee31c0fcd53f0dc22d..f82cd3677da96d3cf051c983d08a8ff302400b18 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
|
||||
@@ -127,7 +127,7 @@ public class BeehiveBlock extends BaseEntityBlock {
|
||||
}
|
||||
|
||||
public static void dropHoneycomb(Level world, BlockPos pos) {
|
||||
- popResource(world, pos, new ItemStack(Items.HONEYCOMB, 3));
|
||||
+ popResource(world, pos, new ItemStack(Items.HONEYCOMB, 3)); // Paper - conflict on change, item needs to be set below
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,8 +140,19 @@ public class BeehiveBlock extends BaseEntityBlock {
|
||||
Item item = itemstack.getItem();
|
||||
|
||||
if (itemstack.is(Items.SHEARS)) {
|
||||
+ // Paper start - Add PlayerShearBlockEvent
|
||||
+ io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (hand == InteractionHand.OFF_HAND ? org.bukkit.inventory.EquipmentSlot.OFF_HAND : org.bukkit.inventory.EquipmentSlot.HAND), new java.util.ArrayList<>());
|
||||
+ event.getDrops().add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(Items.HONEYCOMB, 3)));
|
||||
+ if (!event.callEvent()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ // Paper end
|
||||
world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BEEHIVE_SHEAR, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
- BeehiveBlock.dropHoneycomb(world, pos);
|
||||
+ // Paper start - Add PlayerShearBlockEvent
|
||||
+ for (org.bukkit.inventory.ItemStack itemDrop : event.getDrops()) {
|
||||
+ popResource(world, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(itemDrop));
|
||||
+ }
|
||||
+ // Paper end
|
||||
itemstack.hurtAndBreak(1, player, (entityhuman1) -> {
|
||||
entityhuman1.broadcastBreakEvent(hand);
|
||||
});
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java b/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java
|
||||
index df11efd22682c2ed799dabf15d2cfa5973e8dca9..58bc92f70892a1ff1af3bd2c1b6d8eb57e92aced 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java
|
||||
@@ -35,13 +35,24 @@ public class PumpkinBlock extends Block {
|
||||
ItemStack itemStack = player.getItemInHand(hand);
|
||||
if (itemStack.is(Items.SHEARS)) {
|
||||
if (!world.isClientSide) {
|
||||
+ // Paper start - Add PlayerShearBlockEvent
|
||||
+ io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (hand == InteractionHand.OFF_HAND ? org.bukkit.inventory.EquipmentSlot.OFF_HAND : org.bukkit.inventory.EquipmentSlot.HAND), new java.util.ArrayList<>());
|
||||
+ event.getDrops().add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(Items.PUMPKIN_SEEDS, 4)));
|
||||
+ if (!event.callEvent()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ // Paper end
|
||||
Direction direction = hit.getDirection();
|
||||
Direction direction2 = direction.getAxis() == Direction.Axis.Y ? player.getDirection().getOpposite() : direction;
|
||||
world.playSound((Player)null, pos, SoundEvents.PUMPKIN_CARVE, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
world.setBlock(pos, Blocks.CARVED_PUMPKIN.defaultBlockState().setValue(CarvedPumpkinBlock.FACING, direction2), 11);
|
||||
- ItemEntity itemEntity = new ItemEntity(world, (double)pos.getX() + 0.5D + (double)direction2.getStepX() * 0.65D, (double)pos.getY() + 0.1D, (double)pos.getZ() + 0.5D + (double)direction2.getStepZ() * 0.65D, new ItemStack(Items.PUMPKIN_SEEDS, 4));
|
||||
+ // Paper start - Add PlayerShearBlockEvent
|
||||
+ for (org.bukkit.inventory.ItemStack item : event.getDrops()) {
|
||||
+ ItemEntity itemEntity = new ItemEntity(world, (double) pos.getX() + 0.5D + (double) direction2.getStepX() * 0.65D, (double) pos.getY() + 0.1D, (double) pos.getZ() + 0.5D + (double) direction2.getStepZ() * 0.65D, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item));
|
||||
+ // Paper end
|
||||
itemEntity.setDeltaMovement(0.05D * (double)direction2.getStepX() + world.random.nextDouble() * 0.02D, 0.05D, 0.05D * (double)direction2.getStepZ() + world.random.nextDouble() * 0.02D);
|
||||
world.addFreshEntity(itemEntity);
|
||||
+ } // Paper - Add PlayerShearBlockEvent
|
||||
itemStack.hurtAndBreak(1, player, (playerx) -> {
|
||||
playerx.broadcastBreakEvent(hand);
|
||||
});
|
41
patches/server/0498-Limit-recipe-packets.patch
Normal file
41
patches/server/0498-Limit-recipe-packets.patch
Normal file
|
@ -0,0 +1,41 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sat, 12 Dec 2020 23:45:28 +0000
|
||||
Subject: [PATCH] Limit recipe packets
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index bace3a1d8e2e4b2b36f1b4cb80bb5c3bb473ad47..08ff8e489d86030dac403b405b016b77d7f81598 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -258,6 +258,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
// CraftBukkit start - multithreaded fields
|
||||
private final AtomicInteger chatSpamTickCount = new AtomicInteger();
|
||||
private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits
|
||||
+ private final java.util.concurrent.atomic.AtomicInteger recipeSpamPackets = new java.util.concurrent.atomic.AtomicInteger(); // Paper - auto recipe limit
|
||||
// CraftBukkit end
|
||||
private int dropSpamTickCount;
|
||||
private double firstGoodX;
|
||||
@@ -378,6 +379,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
// CraftBukkit start
|
||||
for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ;
|
||||
if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable
|
||||
+ if (recipeSpamPackets.get() > 0) recipeSpamPackets.getAndDecrement(); // Paper
|
||||
/* Use thread-safe field access instead
|
||||
if (this.chatSpamTickCount > 0) {
|
||||
--this.chatSpamTickCount;
|
||||
@@ -2983,6 +2985,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
|
||||
@Override
|
||||
public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) {
|
||||
+ // Paper start
|
||||
+ if (!org.bukkit.Bukkit.isPrimaryThread()) {
|
||||
+ if (this.recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) {
|
||||
+ this.server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", new Object[0]))); // Paper
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
this.player.resetLastActionTime();
|
||||
if (!this.player.isSpectator() && this.player.containerMenu.containerId == packet.getContainerId() && this.player.containerMenu instanceof RecipeBookMenu) {
|
|
@ -0,0 +1,21 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 17 Dec 2020 15:25:49 -0600
|
||||
Subject: [PATCH] Fix CraftSound backwards compatibility
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftSound.java b/src/main/java/org/bukkit/craftbukkit/CraftSound.java
|
||||
index 260a738d5d61cf931b939502ea9c66451855b91e..dce716b6ac407d1e1ae07272ee5c8b14f891f5fa 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftSound.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftSound.java
|
||||
@@ -40,4 +40,10 @@ public class CraftSound {
|
||||
throw new IllegalArgumentException("No Reference holder found for " + bukkit
|
||||
+ ", this can happen if a plugin creates its own sound effect with out properly registering it.");
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public static String getSound(Sound sound) {
|
||||
+ return sound.getKey().getKey();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
34
patches/server/0500-Player-Chunk-Load-Unload-Events.patch
Normal file
34
patches/server/0500-Player-Chunk-Load-Unload-Events.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: ysl3000 <yannicklamprecht@live.de>
|
||||
Date: Mon, 5 Oct 2020 21:25:16 +0200
|
||||
Subject: [PATCH] Player Chunk Load/Unload Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
index 19b3f4fa7678a038bf25efc2a8b46ddad0193fde..cfeb85b89a7f3dbc856fe7ebdf0bd6a9f3761f1c 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
@@ -46,6 +46,11 @@ public class PlayerChunkSender {
|
||||
public static void dropChunkStatic(ServerPlayer player, ChunkPos pos) {
|
||||
player.serverLevel().chunkSource.chunkMap.getVisibleChunkIfPresent(pos.toLong()).removePlayer(player);
|
||||
player.connection.send(new ClientboundForgetLevelChunkPacket(pos));
|
||||
+ // Paper start
|
||||
+ if (io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ new io.papermc.paper.event.packet.PlayerChunkUnloadEvent(player.getBukkitEntity().getWorld().getChunkAt(pos.longKey), player.getBukkitEntity()).callEvent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
// Paper end - rewrite player chunk loader
|
||||
|
||||
@@ -89,6 +94,11 @@ public class PlayerChunkSender {
|
||||
final boolean shouldModify = world.chunkPacketBlockController.shouldModify(handler.player, chunk);
|
||||
handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), (BitSet)null, (BitSet)null, shouldModify));
|
||||
// Paper end - Anti-Xray
|
||||
+ // Paper start - PlayerChunkLoadEvent
|
||||
+ if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent();
|
||||
+ }
|
||||
+ // Paper end - PlayerChunkLoadEvent
|
||||
ChunkPos chunkPos = chunk.getPos();
|
||||
DebugPackets.sendPoiPacketsForChunk(world, chunkPos);
|
||||
}
|
34
patches/server/0501-Optimize-Dynamic-get-Missing-Keys.patch
Normal file
34
patches/server/0501-Optimize-Dynamic-get-Missing-Keys.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 21 Dec 2020 11:01:42 -0500
|
||||
Subject: [PATCH] Optimize Dynamic#get Missing Keys
|
||||
|
||||
get was calling toString() on every NBT object that was ever asked for an optional
|
||||
key from the object to build a string for the error text.
|
||||
|
||||
When done on large NBT objects, this was using a ton of computation time building the
|
||||
JSON representation of the NBT object.
|
||||
|
||||
Now we will just skip the value when 99.9999% of the time the text is never even printed.
|
||||
|
||||
diff --git a/src/main/java/com/mojang/serialization/Dynamic.java b/src/main/java/com/mojang/serialization/Dynamic.java
|
||||
index a24cc02a62585d7c04d36456739b11bddccf1a15..683f516b86f246792dcb3d6f9a738fc14155d2f6 100644
|
||||
--- a/src/main/java/com/mojang/serialization/Dynamic.java
|
||||
+++ b/src/main/java/com/mojang/serialization/Dynamic.java
|
||||
@@ -17,6 +17,7 @@ import java.util.stream.Stream;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class Dynamic<T> extends DynamicLike<T> {
|
||||
+ private static final boolean DEBUG_MISSING_KEYS = Boolean.getBoolean("Paper.debugDynamicMissingKeys"); // Paper
|
||||
private final T value;
|
||||
|
||||
public Dynamic(final DynamicOps<T> ops) {
|
||||
@@ -113,7 +114,7 @@ public class Dynamic<T> extends DynamicLike<T> {
|
||||
return new OptionalDynamic<>(ops, ops.getMap(value).flatMap(m -> {
|
||||
final T value = m.get(key);
|
||||
if (value == null) {
|
||||
- return DataResult.error(() -> "key missing: " + key + " in " + this.value);
|
||||
+ return DataResult.error(() -> DEBUG_MISSING_KEYS ? "key missing: " + key + " in " + this.value : "key missing: " + key); // Paper
|
||||
}
|
||||
return DataResult.success(new Dynamic<>(ops, value));
|
||||
}));
|
57
patches/server/0502-Expose-LivingEntity-hurt-direction.patch
Normal file
57
patches/server/0502-Expose-LivingEntity-hurt-direction.patch
Normal file
|
@ -0,0 +1,57 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Sun, 13 Dec 2020 05:32:05 +0200
|
||||
Subject: [PATCH] Expose LivingEntity hurt direction
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 4bac05cb48d81dc9776d90502b6f12285b92122b..2957b3929c1e92af1b1a2636b83b757a0fbc789d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -178,7 +178,7 @@ public abstract class Player extends LivingEntity {
|
||||
private Optional<GlobalPos> lastDeathLocation;
|
||||
@Nullable
|
||||
public FishingHook fishing;
|
||||
- protected float hurtDir;
|
||||
+ public float hurtDir; // Paper - protected -> public
|
||||
// Paper start
|
||||
public boolean affectsSpawning = true;
|
||||
// Paper end
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 2609da834c014e82d0038de580d50163dd0c5687..6a5f5c00f9276337ddee8c8d1458a429bc5443d9 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -127,6 +127,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setHurtDirection(float hurtDirection) {
|
||||
+ this.getHandle().hurtDir = hurtDirection;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public int getSleepTicks() {
|
||||
return this.getHandle().sleepCounter;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 66c762c13a70f917e06795dcee85cae66cd316d4..4fc1ea695611e636349ea9d4d4ae48bab93d3b98 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -937,5 +937,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
public void playPickupItemAnimation(org.bukkit.entity.Item item, int quantity) {
|
||||
getHandle().take(((CraftItem) item).getHandle(), quantity);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public float getHurtDirection() {
|
||||
+ return this.getHandle().getHurtDir();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHurtDirection(float hurtDirection) {
|
||||
+ throw new UnsupportedOperationException("Cannot set the hurt direction on a non player");
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 24 Dec 2020 12:43:39 -0800
|
||||
Subject: [PATCH] Add OBSTRUCTED reason to BedEnterResult
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index bb7ec8b5a76155ec5a6bfa29eda4e395cf3f23d2..c4dd2ab7afe61d354418dc5475c3b444609ccd80 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -304,6 +304,10 @@ public class CraftEventFactory {
|
||||
return BedEnterResult.TOO_FAR_AWAY;
|
||||
case NOT_SAFE:
|
||||
return BedEnterResult.NOT_SAFE;
|
||||
+ // Paper start
|
||||
+ case OBSTRUCTED:
|
||||
+ return BedEnterResult.OBSTRUCTED;
|
||||
+ // Paper end
|
||||
default:
|
||||
return BedEnterResult.OTHER_PROBLEM;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 27 Dec 2020 11:31:06 +0000
|
||||
Subject: [PATCH] Do not crash from invalid ingredient lists in
|
||||
VillagerAcquireTradeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
index 66b7a2c9a7dc18a98bf2c3aac863a10cbc3ae9f9..73bc45000b5285ccf5b06e2f372d6c82bf843b82 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
@@ -261,7 +261,11 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
}
|
||||
if (!event.isCancelled()) {
|
||||
- recipeList.add(CraftMerchantRecipe.fromBukkit(event.getRecipe()).toMinecraft());
|
||||
+ // Paper start
|
||||
+ final CraftMerchantRecipe craftMerchantRecipe = CraftMerchantRecipe.fromBukkit(event.getRecipe());
|
||||
+ if (craftMerchantRecipe.getIngredients().isEmpty()) return;
|
||||
+ recipeList.add(craftMerchantRecipe.toMinecraft());
|
||||
+ // Paper end
|
||||
}
|
||||
// CraftBukkit end
|
||||
++j;
|
|
@ -0,0 +1,251 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 2 Jul 2020 16:12:10 -0700
|
||||
Subject: [PATCH] Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
|
||||
Co-authored-by: Alexander <protonull@protonmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
index 73bc45000b5285ccf5b06e2f372d6c82bf843b82..5a591c439c5cef6b7e7e6f836ab813cb4f29b08c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
@@ -137,11 +137,24 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa
|
||||
@Override
|
||||
public void overrideXp(int experience) {}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void processTrade(MerchantOffer recipe, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent
|
||||
+ if (event == null || event.willIncreaseTradeUses()) {
|
||||
+ recipe.increaseUses();
|
||||
+ }
|
||||
+ if (event == null || event.isRewardingExp()) {
|
||||
+ this.rewardTradeXp(recipe);
|
||||
+ }
|
||||
+ this.notifyTrade(recipe);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void notifyTrade(MerchantOffer offer) {
|
||||
- offer.increaseUses();
|
||||
+ // offer.increaseUses(); // Paper - handled in processTrade
|
||||
this.ambientSoundTime = -this.getAmbientSoundInterval();
|
||||
- this.rewardTradeXp(offer);
|
||||
+ // this.rewardTradeXp(offer); // Paper - handled in processTrade
|
||||
if (this.tradingPlayer instanceof ServerPlayer) {
|
||||
CriteriaTriggers.TRADE.trigger((ServerPlayer) this.tradingPlayer, this, offer.getResult());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 52e57fa3b25dce10c17682964cbd4bcb4c130dc6..c6ac55cdece9e2901e5d17a23408171c6c49ff69 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -760,6 +760,14 @@ public abstract class AbstractContainerMenu {
|
||||
public abstract boolean stillValid(Player player);
|
||||
|
||||
protected boolean moveItemStackTo(ItemStack stack, int startIndex, int endIndex, boolean fromLast) {
|
||||
+ // Paper start
|
||||
+ return this.moveItemStackTo(stack, startIndex, endIndex, fromLast, false);
|
||||
+ }
|
||||
+ protected boolean moveItemStackTo(ItemStack stack, int startIndex, int endIndex, boolean fromLast, boolean isCheck) {
|
||||
+ if (isCheck) {
|
||||
+ stack = stack.copy();
|
||||
+ }
|
||||
+ // Paper end
|
||||
boolean flag1 = false;
|
||||
int k = startIndex;
|
||||
|
||||
@@ -782,18 +790,27 @@ public abstract class AbstractContainerMenu {
|
||||
|
||||
slot = (Slot) this.slots.get(k);
|
||||
itemstack1 = slot.getItem();
|
||||
+ // Paper start - clone if only a check
|
||||
+ if (isCheck) {
|
||||
+ itemstack1 = itemstack1.copy();
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (!itemstack1.isEmpty() && ItemStack.isSameItemSameTags(stack, itemstack1)) {
|
||||
int l = itemstack1.getCount() + stack.getCount();
|
||||
|
||||
if (l <= stack.getMaxStackSize()) {
|
||||
stack.setCount(0);
|
||||
itemstack1.setCount(l);
|
||||
+ if (!isCheck) { // Paper - dont update if only a check
|
||||
slot.setChanged();
|
||||
+ } // Paper
|
||||
flag1 = true;
|
||||
} else if (itemstack1.getCount() < stack.getMaxStackSize()) {
|
||||
stack.shrink(stack.getMaxStackSize() - itemstack1.getCount());
|
||||
itemstack1.setCount(stack.getMaxStackSize());
|
||||
+ if (!isCheck) { // Paper - dont update if only a check
|
||||
slot.setChanged();
|
||||
+ } // Paper
|
||||
flag1 = true;
|
||||
}
|
||||
}
|
||||
@@ -824,14 +841,33 @@ public abstract class AbstractContainerMenu {
|
||||
|
||||
slot = (Slot) this.slots.get(k);
|
||||
itemstack1 = slot.getItem();
|
||||
+ // Paper start - clone if only a check
|
||||
+ if (isCheck) {
|
||||
+ itemstack1 = itemstack1.copy();
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (itemstack1.isEmpty() && slot.mayPlace(stack)) {
|
||||
if (stack.getCount() > slot.getMaxStackSize()) {
|
||||
+ // Paper start - dont set slot if only check
|
||||
+ if (isCheck) {
|
||||
+ stack.shrink(slot.getMaxStackSize());
|
||||
+ } else {
|
||||
+ // Paper end
|
||||
slot.setByPlayer(stack.split(slot.getMaxStackSize()));
|
||||
+ } // Paper
|
||||
} else {
|
||||
+ // Paper start - dont set slot if only check
|
||||
+ if (isCheck) {
|
||||
+ stack.shrink(stack.getCount());
|
||||
+ } else {
|
||||
+ // Paper end
|
||||
slot.setByPlayer(stack.split(stack.getCount()));
|
||||
+ } // Paper
|
||||
}
|
||||
|
||||
+ if (!isCheck) { // Paper - dont update if only check
|
||||
slot.setChanged();
|
||||
+ } // Paper
|
||||
flag1 = true;
|
||||
break;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java b/src/main/java/net/minecraft/world/inventory/MerchantMenu.java
|
||||
index 743a2adc465be5477d204185967265389d7102de..8eab7596e1f7d1beb9ab0d70d1310d26822262e9 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/MerchantMenu.java
|
||||
@@ -134,12 +134,12 @@ public class MerchantMenu extends AbstractContainerMenu {
|
||||
|
||||
itemstack = itemstack1.copy();
|
||||
if (slot == 2) {
|
||||
- if (!this.moveItemStackTo(itemstack1, 3, 39, true)) {
|
||||
+ if (!this.moveItemStackTo(itemstack1, 3, 39, true, true)) { // Paper
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
- slot1.onQuickCraft(itemstack1, itemstack);
|
||||
- this.playTradeSound();
|
||||
+ // slot1.onQuickCraft(itemstack1, itemstack); // Paper - moved to after the non-check moveItemStackTo call
|
||||
+ // this.playTradeSound();
|
||||
} else if (slot != 0 && slot != 1) {
|
||||
if (slot >= 3 && slot < 30) {
|
||||
if (!this.moveItemStackTo(itemstack1, 30, 39, false)) {
|
||||
@@ -152,6 +152,7 @@ public class MerchantMenu extends AbstractContainerMenu {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
+ if (slot != 2) { // Paper - moved down for slot 2
|
||||
if (itemstack1.isEmpty()) {
|
||||
slot1.setByPlayer(ItemStack.EMPTY);
|
||||
} else {
|
||||
@@ -163,6 +164,21 @@ public class MerchantMenu extends AbstractContainerMenu {
|
||||
}
|
||||
|
||||
slot1.onTake(player, itemstack1);
|
||||
+ } // Paper start - handle slot 2
|
||||
+ if (slot == 2) { // is merchant result slot
|
||||
+ slot1.onTake(player, itemstack1);
|
||||
+ if (itemstack1.isEmpty()) {
|
||||
+ slot1.set(ItemStack.EMPTY);
|
||||
+ return ItemStack.EMPTY;
|
||||
+ }
|
||||
+
|
||||
+ this.moveItemStackTo(itemstack1, 3, 39, true, false); // This should always succeed because it's checked above
|
||||
+
|
||||
+ slot1.onQuickCraft(itemstack1, itemstack);
|
||||
+ this.playTradeSound();
|
||||
+ slot1.set(ItemStack.EMPTY); // itemstack1 should ALWAYS be empty
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java b/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java
|
||||
index e49bbb803399ef696665c5844a18b55a551654f6..1f2b9a9a3fa167e2ba021c823dd142b0bb18a695 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java
|
||||
@@ -47,13 +47,32 @@ public class MerchantResultSlot extends Slot {
|
||||
|
||||
@Override
|
||||
public void onTake(Player player, ItemStack stack) {
|
||||
- this.checkTakeAchievements(stack);
|
||||
+ // this.checkTakeAchievements(stack); // Paper - move to after event is called and not cancelled
|
||||
MerchantOffer merchantOffer = this.slots.getActiveOffer();
|
||||
+ // Paper start
|
||||
+ io.papermc.paper.event.player.PlayerPurchaseEvent event = null;
|
||||
+ if (merchantOffer != null && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
|
||||
+ if (this.merchant instanceof net.minecraft.world.entity.npc.AbstractVillager abstractVillager) {
|
||||
+ event = new io.papermc.paper.event.player.PlayerTradeEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.AbstractVillager) abstractVillager.getBukkitEntity(), merchantOffer.asBukkit(), true, true);
|
||||
+ } else if (this.merchant instanceof org.bukkit.craftbukkit.inventory.CraftMerchantCustom.MinecraftMerchant) {
|
||||
+ event = new io.papermc.paper.event.player.PlayerPurchaseEvent(serverPlayer.getBukkitEntity(), merchantOffer.asBukkit(), false, true);
|
||||
+ }
|
||||
+ if (event != null) {
|
||||
+ if (!event.callEvent()) {
|
||||
+ stack.setCount(0);
|
||||
+ event.getPlayer().updateInventory();
|
||||
+ return;
|
||||
+ }
|
||||
+ merchantOffer = org.bukkit.craftbukkit.inventory.CraftMerchantRecipe.fromBukkit(event.getTrade()).toMinecraft();
|
||||
+ }
|
||||
+ }
|
||||
+ this.checkTakeAchievements(stack);
|
||||
+ // Paper end
|
||||
if (merchantOffer != null) {
|
||||
ItemStack itemStack = this.slots.getItem(0);
|
||||
ItemStack itemStack2 = this.slots.getItem(1);
|
||||
if (merchantOffer.take(itemStack, itemStack2) || merchantOffer.take(itemStack2, itemStack)) {
|
||||
- this.merchant.notifyTrade(merchantOffer);
|
||||
+ this.merchant.processTrade(merchantOffer, event); // Paper
|
||||
player.awardStat(Stats.TRADED_WITH_VILLAGER);
|
||||
this.slots.setItem(0, itemStack);
|
||||
this.slots.setItem(1, itemStack2);
|
||||
diff --git a/src/main/java/net/minecraft/world/item/trading/Merchant.java b/src/main/java/net/minecraft/world/item/trading/Merchant.java
|
||||
index 5a350948a4735902f5c612592bc9d100445a0c8a..716b30dcd7e63c66736c448dd136c9f74dc7fe43 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/trading/Merchant.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/trading/Merchant.java
|
||||
@@ -20,6 +20,7 @@ public interface Merchant {
|
||||
|
||||
void overrideOffers(MerchantOffers offers);
|
||||
|
||||
+ default void processTrade(MerchantOffer merchantRecipe, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { this.notifyTrade(merchantRecipe); } // Paper
|
||||
void notifyTrade(MerchantOffer offer);
|
||||
|
||||
void notifyTradeUpdated(ItemStack stack);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java
|
||||
index adf22ce4f0bcd3bd57dc2030c6c92d3df96566e3..05af1f1cfb38e4ae4ea0ecc2d0a943cbc4063c77 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java
|
||||
@@ -74,10 +74,25 @@ public class CraftMerchantCustom extends CraftMerchant {
|
||||
return this.trades;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void processTrade(MerchantOffer merchantRecipe, @javax.annotation.Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent
|
||||
+ /** Based on {@link net.minecraft.world.entity.npc.AbstractVillager#processTrade(MerchantOffer, io.papermc.paper.event.player.PlayerPurchaseEvent)} */
|
||||
+ if (getTradingPlayer() instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ if (event == null || event.willIncreaseTradeUses()) {
|
||||
+ merchantRecipe.increaseUses();
|
||||
+ }
|
||||
+ if (event == null || event.isRewardingExp()) {
|
||||
+ this.tradingPlayer.level().addFreshEntity(new net.minecraft.world.entity.ExperienceOrb(this.tradingPlayer.level(), this.tradingPlayer.getX(), this.tradingPlayer.getY(), this.tradingPlayer.getZ(), merchantRecipe.getXp(), org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, this.tradingPlayer, null));
|
||||
+ }
|
||||
+ }
|
||||
+ this.notifyTrade(merchantRecipe);
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public void notifyTrade(MerchantOffer offer) {
|
||||
// increase recipe's uses
|
||||
- offer.increaseUses();
|
||||
+ // offer.increaseUses(); // Paper - handled above in processTrade
|
||||
}
|
||||
|
||||
@Override
|
42
patches/server/0506-Implement-TargetHitEvent.patch
Normal file
42
patches/server/0506-Implement-TargetHitEvent.patch
Normal file
|
@ -0,0 +1,42 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Wed, 25 Nov 2020 23:20:44 -0800
|
||||
Subject: [PATCH] Implement TargetHitEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TargetBlock.java b/src/main/java/net/minecraft/world/level/block/TargetBlock.java
|
||||
index 5ea231aadfafdfc6d08aae472827ff1e3d62f4eb..3fdc994a9b27eb099e5483c019d673c1b390434c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TargetBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TargetBlock.java
|
||||
@@ -42,6 +42,10 @@ public class TargetBlock extends Block {
|
||||
@Override
|
||||
public void onProjectileHit(Level world, BlockState state, BlockHitResult hit, Projectile projectile) {
|
||||
int i = updateRedstoneOutput(world, state, hit, projectile);
|
||||
+ // Paper start
|
||||
+ }
|
||||
+ private static void awardTargetHitCriteria(Projectile projectile, BlockHitResult hit, int i) {
|
||||
+ // Paper end
|
||||
Entity entity = projectile.getOwner();
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
serverPlayer.awardStat(Stats.TARGET_HIT);
|
||||
@@ -53,6 +57,20 @@ public class TargetBlock extends Block {
|
||||
private static int updateRedstoneOutput(LevelAccessor world, BlockState state, BlockHitResult hitResult, Entity entity) {
|
||||
int i = getRedstoneStrength(hitResult, hitResult.getLocation());
|
||||
int j = entity instanceof AbstractArrow ? 20 : 8;
|
||||
+ // Paper start
|
||||
+ if (entity instanceof Projectile) {
|
||||
+ final Projectile projectile = (Projectile) entity;
|
||||
+ final org.bukkit.craftbukkit.block.CraftBlock craftBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, hitResult.getBlockPos());
|
||||
+ final org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(hitResult.getDirection());
|
||||
+ final io.papermc.paper.event.block.TargetHitEvent targetHitEvent = new io.papermc.paper.event.block.TargetHitEvent((org.bukkit.entity.Projectile) projectile.getBukkitEntity(), craftBlock, blockFace, i);
|
||||
+ if (targetHitEvent.callEvent()) {
|
||||
+ i = targetHitEvent.getSignalStrength();
|
||||
+ awardTargetHitCriteria(projectile, hitResult, i);
|
||||
+ } else {
|
||||
+ return i;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (!world.getBlockTicks().hasScheduledTick(hitResult.getBlockPos(), state.getBlock())) {
|
||||
setOutputPower(world, state, i, hitResult.getBlockPos(), j);
|
||||
}
|
50
patches/server/0507-MC-4-Fix-item-position-desync.patch
Normal file
50
patches/server/0507-MC-4-Fix-item-position-desync.patch
Normal file
|
@ -0,0 +1,50 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Tue, 8 Dec 2020 20:24:52 -0600
|
||||
Subject: [PATCH] MC-4: Fix item position desync
|
||||
|
||||
This fixes item position desync (MC-4) by running the item coordinates
|
||||
through the encode/decode methods of the packet that causes the precision
|
||||
loss, which forces the server to lose the same precision as the client
|
||||
keeping them in sync.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/VecDeltaCodec.java b/src/main/java/net/minecraft/network/protocol/game/VecDeltaCodec.java
|
||||
index 05ac41e136da43284fb24a6b698ebd36318278fb..33d9131e9c75ef23cd637f5d6c39a2704a0c92a5 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/VecDeltaCodec.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/VecDeltaCodec.java
|
||||
@@ -9,12 +9,12 @@ public class VecDeltaCodec {
|
||||
|
||||
@VisibleForTesting
|
||||
static long encode(double value) {
|
||||
- return Math.round(value * 4096.0D);
|
||||
+ return Math.round(value * 4096.0D); // Paper - diff on change
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static double decode(long value) {
|
||||
- return (double)value / 4096.0D;
|
||||
+ return (double)value / 4096.0D; // Paper - diff on change
|
||||
}
|
||||
|
||||
public Vec3 decode(long x, long y, long z) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 90621d3dfe8660f9b389ed292a3582a5dbb726bd..e68874f8d3d7628d11c1164849a4f835399d2452 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -4269,6 +4269,16 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
return;
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
+ // Paper start - fix MC-4
|
||||
+ if (this instanceof ItemEntity) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.fixEntityPositionDesync) {
|
||||
+ // encode/decode from ClientboundMoveEntityPacket
|
||||
+ x = Mth.lfloor(x * 4096.0D) * (1 / 4096.0D);
|
||||
+ y = Mth.lfloor(y * 4096.0D) * (1 / 4096.0D);
|
||||
+ z = Mth.lfloor(z * 4096.0D) * (1 / 4096.0D);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - fix MC-4
|
||||
if (this.position.x != x || this.position.y != y || this.position.z != z) {
|
||||
this.position = new Vec3(x, y, z);
|
||||
int i = Mth.floor(x);
|
40
patches/server/0508-Additional-Block-Material-API-s.patch
Normal file
40
patches/server/0508-Additional-Block-Material-API-s.patch
Normal file
|
@ -0,0 +1,40 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 30 Dec 2020 19:43:01 -0500
|
||||
Subject: [PATCH] Additional Block Material API's
|
||||
|
||||
Faster version for isSolid() that utilizes NMS's state for isSolid instead of the slower
|
||||
process to do this in the Bukkit API
|
||||
|
||||
Adds API for buildable, replaceable, burnable too.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
index aa644231425b9622437538b5c092d4064a40cced..98e87dc15e2ed23f6897ba6359846ff5bc32b655 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
@@ -440,6 +440,25 @@ public class CraftBlock implements Block {
|
||||
return this.getNMS().liquid();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isBuildable() {
|
||||
+ return this.getNMS().isSolid(); // This is in fact isSolid, despite the fact that isSolid below returns blocksMotion
|
||||
+ }
|
||||
+ @Override
|
||||
+ public boolean isBurnable() {
|
||||
+ return this.getNMS().ignitedByLava();
|
||||
+ }
|
||||
+ @Override
|
||||
+ public boolean isReplaceable() {
|
||||
+ return this.getNMS().canBeReplaced();
|
||||
+ }
|
||||
+ @Override
|
||||
+ public boolean isSolid() {
|
||||
+ return this.getNMS().blocksMotion();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public PistonMoveReaction getPistonMoveReaction() {
|
||||
return PistonMoveReaction.getById(this.getNMS().getPistonPushReaction().ordinal());
|
49
patches/server/0509-Fix-harming-potion-dupe.patch
Normal file
49
patches/server/0509-Fix-harming-potion-dupe.patch
Normal file
|
@ -0,0 +1,49 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com>
|
||||
Date: Thu, 23 Jul 2020 14:25:07 -0700
|
||||
Subject: [PATCH] Fix harming potion dupe
|
||||
|
||||
EntityLiving#applyInstantEffect() immediately kills the player and drops their inventory.
|
||||
Before this patch, instant effects would be applied before the potion ItemStack is removed and replaced with a glass bottle. This caused the potion ItemStack to be dropped before it was supposed to be removed from the inventory. It also caused the glass bottle to be put into a dead player's inventory.
|
||||
This patch makes it so that instant effects are applied after the potion ItemStack is removed, and the glass bottle is only put into the player's inventory if the player is not dead. Otherwise, the glass bottle is dropped on the ground.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/PotionItem.java b/src/main/java/net/minecraft/world/item/PotionItem.java
|
||||
index bb19a00c24e92058e05076b2ca0278dcae1890ae..d7ef159cc44787558ba41964f57a79f048371e97 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/PotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/PotionItem.java
|
||||
@@ -50,6 +50,7 @@ public class PotionItem extends Item {
|
||||
CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer) entityhuman, stack);
|
||||
}
|
||||
|
||||
+ List<MobEffectInstance> instantLater = new java.util.ArrayList<>(); // Paper - Fix harming potion dupe
|
||||
if (!world.isClientSide) {
|
||||
List<MobEffectInstance> list = PotionUtils.getMobEffects(stack);
|
||||
Iterator iterator = list.iterator();
|
||||
@@ -58,7 +59,7 @@ public class PotionItem extends Item {
|
||||
MobEffectInstance mobeffect = (MobEffectInstance) iterator.next();
|
||||
|
||||
if (mobeffect.getEffect().isInstantenous()) {
|
||||
- mobeffect.getEffect().applyInstantenousEffect(entityhuman, entityhuman, user, mobeffect.getAmplifier(), 1.0D);
|
||||
+ instantLater.add(mobeffect); // Paper - Fix harming potion dupe
|
||||
} else {
|
||||
user.addEffect(new MobEffectInstance(mobeffect), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_DRINK); // CraftBukkit
|
||||
}
|
||||
@@ -72,7 +73,18 @@ public class PotionItem extends Item {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Fix harming potion dupe
|
||||
+ for (MobEffectInstance mobeffect : instantLater) {
|
||||
+ mobeffect.getEffect().applyInstantenousEffect(entityhuman, entityhuman, user, mobeffect.getAmplifier(), 1.0D);
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (entityhuman == null || !entityhuman.getAbilities().instabuild) {
|
||||
+ // Paper start - Fix harming potion dupe
|
||||
+ if (user.getHealth() <= 0 && !user.level().getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_KEEPINVENTORY)) {
|
||||
+ user.spawnAtLocation(new ItemStack(Items.GLASS_BOTTLE), 0);
|
||||
+ return ItemStack.EMPTY;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (stack.isEmpty()) {
|
||||
return new ItemStack(Items.GLASS_BOTTLE);
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Madeline Miller <mnmiller1@me.com>
|
||||
Date: Thu, 31 Dec 2020 12:48:19 +1000
|
||||
Subject: [PATCH] Implement API to get Material from Boats and Minecarts
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java
|
||||
index f332bd4e6f663147c9ef6ce03d926feb74b55e93..d161cbf9c83cd78593864850b98f688da2c85aa5 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java
|
||||
@@ -79,6 +79,13 @@ public class CraftBoat extends CraftVehicle implements Boat {
|
||||
this.getHandle().landBoats = workOnLand;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.Material getBoatMaterial() {
|
||||
+ return org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(this.getHandle().getDropItem());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
return CraftBoat.boatStatusFromNms(this.getHandle().status);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java
|
||||
index ee010d53f8c671d17d68f3f43dca9978e23ac8ab..8920af5a0dfe737c1f38d906b53e6a278456d2aa 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java
|
||||
@@ -1,8 +1,10 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
+import net.minecraft.world.item.Items; // Paper
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
+import org.bukkit.Material; // Paper
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
@@ -68,6 +70,22 @@ public abstract class CraftMinecart extends CraftVehicle implements Minecart {
|
||||
this.getHandle().setDerailedVelocityMod(derailed);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public Material getMinecartMaterial() {
|
||||
+ net.minecraft.world.item.Item minecartItem = switch (getHandle().getMinecartType()) {
|
||||
+ case CHEST -> Items.CHEST_MINECART;
|
||||
+ case FURNACE -> Items.FURNACE_MINECART;
|
||||
+ case TNT -> Items.TNT_MINECART;
|
||||
+ case HOPPER -> Items.HOPPER_MINECART;
|
||||
+ case COMMAND_BLOCK -> Items.COMMAND_BLOCK_MINECART;
|
||||
+ case RIDEABLE, SPAWNER -> Items.MINECART;
|
||||
+ };
|
||||
+
|
||||
+ return CraftMagicNumbers.getMaterial(minecartItem);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public AbstractMinecart getHandle() {
|
||||
return (AbstractMinecart) this.entity;
|
36
patches/server/0511-Cache-burn-durations.patch
Normal file
36
patches/server/0511-Cache-burn-durations.patch
Normal file
|
@ -0,0 +1,36 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: lukas <lukasalt98@gmail.com>
|
||||
Date: Sun, 27 Dec 2020 16:47:00 +0100
|
||||
Subject: [PATCH] Cache burn durations
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
index d7a89c2b70de20f632ee210780ede0bc36369710..b6e31bede16f7dbc9abb6609f1c39b82883512b2 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -133,7 +133,13 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
this.recipeType = recipeType; // Paper
|
||||
}
|
||||
|
||||
+ private static Map<Item, Integer> cachedBurnDurations = null; // Paper - cache burn durations
|
||||
public static Map<Item, Integer> getFuel() {
|
||||
+ // Paper start - cache burn durations
|
||||
+ if(cachedBurnDurations != null) {
|
||||
+ return cachedBurnDurations;
|
||||
+ }
|
||||
+ // Paper end
|
||||
Map<Item, Integer> map = Maps.newLinkedHashMap();
|
||||
|
||||
AbstractFurnaceBlockEntity.add(map, (ItemLike) Items.LAVA_BUCKET, 20000);
|
||||
@@ -195,7 +201,10 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
AbstractFurnaceBlockEntity.add(map, (ItemLike) Blocks.AZALEA, 100);
|
||||
AbstractFurnaceBlockEntity.add(map, (ItemLike) Blocks.FLOWERING_AZALEA, 100);
|
||||
AbstractFurnaceBlockEntity.add(map, (ItemLike) Blocks.MANGROVE_ROOTS, 300);
|
||||
- return map;
|
||||
+ // Paper start - cache burn durations
|
||||
+ cachedBurnDurations = com.google.common.collect.ImmutableMap.copyOf(map);
|
||||
+ return cachedBurnDurations;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// CraftBukkit start - add fields and methods
|
|
@ -0,0 +1,26 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BrodyBeckwith <brody@beckwith.dev>
|
||||
Date: Fri, 9 Oct 2020 20:30:12 -0400
|
||||
Subject: [PATCH] Allow disabling mob spawner spawn egg transformation
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/SpawnEggItem.java b/src/main/java/net/minecraft/world/item/SpawnEggItem.java
|
||||
index 8176b64e49166cc24ef7f011881fda38bc68c2a4..591291d3d872d505a6031048c21b2cbeeb5394b2 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/SpawnEggItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/SpawnEggItem.java
|
||||
@@ -63,6 +63,7 @@ public class SpawnEggItem extends Item {
|
||||
EntityType entitytypes;
|
||||
|
||||
if (tileentity instanceof Spawner) {
|
||||
+ if (!world.paperConfig().entities.spawning.disableMobSpawnerSpawnEggTransformation) { // Paper - add condition
|
||||
Spawner spawner = (Spawner) tileentity;
|
||||
|
||||
entitytypes = this.getType(itemstack.getTag());
|
||||
@@ -71,6 +72,7 @@ public class SpawnEggItem extends Item {
|
||||
world.gameEvent((Entity) context.getPlayer(), GameEvent.BLOCK_CHANGE, blockposition);
|
||||
itemstack.shrink(1);
|
||||
return InteractionResult.CONSUME;
|
||||
+ } // Paper - end if
|
||||
} else {
|
||||
BlockPos blockposition1;
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 8 Oct 2020 00:00:25 -0400
|
||||
Subject: [PATCH] Fix "Not a string" Map Conversion spam
|
||||
|
||||
The maps did convert successfully, but had noisy logs due to Spigot
|
||||
implementing this logic incorrectly.
|
||||
|
||||
This stops the spam by converting the old format to new before
|
||||
requesting the world.
|
||||
|
||||
Track spigot issue to see when fixed: https://hub.spigotmc.org/jira/browse/SPIGOT-6181
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
index e1623ade449fe56ec51955ee9594a93f85660c51..5992f450f01349ce49286c34b8af56737de01a45 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
@@ -15,6 +15,8 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
+import net.minecraft.nbt.NumericTag;
|
||||
+import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
@@ -110,7 +112,26 @@ public class MapItemSavedData extends SavedData {
|
||||
}
|
||||
|
||||
public static MapItemSavedData load(CompoundTag nbt) {
|
||||
- DataResult<ResourceKey<Level>> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbt.get("dimension"))); // CraftBukkit - decompile error
|
||||
+ // Paper start - fix "Not a string" spam
|
||||
+ Tag dimension = nbt.get("dimension");
|
||||
+ if (dimension instanceof NumericTag && ((NumericTag) dimension).getAsInt() >= CraftWorld.CUSTOM_DIMENSION_OFFSET) {
|
||||
+ long least = nbt.getLong("UUIDLeast");
|
||||
+ long most = nbt.getLong("UUIDMost");
|
||||
+
|
||||
+ if (least != 0L && most != 0L) {
|
||||
+ UUID uuid = new UUID(most, least);
|
||||
+ CraftWorld world = (CraftWorld) Bukkit.getWorld(uuid);
|
||||
+ if (world != null) {
|
||||
+ dimension = StringTag.valueOf("minecraft:" + world.getName().toLowerCase(java.util.Locale.ENGLISH));
|
||||
+ } else {
|
||||
+ dimension = StringTag.valueOf("bukkit:_invalidworld_");
|
||||
+ }
|
||||
+ } else {
|
||||
+ dimension = StringTag.valueOf("bukkit:_invalidworld_");
|
||||
+ }
|
||||
+ }
|
||||
+ DataResult<ResourceKey<Level>> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, dimension)); // CraftBukkit - decompile error
|
||||
+ // Paper end - fix "Not a string" spam
|
||||
Logger logger = MapItemSavedData.LOGGER;
|
||||
|
||||
Objects.requireNonNull(logger);
|
|
@ -0,0 +1,36 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MisterVector <whizkid3000@hotmail.com>
|
||||
Date: Tue, 13 Aug 2019 19:45:06 -0700
|
||||
Subject: [PATCH] Implement PlayerFlowerPotManipulateEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java b/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java
|
||||
index c450faf8c043665eab020141f3c27e3d9890cb86..f8d76e05a1b5ed25cbe8e2adeb63a748ff0fe3d7 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java
|
||||
@@ -66,6 +66,25 @@ public class FlowerPotBlock extends Block {
|
||||
boolean bl = blockState.is(Blocks.AIR);
|
||||
boolean bl2 = this.isEmpty();
|
||||
if (bl != bl2) {
|
||||
+ // Paper start
|
||||
+ org.bukkit.entity.Player player1 = (org.bukkit.entity.Player) player.getBukkitEntity();
|
||||
+ boolean placing = bl2;
|
||||
+ org.bukkit.block.Block bukkitblock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos);
|
||||
+ org.bukkit.inventory.ItemStack bukkititemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemStack);
|
||||
+ org.bukkit.Material mat = org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(content);
|
||||
+ org.bukkit.inventory.ItemStack bukkititemstack1 = new org.bukkit.inventory.ItemStack(mat, 1);
|
||||
+ org.bukkit.inventory.ItemStack whichitem = placing ? bukkititemstack : bukkititemstack1;
|
||||
+
|
||||
+ io.papermc.paper.event.player.PlayerFlowerPotManipulateEvent event = new io.papermc.paper.event.player.PlayerFlowerPotManipulateEvent(player1, bukkitblock, whichitem, placing);
|
||||
+ player1.getServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // Update client
|
||||
+ player1.updateInventory();
|
||||
+
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (bl2) {
|
||||
world.setBlock(pos, blockState, 3);
|
||||
player.awardStat(Stats.POT_FLOWER);
|
|
@ -0,0 +1,48 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TheMolkaPL <themolkapl@gmail.com>
|
||||
Date: Sun, 21 Jun 2020 17:21:46 +0200
|
||||
Subject: [PATCH] Fix interact event not being called sometimes
|
||||
|
||||
* Call PlayerInteractEvent when left-clicking on a block in adventure
|
||||
mode.
|
||||
* Call PlayerInteractEvent when left-clicking an Entity that is out of
|
||||
range in adventure/survival (entity reach is 3.0).
|
||||
|
||||
Co-authored-by: Moulberry <james.jenour@protonmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 08ff8e489d86030dac403b405b016b77d7f81598..f26d43404a613807cef765897e17192651b9e1a8 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1761,7 +1761,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
MutableComponent ichatmutablecomponent = Component.translatable("build.tooHigh", i - 1).withStyle(ChatFormatting.RED);
|
||||
|
||||
this.player.sendSystemMessage(ichatmutablecomponent, true);
|
||||
- } else if (enuminteractionresult.shouldSwing()) {
|
||||
+ } else if (enuminteractionresult.shouldSwing() && !this.player.gameMode.interactResult) { // Paper
|
||||
this.player.swing(enumhand, true);
|
||||
}
|
||||
}
|
||||
@@ -2304,13 +2304,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
double d3 = this.player.gameMode.getGameModeForPlayer() == GameType.CREATIVE ? 5.0D : 4.5D;
|
||||
// SPIGOT-5607: Only call interact event if no block or entity is being clicked. Use bukkit ray trace method, because it handles blocks and entities at the same time
|
||||
// SPIGOT-7429: Make sure to call PlayerInteractEvent for spectators and non-pickable entities
|
||||
- org.bukkit.util.RayTraceResult result = this.player.level().getWorld().rayTrace(origin, origin.getDirection(), d3, org.bukkit.FluidCollisionMode.NEVER, false, 0.1, entity -> {
|
||||
+ org.bukkit.util.RayTraceResult result = this.player.level().getWorld().rayTrace(origin, origin.getDirection(), d3, org.bukkit.FluidCollisionMode.NEVER, false, 0.0, entity -> { // Paper - change raySize from 0.1 to 0.0
|
||||
Entity handle = ((CraftEntity) entity).getHandle();
|
||||
return entity != this.player.getBukkitEntity() && this.player.getBukkitEntity().canSee(entity) && !handle.isSpectator() && handle.isPickable() && !handle.isPassengerOfSameVehicle(this.player);
|
||||
});
|
||||
if (result == null) {
|
||||
CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND);
|
||||
- }
|
||||
+ } else { // Paper start - Fix interact event not being called sometimes
|
||||
+ GameType gameType = this.player.gameMode.getGameModeForPlayer();
|
||||
+ if (gameType == GameType.ADVENTURE && result.getHitBlock() != null) {
|
||||
+ CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, io.papermc.paper.util.MCUtil.toBlockPosition(result.getHitPosition()), org.bukkit.craftbukkit.block.CraftBlock.blockFaceToNotch(result.getHitBlockFace()), this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND);
|
||||
+ } else if (gameType != GameType.CREATIVE && result.getHitEntity() != null && origin.toVector().distanceSquared(result.getHitPosition()) > 3.0D * 3.0D) {
|
||||
+ CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND);
|
||||
+ }
|
||||
+ } // Paper end
|
||||
|
||||
// Arm swing animation
|
||||
PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer(), (packet.getHand() == InteractionHand.MAIN_HAND) ? PlayerAnimationType.ARM_SWING : PlayerAnimationType.OFF_ARM_SWING);
|
24
patches/server/0516-Zombie-API-breaking-doors.patch
Normal file
24
patches/server/0516-Zombie-API-breaking-doors.patch
Normal file
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 18 Nov 2020 11:32:46 -0800
|
||||
Subject: [PATCH] Zombie API - breaking doors
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.monster.Zombie supportsBreakDoorGoal()Z
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java
|
||||
index 4412c913123f7521f449c98b60378e8d3b1671ce..46336111dcf62a29390e724b1879c84c697076e9 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java
|
||||
@@ -122,6 +122,11 @@ public class CraftZombie extends CraftMonster implements Zombie {
|
||||
public void setShouldBurnInDay(boolean shouldBurnInDay) {
|
||||
getHandle().setShouldBurnInDay(shouldBurnInDay);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean supportsBreakingDoors() {
|
||||
+ return getHandle().supportsBreakDoorGoal();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@Override
|
18
patches/server/0517-Fix-nerfed-slime-when-splitting.patch
Normal file
18
patches/server/0517-Fix-nerfed-slime-when-splitting.patch
Normal file
|
@ -0,0 +1,18 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Mon, 24 Aug 2020 08:39:06 -0700
|
||||
Subject: [PATCH] Fix nerfed slime when splitting
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index fa014c04cc51a55345a1c50098f486161051741d..37724831ba9db2d0fb2e7756816e0355bc760815 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -243,6 +243,7 @@ public class Slime extends Mob implements Enemy {
|
||||
entityslime.setPersistenceRequired();
|
||||
}
|
||||
|
||||
+ entityslime.aware = this.aware; // Paper
|
||||
entityslime.setCustomName(ichatbasecomponent);
|
||||
entityslime.setNoAi(flag);
|
||||
entityslime.setInvulnerable(this.isInvulnerable());
|
44
patches/server/0518-Add-EntityLoadCrossbowEvent.patch
Normal file
44
patches/server/0518-Add-EntityLoadCrossbowEvent.patch
Normal file
|
@ -0,0 +1,44 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: JRoy <joshroy126@gmail.com>
|
||||
Date: Wed, 7 Oct 2020 12:04:01 -0400
|
||||
Subject: [PATCH] Add EntityLoadCrossbowEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/CrossbowItem.java b/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
index ba570f1c9654e1004e068a1efe2118f36c954505..eede02c3f125d230af537bb67bebed9b88f7d1b4 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
@@ -89,7 +89,14 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||
int j = this.getUseDuration(stack) - remainingUseTicks;
|
||||
float f = CrossbowItem.getPowerForTime(j, stack);
|
||||
|
||||
- if (f >= 1.0F && !CrossbowItem.isCharged(stack) && CrossbowItem.tryLoadProjectiles(user, stack)) {
|
||||
+ // Paper start - EntityLoadCrossbowEvent
|
||||
+ if (f >= 1.0F && !CrossbowItem.isCharged(stack) /*&& CrossbowItem.tryLoadProjectiles(entityliving, itemstack)*/) {
|
||||
+ final io.papermc.paper.event.entity.EntityLoadCrossbowEvent event = new io.papermc.paper.event.entity.EntityLoadCrossbowEvent(user.getBukkitLivingEntity(), stack.asBukkitMirror(), user.getUsedItemHand() == InteractionHand.MAIN_HAND ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND);
|
||||
+ if (!event.callEvent() || !tryLoadProjectiles(user, stack, event.shouldConsumeItem())) {
|
||||
+ if (user instanceof ServerPlayer player) player.containerMenu.sendAllDataToRemote();
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
CrossbowItem.setCharged(stack, true);
|
||||
SoundSource soundcategory = user instanceof Player ? SoundSource.PLAYERS : SoundSource.HOSTILE;
|
||||
|
||||
@@ -98,10 +105,16 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||
|
||||
}
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse // Paper
|
||||
private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbow) {
|
||||
+ // Paper start
|
||||
+ return CrossbowItem.tryLoadProjectiles(shooter, crossbow, true);
|
||||
+ }
|
||||
+ private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbow, boolean consume) {
|
||||
+ // Paper end
|
||||
int i = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MULTISHOT, crossbow);
|
||||
int j = i == 0 ? 1 : 3;
|
||||
- boolean flag = shooter instanceof Player && ((Player) shooter).getAbilities().instabuild;
|
||||
+ boolean flag = !consume || shooter instanceof Player && ((Player) shooter).getAbilities().instabuild; // Paper - add consume
|
||||
ItemStack itemstack1 = shooter.getProjectile(crossbow);
|
||||
ItemStack itemstack2 = itemstack1.copy();
|
||||
|
98
patches/server/0519-Added-WorldGameRuleChangeEvent.patch
Normal file
98
patches/server/0519-Added-WorldGameRuleChangeEvent.patch
Normal file
|
@ -0,0 +1,98 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 20 Dec 2020 16:41:44 -0800
|
||||
Subject: [PATCH] Added WorldGameRuleChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/commands/GameRuleCommand.java b/src/main/java/net/minecraft/server/commands/GameRuleCommand.java
|
||||
index c8c358531dbc167e249bac2af246c5e34fbdd4df..307854468ac985560b4c63b6e9897c444a7b8a3a 100644
|
||||
--- a/src/main/java/net/minecraft/server/commands/GameRuleCommand.java
|
||||
+++ b/src/main/java/net/minecraft/server/commands/GameRuleCommand.java
|
||||
@@ -33,7 +33,7 @@ public class GameRuleCommand {
|
||||
CommandSourceStack commandlistenerwrapper = (CommandSourceStack) context.getSource();
|
||||
T t0 = commandlistenerwrapper.getLevel().getGameRules().getRule(key); // CraftBukkit
|
||||
|
||||
- t0.setFromArgument(context, "value");
|
||||
+ t0.setFromArgument(context, "value", key); // Paper
|
||||
commandlistenerwrapper.sendSuccess(() -> {
|
||||
return Component.translatable("commands.gamerule.set", key.getId(), t0.toString());
|
||||
}, true);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java
|
||||
index 334001cb749600c973c82391e1c11f0e40bd2dfb..2a480026c3bfb06e6556fe5b11d9712c8e02debe 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/GameRules.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/GameRules.java
|
||||
@@ -285,10 +285,10 @@ public class GameRules {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
- protected abstract void updateFromArgument(CommandContext<CommandSourceStack> context, String name);
|
||||
+ protected abstract void updateFromArgument(CommandContext<CommandSourceStack> context, String name, GameRules.Key<T> gameRuleKey); // Paper
|
||||
|
||||
- public void setFromArgument(CommandContext<CommandSourceStack> context, String name) {
|
||||
- this.updateFromArgument(context, name);
|
||||
+ public void setFromArgument(CommandContext<CommandSourceStack> context, String name, GameRules.Key<T> gameRuleKey) { // Paper
|
||||
+ this.updateFromArgument(context, name, gameRuleKey); // Paper
|
||||
this.onChanged(((CommandSourceStack) context.getSource()).getServer());
|
||||
}
|
||||
|
||||
@@ -346,8 +346,11 @@ public class GameRules {
|
||||
}
|
||||
|
||||
@Override
|
||||
- protected void updateFromArgument(CommandContext<CommandSourceStack> context, String name) {
|
||||
- this.value = BoolArgumentType.getBool(context, name);
|
||||
+ protected void updateFromArgument(CommandContext<CommandSourceStack> context, String name, GameRules.Key<BooleanValue> gameRuleKey) { // Paper start
|
||||
+ io.papermc.paper.event.world.WorldGameRuleChangeEvent event = new io.papermc.paper.event.world.WorldGameRuleChangeEvent(context.getSource().getBukkitWorld(), context.getSource().getBukkitSender(), (org.bukkit.GameRule<Boolean>) org.bukkit.GameRule.getByName(gameRuleKey.toString()), String.valueOf(BoolArgumentType.getBool(context, name)));
|
||||
+ if (!event.callEvent()) return;
|
||||
+ this.value = Boolean.parseBoolean(event.getValue());
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public boolean get() {
|
||||
@@ -411,8 +414,11 @@ public class GameRules {
|
||||
}
|
||||
|
||||
@Override
|
||||
- protected void updateFromArgument(CommandContext<CommandSourceStack> context, String name) {
|
||||
- this.value = IntegerArgumentType.getInteger(context, name);
|
||||
+ protected void updateFromArgument(CommandContext<CommandSourceStack> context, String name, GameRules.Key<IntegerValue> gameRuleKey) { // Paper start
|
||||
+ io.papermc.paper.event.world.WorldGameRuleChangeEvent event = new io.papermc.paper.event.world.WorldGameRuleChangeEvent(context.getSource().getBukkitWorld(), context.getSource().getBukkitSender(), (org.bukkit.GameRule<Integer>) org.bukkit.GameRule.getByName(gameRuleKey.toString()), String.valueOf(IntegerArgumentType.getInteger(context, name)));
|
||||
+ if (!event.callEvent()) return;
|
||||
+ this.value = Integer.parseInt(event.getValue());
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public int get() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 16df867ff996d33dc08831200d172633c9d68612..cb9db52f7dba755146713be45cb66905e065336f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -1879,8 +1879,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
if (!this.isGameRule(rule)) return false;
|
||||
|
||||
+ // Paper start
|
||||
+ GameRule<?> gameRule = GameRule.getByName(rule);
|
||||
+ io.papermc.paper.event.world.WorldGameRuleChangeEvent event = new io.papermc.paper.event.world.WorldGameRuleChangeEvent(this, null, gameRule, value);
|
||||
+ if (!event.callEvent()) return false;
|
||||
+ // Paper end
|
||||
GameRules.Value<?> handle = this.getHandle().getGameRules().getRule(CraftWorld.getGameRulesNMS().get(rule));
|
||||
- handle.deserialize(value);
|
||||
+ handle.deserialize(event.getValue()); // Paper
|
||||
handle.onChanged(this.getHandle().getServer());
|
||||
return true;
|
||||
}
|
||||
@@ -1916,8 +1921,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
if (!this.isGameRule(rule.getName())) return false;
|
||||
|
||||
+ // Paper start
|
||||
+ io.papermc.paper.event.world.WorldGameRuleChangeEvent event = new io.papermc.paper.event.world.WorldGameRuleChangeEvent(this, null, rule, String.valueOf(newValue));
|
||||
+ if (!event.callEvent()) return false;
|
||||
+ // Paper end
|
||||
GameRules.Value<?> handle = this.getHandle().getGameRules().getRule(CraftWorld.getGameRulesNMS().get(rule.getName()));
|
||||
- handle.deserialize(newValue.toString());
|
||||
+ handle.deserialize(event.getValue()); // Paper
|
||||
handle.onChanged(this.getHandle().getServer());
|
||||
return true;
|
||||
}
|
54
patches/server/0520-Added-ServerResourcesReloadedEvent.patch
Normal file
54
patches/server/0520-Added-ServerResourcesReloadedEvent.patch
Normal file
|
@ -0,0 +1,54 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 2 Dec 2020 20:04:01 -0800
|
||||
Subject: [PATCH] Added ServerResourcesReloadedEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index f73ad3b85ed46913c10891edd3a52b9ad694e5e2..c063dece36e110691297b38635a9d14d70c4e391 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2108,7 +2108,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return this.functionManager;
|
||||
}
|
||||
|
||||
+ // Paper start - add cause
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse
|
||||
public CompletableFuture<Void> reloadResources(Collection<String> dataPacks) {
|
||||
+ return this.reloadResources(dataPacks, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.PLUGIN);
|
||||
+ }
|
||||
+ public CompletableFuture<Void> reloadResources(Collection<String> dataPacks, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause cause) {
|
||||
+ // Paper end
|
||||
RegistryAccess.Frozen iregistrycustom_dimension = this.registries.getAccessForLoading(RegistryLayer.RELOADABLE);
|
||||
CompletableFuture<Void> completablefuture = CompletableFuture.supplyAsync(() -> {
|
||||
Stream<String> stream = dataPacks.stream(); // CraftBukkit - decompile error
|
||||
@@ -2149,6 +2155,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
|
||||
this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager);
|
||||
org.bukkit.craftbukkit.block.data.CraftBlockData.reloadCache(); // Paper - cache block data strings, they can be defined by datapacks so refresh it here
|
||||
+ new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper - fire after everything has been reloaded
|
||||
}, this);
|
||||
|
||||
if (this.isSameThread()) {
|
||||
diff --git a/src/main/java/net/minecraft/server/commands/ReloadCommand.java b/src/main/java/net/minecraft/server/commands/ReloadCommand.java
|
||||
index fa18d018a8458b30c0048f7e59aea39f928d974a..87d32af973b84fbbea5dcdb34273f3b3fc82d054 100644
|
||||
--- a/src/main/java/net/minecraft/server/commands/ReloadCommand.java
|
||||
+++ b/src/main/java/net/minecraft/server/commands/ReloadCommand.java
|
||||
@@ -20,7 +20,7 @@ public class ReloadCommand {
|
||||
public ReloadCommand() {}
|
||||
|
||||
public static void reloadPacks(Collection<String> dataPacks, CommandSourceStack source) {
|
||||
- source.getServer().reloadResources(dataPacks).exceptionally((throwable) -> {
|
||||
+ source.getServer().reloadResources(dataPacks, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.COMMAND).exceptionally((throwable) -> {
|
||||
ReloadCommand.LOGGER.warn("Failed to execute reload", throwable);
|
||||
source.sendFailure(Component.translatable("commands.reload.failure"));
|
||||
return null;
|
||||
@@ -50,7 +50,7 @@ public class ReloadCommand {
|
||||
WorldData savedata = minecraftserver.getWorldData();
|
||||
Collection<String> collection = resourcepackrepository.getSelectedIds();
|
||||
Collection<String> collection1 = ReloadCommand.discoverNewPacks(resourcepackrepository, savedata, collection);
|
||||
- minecraftserver.reloadResources(collection1);
|
||||
+ minecraftserver.reloadResources(collection1, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.PLUGIN); // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 28 Nov 2020 18:43:52 -0800
|
||||
Subject: [PATCH] Added world settings for mobs picking up loot
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
index dadb419a04b343d6ba59353c6caa1a50aa07b67f..6be9e8d693bbb084791d7b30a1891ddb803d6b02 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
@@ -153,7 +153,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
|
||||
this.populateDefaultEquipmentSlots(randomsource, difficulty);
|
||||
this.populateDefaultEquipmentEnchantments(randomsource, difficulty);
|
||||
this.reassessWeaponGoal();
|
||||
- this.setCanPickUpLoot(randomsource.nextFloat() < 0.55F * difficulty.getSpecialMultiplier());
|
||||
+ this.setCanPickUpLoot(this.level().paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.skeletons || randomsource.nextFloat() < 0.55F * difficulty.getSpecialMultiplier()); // Paper
|
||||
if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
|
||||
LocalDate localdate = LocalDate.now();
|
||||
int i = localdate.get(ChronoField.DAY_OF_MONTH);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
index f99e4382b4b191d9bd673a4307c6641857b836ca..89515078590b2f2c7e73456b7ab5817f44039be5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
@@ -507,7 +507,7 @@ public class Zombie extends Monster {
|
||||
Object object = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt);
|
||||
float f = difficulty.getSpecialMultiplier();
|
||||
|
||||
- this.setCanPickUpLoot(randomsource.nextFloat() < 0.55F * f);
|
||||
+ this.setCanPickUpLoot(this.level().paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.zombies || randomsource.nextFloat() < 0.55F * f); // Paper
|
||||
if (object == null) {
|
||||
object = new Zombie.ZombieGroupData(Zombie.getSpawnAsBabyOdds(randomsource), true);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TheViperShow <29604693+TheViperShow@users.noreply.github.com>
|
||||
Date: Wed, 22 Apr 2020 09:40:38 +0200
|
||||
Subject: [PATCH] Implemented BlockFailedDispenseEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java
|
||||
index d77ca08832105e82cee265eea222e0d64a8876ef..21c37ad365e09a296c3e7a2d0cde7a29ced09c33 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java
|
||||
@@ -95,8 +95,10 @@ public class DispenserBlock extends BaseEntityBlock {
|
||||
int i = tileentitydispenser.getRandomSlot(world.random);
|
||||
|
||||
if (i < 0) {
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFailedDispenseEvent(world, pos)) { // Paper - BlockFailedDispenseEvent is called here
|
||||
world.levelEvent(1001, pos, 0);
|
||||
world.gameEvent(GameEvent.BLOCK_ACTIVATE, pos, GameEvent.Context.of(tileentitydispenser.getBlockState()));
|
||||
+ } // Paper
|
||||
} else {
|
||||
ItemStack itemstack = tileentitydispenser.getItem(i);
|
||||
DispenseItemBehavior idispensebehavior = this.getDispenseMethod(itemstack);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/DropperBlock.java b/src/main/java/net/minecraft/world/level/block/DropperBlock.java
|
||||
index 913ed110d8402d377152753325901eb7f3ac82d6..675644974ae6fb5380a6496a2ac3ec4d1ef7c924 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/DropperBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/DropperBlock.java
|
||||
@@ -59,6 +59,7 @@ public class DropperBlock extends DispenserBlock {
|
||||
int i = tileentitydispenser.getRandomSlot(world.random);
|
||||
|
||||
if (i < 0) {
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFailedDispenseEvent(world, pos)) // Paper - BlockFailedDispenseEvent is called here
|
||||
world.levelEvent(1001, pos, 0);
|
||||
} else {
|
||||
ItemStack itemstack = tileentitydispenser.getItem(i);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index c4dd2ab7afe61d354418dc5475c3b444609ccd80..7b6ed5812a9ea1ba1a4a2183c1568e9c60cc9c21 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -2043,4 +2043,12 @@ public class CraftEventFactory {
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
return event;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public static boolean handleBlockFailedDispenseEvent(ServerLevel serverLevel, BlockPos blockposition) {
|
||||
+ org.bukkit.block.Block block = serverLevel.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
+ io.papermc.paper.event.block.BlockFailedDispenseEvent event = new io.papermc.paper.event.block.BlockFailedDispenseEvent(block);
|
||||
+ return event.callEvent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
46
patches/server/0523-Added-PlayerLecternPageChangeEvent.patch
Normal file
46
patches/server/0523-Added-PlayerLecternPageChangeEvent.patch
Normal file
|
@ -0,0 +1,46 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Mon, 23 Nov 2020 12:58:51 -0800
|
||||
Subject: [PATCH] Added PlayerLecternPageChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/LecternMenu.java b/src/main/java/net/minecraft/world/inventory/LecternMenu.java
|
||||
index 19858ecd7cfaaf0fb09552292bf573bb02b3a6ec..84795cd53720a618360644702b22abe8d015dadc 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/LecternMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/LecternMenu.java
|
||||
@@ -64,6 +64,7 @@ public class LecternMenu extends AbstractContainerMenu {
|
||||
@Override
|
||||
public boolean clickMenuButton(net.minecraft.world.entity.player.Player player, int id) {
|
||||
int j;
|
||||
+ io.papermc.paper.event.player.PlayerLecternPageChangeEvent playerLecternPageChangeEvent; CraftInventoryLectern bukkitView; // Paper
|
||||
|
||||
if (id >= 100) {
|
||||
j = id - 100;
|
||||
@@ -73,11 +74,25 @@ public class LecternMenu extends AbstractContainerMenu {
|
||||
switch (id) {
|
||||
case 1:
|
||||
j = this.lecternData.get(0);
|
||||
- this.setData(0, j - 1);
|
||||
+ // Paper start
|
||||
+ bukkitView = (CraftInventoryLectern) getBukkitView().getTopInventory();
|
||||
+ playerLecternPageChangeEvent = new io.papermc.paper.event.player.PlayerLecternPageChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), bukkitView.getHolder(), bukkitView.getBook(), io.papermc.paper.event.player.PlayerLecternPageChangeEvent.PageChangeDirection.LEFT, j, j - 1);
|
||||
+ if (!playerLecternPageChangeEvent.callEvent()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ this.setData(0, playerLecternPageChangeEvent.getNewPage());
|
||||
+ // Paper end
|
||||
return true;
|
||||
case 2:
|
||||
j = this.lecternData.get(0);
|
||||
- this.setData(0, j + 1);
|
||||
+ // Paper start
|
||||
+ bukkitView = (CraftInventoryLectern) getBukkitView().getTopInventory();
|
||||
+ playerLecternPageChangeEvent = new io.papermc.paper.event.player.PlayerLecternPageChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), bukkitView.getHolder(), bukkitView.getBook(), io.papermc.paper.event.player.PlayerLecternPageChangeEvent.PageChangeDirection.RIGHT, j, j + 1);
|
||||
+ if (!playerLecternPageChangeEvent.callEvent()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ this.setData(0, playerLecternPageChangeEvent.getNewPage());
|
||||
+ // Paper end
|
||||
return true;
|
||||
case 3:
|
||||
if (!player.mayBuild()) {
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue