Compare commits
78
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
427c3062d7 | ||
|
|
d837c9f3c3 | ||
|
|
840583cc5e | ||
|
|
96e5ceb147 | ||
|
|
d52684e325 | ||
|
|
c8f9c17638 | ||
|
|
dbc5747dad | ||
|
|
75297490ed | ||
|
|
8849f5b24e | ||
|
|
d5c6a22613 | ||
|
|
a85a2db790 | ||
|
|
af241555be | ||
|
|
57c3792405 | ||
|
|
1bb6118750 | ||
|
|
df9ce9405e | ||
|
|
218bb00997 | ||
|
|
e0e6ae86a8 | ||
|
|
fc231e5b78 | ||
|
|
a0a0bec65c | ||
|
|
b803be88ee | ||
|
|
ab3b3f2564 | ||
|
|
aa15ca8009 | ||
|
|
41d9ab1aeb | ||
|
|
34ee6e5d49 | ||
|
|
cefefc9591 | ||
|
|
befe2439b8 | ||
|
|
c2811eddbe | ||
|
|
e205825404 | ||
|
|
72e7cc1a3c | ||
|
|
6eed97a251 | ||
|
|
eebde33db3 | ||
|
|
461c531e0a | ||
|
|
51e8551ea0 | ||
|
|
90805c262c | ||
|
|
ad5d426e62 | ||
|
|
91c0d9f374 | ||
|
|
c8b5eb5db7 | ||
|
|
afeb8e951f | ||
|
|
75d19e26d7 | ||
|
|
6e5effa052 | ||
|
|
4fb84d6047 | ||
|
|
0a41b4eeaf | ||
|
|
4b53e74746 | ||
|
|
bea046e78d | ||
|
|
d933a7b302 | ||
|
|
641505fee5 | ||
|
|
c99e67a4fd | ||
|
|
d4ea8628e2 | ||
|
|
2379365a2b | ||
|
|
eee862f577 | ||
|
|
f3f2c8155f | ||
|
|
ac68fdc170 | ||
|
|
c0718848eb | ||
|
|
a6cff5b519 | ||
|
|
27bd1fa0b7 | ||
|
|
3ca4f21b90 | ||
|
|
5ace1ec0f4 | ||
|
|
667fa29f93 | ||
|
|
e69d1e6bb4 | ||
|
|
b4322626d2 | ||
|
|
2d58b75357 | ||
|
|
f875b15d7e | ||
|
|
637a82d779 | ||
|
|
0f34603c5c | ||
|
|
8ea09b9d47 | ||
|
|
3ec2262294 | ||
|
|
fd4d92e604 | ||
|
|
6f87d74cf5 | ||
|
|
1b15719bc8 | ||
|
|
20dee726d0 | ||
|
|
2ce46092d6 | ||
|
|
ff9bebb2f1 | ||
|
|
208e1ee139 | ||
|
|
02e693f159 | ||
|
|
5e6bcf1412 | ||
|
|
3281c4fdce | ||
|
|
ffd7272128 | ||
|
|
b7f4c58eab |
No files matched your search
@@ -122,6 +122,7 @@ public net.minecraft.tags.TagEntry id
|
||||
public net.minecraft.tags.TagEntry required
|
||||
public net.minecraft.tags.TagEntry tag
|
||||
public net.minecraft.util.datafix.fixes.BlockStateData register(ILjava/lang/String;[Ljava/lang/String;)V
|
||||
public net.minecraft.util.datafix.fixes.EntityCustomNameToComponentFix fixCustomName(Lcom/mojang/serialization/DynamicOps;Ljava/lang/String;Ljava/lang/String;)Lcom/mojang/serialization/Dynamic;
|
||||
public net.minecraft.util.datafix.fixes.ItemIdFix ITEM_NAMES
|
||||
public net.minecraft.util.datafix.fixes.ItemSpawnEggFix ID_TO_ENTITY
|
||||
public net.minecraft.world.BossEvent color
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import java.nio.file.Path
|
||||
import kotlin.random.Random
|
||||
|
||||
plugins {
|
||||
id("io.papermc.paperweight.core") version "2.0.0-beta.14" apply false
|
||||
id("io.papermc.paperweight.core") version "2.0.0-beta.15" apply false
|
||||
}
|
||||
|
||||
subprojects {
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
group=io.papermc.paper
|
||||
version=1.21.4-R0.1-SNAPSHOT
|
||||
mcVersion=1.21.4
|
||||
version=1.21.5-R0.1-SNAPSHOT
|
||||
mcVersion=1.21.5-pre1
|
||||
|
||||
# Set to true while updating Minecraft version
|
||||
updatingMinecraft=false
|
||||
updatingMinecraft=true
|
||||
updateTaskListIssue=https://github.com/PaperMC/Paper/issues/11736
|
||||
|
||||
org.gradle.configuration-cache=true
|
||||
|
||||
@@ -11,15 +11,18 @@ plugins {
|
||||
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
||||
|
||||
dependencies {
|
||||
mache("io.papermc:mache:1.21.4+build.7")
|
||||
mache("io.papermc:mache:1.21.5-pre1+build.1")
|
||||
paperclip("io.papermc:paperclip:3.0.3")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
}
|
||||
|
||||
paperweight {
|
||||
minecraftVersion = providers.gradleProperty("mcVersion")
|
||||
// macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java")
|
||||
// gitFilePatches = true
|
||||
gitFilePatches = false
|
||||
|
||||
updatingMinecraft {
|
||||
oldPaperCommit = "f4f275519f7c1fbe9db173b7144a4fe81440e365"
|
||||
}
|
||||
|
||||
spigot {
|
||||
buildDataRef = "3edaf46ec1eed4115ce1b18d2846cded42577e42"
|
||||
|
||||
+60
-52
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 4894d2bdb354d191fd062202cbcc0bdabfed9209..e54b5a165ad4dc4d2158dab34c5008512e5f7885 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -174,11 +_,13 @@
|
||||
@@ -174,11 +174,13 @@ import net.minecraft.world.phys.Vec3;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements ServerInfo, ChunkIOErrorReporter, CommandSource {
|
||||
@@ -15,7 +23,7 @@
|
||||
private static final int OVERLOADED_TICKS_THRESHOLD = 20;
|
||||
private static final long OVERLOADED_WARNING_INTERVAL_NANOS = 10L * TimeUtil.NANOSECONDS_PER_SECOND;
|
||||
private static final int OVERLOADED_TICKS_WARNING_INTERVAL = 100;
|
||||
@@ -218,6 +_,7 @@
|
||||
@@ -218,6 +220,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private Map<ResourceKey<Level>, ServerLevel> levels = Maps.newLinkedHashMap();
|
||||
private PlayerList playerList;
|
||||
private volatile boolean running = true;
|
||||
@@ -23,7 +31,7 @@
|
||||
private boolean stopped;
|
||||
private int tickCount;
|
||||
private int ticksUntilAutosave = 6000;
|
||||
@@ -226,11 +_,15 @@
|
||||
@@ -226,11 +229,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private boolean preventProxyConnections;
|
||||
private boolean pvp;
|
||||
private boolean allowFlight;
|
||||
@@ -41,7 +49,7 @@
|
||||
@Nullable
|
||||
private KeyPair keyPair;
|
||||
@Nullable
|
||||
@@ -271,10 +_,37 @@
|
||||
@@ -271,10 +278,37 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private final SuppressedExceptionCollector suppressedExceptions = new SuppressedExceptionCollector();
|
||||
private final DiscontinuousFrame tickFrame;
|
||||
|
||||
@@ -80,7 +88,7 @@
|
||||
if (Runtime.getRuntime().availableProcessors() > 4) {
|
||||
thread.setPriority(8);
|
||||
}
|
||||
@@ -286,6 +_,10 @@
|
||||
@@ -286,6 +320,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
public MinecraftServer(
|
||||
@@ -91,7 +99,7 @@
|
||||
Thread serverThread,
|
||||
LevelStorageSource.LevelStorageAccess storageSource,
|
||||
PackRepository packRepository,
|
||||
@@ -296,9 +_,10 @@
|
||||
@@ -296,9 +334,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
ChunkProgressListenerFactory progressListenerFactory
|
||||
) {
|
||||
super("Server");
|
||||
@@ -103,7 +111,7 @@
|
||||
throw new IllegalStateException("Missing Overworld dimension data");
|
||||
} else {
|
||||
this.proxy = proxy;
|
||||
@@ -309,7 +_,7 @@
|
||||
@@ -309,7 +348,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
services.profileCache().setExecutor(this);
|
||||
}
|
||||
|
||||
@@ -112,7 +120,7 @@
|
||||
this.tickRateManager = new ServerTickRateManager(this);
|
||||
this.progressListenerFactory = progressListenerFactory;
|
||||
this.storageSource = storageSource;
|
||||
@@ -328,6 +_,38 @@
|
||||
@@ -328,6 +367,38 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures());
|
||||
this.tickFrame = TracyClient.createDiscontinuousFrame("Server Tick");
|
||||
}
|
||||
@@ -151,7 +159,7 @@
|
||||
}
|
||||
|
||||
private void readScoreboard(DimensionDataStorage dataStorage) {
|
||||
@@ -336,18 +_,13 @@
|
||||
@@ -336,18 +407,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
protected abstract boolean initServer() throws IOException;
|
||||
|
||||
@@ -172,7 +180,7 @@
|
||||
if (profiledDuration != null) {
|
||||
profiledDuration.finish(true);
|
||||
}
|
||||
@@ -364,25 +_,265 @@
|
||||
@@ -364,25 +430,265 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
protected void forceDifficulty() {
|
||||
}
|
||||
|
||||
@@ -457,7 +465,7 @@
|
||||
if (!serverLevelData.isInitialized()) {
|
||||
try {
|
||||
setInitialSpawn(serverLevel, serverLevelData, worldOptions.generateBonusChest(), isDebugWorld);
|
||||
@@ -403,47 +_,30 @@
|
||||
@@ -403,47 +709,30 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
serverLevelData.setInitialized(true);
|
||||
}
|
||||
@@ -522,7 +530,7 @@
|
||||
int spawnHeight = chunkSource.getGenerator().getSpawnHeight(level);
|
||||
if (spawnHeight < level.getMinY()) {
|
||||
BlockPos worldPosition = chunkPos.getWorldPosition();
|
||||
@@ -495,26 +_,31 @@
|
||||
@@ -495,26 +784,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
serverLevelData.setGameType(GameType.SPECTATOR);
|
||||
}
|
||||
|
||||
@@ -562,7 +570,7 @@
|
||||
ForcedChunksSavedData forcedChunksSavedData = serverLevel1.getDataStorage().get(ForcedChunksSavedData.factory(), "chunks");
|
||||
if (forcedChunksSavedData != null) {
|
||||
LongIterator longIterator = forcedChunksSavedData.getChunks().iterator();
|
||||
@@ -527,10 +_,17 @@
|
||||
@@ -527,10 +821,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,7 +591,7 @@
|
||||
}
|
||||
|
||||
public GameType getDefaultGameType() {
|
||||
@@ -559,11 +_,14 @@
|
||||
@@ -559,11 +860,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
flag = true;
|
||||
}
|
||||
|
||||
@@ -598,7 +606,7 @@
|
||||
if (flush) {
|
||||
for (ServerLevel serverLevel2 : this.getAllLevels()) {
|
||||
LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", serverLevel2.getChunkSource().chunkMap.getStorageName());
|
||||
@@ -593,18 +_,48 @@
|
||||
@@ -593,18 +897,48 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.stopServer();
|
||||
}
|
||||
|
||||
@@ -648,7 +656,7 @@
|
||||
}
|
||||
|
||||
LOGGER.info("Saving worlds");
|
||||
@@ -646,6 +_,25 @@
|
||||
@@ -646,6 +980,25 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
} catch (IOException var4) {
|
||||
LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), var4);
|
||||
}
|
||||
@@ -674,7 +682,7 @@
|
||||
}
|
||||
|
||||
public String getLocalIp() {
|
||||
@@ -661,6 +_,14 @@
|
||||
@@ -661,6 +1014,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
public void halt(boolean waitForServer) {
|
||||
@@ -689,7 +697,7 @@
|
||||
this.running = false;
|
||||
if (waitForServer) {
|
||||
try {
|
||||
@@ -671,6 +_,57 @@
|
||||
@@ -671,6 +1032,57 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,7 +755,7 @@
|
||||
protected void runServer() {
|
||||
try {
|
||||
if (!this.initServer()) {
|
||||
@@ -681,6 +_,35 @@
|
||||
@@ -681,6 +1093,35 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.statusIcon = this.loadStatusIcon().orElse(null);
|
||||
this.status = this.buildServerStatus();
|
||||
|
||||
@@ -783,7 +791,7 @@
|
||||
while (this.running) {
|
||||
long l;
|
||||
if (!this.isPaused() && this.tickRateManager.isSprinting() && this.tickRateManager.checkShouldSprintThisTick()) {
|
||||
@@ -693,11 +_,30 @@
|
||||
@@ -693,11 +1134,30 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (l1 > OVERLOADED_THRESHOLD_NANOS + 20L * l
|
||||
&& this.nextTickTimeNanos - this.lastOverloadWarningNanos >= OVERLOADED_WARNING_INTERVAL_NANOS + 100L * l) {
|
||||
long l2 = l1 / l;
|
||||
@@ -814,7 +822,7 @@
|
||||
|
||||
boolean flag = l == 0L;
|
||||
if (this.debugCommandProfilerDelayStart) {
|
||||
@@ -705,6 +_,8 @@
|
||||
@@ -705,6 +1165,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount);
|
||||
}
|
||||
|
||||
@@ -823,7 +831,7 @@
|
||||
this.nextTickTimeNanos += l;
|
||||
|
||||
try (Profiler.Scope scope = Profiler.use(this.createProfiler())) {
|
||||
@@ -755,7 +_,7 @@
|
||||
@@ -755,7 +1217,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.services.profileCache().clearExecutor();
|
||||
}
|
||||
|
||||
@@ -832,7 +840,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -807,7 +_,14 @@
|
||||
@@ -807,7 +1269,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
private boolean haveTime() {
|
||||
@@ -848,7 +856,7 @@
|
||||
}
|
||||
|
||||
public static boolean throwIfFatalException() {
|
||||
@@ -852,6 +_,12 @@
|
||||
@@ -852,6 +1321,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
@Override
|
||||
public TickTask wrapRunnable(Runnable runnable) {
|
||||
@@ -861,7 +869,7 @@
|
||||
return new TickTask(this.tickCount, runnable);
|
||||
}
|
||||
|
||||
@@ -871,15 +_,16 @@
|
||||
@@ -871,15 +1346,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (super.pollTask()) {
|
||||
return true;
|
||||
} else {
|
||||
@@ -880,7 +888,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -927,26 +_,44 @@
|
||||
@@ -927,26 +1403,44 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
public void tickServer(BooleanSupplier hasTimeLeft) {
|
||||
@@ -926,7 +934,7 @@
|
||||
this.tickCount++;
|
||||
this.tickRateManager.tick();
|
||||
this.tickChildren(hasTimeLeft);
|
||||
@@ -956,11 +_,19 @@
|
||||
@@ -956,11 +1450,19 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
this.ticksUntilAutosave--;
|
||||
@@ -947,7 +955,7 @@
|
||||
profilerFiller.push("tallying");
|
||||
long l = Util.getNanos() - nanos;
|
||||
int i1 = this.tickCount % 100;
|
||||
@@ -968,12 +_,17 @@
|
||||
@@ -968,12 +1470,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.aggregatedTickTimesNanos += l;
|
||||
this.tickTimesNanos[i1] = l;
|
||||
this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)l / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F;
|
||||
@@ -966,7 +974,7 @@
|
||||
LOGGER.debug("Autosave started");
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("save");
|
||||
@@ -1015,7 +_,7 @@
|
||||
@@ -1015,7 +1522,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private ServerStatus buildServerStatus() {
|
||||
ServerStatus.Players players = this.buildPlayerStatus();
|
||||
return new ServerStatus(
|
||||
@@ -975,7 +983,7 @@
|
||||
Optional.of(players),
|
||||
Optional.of(ServerStatus.Version.current()),
|
||||
Optional.ofNullable(this.statusIcon),
|
||||
@@ -1029,7 +_,7 @@
|
||||
@@ -1029,7 +1536,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (this.hidesOnlinePlayers()) {
|
||||
return new ServerStatus.Players(maxPlayers, players.size(), List.of());
|
||||
} else {
|
||||
@@ -984,7 +992,7 @@
|
||||
ObjectArrayList<GameProfile> list = new ObjectArrayList<>(min);
|
||||
int randomInt = Mth.nextInt(this.random, 0, players.size() - min);
|
||||
|
||||
@@ -1046,17 +_,66 @@
|
||||
@@ -1046,17 +1553,66 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
protected void tickChildren(BooleanSupplier hasTimeLeft) {
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing());
|
||||
@@ -1051,7 +1059,7 @@
|
||||
|
||||
profilerFiller.push("tick");
|
||||
|
||||
@@ -1070,7 +_,9 @@
|
||||
@@ -1070,7 +1626,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
profilerFiller.pop();
|
||||
profilerFiller.pop();
|
||||
@@ -1061,7 +1069,7 @@
|
||||
|
||||
profilerFiller.popPush("connection");
|
||||
this.tickConnection();
|
||||
@@ -1148,6 +_,22 @@
|
||||
@@ -1148,6 +1706,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return this.levels.get(dimension);
|
||||
}
|
||||
|
||||
@@ -1084,7 +1092,7 @@
|
||||
public Set<ResourceKey<Level>> levelKeys() {
|
||||
return this.levels.keySet();
|
||||
}
|
||||
@@ -1177,7 +_,7 @@
|
||||
@@ -1177,7 +1751,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
@DontObfuscate
|
||||
public String getServerModName() {
|
||||
@@ -1093,7 +1101,7 @@
|
||||
}
|
||||
|
||||
public SystemReport fillSystemReport(SystemReport systemReport) {
|
||||
@@ -1212,7 +_,7 @@
|
||||
@@ -1212,7 +1786,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
@Override
|
||||
public void sendSystemMessage(Component component) {
|
||||
@@ -1102,7 +1110,7 @@
|
||||
}
|
||||
|
||||
public KeyPair getKeyPair() {
|
||||
@@ -1250,11 +_,14 @@
|
||||
@@ -1250,11 +1824,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1122,7 +1130,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1264,7 +_,7 @@
|
||||
@@ -1264,7 +1841,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
private void updateMobSpawningFlags() {
|
||||
for (ServerLevel serverLevel : this.getAllLevels()) {
|
||||
@@ -1131,7 +1139,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1340,10 +_,20 @@
|
||||
@@ -1340,10 +1917,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
@Override
|
||||
public String getMotd() {
|
||||
@@ -1153,7 +1161,7 @@
|
||||
this.motd = motd;
|
||||
}
|
||||
|
||||
@@ -1366,7 +_,7 @@
|
||||
@@ -1366,7 +1953,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
public ServerConnectionListener getConnection() {
|
||||
@@ -1162,7 +1170,7 @@
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
@@ -1452,7 +_,7 @@
|
||||
@@ -1452,7 +2039,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@Override
|
||||
public void executeIfPossible(Runnable task) {
|
||||
if (this.isStopped()) {
|
||||
@@ -1171,7 +1179,7 @@
|
||||
} else {
|
||||
super.executeIfPossible(task);
|
||||
}
|
||||
@@ -1491,7 +_,13 @@
|
||||
@@ -1491,7 +2078,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return this.functionManager;
|
||||
}
|
||||
|
||||
@@ -1185,7 +1193,7 @@
|
||||
CompletableFuture<Void> completableFuture = CompletableFuture.<ImmutableList>supplyAsync(
|
||||
() -> selectedIds.stream().map(this.packRepository::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList()),
|
||||
this
|
||||
@@ -1499,7 +_,7 @@
|
||||
@@ -1499,7 +2092,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
.thenCompose(
|
||||
list -> {
|
||||
CloseableResourceManager closeableResourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, list);
|
||||
@@ -1194,7 +1202,7 @@
|
||||
return ReloadableServerResources.loadResources(
|
||||
closeableResourceManager,
|
||||
this.registries,
|
||||
@@ -1520,20 +_,39 @@
|
||||
@@ -1520,20 +2113,39 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
)
|
||||
.thenAcceptAsync(
|
||||
reloadableResources -> {
|
||||
@@ -1236,7 +1244,7 @@
|
||||
},
|
||||
this
|
||||
);
|
||||
@@ -1550,7 +_,7 @@
|
||||
@@ -1550,7 +2162,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
DataPackConfig dataPackConfig = initialDataConfig.dataPacks();
|
||||
FeatureFlagSet featureFlagSet = initMode ? FeatureFlagSet.of() : initialDataConfig.enabledFeatures();
|
||||
FeatureFlagSet featureFlagSet1 = initMode ? FeatureFlags.REGISTRY.allFlags() : initialDataConfig.enabledFeatures();
|
||||
@@ -1245,7 +1253,7 @@
|
||||
if (safeMode) {
|
||||
return configureRepositoryWithSelection(packRepository, List.of("vanilla"), featureFlagSet, false);
|
||||
} else {
|
||||
@@ -1605,7 +_,7 @@
|
||||
@@ -1605,7 +2217,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private static WorldDataConfiguration configureRepositoryWithSelection(
|
||||
PackRepository packRepository, Collection<String> selectedPacks, FeatureFlagSet enabledFeatures, boolean safeMode
|
||||
) {
|
||||
@@ -1254,7 +1262,7 @@
|
||||
enableForcedFeaturePacks(packRepository, enabledFeatures);
|
||||
DataPackConfig selectedPacks1 = getSelectedPacks(packRepository, safeMode);
|
||||
FeatureFlagSet featureFlagSet = packRepository.getRequestedFeatureFlags().join(enabledFeatures);
|
||||
@@ -1637,7 +_,7 @@
|
||||
@@ -1637,7 +2249,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1263,7 +1271,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1651,11 +_,12 @@
|
||||
@@ -1651,11 +2263,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public void kickUnlistedPlayers(CommandSourceStack commandSource) {
|
||||
if (this.isEnforceWhitelist()) {
|
||||
PlayerList playerList = commandSource.getServer().getPlayerList();
|
||||
@@ -1278,7 +1286,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1859,6 +_,22 @@
|
||||
@@ -1859,6 +2472,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1301,7 +1309,7 @@
|
||||
private ProfilerFiller createProfiler() {
|
||||
if (this.willStartRecordingMetrics) {
|
||||
this.metricsRecorder = ActiveMetricsRecorder.createStarted(
|
||||
@@ -1980,16 +_,22 @@
|
||||
@@ -1980,16 +2609,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
public void logChatMessage(Component content, ChatType.Bound boundChatType, @Nullable String header) {
|
||||
@@ -1317,18 +1325,18 @@
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
+
|
||||
|
||||
+ public final java.util.concurrent.ExecutorService chatExecutor = java.util.concurrent.Executors.newCachedThreadPool(
|
||||
+ new com.google.common.util.concurrent.ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Chat Thread - #%d").setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)).build()); // Paper
|
||||
+ public final ChatDecorator improvedChatDecorator = new io.papermc.paper.adventure.ImprovedChatDecorator(this); // Paper - adventure
|
||||
|
||||
+
|
||||
public ChatDecorator getChatDecorator() {
|
||||
- return ChatDecorator.PLAIN;
|
||||
+ return this.improvedChatDecorator; // Paper - support async chat decoration events
|
||||
}
|
||||
|
||||
public boolean logIPs() {
|
||||
@@ -2122,4 +_,53 @@
|
||||
@@ -2122,4 +2757,53 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 146b11ebb315efb4aea1d1183bd08f9db7c350e0..d95413af04121fe91ca0f3b0c70025b9808acef9 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -145,6 +145,33 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
public int serverViewDistance;
|
||||
private final WorldGenContext worldGenContext;
|
||||
|
||||
+ // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
|
||||
+ public final CallbackExecutor callbackExecutor = new CallbackExecutor();
|
||||
+ public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable {
|
||||
+
|
||||
+ private final java.util.Queue<Runnable> queue = new java.util.ArrayDeque<>();
|
||||
+
|
||||
+ @Override
|
||||
+ public void execute(Runnable runnable) {
|
||||
+ this.queue.add(runnable);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ Runnable task;
|
||||
+ while ((task = this.queue.poll()) != null) {
|
||||
+ task.run();
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ // Paper start
|
||||
+ public final ChunkHolder getUnloadingChunkHolder(int chunkX, int chunkZ) {
|
||||
+ return this.pendingUnloads.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public ChunkMap(
|
||||
ServerLevel level,
|
||||
LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
@@ -171,13 +198,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.level = level;
|
||||
RegistryAccess registryAccess = level.registryAccess();
|
||||
long seed = level.getSeed();
|
||||
- if (generator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||
+ // CraftBukkit start - SPIGOT-7051: It's a rigged game! Use delegate for random state creation, otherwise it is not so random.
|
||||
+ ChunkGenerator randomGenerator = generator;
|
||||
+ if (randomGenerator instanceof org.bukkit.craftbukkit.generator.CustomChunkGenerator customChunkGenerator) {
|
||||
+ randomGenerator = customChunkGenerator.getDelegate();
|
||||
+ }
|
||||
+ if (randomGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||
+ // CraftBukkit end
|
||||
this.randomState = RandomState.create(noiseBasedChunkGenerator.generatorSettings().value(), registryAccess.lookupOrThrow(Registries.NOISE), seed);
|
||||
} else {
|
||||
this.randomState = RandomState.create(NoiseGeneratorSettings.dummy(), registryAccess.lookupOrThrow(Registries.NOISE), seed);
|
||||
}
|
||||
|
||||
- this.chunkGeneratorState = generator.createState(registryAccess.lookupOrThrow(Registries.STRUCTURE_SET), this.randomState, seed);
|
||||
+ this.chunkGeneratorState = generator.createState(registryAccess.lookupOrThrow(Registries.STRUCTURE_SET), this.randomState, seed, level.spigotConfig); // Spigot
|
||||
this.mainThreadExecutor = mainThreadExecutor;
|
||||
ConsecutiveExecutor consecutiveExecutor = new ConsecutiveExecutor(dispatcher, "worldgen");
|
||||
this.progressListener = progressListener;
|
||||
@@ -207,6 +240,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.chunksToEagerlySave.add(chunkPos.toLong());
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public int getMobCountNear(final ServerPlayer player, final net.minecraft.world.entity.MobCategory mobCategory) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
protected ChunkGenerator generator() {
|
||||
return this.worldGenContext.generator();
|
||||
}
|
||||
@@ -354,9 +393,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
);
|
||||
stringBuilder.append("Updating:").append(System.lineSeparator());
|
||||
- this.updatingChunkMap.values().forEach(consumer);
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().getUpdatingChunkHolders(this.level).forEach(consumer); // Paper
|
||||
stringBuilder.append("Visible:").append(System.lineSeparator());
|
||||
- this.visibleChunkMap.values().forEach(consumer);
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level).forEach(consumer); // Paper
|
||||
CrashReport crashReport = CrashReport.forThrowable(exception, "Chunk loading");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Chunk loading");
|
||||
crashReportCategory.setDetail("Details", details);
|
||||
@@ -392,6 +431,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
holder.setTicketLevel(newLevel);
|
||||
} else {
|
||||
holder = new ChunkHolder(new ChunkPos(chunkPos), newLevel, this.level, this.lightEngine, this::onLevelChange, this);
|
||||
+ // Paper start
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderCreate(this.level, holder);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
this.updatingChunkMap.put(chunkPos, holder);
|
||||
@@ -420,8 +462,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
protected void saveAllChunks(boolean flush) {
|
||||
if (flush) {
|
||||
- List<ChunkHolder> list = this.visibleChunkMap
|
||||
- .values()
|
||||
+ List<ChunkHolder> list = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level) // Paper - moonrise
|
||||
+ //.values() // Paper - moonrise
|
||||
.stream()
|
||||
.filter(ChunkHolder::wasAccessibleSinceLastSave)
|
||||
.peek(ChunkHolder::refreshAccessibility)
|
||||
@@ -447,7 +489,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.nextChunkSaveTime.clear();
|
||||
long millis = Util.getMillis();
|
||||
|
||||
- for (ChunkHolder chunkHolder : this.visibleChunkMap.values()) {
|
||||
+ for (ChunkHolder chunkHolder : ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)) { // Paper
|
||||
this.saveChunkIfNeeded(chunkHolder, millis);
|
||||
}
|
||||
}
|
||||
@@ -468,6 +510,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
public boolean hasWork() {
|
||||
return this.lightEngine.hasLightWork()
|
||||
|| !this.pendingUnloads.isEmpty()
|
||||
+ || ca.spottedleaf.moonrise.common.PlatformHooks.get().hasAnyChunkHolders(this.level) // Paper - moonrise
|
||||
|| !this.updatingChunkMap.isEmpty()
|
||||
|| this.poiManager.hasWork()
|
||||
|| !this.toDrop.isEmpty()
|
||||
@@ -526,7 +569,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.scheduleUnload(chunkPos, chunkHolder);
|
||||
} else {
|
||||
ChunkAccess latestChunk = chunkHolder.getLatestChunk();
|
||||
- if (this.pendingUnloads.remove(chunkPos, chunkHolder) && latestChunk != null) {
|
||||
+ // Paper start
|
||||
+ boolean removed;
|
||||
+ if ((removed = this.pendingUnloads.remove(chunkPos, chunkHolder)) && latestChunk != null) {
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderDelete(this.level, chunkHolder);
|
||||
+ // Paper end
|
||||
if (latestChunk instanceof LevelChunk levelChunk) {
|
||||
levelChunk.setLoaded(false);
|
||||
}
|
||||
@@ -540,7 +587,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.lightEngine.tryScheduleUpdate();
|
||||
this.progressListener.onStatusChange(latestChunk.getPos(), null);
|
||||
this.nextChunkSaveTime.remove(latestChunk.getPos().toLong());
|
||||
- }
|
||||
+ } else if (removed) { // Paper start
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderDelete(this.level, chunkHolder);
|
||||
+ } // Paper end
|
||||
}
|
||||
}, this.unloadQueue::add).whenComplete((_void, error) -> {
|
||||
if (error != null) {
|
||||
@@ -856,7 +905,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
public int size() {
|
||||
- return this.visibleChunkMap.size();
|
||||
+ return ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolderCount(this.level); // Paper
|
||||
}
|
||||
|
||||
public net.minecraft.server.level.DistanceManager getDistanceManager() {
|
||||
@@ -864,7 +913,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
protected Iterable<ChunkHolder> getChunks() {
|
||||
- return Iterables.unmodifiableIterable(this.visibleChunkMap.values());
|
||||
+ return Iterables.unmodifiableIterable(ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)); // Paper
|
||||
}
|
||||
|
||||
void dumpChunks(Writer writer) throws IOException {
|
||||
@@ -888,10 +937,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
.build(writer);
|
||||
TickingTracker tickingTracker = this.distanceManager.tickingTracker();
|
||||
|
||||
- for (Entry<ChunkHolder> entry : this.visibleChunkMap.long2ObjectEntrySet()) {
|
||||
- long longKey = entry.getLongKey();
|
||||
+ for (ChunkHolder entry : ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)) { // Paper - Moonrise
|
||||
+ long longKey = entry.pos.toLong(); // Paper - Moonrise
|
||||
ChunkPos chunkPos = new ChunkPos(longKey);
|
||||
- ChunkHolder chunkHolder = entry.getValue();
|
||||
+ ChunkHolder chunkHolder = entry; // Paper - Moonrise
|
||||
Optional<ChunkAccess> optional = Optional.ofNullable(chunkHolder.getLatestChunk());
|
||||
Optional<LevelChunk> optional1 = optional.flatMap(chunk -> chunk instanceof LevelChunk ? Optional.of((LevelChunk)chunk) : Optional.empty());
|
||||
csvOutput.writeRow(
|
||||
@@ -931,11 +980,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
private CompletableFuture<Optional<CompoundTag>> readChunk(ChunkPos pos) {
|
||||
- return this.read(pos).thenApplyAsync(optional -> optional.map(this::upgradeChunkTag), Util.backgroundExecutor().forName("upgradeChunk"));
|
||||
+ return this.read(pos).thenApplyAsync(optional -> optional.map(tag -> upgradeChunkTag(tag, pos)), Util.backgroundExecutor().forName("upgradeChunk")); // CraftBukkit
|
||||
}
|
||||
|
||||
- private CompoundTag upgradeChunkTag(CompoundTag tag) {
|
||||
- return this.upgradeChunkTag(this.level.dimension(), this.overworldDataStorage, tag, this.generator().getTypeNameForDataFixer());
|
||||
+ // CraftBukkit start
|
||||
+ private CompoundTag upgradeChunkTag(CompoundTag tag, ChunkPos pos) {
|
||||
+ return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, tag, this.generator().getTypeNameForDataFixer(), pos, this.level);
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
void forEachSpawnCandidateChunk(Consumer<ChunkHolder> action) {
|
||||
@@ -951,12 +1002,34 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
public boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkPos) {
|
||||
- return this.distanceManager.hasPlayersNearby(chunkPos.toLong()) && this.anyPlayerCloseEnoughForSpawningInternal(chunkPos);
|
||||
+ // Spigot start
|
||||
+ return this.anyPlayerCloseEnoughForSpawning(chunkPos, false);
|
||||
+ }
|
||||
+
|
||||
+ boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkPos, boolean reducedRange) {
|
||||
+ return this.distanceManager.hasPlayersNearby(chunkPos.toLong()) && this.anyPlayerCloseEnoughForSpawningInternal(chunkPos, reducedRange);
|
||||
+ // Spigot end
|
||||
}
|
||||
|
||||
private boolean anyPlayerCloseEnoughForSpawningInternal(ChunkPos chunkPos) {
|
||||
+ // Spigot start
|
||||
+ return this.anyPlayerCloseEnoughForSpawningInternal(chunkPos, false);
|
||||
+ }
|
||||
+
|
||||
+ private boolean anyPlayerCloseEnoughForSpawningInternal(ChunkPos chunkPos, boolean reducedRange) {
|
||||
+ double blockRange; // Paper - use from event
|
||||
+ // Spigot end
|
||||
for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
|
||||
- if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos)) {
|
||||
+ // Paper start - PlayerNaturallySpawnCreaturesEvent
|
||||
+ com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event;
|
||||
+ blockRange = 16384.0D;
|
||||
+ if (reducedRange) {
|
||||
+ event = serverPlayer.playerNaturallySpawnedEvent;
|
||||
+ if (event == null || event.isCancelled()) continue;
|
||||
+ blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4));
|
||||
+ }
|
||||
+ // Paper end - PlayerNaturallySpawnCreaturesEvent
|
||||
+ if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos, blockRange)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -972,7 +1045,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
Builder<ServerPlayer> builder = ImmutableList.builder();
|
||||
|
||||
for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
|
||||
- if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos)) {
|
||||
+ if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos, 16384.0D)) { // Spigot
|
||||
builder.add(serverPlayer);
|
||||
}
|
||||
}
|
||||
@@ -981,12 +1054,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
}
|
||||
|
||||
- private boolean playerIsCloseEnoughForSpawning(ServerPlayer player, ChunkPos chunkPos) {
|
||||
+ private boolean playerIsCloseEnoughForSpawning(ServerPlayer player, ChunkPos chunkPos, double range) { // Spigot
|
||||
if (player.isSpectator()) {
|
||||
return false;
|
||||
} else {
|
||||
double d = euclideanDistanceSquared(chunkPos, player);
|
||||
- return d < 16384.0;
|
||||
+ return d < range; // Spigot
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,9 +1173,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
public void addEntity(Entity entity) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot
|
||||
+ // Paper start - ignore and warn about illegal addEntity calls instead of crashing server
|
||||
+ if (!entity.valid || entity.level() != this.level || this.entityMap.containsKey(entity.getId())) {
|
||||
+ LOGGER.error("Illegal ChunkMap::addEntity for world " + this.level.getWorld().getName()
|
||||
+ + ": " + entity + (this.entityMap.containsKey(entity.getId()) ? " ALREADY CONTAINED (This would have crashed your server)" : ""), new Throwable());
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - ignore and warn about illegal addEntity calls instead of crashing server
|
||||
+ if (entity instanceof ServerPlayer && ((ServerPlayer) entity).supressTrackerForLogin) return; // Paper - Fire PlayerJoinEvent when Player is actually ready; Delay adding to tracker until after list packets
|
||||
if (!(entity instanceof EnderDragonPart)) {
|
||||
EntityType<?> type = entity.getType();
|
||||
int i = type.clientTrackingRange() * 16;
|
||||
+ i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i); // Spigot
|
||||
if (i != 0) {
|
||||
int updateInterval = type.updateInterval();
|
||||
if (this.entityMap.containsKey(entity.getId())) {
|
||||
@@ -1126,6 +1209,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
protected void removeEntity(Entity entity) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("entity untrack"); // Spigot
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
this.updatePlayerStatus(serverPlayer, false);
|
||||
|
||||
@@ -1230,7 +1314,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
});
|
||||
}
|
||||
|
||||
- class DistanceManager extends net.minecraft.server.level.DistanceManager {
|
||||
+ public class DistanceManager extends net.minecraft.server.level.DistanceManager { // Paper - public
|
||||
protected DistanceManager(final Executor dispatcher, final Executor mainThreadExecutor) {
|
||||
super(dispatcher, mainThreadExecutor);
|
||||
}
|
||||
@@ -1258,10 +1342,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
final Entity entity;
|
||||
private final int range;
|
||||
SectionPos lastSectionPos;
|
||||
- public final Set<ServerPlayerConnection> seenBy = Sets.newIdentityHashSet();
|
||||
+ public final Set<ServerPlayerConnection> seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
|
||||
|
||||
public TrackedEntity(final Entity entity, final int range, final int updateInterval, final boolean trackDelta) {
|
||||
- this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, updateInterval, trackDelta, this::broadcast);
|
||||
+ this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, updateInterval, trackDelta, this::broadcast, this.seenBy); // CraftBukkit
|
||||
this.entity = entity;
|
||||
this.range = range;
|
||||
this.lastSectionPos = SectionPos.of(entity);
|
||||
@@ -1297,24 +1381,47 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
public void removePlayer(ServerPlayer player) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot
|
||||
if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePlayer(ServerPlayer player) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
|
||||
if (player != this.entity) {
|
||||
- Vec3 vec3 = player.position().subtract(this.entity.position());
|
||||
+ // Paper start - remove allocation of Vec3D here
|
||||
+ // Vec3 vec3 = player.position().subtract(this.entity.position());
|
||||
+ double vec3_dx = player.getX() - this.entity.getX();
|
||||
+ double vec3_dz = player.getZ() - this.entity.getZ();
|
||||
+ // Paper end - remove allocation of Vec3D here
|
||||
int playerViewDistance = ChunkMap.this.getPlayerViewDistance(player);
|
||||
double d = Math.min(this.getEffectiveRange(), playerViewDistance * 16);
|
||||
- double d1 = vec3.x * vec3.x + vec3.z * vec3.z;
|
||||
+ double d1 = vec3_dx * vec3_dx + vec3_dz * vec3_dz; // Paper
|
||||
double d2 = d * d;
|
||||
- boolean flag = d1 <= d2
|
||||
- && this.entity.broadcastToPlayer(player)
|
||||
- && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
|
||||
+ // Paper start - Configurable entity tracking range by Y
|
||||
+ boolean flag = d1 <= d2;
|
||||
+ if (flag && level.paperConfig().entities.trackingRangeY.enabled) {
|
||||
+ double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||
+ if (rangeY != -1) {
|
||||
+ double vec3_dy = player.getY() - this.entity.getY();
|
||||
+ flag = vec3_dy * vec3_dy <= rangeY * rangeY;
|
||||
+ }
|
||||
+ }
|
||||
+ flag = flag && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
|
||||
+ // Paper end - Configurable entity tracking range by Y
|
||||
+ // CraftBukkit start - respect vanish API
|
||||
+ if (flag && !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Paper - only consider hits
|
||||
+ flag = false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (flag) {
|
||||
if (this.seenBy.add(player.connection)) {
|
||||
+ // Paper start - entity tracking events
|
||||
+ if (io.papermc.paper.event.player.PlayerTrackEntityEvent.getHandlerList().getRegisteredListeners().length == 0 || new io.papermc.paper.event.player.PlayerTrackEntityEvent(player.getBukkitEntity(), this.entity.getBukkitEntity()).callEvent()) {
|
||||
this.serverEntity.addPairing(player);
|
||||
+ }
|
||||
+ // Paper end - entity tracking events
|
||||
}
|
||||
} else if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
@@ -1331,6 +1438,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
for (Entity entity : this.entity.getIndirectPassengers()) {
|
||||
int i1 = entity.getType().clientTrackingRange() * 16;
|
||||
+ i1 = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i1); // Paper
|
||||
if (i1 > i) {
|
||||
i = i1;
|
||||
}
|
||||
+60
-54
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 969ed16b60e4a4e3b656f44823bceee7fe215890..f45fb8ddb08d82ce76018b5a5c4fce5b3b319559 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -182,7 +_,7 @@
|
||||
@@ -182,7 +182,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
final List<ServerPlayer> players = Lists.newArrayList();
|
||||
public final ServerChunkCache chunkSource;
|
||||
private final MinecraftServer server;
|
||||
@@ -9,7 +17,7 @@
|
||||
private int lastSpawnChunkRadius;
|
||||
final EntityTickList entityTickList = new EntityTickList();
|
||||
public final PersistentEntitySectionManager<Entity> entityManager;
|
||||
@@ -209,11 +_,132 @@
|
||||
@@ -209,11 +209,132 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
private final boolean tickTime;
|
||||
private final RandomSequences randomSequences;
|
||||
|
||||
@@ -143,7 +151,7 @@
|
||||
ResourceKey<Level> dimension,
|
||||
LevelStem levelStem,
|
||||
ChunkProgressListener progressListener,
|
||||
@@ -221,14 +_,38 @@
|
||||
@@ -221,14 +342,38 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
long biomeZoomSeed,
|
||||
List<CustomSpawner> customSpawners,
|
||||
boolean tickTime,
|
||||
@@ -184,7 +192,7 @@
|
||||
boolean flag = server.forceSynchronousWrites();
|
||||
DataFixer fixerUpper = server.getFixerUpper();
|
||||
EntityPersistentStorage<Entity> entityPersistentStorage = new EntityStorage(
|
||||
@@ -250,8 +_,8 @@
|
||||
@@ -250,8 +395,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
server.getStructureManager(),
|
||||
dispatcher,
|
||||
chunkGenerator,
|
||||
@@ -195,7 +203,7 @@
|
||||
flag,
|
||||
progressListener,
|
||||
this.entityManager::updateChunkStatus,
|
||||
@@ -272,7 +_,7 @@
|
||||
@@ -272,7 +417,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.chunkSource.chunkScanner(),
|
||||
this.registryAccess(),
|
||||
server.getStructureManager(),
|
||||
@@ -204,7 +212,7 @@
|
||||
chunkGenerator,
|
||||
this.chunkSource.randomState(),
|
||||
this,
|
||||
@@ -280,9 +_,9 @@
|
||||
@@ -280,9 +425,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
seed,
|
||||
fixerUpper
|
||||
);
|
||||
@@ -217,11 +225,10 @@
|
||||
} else {
|
||||
this.dragonFight = null;
|
||||
}
|
||||
@@ -292,7 +_,15 @@
|
||||
@@ -292,7 +437,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.randomSequences = Objects.requireNonNullElseGet(
|
||||
randomSequences, () -> this.getDataStorage().computeIfAbsent(RandomSequences.factory(seed), "random_sequences")
|
||||
);
|
||||
- }
|
||||
+ this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
+ }
|
||||
+
|
||||
@@ -229,12 +236,12 @@
|
||||
+ @Override
|
||||
+ public boolean hasChunk(int chunkX, int chunkZ) {
|
||||
+ return this.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ) != null;
|
||||
+ }
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
@Deprecated
|
||||
@VisibleForTesting
|
||||
@@ -304,8 +_,8 @@
|
||||
@@ -304,8 +457,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.serverLevelData.setClearWeatherTime(clearTime);
|
||||
this.serverLevelData.setRainTime(weatherTime);
|
||||
this.serverLevelData.setThunderTime(weatherTime);
|
||||
@@ -245,7 +252,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -332,12 +_,25 @@
|
||||
@@ -332,12 +485,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
int _int = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE);
|
||||
if (this.sleepStatus.areEnoughSleeping(_int) && this.sleepStatus.areEnoughDeepSleeping(_int, this.players)) {
|
||||
@@ -274,7 +281,7 @@
|
||||
if (this.getGameRules().getBoolean(GameRules.RULE_WEATHER_CYCLE) && this.isRaining()) {
|
||||
this.resetWeatherCycle();
|
||||
}
|
||||
@@ -352,9 +_,9 @@
|
||||
@@ -352,9 +518,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (!this.isDebug() && runsNormally) {
|
||||
long l = this.getGameTime();
|
||||
profilerFiller.push("blockTicks");
|
||||
@@ -286,7 +293,7 @@
|
||||
profilerFiller.pop();
|
||||
}
|
||||
|
||||
@@ -372,7 +_,7 @@
|
||||
@@ -372,7 +538,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
this.handlingTick = false;
|
||||
profilerFiller.pop();
|
||||
@@ -295,7 +302,7 @@
|
||||
if (flag) {
|
||||
this.resetEmptyTime();
|
||||
}
|
||||
@@ -461,12 +_,12 @@
|
||||
@@ -461,12 +627,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
int minBlockZ = pos.getMinBlockZ();
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("thunder");
|
||||
@@ -310,7 +317,7 @@
|
||||
&& !this.getBlockState(blockPos.below()).is(Blocks.LIGHTNING_ROD);
|
||||
if (flag) {
|
||||
SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT);
|
||||
@@ -474,7 +_,7 @@
|
||||
@@ -474,7 +640,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
skeletonHorse.setTrap(true);
|
||||
skeletonHorse.setAge(0);
|
||||
skeletonHorse.setPos(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||
@@ -319,7 +326,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,18 +_,20 @@
|
||||
@@ -482,18 +648,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (lightningBolt != null) {
|
||||
lightningBolt.moveTo(Vec3.atBottomCenterOf(blockPos));
|
||||
lightningBolt.setVisualOnly(flag);
|
||||
@@ -341,7 +348,7 @@
|
||||
|
||||
profilerFiller.popPush("tickBlocks");
|
||||
if (randomTickSpeed > 0) {
|
||||
@@ -535,7 +_,7 @@
|
||||
@@ -535,7 +703,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
BlockPos blockPos1 = heightmapPos.below();
|
||||
Biome biome = this.getBiome(heightmapPos).value();
|
||||
if (biome.shouldFreeze(this, blockPos1)) {
|
||||
@@ -350,7 +357,7 @@
|
||||
}
|
||||
|
||||
if (this.isRaining()) {
|
||||
@@ -547,10 +_,10 @@
|
||||
@@ -547,10 +715,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (layersValue < Math.min(_int, 8)) {
|
||||
BlockState blockState1 = blockState.setValue(SnowLayerBlock.LAYERS, Integer.valueOf(layersValue + 1));
|
||||
Block.pushEntitiesUp(blockState, blockState1, this, heightmapPos);
|
||||
@@ -363,7 +370,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -575,6 +_,11 @@
|
||||
@@ -575,6 +743,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
protected BlockPos findLightningTargetAround(BlockPos pos) {
|
||||
@@ -375,7 +382,7 @@
|
||||
BlockPos heightmapPos = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
|
||||
Optional<BlockPos> optional = this.findLightningRod(heightmapPos);
|
||||
if (optional.isPresent()) {
|
||||
@@ -582,11 +_,12 @@
|
||||
@@ -582,11 +755,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
} else {
|
||||
AABB aabb = AABB.encapsulatingFullBlocks(heightmapPos, heightmapPos.atY(this.getMaxY() + 1)).inflate(3.0);
|
||||
List<LivingEntity> entitiesOfClass = this.getEntitiesOfClass(
|
||||
@@ -389,7 +396,7 @@
|
||||
if (heightmapPos.getY() == this.getMinY() - 1) {
|
||||
heightmapPos = heightmapPos.above(2);
|
||||
}
|
||||
@@ -673,8 +_,8 @@
|
||||
@@ -673,8 +847,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.serverLevelData.setThunderTime(thunderTime);
|
||||
this.serverLevelData.setRainTime(rainTime);
|
||||
this.serverLevelData.setClearWeatherTime(clearWeatherTime);
|
||||
@@ -400,7 +407,7 @@
|
||||
}
|
||||
|
||||
this.oThunderLevel = this.thunderLevel;
|
||||
@@ -695,6 +_,7 @@
|
||||
@@ -695,6 +869,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.rainLevel = Mth.clamp(this.rainLevel, 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
@@ -408,7 +415,7 @@
|
||||
if (this.oRainLevel != this.rainLevel) {
|
||||
this.server
|
||||
.getPlayerList()
|
||||
@@ -717,14 +_,47 @@
|
||||
@@ -717,14 +892,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.RAIN_LEVEL_CHANGE, this.rainLevel));
|
||||
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, this.thunderLevel));
|
||||
}
|
||||
@@ -460,7 +467,7 @@
|
||||
}
|
||||
|
||||
public void resetEmptyTime() {
|
||||
@@ -746,18 +_,46 @@
|
||||
@@ -746,18 +954,46 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,7 +514,7 @@
|
||||
}
|
||||
|
||||
private void tickPassenger(Entity ridingEntity, Entity passengerEntity) {
|
||||
@@ -766,10 +_,12 @@
|
||||
@@ -766,10 +1002,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
} else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) {
|
||||
passengerEntity.setOldPosAndRot();
|
||||
passengerEntity.tickCount++;
|
||||
@@ -520,7 +527,7 @@
|
||||
profilerFiller.pop();
|
||||
|
||||
for (Entity entity : passengerEntity.getPassengers()) {
|
||||
@@ -786,6 +_,7 @@
|
||||
@@ -786,6 +1024,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) {
|
||||
ServerChunkCache chunkSource = this.getChunkSource();
|
||||
if (!skipSave) {
|
||||
@@ -528,7 +535,7 @@
|
||||
if (progress != null) {
|
||||
progress.progressStartNoAbort(Component.translatable("menu.savingLevel"));
|
||||
}
|
||||
@@ -802,11 +_,19 @@
|
||||
@@ -802,11 +1041,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.entityManager.autoSave();
|
||||
}
|
||||
}
|
||||
@@ -549,7 +556,7 @@
|
||||
}
|
||||
|
||||
DimensionDataStorage dataStorage = this.getChunkSource().getDataStorage();
|
||||
@@ -871,18 +_,40 @@
|
||||
@@ -871,18 +1118,40 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
@Override
|
||||
public boolean addFreshEntity(Entity entity) {
|
||||
@@ -593,7 +600,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -905,40 +_,119 @@
|
||||
@@ -905,40 +1174,119 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.entityManager.addNewEntity(player);
|
||||
}
|
||||
|
||||
@@ -667,7 +674,6 @@
|
||||
|
||||
public void removePlayerImmediately(ServerPlayer player, Entity.RemovalReason reason) {
|
||||
- player.remove(reason);
|
||||
- }
|
||||
+ player.remove(reason, null); // CraftBukkit - add Bukkit remove cause
|
||||
+ }
|
||||
+
|
||||
@@ -684,7 +690,7 @@
|
||||
+ }
|
||||
+
|
||||
+ return this.addFreshEntity(entitylightning);
|
||||
+ }
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
|
||||
@Override
|
||||
@@ -718,7 +724,7 @@
|
||||
if (d * d + d1 * d1 + d2 * d2 < 1024.0) {
|
||||
serverPlayer.connection.send(new ClientboundBlockDestructionPacket(breakerId, pos, progress));
|
||||
}
|
||||
@@ -1000,7 +_,7 @@
|
||||
@@ -1000,7 +1348,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
public void levelEvent(@Nullable Player player, int type, BlockPos pos, int data) {
|
||||
this.server
|
||||
.getPlayerList()
|
||||
@@ -727,7 +733,7 @@
|
||||
}
|
||||
|
||||
public int getLogicalHeight() {
|
||||
@@ -1009,6 +_,11 @@
|
||||
@@ -1009,6 +1357,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
@Override
|
||||
public void gameEvent(Holder<GameEvent> gameEvent, Vec3 pos, GameEvent.Context context) {
|
||||
@@ -739,7 +745,7 @@
|
||||
this.gameEventDispatcher.post(gameEvent, pos, context);
|
||||
}
|
||||
|
||||
@@ -1021,17 +_,28 @@
|
||||
@@ -1021,17 +1374,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
this.getChunkSource().blockChanged(pos);
|
||||
this.pathTypesByPosCache.invalidate(pos);
|
||||
@@ -768,7 +774,7 @@
|
||||
|
||||
try {
|
||||
this.isUpdatingNavigations = true;
|
||||
@@ -1043,15 +_,18 @@
|
||||
@@ -1043,15 +1407,18 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.isUpdatingNavigations = false;
|
||||
}
|
||||
}
|
||||
@@ -787,7 +793,7 @@
|
||||
this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, block, null, orientation);
|
||||
}
|
||||
|
||||
@@ -1100,6 +_,42 @@
|
||||
@@ -1100,6 +1467,42 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
ParticleOptions largeExplosionParticles,
|
||||
Holder<SoundEvent> explosionSound
|
||||
) {
|
||||
@@ -830,7 +836,7 @@
|
||||
Explosion.BlockInteraction blockInteraction = switch (explosionInteraction) {
|
||||
case NONE -> Explosion.BlockInteraction.KEEP;
|
||||
case BLOCK -> this.getDestroyType(GameRules.RULE_BLOCK_EXPLOSION_DROP_DECAY);
|
||||
@@ -1108,10 +_,17 @@
|
||||
@@ -1108,10 +1511,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
: Explosion.BlockInteraction.KEEP;
|
||||
case TNT -> this.getDestroyType(GameRules.RULE_TNT_EXPLOSION_DROP_DECAY);
|
||||
case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK;
|
||||
@@ -848,7 +854,7 @@
|
||||
ParticleOptions particleOptions = serverExplosion.isSmall() ? smallExplosionParticles : largeExplosionParticles;
|
||||
|
||||
for (ServerPlayer serverPlayer : this.players) {
|
||||
@@ -1120,6 +_,8 @@
|
||||
@@ -1120,6 +1530,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
serverPlayer.connection.send(new ClientboundExplodePacket(vec3, optional, particleOptions, explosionSound));
|
||||
}
|
||||
}
|
||||
@@ -857,7 +863,7 @@
|
||||
}
|
||||
|
||||
private Explosion.BlockInteraction getDestroyType(GameRules.Key<GameRules.BooleanValue> decayGameRule) {
|
||||
@@ -1190,7 +_,7 @@
|
||||
@@ -1190,7 +1602,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
public <T extends ParticleOptions> int sendParticles(
|
||||
T type, double posX, double posY, double posZ, int particleCount, double xOffset, double yOffset, double zOffset, double speed
|
||||
) {
|
||||
@@ -866,7 +872,7 @@
|
||||
}
|
||||
|
||||
public <T extends ParticleOptions> int sendParticles(
|
||||
@@ -1206,13 +_,49 @@
|
||||
@@ -1206,13 +1618,49 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
double zOffset,
|
||||
double speed
|
||||
) {
|
||||
@@ -918,7 +924,7 @@
|
||||
if (this.sendParticles(serverPlayer, overrideLimiter, posX, posY, posZ, clientboundLevelParticlesPacket)) {
|
||||
i++;
|
||||
}
|
||||
@@ -1280,7 +_,7 @@
|
||||
@@ -1280,7 +1728,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
@Nullable
|
||||
public BlockPos findNearestMapStructure(TagKey<Structure> structureTag, BlockPos pos, int radius, boolean skipExistingChunks) {
|
||||
@@ -927,7 +933,7 @@
|
||||
return null;
|
||||
} else {
|
||||
Optional<HolderSet.Named<Structure>> optional = this.registryAccess().lookupOrThrow(Registries.STRUCTURE).get(structureTag);
|
||||
@@ -1327,11 +_,38 @@
|
||||
@@ -1327,11 +1775,38 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@Nullable
|
||||
@Override
|
||||
public MapItemSavedData getMapData(MapId mapId) {
|
||||
@@ -967,7 +973,7 @@
|
||||
this.getServer().overworld().getDataStorage().set(mapId.key(), mapData);
|
||||
}
|
||||
|
||||
@@ -1344,17 +_,27 @@
|
||||
@@ -1344,17 +1819,27 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
BlockPos spawnPos = this.levelData.getSpawnPos();
|
||||
float spawnAngle = this.levelData.getSpawnAngle();
|
||||
if (!spawnPos.equals(pos) || spawnAngle != angle) {
|
||||
@@ -997,7 +1003,7 @@
|
||||
}
|
||||
|
||||
this.lastSpawnChunkRadius = i;
|
||||
@@ -1403,6 +_,11 @@
|
||||
@@ -1403,6 +1888,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
DebugPackets.sendPoiRemovedPacket(this, blockPos);
|
||||
}));
|
||||
optional1.ifPresent(poiType -> this.getServer().execute(() -> {
|
||||
@@ -1009,7 +1015,7 @@
|
||||
this.getPoiManager().add(blockPos, (Holder<PoiType>)poiType);
|
||||
DebugPackets.sendPoiAddedPacket(this, blockPos);
|
||||
}));
|
||||
@@ -1543,6 +_,11 @@
|
||||
@@ -1543,6 +2033,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@Override
|
||||
public void blockUpdated(BlockPos pos, Block block) {
|
||||
if (!this.isDebug()) {
|
||||
@@ -1021,7 +1027,7 @@
|
||||
this.updateNeighborsAt(pos, block);
|
||||
}
|
||||
}
|
||||
@@ -1562,12 +_,12 @@
|
||||
@@ -1562,12 +2057,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
public boolean isFlat() {
|
||||
@@ -1036,7 +1042,7 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1618,6 +_,7 @@
|
||||
@@ -1618,6 +2113,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
@Override
|
||||
public LevelEntityGetter<Entity> getEntities() {
|
||||
@@ -1044,7 +1050,7 @@
|
||||
return this.entityManager.getEntityGetter();
|
||||
}
|
||||
|
||||
@@ -1699,6 +_,27 @@
|
||||
@@ -1699,6 +2195,27 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
return this.serverLevelData.getGameRules();
|
||||
}
|
||||
|
||||
@@ -1072,7 +1078,7 @@
|
||||
@Override
|
||||
public CrashReportCategory fillReportDetails(CrashReport report) {
|
||||
CrashReportCategory crashReportCategory = super.fillReportDetails(report);
|
||||
@@ -1714,6 +_,7 @@
|
||||
@@ -1714,6 +2231,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
final class EntityCallbacks implements LevelCallback<Entity> {
|
||||
@Override
|
||||
public void onCreated(Entity entity) {
|
||||
@@ -1080,7 +1086,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1723,24 +_,32 @@
|
||||
@@ -1723,24 +2241,32 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
@Override
|
||||
public void onTickingStart(Entity entity) {
|
||||
@@ -1115,7 +1121,7 @@
|
||||
String string = "onTrackingStart called during navigation iteration";
|
||||
Util.logAndPauseIfInIde(
|
||||
"onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")
|
||||
@@ -1757,10 +_,52 @@
|
||||
@@ -1757,10 +2283,52 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::add);
|
||||
@@ -1168,7 +1174,7 @@
|
||||
ServerLevel.this.getChunkSource().removeEntity(entity);
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.remove(serverPlayer);
|
||||
@@ -1768,7 +_,7 @@
|
||||
@@ -1768,7 +2336,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
if (entity instanceof Mob mob) {
|
||||
@@ -1177,7 +1183,7 @@
|
||||
String string = "onTrackingStart called during navigation iteration";
|
||||
Util.logAndPauseIfInIde(
|
||||
"onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")
|
||||
@@ -1785,6 +_,15 @@
|
||||
@@ -1785,6 +2353,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::remove);
|
||||
@@ -1193,7 +1199,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1792,4 +_,24 @@
|
||||
@@ -1792,4 +2369,24 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::move);
|
||||
}
|
||||
}
|
||||
+82
-75
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index ae499e8589f51d910976c614f6c11ff19f7b69ff..f054ea710108e5017bc48fdda5f180a04f5b55e2 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -223,7 +_,8 @@
|
||||
@@ -223,7 +223,8 @@ public class ServerPlayer extends Player {
|
||||
private int levitationStartTime;
|
||||
private boolean disconnected;
|
||||
private int requestedViewDistance = 2;
|
||||
@@ -10,7 +18,7 @@
|
||||
@Nullable
|
||||
private Vec3 startingToFallPosition;
|
||||
@Nullable
|
||||
@@ -258,6 +_,13 @@
|
||||
@@ -258,6 +259,13 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +32,7 @@
|
||||
@Override
|
||||
public void sendSlotChange(AbstractContainerMenu container, int slot, ItemStack itemStack) {
|
||||
ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(container.containerId, container.incrementStateId(), slot, itemStack));
|
||||
@@ -288,6 +_,32 @@
|
||||
@@ -288,6 +296,32 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +65,7 @@
|
||||
@Override
|
||||
public void dataChanged(AbstractContainerMenu containerMenu, int dataSlotIndex, int value) {
|
||||
}
|
||||
@@ -316,9 +_,43 @@
|
||||
@@ -316,9 +350,43 @@ public class ServerPlayer extends Player {
|
||||
public void sendSystemMessage(Component component) {
|
||||
ServerPlayer.this.sendSystemMessage(component);
|
||||
}
|
||||
@@ -101,7 +109,7 @@
|
||||
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) {
|
||||
super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile);
|
||||
@@ -328,16 +_,22 @@
|
||||
@@ -328,16 +396,22 @@ public class ServerPlayer extends Player {
|
||||
this.server = server;
|
||||
this.stats = server.getPlayerList().getPlayerStats(this);
|
||||
this.advancements = server.getPlayerList().getPlayerAdvancements(this);
|
||||
@@ -127,7 +135,7 @@
|
||||
int max = Math.max(0, this.server.getSpawnRadius(level));
|
||||
int floor = Mth.floor(level.getWorldBorder().getDistanceToBorder(pos.getX(), pos.getZ()));
|
||||
if (floor < max) {
|
||||
@@ -420,11 +_,20 @@
|
||||
@@ -420,11 +494,20 @@ public class ServerPlayer extends Player {
|
||||
if (compound.contains("recipeBook", 10)) {
|
||||
this.recipeBook.fromNbt(compound.getCompound("recipeBook"), key -> this.server.getRecipeManager().byKey(key).isPresent());
|
||||
}
|
||||
@@ -148,7 +156,7 @@
|
||||
if (compound.contains("SpawnX", 99) && compound.contains("SpawnY", 99) && compound.contains("SpawnZ", 99)) {
|
||||
this.respawnPosition = new BlockPos(compound.getInt("SpawnX"), compound.getInt("SpawnY"), compound.getInt("SpawnZ"));
|
||||
this.respawnForced = compound.getBoolean("SpawnForced");
|
||||
@@ -475,6 +_,7 @@
|
||||
@@ -475,6 +558,7 @@ public class ServerPlayer extends Player {
|
||||
.resultOrPartial(LOGGER::error)
|
||||
.ifPresent(spawnDimension -> compound.put("SpawnDimension", spawnDimension));
|
||||
}
|
||||
@@ -156,7 +164,7 @@
|
||||
|
||||
compound.putBoolean("spawn_extra_particles_on_fall", this.spawnExtraParticlesOnFall);
|
||||
if (this.raidOmenPosition != null) {
|
||||
@@ -490,7 +_,18 @@
|
||||
@@ -490,7 +574,18 @@ public class ServerPlayer extends Player {
|
||||
private void saveParentVehicle(CompoundTag tag) {
|
||||
Entity rootVehicle = this.getRootVehicle();
|
||||
Entity vehicle = this.getVehicle();
|
||||
@@ -176,7 +184,7 @@
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
CompoundTag compoundTag1 = new CompoundTag();
|
||||
rootVehicle.save(compoundTag1);
|
||||
@@ -504,7 +_,7 @@
|
||||
@@ -504,7 +599,7 @@ public class ServerPlayer extends Player {
|
||||
if (tag.isPresent() && tag.get().contains("RootVehicle", 10) && this.level() instanceof ServerLevel serverLevel) {
|
||||
CompoundTag compound = tag.get().getCompound("RootVehicle");
|
||||
Entity entity = EntityType.loadEntityRecursive(
|
||||
@@ -185,7 +193,7 @@
|
||||
);
|
||||
if (entity == null) {
|
||||
return;
|
||||
@@ -530,10 +_,10 @@
|
||||
@@ -530,10 +625,10 @@ public class ServerPlayer extends Player {
|
||||
|
||||
if (!this.isPassenger()) {
|
||||
LOGGER.warn("Couldn't reattach entity to player");
|
||||
@@ -198,7 +206,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -544,6 +_,7 @@
|
||||
@@ -544,6 +639,7 @@ public class ServerPlayer extends Player {
|
||||
ListTag listTag = new ListTag();
|
||||
|
||||
for (ThrownEnderpearl thrownEnderpearl : this.enderPearls) {
|
||||
@@ -206,7 +214,7 @@
|
||||
if (thrownEnderpearl.isRemoved()) {
|
||||
LOGGER.warn("Trying to save removed ender pearl, skipping");
|
||||
} else {
|
||||
@@ -593,6 +_,16 @@
|
||||
@@ -593,6 +689,16 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +231,7 @@
|
||||
public void setExperiencePoints(int experiencePoints) {
|
||||
float f = this.getXpNeededForNextLevel();
|
||||
float f1 = (f - 1.0F) / f;
|
||||
@@ -650,6 +_,11 @@
|
||||
@@ -650,6 +756,11 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
@@ -235,7 +243,7 @@
|
||||
this.tickClientLoadTimeout();
|
||||
this.gameMode.tick();
|
||||
this.wardenSpawnTracker.tick();
|
||||
@@ -657,9 +_,14 @@
|
||||
@@ -657,9 +768,14 @@ public class ServerPlayer extends Player {
|
||||
this.invulnerableTime--;
|
||||
}
|
||||
|
||||
@@ -253,7 +261,7 @@
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -709,7 +_,7 @@
|
||||
@@ -709,7 +825,7 @@ public class ServerPlayer extends Player {
|
||||
|
||||
public void doTick() {
|
||||
try {
|
||||
@@ -262,7 +270,7 @@
|
||||
super.tick();
|
||||
}
|
||||
|
||||
@@ -723,7 +_,7 @@
|
||||
@@ -723,7 +839,7 @@ public class ServerPlayer extends Player {
|
||||
if (this.getHealth() != this.lastSentHealth
|
||||
|| this.lastSentFood != this.foodData.getFoodLevel()
|
||||
|| this.foodData.getSaturationLevel() == 0.0F != this.lastFoodSaturationZero) {
|
||||
@@ -271,7 +279,7 @@
|
||||
this.lastSentHealth = this.getHealth();
|
||||
this.lastSentFood = this.foodData.getFoodLevel();
|
||||
this.lastFoodSaturationZero = this.foodData.getSaturationLevel() == 0.0F;
|
||||
@@ -754,6 +_,12 @@
|
||||
@@ -754,6 +870,12 @@ public class ServerPlayer extends Player {
|
||||
this.updateScoreForCriteria(ObjectiveCriteria.EXPERIENCE, Mth.ceil((float)this.lastRecordedExperience));
|
||||
}
|
||||
|
||||
@@ -284,7 +292,7 @@
|
||||
if (this.experienceLevel != this.lastRecordedLevel) {
|
||||
this.lastRecordedLevel = this.experienceLevel;
|
||||
this.updateScoreForCriteria(ObjectiveCriteria.LEVEL, Mth.ceil((float)this.lastRecordedLevel));
|
||||
@@ -767,6 +_,21 @@
|
||||
@@ -767,6 +889,21 @@ public class ServerPlayer extends Player {
|
||||
if (this.tickCount % 20 == 0) {
|
||||
CriteriaTriggers.LOCATION.trigger(this);
|
||||
}
|
||||
@@ -306,7 +314,7 @@
|
||||
} catch (Throwable var4) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var4, "Ticking player");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Player being ticked");
|
||||
@@ -791,7 +_,7 @@
|
||||
@@ -791,7 +928,7 @@ public class ServerPlayer extends Player {
|
||||
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) {
|
||||
if (this.tickCount % 20 == 0) {
|
||||
if (this.getHealth() < this.getMaxHealth()) {
|
||||
@@ -315,15 +323,14 @@
|
||||
}
|
||||
|
||||
float saturationLevel = this.foodData.getSaturationLevel();
|
||||
@@ -840,15 +_,100 @@
|
||||
@@ -840,15 +977,100 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
private void updateScoreForCriteria(ObjectiveCriteria criteria, int points) {
|
||||
- this.getScoreboard().forAllObjectives(criteria, this, scoreAccess -> scoreAccess.set(points));
|
||||
- }
|
||||
+ this.level().getCraftServer().getScoreboardManager().forAllObjectives(criteria, this, scoreAccess -> scoreAccess.set(points)); // CraftBukkit - Use our scores instead
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ // Paper start - PlayerDeathEvent#getItemsToKeep
|
||||
+ private static void processKeep(org.bukkit.event.entity.PlayerDeathEvent event, NonNullList<ItemStack> inv) {
|
||||
+ List<org.bukkit.inventory.ItemStack> itemsToKeep = event.getItemsToKeep();
|
||||
@@ -363,7 +370,7 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - PlayerDeathEvent#getItemsToKeep
|
||||
|
||||
+
|
||||
@Override
|
||||
public void die(DamageSource cause) {
|
||||
- this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
@@ -422,7 +429,7 @@
|
||||
this.connection
|
||||
.send(
|
||||
new ClientboundPlayerCombatKillPacket(this.getId(), deathMessage),
|
||||
@@ -882,11 +_,22 @@
|
||||
@@ -882,11 +1104,22 @@ public class ServerPlayer extends Player {
|
||||
this.tellNeutralMobsThatIDied();
|
||||
}
|
||||
|
||||
@@ -448,7 +455,7 @@
|
||||
LivingEntity killCredit = this.getKillCredit();
|
||||
if (killCredit != null) {
|
||||
this.awardStat(Stats.ENTITY_KILLED_BY.get(killCredit.getType()));
|
||||
@@ -919,10 +_,10 @@
|
||||
@@ -919,10 +1152,10 @@ public class ServerPlayer extends Player {
|
||||
public void awardKillScore(Entity entity, DamageSource damageSource) {
|
||||
if (entity != this) {
|
||||
super.awardKillScore(entity, damageSource);
|
||||
@@ -461,7 +468,7 @@
|
||||
} else {
|
||||
this.awardStat(Stats.MOB_KILLS);
|
||||
}
|
||||
@@ -938,7 +_,7 @@
|
||||
@@ -938,7 +1171,7 @@ public class ServerPlayer extends Player {
|
||||
if (playersTeam != null) {
|
||||
int id = playersTeam.getColor().getId();
|
||||
if (id >= 0 && id < crtieria.length) {
|
||||
@@ -470,7 +477,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -949,9 +_,20 @@
|
||||
@@ -949,9 +1182,20 @@ public class ServerPlayer extends Player {
|
||||
return false;
|
||||
} else {
|
||||
Entity entity = damageSource.getEntity();
|
||||
@@ -493,7 +500,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -961,10 +_,15 @@
|
||||
@@ -961,10 +1205,15 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
private boolean isPvpAllowed() {
|
||||
@@ -511,7 +518,7 @@
|
||||
BlockPos respawnPosition = this.getRespawnPosition();
|
||||
float respawnAngle = this.getRespawnAngle();
|
||||
boolean isRespawnForced = this.isRespawnForced();
|
||||
@@ -973,13 +_,66 @@
|
||||
@@ -973,13 +1222,66 @@ public class ServerPlayer extends Player {
|
||||
Optional<ServerPlayer.RespawnPosAngle> optional = findRespawnAndUseSpawnBlock(level, respawnPosition, respawnAngle, isRespawnForced, useCharge);
|
||||
if (optional.isPresent()) {
|
||||
ServerPlayer.RespawnPosAngle respawnPosAngle = optional.get();
|
||||
@@ -527,13 +534,12 @@
|
||||
}
|
||||
} else {
|
||||
- return new TeleportTransition(this.server.overworld(), this, postTeleportTransition);
|
||||
- }
|
||||
+ teleportTransition = new TeleportTransition(this.server.overworld(), this, postTeleportTransition); // CraftBukkit
|
||||
+ }
|
||||
+ // CraftBukkit start
|
||||
+ if (respawnReason == null) {
|
||||
+ return teleportTransition;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ org.bukkit.entity.Player respawnPlayer = this.getBukkitEntity();
|
||||
+ org.bukkit.Location location = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(
|
||||
@@ -582,7 +588,7 @@
|
||||
}
|
||||
|
||||
public static Optional<ServerPlayer.RespawnPosAngle> findRespawnAndUseSpawnBlock(
|
||||
@@ -993,10 +_,10 @@
|
||||
@@ -993,10 +1295,10 @@ public class ServerPlayer extends Player {
|
||||
level.setBlock(pos, blockState.setValue(RespawnAnchorBlock.CHARGE, Integer.valueOf(blockState.getValue(RespawnAnchorBlock.CHARGE) - 1)), 3);
|
||||
}
|
||||
|
||||
@@ -595,7 +601,7 @@
|
||||
} else if (!forced) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
@@ -1004,7 +_,7 @@
|
||||
@@ -1004,7 +1306,7 @@ public class ServerPlayer extends Player {
|
||||
BlockState blockState1 = level.getBlockState(pos.above());
|
||||
boolean isPossibleToRespawnInThis1 = blockState1.getBlock().isPossibleToRespawnInThis(blockState1);
|
||||
return isPossibleToRespawnInThis && isPossibleToRespawnInThis1
|
||||
@@ -604,7 +610,7 @@
|
||||
: Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -1022,6 +_,7 @@
|
||||
@@ -1022,6 +1324,7 @@ public class ServerPlayer extends Player {
|
||||
@Nullable
|
||||
@Override
|
||||
public ServerPlayer teleport(TeleportTransition teleportTransition) {
|
||||
@@ -612,7 +618,7 @@
|
||||
if (this.isRemoved()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -1031,17 +_,52 @@
|
||||
@@ -1031,17 +1334,52 @@ public class ServerPlayer extends Player {
|
||||
|
||||
ServerLevel level = teleportTransition.newLevel();
|
||||
ServerLevel serverLevel = this.serverLevel();
|
||||
@@ -668,7 +674,7 @@
|
||||
this.isChangingDimension = true;
|
||||
LevelData levelData = level.getLevelData();
|
||||
this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(level), (byte)3));
|
||||
@@ -1050,16 +_,30 @@
|
||||
@@ -1050,16 +1388,30 @@ public class ServerPlayer extends Player {
|
||||
playerList.sendPlayerPermissionLevel(this);
|
||||
serverLevel.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
|
||||
this.unsetRemoved();
|
||||
@@ -701,7 +707,7 @@
|
||||
this.connection.resetPosition();
|
||||
level.addDuringTeleport(this);
|
||||
profilerFiller.pop();
|
||||
@@ -1073,10 +_,40 @@
|
||||
@@ -1073,11 +1425,41 @@ public class ServerPlayer extends Player {
|
||||
this.lastSentExp = -1;
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
@@ -720,7 +726,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ @Override
|
||||
+ public org.bukkit.craftbukkit.event.CraftPortalEvent callPortalEvent(
|
||||
@@ -739,10 +745,11 @@
|
||||
+ return new org.bukkit.craftbukkit.event.CraftPortalEvent(event);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
+
|
||||
@Override
|
||||
public void forceSetRotation(float yRot, float xRot) {
|
||||
@@ -1086,12 +_,26 @@
|
||||
this.connection.send(new ClientboundPlayerRotationPacket(yRot, xRot));
|
||||
@@ -1086,12 +1468,26 @@ public class ServerPlayer extends Player {
|
||||
public void triggerDimensionChangeTriggers(ServerLevel level) {
|
||||
ResourceKey<Level> resourceKey = level.dimension();
|
||||
ResourceKey<Level> resourceKey1 = this.level().dimension();
|
||||
@@ -772,7 +779,7 @@
|
||||
this.enteredNetherPosition = null;
|
||||
}
|
||||
}
|
||||
@@ -1107,19 +_,18 @@
|
||||
@@ -1107,19 +1503,18 @@ public class ServerPlayer extends Player {
|
||||
this.containerMenu.broadcastChanges();
|
||||
}
|
||||
|
||||
@@ -796,7 +803,7 @@
|
||||
if (this.level().isDay()) {
|
||||
return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_NOW);
|
||||
} else {
|
||||
@@ -1138,7 +_,34 @@
|
||||
@@ -1138,7 +1533,34 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,7 +839,7 @@
|
||||
this.awardStat(Stats.SLEEP_IN_BED);
|
||||
CriteriaTriggers.SLEPT_IN_BED.trigger(this);
|
||||
});
|
||||
@@ -1174,13 +_,31 @@
|
||||
@@ -1174,13 +1596,31 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void stopSleepInBed(boolean wakeImmediately, boolean updateLevelForSleepingPlayers) {
|
||||
@@ -865,7 +872,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1192,9 +_,9 @@
|
||||
@@ -1192,9 +1632,9 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public boolean isInvulnerableTo(ServerLevel level, DamageSource damageSource) {
|
||||
@@ -877,7 +884,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1237,8 +_,9 @@
|
||||
@@ -1237,8 +1677,9 @@ public class ServerPlayer extends Player {
|
||||
this.connection.send(new ClientboundOpenSignEditorPacket(signEntity.getBlockPos(), isFrontText));
|
||||
}
|
||||
|
||||
@@ -888,7 +895,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1246,12 +_,43 @@
|
||||
@@ -1246,12 +1687,43 @@ public class ServerPlayer extends Player {
|
||||
if (menu == null) {
|
||||
return OptionalInt.empty();
|
||||
} else {
|
||||
@@ -932,7 +939,7 @@
|
||||
if (abstractContainerMenu == null) {
|
||||
if (this.isSpectator()) {
|
||||
this.displayClientMessage(Component.translatable("container.spectatorCantOpen").withStyle(ChatFormatting.RED), true);
|
||||
@@ -1259,10 +_,14 @@
|
||||
@@ -1259,10 +1731,14 @@ public class ServerPlayer extends Player {
|
||||
|
||||
return OptionalInt.empty();
|
||||
} else {
|
||||
@@ -949,7 +956,7 @@
|
||||
return OptionalInt.of(this.containerCounter);
|
||||
}
|
||||
}
|
||||
@@ -1275,14 +_,25 @@
|
||||
@@ -1275,14 +1751,25 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void openHorseInventory(AbstractHorse horse, Container inventory) {
|
||||
@@ -978,7 +985,7 @@
|
||||
this.initMenu(this.containerMenu);
|
||||
}
|
||||
|
||||
@@ -1304,9 +_,28 @@
|
||||
@@ -1304,9 +1791,28 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void closeContainer() {
|
||||
@@ -1007,7 +1014,7 @@
|
||||
|
||||
@Override
|
||||
public void doCloseContainer() {
|
||||
@@ -1330,19 +_,19 @@
|
||||
@@ -1330,19 +1836,19 @@ public class ServerPlayer extends Player {
|
||||
int rounded = Math.round((float)Math.sqrt(dx * dx + dy * dy + dz * dz) * 100.0F);
|
||||
if (rounded > 0) {
|
||||
this.awardStat(Stats.SWIM_ONE_CM, rounded);
|
||||
@@ -1030,7 +1037,7 @@
|
||||
}
|
||||
} else if (this.onClimbable()) {
|
||||
if (dy > 0.0) {
|
||||
@@ -1353,13 +_,13 @@
|
||||
@@ -1353,13 +1859,13 @@ public class ServerPlayer extends Player {
|
||||
if (rounded > 0) {
|
||||
if (this.isSprinting()) {
|
||||
this.awardStat(Stats.SPRINT_ONE_CM, rounded);
|
||||
@@ -1047,7 +1054,7 @@
|
||||
}
|
||||
}
|
||||
} else if (this.isFallFlying()) {
|
||||
@@ -1399,13 +_,13 @@
|
||||
@@ -1399,13 +1905,13 @@ public class ServerPlayer extends Player {
|
||||
@Override
|
||||
public void awardStat(Stat<?> stat, int amount) {
|
||||
this.stats.increment(this, stat, amount);
|
||||
@@ -1063,7 +1070,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1436,9 +_,9 @@
|
||||
@@ -1436,9 +1942,9 @@ public class ServerPlayer extends Player {
|
||||
super.jumpFromGround();
|
||||
this.awardStat(Stats.JUMP);
|
||||
if (this.isSprinting()) {
|
||||
@@ -1075,7 +1082,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,6 +_,13 @@
|
||||
@@ -1451,6 +1957,13 @@ public class ServerPlayer extends Player {
|
||||
public void disconnect() {
|
||||
this.disconnected = true;
|
||||
this.ejectPassengers();
|
||||
@@ -1089,7 +1096,7 @@
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleepInBed(true, false);
|
||||
}
|
||||
@@ -1462,6 +_,7 @@
|
||||
@@ -1462,6 +1975,7 @@ public class ServerPlayer extends Player {
|
||||
|
||||
public void resetSentInfo() {
|
||||
this.lastSentHealth = -1.0E8F;
|
||||
@@ -1097,7 +1104,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1496,12 +_,12 @@
|
||||
@@ -1496,12 +2010,12 @@ public class ServerPlayer extends Player {
|
||||
this.onUpdateAbilities();
|
||||
if (keepEverything) {
|
||||
this.getAttributes().assignBaseValues(that.getAttributes());
|
||||
@@ -1112,7 +1119,7 @@
|
||||
}
|
||||
|
||||
this.getInventory().replaceWith(that.getInventory());
|
||||
@@ -1512,7 +_,7 @@
|
||||
@@ -1512,7 +2026,7 @@ public class ServerPlayer extends Player {
|
||||
this.portalProcess = that.portalProcess;
|
||||
} else {
|
||||
this.getAttributes().assignBaseValues(that.getAttributes());
|
||||
@@ -1121,7 +1128,7 @@
|
||||
if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || that.isSpectator()) {
|
||||
this.getInventory().replaceWith(that.getInventory());
|
||||
this.experienceLevel = that.experienceLevel;
|
||||
@@ -1528,7 +_,7 @@
|
||||
@@ -1528,7 +2042,7 @@ public class ServerPlayer extends Player {
|
||||
this.lastSentExp = -1;
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
@@ -1130,7 +1137,7 @@
|
||||
this.seenCredits = that.seenCredits;
|
||||
this.enteredNetherPosition = that.enteredNetherPosition;
|
||||
this.chunkTrackingView = that.chunkTrackingView;
|
||||
@@ -1581,7 +_,7 @@
|
||||
@@ -1581,7 +2095,7 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1139,7 +1146,7 @@
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleepInBed(true, true);
|
||||
}
|
||||
@@ -1590,7 +_,7 @@
|
||||
@@ -1590,7 +2104,7 @@ public class ServerPlayer extends Player {
|
||||
this.setCamera(this);
|
||||
}
|
||||
|
||||
@@ -1148,7 +1155,7 @@
|
||||
if (flag) {
|
||||
this.setYHeadRot(relativeMovements.contains(Relative.Y_ROT) ? this.getYHeadRot() + yaw : yaw);
|
||||
}
|
||||
@@ -1627,9 +_,17 @@
|
||||
@@ -1627,9 +2141,17 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
public boolean setGameMode(GameType gameMode) {
|
||||
@@ -1168,7 +1175,7 @@
|
||||
} else {
|
||||
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, gameMode.getId()));
|
||||
if (gameMode == GameType.SPECTATOR) {
|
||||
@@ -1645,7 +_,7 @@
|
||||
@@ -1645,7 +2167,7 @@ public class ServerPlayer extends Player {
|
||||
|
||||
this.onUpdateAbilities();
|
||||
this.updateEffectVisibility();
|
||||
@@ -1177,7 +1184,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1705,8 +_,13 @@
|
||||
@@ -1705,8 +2227,13 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
public void sendChatMessage(OutgoingChatMessage message, boolean filtered, ChatType.Bound boundType) {
|
||||
@@ -1192,7 +1199,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1717,7 +_,42 @@
|
||||
@@ -1717,7 +2244,42 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
public void updateOptions(ClientInformation clientInformation) {
|
||||
@@ -1235,7 +1242,7 @@
|
||||
this.requestedViewDistance = clientInformation.viewDistance();
|
||||
this.chatVisibility = clientInformation.chatVisibility();
|
||||
this.canChatColor = clientInformation.chatColors();
|
||||
@@ -1803,8 +_,23 @@
|
||||
@@ -1803,8 +2365,23 @@ public class ServerPlayer extends Player {
|
||||
Entity camera = this.getCamera();
|
||||
this.camera = (Entity)(entityToSpectate == null ? this : entityToSpectate);
|
||||
if (camera != this.camera) {
|
||||
@@ -1260,7 +1267,7 @@
|
||||
}
|
||||
|
||||
if (entityToSpectate != null) {
|
||||
@@ -1838,11 +_,11 @@
|
||||
@@ -1838,11 +2415,11 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Nullable
|
||||
public Component getTabListDisplayName() {
|
||||
@@ -1274,7 +1281,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1884,11 +_,56 @@
|
||||
@@ -1884,11 +2461,56 @@ public class ServerPlayer extends Player {
|
||||
this.setRespawnPosition(player.getRespawnDimension(), player.getRespawnPosition(), player.getRespawnAngle(), player.isRespawnForced(), false);
|
||||
}
|
||||
|
||||
@@ -1333,7 +1340,7 @@
|
||||
}
|
||||
|
||||
this.respawnPosition = position;
|
||||
@@ -1901,6 +_,8 @@
|
||||
@@ -1901,6 +2523,8 @@ public class ServerPlayer extends Player {
|
||||
this.respawnAngle = 0.0F;
|
||||
this.respawnForced = false;
|
||||
}
|
||||
@@ -1342,7 +1349,7 @@
|
||||
}
|
||||
|
||||
public SectionPos getLastSectionPos() {
|
||||
@@ -1930,21 +_,55 @@
|
||||
@@ -1930,21 +2554,55 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1400,7 +1407,7 @@
|
||||
return itemEntity;
|
||||
}
|
||||
}
|
||||
@@ -1955,6 +_,11 @@
|
||||
@@ -1955,6 +2613,11 @@ public class ServerPlayer extends Player {
|
||||
return null;
|
||||
} else {
|
||||
double d = this.getEyeY() - 0.3F;
|
||||
@@ -1412,7 +1419,7 @@
|
||||
ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), d, this.getZ(), droppedItem);
|
||||
itemEntity.setPickUpDelay(40);
|
||||
if (includeThrowerName) {
|
||||
@@ -2008,6 +_,16 @@
|
||||
@@ -2008,6 +2671,16 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
public void loadGameTypes(@Nullable CompoundTag tag) {
|
||||
@@ -1429,7 +1436,7 @@
|
||||
this.gameMode
|
||||
.setGameModeForPlayer(this.calculateGameModeForNewPlayer(readPlayerMode(tag, "playerGameType")), readPlayerMode(tag, "previousPlayerGameType"));
|
||||
}
|
||||
@@ -2108,8 +_,14 @@
|
||||
@@ -2108,8 +2781,14 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void stopRiding() {
|
||||
@@ -1445,7 +1452,7 @@
|
||||
if (vehicle instanceof LivingEntity livingEntity) {
|
||||
for (MobEffectInstance mobEffectInstance : livingEntity.getActiveEffects()) {
|
||||
this.connection.send(new ClientboundRemoveMobEffectPacket(vehicle.getId(), mobEffectInstance.getEffect()));
|
||||
@@ -2204,13 +_,15 @@
|
||||
@@ -2204,13 +2883,15 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
public static long placeEnderPearlTicket(ServerLevel level, ChunkPos pos) {
|
||||
@@ -1465,7 +1472,7 @@
|
||||
}
|
||||
|
||||
private static float calculateLookAtYaw(Vec3 position, BlockPos towardsPos) {
|
||||
@@ -2218,4 +_,147 @@
|
||||
@@ -2218,4 +2899,147 @@ public class ServerPlayer extends Player {
|
||||
return (float)Mth.wrapDegrees(Mth.atan2(vec3.z, vec3.x) * 180.0F / (float)Math.PI - 90.0);
|
||||
}
|
||||
}
|
||||
+28
-25
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index e64f6f68bc29f680f6f78db07e77445534e10592..47ed3ad5c0b4753f58e0bafff5e5e70b2f0bb40b 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -41,28 +_,49 @@
|
||||
@@ -41,28 +41,49 @@ public class ServerPlayerGameMode {
|
||||
private BlockPos delayedDestroyPos = BlockPos.ZERO;
|
||||
private int delayedTickStart;
|
||||
private int lastSentState = -1;
|
||||
@@ -54,7 +62,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,10 +_,11 @@
|
||||
@@ -90,10 +111,11 @@ public class ServerPlayerGameMode {
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
@@ -69,7 +77,7 @@
|
||||
this.hasDelayedDestroy = false;
|
||||
} else {
|
||||
float f = this.incrementDestroyProgress(blockState, this.delayedDestroyPos, this.delayedTickStart);
|
||||
@@ -103,7 +_,13 @@
|
||||
@@ -103,7 +125,13 @@ public class ServerPlayerGameMode {
|
||||
}
|
||||
}
|
||||
} else if (this.isDestroyingBlock) {
|
||||
@@ -84,7 +92,7 @@
|
||||
if (blockState.isAir()) {
|
||||
this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1);
|
||||
this.lastSentState = -1;
|
||||
@@ -131,6 +_,7 @@
|
||||
@@ -131,6 +159,7 @@ public class ServerPlayerGameMode {
|
||||
|
||||
public void handleBlockBreakAction(BlockPos pos, ServerboundPlayerActionPacket.Action action, Direction face, int maxBuildHeight, int sequence) {
|
||||
if (!this.player.canInteractWithBlock(pos, 1.0)) {
|
||||
@@ -92,7 +100,7 @@
|
||||
this.debugLogging(pos, false, sequence, "too far");
|
||||
} else if (pos.getY() > maxBuildHeight) {
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos)));
|
||||
@@ -138,16 +_,39 @@
|
||||
@@ -138,16 +167,39 @@ public class ServerPlayerGameMode {
|
||||
} else {
|
||||
if (action == ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK) {
|
||||
if (!this.level.mayInteract(this.player, pos)) {
|
||||
@@ -100,14 +108,12 @@
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(this.player, org.bukkit.event.block.Action.LEFT_CLICK_BLOCK, pos, face, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND);
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos)));
|
||||
this.debugLogging(pos, false, sequence, "may not interact");
|
||||
- return;
|
||||
- }
|
||||
+ // Update any tile entity data for this block
|
||||
+ this.capturedBlockEntity = true; // Paper - Send block entities after destroy prediction
|
||||
+ // CraftBukkit end
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
return;
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(this.player, org.bukkit.event.block.Action.LEFT_CLICK_BLOCK, pos, face, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND);
|
||||
+ if (event.isCancelled()) {
|
||||
@@ -118,7 +124,7 @@
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
+
|
||||
if (this.isCreative()) {
|
||||
this.destroyAndAck(pos, sequence, "creative destroy");
|
||||
return;
|
||||
@@ -134,7 +140,7 @@
|
||||
if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) {
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos)));
|
||||
this.debugLogging(pos, false, sequence, "block action restricted");
|
||||
@@ -157,7 +_,7 @@
|
||||
@@ -157,7 +209,7 @@ public class ServerPlayerGameMode {
|
||||
this.destroyProgressStart = this.gameTicks;
|
||||
float f = 1.0F;
|
||||
BlockState blockState = this.level.getBlockState(pos);
|
||||
@@ -143,7 +149,7 @@
|
||||
EnchantmentHelper.onHitBlock(
|
||||
this.level,
|
||||
this.player.getMainHandItem(),
|
||||
@@ -172,6 +_,23 @@
|
||||
@@ -172,6 +224,23 @@ public class ServerPlayerGameMode {
|
||||
f = blockState.getDestroyProgress(this.player, this.player.level(), pos);
|
||||
}
|
||||
|
||||
@@ -167,7 +173,7 @@
|
||||
if (!blockState.isAir() && f >= 1.0F) {
|
||||
this.destroyAndAck(pos, sequence, "insta mine");
|
||||
} else {
|
||||
@@ -212,14 +_,22 @@
|
||||
@@ -212,14 +281,22 @@ public class ServerPlayerGameMode {
|
||||
this.debugLogging(pos, true, sequence, "stopped destroying");
|
||||
} else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) {
|
||||
this.isDestroyingBlock = false;
|
||||
@@ -192,7 +198,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,36 +_,108 @@
|
||||
@@ -235,36 +312,108 @@ public class ServerPlayerGameMode {
|
||||
|
||||
public boolean destroyBlock(BlockPos pos) {
|
||||
BlockState blockState = this.level.getBlockState(pos);
|
||||
@@ -276,14 +282,11 @@
|
||||
mainHandItem.mineBlock(this.level, blockState1, pos, this.player);
|
||||
- if (flag && hasCorrectToolForDrops) {
|
||||
- block.playerDestroy(this.level, this.player, pos, blockState1, blockEntity, itemStack);
|
||||
- }
|
||||
-
|
||||
- return true;
|
||||
- }
|
||||
+ if (flag && hasCorrectToolForDrops) { // CraftBukkit - Check if block should drop items // Paper - fix drops not preventing stats/food exhaustion
|
||||
+ block.playerDestroy(this.level, this.player, pos, blockState1, blockEntity, itemStack, event.isDropItems(), false); // Paper - fix drops not preventing stats/food exhaustion
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
- return true;
|
||||
+ // return true; // CraftBukkit
|
||||
+ }
|
||||
+ // CraftBukkit start
|
||||
@@ -291,7 +294,7 @@
|
||||
+ this.level.captureDrops = null; // Paper - capture all item additions to the world; Remove this earlier so that we can actually drop stuff
|
||||
+ if (event.isDropItems()) {
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, itemsToDrop); // Paper - capture all item additions to the world
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ // Drop event experience
|
||||
+ if (flag) {
|
||||
@@ -310,7 +313,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,15 +_,47 @@
|
||||
@@ -307,15 +456,47 @@ public class ServerPlayerGameMode {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +363,7 @@
|
||||
return InteractionResult.CONSUME;
|
||||
} else {
|
||||
return InteractionResult.PASS;
|
||||
@@ -340,7 +_,7 @@
|
||||
@@ -340,7 +521,7 @@ public class ServerPlayerGameMode {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,7 +372,7 @@
|
||||
UseOnContext useOnContext = new UseOnContext(player, hand, hitResult);
|
||||
InteractionResult interactionResult1;
|
||||
if (this.isCreative()) {
|
||||
@@ -357,6 +_,11 @@
|
||||
@@ -357,6 +538,11 @@ public class ServerPlayerGameMode {
|
||||
|
||||
return interactionResult1;
|
||||
} else {
|
||||
+11
-3
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/item/enchantment/ItemEnchantments.java b/net/minecraft/world/item/enchantment/ItemEnchantments.java
|
||||
index 7f2568b40b5f8858d85e41732df84187d48db586..cc87a5026a65192ae1f97b2bd03a918b75df0698 100644
|
||||
--- a/net/minecraft/world/item/enchantment/ItemEnchantments.java
|
||||
+++ b/net/minecraft/world/item/enchantment/ItemEnchantments.java
|
||||
@@ -28,10 +_,19 @@
|
||||
@@ -28,10 +28,19 @@ import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.item.component.TooltipProvider;
|
||||
|
||||
public class ItemEnchantments implements TooltipProvider {
|
||||
@@ -23,7 +31,7 @@
|
||||
private static final Codec<ItemEnchantments> FULL_CODEC = RecordCodecBuilder.create(
|
||||
instance -> instance.group(
|
||||
LEVELS_CODEC.fieldOf("levels").forGetter(itemEnchantments -> itemEnchantments.enchantments),
|
||||
@@ -41,16 +_,16 @@
|
||||
@@ -41,16 +50,16 @@ public class ItemEnchantments implements TooltipProvider {
|
||||
);
|
||||
public static final Codec<ItemEnchantments> CODEC = Codec.withAlternative(FULL_CODEC, LEVELS_CODEC, map -> new ItemEnchantments(map, true));
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, ItemEnchantments> STREAM_CODEC = StreamCodec.composite(
|
||||
@@ -43,7 +51,7 @@
|
||||
this.enchantments = enchantments;
|
||||
this.showInTooltip = showInTooltip;
|
||||
|
||||
@@ -139,7 +_,7 @@
|
||||
@@ -139,7 +148,7 @@ public class ItemEnchantments implements TooltipProvider {
|
||||
}
|
||||
|
||||
public static class Mutable {
|
||||
+22
-14
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index fc3e691ebd28365ef6c13d576cb4122c1576b6ff..ce781ba2c8b3f9f051201d3809a9cb041036f93a 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -76,7 +_,7 @@
|
||||
@@ -76,7 +76,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
};
|
||||
private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = Maps.newHashMap();
|
||||
public boolean loaded;
|
||||
@@ -9,7 +17,7 @@
|
||||
@Nullable
|
||||
private Supplier<FullChunkStatus> fullStatus;
|
||||
@Nullable
|
||||
@@ -85,6 +_,14 @@
|
||||
@@ -85,6 +85,14 @@ public class LevelChunk extends ChunkAccess {
|
||||
private final LevelChunkTicks<Block> blockTicks;
|
||||
private final LevelChunkTicks<Fluid> fluidTicks;
|
||||
private LevelChunk.UnsavedListener unsavedListener = chunkPos -> {};
|
||||
@@ -24,7 +32,7 @@
|
||||
|
||||
public LevelChunk(Level level, ChunkPos pos) {
|
||||
this(level, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, null, null, null);
|
||||
@@ -102,7 +_,7 @@
|
||||
@@ -102,7 +110,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
@Nullable BlendingData blendingData
|
||||
) {
|
||||
super(pos, data, level, level.registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData);
|
||||
@@ -33,7 +41,7 @@
|
||||
this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
for (Heightmap.Types types : Heightmap.Types.values()) {
|
||||
@@ -154,6 +_,10 @@
|
||||
@@ -154,6 +162,10 @@ public class LevelChunk extends ChunkAccess {
|
||||
this.skyLightSources = chunk.skyLightSources;
|
||||
this.setLightCorrect(chunk.isLightCorrect());
|
||||
this.markUnsaved();
|
||||
@@ -44,7 +52,7 @@
|
||||
}
|
||||
|
||||
public void setUnsavedListener(LevelChunk.UnsavedListener unsavedListener) {
|
||||
@@ -162,6 +_,12 @@
|
||||
@@ -162,6 +174,12 @@ public class LevelChunk extends ChunkAccess {
|
||||
unsavedListener.setUnsaved(this.chunkPos);
|
||||
}
|
||||
}
|
||||
@@ -57,7 +65,7 @@
|
||||
|
||||
@Override
|
||||
public void markUnsaved() {
|
||||
@@ -195,8 +_,25 @@
|
||||
@@ -195,8 +213,25 @@ public class LevelChunk extends ChunkAccess {
|
||||
: super.getListenerRegistry(sectionY);
|
||||
}
|
||||
|
||||
@@ -83,7 +91,7 @@
|
||||
int x = pos.getX();
|
||||
int y = pos.getY();
|
||||
int z = pos.getZ();
|
||||
@@ -231,33 +_,54 @@
|
||||
@@ -231,33 +266,54 @@ public class LevelChunk extends ChunkAccess {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +148,7 @@
|
||||
int y = pos.getY();
|
||||
LevelChunkSection section = this.getSection(this.getSectionIndex(y));
|
||||
boolean hasOnlyAir = section.hasOnlyAir();
|
||||
@@ -292,7 +_,7 @@
|
||||
@@ -292,7 +348,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
}
|
||||
|
||||
boolean hasBlockEntity = blockState.hasBlockEntity();
|
||||
@@ -149,7 +157,7 @@
|
||||
blockState.onRemove(this.level, pos, state, isMoving);
|
||||
} else if (!blockState.is(block) && hasBlockEntity) {
|
||||
this.removeBlockEntity(pos);
|
||||
@@ -301,7 +_,7 @@
|
||||
@@ -301,7 +357,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
if (!section.getBlockState(i, i1, i2).is(block)) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -158,7 +166,7 @@
|
||||
state.onPlace(this.level, pos, blockState, isMoving);
|
||||
}
|
||||
|
||||
@@ -355,7 +_,12 @@
|
||||
@@ -355,7 +411,12 @@ public class LevelChunk extends ChunkAccess {
|
||||
|
||||
@Nullable
|
||||
public BlockEntity getBlockEntity(BlockPos pos, LevelChunk.EntityCreationType creationType) {
|
||||
@@ -172,7 +180,7 @@
|
||||
if (blockEntity == null) {
|
||||
CompoundTag compoundTag = this.pendingBlockEntities.remove(pos);
|
||||
if (compoundTag != null) {
|
||||
@@ -409,7 +_,13 @@
|
||||
@@ -409,7 +470,13 @@ public class LevelChunk extends ChunkAccess {
|
||||
BlockPos blockPos = blockEntity.getBlockPos();
|
||||
BlockState blockState = this.getBlockState(blockPos);
|
||||
if (!blockState.hasBlockEntity()) {
|
||||
@@ -187,7 +195,7 @@
|
||||
} else {
|
||||
BlockState blockState1 = blockEntity.getBlockState();
|
||||
if (blockState != blockState1) {
|
||||
@@ -457,6 +_,11 @@
|
||||
@@ -457,6 +524,11 @@ public class LevelChunk extends ChunkAccess {
|
||||
public void removeBlockEntity(BlockPos pos) {
|
||||
if (this.isInLevel()) {
|
||||
BlockEntity blockEntity = this.blockEntities.remove(pos);
|
||||
@@ -199,7 +207,7 @@
|
||||
if (blockEntity != null) {
|
||||
if (this.level instanceof ServerLevel serverLevel) {
|
||||
this.removeGameEventListener(blockEntity, serverLevel);
|
||||
@@ -499,6 +_,65 @@
|
||||
@@ -499,6 +571,65 @@ public class LevelChunk extends ChunkAccess {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +273,7 @@
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
@@ -711,23 +_,24 @@
|
||||
@@ -711,23 +842,24 @@ public class LevelChunk extends ChunkAccess {
|
||||
if (this.blockEntity.getType().isValid(blockState)) {
|
||||
this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), blockState, this.blockEntity);
|
||||
this.loggedInvalidBlockState = false;
|
||||
+21
-13
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
index d84090814956f36cacb4e1ed1e3dbad1fc8a2ab0..c7c87bc8df86ceeef3e15a8f23fc252d4cee1984 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
@@ -91,6 +_,7 @@
|
||||
@@ -91,6 +91,7 @@ public record SerializableChunkData(
|
||||
List<CompoundTag> entities,
|
||||
List<CompoundTag> blockEntities,
|
||||
CompoundTag structureData
|
||||
@@ -8,7 +16,7 @@
|
||||
) {
|
||||
public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(
|
||||
Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState()
|
||||
@@ -107,12 +_,39 @@
|
||||
@@ -107,12 +108,39 @@ public record SerializableChunkData(
|
||||
public static final String BLOCK_LIGHT_TAG = "BlockLight";
|
||||
public static final String SKY_LIGHT_TAG = "SkyLight";
|
||||
|
||||
@@ -49,7 +57,7 @@
|
||||
long _long = tag.getLong("LastUpdate");
|
||||
long _long1 = tag.getLong("InhabitedTime");
|
||||
ChunkStatus chunkStatus = ChunkStatus.byName(tag.getString("Status"));
|
||||
@@ -181,7 +_,7 @@
|
||||
@@ -181,7 +209,7 @@ public record SerializableChunkData(
|
||||
ListTag list7 = tag.getList("sections", 10);
|
||||
List<SerializableChunkData.SectionData> list8 = new ArrayList<>(list7.size());
|
||||
Registry<Biome> registry = registries.lookupOrThrow(Registries.BIOME);
|
||||
@@ -58,7 +66,7 @@
|
||||
|
||||
for (int i2 = 0; i2 < list7.size(); i2++) {
|
||||
CompoundTag compound2 = list7.getCompound(i2);
|
||||
@@ -199,7 +_,7 @@
|
||||
@@ -199,7 +227,7 @@ public record SerializableChunkData(
|
||||
);
|
||||
}
|
||||
|
||||
@@ -67,7 +75,7 @@
|
||||
if (compound2.contains("biomes", 10)) {
|
||||
palettedContainerRo = codec.parse(NbtOps.INSTANCE, compound2.getCompound("biomes"))
|
||||
.promotePartial(string -> logErrors(chunkPos, _byte, string))
|
||||
@@ -239,6 +_,7 @@
|
||||
@@ -239,6 +267,7 @@ public record SerializableChunkData(
|
||||
list5,
|
||||
list6,
|
||||
compound1
|
||||
@@ -75,7 +83,7 @@
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -316,6 +_,12 @@
|
||||
@@ -316,6 +345,12 @@ public record SerializableChunkData(
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +96,7 @@
|
||||
chunkAccess.setLightCorrect(this.lightCorrect);
|
||||
EnumSet<Heightmap.Types> set = EnumSet.noneOf(Heightmap.Types.class);
|
||||
|
||||
@@ -346,6 +_,13 @@
|
||||
@@ -346,6 +381,13 @@ public record SerializableChunkData(
|
||||
}
|
||||
|
||||
for (CompoundTag compoundTag : this.blockEntities) {
|
||||
@@ -102,7 +110,7 @@
|
||||
protoChunk1.setBlockEntityNbt(compoundTag);
|
||||
}
|
||||
|
||||
@@ -370,6 +_,12 @@
|
||||
@@ -370,6 +412,12 @@ public record SerializableChunkData(
|
||||
);
|
||||
}
|
||||
|
||||
@@ -115,7 +123,7 @@
|
||||
public static SerializableChunkData copyOf(ServerLevel level, ChunkAccess chunk) {
|
||||
if (!chunk.canBeSerialized()) {
|
||||
throw new IllegalArgumentException("Chunk can't be serialized: " + chunk);
|
||||
@@ -428,6 +_,12 @@
|
||||
@@ -428,6 +476,12 @@ public record SerializableChunkData(
|
||||
CompoundTag compoundTag = packStructureData(
|
||||
StructurePieceSerializationContext.fromLevel(level), pos, chunk.getAllStarts(), chunk.getAllReferences()
|
||||
);
|
||||
@@ -128,7 +136,7 @@
|
||||
return new SerializableChunkData(
|
||||
level.registryAccess().lookupOrThrow(Registries.BIOME),
|
||||
pos,
|
||||
@@ -447,6 +_,7 @@
|
||||
@@ -447,6 +501,7 @@ public record SerializableChunkData(
|
||||
list2,
|
||||
list1,
|
||||
compoundTag
|
||||
@@ -136,7 +144,7 @@
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -525,6 +_,11 @@
|
||||
@@ -525,6 +580,11 @@ public record SerializableChunkData(
|
||||
this.heightmaps.forEach((types, longs) -> compoundTag2.put(types.getSerializationKey(), new LongArrayTag(longs)));
|
||||
compoundTag.put("Heightmaps", compoundTag2);
|
||||
compoundTag.put("structures", this.structureData);
|
||||
@@ -148,7 +156,7 @@
|
||||
return compoundTag;
|
||||
}
|
||||
|
||||
@@ -562,6 +_,13 @@
|
||||
@@ -562,6 +622,13 @@ public record SerializableChunkData(
|
||||
chunk.setBlockEntityNbt(compoundTag);
|
||||
} else {
|
||||
BlockPos posFromTag = BlockEntity.getPosFromTag(compoundTag);
|
||||
@@ -162,7 +170,7 @@
|
||||
BlockEntity blockEntity = BlockEntity.loadStatic(posFromTag, chunk.getBlockState(posFromTag), compoundTag, level.registryAccess());
|
||||
if (blockEntity != null) {
|
||||
chunk.setBlockEntity(blockEntity);
|
||||
@@ -610,6 +_,12 @@
|
||||
@@ -610,6 +677,12 @@ public record SerializableChunkData(
|
||||
} else {
|
||||
StructureStart structureStart = StructureStart.loadStaticStart(context, compound.getCompound(string), seed);
|
||||
if (structureStart != null) {
|
||||
+21
-13
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
index 3bfdc4df0db8944db6c671f53499cf07f3a3e7be..3c1c89aade5ff092b880ba1bf1de83f54d3d62cc 100644
|
||||
--- a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
+++ b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
@@ -61,6 +_,7 @@
|
||||
@@ -61,6 +61,7 @@ public class MapItemSavedData extends SavedData {
|
||||
public byte scale;
|
||||
public byte[] colors = new byte[16384];
|
||||
public boolean locked;
|
||||
@@ -8,7 +16,7 @@
|
||||
public final List<MapItemSavedData.HoldingPlayer> carriedBy = Lists.newArrayList();
|
||||
public final Map<Player, MapItemSavedData.HoldingPlayer> carriedByPlayers = Maps.newHashMap();
|
||||
private final Map<String, MapBanner> bannerMarkers = Maps.newHashMap();
|
||||
@@ -68,6 +_,13 @@
|
||||
@@ -68,6 +69,13 @@ public class MapItemSavedData extends SavedData {
|
||||
private final Map<String, MapFrame> frameMarkers = Maps.newHashMap();
|
||||
private int trackedDecorationCount;
|
||||
|
||||
@@ -22,7 +30,7 @@
|
||||
public static SavedData.Factory<MapItemSavedData> factory() {
|
||||
return new SavedData.Factory<>(() -> {
|
||||
throw new IllegalStateException("Should never create an empty map saved data");
|
||||
@@ -82,6 +_,11 @@
|
||||
@@ -82,6 +90,11 @@ public class MapItemSavedData extends SavedData {
|
||||
this.trackingPosition = trackingPosition;
|
||||
this.unlimitedTracking = unlimitedTracking;
|
||||
this.locked = locked;
|
||||
@@ -34,7 +42,7 @@
|
||||
}
|
||||
|
||||
public static MapItemSavedData createFresh(
|
||||
@@ -100,9 +_,47 @@
|
||||
@@ -100,9 +113,47 @@ public class MapItemSavedData extends SavedData {
|
||||
}
|
||||
|
||||
public static MapItemSavedData load(CompoundTag tag, HolderLookup.Provider levelRegistry) {
|
||||
@@ -85,7 +93,7 @@
|
||||
int _int = tag.getInt("xCenter");
|
||||
int _int1 = tag.getInt("zCenter");
|
||||
byte b = (byte)Mth.clamp(tag.getByte("scale"), 0, 4);
|
||||
@@ -114,6 +_,7 @@
|
||||
@@ -114,6 +165,7 @@ public class MapItemSavedData extends SavedData {
|
||||
if (byteArray.length == 16384) {
|
||||
mapItemSavedData.colors = byteArray;
|
||||
}
|
||||
@@ -93,7 +101,7 @@
|
||||
|
||||
RegistryOps<Tag> registryOps = levelRegistry.createSerializationContext(NbtOps.INSTANCE);
|
||||
|
||||
@@ -154,6 +_,25 @@
|
||||
@@ -154,6 +206,25 @@ public class MapItemSavedData extends SavedData {
|
||||
.encodeStart(NbtOps.INSTANCE, this.dimension.location())
|
||||
.resultOrPartial(LOGGER::error)
|
||||
.ifPresent(dimension -> tag.put("dimension", dimension));
|
||||
@@ -119,7 +127,7 @@
|
||||
tag.putInt("xCenter", this.centerX);
|
||||
tag.putInt("zCenter", this.centerZ);
|
||||
tag.putByte("scale", this.scale);
|
||||
@@ -233,10 +_,12 @@
|
||||
@@ -233,10 +304,12 @@ public class MapItemSavedData extends SavedData {
|
||||
}
|
||||
|
||||
MapFrame mapFrame1 = new MapFrame(pos, frame.getDirection().get2DDataValue() * 90, frame.getId());
|
||||
@@ -132,7 +140,7 @@
|
||||
}
|
||||
|
||||
MapDecorations mapDecorations = mapStack.getOrDefault(DataComponents.MAP_DECORATIONS, MapDecorations.EMPTY);
|
||||
@@ -267,7 +_,7 @@
|
||||
@@ -267,7 +340,7 @@ public class MapItemSavedData extends SavedData {
|
||||
this.trackedDecorationCount--;
|
||||
}
|
||||
|
||||
@@ -141,7 +149,7 @@
|
||||
}
|
||||
|
||||
public static void addTargetDecoration(ItemStack stack, BlockPos pos, String type, Holder<MapDecorationType> mapDecorationType) {
|
||||
@@ -421,7 +_,7 @@
|
||||
@@ -421,7 +494,7 @@ public class MapItemSavedData extends SavedData {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -150,7 +158,7 @@
|
||||
this.bannerMarkers.put(mapBanner.getId(), mapBanner);
|
||||
this.addDecoration(mapBanner.getDecoration(), accessor, mapBanner.getId(), d, d1, 180.0, mapBanner.name().orElse(null));
|
||||
return true;
|
||||
@@ -521,7 +_,7 @@
|
||||
@@ -521,7 +594,7 @@ public class MapItemSavedData extends SavedData {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@@ -159,7 +167,7 @@
|
||||
int i = this.minDirtyX;
|
||||
int i1 = this.minDirtyY;
|
||||
int i2 = this.maxDirtyX + 1 - this.minDirtyX;
|
||||
@@ -530,7 +_,7 @@
|
||||
@@ -530,7 +603,7 @@ public class MapItemSavedData extends SavedData {
|
||||
|
||||
for (int i4 = 0; i4 < i2; i4++) {
|
||||
for (int i5 = 0; i5 < i3; i5++) {
|
||||
@@ -168,7 +176,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,17 +_,38 @@
|
||||
@@ -540,17 +613,38 @@ public class MapItemSavedData extends SavedData {
|
||||
@Nullable
|
||||
Packet<?> nextUpdatePacket(MapId mapId) {
|
||||
MapItemSavedData.MapPatch mapPatch;
|
||||
@@ -210,7 +218,7 @@
|
||||
} else {
|
||||
collection = null;
|
||||
}
|
||||
@@ -578,6 +_,23 @@
|
||||
@@ -578,6 +672,23 @@ public class MapItemSavedData extends SavedData {
|
||||
private void markDecorationsDirty() {
|
||||
this.dirtyDecorations = true;
|
||||
}
|
||||
+10
-2
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/storage/DimensionDataStorage.java b/net/minecraft/world/level/storage/DimensionDataStorage.java
|
||||
index 693edd43b9ff2a9f93889eb321c3c7b943b98708..d9a3b5a2e6495b7e22c114506c2bd1e406f58f8f 100644
|
||||
--- a/net/minecraft/world/level/storage/DimensionDataStorage.java
|
||||
+++ b/net/minecraft/world/level/storage/DimensionDataStorage.java
|
||||
@@ -139,7 +_,7 @@
|
||||
@@ -139,7 +139,7 @@ public class DimensionDataStorage implements AutoCloseable {
|
||||
} else {
|
||||
int i = Util.maxAllowedExecutorThreads();
|
||||
int size = map.size();
|
||||
@@ -9,7 +17,7 @@
|
||||
this.pendingWriteFuture = this.pendingWriteFuture.thenCompose(object -> {
|
||||
List<CompletableFuture<?>> list = new ArrayList<>(i);
|
||||
int i1 = Mth.positiveCeilDiv(size, i);
|
||||
@@ -160,7 +_,7 @@
|
||||
@@ -160,7 +160,7 @@ public class DimensionDataStorage implements AutoCloseable {
|
||||
object -> CompletableFuture.allOf(
|
||||
map.entrySet()
|
||||
.stream()
|
||||
+18
-10
@@ -1,6 +1,14 @@
|
||||
From 3aeeaf31b7a7f888f54e47826e8ec0ddbe65c4bf Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 14:37:42 +0100
|
||||
Subject: [PATCH] paper File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/storage/PrimaryLevelData.java b/net/minecraft/world/level/storage/PrimaryLevelData.java
|
||||
index 385d424ed08a6f3202c263cc8acedbc32cdeae7c..2f4922a2035cc7d628dd2c979137163feb90e19f 100644
|
||||
--- a/net/minecraft/world/level/storage/PrimaryLevelData.java
|
||||
+++ b/net/minecraft/world/level/storage/PrimaryLevelData.java
|
||||
@@ -74,6 +_,21 @@
|
||||
@@ -74,6 +74,21 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
|
||||
private final Set<String> removedFeatureFlags;
|
||||
private final TimerQueue<MinecraftServer> scheduledEvents;
|
||||
|
||||
@@ -22,7 +30,7 @@
|
||||
private PrimaryLevelData(
|
||||
@Nullable CompoundTag loadedPlayerTag,
|
||||
boolean wasModded,
|
||||
@@ -237,7 +_,7 @@
|
||||
@@ -237,7 +252,7 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
|
||||
nbt.put("Version", compoundTag);
|
||||
NbtUtils.addCurrentDataVersion(nbt);
|
||||
DynamicOps<Tag> dynamicOps = registry.createSerializationContext(NbtOps.INSTANCE);
|
||||
@@ -31,7 +39,7 @@
|
||||
.resultOrPartial(Util.prefix("WorldGenSettings: ", LOGGER::error))
|
||||
.ifPresent(worldOptionsTag -> nbt.put("WorldGenSettings", worldOptionsTag));
|
||||
nbt.putInt("GameType", this.settings.gameType().getId());
|
||||
@@ -281,6 +_,8 @@
|
||||
@@ -281,6 +296,8 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
|
||||
if (this.wanderingTraderId != null) {
|
||||
nbt.putUUID("WanderingTraderId", this.wanderingTraderId);
|
||||
}
|
||||
@@ -40,7 +48,7 @@
|
||||
}
|
||||
|
||||
private static ListTag stringCollectionToTag(Set<String> stringCollection) {
|
||||
@@ -358,6 +_,25 @@
|
||||
@@ -358,6 +375,25 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
|
||||
|
||||
@Override
|
||||
public void setThundering(boolean thundering) {
|
||||
@@ -66,7 +74,7 @@
|
||||
this.thundering = thundering;
|
||||
}
|
||||
|
||||
@@ -378,6 +_,26 @@
|
||||
@@ -378,6 +414,26 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
|
||||
|
||||
@Override
|
||||
public void setRaining(boolean isRaining) {
|
||||
@@ -93,7 +101,7 @@
|
||||
this.raining = isRaining;
|
||||
}
|
||||
|
||||
@@ -444,6 +_,12 @@
|
||||
@@ -444,6 +500,12 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
|
||||
@Override
|
||||
public void setDifficulty(Difficulty difficulty) {
|
||||
this.settings = this.settings.withDifficulty(difficulty);
|
||||
@@ -106,11 +114,10 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -579,6 +_,14 @@
|
||||
public LevelSettings getLevelSettings() {
|
||||
@@ -580,6 +642,14 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
|
||||
return this.settings.copy();
|
||||
}
|
||||
+
|
||||
|
||||
+ // CraftBukkit start - Check if the name stored in NBT is the correct one
|
||||
+ public void checkName(String name) {
|
||||
+ if (!this.settings.levelName.equals(name)) {
|
||||
@@ -118,6 +125,7 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
+
|
||||
@Deprecated
|
||||
public static enum SpecialWorldProperty {
|
||||
NONE,
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
--- a/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java
|
||||
+++ b/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java
|
||||
@@ -44,6 +_,7 @@
|
||||
@@ -47,6 +_,7 @@
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
final int page = 0;
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
for (final List<String> request : Iterables.partition(criteria, ENTRIES_PER_PAGE)) {
|
||||
final List<String> normalizedRequest = request.stream().map(YggdrasilGameProfileRepository::normalizeName).toList();
|
||||
@@ -75,6 +_,12 @@
|
||||
@@ -78,6 +_,12 @@
|
||||
LOGGER.debug("Couldn't find profile {}", name);
|
||||
callback.onProfileLookupFailed(name, new ProfileNotFoundException("Server did not find the requested profile"));
|
||||
}
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
--- a/com/mojang/math/OctahedralGroup.java
|
||||
+++ b/com/mojang/math/OctahedralGroup.java
|
||||
@@ -111,6 +_,7 @@
|
||||
this.permutation = permutation;
|
||||
this.transformation = new Matrix3f().scaling(invertX ? -1.0F : 1.0F, invertY ? -1.0F : 1.0F, invertZ ? -1.0F : 1.0F);
|
||||
this.transformation.mul(permutation.transformation());
|
||||
@@ -132,6 +_,7 @@
|
||||
Matrix3f matrix3f = new Matrix3f().scaling(invertX ? -1.0F : 1.0F, invertY ? -1.0F : 1.0F, invertZ ? -1.0F : 1.0F);
|
||||
matrix3f.mul(permutation.transformation());
|
||||
this.transformation = matrix3f;
|
||||
+ this.initializeRotationDirections(); // Paper - Avoid Lazy Initialization for Enum Fields
|
||||
}
|
||||
|
||||
private BooleanList packInversions() {
|
||||
@@ -139,7 +_,7 @@
|
||||
@@ -160,7 +_,7 @@
|
||||
return this.name;
|
||||
}
|
||||
|
||||
- public Direction rotate(Direction direction) {
|
||||
+ public void initializeRotationDirections() { // Paper - Avoid Lazy Initialization for Enum Fields
|
||||
if (this.rotatedDirections == null) {
|
||||
this.rotatedDirections = Maps.newEnumMap(Direction.class);
|
||||
Direction.Axis[] axiss = Direction.Axis.values();
|
||||
@@ -154,6 +_,10 @@
|
||||
}
|
||||
this.rotatedDirections = Util.makeEnumMap(Direction.class, direction1 -> {
|
||||
Direction.Axis axis = direction1.getAxis();
|
||||
@@ -171,6 +_,11 @@
|
||||
});
|
||||
}
|
||||
|
||||
+ // Paper start - Avoid Lazy Initialization for Enum Fields
|
||||
+ }
|
||||
+
|
||||
+ public Direction rotate(Direction direction) {
|
||||
+ // Paper end - Avoid Lazy Initialization for Enum Fields
|
||||
return this.rotatedDirections.get(direction);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/ChatFormatting.java
|
||||
+++ b/net/minecraft/ChatFormatting.java
|
||||
@@ -112,6 +_,19 @@
|
||||
@@ -118,6 +_,19 @@
|
||||
return friendlyName == null ? null : FORMATTING_BY_NAME.get(cleanName(friendlyName));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/Util.java
|
||||
+++ b/net/minecraft/Util.java
|
||||
@@ -92,9 +_,26 @@
|
||||
@@ -93,9 +_,26 @@
|
||||
private static final int DEFAULT_MAX_THREADS = 255;
|
||||
private static final int DEFAULT_SAFE_FILE_OPERATION_RETRIES = 10;
|
||||
private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads";
|
||||
@@ -28,7 +28,7 @@
|
||||
private static final DateTimeFormatter FILENAME_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss", Locale.ROOT);
|
||||
public static final int LINEAR_LOOKUP_THRESHOLD = 8;
|
||||
private static final Set<String> ALLOWED_UNTRUSTED_LINK_PROTOCOLS = Set.of("http", "https");
|
||||
@@ -113,6 +_,7 @@
|
||||
@@ -114,6 +_,7 @@
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException("No jar file system provider found"));
|
||||
private static Consumer<String> thePauser = string -> {};
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
public static <K, V> Collector<Entry<? extends K, ? extends V>, ?, Map<K, V>> toMap() {
|
||||
return Collectors.toMap(Entry::getKey, Entry::getValue);
|
||||
@@ -135,7 +_,7 @@
|
||||
@@ -136,7 +_,7 @@
|
||||
}
|
||||
|
||||
public static long getNanos() {
|
||||
@@ -45,7 +45,7 @@
|
||||
}
|
||||
|
||||
public static long getEpochMillis() {
|
||||
@@ -146,9 +_,10 @@
|
||||
@@ -147,9 +_,10 @@
|
||||
return FILENAME_DATE_TIME_FORMATTER.format(ZonedDateTime.now());
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
if (i <= 0) {
|
||||
directExecutorService = MoreExecutors.newDirectExecutorService();
|
||||
} else {
|
||||
@@ -173,16 +_,30 @@
|
||||
@@ -174,16 +_,30 @@
|
||||
super.onTermination(throwOnTermination);
|
||||
}
|
||||
};
|
||||
@@ -91,7 +91,7 @@
|
||||
}
|
||||
|
||||
private static int getMaxThreads() {
|
||||
@@ -233,6 +_,21 @@
|
||||
@@ -234,6 +_,21 @@
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
public static void throwAsRuntime(Throwable throwable) {
|
||||
throw throwable instanceof RuntimeException ? (RuntimeException)throwable : new RuntimeException(throwable);
|
||||
}
|
||||
@@ -1075,16 +_,7 @@
|
||||
@@ -1088,16 +_,7 @@
|
||||
}
|
||||
|
||||
public void openUri(URI uri) {
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
public Vec3 getPosition() {
|
||||
return this.worldPosition;
|
||||
}
|
||||
@@ -499,20 +_,25 @@
|
||||
@@ -498,20 +_,25 @@
|
||||
Component component = Component.translatable("chat.type.admin", this.getDisplayName(), message).withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC);
|
||||
if (this.server.getGameRules().getBoolean(GameRules.RULE_SENDCOMMANDFEEDBACK)) {
|
||||
for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
|
||||
@@ -123,7 +123,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,7 +_,7 @@
|
||||
@@ -522,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public Collection<String> getOnlinePlayerNames() {
|
||||
@@ -132,7 +132,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -598,4 +_,16 @@
|
||||
@@ -597,4 +_,16 @@
|
||||
public boolean isSilent() {
|
||||
return this.silent;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
StackTraceElement[] stackTrace = var12.getStackTrace();
|
||||
|
||||
for (int i = 0; i < Math.min(stackTrace.length, 3); i++) {
|
||||
@@ -309,18 +_,22 @@
|
||||
@@ -308,18 +_,22 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -148,12 +148,12 @@
|
||||
int min = Math.min(var7.getInput().length(), var7.getCursor());
|
||||
MutableComponent mutableComponent = Component.empty()
|
||||
.withStyle(ChatFormatting.GRAY)
|
||||
- .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + command)));
|
||||
+ .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + label))); // CraftBukkit // Paper
|
||||
- .withStyle(style -> style.withClickEvent(new ClickEvent.SuggestCommand("/" + command)));
|
||||
+ .withStyle(style -> style.withClickEvent(new ClickEvent.SuggestCommand("/" + label))); // CraftBukkit // Paper
|
||||
if (min > 10) {
|
||||
mutableComponent.append(CommonComponents.ELLIPSIS);
|
||||
}
|
||||
@@ -332,7 +_,17 @@
|
||||
@@ -331,7 +_,17 @@
|
||||
}
|
||||
|
||||
mutableComponent.append(Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC));
|
||||
@@ -172,7 +172,7 @@
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -360,26 +_,120 @@
|
||||
@@ -359,26 +_,120 @@
|
||||
}
|
||||
|
||||
public void sendCommands(ServerPlayer player) {
|
||||
@@ -297,9 +297,9 @@
|
||||
+ // we want the exact command instance to be used for equality checks
|
||||
+ // when assigning serialization ids to each command node
|
||||
|
||||
if (argumentBuilder instanceof RequiredArgumentBuilder) {
|
||||
RequiredArgumentBuilder<SharedSuggestionProvider, ?> requiredArgumentBuilder = (RequiredArgumentBuilder<SharedSuggestionProvider, ?>)argumentBuilder;
|
||||
@@ -396,7 +_,7 @@
|
||||
if (argumentBuilder instanceof RequiredArgumentBuilder requiredArgumentBuilder
|
||||
&& requiredArgumentBuilder.getSuggestionsProvider() != null) {
|
||||
@@ -393,7 +_,7 @@
|
||||
commandNodeToSuggestionNode.put(commandNode, commandNode1);
|
||||
rootSuggestion.addChild(commandNode1);
|
||||
if (!commandNode.getChildren().isEmpty()) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/Direction.java
|
||||
+++ b/net/minecraft/core/Direction.java
|
||||
@@ -57,6 +_,12 @@
|
||||
@@ -62,6 +_,12 @@
|
||||
.sorted(Comparator.comparingInt(direction -> direction.data2d))
|
||||
.toArray(Direction[]::new);
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
private Direction(
|
||||
final int data3d,
|
||||
final int oppositeIndex,
|
||||
@@ -74,6 +_,11 @@
|
||||
this.axisDirection = axisDirection;
|
||||
@@ -80,6 +_,11 @@
|
||||
this.normal = normal;
|
||||
this.normalVec3 = Vec3.atLowerCornerOf(normal);
|
||||
this.normalVec3f = new Vector3f(normal.getX(), normal.getY(), normal.getZ());
|
||||
+ // Paper start - Perf: Inline shift direction fields
|
||||
+ this.adjX = normal.getX();
|
||||
+ this.adjY = normal.getY();
|
||||
@@ -25,7 +25,7 @@
|
||||
}
|
||||
|
||||
public static Direction[] orderedByNearest(Entity entity) {
|
||||
@@ -247,15 +_,15 @@
|
||||
@@ -252,15 +_,15 @@
|
||||
}
|
||||
|
||||
public int getStepX() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/MappedRegistry.java
|
||||
+++ b/net/minecraft/core/MappedRegistry.java
|
||||
@@ -33,17 +_,18 @@
|
||||
@@ -32,17 +_,18 @@
|
||||
public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||
private final ResourceKey<? extends Registry<T>> key;
|
||||
private final ObjectList<Holder.Reference<T>> byId = new ObjectArrayList<>(256);
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
@Override
|
||||
public Stream<HolderSet.Named<T>> listTags() {
|
||||
@@ -114,6 +_,7 @@
|
||||
@@ -113,6 +_,7 @@
|
||||
this.toId.put(value, size);
|
||||
this.registrationInfos.put(key, registrationInfo);
|
||||
this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle());
|
||||
@@ -32,7 +32,7 @@
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
@@ -275,6 +_,7 @@
|
||||
@@ -274,6 +_,7 @@
|
||||
return this;
|
||||
} else {
|
||||
this.frozen = true;
|
||||
@@ -40,7 +40,7 @@
|
||||
this.byValue.forEach((object, reference) -> reference.bindValue((T)object));
|
||||
List<ResourceLocation> list = this.byKey
|
||||
.entrySet()
|
||||
@@ -509,4 +_,13 @@
|
||||
@@ -508,4 +_,13 @@
|
||||
|
||||
Stream<HolderSet.Named<T>> getTags();
|
||||
}
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
--- a/net/minecraft/core/Rotations.java
|
||||
+++ b/net/minecraft/core/Rotations.java
|
||||
@@ -34,6 +_,18 @@
|
||||
this(tag.getFloat(0), tag.getFloat(1), tag.getFloat(2));
|
||||
}
|
||||
|
||||
+ // Paper start - faster alternative constructor
|
||||
+ private Rotations(float x, float y, float z, Void dummy_var) {
|
||||
+ this.x = x;
|
||||
+ this.y = y;
|
||||
+ this.z = z;
|
||||
+ }
|
||||
+
|
||||
@@ -26,11 +_,22 @@
|
||||
buffer.writeFloat(value.z);
|
||||
}
|
||||
};
|
||||
+ // Paper start - add internal method for skipping validation for plugins
|
||||
+ private static boolean SKIP_VALIDATION = false;
|
||||
+ public static Rotations createWithoutValidityChecks(float x, float y, float z) {
|
||||
+ return new Rotations(x, y, z, null);
|
||||
+ SKIP_VALIDATION = true;
|
||||
+ Rotations rotations = new Rotations(x, y, z);
|
||||
+ SKIP_VALIDATION = false;
|
||||
+ return rotations;
|
||||
+ }
|
||||
+ // Paper end - faster alternative constructor
|
||||
+
|
||||
public ListTag save() {
|
||||
ListTag listTag = new ListTag();
|
||||
listTag.add(FloatTag.valueOf(this.x));
|
||||
+ // Paper end - add internal method for skipping validation for plugins
|
||||
|
||||
public Rotations(float x, float y, float z) {
|
||||
+ if (SKIP_VALIDATION) { // Paper - add internal method for skipping validation for plugins
|
||||
x = !Float.isInfinite(x) && !Float.isNaN(x) ? x % 360.0F : 0.0F;
|
||||
y = !Float.isInfinite(y) && !Float.isNaN(y) ? y % 360.0F : 0.0F;
|
||||
z = !Float.isInfinite(z) && !Float.isNaN(z) ? z % 360.0F : 0.0F;
|
||||
+ } // Paper - add internal method for skipping validation for plugins
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
@@ -1,8 +1,8 @@
|
||||
--- a/net/minecraft/core/Vec3i.java
|
||||
+++ b/net/minecraft/core/Vec3i.java
|
||||
@@ -16,9 +_,9 @@
|
||||
vec3i -> IntStream.of(vec3i.getX(), vec3i.getY(), vec3i.getZ())
|
||||
);
|
||||
@@ -22,9 +_,9 @@
|
||||
ByteBufCodecs.VAR_INT, Vec3i::getX, ByteBufCodecs.VAR_INT, Vec3i::getY, ByteBufCodecs.VAR_INT, Vec3i::getZ, Vec3i::new
|
||||
);
|
||||
public static final Vec3i ZERO = new Vec3i(0, 0, 0);
|
||||
- private int x;
|
||||
- private int y;
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
public static Codec<Vec3i> offsetCodec(int maxOffset) {
|
||||
return CODEC.validate(
|
||||
@@ -35,12 +_,12 @@
|
||||
@@ -41,12 +_,12 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -28,7 +28,7 @@
|
||||
return (this.getY() + this.getZ() * 31) * 31 + this.getX();
|
||||
}
|
||||
|
||||
@@ -53,15 +_,15 @@
|
||||
@@ -59,15 +_,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
return this.z;
|
||||
}
|
||||
|
||||
@@ -235,4 +_,10 @@
|
||||
@@ -241,4 +_,10 @@
|
||||
public String toShortString() {
|
||||
return this.getX() + ", " + this.getY() + ", " + this.getZ();
|
||||
}
|
||||
|
||||
+11
-14
@@ -122,13 +122,14 @@
|
||||
)
|
||||
);
|
||||
addDefaultInteractions(map3);
|
||||
@@ -202,15 +_,34 @@
|
||||
@@ -202,15 +_,35 @@
|
||||
Predicate<BlockState> statePredicate,
|
||||
SoundEvent fillSound
|
||||
) {
|
||||
+ // Paper start - add hitDirection
|
||||
+ return fillBucket(state, level, pos, player, hand, emptyStack, filledStack, statePredicate, fillSound, null); // Paper - add hitDirection
|
||||
+ }
|
||||
+
|
||||
+ static InteractionResult fillBucket(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack emptyStack, ItemStack filledStack, Predicate<BlockState> statePredicate, SoundEvent fillSound, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) {
|
||||
+ // Paper end - add hitDirection
|
||||
if (!statePredicate.test(state)) {
|
||||
@@ -137,7 +138,7 @@
|
||||
if (!level.isClientSide) {
|
||||
+ // Paper start - fire PlayerBucketFillEvent
|
||||
+ if (hitDirection != null) {
|
||||
+ org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((net.minecraft.server.level.ServerLevel) level, player, pos, pos, hitDirection, emptyStack, filledStack.getItem(), hand);
|
||||
+ org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent(level, player, pos, pos, hitDirection, emptyStack, filledStack.getItem(), hand);
|
||||
+ if (event.isCancelled()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
@@ -158,20 +159,21 @@
|
||||
level.playSound(null, pos, fillSound, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
level.gameEvent(null, GameEvent.FLUID_PICKUP, pos);
|
||||
}
|
||||
@@ -222,12 +_,32 @@
|
||||
@@ -222,12 +_,33 @@
|
||||
static InteractionResult emptyBucket(
|
||||
Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStackl, BlockState state, SoundEvent emptySound
|
||||
) {
|
||||
+ // Paper start - add hitDirection
|
||||
+ return emptyBucket(level, pos, player, hand, filledStackl, state, emptySound, null);
|
||||
+ }
|
||||
+
|
||||
+ static InteractionResult emptyBucket(Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStackl, BlockState state, SoundEvent emptySound, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) {
|
||||
+ // Paper end - add hitDirection
|
||||
if (!level.isClientSide) {
|
||||
+ // Paper start - fire PlayerBucketEmptyEvent
|
||||
+ ItemStack output = new ItemStack(Items.BUCKET);
|
||||
+ if (hitDirection != null) {
|
||||
+ org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketEmptyEvent((net.minecraft.server.level.ServerLevel) level, player, pos, pos, hitDirection, filledStackl, hand);
|
||||
+ org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketEmptyEvent(level, player, pos, pos, hitDirection, filledStackl, hand);
|
||||
+ if (event.isCancelled()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
@@ -193,7 +195,7 @@
|
||||
level.playSound(null, pos, emptySound, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
level.gameEvent(null, GameEvent.FLUID_PLACE, pos);
|
||||
}
|
||||
@@ -236,7 +_,7 @@
|
||||
@@ -236,23 +_,23 @@
|
||||
}
|
||||
|
||||
private static InteractionResult fillWaterInteraction(
|
||||
@@ -201,13 +203,8 @@
|
||||
+ BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, ItemStack filledStack, final net.minecraft.core.Direction hitDirection // Paper - add hitDirection
|
||||
) {
|
||||
return emptyBucket(
|
||||
level,
|
||||
@@ -245,20 +_,20 @@
|
||||
hand,
|
||||
filledStack,
|
||||
Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, Integer.valueOf(3)),
|
||||
- SoundEvents.BUCKET_EMPTY
|
||||
+ SoundEvents.BUCKET_EMPTY, hitDirection // Paper - add hitDirection
|
||||
- level, pos, player, hand, filledStack, Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY
|
||||
+ level, pos, player, hand, filledStack, Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY, hitDirection // Paper - add hitDirection
|
||||
);
|
||||
}
|
||||
|
||||
@@ -227,10 +224,10 @@
|
||||
) {
|
||||
return (InteractionResult)(isUnderWater(level, pos)
|
||||
? InteractionResult.CONSUME
|
||||
@@ -269,53 +_,68 @@
|
||||
@@ -263,53 +_,68 @@
|
||||
hand,
|
||||
filledStack,
|
||||
Blocks.POWDER_SNOW_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, Integer.valueOf(3)),
|
||||
Blocks.POWDER_SNOW_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3),
|
||||
- SoundEvents.BUCKET_EMPTY_POWDER_SNOW
|
||||
+ SoundEvents.BUCKET_EMPTY_POWDER_SNOW, hitDirection // Paper - add hitDirection
|
||||
));
|
||||
|
||||
+43
-43
@@ -1,50 +1,50 @@
|
||||
--- a/net/minecraft/core/component/DataComponentPatch.java
|
||||
+++ b/net/minecraft/core/component/DataComponentPatch.java
|
||||
@@ -86,6 +_,11 @@
|
||||
buffer.writeVarInt(0);
|
||||
buffer.writeVarInt(0);
|
||||
} else {
|
||||
+ // Paper start - data sanitization for items
|
||||
+ final io.papermc.paper.util.ItemObfuscationSession itemObfuscationSession = value.map.isEmpty()
|
||||
+ ? null // Avoid thread local lookup of current session if it won't be needed anyway.
|
||||
+ : io.papermc.paper.util.ItemObfuscationSession.currentSession();
|
||||
+ // Paper end - data sanitization for items
|
||||
int i = 0;
|
||||
int i1 = 0;
|
||||
@@ -106,6 +_,11 @@
|
||||
buffer.writeVarInt(0);
|
||||
buffer.writeVarInt(0);
|
||||
} else {
|
||||
+ // Paper start - data sanitization for items
|
||||
+ final io.papermc.paper.util.ItemObfuscationSession itemObfuscationSession = value.map.isEmpty()
|
||||
+ ? null // Avoid thread local lookup of current session if it won't be needed anyway.
|
||||
+ : io.papermc.paper.util.ItemObfuscationSession.currentSession();
|
||||
+ // Paper end - data sanitization for items
|
||||
int i = 0;
|
||||
int i1 = 0;
|
||||
|
||||
@@ -93,7 +_,7 @@
|
||||
value.map
|
||||
)) {
|
||||
if (entry.getValue().isPresent()) {
|
||||
- i++;
|
||||
+ if (!io.papermc.paper.util.ItemComponentSanitizer.shouldDrop(itemObfuscationSession, entry.getKey())) i++; // Paper - data sanitization for items
|
||||
} else {
|
||||
i1++;
|
||||
}
|
||||
@@ -106,6 +_,7 @@
|
||||
value.map
|
||||
)) {
|
||||
Optional<?> optional = entryx.getValue();
|
||||
+ optional = io.papermc.paper.util.ItemComponentSanitizer.override(itemObfuscationSession, entryx.getKey(), entryx.getValue()); // Paper - data sanitization for items
|
||||
if (optional.isPresent()) {
|
||||
DataComponentType<?> dataComponentType = entryx.getKey();
|
||||
DataComponentType.STREAM_CODEC.encode(buffer, dataComponentType);
|
||||
@@ -125,7 +_,13 @@
|
||||
}
|
||||
@@ -113,7 +_,7 @@
|
||||
value.map
|
||||
)) {
|
||||
if (entry.getValue().isPresent()) {
|
||||
- i++;
|
||||
+ if (!io.papermc.paper.util.ItemComponentSanitizer.shouldDrop(itemObfuscationSession, entry.getKey())) i++; // Paper - data sanitization for items
|
||||
} else {
|
||||
i1++;
|
||||
}
|
||||
@@ -126,6 +_,7 @@
|
||||
value.map
|
||||
)) {
|
||||
Optional<?> optional = entryx.getValue();
|
||||
+ optional = io.papermc.paper.util.ItemComponentSanitizer.override(itemObfuscationSession, entryx.getKey(), entryx.getValue()); // Paper - data sanitization for items
|
||||
if (optional.isPresent()) {
|
||||
DataComponentType<?> dataComponentType = entryx.getKey();
|
||||
DataComponentType.STREAM_CODEC.encode(buffer, dataComponentType);
|
||||
@@ -145,7 +_,13 @@
|
||||
}
|
||||
|
||||
private static <T> void encodeComponent(RegistryFriendlyByteBuf buffer, DataComponentType<T> component, Object value) {
|
||||
- component.streamCodec().encode(buffer, (T)value);
|
||||
+ // Paper start - codec errors of random anonymous classes are useless
|
||||
+ try {
|
||||
+ component.streamCodec().encode(buffer, (T)value);
|
||||
+ } catch (final Exception e) {
|
||||
+ throw new RuntimeException("Error encoding component " + component, e);
|
||||
+ }
|
||||
+ // Paper end - codec errors of random anonymous classes are useless
|
||||
}
|
||||
};
|
||||
private static final String REMOVED_PREFIX = "!";
|
||||
@@ -230,6 +_,42 @@
|
||||
private <T> void encodeComponent(RegistryFriendlyByteBuf registryFriendlyByteBuf, DataComponentType<T> dataComponentType, Object object) {
|
||||
- codecGetter.apply(dataComponentType).encode(registryFriendlyByteBuf, (T)object);
|
||||
+ // Paper start - codec errors of random anonymous classes are useless
|
||||
+ try {
|
||||
+ codecGetter.apply(dataComponentType).encode(registryFriendlyByteBuf, (T)object);
|
||||
+ } catch (final Exception e) {
|
||||
+ throw new RuntimeException("Error encoding component " + dataComponentType, e);
|
||||
+ }
|
||||
+ // Paper end - codec errors of random anonymous classes are useless
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -249,6 +_,42 @@
|
||||
|
||||
Builder() {
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/component/DataComponents.java
|
||||
+++ b/net/minecraft/core/component/DataComponents.java
|
||||
@@ -180,10 +_,10 @@
|
||||
@@ -203,10 +_,10 @@
|
||||
"map_post_processing", builder -> builder.networkSynchronized(MapPostProcessing.STREAM_CODEC)
|
||||
);
|
||||
public static final DataComponentType<ChargedProjectiles> CHARGED_PROJECTILES = register(
|
||||
@@ -13,7 +13,7 @@
|
||||
);
|
||||
public static final DataComponentType<PotionContents> POTION_CONTENTS = register(
|
||||
"potion_contents", builder -> builder.persistent(PotionContents.CODEC).networkSynchronized(PotionContents.STREAM_CODEC).cacheEncoding()
|
||||
@@ -250,7 +_,7 @@
|
||||
@@ -286,7 +_,7 @@
|
||||
"pot_decorations", builder -> builder.persistent(PotDecorations.CODEC).networkSynchronized(PotDecorations.STREAM_CODEC).cacheEncoding()
|
||||
);
|
||||
public static final DataComponentType<ItemContainerContents> CONTAINER = register(
|
||||
|
||||
+61
-97
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
@@ -82,16 +_,48 @@
|
||||
@@ -83,16 +_,48 @@
|
||||
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
|
||||
EntityType<?> type = ((SpawnEggItem)item.getItem()).getType(blockSource.level().registryAccess(), item);
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
blockSource.level().gameEvent(null, GameEvent.ENTITY_PLACE, blockSource.pos());
|
||||
return item;
|
||||
}
|
||||
@@ -109,12 +_,40 @@
|
||||
@@ -110,12 +_,40 @@
|
||||
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos blockPos = blockSource.pos().relative(direction);
|
||||
ServerLevel serverLevel = blockSource.level();
|
||||
@@ -94,45 +94,7 @@
|
||||
}
|
||||
|
||||
return item;
|
||||
@@ -134,7 +_,36 @@
|
||||
livingEntity -> livingEntity instanceof Saddleable saddleable && !saddleable.isSaddled() && saddleable.isSaddleable()
|
||||
);
|
||||
if (!entitiesOfClass.isEmpty()) {
|
||||
- ((Saddleable)entitiesOfClass.get(0)).equipSaddle(item.split(1), SoundSource.BLOCKS);
|
||||
+ // CraftBukkit start
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1); // Paper - shrink below and single item in event
|
||||
+ ServerLevel world = blockSource.level();
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(singleItemStack);
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseArmorEvent event = new org.bukkit.event.block.BlockDispenseArmorEvent(block, craftItem.clone(), entitiesOfClass.get(0).getBukkitLivingEntity());
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ world.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // item.grow(1); // Paper - shrink below
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true; // Paper
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ // Chain to handler for new item
|
||||
+ ItemStack eventStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack); // Paper - Fix NPE with equippable and items without behavior
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) { // Paper - fix possible StackOverflowError
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
+ }
|
||||
+ }
|
||||
+ ((Saddleable) entitiesOfClass.get(0)).equipSaddle(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), SoundSource.BLOCKS); // Paper - track changed items in dispense event
|
||||
+ // CraftBukkit end
|
||||
+ if (shrink) item.shrink(1); // Paper - actually handle here
|
||||
this.setSuccess(true);
|
||||
return item;
|
||||
} else {
|
||||
@@ -156,8 +_,36 @@
|
||||
@@ -135,8 +_,36 @@
|
||||
new AABB(blockPos),
|
||||
abstractChestedHorse1 -> abstractChestedHorse1.isAlive() && !abstractChestedHorse1.hasChest()
|
||||
)) {
|
||||
@@ -171,7 +133,7 @@
|
||||
this.setSuccess(true);
|
||||
return item;
|
||||
}
|
||||
@@ -195,8 +_,50 @@
|
||||
@@ -174,8 +_,50 @@
|
||||
DispensibleContainerItem dispensibleContainerItem = (DispensibleContainerItem)item.getItem();
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
Level level = blockSource.level();
|
||||
@@ -223,7 +185,7 @@
|
||||
return this.consumeWithRemainder(blockSource, item, new ItemStack(Items.BUCKET));
|
||||
} else {
|
||||
return this.defaultDispenseItemBehavior.dispense(blockSource, item);
|
||||
@@ -219,12 +_,37 @@
|
||||
@@ -198,12 +_,37 @@
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
BlockState blockState = levelAccessor.getBlockState(blockPos);
|
||||
if (blockState.getBlock() instanceof BucketPickup bucketPickup) {
|
||||
@@ -262,7 +224,7 @@
|
||||
return this.consumeWithRemainder(blockSource, item, new ItemStack(item1));
|
||||
}
|
||||
} else {
|
||||
@@ -236,17 +_,44 @@
|
||||
@@ -215,18 +_,45 @@
|
||||
@Override
|
||||
protected ItemStack execute(BlockSource blockSource, ItemStack item) {
|
||||
ServerLevel serverLevel = blockSource.level();
|
||||
@@ -303,14 +265,15 @@
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
} else if (CampfireBlock.canLight(blockState) || CandleBlock.canLight(blockState) || CandleCakeBlock.canLight(blockState)) {
|
||||
serverLevel.setBlockAndUpdate(blockPos, blockState.setValue(BlockStateProperties.LIT, Boolean.valueOf(true)));
|
||||
serverLevel.setBlockAndUpdate(blockPos, blockState.setValue(BlockStateProperties.LIT, true));
|
||||
serverLevel.gameEvent(null, GameEvent.BLOCK_CHANGE, blockPos);
|
||||
- } else if (blockState.getBlock() instanceof TntBlock) {
|
||||
+ } else if (blockState.getBlock() instanceof TntBlock && org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(serverLevel, blockPos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.DISPENSER, null, blockSource.pos())) { // CraftBukkit - TNTPrimeEvent
|
||||
TntBlock.explode(serverLevel, blockPos);
|
||||
serverLevel.removeBlock(blockPos, false);
|
||||
} else {
|
||||
@@ -266,11 +_,62 @@
|
||||
} else if (blockState.getBlock() instanceof TntBlock) {
|
||||
- if (TntBlock.prime(serverLevel, blockPos)) {
|
||||
+ if (TntBlock.prime(serverLevel, blockPos, () -> org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(serverLevel, blockPos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.DISPENSER, null, blockSource.pos()))) { // CraftBukkit - TNTPrimeEvent
|
||||
serverLevel.removeBlock(blockPos, false);
|
||||
} else {
|
||||
this.setSuccess(false);
|
||||
@@ -248,11 +_,62 @@
|
||||
this.setSuccess(true);
|
||||
Level level = blockSource.level();
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
@@ -373,49 +336,50 @@
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -280,11 +_,39 @@
|
||||
protected ItemStack execute(BlockSource blockSource, ItemStack item) {
|
||||
Level level = blockSource.level();
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
- PrimedTnt primedTnt = new PrimedTnt(level, blockPos.getX() + 0.5, blockPos.getY(), blockPos.getZ() + 0.5, null);
|
||||
+ // CraftBukkit start
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1); // Paper - shrink at end and single item in event
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(singleItemStack);
|
||||
@@ -265,12 +_,39 @@
|
||||
this.setSuccess(false);
|
||||
return item;
|
||||
} else {
|
||||
- BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
- PrimedTnt primedTnt = new PrimedTnt(serverLevel, blockPos.getX() + 0.5, blockPos.getY(), blockPos.getZ() + 0.5, null);
|
||||
+ // CraftBukkit start
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1); // Paper - shrink at end and single item in event
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(singleItemStack);
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockPos.getX() + 0.5D, (double) blockPos.getY(), (double) blockPos.getZ() + 0.5D));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockPos.getX() + 0.5D, (double) blockPos.getY(), (double) blockPos.getZ() + 0.5D));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // item.grow(1); // Paper - shrink below
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true; // Paper
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ // Chain to handler for new item
|
||||
+ ItemStack eventStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack); // Paper - Fix NPE with equippable and items without behavior
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ if (event.isCancelled()) {
|
||||
+ // item.grow(1); // Paper - shrink below
|
||||
+ return item;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ PrimedTnt primedTnt = new PrimedTnt(level, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), null);
|
||||
+ // CraftBukkit end
|
||||
level.addFreshEntity(primedTnt);
|
||||
level.playSound(null, primedTnt.getX(), primedTnt.getY(), primedTnt.getZ(), SoundEvents.TNT_PRIMED, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
level.gameEvent(null, GameEvent.ENTITY_PLACE, blockPos);
|
||||
- item.shrink(1);
|
||||
+ if (shrink) item.shrink(1); // Paper - actually handle here
|
||||
return item;
|
||||
}
|
||||
});
|
||||
@@ -296,6 +_,29 @@
|
||||
+ boolean shrink = true; // Paper
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ // Chain to handler for new item
|
||||
+ ItemStack eventStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack); // Paper - Fix NPE with equippable and items without behavior
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ PrimedTnt primedTnt = new PrimedTnt(serverLevel, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), null);
|
||||
+ // CraftBukkit end
|
||||
serverLevel.addFreshEntity(primedTnt);
|
||||
serverLevel.playSound(null, primedTnt.getX(), primedTnt.getY(), primedTnt.getZ(), SoundEvents.TNT_PRIMED, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
serverLevel.gameEvent(null, GameEvent.ENTITY_PLACE, blockPos);
|
||||
- item.shrink(1);
|
||||
+ if (shrink) item.shrink(1); // Paper - actually handle here;
|
||||
this.setSuccess(true);
|
||||
return item;
|
||||
}
|
||||
@@ -284,6 +_,29 @@
|
||||
Level level = blockSource.level();
|
||||
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos blockPos = blockSource.pos().relative(direction);
|
||||
@@ -445,7 +409,7 @@
|
||||
if (level.isEmptyBlock(blockPos) && WitherSkullBlock.canSpawnMob(level, blockPos, item)) {
|
||||
level.setBlock(
|
||||
blockPos,
|
||||
@@ -313,7 +_,7 @@
|
||||
@@ -299,7 +_,7 @@
|
||||
item.shrink(1);
|
||||
this.setSuccess(true);
|
||||
} else {
|
||||
@@ -454,7 +418,7 @@
|
||||
}
|
||||
|
||||
return item;
|
||||
@@ -326,6 +_,29 @@
|
||||
@@ -312,6 +_,29 @@
|
||||
Level level = blockSource.level();
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
CarvedPumpkinBlock carvedPumpkinBlock = (CarvedPumpkinBlock)Blocks.CARVED_PUMPKIN;
|
||||
@@ -484,7 +448,7 @@
|
||||
if (level.isEmptyBlock(blockPos) && carvedPumpkinBlock.canSpawnGolem(level, blockPos)) {
|
||||
if (!level.isClientSide) {
|
||||
level.setBlock(blockPos, carvedPumpkinBlock.defaultBlockState(), 3);
|
||||
@@ -335,7 +_,7 @@
|
||||
@@ -321,7 +_,7 @@
|
||||
item.shrink(1);
|
||||
this.setSuccess(true);
|
||||
} else {
|
||||
@@ -493,7 +457,7 @@
|
||||
}
|
||||
|
||||
return item;
|
||||
@@ -361,6 +_,29 @@
|
||||
@@ -347,6 +_,29 @@
|
||||
ServerLevel serverLevel = blockSource.level();
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
BlockState blockState = serverLevel.getBlockState(blockPos);
|
||||
@@ -523,7 +487,7 @@
|
||||
if (blockState.is(
|
||||
BlockTags.BEEHIVES,
|
||||
blockStateBase -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL) && blockStateBase.getBlock() instanceof BeehiveBlock
|
||||
@@ -389,6 +_,13 @@
|
||||
@@ -375,6 +_,13 @@
|
||||
this.setSuccess(true);
|
||||
if (blockState.is(Blocks.RESPAWN_ANCHOR)) {
|
||||
if (blockState.getValue(RespawnAnchorBlock.CHARGE) != 4) {
|
||||
@@ -537,7 +501,7 @@
|
||||
RespawnAnchorBlock.charge(null, level, blockPos, blockState);
|
||||
item.shrink(1);
|
||||
} else {
|
||||
@@ -412,6 +_,29 @@
|
||||
@@ -398,6 +_,29 @@
|
||||
this.setSuccess(false);
|
||||
return item;
|
||||
} else {
|
||||
@@ -567,7 +531,7 @@
|
||||
for (Armadillo armadillo : entitiesOfClass) {
|
||||
if (armadillo.brushOffScute()) {
|
||||
item.hurtAndBreak(16, serverLevel, null, item1 -> {});
|
||||
@@ -432,6 +_,13 @@
|
||||
@@ -418,6 +_,13 @@
|
||||
BlockState blockState = level.getBlockState(blockPos);
|
||||
Optional<BlockState> waxed = HoneycombItem.getWaxed(blockState);
|
||||
if (waxed.isPresent()) {
|
||||
@@ -581,7 +545,7 @@
|
||||
level.setBlockAndUpdate(blockPos, waxed.get());
|
||||
level.levelEvent(3003, blockPos, 0);
|
||||
item.shrink(1);
|
||||
@@ -459,6 +_,12 @@
|
||||
@@ -445,6 +_,12 @@
|
||||
if (!serverLevel.getBlockState(blockPos1).is(BlockTags.CONVERTABLE_TO_MUD)) {
|
||||
return this.defaultDispenseItemBehavior.dispense(blockSource, item);
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@
|
||||
+ livingEntity.setItemSlot(equipmentSlotForItem, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()));
|
||||
+ // CraftBukkit end
|
||||
if (livingEntity instanceof Mob mob) {
|
||||
mob.setDropChance(equipmentSlotForItem, 2.0F);
|
||||
mob.setGuaranteedDrop(equipmentSlotForItem);
|
||||
mob.setPersistenceRequired();
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
--- a/net/minecraft/core/registries/BuiltInRegistries.java
|
||||
+++ b/net/minecraft/core/registries/BuiltInRegistries.java
|
||||
@@ -296,6 +_,17 @@
|
||||
public static final Registry<SlotDisplay.Type<?>> SLOT_DISPLAY = registerSimple(Registries.SLOT_DISPLAY, SlotDisplays::bootstrap);
|
||||
public static final Registry<RecipeBookCategory> RECIPE_BOOK_CATEGORY = registerSimple(Registries.RECIPE_BOOK_CATEGORY, RecipeBookCategories::bootstrap);
|
||||
@@ -311,6 +_,17 @@
|
||||
);
|
||||
public static final Registry<Consumer<GameTestHelper>> TEST_FUNCTION = registerSimple(Registries.TEST_FUNCTION, BuiltinTestFunctions::bootstrap);
|
||||
public static final Registry<? extends Registry<?>> REGISTRY = WRITABLE_REGISTRY;
|
||||
+ // Paper start - add built-in registry conversions
|
||||
+ public static final io.papermc.paper.registry.data.util.Conversions BUILT_IN_CONVERSIONS = new io.papermc.paper.registry.data.util.Conversions(new net.minecraft.resources.RegistryOps.RegistryInfoLookup() {
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
private static <T> Registry<T> registerSimple(ResourceKey<? extends Registry<T>> key, BuiltInRegistries.RegistryBootstrap<T> bootstrap) {
|
||||
return internalRegister(key, new MappedRegistry<>(key, Lifecycle.stable(), false), bootstrap);
|
||||
@@ -321,6 +_,7 @@
|
||||
@@ -336,6 +_,7 @@
|
||||
ResourceKey<? extends Registry<T>> key, R registry, BuiltInRegistries.RegistryBootstrap<T> bootstrap
|
||||
) {
|
||||
Bootstrap.checkBootstrapCalled(() -> "registry " + key.location());
|
||||
@@ -26,7 +26,7 @@
|
||||
ResourceLocation resourceLocation = key.location();
|
||||
LOADERS.put(resourceLocation, () -> bootstrap.run(registry));
|
||||
WRITABLE_REGISTRY.register((ResourceKey)key, registry, RegistrationInfo.BUILT_IN);
|
||||
@@ -328,16 +_,34 @@
|
||||
@@ -343,16 +_,34 @@
|
||||
}
|
||||
|
||||
public static void bootStrap() {
|
||||
@@ -61,7 +61,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
@@ -346,6 +_,7 @@
|
||||
@@ -361,6 +_,7 @@
|
||||
|
||||
for (Registry<?> registry : REGISTRY) {
|
||||
bindBootstrappedTagsToEmpty(registry);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/data/loot/packs/VanillaChestLoot.java
|
||||
+++ b/net/minecraft/data/loot/packs/VanillaChestLoot.java
|
||||
@@ -946,7 +_,6 @@
|
||||
@@ -1000,7 +_,6 @@
|
||||
.add(
|
||||
LootItem.lootTableItem(Items.COMPASS)
|
||||
.apply(SetItemCountFunction.setCount(ConstantValue.exactly(1.0F)))
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/gametest/framework/GameTestInfo.java
|
||||
+++ b/net/minecraft/gametest/framework/GameTestInfo.java
|
||||
@@ -241,7 +_,7 @@
|
||||
@@ -247,7 +_,7 @@
|
||||
AABB structureBounds = this.getStructureBounds();
|
||||
List<Entity> entitiesOfClass = this.getLevel()
|
||||
.getEntitiesOfClass(Entity.class, structureBounds.inflate(1.0), entity -> !(entity instanceof Player));
|
||||
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/gametest/framework/GameTestServer.java
|
||||
+++ b/net/minecraft/gametest/framework/GameTestServer.java
|
||||
@@ -139,6 +_,8 @@
|
||||
BlockPos spawnPos
|
||||
@@ -133,6 +_,8 @@
|
||||
boolean verify
|
||||
) {
|
||||
super(
|
||||
+ null, // Paper
|
||||
@@ -9,7 +9,7 @@
|
||||
serverThread,
|
||||
storageSource,
|
||||
packRepository,
|
||||
@@ -154,8 +_,15 @@
|
||||
@@ -148,8 +_,15 @@
|
||||
|
||||
@Override
|
||||
public boolean initServer() {
|
||||
@@ -25,9 +25,9 @@
|
||||
+ this.loadLevel("blah");
|
||||
+ // Paper end
|
||||
ServerLevel serverLevel = this.overworld();
|
||||
this.testBatches = Lists.newArrayList(GameTestBatchFactory.fromTestFunction(this.testFunctions, serverLevel));
|
||||
serverLevel.setDefaultSpawnPos(this.spawnPos, 0.0F);
|
||||
@@ -303,6 +_,13 @@
|
||||
this.testBatches = this.evaluateTestsToRun(serverLevel);
|
||||
LOGGER.info("Started game test server");
|
||||
@@ -338,6 +_,13 @@
|
||||
public boolean shouldInformAdmins() {
|
||||
return false;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/gametest/framework/StructureUtils.java
|
||||
+++ b/net/minecraft/gametest/framework/StructureUtils.java
|
||||
@@ -187,7 +_,7 @@
|
||||
@@ -86,7 +_,7 @@
|
||||
level.clearBlockEvents(boundingBox1);
|
||||
AABB aabb = AABB.of(boundingBox1);
|
||||
List<Entity> entitiesOfClass = level.getEntitiesOfClass(Entity.class, aabb, entity -> !(entity instanceof Player));
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/net/minecraft/gametest/framework/TestCommand.java
|
||||
+++ b/net/minecraft/gametest/framework/TestCommand.java
|
||||
@@ -278,7 +_,7 @@
|
||||
}
|
||||
|
||||
private static int resetGameTestInfo(GameTestInfo gameTestInfo) {
|
||||
- gameTestInfo.getLevel().getEntities(null, gameTestInfo.getStructureBounds()).stream().forEach(entity -> entity.remove(Entity.RemovalReason.DISCARDED));
|
||||
+ gameTestInfo.getLevel().getEntities(null, gameTestInfo.getStructureBounds()).stream().forEach(entity -> entity.remove(Entity.RemovalReason.DISCARDED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD)); // Paper
|
||||
gameTestInfo.getStructureBlockEntity().placeStructure(gameTestInfo.getLevel());
|
||||
StructureUtils.removeBarriers(gameTestInfo.getStructureBounds(), gameTestInfo.getLevel());
|
||||
say(gameTestInfo.getLevel(), "Reset succeded for: " + gameTestInfo.getTestName(), ChatFormatting.GREEN);
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/nbt/CompoundTag.java
|
||||
+++ b/net/minecraft/nbt/CompoundTag.java
|
||||
@@ -49,7 +_,7 @@
|
||||
@@ -54,7 +_,7 @@
|
||||
|
||||
private static CompoundTag loadCompound(DataInput input, NbtAccounter nbtAccounter) throws IOException {
|
||||
nbtAccounter.accountBytes(48L);
|
||||
@@ -9,55 +9,21 @@
|
||||
|
||||
byte b;
|
||||
while ((b = input.readByte()) != 0) {
|
||||
@@ -166,7 +_,7 @@
|
||||
@@ -171,7 +_,7 @@
|
||||
}
|
||||
|
||||
public CompoundTag() {
|
||||
- this(Maps.newHashMap());
|
||||
- this(new HashMap<>());
|
||||
+ this(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - Reduce memory footprint of CompoundTag
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,14 +_,34 @@
|
||||
}
|
||||
|
||||
public void putUUID(String key, UUID value) {
|
||||
+ // Paper start - Support old UUID format
|
||||
+ if (this.contains(key + "Most", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) && this.contains(key + "Least", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
|
||||
+ this.tags.remove(key + "Most");
|
||||
+ this.tags.remove(key + "Least");
|
||||
+ }
|
||||
+ // Paper end - Support old UUID format
|
||||
this.tags.put(key, NbtUtils.createUUID(value));
|
||||
}
|
||||
|
||||
+
|
||||
+ /**
|
||||
+ * 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 UUID format
|
||||
+ if (!contains(key, 11) && this.contains(key + "Most", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) && this.contains(key + "Least", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
|
||||
+ return new UUID(this.getLong(key + "Most"), this.getLong(key + "Least"));
|
||||
+ }
|
||||
+ // Paper end - Support old UUID format
|
||||
return NbtUtils.loadUUID(this.get(key));
|
||||
}
|
||||
|
||||
public boolean hasUUID(String key) {
|
||||
+ // Paper start - Support old UUID format
|
||||
+ if (this.contains(key + "Most", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) && this.contains(key + "Least", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Support old UUID format
|
||||
Tag tag = this.get(key);
|
||||
return tag != null && tag.getType() == IntArrayTag.TYPE && ((IntArrayTag)tag).getAsIntArray().length == 4;
|
||||
}
|
||||
@@ -477,8 +_,16 @@
|
||||
@@ -402,9 +_,16 @@
|
||||
|
||||
@Override
|
||||
public CompoundTag copy() {
|
||||
- Map<String, Tag> map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy));
|
||||
- HashMap<String, Tag> map = new HashMap<>();
|
||||
- this.tags.forEach((string, tag) -> map.put(string, tag.copy()));
|
||||
- return new CompoundTag(map);
|
||||
+ // Paper start - Reduce memory footprint of CompoundTag
|
||||
+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f);
|
||||
@@ -72,3 +38,55 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -525,22 +_,47 @@
|
||||
this.merge((CompoundTag)mapCodec.encoder().encodeStart(ops, data).getOrThrow());
|
||||
}
|
||||
|
||||
- public <T> Optional<T> read(String key, Codec<T> codec) {
|
||||
+ public <T> Optional<T> read(String key, Codec<T> codec) { // Paper - option to read via codec without logging errors - diff on change
|
||||
return this.read(key, codec, NbtOps.INSTANCE);
|
||||
}
|
||||
|
||||
- public <T> Optional<T> read(String key, Codec<T> codec, DynamicOps<Tag> ops) {
|
||||
+ public <T> Optional<T> read(String key, Codec<T> codec, DynamicOps<Tag> ops) { // Paper - option to read via codec without logging errors - diff on change
|
||||
Tag tag = this.get(key);
|
||||
return tag == null
|
||||
? Optional.empty()
|
||||
: codec.parse(ops, tag).resultOrPartial(string -> LOGGER.error("Failed to read field ({}={}): {}", key, tag, string));
|
||||
}
|
||||
|
||||
- public <T> Optional<T> read(MapCodec<T> mapCodec) {
|
||||
+ public <T> Optional<T> read(MapCodec<T> mapCodec) { // Paper - option to read via codec without logging errors - diff on change
|
||||
return this.read(mapCodec, NbtOps.INSTANCE);
|
||||
}
|
||||
|
||||
- public <T> Optional<T> read(MapCodec<T> mapCodec, DynamicOps<Tag> ops) {
|
||||
+ public <T> Optional<T> read(MapCodec<T> mapCodec, DynamicOps<Tag> ops) { // Paper - option to read via codec without logging errors - diff on change
|
||||
return mapCodec.decode(ops, ops.getMap(this).getOrThrow()).resultOrPartial(string -> LOGGER.error("Failed to read value ({}): {}", this, string));
|
||||
}
|
||||
+
|
||||
+ // Paper start - option to read via codec without logging errors
|
||||
+ // The below methods are 1 to 1 copies of the above-defined read methods without the logging part.
|
||||
+ // Copying was chosen over overloading the read methods as a boolean parameter to mark a method as quiet
|
||||
+ // is not intuitive and would require even more overloads.
|
||||
+ // Not a lot of diff in these methods is expected
|
||||
+ public <T> Optional<T> readQuiet(String key, Codec<T> codec) {
|
||||
+ return this.readQuiet(key, codec, NbtOps.INSTANCE);
|
||||
+ }
|
||||
+
|
||||
+ public <T> Optional<T> readQuiet(String key, Codec<T> codec, DynamicOps<Tag> ops) {
|
||||
+ Tag tag = this.get(key);
|
||||
+ return tag == null
|
||||
+ ? Optional.empty()
|
||||
+ : codec.parse(ops, tag).resultOrPartial();
|
||||
+ }
|
||||
+
|
||||
+ public <T> Optional<T> readQuiet(MapCodec<T> mapCodec) {
|
||||
+ return this.readQuiet(mapCodec, NbtOps.INSTANCE);
|
||||
+ }
|
||||
+
|
||||
+ public <T> Optional<T> readQuiet(MapCodec<T> mapCodec, DynamicOps<Tag> ops) {
|
||||
+ return mapCodec.decode(ops, ops.getMap(this).getOrThrow()).resultOrPartial();
|
||||
+ }
|
||||
+ // Paper end - option to read via codec without logging errors
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/nbt/NbtIo.java
|
||||
+++ b/net/minecraft/nbt/NbtIo.java
|
||||
@@ -118,6 +_,11 @@
|
||||
@@ -119,6 +_,11 @@
|
||||
}
|
||||
|
||||
public static CompoundTag read(DataInput input, NbtAccounter accounter) throws IOException {
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
--- a/net/minecraft/nbt/NbtUtils.java
|
||||
+++ b/net/minecraft/nbt/NbtUtils.java
|
||||
@@ -143,8 +_,10 @@
|
||||
if (!tag.contains("Name", 8)) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
} else {
|
||||
- ResourceLocation resourceLocation = ResourceLocation.parse(tag.getString("Name"));
|
||||
- Optional<? extends Holder<Block>> optional = blockGetter.get(ResourceKey.create(Registries.BLOCK, resourceLocation));
|
||||
+ // Paper start - Validate resource location
|
||||
+ ResourceLocation resourceLocation = ResourceLocation.tryParse(tag.getString("Name"));
|
||||
+ Optional<? extends Holder<Block>> optional = resourceLocation != null ? blockGetter.get(ResourceKey.create(Registries.BLOCK, resourceLocation)) : Optional.empty();
|
||||
+ // Paper end - Validate resource location
|
||||
if (optional.isEmpty()) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
} else {
|
||||
@@ -0,0 +1,21 @@
|
||||
--- a/net/minecraft/nbt/SnbtGrammar.java
|
||||
+++ b/net/minecraft/nbt/SnbtGrammar.java
|
||||
@@ -591,7 +_,7 @@
|
||||
Atom<List<Entry<String, T>>> atom30 = Atom.of("map_entries");
|
||||
dictionary.put(atom30, Term.repeatedWithTrailingSeparator(namedRule3, atom30, StringReaderTerms.character(',')), scope -> scope.getOrThrow(atom30));
|
||||
Atom<T> atom31 = Atom.of("map_literal");
|
||||
- dictionary.put(atom31, Term.sequence(StringReaderTerms.character('{'), dictionary.named(atom30), StringReaderTerms.character('}')), scope -> {
|
||||
+ dictionary.put(atom31, Term.sequence(StringReaderTerms.character('{'), Scope.increaseDepth(), dictionary.named(atom30), Scope.decreaseDepth(), StringReaderTerms.character('}')), scope -> { // Paper - track depth
|
||||
List<Entry<String, T>> list = scope.getOrThrow(atom30);
|
||||
if (list.isEmpty()) {
|
||||
return object2;
|
||||
@@ -626,7 +_,9 @@
|
||||
atom35,
|
||||
Term.sequence(
|
||||
StringReaderTerms.character('['),
|
||||
+ Scope.increaseDepth(), // Paper - track depth
|
||||
Term.alternative(Term.sequence(dictionary.named(atom33), StringReaderTerms.character(';'), dictionary.named(atom34)), dictionary.named(atom32)),
|
||||
+ Scope.decreaseDepth(), // Paper - track depth
|
||||
StringReaderTerms.character(']')
|
||||
),
|
||||
parseState -> {
|
||||
@@ -1,54 +0,0 @@
|
||||
--- a/net/minecraft/nbt/TagParser.java
|
||||
+++ b/net/minecraft/nbt/TagParser.java
|
||||
@@ -49,6 +_,7 @@
|
||||
}, CompoundTag::toString);
|
||||
public static final Codec<CompoundTag> LENIENT_CODEC = Codec.withAlternative(AS_CODEC, CompoundTag.CODEC);
|
||||
private final StringReader reader;
|
||||
+ private int depth; // Paper
|
||||
|
||||
public static CompoundTag parseTag(String text) throws CommandSyntaxException {
|
||||
return new TagParser(new StringReader(text)).readSingleStruct();
|
||||
@@ -159,6 +_,7 @@
|
||||
|
||||
public CompoundTag readStruct() throws CommandSyntaxException {
|
||||
this.expect('{');
|
||||
+ this.increaseDepth(); // Paper
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
this.reader.skipWhitespace();
|
||||
|
||||
@@ -182,6 +_,7 @@
|
||||
}
|
||||
|
||||
this.expect('}');
|
||||
+ this.depth--; // Paper
|
||||
return compoundTag;
|
||||
}
|
||||
|
||||
@@ -191,6 +_,7 @@
|
||||
if (!this.reader.canRead()) {
|
||||
throw ERROR_EXPECTED_VALUE.createWithContext(this.reader);
|
||||
} else {
|
||||
+ this.increaseDepth(); // Paper
|
||||
ListTag listTag = new ListTag();
|
||||
TagType<?> tagType = null;
|
||||
|
||||
@@ -216,6 +_,7 @@
|
||||
}
|
||||
|
||||
this.expect(']');
|
||||
+ this.depth--; // Paper
|
||||
return listTag;
|
||||
}
|
||||
}
|
||||
@@ -287,5 +_,11 @@
|
||||
private void expect(char expected) throws CommandSyntaxException {
|
||||
this.reader.skipWhitespace();
|
||||
this.reader.expect(expected);
|
||||
+ }
|
||||
+ private void increaseDepth() throws CommandSyntaxException {
|
||||
+ this.depth++;
|
||||
+ if (this.depth > 512) {
|
||||
+ throw new io.papermc.paper.brigadier.TagParseCommandSyntaxException("NBT tag is too complex, depth > 512");
|
||||
+ }
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@
|
||||
}
|
||||
|
||||
public static <T> IntFunction<T> limitValue(IntFunction<T> function, int limit) {
|
||||
@@ -527,7 +_,7 @@
|
||||
@@ -539,7 +_,7 @@
|
||||
|
||||
try {
|
||||
NbtIo.writeAnyTag(nbt, new ByteBufOutputStream(buffer));
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/chat/ComponentSerialization.java
|
||||
+++ b/net/minecraft/network/chat/ComponentSerialization.java
|
||||
@@ -37,9 +_,31 @@
|
||||
@@ -35,9 +_,31 @@
|
||||
|
||||
public class ComponentSerialization {
|
||||
public static final Codec<Component> CODEC = Codec.recursive("Component", ComponentSerialization::createCodec);
|
||||
@@ -34,7 +34,7 @@
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, Optional<Component>> TRUSTED_OPTIONAL_STREAM_CODEC = TRUSTED_STREAM_CODEC.apply(
|
||||
ByteBufCodecs::optional
|
||||
);
|
||||
@@ -102,7 +_,25 @@
|
||||
@@ -94,7 +_,25 @@
|
||||
return ExtraCodecs.orCompressed(mapCodec2, mapCodec1);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
ComponentContents.Type<?>[] types = new ComponentContents.Type[]{
|
||||
PlainTextContents.TYPE, TranslatableContents.TYPE, KeybindContents.TYPE, ScoreContents.TYPE, SelectorContents.TYPE, NbtContents.TYPE
|
||||
};
|
||||
@@ -115,6 +_,34 @@
|
||||
@@ -107,6 +_,34 @@
|
||||
)
|
||||
.apply(instance, MutableComponent::new)
|
||||
);
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/chat/PlayerChatMessage.java
|
||||
+++ b/net/minecraft/network/chat/PlayerChatMessage.java
|
||||
@@ -17,6 +_,43 @@
|
||||
@@ -18,6 +_,43 @@
|
||||
public record PlayerChatMessage(
|
||||
SignedMessageLink link, @Nullable MessageSignature signature, SignedMessageBody signedBody, @Nullable Component unsignedContent, FilterMask filterMask
|
||||
) {
|
||||
@@ -44,7 +44,7 @@
|
||||
public static final MapCodec<PlayerChatMessage> MAP_CODEC = RecordCodecBuilder.mapCodec(
|
||||
instance -> instance.group(
|
||||
SignedMessageLink.CODEC.fieldOf("link").forGetter(PlayerChatMessage::link),
|
||||
@@ -47,7 +_,14 @@
|
||||
@@ -48,7 +_,14 @@
|
||||
}
|
||||
|
||||
public PlayerChatMessage withUnsignedContent(Component message) {
|
||||
|
||||
+6
-6
@@ -1,20 +1,20 @@
|
||||
--- a/net/minecraft/network/chat/contents/NbtContents.java
|
||||
+++ b/net/minecraft/network/chat/contents/NbtContents.java
|
||||
@@ -115,7 +_,7 @@
|
||||
}).map(Tag::getAsString);
|
||||
@@ -119,7 +_,7 @@
|
||||
if (this.interpreting) {
|
||||
RegistryOps<Tag> registryOps = nbtPathPattern.registryAccess().createSerializationContext(NbtOps.INSTANCE);
|
||||
Component component = DataFixUtils.orElse(
|
||||
- ComponentUtils.updateForEntity(nbtPathPattern, this.separator, entity, recursionDepth), ComponentUtils.DEFAULT_NO_STYLE_SEPARATOR
|
||||
+ ComponentUtils.updateSeparatorForEntity(nbtPathPattern, this.separator, entity, recursionDepth), ComponentUtils.DEFAULT_NO_STYLE_SEPARATOR // Paper - validate separator
|
||||
);
|
||||
return stream.flatMap(text -> {
|
||||
return stream.flatMap(tag -> {
|
||||
try {
|
||||
@@ -127,7 +_,7 @@
|
||||
}
|
||||
@@ -132,7 +_,7 @@
|
||||
}).reduce((mutableComponent, component1) -> mutableComponent.append(component).append(component1)).orElseGet(Component::empty);
|
||||
} else {
|
||||
Stream<String> stream1 = stream.map(NbtContents::asString);
|
||||
- return ComponentUtils.updateForEntity(nbtPathPattern, this.separator, entity, recursionDepth)
|
||||
+ return ComponentUtils.updateSeparatorForEntity(nbtPathPattern, this.separator, entity, recursionDepth) // Paper - validate separator
|
||||
.map(
|
||||
mutableComponent -> stream.map(Component::literal)
|
||||
mutableComponent -> stream1.map(Component::literal)
|
||||
.reduce((mutableComponent1, otherMutableComponent) -> mutableComponent1.append(mutableComponent).append(otherMutableComponent))
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
+++ b/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
@@ -378,6 +_,48 @@
|
||||
@@ -390,6 +_,48 @@
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+8
-7
@@ -1,9 +1,9 @@
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
|
||||
@@ -35,6 +_,20 @@
|
||||
this.items = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buffer);
|
||||
this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.decode(buffer);
|
||||
}
|
||||
@@ -22,6 +_,21 @@
|
||||
ClientboundContainerSetContentPacket::new
|
||||
);
|
||||
|
||||
+ // Paper start - Handle large packets disconnecting client
|
||||
+ @Override
|
||||
+ public boolean hasLargePacketFallback() {
|
||||
@@ -18,6 +18,7 @@
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Handle large packets disconnecting client
|
||||
|
||||
private void write(RegistryFriendlyByteBuf buffer) {
|
||||
buffer.writeContainerId(this.containerId);
|
||||
+
|
||||
@Override
|
||||
public PacketType<ClientboundContainerSetContentPacket> type() {
|
||||
return GamePacketTypes.CLIENTBOUND_CONTAINER_SET_CONTENT;
|
||||
+9
-9
@@ -1,15 +1,15 @@
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
@@ -52,7 +_,7 @@
|
||||
throw new RuntimeException("Can't read heightmap in packet for [" + x + ", " + z + "]");
|
||||
@@ -50,7 +_,7 @@
|
||||
public ClientboundLevelChunkPacketData(RegistryFriendlyByteBuf buffer, int x, int z) {
|
||||
this.heightmaps = HEIGHTMAPS_STREAM_CODEC.decode(buffer);
|
||||
int varInt = buffer.readVarInt();
|
||||
- if (varInt > 2097152) {
|
||||
+ if (varInt > 2097152) { // Paper - diff on change - if this changes, update PacketEncoder
|
||||
throw new RuntimeException("Chunk Packet trying to allocate too much memory on read.");
|
||||
} else {
|
||||
int varInt = buffer.readVarInt();
|
||||
- if (varInt > 2097152) {
|
||||
+ if (varInt > 2097152) { // Paper - diff on change - if this changes, update PacketEncoder
|
||||
throw new RuntimeException("Chunk Packet trying to allocate too much memory on read.");
|
||||
} else {
|
||||
this.buffer = new byte[varInt];
|
||||
@@ -154,6 +_,7 @@
|
||||
this.buffer = new byte[varInt];
|
||||
@@ -151,6 +_,7 @@
|
||||
CompoundTag updateTag = blockEntity.getUpdateTag(blockEntity.getLevel().registryAccess());
|
||||
BlockPos blockPos = blockEntity.getBlockPos();
|
||||
int i = SectionPos.sectionRelative(blockPos.getX()) << 4 | SectionPos.sectionRelative(blockPos.getZ());
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
@@ -30,6 +_,11 @@
|
||||
@@ -31,6 +_,11 @@
|
||||
private final Collection<String> players;
|
||||
private final Optional<ClientboundSetPlayerTeamPacket.Parameters> parameters;
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
private ClientboundSetPlayerTeamPacket(String name, int method, Optional<ClientboundSetPlayerTeamPacket.Parameters> parameters, Collection<String> players) {
|
||||
this.name = name;
|
||||
this.method = method;
|
||||
@@ -198,7 +_,7 @@
|
||||
@@ -199,7 +_,7 @@
|
||||
ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buffer, this.displayName);
|
||||
buffer.writeByte(this.options);
|
||||
buffer.writeUtf(this.nametagVisibility);
|
||||
- buffer.writeUtf(this.collisionRule);
|
||||
+ buffer.writeUtf(!io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions ? PlayerTeam.CollisionRule.NEVER.name : this.collisionRule); // Paper - Configurable player collision
|
||||
Team.Visibility.STREAM_CODEC.encode(buffer, this.nametagVisibility);
|
||||
- Team.CollisionRule.STREAM_CODEC.encode(buffer, this.collisionRule);
|
||||
+ Team.CollisionRule.STREAM_CODEC.encode(buffer, !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions ? PlayerTeam.CollisionRule.NEVER : this.collisionRule); // Paper - Configurable player collision
|
||||
buffer.writeEnum(this.color);
|
||||
ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buffer, this.playerPrefix);
|
||||
ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buffer, this.playerSuffix);
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
--- a/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java
|
||||
@@ -17,7 +_,7 @@
|
||||
);
|
||||
private static final int MAX_SLOT_COUNT = 128;
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, Int2ObjectMap<ItemStack>> SLOTS_STREAM_CODEC = ByteBufCodecs.map(
|
||||
- Int2ObjectOpenHashMap::new, ByteBufCodecs.SHORT.map(Short::intValue, Integer::shortValue), ItemStack.OPTIONAL_STREAM_CODEC, 128
|
||||
+ Int2ObjectOpenHashMap::new, ByteBufCodecs.SHORT.map(Short::intValue, Integer::shortValue), ItemStack.OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs::trackDepth), 128 // Paper - Track codec depth
|
||||
);
|
||||
private final int containerId;
|
||||
private final int stateId;
|
||||
@@ -46,7 +_,7 @@
|
||||
this.buttonNum = buffer.readByte();
|
||||
this.clickType = buffer.readEnum(ClickType.class);
|
||||
this.changedSlots = Int2ObjectMaps.unmodifiable(SLOTS_STREAM_CODEC.decode(buffer));
|
||||
- this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.decode(buffer);
|
||||
+ this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs::trackDepth).decode(buffer); // Paper - Track codec depth
|
||||
}
|
||||
|
||||
private void write(RegistryFriendlyByteBuf buffer) {
|
||||
+2
-2
@@ -4,8 +4,8 @@
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, ServerboundSetCreativeModeSlotPacket> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.SHORT,
|
||||
ServerboundSetCreativeModeSlotPacket::slotNum,
|
||||
- ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_STREAM_CODEC),
|
||||
+ ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_STREAM_CODEC).apply(ByteBufCodecs::trackDepth), // Paper - Track codec depth
|
||||
- ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_UNTRUSTED_STREAM_CODEC),
|
||||
+ ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_UNTRUSTED_STREAM_CODEC).apply(ByteBufCodecs::trackDepth), // Paper - Track codec depth
|
||||
ServerboundSetCreativeModeSlotPacket::itemStack,
|
||||
ServerboundSetCreativeModeSlotPacket::new
|
||||
);
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/resources/RegistryDataLoader.java
|
||||
+++ b/net/minecraft/resources/RegistryDataLoader.java
|
||||
@@ -247,13 +_,14 @@
|
||||
@@ -271,13 +_,14 @@
|
||||
RegistryOps<JsonElement> ops,
|
||||
ResourceKey<E> resourceKey,
|
||||
Resource resource,
|
||||
@@ -17,7 +17,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,6 +_,7 @@
|
||||
@@ -291,6 +_,7 @@
|
||||
FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key());
|
||||
RegistryOps<JsonElement> registryOps = RegistryOps.create(JsonOps.INSTANCE, registryInfoLookup);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
for (Entry<ResourceLocation, Resource> entry : fileToIdConverter.listMatchingResources(resourceManager).entrySet()) {
|
||||
ResourceLocation resourceLocation = entry.getKey();
|
||||
ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), fileToIdConverter.fileToId(resourceLocation));
|
||||
@@ -274,7 +_,7 @@
|
||||
@@ -298,7 +_,7 @@
|
||||
RegistrationInfo registrationInfo = REGISTRATION_INFO_CACHE.apply(resource.knownPackInfo());
|
||||
|
||||
try {
|
||||
@@ -34,7 +34,7 @@
|
||||
} catch (Exception var14) {
|
||||
loadingErrors.put(
|
||||
resourceKey,
|
||||
@@ -283,7 +_,9 @@
|
||||
@@ -307,7 +_,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
}
|
||||
|
||||
static <E> void loadContentsFromNetwork(
|
||||
@@ -300,6 +_,7 @@
|
||||
@@ -324,6 +_,7 @@
|
||||
RegistryOps<JsonElement> registryOps1 = RegistryOps.create(JsonOps.INSTANCE, registryInfoLookup);
|
||||
FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key());
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
for (RegistrySynchronization.PackedRegistryEntry packedRegistryEntry : networkedRegistryData.elements) {
|
||||
ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), packedRegistryEntry.id());
|
||||
Optional<Tag> optional = packedRegistryEntry.data();
|
||||
@@ -318,7 +_,7 @@
|
||||
@@ -342,7 +_,7 @@
|
||||
|
||||
try {
|
||||
Resource resourceOrThrow = resourceProvider.getResourceOrThrow(resourceLocation);
|
||||
@@ -62,7 +62,7 @@
|
||||
} catch (Exception var17) {
|
||||
loadingErrors.put(resourceKey, new IllegalStateException("Failed to parse local data", var17));
|
||||
}
|
||||
@@ -360,6 +_,7 @@
|
||||
@@ -384,6 +_,7 @@
|
||||
|
||||
RegistryDataLoader.Loader<T> create(Lifecycle registryLifecycle, Map<ResourceKey<?>, Exception> loadingErrors) {
|
||||
WritableRegistry<T> writableRegistry = new MappedRegistry<>(this.key, registryLifecycle);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/resources/ResourceLocation.java
|
||||
+++ b/net/minecraft/resources/ResourceLocation.java
|
||||
@@ -32,6 +_,7 @@
|
||||
@@ -23,6 +_,7 @@
|
||||
public static final char NAMESPACE_SEPARATOR = ':';
|
||||
public static final String DEFAULT_NAMESPACE = "minecraft";
|
||||
public static final String REALMS_NAMESPACE = "realms";
|
||||
@@ -8,7 +8,7 @@
|
||||
private final String namespace;
|
||||
private final String path;
|
||||
|
||||
@@ -40,6 +_,13 @@
|
||||
@@ -31,6 +_,13 @@
|
||||
|
||||
assert isValidPath(path);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
this.namespace = namespace;
|
||||
this.path = path;
|
||||
}
|
||||
@@ -252,7 +_,7 @@
|
||||
@@ -243,7 +_,7 @@
|
||||
|
||||
private static String assertValidNamespace(String namespace, String path) {
|
||||
if (!isValidNamespace(namespace)) {
|
||||
@@ -31,7 +31,7 @@
|
||||
} else {
|
||||
return namespace;
|
||||
}
|
||||
@@ -277,7 +_,7 @@
|
||||
@@ -268,7 +_,7 @@
|
||||
|
||||
private static String assertValidPath(String namespace, String path) {
|
||||
if (!isValidPath(path)) {
|
||||
|
||||
@@ -180,11 +180,11 @@
|
||||
|
||||
+ /*
|
||||
RegistryAccess.Frozen frozen = worldStem.registries().compositeAccess();
|
||||
boolean hasOptionSpec1 = optionSet.has(optionSpec6);
|
||||
if (optionSet.has(optionSpec4) || hasOptionSpec1) {
|
||||
@@ -245,9 +_,13 @@
|
||||
|
||||
WorldData worldData = worldStem.worldData();
|
||||
boolean hasOptionSpec1 = optionSet.has(optionSpec6);
|
||||
@@ -245,9 +_,13 @@
|
||||
}
|
||||
|
||||
levelStorageAccess.saveDataTag(frozen, worldData);
|
||||
+ */
|
||||
final DedicatedServer dedicatedServer = MinecraftServer.spin(
|
||||
@@ -241,12 +241,12 @@
|
||||
} catch (Exception var42) {
|
||||
LOGGER.error(LogUtils.FATAL_MARKER, "Failed to start the minecraft server", (Throwable)var42);
|
||||
}
|
||||
@@ -316,7 +_,7 @@
|
||||
@@ -317,7 +_,7 @@
|
||||
RegistryAccess registryAccess,
|
||||
boolean recreateRegionFiles
|
||||
) {
|
||||
- LOGGER.info("Forcing world upgrade!");
|
||||
+ LOGGER.info("Forcing world upgrade! {}", levelStorage.getLevelId()); // CraftBukkit
|
||||
|
||||
try (WorldUpgrader worldUpgrader = new WorldUpgrader(levelStorage, dataFixer, registryAccess, eraseCache, recreateRegionFiles)) {
|
||||
try (WorldUpgrader worldUpgrader = new WorldUpgrader(levelStorage, dataFixer, worldData, registryAccess, eraseCache, recreateRegionFiles)) {
|
||||
Component component = null;
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/ServerScoreboard.java
|
||||
+++ b/net/minecraft/server/ServerScoreboard.java
|
||||
@@ -39,9 +_,7 @@
|
||||
@@ -43,9 +_,7 @@
|
||||
protected void onScoreChanged(ScoreHolder scoreHolder, Objective objective, Score score) {
|
||||
super.onScoreChanged(scoreHolder, objective, score);
|
||||
if (this.trackedObjectives.contains(objective)) {
|
||||
@@ -11,7 +11,7 @@
|
||||
new ClientboundSetScorePacket(
|
||||
scoreHolder.getScoreboardName(),
|
||||
objective.getName(),
|
||||
@@ -64,7 +_,7 @@
|
||||
@@ -68,7 +_,7 @@
|
||||
@Override
|
||||
public void onPlayerRemoved(ScoreHolder scoreHolder) {
|
||||
super.onPlayerRemoved(scoreHolder);
|
||||
@@ -20,7 +20,7 @@
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
@@ -72,7 +_,7 @@
|
||||
@@ -76,7 +_,7 @@
|
||||
public void onPlayerScoreRemoved(ScoreHolder scoreHolder, Objective objective) {
|
||||
super.onPlayerScoreRemoved(scoreHolder, objective);
|
||||
if (this.trackedObjectives.contains(objective)) {
|
||||
@@ -29,7 +29,7 @@
|
||||
}
|
||||
|
||||
this.setDirty();
|
||||
@@ -84,7 +_,7 @@
|
||||
@@ -88,7 +_,7 @@
|
||||
super.setDisplayObjective(slot, objective);
|
||||
if (displayObjective != objective && displayObjective != null) {
|
||||
if (this.getObjectiveDisplaySlotCount(displayObjective) > 0) {
|
||||
@@ -38,7 +38,7 @@
|
||||
} else {
|
||||
this.stopTrackingObjective(displayObjective);
|
||||
}
|
||||
@@ -92,7 +_,7 @@
|
||||
@@ -96,7 +_,7 @@
|
||||
|
||||
if (objective != null) {
|
||||
if (this.trackedObjectives.contains(objective)) {
|
||||
@@ -47,7 +47,7 @@
|
||||
} else {
|
||||
this.startTrackingObjective(objective);
|
||||
}
|
||||
@@ -104,24 +_,50 @@
|
||||
@@ -108,24 +_,50 @@
|
||||
@Override
|
||||
public boolean addPlayerToTeam(String playerName, PlayerTeam team) {
|
||||
if (super.addPlayerToTeam(playerName, team)) {
|
||||
@@ -112,7 +112,7 @@
|
||||
|
||||
@Override
|
||||
public void onObjectiveAdded(Objective objective) {
|
||||
@@ -133,7 +_,7 @@
|
||||
@@ -137,7 +_,7 @@
|
||||
public void onObjectiveChanged(Objective objective) {
|
||||
super.onObjectiveChanged(objective);
|
||||
if (this.trackedObjectives.contains(objective)) {
|
||||
@@ -121,7 +121,7 @@
|
||||
}
|
||||
|
||||
this.setDirty();
|
||||
@@ -152,21 +_,21 @@
|
||||
@@ -156,21 +_,21 @@
|
||||
@Override
|
||||
public void onTeamAdded(PlayerTeam playerTeam) {
|
||||
super.onTeamAdded(playerTeam);
|
||||
@@ -146,7 +146,7 @@
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
@@ -209,6 +_,7 @@
|
||||
@@ -213,6 +_,7 @@
|
||||
List<Packet<?>> startTrackingPackets = this.getStartTrackingPackets(objective);
|
||||
|
||||
for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
|
||||
@@ -154,7 +154,7 @@
|
||||
for (Packet<?> packet : startTrackingPackets) {
|
||||
serverPlayer.connection.send(packet);
|
||||
}
|
||||
@@ -234,6 +_,7 @@
|
||||
@@ -238,6 +_,7 @@
|
||||
List<Packet<?>> stopTrackingPackets = this.getStopTrackingPackets(objective);
|
||||
|
||||
for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
|
||||
@@ -162,9 +162,9 @@
|
||||
for (Packet<?> packet : stopTrackingPackets) {
|
||||
serverPlayer.connection.send(packet);
|
||||
}
|
||||
@@ -267,6 +_,16 @@
|
||||
private ScoreboardSaveData createData(CompoundTag tag, HolderLookup.Provider registries) {
|
||||
return this.createData().load(tag, registries);
|
||||
@@ -269,6 +_,16 @@
|
||||
scoreboardSaveData.loadFrom(data);
|
||||
return scoreboardSaveData;
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit start - Send to players
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/net/minecraft/server/commands/OpCommand.java
|
||||
+++ b/net/minecraft/server/commands/OpCommand.java
|
||||
@@ -46,7 +_,7 @@
|
||||
if (!playerList.isOp(gameProfile)) {
|
||||
playerList.op(gameProfile);
|
||||
i++;
|
||||
- source.sendSuccess(() -> Component.translatable("commands.op.success", gameProfiles.iterator().next().getName()), true);
|
||||
+ source.sendSuccess(() -> Component.translatable("commands.op.success", gameProfile.getName()), true); // Paper - fixes MC-253721
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/commands/PlaceCommand.java
|
||||
+++ b/net/minecraft/server/commands/PlaceCommand.java
|
||||
@@ -280,6 +_,7 @@
|
||||
@@ -301,6 +_,7 @@
|
||||
if (!structureStart.isValid()) {
|
||||
throw ERROR_STRUCTURE_FAILED.create();
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
|
||||
+ final Collection<ServerPlayer> actualTargets = new java.util.ArrayList<>(); // Paper - Add PlayerSetSpawnEvent
|
||||
for (ServerPlayer serverPlayer : targets) {
|
||||
- serverPlayer.setRespawnPosition(resourceKey, pos, angle, true, false);
|
||||
- serverPlayer.setRespawnPosition(new ServerPlayer.RespawnConfig(resourceKey, pos, angle, true), false);
|
||||
- }
|
||||
+ // Paper start - Add PlayerSetSpawnEvent
|
||||
+ if (serverPlayer.setRespawnPosition(resourceKey, pos, angle, true, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND)) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@@ -82,6 +_,7 @@
|
||||
ServerLevel level = source.getLevel();
|
||||
Entity entity = EntityType.loadEntityRecursive(compoundTag, level, EntitySpawnReason.COMMAND, entity1 -> {
|
||||
entity1.moveTo(pos.x, pos.y, pos.z, entity1.getYRot(), entity1.getXRot());
|
||||
entity1.snapTo(pos.x, pos.y, pos.z, entity1.getYRot(), entity1.getXRot());
|
||||
+ entity1.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.COMMAND; // Paper - Entity#getEntitySpawnReason
|
||||
return entity1;
|
||||
});
|
||||
|
||||
@@ -1,366 +1,20 @@
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -145,6 +_,33 @@
|
||||
public int serverViewDistance;
|
||||
private final WorldGenContext worldGenContext;
|
||||
|
||||
+ // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
|
||||
+ public final CallbackExecutor callbackExecutor = new CallbackExecutor();
|
||||
+ public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable {
|
||||
+
|
||||
+ private final java.util.Queue<Runnable> queue = new java.util.ArrayDeque<>();
|
||||
+
|
||||
+ @Override
|
||||
+ public void execute(Runnable runnable) {
|
||||
+ this.queue.add(runnable);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ Runnable task;
|
||||
+ while ((task = this.queue.poll()) != null) {
|
||||
+ task.run();
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ // Paper start
|
||||
+ public final ChunkHolder getUnloadingChunkHolder(int chunkX, int chunkZ) {
|
||||
+ return this.pendingUnloads.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public ChunkMap(
|
||||
ServerLevel level,
|
||||
LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
@@ -171,13 +_,19 @@
|
||||
this.level = level;
|
||||
RegistryAccess registryAccess = level.registryAccess();
|
||||
long seed = level.getSeed();
|
||||
- if (generator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||
+ // CraftBukkit start - SPIGOT-7051: It's a rigged game! Use delegate for random state creation, otherwise it is not so random.
|
||||
+ ChunkGenerator randomGenerator = generator;
|
||||
+ if (randomGenerator instanceof org.bukkit.craftbukkit.generator.CustomChunkGenerator customChunkGenerator) {
|
||||
+ randomGenerator = customChunkGenerator.getDelegate();
|
||||
+ }
|
||||
+ if (randomGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||
+ // CraftBukkit end
|
||||
this.randomState = RandomState.create(noiseBasedChunkGenerator.generatorSettings().value(), registryAccess.lookupOrThrow(Registries.NOISE), seed);
|
||||
} else {
|
||||
this.randomState = RandomState.create(NoiseGeneratorSettings.dummy(), registryAccess.lookupOrThrow(Registries.NOISE), seed);
|
||||
}
|
||||
|
||||
- this.chunkGeneratorState = generator.createState(registryAccess.lookupOrThrow(Registries.STRUCTURE_SET), this.randomState, seed);
|
||||
+ this.chunkGeneratorState = generator.createState(registryAccess.lookupOrThrow(Registries.STRUCTURE_SET), this.randomState, seed, level.spigotConfig); // Spigot
|
||||
this.mainThreadExecutor = mainThreadExecutor;
|
||||
ConsecutiveExecutor consecutiveExecutor = new ConsecutiveExecutor(dispatcher, "worldgen");
|
||||
this.progressListener = progressListener;
|
||||
@@ -207,6 +_,12 @@
|
||||
this.chunksToEagerlySave.add(chunkPos.toLong());
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public int getMobCountNear(final ServerPlayer player, final net.minecraft.world.entity.MobCategory mobCategory) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
protected ChunkGenerator generator() {
|
||||
return this.worldGenContext.generator();
|
||||
}
|
||||
@@ -354,9 +_,9 @@
|
||||
}
|
||||
);
|
||||
stringBuilder.append("Updating:").append(System.lineSeparator());
|
||||
- this.updatingChunkMap.values().forEach(consumer);
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().getUpdatingChunkHolders(this.level).forEach(consumer); // Paper
|
||||
stringBuilder.append("Visible:").append(System.lineSeparator());
|
||||
- this.visibleChunkMap.values().forEach(consumer);
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level).forEach(consumer); // Paper
|
||||
CrashReport crashReport = CrashReport.forThrowable(exception, "Chunk loading");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Chunk loading");
|
||||
crashReportCategory.setDetail("Details", details);
|
||||
@@ -392,6 +_,9 @@
|
||||
holder.setTicketLevel(newLevel);
|
||||
} else {
|
||||
holder = new ChunkHolder(new ChunkPos(chunkPos), newLevel, this.level, this.lightEngine, this::onLevelChange, this);
|
||||
+ // Paper start
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderCreate(this.level, holder);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
this.updatingChunkMap.put(chunkPos, holder);
|
||||
@@ -420,8 +_,8 @@
|
||||
|
||||
protected void saveAllChunks(boolean flush) {
|
||||
if (flush) {
|
||||
- List<ChunkHolder> list = this.visibleChunkMap
|
||||
- .values()
|
||||
+ List<ChunkHolder> list = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level) // Paper - moonrise
|
||||
+ //.values() // Paper - moonrise
|
||||
.stream()
|
||||
.filter(ChunkHolder::wasAccessibleSinceLastSave)
|
||||
.peek(ChunkHolder::refreshAccessibility)
|
||||
@@ -447,7 +_,7 @@
|
||||
this.nextChunkSaveTime.clear();
|
||||
long millis = Util.getMillis();
|
||||
|
||||
- for (ChunkHolder chunkHolder : this.visibleChunkMap.values()) {
|
||||
+ for (ChunkHolder chunkHolder : ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)) { // Paper
|
||||
this.saveChunkIfNeeded(chunkHolder, millis);
|
||||
}
|
||||
}
|
||||
@@ -468,6 +_,7 @@
|
||||
public boolean hasWork() {
|
||||
return this.lightEngine.hasLightWork()
|
||||
|| !this.pendingUnloads.isEmpty()
|
||||
+ || ca.spottedleaf.moonrise.common.PlatformHooks.get().hasAnyChunkHolders(this.level) // Paper - moonrise
|
||||
|| !this.updatingChunkMap.isEmpty()
|
||||
|| this.poiManager.hasWork()
|
||||
|| !this.toDrop.isEmpty()
|
||||
@@ -526,7 +_,11 @@
|
||||
this.scheduleUnload(chunkPos, chunkHolder);
|
||||
} else {
|
||||
ChunkAccess latestChunk = chunkHolder.getLatestChunk();
|
||||
- if (this.pendingUnloads.remove(chunkPos, chunkHolder) && latestChunk != null) {
|
||||
+ // Paper start
|
||||
+ boolean removed;
|
||||
+ if ((removed = this.pendingUnloads.remove(chunkPos, chunkHolder)) && latestChunk != null) {
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderDelete(this.level, chunkHolder);
|
||||
+ // Paper end
|
||||
if (latestChunk instanceof LevelChunk levelChunk) {
|
||||
levelChunk.setLoaded(false);
|
||||
}
|
||||
@@ -540,7 +_,9 @@
|
||||
this.lightEngine.tryScheduleUpdate();
|
||||
this.progressListener.onStatusChange(latestChunk.getPos(), null);
|
||||
this.nextChunkSaveTime.remove(latestChunk.getPos().toLong());
|
||||
- }
|
||||
+ } else if (removed) { // Paper start
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderDelete(this.level, chunkHolder);
|
||||
+ } // Paper end
|
||||
}
|
||||
}, this.unloadQueue::add).whenComplete((_void, error) -> {
|
||||
if (error != null) {
|
||||
@@ -856,7 +_,7 @@
|
||||
}
|
||||
|
||||
public int size() {
|
||||
- return this.visibleChunkMap.size();
|
||||
+ return ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolderCount(this.level); // Paper
|
||||
}
|
||||
|
||||
public net.minecraft.server.level.DistanceManager getDistanceManager() {
|
||||
@@ -864,7 +_,7 @@
|
||||
}
|
||||
|
||||
protected Iterable<ChunkHolder> getChunks() {
|
||||
- return Iterables.unmodifiableIterable(this.visibleChunkMap.values());
|
||||
+ return Iterables.unmodifiableIterable(ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)); // Paper
|
||||
}
|
||||
|
||||
void dumpChunks(Writer writer) throws IOException {
|
||||
@@ -888,10 +_,10 @@
|
||||
.build(writer);
|
||||
TickingTracker tickingTracker = this.distanceManager.tickingTracker();
|
||||
|
||||
- for (Entry<ChunkHolder> entry : this.visibleChunkMap.long2ObjectEntrySet()) {
|
||||
- long longKey = entry.getLongKey();
|
||||
+ for (ChunkHolder entry : ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)) { // Paper - Moonrise
|
||||
+ long longKey = entry.pos.toLong(); // Paper - Moonrise
|
||||
ChunkPos chunkPos = new ChunkPos(longKey);
|
||||
- ChunkHolder chunkHolder = entry.getValue();
|
||||
+ ChunkHolder chunkHolder = entry; // Paper - Moonrise
|
||||
Optional<ChunkAccess> optional = Optional.ofNullable(chunkHolder.getLatestChunk());
|
||||
Optional<LevelChunk> optional1 = optional.flatMap(chunk -> chunk instanceof LevelChunk ? Optional.of((LevelChunk)chunk) : Optional.empty());
|
||||
csvOutput.writeRow(
|
||||
@@ -931,11 +_,13 @@
|
||||
}
|
||||
|
||||
private CompletableFuture<Optional<CompoundTag>> readChunk(ChunkPos pos) {
|
||||
- return this.read(pos).thenApplyAsync(optional -> optional.map(this::upgradeChunkTag), Util.backgroundExecutor().forName("upgradeChunk"));
|
||||
+ return this.read(pos).thenApplyAsync(optional -> optional.map(tag -> upgradeChunkTag(tag, pos)), Util.backgroundExecutor().forName("upgradeChunk")); // CraftBukkit
|
||||
}
|
||||
|
||||
- private CompoundTag upgradeChunkTag(CompoundTag tag) {
|
||||
- return this.upgradeChunkTag(this.level.dimension(), this.overworldDataStorage, tag, this.generator().getTypeNameForDataFixer());
|
||||
+ // CraftBukkit start
|
||||
+ private CompoundTag upgradeChunkTag(CompoundTag tag, ChunkPos pos) {
|
||||
+ return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, tag, this.generator().getTypeNameForDataFixer(), pos, this.level);
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
void forEachSpawnCandidateChunk(Consumer<ChunkHolder> action) {
|
||||
@@ -951,12 +_,34 @@
|
||||
}
|
||||
|
||||
public boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkPos) {
|
||||
- return this.distanceManager.hasPlayersNearby(chunkPos.toLong()) && this.anyPlayerCloseEnoughForSpawningInternal(chunkPos);
|
||||
+ // Spigot start
|
||||
+ return this.anyPlayerCloseEnoughForSpawning(chunkPos, false);
|
||||
+ }
|
||||
+
|
||||
+ boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkPos, boolean reducedRange) {
|
||||
+ return this.distanceManager.hasPlayersNearby(chunkPos.toLong()) && this.anyPlayerCloseEnoughForSpawningInternal(chunkPos, reducedRange);
|
||||
+ // Spigot end
|
||||
}
|
||||
|
||||
private boolean anyPlayerCloseEnoughForSpawningInternal(ChunkPos chunkPos) {
|
||||
+ // Spigot start
|
||||
+ return this.anyPlayerCloseEnoughForSpawningInternal(chunkPos, false);
|
||||
+ }
|
||||
+
|
||||
+ private boolean anyPlayerCloseEnoughForSpawningInternal(ChunkPos chunkPos, boolean reducedRange) {
|
||||
+ double blockRange; // Paper - use from event
|
||||
+ // Spigot end
|
||||
for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
|
||||
- if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos)) {
|
||||
+ // Paper start - PlayerNaturallySpawnCreaturesEvent
|
||||
+ com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event;
|
||||
+ blockRange = 16384.0D;
|
||||
+ if (reducedRange) {
|
||||
+ event = serverPlayer.playerNaturallySpawnedEvent;
|
||||
+ if (event == null || event.isCancelled()) continue;
|
||||
+ blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4));
|
||||
+ }
|
||||
+ // Paper end - PlayerNaturallySpawnCreaturesEvent
|
||||
+ if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos, blockRange)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -972,7 +_,7 @@
|
||||
Builder<ServerPlayer> builder = ImmutableList.builder();
|
||||
|
||||
for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
|
||||
- if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos)) {
|
||||
+ if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos, 16384.0D)) { // Spigot
|
||||
builder.add(serverPlayer);
|
||||
@@ -939,7 +_,7 @@
|
||||
ChunkHolder chunkHolder = this.visibleChunkMap.get(spawnCandidateChunks.nextLong());
|
||||
if (chunkHolder != null) {
|
||||
LevelChunk tickingChunk = chunkHolder.getTickingChunk();
|
||||
- if (tickingChunk != null && this.anyPlayerCloseEnoughForSpawningInternal(chunkHolder.getPos())) {
|
||||
+ if (tickingChunk != null && this.anyPlayerCloseEnoughForSpawningInternal(chunkHolder.getPos(), true)) { // Spigot
|
||||
output.add(tickingChunk);
|
||||
}
|
||||
}
|
||||
@@ -981,12 +_,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private boolean playerIsCloseEnoughForSpawning(ServerPlayer player, ChunkPos chunkPos) {
|
||||
+ private boolean playerIsCloseEnoughForSpawning(ServerPlayer player, ChunkPos chunkPos, double range) { // Spigot
|
||||
if (player.isSpectator()) {
|
||||
return false;
|
||||
} else {
|
||||
double d = euclideanDistanceSquared(chunkPos, player);
|
||||
- return d < 16384.0;
|
||||
+ return d < range; // Spigot
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,9 +_,19 @@
|
||||
}
|
||||
|
||||
public void addEntity(Entity entity) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot
|
||||
+ // Paper start - ignore and warn about illegal addEntity calls instead of crashing server
|
||||
+ if (!entity.valid || entity.level() != this.level || this.entityMap.containsKey(entity.getId())) {
|
||||
+ LOGGER.error("Illegal ChunkMap::addEntity for world " + this.level.getWorld().getName()
|
||||
+ + ": " + entity + (this.entityMap.containsKey(entity.getId()) ? " ALREADY CONTAINED (This would have crashed your server)" : ""), new Throwable());
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - ignore and warn about illegal addEntity calls instead of crashing server
|
||||
+ if (entity instanceof ServerPlayer && ((ServerPlayer) entity).supressTrackerForLogin) return; // Paper - Fire PlayerJoinEvent when Player is actually ready; Delay adding to tracker until after list packets
|
||||
if (!(entity instanceof EnderDragonPart)) {
|
||||
EntityType<?> type = entity.getType();
|
||||
int i = type.clientTrackingRange() * 16;
|
||||
+ i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i); // Spigot
|
||||
if (i != 0) {
|
||||
int updateInterval = type.updateInterval();
|
||||
if (this.entityMap.containsKey(entity.getId())) {
|
||||
@@ -1126,6 +_,7 @@
|
||||
}
|
||||
|
||||
protected void removeEntity(Entity entity) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("entity untrack"); // Spigot
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
this.updatePlayerStatus(serverPlayer, false);
|
||||
|
||||
@@ -1230,7 +_,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
- class DistanceManager extends net.minecraft.server.level.DistanceManager {
|
||||
+ public class DistanceManager extends net.minecraft.server.level.DistanceManager { // Paper - public
|
||||
protected DistanceManager(final Executor dispatcher, final Executor mainThreadExecutor) {
|
||||
super(dispatcher, mainThreadExecutor);
|
||||
}
|
||||
@@ -1258,10 +_,10 @@
|
||||
final Entity entity;
|
||||
private final int range;
|
||||
SectionPos lastSectionPos;
|
||||
- public final Set<ServerPlayerConnection> seenBy = Sets.newIdentityHashSet();
|
||||
+ public final Set<ServerPlayerConnection> seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
|
||||
@@ -1278,7 +_,7 @@
|
||||
public final Set<ServerPlayerConnection> seenBy = Sets.newIdentityHashSet();
|
||||
|
||||
public TrackedEntity(final Entity entity, final int range, final int updateInterval, final boolean trackDelta) {
|
||||
- this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, updateInterval, trackDelta, this::broadcast);
|
||||
+ this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, updateInterval, trackDelta, this::broadcast, this.seenBy); // CraftBukkit
|
||||
- this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, updateInterval, trackDelta, this::broadcast, this::broadcastIgnorePlayers);
|
||||
+ this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, updateInterval, trackDelta, this::broadcast, this::broadcastIgnorePlayers, this.seenBy); // Paper
|
||||
this.entity = entity;
|
||||
this.range = range;
|
||||
this.lastSectionPos = SectionPos.of(entity);
|
||||
@@ -1297,24 +_,47 @@
|
||||
}
|
||||
|
||||
public void removePlayer(ServerPlayer player) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot
|
||||
if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePlayer(ServerPlayer player) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
|
||||
if (player != this.entity) {
|
||||
- Vec3 vec3 = player.position().subtract(this.entity.position());
|
||||
+ // Paper start - remove allocation of Vec3D here
|
||||
+ // Vec3 vec3 = player.position().subtract(this.entity.position());
|
||||
+ double vec3_dx = player.getX() - this.entity.getX();
|
||||
+ double vec3_dz = player.getZ() - this.entity.getZ();
|
||||
+ // Paper end - remove allocation of Vec3D here
|
||||
int playerViewDistance = ChunkMap.this.getPlayerViewDistance(player);
|
||||
double d = Math.min(this.getEffectiveRange(), playerViewDistance * 16);
|
||||
- double d1 = vec3.x * vec3.x + vec3.z * vec3.z;
|
||||
+ double d1 = vec3_dx * vec3_dx + vec3_dz * vec3_dz; // Paper
|
||||
double d2 = d * d;
|
||||
- boolean flag = d1 <= d2
|
||||
- && this.entity.broadcastToPlayer(player)
|
||||
- && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
|
||||
+ // Paper start - Configurable entity tracking range by Y
|
||||
+ boolean flag = d1 <= d2;
|
||||
+ if (flag && level.paperConfig().entities.trackingRangeY.enabled) {
|
||||
+ double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||
+ if (rangeY != -1) {
|
||||
+ double vec3_dy = player.getY() - this.entity.getY();
|
||||
+ flag = vec3_dy * vec3_dy <= rangeY * rangeY;
|
||||
+ }
|
||||
+ }
|
||||
+ flag = flag && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
|
||||
+ // Paper end - Configurable entity tracking range by Y
|
||||
+ // CraftBukkit start - respect vanish API
|
||||
+ if (flag && !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Paper - only consider hits
|
||||
+ flag = false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (flag) {
|
||||
if (this.seenBy.add(player.connection)) {
|
||||
+ // Paper start - entity tracking events
|
||||
+ if (io.papermc.paper.event.player.PlayerTrackEntityEvent.getHandlerList().getRegisteredListeners().length == 0 || new io.papermc.paper.event.player.PlayerTrackEntityEvent(player.getBukkitEntity(), this.entity.getBukkitEntity()).callEvent()) {
|
||||
this.serverEntity.addPairing(player);
|
||||
+ }
|
||||
+ // Paper end - entity tracking events
|
||||
}
|
||||
} else if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
@@ -1331,6 +_,7 @@
|
||||
|
||||
for (Entity entity : this.entity.getIndirectPassengers()) {
|
||||
int i1 = entity.getType().clientTrackingRange() * 16;
|
||||
+ i1 = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i1); // Paper
|
||||
if (i1 > i) {
|
||||
i = i1;
|
||||
}
|
||||
+11
-82
@@ -1,6 +1,15 @@
|
||||
--- a/net/minecraft/server/level/DistanceManager.java
|
||||
+++ b/net/minecraft/server/level/DistanceManager.java
|
||||
@@ -107,6 +_,12 @@
|
||||
@@ -36,7 +_,7 @@
|
||||
final Long2ObjectMap<ObjectSet<ServerPlayer>> playersPerChunk = new Long2ObjectOpenHashMap<>();
|
||||
private final LoadingChunkTracker loadingChunkTracker;
|
||||
private final SimulationChunkTracker simulationChunkTracker;
|
||||
- final TicketStorage ticketStorage;
|
||||
+ public final TicketStorage ticketStorage; // Paper - TODO: AT
|
||||
private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8);
|
||||
private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(32);
|
||||
protected final Set<ChunkHolder> chunksToUpdateFutures = new ReferenceOpenHashSet<>();
|
||||
@@ -72,6 +_,12 @@
|
||||
}
|
||||
|
||||
if (!this.chunksToUpdateFutures.isEmpty()) {
|
||||
@@ -13,51 +22,7 @@
|
||||
for (ChunkHolder chunkHolder : this.chunksToUpdateFutures) {
|
||||
chunkHolder.updateHighestAllowedStatus(chunkMap);
|
||||
}
|
||||
@@ -177,16 +_,42 @@
|
||||
public <T> void addRegionTicket(TicketType<T> type, ChunkPos pos, int distance, T value) {
|
||||
Ticket<T> ticket = new Ticket<>(type, ChunkLevel.byStatus(FullChunkStatus.FULL) - distance, value);
|
||||
long packedChunkPos = pos.toLong();
|
||||
- this.addTicket(packedChunkPos, ticket);
|
||||
+ this.addTicket(packedChunkPos, ticket); // Paper - diff on change above
|
||||
this.tickingTicketsTracker.addTicket(packedChunkPos, ticket);
|
||||
}
|
||||
|
||||
public <T> void removeRegionTicket(TicketType<T> type, ChunkPos pos, int distance, T value) {
|
||||
Ticket<T> ticket = new Ticket<>(type, ChunkLevel.byStatus(FullChunkStatus.FULL) - distance, value);
|
||||
long packedChunkPos = pos.toLong();
|
||||
+ this.removeTicket(packedChunkPos, ticket); // Paper - diff on change above
|
||||
+ this.tickingTicketsTracker.removeTicket(packedChunkPos, ticket);
|
||||
+ }
|
||||
+
|
||||
+ // Paper start
|
||||
+ public boolean addPluginRegionTicket(final ChunkPos pos, final org.bukkit.plugin.Plugin value) {
|
||||
+ Ticket<org.bukkit.plugin.Plugin> ticket = new Ticket<>(TicketType.PLUGIN_TICKET, ChunkLevel.byStatus(FullChunkStatus.FULL) - 2, value); // Copied from below and keep in-line with force loading, add at level 31
|
||||
+ final long packedChunkPos = pos.toLong();
|
||||
+ final Set<Ticket<?>> tickets = this.getTickets(packedChunkPos);
|
||||
+ if (tickets.contains(ticket)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ this.addTicket(packedChunkPos, ticket);
|
||||
+ this.tickingTicketsTracker.addTicket(packedChunkPos, ticket);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ public boolean removePluginRegionTicket(final ChunkPos pos, final org.bukkit.plugin.Plugin value) {
|
||||
+ Ticket<org.bukkit.plugin.Plugin> ticket = new Ticket<>(TicketType.PLUGIN_TICKET, ChunkLevel.byStatus(FullChunkStatus.FULL) - 2, value); // Copied from below and keep in-line with force loading, add at level 31
|
||||
+ final long packedChunkPos = pos.toLong();
|
||||
+ final Set<Ticket<?>> tickets = this.tickets.get(packedChunkPos); // Don't use getTickets, we don't want to create a new set
|
||||
+ if (tickets == null || !tickets.contains(ticket)) {
|
||||
+ return false;
|
||||
+ }
|
||||
this.removeTicket(packedChunkPos, ticket);
|
||||
this.tickingTicketsTracker.removeTicket(packedChunkPos, ticket);
|
||||
+ return true;
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
private SortedArraySet<Ticket<?>> getTickets(long chunkPos) {
|
||||
return this.tickets.computeIfAbsent(chunkPos, l -> SortedArraySet.create(4));
|
||||
@@ -217,8 +_,10 @@
|
||||
@@ -121,8 +_,10 @@
|
||||
ChunkPos chunkPos = sectionPos.chunk();
|
||||
long packedChunkPos = chunkPos.toLong();
|
||||
ObjectSet<ServerPlayer> set = this.playersPerChunk.get(packedChunkPos);
|
||||
@@ -70,39 +35,3 @@
|
||||
this.playersPerChunk.remove(packedChunkPos);
|
||||
this.naturalSpawnChunkCounter.update(packedChunkPos, Integer.MAX_VALUE, false);
|
||||
this.playerTicketManager.update(packedChunkPos, Integer.MAX_VALUE, false);
|
||||
@@ -299,7 +_,7 @@
|
||||
}
|
||||
|
||||
public void removeTicketsOnClosing() {
|
||||
- ImmutableSet<TicketType<?>> set = ImmutableSet.of(TicketType.UNKNOWN);
|
||||
+ ImmutableSet<TicketType<?>> set = ImmutableSet.of(TicketType.UNKNOWN, TicketType.POST_TELEPORT, TicketType.FUTURE_AWAIT); // Paper - add additional tickets to preserve
|
||||
ObjectIterator<Entry<SortedArraySet<Ticket<?>>>> objectIterator = this.tickets.long2ObjectEntrySet().fastIterator();
|
||||
|
||||
while (objectIterator.hasNext()) {
|
||||
@@ -329,6 +_,26 @@
|
||||
public boolean hasTickets() {
|
||||
return !this.tickets.isEmpty();
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ public <T> void removeAllTicketsFor(TicketType<T> ticketType, int ticketLevel, T ticketIdentifier) {
|
||||
+ Ticket<T> target = new Ticket<>(ticketType, ticketLevel, ticketIdentifier);
|
||||
+
|
||||
+ for (java.util.Iterator<Entry<SortedArraySet<Ticket<?>>>> iterator = this.tickets.long2ObjectEntrySet().fastIterator(); iterator.hasNext();) {
|
||||
+ Entry<SortedArraySet<Ticket<?>>> entry = iterator.next();
|
||||
+ SortedArraySet<Ticket<?>> tickets = entry.getValue();
|
||||
+ if (tickets.remove(target)) {
|
||||
+ // copied from removeTicket
|
||||
+ this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt(tickets), false);
|
||||
+
|
||||
+ // can't use entry after it's removed
|
||||
+ if (tickets.isEmpty()) {
|
||||
+ iterator.remove();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
class ChunkTicketTracker extends ChunkTracker {
|
||||
private static final int MAX_LEVEL = ChunkLevel.MAX_LEVEL + 1;
|
||||
+19
-28
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -73,6 +_,13 @@
|
||||
@@ -77,6 +_,13 @@
|
||||
@Nullable
|
||||
@VisibleForDebug
|
||||
private NaturalSpawner.SpawnState lastSpawnState;
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
public ServerChunkCache(
|
||||
ServerLevel level,
|
||||
@@ -121,6 +_,64 @@
|
||||
@@ -127,6 +_,64 @@
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
@@ -46,12 +46,12 @@
|
||||
+ return holder.getLatestChunk();
|
||||
+ }
|
||||
+
|
||||
+ public <T> void addTicketAtLevel(TicketType<T> ticketType, ChunkPos chunkPos, int ticketLevel, T identifier) {
|
||||
+ this.distanceManager.addTicket(ticketType, chunkPos, ticketLevel, identifier);
|
||||
+ public <T> void addTicketAtLevel(TicketType ticketType, ChunkPos chunkPos, int ticketLevel, T identifier) {
|
||||
+ this.distanceManager.ticketStorage.addTicketWithRadius(ticketType, chunkPos, ticketLevel);
|
||||
+ }
|
||||
+
|
||||
+ public <T> void removeTicketAtLevel(TicketType<T> ticketType, ChunkPos chunkPos, int ticketLevel, T identifier) {
|
||||
+ this.distanceManager.removeTicket(ticketType, chunkPos, ticketLevel, identifier);
|
||||
+ public <T> void removeTicketAtLevel(TicketType ticketType, ChunkPos chunkPos, int ticketLevel, T identifier) {
|
||||
+ this.distanceManager.ticketStorage.removeTicketWithRadius(ticketType, chunkPos, ticketLevel);
|
||||
+ }
|
||||
+
|
||||
+ // "real" get chunk if loaded
|
||||
@@ -79,7 +79,7 @@
|
||||
@Override
|
||||
public ThreadedLevelLightEngine getLightEngine() {
|
||||
return this.lightEngine;
|
||||
@@ -160,7 +_,7 @@
|
||||
@@ -166,7 +_,7 @@
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (packedChunkPos == this.lastChunkPos[i] && chunkStatus == this.lastChunkStatus[i]) {
|
||||
ChunkAccess chunkAccess = this.lastChunk[i];
|
||||
@@ -88,7 +88,7 @@
|
||||
return chunkAccess;
|
||||
}
|
||||
}
|
||||
@@ -169,6 +_,7 @@
|
||||
@@ -175,6 +_,7 @@
|
||||
profilerFiller.incrementCounter("getChunkCacheMiss");
|
||||
CompletableFuture<ChunkResult<ChunkAccess>> chunkFutureMainThread = this.getChunkFutureMainThread(x, z, chunkStatus, requireChunk);
|
||||
this.mainThreadProcessor.managedBlock(chunkFutureMainThread::isDone);
|
||||
@@ -96,7 +96,7 @@
|
||||
ChunkResult<ChunkAccess> chunkResult = chunkFutureMainThread.join();
|
||||
ChunkAccess chunkAccess1 = chunkResult.orElse(null);
|
||||
if (chunkAccess1 == null && requireChunk) {
|
||||
@@ -240,7 +_,15 @@
|
||||
@@ -246,7 +_,15 @@
|
||||
long packedChunkPos = chunkPos.toLong();
|
||||
int i = ChunkLevel.byStatus(chunkStatus);
|
||||
ChunkHolder visibleChunkIfPresent = this.getVisibleChunkIfPresent(packedChunkPos);
|
||||
@@ -109,11 +109,11 @@
|
||||
+ currentlyUnloading = (oldChunkState.isOrAfter(FullChunkStatus.FULL) && !currentChunkState.isOrAfter(FullChunkStatus.FULL));
|
||||
+ }
|
||||
+ if (requireChunk && !currentlyUnloading) {
|
||||
+ // CraftBukkit end
|
||||
this.distanceManager.addTicket(TicketType.UNKNOWN, chunkPos, i, chunkPos);
|
||||
+ // CraftBukkit end
|
||||
this.addTicket(new Ticket(TicketType.UNKNOWN, i), chunkPos);
|
||||
if (this.chunkAbsent(visibleChunkIfPresent, i)) {
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
@@ -260,7 +_,7 @@
|
||||
@@ -266,7 +_,7 @@
|
||||
}
|
||||
|
||||
private boolean chunkAbsent(@Nullable ChunkHolder chunkHolder, int status) {
|
||||
@@ -122,7 +122,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -287,7 +_,7 @@
|
||||
@@ -293,7 +_,7 @@
|
||||
return this.mainThreadProcessor.pollTask();
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
boolean flag = this.distanceManager.runAllUpdates(this.chunkMap);
|
||||
boolean flag1 = this.chunkMap.promoteChunkMap();
|
||||
this.chunkMap.runGenerationTasks();
|
||||
@@ -315,17 +_,39 @@
|
||||
@@ -321,17 +_,39 @@
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
@@ -155,7 +155,7 @@
|
||||
+ ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||
+
|
||||
+ gameprofilerfiller.push("purge");
|
||||
+ this.distanceManager.purgeStaleTickets();
|
||||
+ this.ticketStorage.purgeStaleTickets();
|
||||
+ this.runDistanceManagerUpdates();
|
||||
+ gameprofilerfiller.popPush("unload");
|
||||
+ this.chunkMap.tick(() -> true);
|
||||
@@ -170,10 +170,10 @@
|
||||
profilerFiller.push("purge");
|
||||
- if (this.level.tickRateManager().runsNormally() || !tickChunks) {
|
||||
+ if (this.level.tickRateManager().runsNormally() || !tickChunks || this.level.spigotConfig.unloadFrozenChunks) { // Spigot
|
||||
this.distanceManager.purgeStaleTickets();
|
||||
this.ticketStorage.purgeStaleTickets();
|
||||
}
|
||||
|
||||
@@ -400,12 +_,20 @@
|
||||
@@ -388,12 +_,20 @@
|
||||
);
|
||||
this.lastSpawnState = spawnState;
|
||||
profiler.popPush("spawnAndTick");
|
||||
@@ -197,16 +197,7 @@
|
||||
} else {
|
||||
filteredSpawningCategories = List.of();
|
||||
}
|
||||
@@ -413,7 +_,7 @@
|
||||
for (LevelChunk levelChunk : chunks) {
|
||||
ChunkPos pos = levelChunk.getPos();
|
||||
levelChunk.incrementInhabitedTime(timeInhabited);
|
||||
- if (!filteredSpawningCategories.isEmpty() && this.level.getWorldBorder().isWithinBounds(pos)) {
|
||||
+ if (!filteredSpawningCategories.isEmpty() && this.level.getWorldBorder().isWithinBounds(pos) && this.chunkMap.anyPlayerCloseEnoughForSpawning(pos, true)) { // Spigot
|
||||
NaturalSpawner.spawnForChunk(this.level, levelChunk, spawnState, filteredSpawningCategories);
|
||||
}
|
||||
|
||||
@@ -526,8 +_,13 @@
|
||||
@@ -544,8 +_,13 @@
|
||||
|
||||
@Override
|
||||
public void setSpawnSettings(boolean spawnSettings) {
|
||||
@@ -221,7 +212,7 @@
|
||||
}
|
||||
|
||||
public String getChunkDebugData(ChunkPos chunkPos) {
|
||||
@@ -603,12 +_,18 @@
|
||||
@@ -618,12 +_,18 @@
|
||||
|
||||
@Override
|
||||
public boolean pollTask() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -65,13 +_,17 @@
|
||||
@@ -69,11 +_,12 @@
|
||||
private Vec3 lastSentMovement;
|
||||
private int tickCount;
|
||||
private int teleportDelay;
|
||||
@@ -10,26 +10,25 @@
|
||||
private boolean wasOnGround;
|
||||
@Nullable
|
||||
private List<SynchedEntityData.DataValue<?>> trackedDataValues;
|
||||
+ private final Set<net.minecraft.server.network.ServerPlayerConnection> trackedPlayers; // Paper
|
||||
|
||||
- public ServerEntity(ServerLevel level, Entity entity, int updateInterval, boolean trackDelta, Consumer<Packet<?>> broadcast) {
|
||||
+ // CraftBukkit start
|
||||
+ private final Set<net.minecraft.server.network.ServerPlayerConnection> trackedPlayers;
|
||||
+ public ServerEntity(ServerLevel level, Entity entity, int updateInterval, boolean trackDelta, Consumer<Packet<?>> broadcast, final Set<net.minecraft.server.network.ServerPlayerConnection> trackedPlayers) {
|
||||
+ this.trackedPlayers = trackedPlayers;
|
||||
+ // CraftBukkit end
|
||||
public ServerEntity(
|
||||
ServerLevel level,
|
||||
@@ -81,8 +_,12 @@
|
||||
int updateInterval,
|
||||
boolean trackDelta,
|
||||
Consumer<Packet<?>> broadcast,
|
||||
- BiConsumer<Packet<?>, List<UUID>> broadcastWithIgnore
|
||||
+ // Paper start
|
||||
+ BiConsumer<Packet<?>, List<UUID>> broadcastWithIgnore,
|
||||
+ final Set<net.minecraft.server.network.ServerPlayerConnection> trackedPlayers
|
||||
+ // Paper end
|
||||
) {
|
||||
+ this.trackedPlayers = trackedPlayers; // Paper
|
||||
this.level = level;
|
||||
this.broadcast = broadcast;
|
||||
this.entity = entity;
|
||||
@@ -89,7 +_,7 @@
|
||||
public void sendChanges() {
|
||||
List<Entity> passengers = this.entity.getPassengers();
|
||||
if (!passengers.equals(this.lastPassengers)) {
|
||||
- this.broadcast.accept(new ClientboundSetPassengersPacket(this.entity));
|
||||
+ this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity)); // CraftBukkit
|
||||
removedPassengers(passengers, this.lastPassengers)
|
||||
.forEach(
|
||||
removedPassenger -> {
|
||||
@@ -102,13 +_,14 @@
|
||||
@@ -106,13 +_,14 @@
|
||||
this.lastPassengers = passengers;
|
||||
}
|
||||
|
||||
@@ -48,7 +47,7 @@
|
||||
savedData.tickCarriedBy(serverPlayer, item);
|
||||
Packet<?> updatePacket = savedData.getUpdatePacket(mapId, serverPlayer);
|
||||
if (updatePacket != null) {
|
||||
@@ -141,7 +_,13 @@
|
||||
@@ -145,7 +_,13 @@
|
||||
} else {
|
||||
this.teleportDelay++;
|
||||
Vec3 vec3 = this.entity.trackingPosition();
|
||||
@@ -63,7 +62,7 @@
|
||||
Packet<?> packet = null;
|
||||
boolean flag2 = flag1 || this.tickCount % 60 == 0;
|
||||
boolean flag3 = false;
|
||||
@@ -219,6 +_,25 @@
|
||||
@@ -223,6 +_,25 @@
|
||||
|
||||
this.tickCount++;
|
||||
if (this.entity.hurtMarked) {
|
||||
@@ -89,7 +88,7 @@
|
||||
this.entity.hurtMarked = false;
|
||||
this.broadcastAndSend(new ClientboundSetEntityMotionPacket(this.entity));
|
||||
}
|
||||
@@ -273,7 +_,10 @@
|
||||
@@ -280,7 +_,10 @@
|
||||
|
||||
public void sendPairingData(ServerPlayer player, Consumer<Packet<ClientGamePacketListener>> consumer) {
|
||||
if (this.entity.isRemoved()) {
|
||||
@@ -101,7 +100,7 @@
|
||||
}
|
||||
|
||||
Packet<ClientGamePacketListener> addEntityPacket = this.entity.getAddEntityPacket(this);
|
||||
@@ -285,6 +_,12 @@
|
||||
@@ -292,6 +_,12 @@
|
||||
boolean flag = this.trackDelta;
|
||||
if (this.entity instanceof LivingEntity) {
|
||||
Collection<AttributeInstance> syncableAttributes = ((LivingEntity)this.entity).getAttributes().getSyncableAttributes();
|
||||
@@ -114,7 +113,7 @@
|
||||
if (!syncableAttributes.isEmpty()) {
|
||||
consumer.accept(new ClientboundUpdateAttributesPacket(this.entity.getId(), syncableAttributes));
|
||||
}
|
||||
@@ -309,8 +_,9 @@
|
||||
@@ -316,8 +_,9 @@
|
||||
}
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
@@ -125,7 +124,7 @@
|
||||
}
|
||||
|
||||
if (!this.entity.getPassengers().isEmpty()) {
|
||||
@@ -357,6 +_,11 @@
|
||||
@@ -364,6 +_,11 @@
|
||||
if (this.entity instanceof LivingEntity) {
|
||||
Set<AttributeInstance> attributesToSync = ((LivingEntity)this.entity).getAttributes().getAttributesToSync();
|
||||
if (!attributesToSync.isEmpty()) {
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
--- a/net/minecraft/server/level/TicketType.java
|
||||
+++ b/net/minecraft/server/level/TicketType.java
|
||||
@@ -7,6 +_,7 @@
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
@@ -2,6 +_,7 @@
|
||||
|
||||
public class TicketType<T> {
|
||||
+ public static final TicketType<Long> FUTURE_AWAIT = create("future_await", Long::compareTo); // Paper
|
||||
private final String name;
|
||||
private final Comparator<T> comparator;
|
||||
public long timeout;
|
||||
@@ -17,6 +_,9 @@
|
||||
public static final TicketType<BlockPos> PORTAL = create("portal", Vec3i::compareTo, 300);
|
||||
public static final TicketType<ChunkPos> ENDER_PEARL = create("ender_pearl", Comparator.comparingLong(ChunkPos::toLong), 40);
|
||||
public static final TicketType<ChunkPos> UNKNOWN = create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1);
|
||||
+ public static final TicketType<Unit> PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit
|
||||
+ public static final TicketType<org.bukkit.plugin.Plugin> PLUGIN_TICKET = TicketType.create("plugin_ticket", (plugin1, plugin2) -> plugin1.getClass().getName().compareTo(plugin2.getClass().getName())); // CraftBukkit
|
||||
+ public static final TicketType<Integer> POST_TELEPORT = TicketType.create("post_teleport", Integer::compare, 5); // Paper - post teleport ticket type
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
+import net.minecraft.util.Unit;
|
||||
|
||||
public static <T> TicketType<T> create(String name, Comparator<T> comparator) {
|
||||
return new TicketType<>(name, comparator, 0L);
|
||||
public record TicketType(long timeout, boolean persist, TicketType.TicketUse use) {
|
||||
public static final long NO_TIMEOUT = 0L;
|
||||
@@ -13,6 +_,10 @@
|
||||
public static final TicketType PORTAL = register("portal", 300L, true, TicketType.TicketUse.LOADING_AND_SIMULATION);
|
||||
public static final TicketType ENDER_PEARL = register("ender_pearl", 40L, false, TicketType.TicketUse.LOADING_AND_SIMULATION);
|
||||
public static final TicketType UNKNOWN = register("unknown", 1L, false, TicketType.TicketUse.LOADING);
|
||||
+ public static final TicketType PLUGIN = register("plugin", 0L, false, TicketType.TicketUse.LOADING_AND_SIMULATION); // CraftBukkit
|
||||
+ public static final TicketType POST_TELEPORT = register("post_teleport", 5L, false, TicketType.TicketUse.LOADING_AND_SIMULATION); // Paper
|
||||
+ public static final TicketType PLUGIN_TICKET = register("plugin_ticket", 0L, false, TicketType.TicketUse.LOADING_AND_SIMULATION); // Paper
|
||||
+ public static final TicketType FUTURE_AWAIT = register("future_await", 0L, false, TicketType.TicketUse.LOADING_AND_SIMULATION); // Paper
|
||||
|
||||
private static TicketType register(String name, long timeout, boolean persist, TicketType.TicketUse use) {
|
||||
return Registry.register(BuiltInRegistries.TICKET_TYPE, name, new TicketType(timeout, persist, use));
|
||||
@@ -71,10 +71,10 @@
|
||||
return false;
|
||||
} else {
|
||||
ChunkAccess chunk = this.getChunk(pos);
|
||||
- BlockState blockState = chunk.setBlockState(pos, state, false);
|
||||
+ BlockState blockState = chunk.setBlockState(pos, state, false); final BlockState previousBlockState = blockState; // Paper - Clear block entity before setting up a DUMMY block entity - obfhelper
|
||||
- BlockState blockState = chunk.setBlockState(pos, state, flags);
|
||||
+ BlockState blockState = chunk.setBlockState(pos, state, flags); final BlockState previousBlockState = blockState; // Paper - Clear block entity before setting up a DUMMY block entity - obfhelper
|
||||
if (blockState != null) {
|
||||
this.level.onBlockStateChange(pos, blockState, state);
|
||||
this.level.updatePOIOnBlockStateChange(pos, blockState, state);
|
||||
}
|
||||
@@ -294,6 +_,17 @@
|
||||
chunk.removeBlockEntity(pos);
|
||||
|
||||
+503
-494
File diff suppressed because it is too large.
Load diff
+20
-19
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -56,6 +_,10 @@
|
||||
@@ -54,6 +_,10 @@
|
||||
private final AtomicLong operationCount = new AtomicLong();
|
||||
@Nullable
|
||||
private Executor executor;
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
public GameProfileCache(GameProfileRepository profileRepository, File file) {
|
||||
this.profileRepository = profileRepository;
|
||||
@@ -64,10 +_,12 @@
|
||||
@@ -62,17 +_,21 @@
|
||||
}
|
||||
|
||||
private void safeAdd(GameProfileCache.GameProfileInfo profile) {
|
||||
@@ -24,16 +24,17 @@
|
||||
}
|
||||
|
||||
private static Optional<GameProfile> lookupGameProfile(GameProfileRepository profileRepo, String name) {
|
||||
@@ -86,6 +_,8 @@
|
||||
atomicReference.set(null);
|
||||
}
|
||||
};
|
||||
+ if (!org.apache.commons.lang3.StringUtils.isBlank(name) // Paper - Don't lookup a profile with a blank name
|
||||
+ && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()) // Paper - Add setting for proxy online mode status
|
||||
profileRepo.findProfilesByNames(new String[]{name}, profileLookupCallback);
|
||||
GameProfile gameProfile = atomicReference.get();
|
||||
return gameProfile != null ? Optional.of(gameProfile) : createUnknownProfile(name);
|
||||
@@ -101,7 +_,7 @@
|
||||
if (!StringUtil.isValidPlayerName(name)) {
|
||||
return createUnknownProfile(name);
|
||||
} else {
|
||||
- Optional<GameProfile> optional = profileRepo.findProfileByName(name);
|
||||
+ final boolean shouldLookup = !org.apache.commons.lang3.StringUtils.isBlank(name) // Paper - Don't lookup a profile with a blank name
|
||||
+ && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode(); // Paper - Add setting for proxy online mode status
|
||||
+ Optional<GameProfile> optional = shouldLookup ? profileRepo.findProfileByName(name) : Optional.empty(); // Paper - Don't lookup a profile with a blank name
|
||||
return optional.isEmpty() ? createUnknownProfile(name) : optional;
|
||||
}
|
||||
}
|
||||
@@ -86,7 +_,7 @@
|
||||
}
|
||||
|
||||
private static boolean usesAuthentication() {
|
||||
@@ -42,7 +43,7 @@
|
||||
}
|
||||
|
||||
public void add(GameProfile gameProfile) {
|
||||
@@ -111,15 +_,29 @@
|
||||
@@ -96,15 +_,29 @@
|
||||
Date time = instance.getTime();
|
||||
GameProfileCache.GameProfileInfo gameProfileInfo = new GameProfileCache.GameProfileInfo(gameProfile, time);
|
||||
this.safeAdd(gameProfileInfo);
|
||||
@@ -73,7 +74,7 @@
|
||||
GameProfileCache.GameProfileInfo gameProfileInfo = this.profilesByName.get(string);
|
||||
boolean flag = false;
|
||||
if (gameProfileInfo != null && new Date().getTime() >= gameProfileInfo.expirationDate.getTime()) {
|
||||
@@ -133,19 +_,24 @@
|
||||
@@ -118,19 +_,24 @@
|
||||
if (gameProfileInfo != null) {
|
||||
gameProfileInfo.setLastAccess(this.getNextOperation());
|
||||
optional = Optional.of(gameProfileInfo.getProfile());
|
||||
@@ -101,7 +102,7 @@
|
||||
}
|
||||
|
||||
public CompletableFuture<Optional<GameProfile>> getAsync(String name) {
|
||||
@@ -157,7 +_,7 @@
|
||||
@@ -142,7 +_,7 @@
|
||||
return completableFuture;
|
||||
} else {
|
||||
CompletableFuture<Optional<GameProfile>> completableFuture1 = CompletableFuture.<Optional<GameProfile>>supplyAsync(
|
||||
@@ -110,7 +111,7 @@
|
||||
)
|
||||
.whenCompleteAsync((gameProfile, exception) -> this.requests.remove(name), this.executor);
|
||||
this.requests.put(name, completableFuture1);
|
||||
@@ -167,6 +_,7 @@
|
||||
@@ -152,6 +_,7 @@
|
||||
}
|
||||
|
||||
public Optional<GameProfile> get(UUID uuid) {
|
||||
@@ -118,7 +119,7 @@
|
||||
GameProfileCache.GameProfileInfo gameProfileInfo = this.profilesByUUID.get(uuid);
|
||||
if (gameProfileInfo == null) {
|
||||
return Optional.empty();
|
||||
@@ -174,6 +_,7 @@
|
||||
@@ -159,6 +_,7 @@
|
||||
gameProfileInfo.setLastAccess(this.getNextOperation());
|
||||
return Optional.of(gameProfileInfo.getProfile());
|
||||
}
|
||||
@@ -126,7 +127,7 @@
|
||||
}
|
||||
|
||||
public void setExecutor(Executor exectutor) {
|
||||
@@ -206,6 +_,11 @@
|
||||
@@ -191,6 +_,11 @@
|
||||
|
||||
return (List<GameProfileCache.GameProfileInfo>)var9;
|
||||
} catch (FileNotFoundException var7) {
|
||||
@@ -138,7 +139,7 @@
|
||||
} catch (JsonParseException | IOException var8) {
|
||||
LOGGER.warn("Failed to load profile cache {}", this.file, var8);
|
||||
}
|
||||
@@ -213,24 +_,45 @@
|
||||
@@ -198,24 +_,45 @@
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
GameProfile gameProfile = player.getGameProfile();
|
||||
GameProfileCache profileCache = this.server.getProfileCache();
|
||||
String string;
|
||||
@@ -150,30 +_,93 @@
|
||||
@@ -150,30 +_,94 @@
|
||||
}
|
||||
|
||||
Optional<CompoundTag> optional = this.load(player);
|
||||
@@ -55,11 +55,7 @@
|
||||
- compoundTag -> DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, compoundTag.get("Dimension"))).resultOrPartial(LOGGER::error)
|
||||
+ // CraftBukkit start - Better rename detection
|
||||
+ if (optional.isPresent()) {
|
||||
+ CompoundTag nbttagcompound = optional.get();
|
||||
+ if (nbttagcompound.contains("bukkit")) {
|
||||
+ CompoundTag bukkit = nbttagcompound.getCompound("bukkit");
|
||||
+ string = bukkit.contains("lastKnownName", 8) ? bukkit.getString("lastKnownName") : string;
|
||||
+ }
|
||||
+ string = optional.flatMap(t -> t.getCompound("bukkit")).flatMap(t -> t.getString("lastKnownName")).orElse(string);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found
|
||||
@@ -68,10 +64,15 @@
|
||||
+ bukkitData: if (optional.isPresent()) {
|
||||
+ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds
|
||||
+ final org.bukkit.World bWorld;
|
||||
+ if (optional.get().contains("WorldUUIDMost") && optional.get().contains("WorldUUIDLeast")) {
|
||||
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(new UUID(optional.get().getLong("WorldUUIDMost"), optional.get().getLong("WorldUUIDLeast")));
|
||||
+ } else if (optional.get().contains("world", net.minecraft.nbt.Tag.TAG_STRING)) { // Paper - legacy bukkit world name
|
||||
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(optional.get().getString("world"));
|
||||
+ final CompoundTag playerData = optional.get();
|
||||
+ // TODO maybe convert this to a codec and use compoundTag#read, we need silent variants of that method first.
|
||||
+ final Optional<Long> worldUUIDMost = playerData.getLong("WorldUUIDMost");
|
||||
+ final Optional<Long> worldUUIDLeast = playerData.getLong("WorldUUIDLeast");
|
||||
+ final java.util.Optional<String> worldName = playerData.getString("world");
|
||||
+ if (worldUUIDMost.isPresent() && worldUUIDLeast.isPresent()) {
|
||||
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(new UUID(worldUUIDMost.get(), worldUUIDLeast.get()));
|
||||
+ } else if (worldName.isPresent()) { // Paper - legacy bukkit world name
|
||||
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(worldName.get());
|
||||
+ } else {
|
||||
+ break bukkitData; // if neither of the bukkit data points exist, proceed to the vanilla migration section
|
||||
+ }
|
||||
@@ -113,7 +114,7 @@
|
||||
+ }
|
||||
+ if (optional.isEmpty() || invalidPlayerWorld[0]) {
|
||||
+ // Paper end - reset to main world spawn if first spawn or invalid world
|
||||
+ player.moveTo(player.adjustSpawnLocation(serverLevel, serverLevel.getSharedSpawnPos()).getBottomCenter(), serverLevel.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored
|
||||
+ player.snapTo(player.adjustSpawnLocation(serverLevel, serverLevel.getSharedSpawnPos()).getBottomCenter(), serverLevel.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored
|
||||
+ }
|
||||
+ // Paper end - Entity#getEntitySpawnReason
|
||||
player.setServerLevel(serverLevel);
|
||||
@@ -153,7 +154,7 @@
|
||||
LevelData levelData = serverLevel.getLevelData();
|
||||
player.loadGameTypes(optional.orElse(null));
|
||||
ServerGamePacketListenerImpl serverGamePacketListenerImpl = new ServerGamePacketListenerImpl(this.server, connection, player, cookie);
|
||||
@@ -190,8 +_,8 @@
|
||||
@@ -191,8 +_,8 @@
|
||||
levelData.isHardcore(),
|
||||
this.server.levelKeys(),
|
||||
this.getMaxPlayers(),
|
||||
@@ -164,15 +165,15 @@
|
||||
_boolean1,
|
||||
!_boolean,
|
||||
_boolean2,
|
||||
@@ -199,6 +_,7 @@
|
||||
@@ -200,6 +_,7 @@
|
||||
this.server.enforceSecureProfile()
|
||||
)
|
||||
);
|
||||
+ player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
|
||||
serverGamePacketListenerImpl.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
|
||||
serverGamePacketListenerImpl.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities()));
|
||||
serverGamePacketListenerImpl.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected));
|
||||
@@ -218,24 +_,117 @@
|
||||
serverGamePacketListenerImpl.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot()));
|
||||
@@ -219,26 +_,119 @@
|
||||
mutableComponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), string);
|
||||
}
|
||||
|
||||
@@ -201,8 +202,10 @@
|
||||
- this.sendActivePlayerEffects(player);
|
||||
+ this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below serverLevel.addPlayerJoin(player);
|
||||
+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
|
||||
player.loadAndSpawnEnderpearls(optional);
|
||||
player.loadAndSpawnParentVehicle(optional);
|
||||
optional.ifPresent(compoundTag -> {
|
||||
player.loadAndSpawnEnderPearls(compoundTag);
|
||||
player.loadAndSpawnParentVehicle(compoundTag);
|
||||
});
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.craftbukkit.entity.CraftPlayer bukkitPlayer = player.getBukkitEntity();
|
||||
+
|
||||
@@ -296,7 +299,7 @@
|
||||
}
|
||||
|
||||
public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {
|
||||
@@ -258,30 +_,31 @@
|
||||
@@ -261,30 +_,31 @@
|
||||
}
|
||||
|
||||
public void addWorldborderListener(ServerLevel level) {
|
||||
@@ -333,7 +336,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -309,56 +_,162 @@
|
||||
@@ -312,56 +_,162 @@
|
||||
}
|
||||
|
||||
protected void save(ServerPlayer player) {
|
||||
@@ -510,7 +513,7 @@
|
||||
MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned.reason", userBanListEntry.getReason());
|
||||
if (userBanListEntry.getExpires() != null) {
|
||||
mutableComponent.append(
|
||||
@@ -366,10 +_,12 @@
|
||||
@@ -369,10 +_,12 @@
|
||||
);
|
||||
}
|
||||
|
||||
@@ -527,7 +530,7 @@
|
||||
IpBanListEntry ipBanListEntry = this.ipBans.get(socketAddress);
|
||||
MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipBanListEntry.getReason());
|
||||
if (ipBanListEntry.getExpires() != null) {
|
||||
@@ -378,69 +_,129 @@
|
||||
@@ -381,69 +_,129 @@
|
||||
);
|
||||
}
|
||||
|
||||
@@ -677,9 +680,9 @@
|
||||
+ serverPlayer.unsetRemoved();
|
||||
+ serverPlayer.setShiftKeyDown(false);
|
||||
Vec3 vec3 = teleportTransition.position();
|
||||
- serverPlayer.moveTo(vec3.x, vec3.y, vec3.z, teleportTransition.yRot(), teleportTransition.xRot());
|
||||
- serverPlayer.snapTo(vec3.x, vec3.y, vec3.z, teleportTransition.yRot(), teleportTransition.xRot());
|
||||
+ serverPlayer.forceSetPositionRotation(vec3.x, vec3.y, vec3.z, teleportTransition.yRot(), teleportTransition.xRot());
|
||||
+ level.getChunkSource().addRegionTicket(net.minecraft.server.level.TicketType.POST_TELEPORT, new net.minecraft.world.level.ChunkPos(net.minecraft.util.Mth.floor(vec3.x()) >> 4, net.minecraft.util.Mth.floor(vec3.z()) >> 4), 1, player.getId()); // Paper - post teleport ticket type
|
||||
+ level.getChunkSource().addTicketWithRadius(net.minecraft.server.level.TicketType.POST_TELEPORT, new net.minecraft.world.level.ChunkPos(net.minecraft.util.Mth.floor(vec3.x()) >> 4, net.minecraft.util.Mth.floor(vec3.z()) >> 4), 1); // Paper - post teleport ticket type
|
||||
+ // CraftBukkit end
|
||||
if (teleportTransition.missingRespawnBlock()) {
|
||||
serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F));
|
||||
@@ -698,7 +701,7 @@
|
||||
serverPlayer.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getSharedSpawnPos(), level.getSharedSpawnAngle()));
|
||||
serverPlayer.connection.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
|
||||
serverPlayer.connection
|
||||
@@ -448,10 +_,13 @@
|
||||
@@ -451,10 +_,13 @@
|
||||
this.sendActivePlayerEffects(serverPlayer);
|
||||
this.sendLevelInfo(serverPlayer, level);
|
||||
this.sendPlayerPermissionLevel(serverPlayer);
|
||||
@@ -714,19 +717,19 @@
|
||||
+ }
|
||||
+ // serverPlayer.initInventoryMenu();
|
||||
serverPlayer.setHealth(serverPlayer.getHealth());
|
||||
BlockPos respawnPosition = serverPlayer.getRespawnPosition();
|
||||
ServerLevel level1 = this.server.getLevel(serverPlayer.getRespawnDimension());
|
||||
@@ -472,7 +_,40 @@
|
||||
)
|
||||
);
|
||||
ServerPlayer.RespawnConfig respawnConfig = serverPlayer.getRespawnConfig();
|
||||
if (!keepInventory && respawnConfig != null) {
|
||||
@@ -477,8 +_,41 @@
|
||||
)
|
||||
);
|
||||
}
|
||||
+ // Paper start - Add PlayerPostRespawnEvent
|
||||
+ if (blockState.is(net.minecraft.tags.BlockTags.BEDS) && !teleportTransition.missingRespawnBlock()) {
|
||||
+ isBedSpawn = true;
|
||||
+ }
|
||||
+ // Paper end - Add PlayerPostRespawnEvent
|
||||
}
|
||||
- }
|
||||
+ // Paper start - Add PlayerPostRespawnEvent
|
||||
+ if (blockState.is(net.minecraft.tags.BlockTags.BEDS) && !teleportTransition.missingRespawnBlock()) {
|
||||
+ isBedSpawn = true;
|
||||
+ }
|
||||
+ // Paper end - Add PlayerPostRespawnEvent
|
||||
+ }
|
||||
}
|
||||
+ // Added from changeDimension
|
||||
+ this.sendAllPlayerInfo(player); // Update health, etc...
|
||||
+ player.onUpdateAbilities();
|
||||
@@ -758,7 +761,7 @@
|
||||
|
||||
return serverPlayer;
|
||||
}
|
||||
@@ -482,24 +_,60 @@
|
||||
@@ -488,24 +_,60 @@
|
||||
}
|
||||
|
||||
public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl connection) {
|
||||
@@ -822,7 +825,7 @@
|
||||
public void broadcastAll(Packet<?> packet) {
|
||||
for (ServerPlayer serverPlayer : this.players) {
|
||||
serverPlayer.connection.send(packet);
|
||||
@@ -575,6 +_,11 @@
|
||||
@@ -581,6 +_,11 @@
|
||||
}
|
||||
|
||||
private void sendPlayerPermissionLevel(ServerPlayer player, int permLevel) {
|
||||
@@ -834,7 +837,7 @@
|
||||
if (player.connection != null) {
|
||||
byte b;
|
||||
if (permLevel <= 0) {
|
||||
@@ -588,11 +_,32 @@
|
||||
@@ -594,11 +_,32 @@
|
||||
player.connection.send(new ClientboundEntityEventPacket(player, b));
|
||||
}
|
||||
|
||||
@@ -868,7 +871,7 @@
|
||||
}
|
||||
|
||||
public boolean isOp(GameProfile profile) {
|
||||
@@ -603,21 +_,17 @@
|
||||
@@ -609,21 +_,17 @@
|
||||
|
||||
@Nullable
|
||||
public ServerPlayer getPlayerByName(String username) {
|
||||
@@ -896,7 +899,7 @@
|
||||
if (serverPlayer != except && serverPlayer.level().dimension() == dimension) {
|
||||
double d = x - serverPlayer.getX();
|
||||
double d1 = y - serverPlayer.getY();
|
||||
@@ -630,9 +_,11 @@
|
||||
@@ -636,9 +_,11 @@
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
@@ -908,7 +911,7 @@
|
||||
}
|
||||
|
||||
public UserWhiteList getWhiteList() {
|
||||
@@ -655,14 +_,18 @@
|
||||
@@ -661,14 +_,18 @@
|
||||
}
|
||||
|
||||
public void sendLevelInfo(ServerPlayer player, ServerLevel level) {
|
||||
@@ -931,7 +934,7 @@
|
||||
}
|
||||
|
||||
player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F));
|
||||
@@ -671,8 +_,16 @@
|
||||
@@ -677,8 +_,16 @@
|
||||
|
||||
public void sendAllPlayerInfo(ServerPlayer player) {
|
||||
player.inventoryMenu.sendAllDataToRemote();
|
||||
@@ -939,7 +942,7 @@
|
||||
+ // entityplayer.resetSentInfo();
|
||||
+ player.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange
|
||||
+ player.refreshEntityData(player); // CraftBukkit - SPIGOT-7218: sync metadata
|
||||
player.connection.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected));
|
||||
player.connection.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot()));
|
||||
+ // CraftBukkit start - from GameRules
|
||||
+ int i = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23;
|
||||
+ player.connection.send(new ClientboundEntityEventPacket(player, (byte) i));
|
||||
@@ -949,7 +952,7 @@
|
||||
}
|
||||
|
||||
public int getPlayerCount() {
|
||||
@@ -688,6 +_,7 @@
|
||||
@@ -694,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void setUsingWhiteList(boolean whitelistEnabled) {
|
||||
@@ -957,7 +960,7 @@
|
||||
this.doWhiteList = whitelistEnabled;
|
||||
}
|
||||
|
||||
@@ -725,10 +_,35 @@
|
||||
@@ -731,10 +_,35 @@
|
||||
}
|
||||
|
||||
public void removeAll() {
|
||||
@@ -997,7 +1000,7 @@
|
||||
|
||||
public void broadcastSystemMessage(Component message, boolean bypassHiddenChat) {
|
||||
this.broadcastSystemMessage(message, serverPlayer -> message, bypassHiddenChat);
|
||||
@@ -750,20 +_,39 @@
|
||||
@@ -756,20 +_,39 @@
|
||||
}
|
||||
|
||||
public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound boundChatType) {
|
||||
@@ -1040,7 +1043,7 @@
|
||||
flag1 |= flag2 && message.isFullyFiltered();
|
||||
}
|
||||
|
||||
@@ -772,18 +_,25 @@
|
||||
@@ -778,18 +_,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1071,7 +1074,7 @@
|
||||
Path path = file2.toPath();
|
||||
if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) {
|
||||
file2.renameTo(file1);
|
||||
@@ -791,7 +_,7 @@
|
||||
@@ -797,7 +_,7 @@
|
||||
}
|
||||
|
||||
serverStatsCounter = new ServerStatsCounter(this.server, file1);
|
||||
@@ -1080,7 +1083,7 @@
|
||||
}
|
||||
|
||||
return serverStatsCounter;
|
||||
@@ -799,11 +_,11 @@
|
||||
@@ -805,11 +_,11 @@
|
||||
|
||||
public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) {
|
||||
UUID uuid = player.getUUID();
|
||||
@@ -1094,7 +1097,7 @@
|
||||
}
|
||||
|
||||
playerAdvancements.setPlayer(player);
|
||||
@@ -846,11 +_,34 @@
|
||||
@@ -852,11 +_,34 @@
|
||||
}
|
||||
|
||||
public void reloadResources() {
|
||||
@@ -1113,7 +1116,7 @@
|
||||
+ // }
|
||||
+ for (ServerPlayer player : this.players) {
|
||||
+ player.getAdvancements().reload(this.server.getAdvancements());
|
||||
+ player.getAdvancements().flushDirty(player); // CraftBukkit - trigger immediate flush of advancements
|
||||
+ player.getAdvancements().flushDirty(player, false); // CraftBukkit - trigger immediate flush of advancements
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/stats/ServerRecipeBook.java
|
||||
+++ b/net/minecraft/stats/ServerRecipeBook.java
|
||||
@@ -67,7 +_,7 @@
|
||||
@@ -66,7 +_,7 @@
|
||||
|
||||
for (RecipeHolder<?> recipeHolder : recipes) {
|
||||
ResourceKey<Recipe<?>> resourceKey = recipeHolder.id();
|
||||
@@ -9,7 +9,7 @@
|
||||
this.add(resourceKey);
|
||||
this.addHighlight(resourceKey);
|
||||
this.displayResolver
|
||||
@@ -78,7 +_,7 @@
|
||||
@@ -77,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
player.connection.send(new ClientboundRecipeBookAddPacket(list, false));
|
||||
}
|
||||
|
||||
@@ -96,7 +_,7 @@
|
||||
@@ -95,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/stats/ServerStatsCounter.java
|
||||
+++ b/net/minecraft/stats/ServerStatsCounter.java
|
||||
@@ -51,9 +_,21 @@
|
||||
@@ -70,9 +_,21 @@
|
||||
LOGGER.error("Couldn't parse statistics file {}", file, var5);
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
try {
|
||||
FileUtils.writeStringToFile(this.file, this.toJson());
|
||||
} catch (IOException var2) {
|
||||
@@ -63,6 +_,8 @@
|
||||
@@ -82,6 +_,8 @@
|
||||
|
||||
@Override
|
||||
public void setValue(Player player, Stat<?> stat, int i) {
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
--- a/net/minecraft/util/datafix/DataFixers.java
|
||||
+++ b/net/minecraft/util/datafix/DataFixers.java
|
||||
@@ -505,6 +_,18 @@
|
||||
@@ -541,6 +_,18 @@
|
||||
Schema schema44 = builder.addSchema(1456, SAME_NAMESPACED);
|
||||
builder.addFixer(new EntityItemFrameDirectionFix(schema44, false));
|
||||
Schema schema45 = builder.addSchema(1458, SAME_NAMESPACED);
|
||||
Schema schema45 = builder.addSchema(1458, V1458::new);
|
||||
+ // CraftBukkit start
|
||||
+ builder.addFixer(new com.mojang.datafixers.DataFix(schema45, false) {
|
||||
+ @Override
|
||||
+ protected com.mojang.datafixers.TypeRewriteRule makeRule() {
|
||||
+ return this.fixTypeEverywhereTyped("Player CustomName", this.getInputSchema().getType(References.PLAYER), (typed) -> {
|
||||
+ return typed.update(DSL.remainderFinder(), (dynamic) -> {
|
||||
+ return EntityCustomNameToComponentFix.fixTagCustomName(dynamic);
|
||||
+ return EntityCustomNameToComponentFix.fixCustomName(dynamic.getOps(), dynamic.get("CustomName").asString(""), "minecraft:player");
|
||||
+ });
|
||||
+ });
|
||||
+ }
|
||||
+ });
|
||||
+ // CraftBukkit end
|
||||
builder.addFixer(new EntityCustomNameToComponentFix(schema45, false));
|
||||
builder.addFixer(new ItemCustomNameToComponentFix(schema45, false));
|
||||
builder.addFixer(new BlockEntityCustomNameToComponentFix(schema45, false));
|
||||
builder.addFixer(new EntityCustomNameToComponentFix(schema45));
|
||||
builder.addFixer(new ItemCustomNameToComponentFix(schema45));
|
||||
builder.addFixer(new BlockEntityCustomNameToComponentFix(schema45));
|
||||
@@ -0,0 +1,39 @@
|
||||
--- a/net/minecraft/util/parsing/packrat/Scope.java
|
||||
+++ b/net/minecraft/util/parsing/packrat/Scope.java
|
||||
@@ -281,4 +_,36 @@
|
||||
|
||||
return true;
|
||||
}
|
||||
+
|
||||
+ // Paper start - track depth
|
||||
+ private int depth;
|
||||
+ @SuppressWarnings({"unchecked","rawtypes"})
|
||||
+ public static <S> Term<S> increaseDepth() {
|
||||
+ class IncreasingDepthTerm<W> implements Term<W> {
|
||||
+ public static final IncreasingDepthTerm INSTANCE = new IncreasingDepthTerm();
|
||||
+ @Override
|
||||
+ public boolean parse(final ParseState<W> parseState, final Scope scope, final Control control) {
|
||||
+ if (++scope.depth > 512) {
|
||||
+ parseState.errorCollector().store(parseState.mark(), new IllegalStateException("Too deep"));
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return (Term<S>) IncreasingDepthTerm.INSTANCE;
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings({"unchecked","rawtypes"})
|
||||
+ public static <S> Term<S> decreaseDepth() {
|
||||
+ class DecreasingDepthTerm<W> implements Term<W> {
|
||||
+ public static final DecreasingDepthTerm INSTANCE = new DecreasingDepthTerm();
|
||||
+ @Override
|
||||
+ public boolean parse(final ParseState<W> parseState, final Scope scope, final Control control) {
|
||||
+ scope.depth--;
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return (Term<S>) DecreasingDepthTerm.INSTANCE;
|
||||
+ }
|
||||
+ // Paper end - track depth
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
--- a/net/minecraft/util/random/WeightedList.java
|
||||
+++ b/net/minecraft/util/random/WeightedList.java
|
||||
@@ -13,14 +_,14 @@
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
-public final class WeightedList<E> {
|
||||
+public class WeightedList<E> { // Paper - non-final
|
||||
private static final int FLAT_THRESHOLD = 64;
|
||||
private final int totalWeight;
|
||||
private final List<Weighted<E>> items;
|
||||
@Nullable
|
||||
private final WeightedList.Selector<E> selector;
|
||||
|
||||
- WeightedList(List<? extends Weighted<E>> items) {
|
||||
+ protected WeightedList(List<? extends Weighted<E>> items) { // Paper - protected
|
||||
this.items = List.copyOf(items);
|
||||
this.totalWeight = WeightedRandom.getTotalWeight(items, Weighted::weight);
|
||||
if (this.totalWeight == 0) {
|
||||
@@ -122,7 +_,7 @@
|
||||
}
|
||||
|
||||
public static class Builder<E> {
|
||||
- private final ImmutableList.Builder<Weighted<E>> result = ImmutableList.builder();
|
||||
+ protected final ImmutableList.Builder<Weighted<E>> result = ImmutableList.builder();
|
||||
|
||||
public WeightedList.Builder<E> add(E element) {
|
||||
return this.add(element, 1);
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
+++ b/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
@@ -79,7 +_,7 @@
|
||||
LevelStorageSource.LevelStorageAccess levelStorage, DataFixer dataFixer, RegistryAccess registryAccess, boolean eraseCache, boolean recreateRegionFiles
|
||||
@@ -87,7 +_,7 @@
|
||||
boolean recreateRegionFiles
|
||||
) {
|
||||
this.dimensions = registryAccess.lookupOrThrow(Registries.LEVEL_STEM);
|
||||
- this.levels = this.dimensions.registryKeySet().stream().map(Registries::levelStemToLevel).collect(Collectors.toUnmodifiableSet());
|
||||
@@ -9,12 +9,12 @@
|
||||
this.eraseCache = eraseCache;
|
||||
this.dataFixer = dataFixer;
|
||||
this.levelStorage = levelStorage;
|
||||
@@ -358,7 +_,7 @@
|
||||
@@ -369,7 +_,7 @@
|
||||
int version = ChunkStorage.getVersion(compoundTag);
|
||||
ChunkGenerator chunkGenerator = WorldUpgrader.this.dimensions.getValueOrThrow(Registries.levelToLevelStem(dimension)).generator();
|
||||
CompoundTag compoundTag1 = chunkStorage.upgradeChunkTag(
|
||||
- dimension, () -> WorldUpgrader.this.overworldDataStorage, compoundTag, chunkGenerator.getTypeNameForDataFixer()
|
||||
+ Registries.levelToLevelStem(dimension), () -> WorldUpgrader.this.overworldDataStorage, compoundTag, chunkGenerator.getTypeNameForDataFixer(), chunkPos, null // CraftBukkit
|
||||
);
|
||||
ChunkPos chunkPos1 = new ChunkPos(compoundTag1.getInt("xPos"), compoundTag1.getInt("zPos"));
|
||||
ChunkPos chunkPos1 = new ChunkPos(compoundTag1.getIntOr("xPos", 0), compoundTag1.getIntOr("zPos", 0));
|
||||
if (!chunkPos1.equals(chunkPos)) {
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/BossEvent.java
|
||||
+++ b/net/minecraft/world/BossEvent.java
|
||||
@@ -13,6 +_,7 @@
|
||||
@@ -15,6 +_,7 @@
|
||||
protected boolean darkenScreen;
|
||||
protected boolean playBossMusic;
|
||||
protected boolean createWorldFog;
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
public BossEvent(UUID id, Component name, BossEvent.BossBarColor color, BossEvent.BossBarOverlay overlay) {
|
||||
this.id = id;
|
||||
@@ -27,61 +_,75 @@
|
||||
@@ -29,61 +_,75 @@
|
||||
}
|
||||
|
||||
public Component getName() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/Container.java
|
||||
+++ b/net/minecraft/world/Container.java
|
||||
@@ -24,9 +_,7 @@
|
||||
@@ -26,9 +_,7 @@
|
||||
|
||||
void setItem(int slot, ItemStack stack);
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
|
||||
default int getMaxStackSize(ItemStack stack) {
|
||||
return Math.min(this.getMaxStackSize(), stack.getMaxStackSize());
|
||||
@@ -87,4 +_,22 @@
|
||||
BlockPos blockPos = blockEntity.getBlockPos();
|
||||
return level != null && level.getBlockEntity(blockPos) == blockEntity && player.canInteractWithBlock(blockPos, distance);
|
||||
@@ -117,4 +_,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/RandomizableContainer.java
|
||||
+++ b/net/minecraft/world/RandomizableContainer.java
|
||||
@@ -28,7 +_,7 @@
|
||||
@@ -26,7 +_,7 @@
|
||||
|
||||
void setLootTable(@Nullable ResourceKey<LootTable> lootTable);
|
||||
|
||||
@@ -9,30 +9,21 @@
|
||||
this.setLootTable(lootTable);
|
||||
this.setLootTableSeed(seed);
|
||||
}
|
||||
@@ -50,15 +_,17 @@
|
||||
|
||||
@@ -49,8 +_,9 @@
|
||||
default boolean tryLoadLootTable(CompoundTag tag) {
|
||||
if (tag.contains("LootTable", 8)) {
|
||||
- this.setLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(tag.getString("LootTable"))));
|
||||
+ this.setLootTable(net.minecraft.Optionull.map(ResourceLocation.tryParse(tag.getString("LootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl))); // Paper - Validate ResourceLocation
|
||||
+ if (this.lootableData() != null && this.getLootTable() != null) this.lootableData().loadNbt(tag); // Paper - LootTable API
|
||||
if (tag.contains("LootTableSeed", 4)) {
|
||||
this.setLootTableSeed(tag.getLong("LootTableSeed"));
|
||||
} else {
|
||||
this.setLootTableSeed(0L);
|
||||
}
|
||||
|
||||
- return true;
|
||||
+ return this.lootableData() == null; // Paper - only track the loot table if there is chance for replenish
|
||||
} else {
|
||||
+ setLootTable(null); // Paper - Fix removing loottable from nbt not updating block entity, MC-279196
|
||||
return false;
|
||||
}
|
||||
ResourceKey<LootTable> resourceKey = tag.read("LootTable", LootTable.KEY_CODEC).orElse(null);
|
||||
this.setLootTable(resourceKey);
|
||||
+ if (this.lootableData() != null && resourceKey != null) this.lootableData().loadNbt(tag); // Paper - LootTable API
|
||||
this.setLootTableSeed(tag.getLongOr("LootTableSeed", 0L));
|
||||
- return resourceKey != null;
|
||||
+ return resourceKey != null && this.lootableData() == null; // Paper - only track the loot table if there is chance for replenish
|
||||
}
|
||||
@@ -69,26 +_,42 @@
|
||||
|
||||
default boolean trySaveLootTable(CompoundTag tag) {
|
||||
@@ -59,26 +_,42 @@
|
||||
return false;
|
||||
} else {
|
||||
tag.putString("LootTable", lootTable.location().toString());
|
||||
tag.store("LootTable", LootTable.KEY_CODEC, lootTable);
|
||||
+ if (this.lootableData() != null) this.lootableData().saveNbt(tag); // Paper - LootTable API
|
||||
long lootTableSeed = this.getLootTableSeed();
|
||||
if (lootTableSeed != 0L) {
|
||||
@@ -74,7 +65,7 @@
|
||||
LootParams.Builder builder = new LootParams.Builder((ServerLevel)level).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockPos));
|
||||
if (player != null) {
|
||||
builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player);
|
||||
@@ -97,4 +_,17 @@
|
||||
@@ -87,4 +_,17 @@
|
||||
lootTable1.fill(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
+++ b/net/minecraft/world/effect/InfestedMobEffect.java
|
||||
@@ -44,7 +_,11 @@
|
||||
Vector3f vector3f = entity.getLookAngle().toVector3f().mul(0.3F).mul(1.0F, 1.5F, 1.0F).rotateY(f1);
|
||||
silverfish.moveTo(x, y, z, level.getRandom().nextFloat() * 360.0F, 0.0F);
|
||||
silverfish.snapTo(x, y, z, level.getRandom().nextFloat() * 360.0F, 0.0F);
|
||||
silverfish.setDeltaMovement(new Vec3(vector3f));
|
||||
- level.addFreshEntity(silverfish);
|
||||
+ // CraftBukkit start
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/effect/MobEffect.java
|
||||
+++ b/net/minecraft/world/effect/MobEffect.java
|
||||
@@ -76,6 +_,7 @@
|
||||
@@ -86,6 +_,7 @@
|
||||
public void applyInstantenousEffect(
|
||||
ServerLevel level, @Nullable Entity source, @Nullable Entity indirectSource, LivingEntity entity, int amplifier, double health
|
||||
) {
|
||||
|
||||
+10
-9
@@ -1,14 +1,15 @@
|
||||
--- a/net/minecraft/world/effect/MobEffectInstance.java
|
||||
+++ b/net/minecraft/world/effect/MobEffectInstance.java
|
||||
@@ -216,6 +_,7 @@
|
||||
@@ -219,7 +_,7 @@
|
||||
return false;
|
||||
} else {
|
||||
int i = this.isInfiniteDuration() ? entity.tickCount : this.duration;
|
||||
if (entity.level() instanceof ServerLevel serverLevel
|
||||
&& this.effect.value().shouldApplyEffectTickThisTick(i, this.amplifier)
|
||||
+ && new io.papermc.paper.event.entity.EntityEffectTickEvent(entity.getBukkitLivingEntity(), org.bukkit.craftbukkit.potion.CraftPotionEffectType.minecraftHolderToBukkit(this.effect), this.amplifier).callEvent() // Paper - Add EntityEffectTickEvent
|
||||
&& !this.effect.value().applyEffectTick(serverLevel, entity, this.amplifier)) {
|
||||
entity.removeEffect(this.effect);
|
||||
}
|
||||
@@ -408,7 +_,7 @@
|
||||
- if (this.effect.value().shouldApplyEffectTickThisTick(i, this.amplifier) && !this.effect.value().applyEffectTick(level, entity, this.amplifier)) {
|
||||
+ if (this.effect.value().shouldApplyEffectTickThisTick(i, this.amplifier) && new io.papermc.paper.event.entity.EntityEffectTickEvent(entity.getBukkitLivingEntity(), org.bukkit.craftbukkit.potion.CraftPotionEffectType.minecraftHolderToBukkit(this.effect), this.amplifier).callEvent() && !this.effect.value().applyEffectTick(level, entity, this.amplifier)) { // Paper - Add EntityEffectTickEvent
|
||||
return false;
|
||||
} else {
|
||||
this.tickDownDuration();
|
||||
@@ -415,7 +_,7 @@
|
||||
.apply(instance, MobEffectInstance.Details::create)
|
||||
)
|
||||
);
|
||||
@@ -17,7 +18,7 @@
|
||||
codec -> StreamCodec.composite(
|
||||
ByteBufCodecs.VAR_INT,
|
||||
MobEffectInstance.Details::amplifier,
|
||||
@@ -420,7 +_,7 @@
|
||||
@@ -427,7 +_,7 @@
|
||||
MobEffectInstance.Details::showParticles,
|
||||
ByteBufCodecs.BOOL,
|
||||
MobEffectInstance.Details::showIcon,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@@ -49,7 +_,7 @@
|
||||
if (slime != null) {
|
||||
slime.setSize(2, true);
|
||||
slime.moveTo(x, y, z, level.getRandom().nextFloat() * 360.0F, 0.0F);
|
||||
slime.snapTo(x, y, z, level.getRandom().nextFloat() * 360.0F, 0.0F);
|
||||
- level.addFreshEntity(slime);
|
||||
+ level.addFreshEntity(slime, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.POTION_EFFECT); // CraftBukkit
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
--- a/net/minecraft/world/entity/AgeableMob.java
|
||||
+++ b/net/minecraft/world/entity/AgeableMob.java
|
||||
@@ -20,6 +_,7 @@
|
||||
protected int age;
|
||||
protected int forcedAge;
|
||||
@@ -22,6 +_,7 @@
|
||||
protected int age = 0;
|
||||
protected int forcedAge = 0;
|
||||
protected int forcedAgeTimer;
|
||||
+ public boolean ageLocked; // CraftBukkit
|
||||
|
||||
protected AgeableMob(EntityType<? extends AgeableMob> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -66,6 +_,7 @@
|
||||
@@ -68,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void ageUp(int amount, boolean forced) {
|
||||
@@ -16,7 +16,7 @@
|
||||
int age = this.getAge();
|
||||
age += amount * 20;
|
||||
if (age > 0) {
|
||||
@@ -104,6 +_,7 @@
|
||||
@@ -106,6 +_,7 @@
|
||||
super.addAdditionalSaveData(compound);
|
||||
compound.putInt("Age", this.getAge());
|
||||
compound.putInt("ForcedAge", this.forcedAge);
|
||||
@@ -24,15 +24,15 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,6 +_,7 @@
|
||||
@@ -113,6 +_,7 @@
|
||||
super.readAdditionalSaveData(compound);
|
||||
this.setAge(compound.getInt("Age"));
|
||||
this.forcedAge = compound.getInt("ForcedAge");
|
||||
+ this.ageLocked = compound.getBoolean("AgeLocked"); // CraftBukkit
|
||||
this.setAge(compound.getIntOr("Age", 0));
|
||||
this.forcedAge = compound.getIntOr("ForcedAge", 0);
|
||||
+ this.ageLocked = compound.getBooleanOr("AgeLocked", false); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,7 +_,7 @@
|
||||
@@ -127,7 +_,7 @@
|
||||
@Override
|
||||
public void aiStep() {
|
||||
super.aiStep();
|
||||
|
||||
+16
-16
@@ -1,24 +1,24 @@
|
||||
--- a/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
+++ b/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
@@ -47,7 +_,7 @@
|
||||
public float radiusOnUse;
|
||||
public float radiusPerTick;
|
||||
@@ -59,7 +_,7 @@
|
||||
public float radiusOnUse = 0.0F;
|
||||
public float radiusPerTick = 0.0F;
|
||||
@Nullable
|
||||
- private LivingEntity owner;
|
||||
+ private net.minecraft.world.entity.LivingEntity owner;
|
||||
@Nullable
|
||||
public UUID ownerUUID;
|
||||
|
||||
@@ -177,7 +_,7 @@
|
||||
@@ -193,7 +_,7 @@
|
||||
|
||||
private void serverTick(ServerLevel level) {
|
||||
if (this.tickCount >= this.waitTime + this.duration) {
|
||||
if (this.duration != -1 && this.tickCount >= this.waitTime + this.duration) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
boolean isWaiting = this.isWaiting();
|
||||
boolean flag = this.tickCount < this.waitTime;
|
||||
@@ -190,7 +_,7 @@
|
||||
@@ -206,7 +_,7 @@
|
||||
if (this.radiusPerTick != 0.0F) {
|
||||
radius += this.radiusPerTick;
|
||||
if (radius < 0.5F) {
|
||||
@@ -27,15 +27,15 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -220,6 +_,7 @@
|
||||
list.addAll(this.potionContents.customEffects());
|
||||
@@ -222,6 +_,7 @@
|
||||
this.potionContents.forEachEffect(list::add, this.potionDurationScale);
|
||||
List<LivingEntity> entitiesOfClass = this.level().getEntitiesOfClass(LivingEntity.class, this.getBoundingBox());
|
||||
if (!entitiesOfClass.isEmpty()) {
|
||||
+ List<org.bukkit.entity.LivingEntity> entities = new java.util.ArrayList<>(); // CraftBukkit
|
||||
for (LivingEntity livingEntity : entitiesOfClass) {
|
||||
if (!this.victims.containsKey(livingEntity)
|
||||
&& livingEntity.isAffectedByPotions()
|
||||
@@ -228,6 +_,17 @@
|
||||
@@ -230,6 +_,17 @@
|
||||
double d1 = livingEntity.getZ() - this.getZ();
|
||||
double d2 = d * d + d1 * d1;
|
||||
if (d2 <= radius * radius) {
|
||||
@@ -52,13 +52,13 @@
|
||||
+ // CraftBukkit end
|
||||
this.victims.put(livingEntity, this.tickCount + this.reapplicationDelay);
|
||||
|
||||
for (MobEffectInstance mobEffectInstance1 : list) {
|
||||
@@ -236,14 +_,14 @@
|
||||
for (MobEffectInstance mobEffectInstance : list) {
|
||||
@@ -238,14 +_,14 @@
|
||||
.value()
|
||||
.applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance1.getAmplifier(), 0.5);
|
||||
.applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), 0.5);
|
||||
} else {
|
||||
- livingEntity.addEffect(new MobEffectInstance(mobEffectInstance1), this);
|
||||
+ livingEntity.addEffect(new MobEffectInstance(mobEffectInstance1), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AREA_EFFECT_CLOUD); // CraftBukkit
|
||||
- livingEntity.addEffect(new MobEffectInstance(mobEffectInstance), this);
|
||||
+ livingEntity.addEffect(new MobEffectInstance(mobEffectInstance), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AREA_EFFECT_CLOUD); // CraftBukkit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -253,7 +_,7 @@
|
||||
if (this.durationOnUse != 0) {
|
||||
@@ -255,7 +_,7 @@
|
||||
if (this.durationOnUse != 0 && this.duration != -1) {
|
||||
this.duration = this.duration + this.durationOnUse;
|
||||
if (this.duration <= 0) {
|
||||
- this.discard();
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/net/minecraft/world/entity/Display.java
|
||||
+++ b/net/minecraft/world/entity/Display.java
|
||||
@@ -213,7 +_,7 @@
|
||||
if (tag.contains("transformation")) {
|
||||
Transformation.EXTENDED_CODEC
|
||||
.decode(NbtOps.INSTANCE, tag.get("transformation"))
|
||||
- .resultOrPartial(Util.prefix("Display entity", LOGGER::error))
|
||||
+ .result() // Paper - Hide text display error on spawn
|
||||
.ifPresent(pair -> this.setTransformation(pair.getFirst()));
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -136,6 +_,108 @@
|
||||
import org.slf4j.Logger;
|
||||
@@ -141,6 +_,107 @@
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder {
|
||||
+
|
||||
public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, DataComponentGetter {
|
||||
+ // CraftBukkit start
|
||||
+ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger();
|
||||
+ private static final int CURRENT_LEVEL = 2;
|
||||
+ public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first setPositionRotation
|
||||
+ static boolean isLevelAtLeast(CompoundTag tag, int level) {
|
||||
+ return tag.contains("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
|
||||
+ return tag.getIntOr("Bukkit.updateLevel", CURRENT_LEVEL) >= level;
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Share random for entities to make them more random
|
||||
@@ -84,7 +84,7 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Share random for entities to make them more random
|
||||
+ public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason
|
||||
+ public @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason
|
||||
+
|
||||
+ private @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity;
|
||||
+
|
||||
@@ -105,20 +105,19 @@
|
||||
+ return this.bukkitEntity;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final String ID_TAG = "id";
|
||||
public static final String PASSENGERS_TAG = "Passengers";
|
||||
@@ -196,7 +_,7 @@
|
||||
private static final String DATA_TAG = "data";
|
||||
@@ -203,7 +_,7 @@
|
||||
public double yOld;
|
||||
public double zOld;
|
||||
public boolean noPhysics;
|
||||
private boolean wasOnFire;
|
||||
- public final RandomSource random = RandomSource.create();
|
||||
+ public final RandomSource random = SHARED_RANDOM; // Paper - Share random for entities to make them more random
|
||||
public int tickCount;
|
||||
private int remainingFireTicks = -this.getFireImmuneTicks();
|
||||
public boolean wasTouchingWater;
|
||||
@@ -233,7 +_,7 @@
|
||||
@@ -240,7 +_,7 @@
|
||||
protected UUID uuid = Mth.createInsecureUUID(this.random);
|
||||
protected String stringUUID = this.uuid.toString();
|
||||
private boolean hasGlowingTag;
|
||||
@@ -127,10 +126,10 @@
|
||||
private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0};
|
||||
private long pistonDeltasGameTime;
|
||||
private EntityDimensions dimensions;
|
||||
@@ -250,6 +_,60 @@
|
||||
private final List<Entity.Movement> movementThisTick = new ArrayList<>();
|
||||
private final Set<BlockState> blocksInside = new ReferenceArraySet<>();
|
||||
@@ -259,6 +_,60 @@
|
||||
private final LongSet visitedBlocks = new LongOpenHashSet();
|
||||
private final InsideBlockEffectApplier.StepBasedCollector insideEffectCollector = new InsideBlockEffectApplier.StepBasedCollector();
|
||||
private CustomData customData = CustomData.EMPTY;
|
||||
+ // CraftBukkit start
|
||||
+ public boolean forceDrops;
|
||||
+ public boolean persist = true;
|
||||
@@ -188,7 +187,7 @@
|
||||
|
||||
public Entity(EntityType<?> entityType, Level level) {
|
||||
this.type = entityType;
|
||||
@@ -271,6 +_,7 @@
|
||||
@@ -280,6 +_,7 @@
|
||||
this.entityData = builder.build();
|
||||
this.setPos(0.0, 0.0, 0.0);
|
||||
this.eyeHeight = this.dimensions.eyeHeight();
|
||||
@@ -196,7 +195,7 @@
|
||||
}
|
||||
|
||||
public boolean isColliding(BlockPos pos, BlockState state) {
|
||||
@@ -284,6 +_,12 @@
|
||||
@@ -292,6 +_,12 @@
|
||||
return team != null && team.getColor().getColor() != null ? team.getColor().getColor() : 16777215;
|
||||
}
|
||||
|
||||
@@ -209,7 +208,7 @@
|
||||
public boolean isSpectator() {
|
||||
return false;
|
||||
}
|
||||
@@ -324,7 +_,7 @@
|
||||
@@ -332,7 +_,7 @@
|
||||
}
|
||||
|
||||
public boolean addTag(String tag) {
|
||||
@@ -218,7 +217,7 @@
|
||||
}
|
||||
|
||||
public boolean removeTag(String tag) {
|
||||
@@ -332,12 +_,18 @@
|
||||
@@ -340,12 +_,18 @@
|
||||
}
|
||||
|
||||
public void kill(ServerLevel level) {
|
||||
@@ -239,7 +238,7 @@
|
||||
}
|
||||
|
||||
protected abstract void defineSynchedData(SynchedEntityData.Builder builder);
|
||||
@@ -346,6 +_,48 @@
|
||||
@@ -354,6 +_,48 @@
|
||||
return this.entityData;
|
||||
}
|
||||
|
||||
@@ -288,7 +287,7 @@
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof Entity && ((Entity)object).id == this.id;
|
||||
@@ -357,7 +_,13 @@
|
||||
@@ -365,7 +_,13 @@
|
||||
}
|
||||
|
||||
public void remove(Entity.RemovalReason reason) {
|
||||
@@ -303,7 +302,7 @@
|
||||
}
|
||||
|
||||
public void onClientRemoval() {
|
||||
@@ -367,6 +_,17 @@
|
||||
@@ -375,6 +_,17 @@
|
||||
}
|
||||
|
||||
public void setPose(Pose pose) {
|
||||
@@ -321,7 +320,7 @@
|
||||
this.entityData.set(DATA_POSE, pose);
|
||||
}
|
||||
|
||||
@@ -390,6 +_,32 @@
|
||||
@@ -398,6 +_,32 @@
|
||||
}
|
||||
|
||||
public void setRot(float yRot, float xRot) {
|
||||
@@ -354,7 +353,7 @@
|
||||
this.setYRot(yRot % 360.0F);
|
||||
this.setXRot(xRot % 360.0F);
|
||||
}
|
||||
@@ -399,8 +_,8 @@
|
||||
@@ -407,8 +_,8 @@
|
||||
}
|
||||
|
||||
public void setPos(double x, double y, double z) {
|
||||
@@ -365,7 +364,7 @@
|
||||
}
|
||||
|
||||
protected final AABB makeBoundingBox() {
|
||||
@@ -430,12 +_,28 @@
|
||||
@@ -438,12 +_,28 @@
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
@@ -394,7 +393,7 @@
|
||||
this.inBlockState = null;
|
||||
if (this.isPassenger() && this.getVehicle().isRemoved()) {
|
||||
this.stopRiding();
|
||||
@@ -445,7 +_,7 @@
|
||||
@@ -453,7 +_,7 @@
|
||||
this.boardingCooldown--;
|
||||
}
|
||||
|
||||
@@ -403,19 +402,10 @@
|
||||
if (this.canSpawnSprintParticle()) {
|
||||
this.spawnSprintParticle();
|
||||
}
|
||||
@@ -470,7 +_,7 @@
|
||||
this.setRemainingFireTicks(this.remainingFireTicks - 1);
|
||||
}
|
||||
@@ -484,6 +_,10 @@
|
||||
|
||||
- if (this.getTicksFrozen() > 0) {
|
||||
+ if (this.getTicksFrozen() > 0 && !this.freezeLocked) { // Paper - Freeze Tick Lock API
|
||||
this.setTicksFrozen(0);
|
||||
this.level().levelEvent(null, 1009, this.blockPosition, 1);
|
||||
}
|
||||
@@ -482,6 +_,10 @@
|
||||
if (this.isInLava()) {
|
||||
this.lavaHurt();
|
||||
this.fallDistance *= 0.5F;
|
||||
this.fallDistance *= 0.5;
|
||||
+ // CraftBukkit start
|
||||
+ } else {
|
||||
+ this.lastLavaContact = null;
|
||||
@@ -423,7 +413,7 @@
|
||||
}
|
||||
|
||||
this.checkBelowWorld();
|
||||
@@ -502,7 +_,12 @@
|
||||
@@ -504,7 +_,12 @@
|
||||
}
|
||||
|
||||
public void checkBelowWorld() {
|
||||
@@ -437,9 +427,9 @@
|
||||
this.onBelowWorld();
|
||||
}
|
||||
}
|
||||
@@ -531,9 +_,24 @@
|
||||
@@ -533,14 +_,35 @@
|
||||
|
||||
public void lavaHurt() {
|
||||
public void lavaIgnite() {
|
||||
if (!this.fireImmune()) {
|
||||
- this.igniteForSeconds(15.0F);
|
||||
+ // CraftBukkit start - Fallen in lava TODO: this event spams!
|
||||
@@ -458,13 +448,24 @@
|
||||
+ this.igniteForSeconds(15.0F, false);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
|
||||
public void lavaHurt() {
|
||||
+ // Paper start - track lava contact
|
||||
+ this.lavaHurt(this.lastLavaContact); // fallback for minecarts if defined
|
||||
+ }
|
||||
+
|
||||
+ public void lavaHurt(BlockPos pos) {
|
||||
+ // Paper end - track lava contact
|
||||
if (!this.fireImmune()) {
|
||||
if (this.level() instanceof ServerLevel serverLevel
|
||||
- && this.hurtServer(serverLevel, this.damageSources().lava(), 4.0F)
|
||||
+ && this.hurtServer(serverLevel, this.damageSources().lava().eventBlockDamager(this.level, this.lastLavaContact), 4.0F) // CraftBukkit - we also don't throw an event unless the object in lava is living, to save on some event calls
|
||||
+ && this.hurtServer(serverLevel, this.damageSources().lava().eventBlockDamager(this.level, pos), 4.0F) // CraftBukkit - we also don't throw an event unless the object in lava is living, to save on some event calls
|
||||
&& this.shouldPlayLavaHurtSound()
|
||||
&& !this.isSilent()) {
|
||||
serverLevel.playSound(
|
||||
@@ -548,7 +_,23 @@
|
||||
@@ -555,7 +_,23 @@
|
||||
}
|
||||
|
||||
public final void igniteForSeconds(float seconds) {
|
||||
@@ -489,7 +490,7 @@
|
||||
}
|
||||
|
||||
public void igniteForTicks(int ticks) {
|
||||
@@ -570,7 +_,7 @@
|
||||
@@ -579,7 +_,7 @@
|
||||
}
|
||||
|
||||
protected void onBelowWorld() {
|
||||
@@ -498,7 +499,7 @@
|
||||
}
|
||||
|
||||
public boolean isFree(double x, double y, double z) {
|
||||
@@ -626,7 +_,43 @@
|
||||
@@ -635,7 +_,43 @@
|
||||
return this.onGround;
|
||||
}
|
||||
|
||||
@@ -542,10 +543,10 @@
|
||||
if (this.noPhysics) {
|
||||
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
|
||||
} else {
|
||||
@@ -701,6 +_,28 @@
|
||||
@@ -721,6 +_,27 @@
|
||||
block.updateEntityMovementAfterFallOn(this.level(), this);
|
||||
}
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ if (this.horizontalCollision && this.getBukkitEntity() instanceof org.bukkit.entity.Vehicle) {
|
||||
+ org.bukkit.entity.Vehicle vehicle = (org.bukkit.entity.Vehicle) this.getBukkitEntity();
|
||||
@@ -567,11 +568,10 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
if (!this.level().isClientSide() || this.isControlledByLocalInstance()) {
|
||||
|
||||
if (!this.level().isClientSide() || this.isLocalInstanceAuthoritative()) {
|
||||
Entity.MovementEmission movementEmission = this.getMovementEmission();
|
||||
if (movementEmission.emitsAnything() && !this.isPassenger()) {
|
||||
@@ -713,6 +_,13 @@
|
||||
@@ -734,6 +_,13 @@
|
||||
profilerFiller.pop();
|
||||
}
|
||||
}
|
||||
@@ -585,7 +585,7 @@
|
||||
}
|
||||
|
||||
private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) {
|
||||
@@ -850,7 +_,7 @@
|
||||
@@ -898,7 +_,7 @@
|
||||
}
|
||||
|
||||
protected BlockPos getOnPos(float yOffset) {
|
||||
@@ -594,10 +594,10 @@
|
||||
BlockPos blockPos = this.mainSupportingBlockPos.get();
|
||||
if (!(yOffset > 1.0E-5F)) {
|
||||
return blockPos;
|
||||
@@ -1049,6 +_,20 @@
|
||||
@@ -1081,6 +_,19 @@
|
||||
protected SoundEvent getSwimHighSpeedSplashSound() {
|
||||
return SoundEvents.GENERIC_SPLASH;
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - Add delegate methods
|
||||
+ public SoundEvent getSwimSound0() {
|
||||
+ return this.getSwimSound();
|
||||
@@ -611,32 +611,31 @@
|
||||
+ return this.getSwimHighSpeedSplashSound();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
public void recordMovementThroughBlocks(Vec3 oldPosition, Vec3 position) {
|
||||
this.movementThisTick.add(new Entity.Movement(oldPosition, position));
|
||||
}
|
||||
@@ -1485,6 +_,7 @@
|
||||
|
||||
private void checkInsideBlocks(List<Entity.Movement> movements, InsideBlockEffectApplier.StepBasedCollector stepBasedCollector) {
|
||||
if (this.isAffectedByBlocks()) {
|
||||
@@ -1519,6 +_,7 @@
|
||||
this.setXRot(Mth.clamp(xRot, -90.0F, 90.0F) % 360.0F);
|
||||
this.yRotO = this.getYRot();
|
||||
this.xRotO = this.getXRot();
|
||||
+ this.setYHeadRot(yRot); // Paper - Update head rotation
|
||||
}
|
||||
|
||||
public void absMoveTo(double x, double y, double z) {
|
||||
@@ -1494,6 +_,7 @@
|
||||
public void absSnapTo(double x, double y, double z) {
|
||||
@@ -1528,6 +_,7 @@
|
||||
this.yo = y;
|
||||
this.zo = d1;
|
||||
this.setPos(d, y, d1);
|
||||
+ if (this.valid) this.level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit
|
||||
}
|
||||
|
||||
public void moveTo(Vec3 vec) {
|
||||
@@ -1513,11 +_,19 @@
|
||||
public void snapTo(Vec3 pos) {
|
||||
@@ -1547,11 +_,19 @@
|
||||
}
|
||||
|
||||
public void moveTo(double x, double y, double z, float yRot, float xRot) {
|
||||
public void snapTo(double x, double y, double z, float yRot, float xRot) {
|
||||
+ // Paper start - Fix Entity Teleportation and cancel velocity if teleported
|
||||
+ if (!preserveMotion) {
|
||||
+ if (!this.preserveMotion) {
|
||||
+ this.deltaMovement = Vec3.ZERO;
|
||||
+ } else {
|
||||
+ this.preserveMotion = false;
|
||||
@@ -651,7 +650,7 @@
|
||||
}
|
||||
|
||||
public final void setOldPosAndRot() {
|
||||
@@ -1584,6 +_,7 @@
|
||||
@@ -1618,6 +_,7 @@
|
||||
public void push(Entity entity) {
|
||||
if (!this.isPassengerOfSameVehicle(entity)) {
|
||||
if (!entity.noPhysics && !this.noPhysics) {
|
||||
@@ -659,7 +658,7 @@
|
||||
double d = entity.getX() - this.getX();
|
||||
double d1 = entity.getZ() - this.getZ();
|
||||
double max = Mth.absMax(d, d1);
|
||||
@@ -1617,7 +_,21 @@
|
||||
@@ -1651,7 +_,21 @@
|
||||
}
|
||||
|
||||
public void push(double x, double y, double z) {
|
||||
@@ -682,7 +681,7 @@
|
||||
this.hasImpulse = true;
|
||||
}
|
||||
|
||||
@@ -1724,8 +_,20 @@
|
||||
@@ -1758,8 +_,20 @@
|
||||
}
|
||||
|
||||
public boolean isPushable() {
|
||||
@@ -703,7 +702,7 @@
|
||||
|
||||
public void awardKillScore(Entity entity, DamageSource damageSource) {
|
||||
if (entity instanceof ServerPlayer) {
|
||||
@@ -1752,15 +_,22 @@
|
||||
@@ -1786,15 +_,22 @@
|
||||
}
|
||||
|
||||
public boolean saveAsPassenger(CompoundTag compound) {
|
||||
@@ -730,7 +729,7 @@
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1771,15 +_,37 @@
|
||||
@@ -1805,14 +_,36 @@
|
||||
}
|
||||
|
||||
public CompoundTag saveWithoutId(CompoundTag compound) {
|
||||
@@ -743,23 +742,17 @@
|
||||
+ // Paper end - Raw entity serialization API
|
||||
+ // CraftBukkit end
|
||||
try {
|
||||
- if (this.vehicle != null) {
|
||||
- compound.put("Pos", this.newDoubleList(this.vehicle.getX(), this.getY(), this.vehicle.getZ()));
|
||||
- } else {
|
||||
- compound.put("Pos", this.newDoubleList(this.getX(), this.getY(), this.getZ()));
|
||||
- }
|
||||
+ // CraftBukkit start - selectively save position
|
||||
+ if (includeAll) {
|
||||
+ if (this.vehicle != null) {
|
||||
+ compound.put("Pos", this.newDoubleList(this.vehicle.getX(), this.getY(), this.vehicle.getZ()));
|
||||
+ } else {
|
||||
+ compound.put("Pos", this.newDoubleList(this.getX(), this.getY(), this.getZ()));
|
||||
+ }
|
||||
+ }
|
||||
if (this.vehicle != null) {
|
||||
compound.store("Pos", Vec3.CODEC, new Vec3(this.vehicle.getX(), this.getY(), this.vehicle.getZ()));
|
||||
} else {
|
||||
compound.store("Pos", Vec3.CODEC, this.position());
|
||||
}
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
Vec3 deltaMovement = this.getDeltaMovement();
|
||||
compound.put("Motion", this.newDoubleList(deltaMovement.x, deltaMovement.y, deltaMovement.z));
|
||||
compound.store("Motion", Vec3.CODEC, this.getDeltaMovement());
|
||||
+ // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero
|
||||
+ // TODO: make sure this is the best way to address this.
|
||||
+ if (Float.isNaN(this.yRot)) {
|
||||
@@ -770,17 +763,17 @@
|
||||
+ this.xRot = 0;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
compound.put("Rotation", this.newFloatList(this.getYRot(), this.getXRot()));
|
||||
compound.putFloat("FallDistance", this.fallDistance);
|
||||
compound.store("Rotation", Vec2.CODEC, new Vec2(this.getYRot(), this.getXRot()));
|
||||
compound.putDouble("fall_distance", this.fallDistance);
|
||||
compound.putShort("Fire", (short)this.remainingFireTicks);
|
||||
@@ -1787,7 +_,29 @@
|
||||
@@ -1820,7 +_,29 @@
|
||||
compound.putBoolean("OnGround", this.onGround());
|
||||
compound.putBoolean("Invulnerable", this.invulnerable);
|
||||
compound.putInt("PortalCooldown", this.portalCooldown);
|
||||
- compound.putUUID("UUID", this.getUUID());
|
||||
- compound.store("UUID", UUIDUtil.CODEC, this.getUUID());
|
||||
+ // CraftBukkit start - selectively save uuid and world
|
||||
+ if (includeAll) {
|
||||
+ compound.putUUID("UUID", this.getUUID());
|
||||
+ compound.store("UUID", UUIDUtil.CODEC, this.getUUID());
|
||||
+ // PAIL: Check above UUID reads 1.8 properly, ie: UUIDMost / UUIDLeast
|
||||
+ compound.putLong("WorldUUIDLeast", this.level.getWorld().getUID().getLeastSignificantBits());
|
||||
+ compound.putLong("WorldUUIDMost", this.level.getWorld().getUID().getMostSignificantBits());
|
||||
@@ -803,9 +796,9 @@
|
||||
+ // CraftBukkit end
|
||||
Component customName = this.getCustomName();
|
||||
if (customName != null) {
|
||||
compound.putString("CustomName", Component.Serializer.toJson(customName, this.registryAccess()));
|
||||
@@ -1828,13 +_,13 @@
|
||||
compound.put("Tags", listTag);
|
||||
RegistryOps<Tag> registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE);
|
||||
@@ -1860,13 +_,13 @@
|
||||
compound.store("data", CustomData.CODEC, this.customData);
|
||||
}
|
||||
|
||||
- this.addAdditionalSaveData(compound);
|
||||
@@ -820,7 +813,7 @@
|
||||
listTag.add(compoundTag);
|
||||
}
|
||||
}
|
||||
@@ -1844,6 +_,33 @@
|
||||
@@ -1876,6 +_,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,9 +826,9 @@
|
||||
+ if (this.origin != null) {
|
||||
+ UUID originWorld = this.originWorld != null ? this.originWorld : this.level != null ? this.level.getWorld().getUID() : null;
|
||||
+ if (originWorld != null) {
|
||||
+ compound.putUUID("Paper.OriginWorld", originWorld);
|
||||
+ compound.store("Paper.OriginWorld", UUIDUtil.CODEC, originWorld);
|
||||
+ }
|
||||
+ compound.put("Paper.Origin", this.newDoubleList(this.origin.getX(), this.origin.getY(), this.origin.getZ()));
|
||||
+ compound.store("Paper.Origin", Vec3.CODEC, new Vec3(this.origin.getX(), this.origin.getY(), this.origin.getZ()));
|
||||
+ }
|
||||
+ if (this.spawnReason != null) {
|
||||
+ compound.putString("Paper.SpawnReason", this.spawnReason.name());
|
||||
@@ -852,53 +845,51 @@
|
||||
+ }
|
||||
+ // Paper end
|
||||
return compound;
|
||||
} catch (Throwable var9) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var9, "Saving entity NBT");
|
||||
@@ -1930,6 +_,69 @@
|
||||
} catch (Throwable var8) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var8, "Saving entity NBT");
|
||||
@@ -1932,6 +_,67 @@
|
||||
} else {
|
||||
throw new IllegalStateException("Entity has invalid rotation");
|
||||
}
|
||||
+ // CraftBukkit start
|
||||
+ // Spigot start
|
||||
+ if (this instanceof net.minecraft.world.entity.LivingEntity) {
|
||||
+ this.totalEntityAge = compound.getInt("Spigot.ticksLived"); // Paper
|
||||
+ this.totalEntityAge = compound.getIntOr("Spigot.ticksLived", 0); // Paper
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+ this.persist = !compound.contains("Bukkit.persist") || compound.getBoolean("Bukkit.persist");
|
||||
+ this.visibleByDefault = !compound.contains("Bukkit.visibleByDefault") || compound.getBoolean("Bukkit.visibleByDefault");
|
||||
+ this.persist = compound.getBooleanOr("Bukkit.persist", true);
|
||||
+ this.visibleByDefault = compound.getBooleanOr("Bukkit.visibleByDefault", true);
|
||||
+ // SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
|
||||
+ if (compound.contains("Bukkit.MaxAirSupply")) {
|
||||
+ this.maxAirTicks = compound.getInt("Bukkit.MaxAirSupply");
|
||||
+ }
|
||||
+ this.maxAirTicks = compound.getIntOr("Bukkit.MaxAirSupply",this.maxAirTicks);
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ // Paper - move world parsing/loading to PlayerList#placeNewPlayer
|
||||
+ this.getBukkitEntity().readBukkitValues(compound);
|
||||
+ if (compound.contains("Bukkit.invisible")) {
|
||||
+ boolean bukkitInvisible = compound.getBoolean("Bukkit.invisible");
|
||||
+ boolean bukkitInvisible = compound.getBooleanOr("Bukkit.invisible", false);
|
||||
+ this.setInvisible(bukkitInvisible);
|
||||
+ this.persistentInvisibility = bukkitInvisible;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ // Paper start
|
||||
+ ListTag originTag = compound.getList("Paper.Origin", net.minecraft.nbt.Tag.TAG_DOUBLE);
|
||||
+ if (!originTag.isEmpty()) {
|
||||
+ Optional<Vec3> originTag = compound.read("Paper.Origin", Vec3.CODEC);
|
||||
+ if (originTag.isPresent()) {
|
||||
+ UUID originWorld = null;
|
||||
+ if (compound.contains("Paper.OriginWorld")) {
|
||||
+ originWorld = compound.getUUID("Paper.OriginWorld");
|
||||
+ originWorld = compound.read("Paper.OriginWorld", UUIDUtil.CODEC).orElse(null);
|
||||
+ } else if (this.level != null) {
|
||||
+ originWorld = this.level.getWorld().getUID();
|
||||
+ }
|
||||
+ this.originWorld = originWorld;
|
||||
+ origin = new org.bukkit.util.Vector(originTag.getDouble(0), originTag.getDouble(1), originTag.getDouble(2));
|
||||
+ origin = new org.bukkit.util.Vector(originTag.get().x, originTag.get().y, originTag.get().z);
|
||||
+ }
|
||||
+
|
||||
+ spawnedViaMobSpawner = compound.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
|
||||
+ fromNetherPortal = compound.getBoolean("Paper.FromNetherPortal");
|
||||
+ spawnedViaMobSpawner = compound.getBooleanOr("Paper.FromMobSpawner", false); // Restore entity's from mob spawner status
|
||||
+ fromNetherPortal = compound.getBooleanOr("Paper.FromNetherPortal", false);
|
||||
+ if (compound.contains("Paper.SpawnReason")) {
|
||||
+ String spawnReasonName = compound.getString("Paper.SpawnReason");
|
||||
+ String spawnReasonName = compound.getString("Paper.SpawnReason").orElse(null);
|
||||
+ try {
|
||||
+ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.valueOf(spawnReasonName);
|
||||
+ } catch (Exception ignored) {
|
||||
@@ -909,7 +900,7 @@
|
||||
+ if (spawnedViaMobSpawner) {
|
||||
+ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER;
|
||||
+ } else if (this instanceof Mob && (this instanceof net.minecraft.world.entity.animal.Animal || this instanceof net.minecraft.world.entity.animal.AbstractFish) && !((Mob) this).removeWhenFarAway(0.0)) {
|
||||
+ if (!compound.getBoolean("PersistenceRequired")) {
|
||||
+ if (!compound.getBooleanOr("PersistenceRequired", false)) {
|
||||
+ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL;
|
||||
+ }
|
||||
+ }
|
||||
@@ -918,13 +909,13 @@
|
||||
+ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT;
|
||||
+ }
|
||||
+ if (compound.contains("Paper.FreezeLock")) {
|
||||
+ freezeLocked = compound.getBoolean("Paper.FreezeLock");
|
||||
+ freezeLocked = compound.getBooleanOr("Paper.FreezeLock", false);
|
||||
+ }
|
||||
+ // Paper end
|
||||
} catch (Throwable var17) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var17, "Loading entity NBT");
|
||||
} catch (Throwable var8) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var8, "Loading entity NBT");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being loaded");
|
||||
@@ -1944,10 +_,21 @@
|
||||
@@ -1946,10 +_,21 @@
|
||||
|
||||
@Nullable
|
||||
public final String getEncodeId() {
|
||||
@@ -948,7 +939,7 @@
|
||||
|
||||
protected abstract void readAdditionalSaveData(CompoundTag tag);
|
||||
|
||||
@@ -1990,11 +_,61 @@
|
||||
@@ -1972,11 +_,61 @@
|
||||
|
||||
@Nullable
|
||||
public ItemEntity spawnAtLocation(ServerLevel level, ItemStack stack, float yOffset) {
|
||||
@@ -1011,7 +1002,7 @@
|
||||
level.addFreshEntity(itemEntity);
|
||||
return itemEntity;
|
||||
}
|
||||
@@ -2028,7 +_,16 @@
|
||||
@@ -2008,7 +_,16 @@
|
||||
if (this.isAlive() && this instanceof Leashable leashable) {
|
||||
if (leashable.getLeashHolder() == player) {
|
||||
if (!this.level().isClientSide()) {
|
||||
@@ -1029,7 +1020,7 @@
|
||||
leashable.removeLeash();
|
||||
} else {
|
||||
leashable.dropLeash();
|
||||
@@ -2043,6 +_,13 @@
|
||||
@@ -2023,6 +_,13 @@
|
||||
ItemStack itemInHand = player.getItemInHand(hand);
|
||||
if (itemInHand.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) {
|
||||
if (!this.level().isClientSide()) {
|
||||
@@ -1043,7 +1034,7 @@
|
||||
leashable.setLeashedTo(player, true);
|
||||
}
|
||||
|
||||
@@ -2116,11 +_,11 @@
|
||||
@@ -2096,11 +_,11 @@
|
||||
}
|
||||
|
||||
public boolean startRiding(Entity vehicle, boolean force) {
|
||||
@@ -1057,7 +1048,7 @@
|
||||
return false;
|
||||
} else {
|
||||
for (Entity entity = vehicle; entity.vehicle != null; entity = entity.vehicle) {
|
||||
@@ -2130,6 +_,27 @@
|
||||
@@ -2110,6 +_,27 @@
|
||||
}
|
||||
|
||||
if (force || this.canRide(vehicle) && vehicle.canAddPassenger(this)) {
|
||||
@@ -1085,7 +1076,7 @@
|
||||
if (this.isPassenger()) {
|
||||
this.stopRiding();
|
||||
}
|
||||
@@ -2158,15 +_,26 @@
|
||||
@@ -2138,15 +_,26 @@
|
||||
}
|
||||
|
||||
public void removeVehicle() {
|
||||
@@ -1114,7 +1105,7 @@
|
||||
}
|
||||
|
||||
protected void addPassenger(Entity passenger) {
|
||||
@@ -2190,10 +_,43 @@
|
||||
@@ -2170,10 +_,43 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1159,7 +1150,7 @@
|
||||
if (this.passengers.size() == 1 && this.passengers.get(0) == passenger) {
|
||||
this.passengers = ImmutableList.of();
|
||||
} else {
|
||||
@@ -2203,6 +_,7 @@
|
||||
@@ -2183,6 +_,7 @@
|
||||
passenger.boardingCooldown = 60;
|
||||
this.gameEvent(GameEvent.ENTITY_DISMOUNT, passenger);
|
||||
}
|
||||
@@ -1167,7 +1158,7 @@
|
||||
}
|
||||
|
||||
protected boolean canAddPassenger(Entity passenger) {
|
||||
@@ -2295,8 +_,8 @@
|
||||
@@ -2266,8 +_,8 @@
|
||||
TeleportTransition portalDestination = this.portalProcess.getPortalDestination(serverLevel, this);
|
||||
if (portalDestination != null) {
|
||||
ServerLevel level = portalDestination.newLevel();
|
||||
@@ -1178,7 +1169,7 @@
|
||||
this.teleport(portalDestination);
|
||||
}
|
||||
}
|
||||
@@ -2377,7 +_,7 @@
|
||||
@@ -2348,7 +_,7 @@
|
||||
}
|
||||
|
||||
public boolean isCrouching() {
|
||||
@@ -1187,7 +1178,7 @@
|
||||
}
|
||||
|
||||
public boolean isSprinting() {
|
||||
@@ -2393,7 +_,7 @@
|
||||
@@ -2364,7 +_,7 @@
|
||||
}
|
||||
|
||||
public boolean isVisuallySwimming() {
|
||||
@@ -1196,7 +1187,7 @@
|
||||
}
|
||||
|
||||
public boolean isVisuallyCrawling() {
|
||||
@@ -2401,6 +_,13 @@
|
||||
@@ -2372,6 +_,13 @@
|
||||
}
|
||||
|
||||
public void setSwimming(boolean swimming) {
|
||||
@@ -1210,7 +1201,7 @@
|
||||
this.setSharedFlag(4, swimming);
|
||||
}
|
||||
|
||||
@@ -2439,6 +_,7 @@
|
||||
@@ -2410,6 +_,7 @@
|
||||
|
||||
@Nullable
|
||||
public PlayerTeam getTeam() {
|
||||
@@ -1218,7 +1209,7 @@
|
||||
return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName());
|
||||
}
|
||||
|
||||
@@ -2455,7 +_,11 @@
|
||||
@@ -2426,7 +_,11 @@
|
||||
}
|
||||
|
||||
public void setInvisible(boolean invisible) {
|
||||
@@ -1231,7 +1222,7 @@
|
||||
}
|
||||
|
||||
public boolean getSharedFlag(int flag) {
|
||||
@@ -2472,7 +_,7 @@
|
||||
@@ -2443,7 +_,7 @@
|
||||
}
|
||||
|
||||
public int getMaxAirSupply() {
|
||||
@@ -1240,7 +1231,7 @@
|
||||
}
|
||||
|
||||
public int getAirSupply() {
|
||||
@@ -2480,7 +_,18 @@
|
||||
@@ -2451,10 +_,22 @@
|
||||
}
|
||||
|
||||
public void setAirSupply(int air) {
|
||||
@@ -1259,8 +1250,12 @@
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public int getTicksFrozen() {
|
||||
@@ -2506,11 +_,43 @@
|
||||
public void clearFreeze() {
|
||||
+ if (this.freezeLocked) return; // Paper - Freeze Tick Lock API
|
||||
this.setTicksFrozen(0);
|
||||
}
|
||||
|
||||
@@ -2481,11 +_,43 @@
|
||||
|
||||
public void thunderHit(ServerLevel level, LightningBolt lightning) {
|
||||
this.setRemainingFireTicks(this.remainingFireTicks + 1);
|
||||
@@ -1307,8 +1302,8 @@
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public void onAboveBubbleCol(boolean downwards) {
|
||||
@@ -2636,26 +_,30 @@
|
||||
public void onAboveBubbleColumn(boolean downwards, BlockPos pos) {
|
||||
@@ -2641,26 +_,30 @@
|
||||
return this.removalReason != null
|
||||
? String.format(
|
||||
Locale.ROOT,
|
||||
@@ -1342,7 +1337,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2679,6 +_,13 @@
|
||||
@@ -2684,6 +_,13 @@
|
||||
}
|
||||
|
||||
public void restoreFrom(Entity entity) {
|
||||
@@ -1356,7 +1351,7 @@
|
||||
CompoundTag compoundTag = entity.saveWithoutId(new CompoundTag());
|
||||
compoundTag.remove("Dimension");
|
||||
this.load(compoundTag);
|
||||
@@ -2688,7 +_,56 @@
|
||||
@@ -2693,7 +_,56 @@
|
||||
|
||||
@Nullable
|
||||
public Entity teleport(TeleportTransition teleportTransition) {
|
||||
@@ -1413,7 +1408,7 @@
|
||||
ServerLevel level = teleportTransition.newLevel();
|
||||
boolean flag = level.dimension() != serverLevel.dimension();
|
||||
if (!teleportTransition.asPassenger()) {
|
||||
@@ -2737,10 +_,19 @@
|
||||
@@ -2742,10 +_,19 @@
|
||||
profilerFiller.pop();
|
||||
return null;
|
||||
} else {
|
||||
@@ -1434,7 +1429,7 @@
|
||||
|
||||
for (Entity entity2 : list) {
|
||||
entity2.startRiding(entityx, true);
|
||||
@@ -2814,9 +_,17 @@
|
||||
@@ -2818,9 +_,17 @@
|
||||
}
|
||||
|
||||
protected void removeAfterChangingDimensions() {
|
||||
@@ -1455,7 +1450,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2824,11 +_,34 @@
|
||||
@@ -2828,11 +_,34 @@
|
||||
return PortalShape.getRelativePosition(portal, axis, this.position(), this.getDimensions(this.getPose()));
|
||||
}
|
||||
|
||||
@@ -1490,24 +1485,23 @@
|
||||
if (fromLevel.dimension() == Level.END && toLevel.dimension() == Level.OVERWORLD) {
|
||||
for (Entity entity : this.getPassengers()) {
|
||||
if (entity instanceof ServerPlayer serverPlayer && !serverPlayer.seenCredits) {
|
||||
@@ -2936,9 +_,14 @@
|
||||
@@ -2940,8 +_,13 @@
|
||||
return this.entityData.get(DATA_CUSTOM_NAME_VISIBLE);
|
||||
}
|
||||
|
||||
- public boolean teleportTo(ServerLevel level, double x, double y, double z, Set<Relative> relativeMovements, float yaw, float pitch, boolean setCamera) {
|
||||
- Entity entity = this.teleport(new TeleportTransition(level, new Vec3(x, y, z), Vec3.ZERO, yaw, pitch, relativeMovements, TeleportTransition.DO_NOTHING));
|
||||
+ // CraftBukkit start
|
||||
+ public final boolean teleportTo(ServerLevel level, double x, double y, double z, Set<Relative> relativeMovements, float yaw, float pitch, boolean setCamera) {
|
||||
+ return this.teleportTo(level, x, y, z, relativeMovements, yaw, pitch, setCamera, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.UNKNOWN);
|
||||
+ }
|
||||
+ public boolean teleportTo(ServerLevel level, double x, double y, double z, Set<Relative> relativeMovements, float yaw, float pitch, boolean setCamera, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause) {
|
||||
+ // CraftBukkit end
|
||||
float f = Mth.clamp(pitch, -90.0F, 90.0F);
|
||||
- Entity entity = this.teleport(new TeleportTransition(level, new Vec3(x, y, z), Vec3.ZERO, yaw, f, relativeMovements, TeleportTransition.DO_NOTHING));
|
||||
+ Entity entity = this.teleport(new TeleportTransition(level, new Vec3(x, y, z), Vec3.ZERO, yaw, f, relativeMovements, TeleportTransition.DO_NOTHING, cause)); // CraftBukkit
|
||||
+ Entity entity = this.teleport(new TeleportTransition(level, new Vec3(x, y, z), Vec3.ZERO, yaw, pitch, relativeMovements, TeleportTransition.DO_NOTHING, cause)); // CraftBukkit
|
||||
return entity != null;
|
||||
}
|
||||
|
||||
@@ -3052,7 +_,26 @@
|
||||
@@ -3055,7 +_,26 @@
|
||||
}
|
||||
|
||||
public final void setBoundingBox(AABB bb) {
|
||||
@@ -1535,7 +1529,7 @@
|
||||
}
|
||||
|
||||
public final float getEyeHeight(Pose pose) {
|
||||
@@ -3096,6 +_,12 @@
|
||||
@@ -3099,6 +_,12 @@
|
||||
}
|
||||
|
||||
public void stopSeenByPlayer(ServerPlayer serverPlayer) {
|
||||
@@ -1548,7 +1542,7 @@
|
||||
}
|
||||
|
||||
public float rotate(Rotation transformRotation) {
|
||||
@@ -3129,7 +_,7 @@
|
||||
@@ -3132,7 +_,7 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1557,7 +1551,7 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3161,21 +_,32 @@
|
||||
@@ -3164,21 +_,32 @@
|
||||
}
|
||||
|
||||
private Stream<Entity> getIndirectPassengersStream() {
|
||||
@@ -1591,7 +1585,7 @@
|
||||
}
|
||||
|
||||
public int countPlayerPassengers() {
|
||||
@@ -3183,6 +_,7 @@
|
||||
@@ -3186,6 +_,7 @@
|
||||
}
|
||||
|
||||
public boolean hasExactlyOnePlayerPassenger() {
|
||||
@@ -1599,7 +1593,7 @@
|
||||
return this.countPlayerPassengers() == 1;
|
||||
}
|
||||
|
||||
@@ -3260,9 +_,38 @@
|
||||
@@ -3268,9 +_,38 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1639,7 +1633,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3320,6 +_,11 @@
|
||||
@@ -3328,6 +_,11 @@
|
||||
vec3 = vec3.add(flow);
|
||||
i++;
|
||||
}
|
||||
@@ -1651,7 +1645,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3417,7 +_,9 @@
|
||||
@@ -3425,7 +_,9 @@
|
||||
}
|
||||
|
||||
public void setDeltaMovement(Vec3 deltaMovement) {
|
||||
@@ -1661,7 +1655,7 @@
|
||||
}
|
||||
|
||||
public void addDeltaMovement(Vec3 addend) {
|
||||
@@ -3480,9 +_,43 @@
|
||||
@@ -3488,9 +_,43 @@
|
||||
return this.getZ((2.0 * this.random.nextDouble() - 1.0) * scale);
|
||||
}
|
||||
|
||||
@@ -1705,7 +1699,7 @@
|
||||
int floor = Mth.floor(x);
|
||||
int floor1 = Mth.floor(y);
|
||||
int floor2 = Mth.floor(z);
|
||||
@@ -3496,6 +_,12 @@
|
||||
@@ -3504,6 +_,12 @@
|
||||
|
||||
this.levelCallback.onMove();
|
||||
}
|
||||
@@ -1718,7 +1712,7 @@
|
||||
}
|
||||
|
||||
public void checkDespawn() {
|
||||
@@ -3583,6 +_,15 @@
|
||||
@@ -3594,6 +_,15 @@
|
||||
|
||||
@Override
|
||||
public final void setRemoved(Entity.RemovalReason removalReason) {
|
||||
@@ -1734,7 +1728,7 @@
|
||||
if (this.removalReason == null) {
|
||||
this.removalReason = removalReason;
|
||||
}
|
||||
@@ -3594,12 +_,28 @@
|
||||
@@ -3605,12 +_,28 @@
|
||||
this.getPassengers().forEach(Entity::stopRiding);
|
||||
this.levelCallback.onRemove(removalReason);
|
||||
this.onRemoval(removalReason);
|
||||
@@ -1763,7 +1757,7 @@
|
||||
@Override
|
||||
public void setLevelCallback(EntityInLevelCallback levelCallback) {
|
||||
this.levelCallback = levelCallback;
|
||||
@@ -3723,4 +_,14 @@
|
||||
@@ -3780,4 +_,14 @@
|
||||
return this.save;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/EntitySelector.java
|
||||
+++ b/net/minecraft/world/entity/EntitySelector.java
|
||||
@@ -16,6 +_,23 @@
|
||||
@@ -17,6 +_,23 @@
|
||||
public static final Predicate<Entity> NO_SPECTATORS = entity -> !entity.isSpectator();
|
||||
public static final Predicate<Entity> CAN_BE_COLLIDED_WITH = NO_SPECTATORS.and(Entity::canBeCollidedWith);
|
||||
public static final Predicate<Entity> CAN_BE_PICKED = NO_SPECTATORS.and(Entity::isPickable);
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
private EntitySelector() {
|
||||
}
|
||||
@@ -26,29 +_,34 @@
|
||||
@@ -27,18 +_,23 @@
|
||||
}
|
||||
|
||||
public static Predicate<Entity> pushableBy(Entity entity) {
|
||||
@@ -38,38 +38,15 @@
|
||||
return (Predicate<Entity>)(collisionRule == Team.CollisionRule.NEVER
|
||||
? Predicates.alwaysFalse()
|
||||
: NO_SPECTATORS.and(
|
||||
- pushedEntity -> {
|
||||
pushedEntity -> {
|
||||
- if (!pushedEntity.isPushable()) {
|
||||
+ pushedEntity -> {
|
||||
+ if (!pushedEntity.isCollidable(ignoreClimbing) || !pushedEntity.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(pushedEntity)) { // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule
|
||||
+ return false;
|
||||
+ } else if (!entity.level().isClientSide || pushedEntity instanceof Player && ((Player)pushedEntity).isLocalPlayer()) {
|
||||
+ Team team1 = pushedEntity.getTeam();
|
||||
+ Team.CollisionRule collisionRule1 = team1 == null ? Team.CollisionRule.ALWAYS : team1.getCollisionRule();
|
||||
+ if (collisionRule1 == Team.CollisionRule.NEVER || (pushedEntity instanceof Player && !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions)) { // Paper - Configurable player collision
|
||||
+ if (!pushedEntity.isCollidable(ignoreClimbing) || !pushedEntity.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(pushedEntity)) { // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule
|
||||
return false;
|
||||
- } else if (!entity.level().isClientSide || pushedEntity instanceof Player && ((Player)pushedEntity).isLocalPlayer()) {
|
||||
- Team team1 = pushedEntity.getTeam();
|
||||
- Team.CollisionRule collisionRule1 = team1 == null ? Team.CollisionRule.ALWAYS : team1.getCollisionRule();
|
||||
} else if (!entity.level().isClientSide || pushedEntity instanceof Player player && player.isLocalPlayer()) {
|
||||
Team team1 = pushedEntity.getTeam();
|
||||
Team.CollisionRule collisionRule1 = team1 == null ? Team.CollisionRule.ALWAYS : team1.getCollisionRule();
|
||||
- if (collisionRule1 == Team.CollisionRule.NEVER) {
|
||||
- return false;
|
||||
- } else {
|
||||
- boolean flag = team != null && team.isAlliedTo(team1);
|
||||
- return (collisionRule != Team.CollisionRule.PUSH_OWN_TEAM && collisionRule1 != Team.CollisionRule.PUSH_OWN_TEAM || !flag)
|
||||
- && (collisionRule != Team.CollisionRule.PUSH_OTHER_TEAMS && collisionRule1 != Team.CollisionRule.PUSH_OTHER_TEAMS || flag);
|
||||
- }
|
||||
} else {
|
||||
- return false;
|
||||
+ boolean flag = team != null && team.isAlliedTo(team1);
|
||||
+ return (collisionRule != Team.CollisionRule.PUSH_OWN_TEAM && collisionRule1 != Team.CollisionRule.PUSH_OWN_TEAM || !flag)
|
||||
+ && (collisionRule != Team.CollisionRule.PUSH_OTHER_TEAMS && collisionRule1 != Team.CollisionRule.PUSH_OTHER_TEAMS || flag);
|
||||
}
|
||||
+ } else {
|
||||
+ return false;
|
||||
}
|
||||
- ));
|
||||
+ }
|
||||
+ ));
|
||||
}
|
||||
|
||||
public static Predicate<Entity> notRiding(Entity entity) {
|
||||
+ if (collisionRule1 == Team.CollisionRule.NEVER || (pushedEntity instanceof Player && !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions)) { // Paper - Configurable player collision
|
||||
return false;
|
||||
} else {
|
||||
boolean flag = team != null && team.isAlliedTo(team1);
|
||||
@@ -1,14 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/net/minecraft/world/entity/EntityType.java
|
||||
@@ -176,6 +_,7 @@
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class EntityType<T extends Entity> implements FeatureElement, EntityTypeTest<Entity, T> {
|
||||
@@ -215,7 +_,7 @@
|
||||
@@ -216,7 +_,7 @@
|
||||
.fireImmune()
|
||||
.sized(6.0F, 0.5F)
|
||||
.clientTrackingRange(10)
|
||||
@@ -17,7 +9,7 @@
|
||||
);
|
||||
public static final EntityType<Armadillo> ARMADILLO = register(
|
||||
"armadillo", EntityType.Builder.of(Armadillo::new, MobCategory.CREATURE).sized(0.7F, 0.65F).eyeHeight(0.26F).clientTrackingRange(10)
|
||||
@@ -1132,6 +_,22 @@
|
||||
@@ -1145,6 +_,22 @@
|
||||
boolean shouldOffsetY,
|
||||
boolean shouldOffsetYMore
|
||||
) {
|
||||
@@ -39,8 +31,8 @@
|
||||
+ // CraftBukkit end
|
||||
Consumer<T> consumer;
|
||||
if (spawnedFrom != null) {
|
||||
consumer = createDefaultStackConfig(level, spawnedFrom, player);
|
||||
@@ -1139,7 +_,7 @@
|
||||
consumer = createDefaultStackConfig(level, spawnedFrom, owner);
|
||||
@@ -1152,7 +_,7 @@
|
||||
consumer = entity -> {};
|
||||
}
|
||||
|
||||
@@ -48,16 +40,16 @@
|
||||
+ return this.spawn(level, consumer, pos, reason, shouldOffsetY, shouldOffsetYMore, createSpawnReason); // CraftBukkit
|
||||
}
|
||||
|
||||
public static <T extends Entity> Consumer<T> createDefaultStackConfig(Level level, ItemStack spawnedFrom, @Nullable Player player) {
|
||||
@@ -1159,19 +_,54 @@
|
||||
Consumer<T> consumer, Level level, ItemStack spawnedFrom, @Nullable Player player
|
||||
) {
|
||||
CustomData customData = spawnedFrom.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
|
||||
- return !customData.isEmpty() ? consumer.andThen(entity -> updateCustomEntityTag(level, player, entity, customData)) : consumer;
|
||||
public static <T extends Entity> Consumer<T> createDefaultStackConfig(Level level, ItemStack stack, @Nullable LivingEntity owner) {
|
||||
@@ -1169,19 +_,54 @@
|
||||
|
||||
public static <T extends Entity> Consumer<T> appendCustomEntityStackConfig(Consumer<T> consumer, Level level, ItemStack stack, @Nullable LivingEntity owner) {
|
||||
CustomData customData = stack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
|
||||
- return !customData.isEmpty() ? consumer.andThen(entity -> updateCustomEntityTag(level, owner, entity, customData)) : consumer;
|
||||
+ // CraftBukkit start - SPIGOT-5665
|
||||
+ return !customData.isEmpty() ? consumer.andThen(entity -> {
|
||||
+ try {
|
||||
+ updateCustomEntityTag(level, player, entity, customData);
|
||||
+ updateCustomEntityTag(level, owner, entity, customData);
|
||||
+ } catch (Throwable t) {
|
||||
+ EntityType.LOGGER.warn("Error loading spawn egg NBT", t);
|
||||
+ }
|
||||
@@ -107,12 +99,12 @@
|
||||
if (entity instanceof Mob mob) {
|
||||
mob.playAmbientSound();
|
||||
}
|
||||
@@ -1225,6 +_,15 @@
|
||||
EntityType<?> entityType = customData.parseEntityType(server.registryAccess(), Registries.ENTITY_TYPE);
|
||||
if (entity.getType() == entityType) {
|
||||
if (level.isClientSide || !entity.getType().onlyOpCanSetNbt() || player != null && server.getPlayerList().isOp(player.getGameProfile())) {
|
||||
@@ -1237,6 +_,15 @@
|
||||
if (level.isClientSide
|
||||
|| !entity.getType().onlyOpCanSetNbt()
|
||||
|| owner instanceof Player player && server.getPlayerList().isOp(player.getGameProfile())) {
|
||||
+ // Paper start - filter out protected tags
|
||||
+ if (player == null || !player.getBukkitEntity().hasPermission("minecraft.nbt.place")) {
|
||||
+ if (owner == null || !owner.getBukkitEntity().hasPermission("minecraft.nbt.place")) {
|
||||
+ customData = customData.update((compound) -> {
|
||||
+ for (net.minecraft.commands.arguments.NbtPathArgument.NbtPath tag : level.paperConfig().entities.spawning.filteredEntityTagNbtPaths) {
|
||||
+ tag.remove(compound);
|
||||
@@ -123,7 +115,7 @@
|
||||
customData.loadInto(entity);
|
||||
}
|
||||
}
|
||||
@@ -1296,9 +_,19 @@
|
||||
@@ -1308,9 +_,19 @@
|
||||
}
|
||||
|
||||
public static Optional<Entity> create(CompoundTag tag, Level level, EntitySpawnReason spawnReason) {
|
||||
@@ -135,21 +127,12 @@
|
||||
return Util.ifElse(
|
||||
by(tag).map(entityType -> entityType.create(level, spawnReason)),
|
||||
- entity -> entity.load(tag),
|
||||
+ // Paper start - Don't fire sync event during generation
|
||||
+ entity -> {
|
||||
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
|
||||
+ entity.load(tag);
|
||||
+ },
|
||||
+ // Paper end - Don't fire sync event during generation
|
||||
() -> LOGGER.warn("Skipping Entity with id {}", tag.getString("id"))
|
||||
+ // Paper start - Don't fire sync event during generation
|
||||
+ entity -> {
|
||||
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
|
||||
+ entity.load(tag);
|
||||
+ },
|
||||
+ // Paper end - Don't fire sync event during generation
|
||||
() -> LOGGER.warn("Skipping Entity with id {}", tag.getStringOr("id", "[invalid]"))
|
||||
);
|
||||
}
|
||||
@@ -1325,7 +_,7 @@
|
||||
}
|
||||
|
||||
public static Optional<EntityType<?>> by(CompoundTag tag) {
|
||||
- return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.parse(tag.getString("id")));
|
||||
+ return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(tag.getString("id"))); // Paper - Validate ResourceLocation
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -13,12 +13,12 @@
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public class ExperienceOrb extends Entity {
|
||||
protected static final EntityDataAccessor<Integer> DATA_VALUE = SynchedEntityData.defineId(ExperienceOrb.class, EntityDataSerializers.INT);
|
||||
private static final int LIFETIME = 6000;
|
||||
private static final int ENTITY_SCAN_PERIOD = 20;
|
||||
@@ -35,9 +_,63 @@
|
||||
public int value;
|
||||
public int count = 1;
|
||||
@@ -41,9 +_,63 @@
|
||||
@Nullable
|
||||
private Player followingPlayer;
|
||||
private final InterpolationHandler interpolation = new InterpolationHandler(this);
|
||||
-
|
||||
+ // Paper start
|
||||
+ @javax.annotation.Nullable
|
||||
@@ -78,18 +78,25 @@
|
||||
+ this.spawnReason = reason != null ? reason : org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
|
||||
+ // Paper end
|
||||
this.setPos(x, y, z);
|
||||
this.setYRot((float)(this.random.nextDouble() * 360.0));
|
||||
this.setDeltaMovement(
|
||||
@@ -67,6 +_,7 @@
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!this.level().isClientSide) {
|
||||
this.setYRot((float)(this.random.nextDouble() * 360.0));
|
||||
@@ -119,12 +_,13 @@
|
||||
|
||||
this.age++;
|
||||
if (this.age >= 6000) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void followNearbyPlayer() {
|
||||
+ Player prevTarget = this.followingPlayer;// CraftBukkit - store old target
|
||||
this.xo = this.getX();
|
||||
this.yo = this.getY();
|
||||
this.zo = this.getZ();
|
||||
@@ -92,7 +_,22 @@
|
||||
this.followingPlayer = null;
|
||||
if (this.followingPlayer == null || this.followingPlayer.distanceToSqr(this) > 64.0) {
|
||||
Player nearestPlayer = this.level().getNearestPlayer(this, 8.0);
|
||||
if (nearestPlayer != null && !nearestPlayer.isSpectator() && !nearestPlayer.isDeadOrDying()) {
|
||||
@@ -134,7 +_,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (this.followingPlayer != null) {
|
||||
@@ -112,16 +119,7 @@
|
||||
Vec3 vec3 = new Vec3(
|
||||
this.followingPlayer.getX() - this.getX(),
|
||||
this.followingPlayer.getY() + this.followingPlayer.getEyeHeight() / 2.0 - this.getY(),
|
||||
@@ -120,7 +_,7 @@
|
||||
|
||||
this.age++;
|
||||
if (this.age >= 6000) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,16 +_,25 @@
|
||||
@@ -161,16 +_,25 @@
|
||||
}
|
||||
|
||||
public static void award(ServerLevel level, Vec3 pos, int amount) {
|
||||
@@ -148,7 +146,7 @@
|
||||
AABB aabb = AABB.ofSize(pos, 1.0, 1.0, 1.0);
|
||||
int randomInt = level.getRandom().nextInt(40);
|
||||
List<ExperienceOrb> entities = level.getEntities(EntityTypeTest.forClass(ExperienceOrb.class), aabb, orb -> canMerge(orb, randomInt, amount));
|
||||
@@ -175,9 +_,14 @@
|
||||
@@ -193,9 +_,14 @@
|
||||
}
|
||||
|
||||
private void merge(ExperienceOrb orb) {
|
||||
@@ -164,7 +162,7 @@
|
||||
}
|
||||
|
||||
private void setUnderwaterMovement() {
|
||||
@@ -202,7 +_,7 @@
|
||||
@@ -220,7 +_,7 @@
|
||||
this.markHurt();
|
||||
this.health = (int)(this.health - amount);
|
||||
if (this.health <= 0) {
|
||||
@@ -173,23 +171,23 @@
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -213,32 +_,34 @@
|
||||
@@ -231,32 +_,34 @@
|
||||
public void addAdditionalSaveData(CompoundTag compound) {
|
||||
compound.putShort("Health", (short)this.health);
|
||||
compound.putShort("Age", (short)this.age);
|
||||
- compound.putShort("Value", (short)this.value);
|
||||
+ compound.putInt("Value", this.value); // Paper - save as Integer
|
||||
- compound.putShort("Value", (short)this.getValue());
|
||||
+ compound.putInt("Value", this.getValue()); // Paper - save as Integer
|
||||
compound.putInt("Count", this.count);
|
||||
+ this.savePaperNBT(compound); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag compound) {
|
||||
this.health = compound.getShort("Health");
|
||||
this.age = compound.getShort("Age");
|
||||
- this.value = compound.getShort("Value");
|
||||
+ this.value = compound.getInt("Value"); // Paper - load as Integer
|
||||
this.count = Math.max(compound.getInt("Count"), 1);
|
||||
this.health = compound.getShortOr("Health", (short)5);
|
||||
this.age = compound.getShortOr("Age", (short)0);
|
||||
- this.setValue(compound.getShortOr("Value", (short)0));
|
||||
+ this.setValue(compound.getIntOr("Value", 0)); // Paper - load as Integer
|
||||
this.count = compound.read("Count", ExtraCodecs.POSITIVE_INT).orElse(1);
|
||||
+ this.loadPaperNBT(compound); // Paper
|
||||
}
|
||||
|
||||
@@ -201,7 +199,7 @@
|
||||
+ if (entity.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent
|
||||
+ entity.takeXpDelay = CraftEventFactory.callPlayerXpCooldownEvent(entity, 2, PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2;
|
||||
entity.take(this, 1);
|
||||
int i = this.repairPlayerItems(serverPlayer, this.value);
|
||||
int i = this.repairPlayerItems(serverPlayer, this.getValue());
|
||||
if (i > 0) {
|
||||
- entity.giveExperiencePoints(i);
|
||||
+ entity.giveExperiencePoints(CraftEventFactory.callPlayerExpChangeEvent(entity, this).getAmount()); // CraftBukkit - this.value -> event.getAmount() // Paper - supply experience orb object
|
||||
@@ -214,7 +212,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,10 +_,21 @@
|
||||
@@ -270,10 +_,21 @@
|
||||
ItemStack itemStack = randomItemWith.get().itemStack();
|
||||
int i = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.serverLevel(), itemStack, value);
|
||||
int min = Math.min(i, itemStack.getDamageValue());
|
||||
@@ -237,7 +235,7 @@
|
||||
return this.repairPlayerItems(player, i1);
|
||||
}
|
||||
}
|
||||
@@ -295,6 +_,24 @@
|
||||
@@ -318,6 +_,24 @@
|
||||
}
|
||||
|
||||
public static int getExperienceValue(int expValue) {
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/world/entity/InsideBlockEffectType.java
|
||||
+++ b/net/minecraft/world/entity/InsideBlockEffectType.java
|
||||
@@ -6,7 +_,7 @@
|
||||
public enum InsideBlockEffectType {
|
||||
FREEZE(entity -> {
|
||||
entity.setIsInPowderSnow(true);
|
||||
- if (entity.canFreeze()) {
|
||||
+ if (entity.canFreeze() && !entity.freezeLocked) { // Paper - Freeze Tick Lock API
|
||||
entity.setTicksFrozen(Math.min(entity.getTicksRequiredToFreeze(), entity.getTicksFrozen() + 1));
|
||||
}
|
||||
}),
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/Interaction.java
|
||||
+++ b/net/minecraft/world/entity/Interaction.java
|
||||
@@ -130,9 +_,16 @@
|
||||
@@ -100,9 +_,16 @@
|
||||
@Override
|
||||
public boolean skipAttackInteraction(Entity entity) {
|
||||
if (entity instanceof Player player) {
|
||||
|
||||
+3
-6
@@ -1,9 +1,9 @@
|
||||
--- a/net/minecraft/world/entity/ItemBasedSteering.java
|
||||
+++ b/net/minecraft/world/entity/ItemBasedSteering.java
|
||||
@@ -51,6 +_,14 @@
|
||||
@@ -47,4 +_,11 @@
|
||||
public int boostTimeTotal() {
|
||||
return this.entityData.get(this.boostTimeAccessor);
|
||||
}
|
||||
|
||||
+ // CraftBukkit add setBoostTicks(int)
|
||||
+ public void setBoostTicks(int ticks) {
|
||||
+ this.boosting = true;
|
||||
@@ -11,7 +11,4 @@
|
||||
+ this.entityData.set(this.boostTimeAccessor, ticks);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
nbt.putBoolean("Saddle", this.hasSaddle());
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,18 @@
|
||||
--- a/net/minecraft/world/entity/Leashable.java
|
||||
+++ b/net/minecraft/world/entity/Leashable.java
|
||||
@@ -56,7 +_,13 @@
|
||||
@Nullable
|
||||
private static Leashable.LeashData readLeashDataInternal(CompoundTag tag) {
|
||||
if (tag.contains("leash", 10)) {
|
||||
- return new Leashable.LeashData(Either.left(tag.getCompound("leash").getUUID("UUID")));
|
||||
+ // Paper start
|
||||
+ final CompoundTag leashTag = tag.getCompound("leash");
|
||||
+ if (!leashTag.hasUUID("UUID")) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return new Leashable.LeashData(Either.left(leashTag.getUUID("UUID")));
|
||||
+ // Paper end
|
||||
} else {
|
||||
if (tag.contains("leash", 11)) {
|
||||
Either<UUID, BlockPos> either = NbtUtils.readBlockPos(tag, "leash").<Either<UUID, BlockPos>>map(Either::right).orElse(null);
|
||||
@@ -72,6 +_,11 @@
|
||||
@@ -56,6 +_,11 @@
|
||||
}
|
||||
|
||||
default void writeLeashData(CompoundTag tag, @Nullable Leashable.LeashData leashData) {
|
||||
if (leashData != null) {
|
||||
Either<UUID, BlockPos> either = leashData.delayedLeashInfo;
|
||||
+ // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin
|
||||
+ if (leashData.leashHolder != null && leashData.leashHolder.pluginRemoved) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (leashData.leashHolder instanceof LeashFenceKnotEntity leashFenceKnotEntity) {
|
||||
either = Either.right(leashFenceKnotEntity.getPos());
|
||||
} else if (leashData.leashHolder != null) {
|
||||
@@ -104,7 +_,9 @@
|
||||
+ // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin
|
||||
+ if (leashData != null && leashData.leashHolder != null && leashData.leashHolder.pluginRemoved) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
tag.storeNullable("leash", Leashable.LeashData.CODEC, leashData);
|
||||
}
|
||||
|
||||
@@ -75,7 +_,9 @@
|
||||
}
|
||||
|
||||
if (entity.tickCount > 100) {
|
||||
@@ -37,7 +22,7 @@
|
||||
entity.setLeashData(null);
|
||||
}
|
||||
}
|
||||
@@ -128,7 +_,9 @@
|
||||
@@ -99,7 +_,9 @@
|
||||
entity.onLeashRemoved();
|
||||
if (entity.level() instanceof ServerLevel serverLevel) {
|
||||
if (dropItem) {
|
||||
@@ -47,7 +32,7 @@
|
||||
}
|
||||
|
||||
if (broadcastPacket) {
|
||||
@@ -146,7 +_,15 @@
|
||||
@@ -117,7 +_,15 @@
|
||||
|
||||
if (leashData != null && leashData.leashHolder != null) {
|
||||
if (!entity.isAlive() || !leashData.leashHolder.isAlive()) {
|
||||
@@ -64,7 +49,7 @@
|
||||
entity.dropLeash();
|
||||
} else {
|
||||
entity.removeLeash();
|
||||
@@ -160,7 +_,7 @@
|
||||
@@ -131,7 +_,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -73,7 +58,7 @@
|
||||
entity.leashTooFarBehaviour();
|
||||
} else if (f > 6.0) {
|
||||
entity.elasticRangeLeashBehaviour(leashHolder, f);
|
||||
@@ -177,7 +_,21 @@
|
||||
@@ -148,7 +_,21 @@
|
||||
}
|
||||
|
||||
default void leashTooFarBehaviour() {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,8 +1,8 @@
|
||||
--- a/net/minecraft/world/entity/Mob.java
|
||||
+++ b/net/minecraft/world/entity/Mob.java
|
||||
@@ -84,6 +_,18 @@
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
@@ -83,6 +_,18 @@
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.ticks.ContainerSingleItem;
|
||||
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
@@ -27,7 +27,7 @@
|
||||
public GoalSelector targetSelector;
|
||||
@Nullable
|
||||
private LivingEntity target;
|
||||
@@ -131,6 +_,7 @@
|
||||
@@ -126,6 +_,7 @@
|
||||
private Leashable.LeashData leashData;
|
||||
private BlockPos restrictCenter = BlockPos.ZERO;
|
||||
private float restrictRadius = -1.0F;
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
protected Mob(EntityType<? extends Mob> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -150,6 +_,12 @@
|
||||
@@ -142,6 +_,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
protected void registerGoals() {
|
||||
}
|
||||
|
||||
@@ -230,7 +_,40 @@
|
||||
@@ -222,7 +_,40 @@
|
||||
}
|
||||
|
||||
public void setTarget(@Nullable LivingEntity target) {
|
||||
@@ -89,7 +89,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -354,6 +_,12 @@
|
||||
@@ -338,6 +_,12 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag compound) {
|
||||
super.addAdditionalSaveData(compound);
|
||||
@@ -413,13 +_,25 @@
|
||||
@@ -358,13 +_,22 @@
|
||||
if (this.isNoAi()) {
|
||||
compound.putBoolean("NoAI", this.isNoAi());
|
||||
}
|
||||
@@ -112,45 +112,30 @@
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag compound) {
|
||||
super.readAdditionalSaveData(compound);
|
||||
- this.setCanPickUpLoot(compound.getBoolean("CanPickUpLoot"));
|
||||
- this.persistenceRequired = compound.getBoolean("PersistenceRequired");
|
||||
- this.setCanPickUpLoot(compound.getBooleanOr("CanPickUpLoot", false));
|
||||
- this.persistenceRequired = compound.getBooleanOr("PersistenceRequired", false);
|
||||
+ // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it
|
||||
+ if (compound.contains("CanPickUpLoot", 99)) {
|
||||
+ boolean data = compound.getBoolean("CanPickUpLoot");
|
||||
+ if (isLevelAtLeast(compound, 1) || data) {
|
||||
+ this.setCanPickUpLoot(data);
|
||||
+ }
|
||||
+ boolean canPickUpLoot = compound.getBooleanOr("CanPickUpLoot", false);
|
||||
+ if (isLevelAtLeast(compound, 1) || canPickUpLoot) {
|
||||
+ this.setCanPickUpLoot(canPickUpLoot);
|
||||
+ }
|
||||
+
|
||||
+ boolean data = compound.getBoolean("PersistenceRequired");
|
||||
+ if (isLevelAtLeast(compound, 1) || data) {
|
||||
+ this.persistenceRequired = data;
|
||||
+ boolean persistenceRequired = compound.getBooleanOr("PersistenceRequired", false);
|
||||
+ if (isLevelAtLeast(compound, 1) || persistenceRequired) {
|
||||
+ this.persistenceRequired = persistenceRequired;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (compound.contains("ArmorItems", 9)) {
|
||||
ListTag list = compound.getList("ArmorItems", 10);
|
||||
|
||||
@@ -472,13 +_,18 @@
|
||||
RegistryOps<Tag> registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE);
|
||||
this.dropChances = compound.read("drop_chances", DropChances.CODEC, registryOps).orElse(DropChances.DEFAULT);
|
||||
this.readLeashData(compound);
|
||||
this.setLeftHanded(compound.getBoolean("LeftHanded"));
|
||||
if (compound.contains("DeathLootTable", 8)) {
|
||||
- this.lootTable = Optional.of(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(compound.getString("DeathLootTable"))));
|
||||
+ this.lootTable = Optional.ofNullable(ResourceLocation.tryParse(compound.getString("DeathLootTable"))).map((rs) -> ResourceKey.create(Registries.LOOT_TABLE, rs)); // Paper - Validate ResourceLocation
|
||||
} else {
|
||||
this.lootTable = Optional.empty();
|
||||
}
|
||||
|
||||
this.lootTableSeed = compound.getLong("DeathLootTableSeed");
|
||||
this.setNoAi(compound.getBoolean("NoAI"));
|
||||
+ // CraftBukkit start
|
||||
+ if (compound.contains("Bukkit.Aware")) {
|
||||
+ this.aware = compound.getBoolean("Bukkit.Aware");
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
@@ -372,6 +_,7 @@
|
||||
this.lootTable = compound.read("DeathLootTable", LootTable.KEY_CODEC);
|
||||
this.lootTableSeed = compound.getLongOr("DeathLootTableSeed", 0L);
|
||||
this.setNoAi(compound.getBooleanOr("NoAI", false));
|
||||
+ this.aware = compound.getBooleanOr("Bukkit.Aware", true); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -540,6 +_,11 @@
|
||||
@@ -433,6 +_,11 @@
|
||||
&& !itemEntity.getItem().isEmpty()
|
||||
&& !itemEntity.hasPickUpDelay()
|
||||
&& this.wantsToPickUp(serverLevel, itemEntity.getItem())) {
|
||||
@@ -162,7 +147,7 @@
|
||||
this.pickUpItem(serverLevel, itemEntity);
|
||||
}
|
||||
}
|
||||
@@ -554,18 +_,24 @@
|
||||
@@ -447,18 +_,24 @@
|
||||
|
||||
protected void pickUpItem(ServerLevel level, ItemEntity entity) {
|
||||
ItemStack item = entity.getItem();
|
||||
@@ -184,32 +169,32 @@
|
||||
+ return this.equipItemIfPossible(level, stack, null);
|
||||
+ }
|
||||
+
|
||||
+ public ItemStack equipItemIfPossible(ServerLevel level, ItemStack stack, ItemEntity entity) {
|
||||
+ public ItemStack equipItemIfPossible(ServerLevel level, ItemStack stack, @Nullable ItemEntity entity) {
|
||||
+ // CraftBukkit end
|
||||
EquipmentSlot equipmentSlotForItem = this.getEquipmentSlotForItem(stack);
|
||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlotForItem);
|
||||
boolean canReplaceCurrentItem = this.canReplaceCurrentItem(stack, itemBySlot, equipmentSlotForItem);
|
||||
@@ -575,10 +_,18 @@
|
||||
canReplaceCurrentItem = itemBySlot.isEmpty();
|
||||
}
|
||||
|
||||
- if (canReplaceCurrentItem && this.canHoldItem(stack)) {
|
||||
+ // CraftBukkit start
|
||||
+ boolean canPickup = canReplaceCurrentItem && this.canHoldItem(stack);
|
||||
+ if (entity != null) {
|
||||
+ canPickup = !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entity, 0, !canPickup).isCancelled();
|
||||
+ }
|
||||
+ if (canPickup) {
|
||||
+ // CraftBukkit end
|
||||
double d = this.getEquipmentDropChance(equipmentSlotForItem);
|
||||
if (!itemBySlot.isEmpty() && Math.max(this.random.nextFloat() - 0.1F, 0.0F) < d) {
|
||||
+ this.forceDrops = true; // CraftBukkit
|
||||
this.spawnAtLocation(level, itemBySlot);
|
||||
+ this.forceDrops = false; // CraftBukkit
|
||||
if (!this.isEquippableInSlot(stack, equipmentSlotForItem)) {
|
||||
return ItemStack.EMPTY;
|
||||
@@ -471,10 +_,18 @@
|
||||
canReplaceCurrentItem = itemBySlot.isEmpty();
|
||||
}
|
||||
|
||||
ItemStack itemStack = equipmentSlotForItem.limit(stack);
|
||||
@@ -703,22 +_,29 @@
|
||||
- if (canReplaceCurrentItem && this.canHoldItem(stack)) {
|
||||
+ // CraftBukkit start
|
||||
+ boolean canPickup = canReplaceCurrentItem && this.canHoldItem(stack);
|
||||
+ if (entity != null) {
|
||||
+ canPickup = !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entity, 0, !canPickup).isCancelled();
|
||||
+ }
|
||||
+ if (canPickup) {
|
||||
+ // CraftBukkit end
|
||||
double d = this.dropChances.byEquipment(equipmentSlotForItem);
|
||||
if (!itemBySlot.isEmpty() && Math.max(this.random.nextFloat() - 0.1F, 0.0F) < d) {
|
||||
+ this.forceDrops = true; // CraftBukkit
|
||||
this.spawnAtLocation(level, itemBySlot);
|
||||
+ this.forceDrops = false; // CraftBukkit
|
||||
}
|
||||
|
||||
ItemStack itemStack = equipmentSlotForItem.limit(stack);
|
||||
@@ -591,22 +_,29 @@
|
||||
@Override
|
||||
public void checkDespawn() {
|
||||
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
|
||||
@@ -229,9 +214,9 @@
|
||||
+ final io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DespawnRangePair despawnRangePair = this.level().paperConfig().entities.spawning.despawnRanges.get(this.getType().getCategory());
|
||||
+ final io.papermc.paper.configuration.type.DespawnRange.Shape shape = this.level().paperConfig().entities.spawning.despawnRangeShape;
|
||||
+ final double dy = Math.abs(nearestPlayer.getY() - this.getY());
|
||||
+ final double dySqr = Math.pow(dy, 2);
|
||||
+ final double dxSqr = Math.pow(nearestPlayer.getX() - this.getX(), 2);
|
||||
+ final double dzSqr = Math.pow(nearestPlayer.getZ() - this.getZ(), 2);
|
||||
+ final double dySqr = Mth.square(dy);
|
||||
+ final double dxSqr = Mth.square(nearestPlayer.getX() - this.getX());
|
||||
+ final double dzSqr = Mth.square(nearestPlayer.getZ() - this.getZ());
|
||||
+ final double distanceSquared = dxSqr + dzSqr + dySqr;
|
||||
+ // Despawn if hard/soft limit is exceeded
|
||||
+ if (despawnRangePair.hard().shouldDespawn(shape, dxSqr, dySqr, dzSqr, dy) && this.removeWhenFarAway(distanceSquared)) {
|
||||
@@ -252,7 +237,7 @@
|
||||
this.noActionTime = 0;
|
||||
}
|
||||
}
|
||||
@@ -730,6 +_,15 @@
|
||||
@@ -618,6 +_,15 @@
|
||||
@Override
|
||||
protected final void serverAiStep() {
|
||||
this.noActionTime++;
|
||||
@@ -268,41 +253,16 @@
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("sensing");
|
||||
this.sensing.tick();
|
||||
@@ -908,26 +_,40 @@
|
||||
|
||||
@Override
|
||||
public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
|
||||
+ // Paper start - Fix silent equipment change
|
||||
+ setItemSlot(slot, stack, false);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) {
|
||||
+ // Paper end - Fix silent equipment change
|
||||
this.verifyEquippedItem(stack);
|
||||
switch (slot.getType()) {
|
||||
case HAND:
|
||||
- this.onEquipItem(slot, this.handItems.set(slot.getIndex(), stack), stack);
|
||||
+ this.onEquipItem(slot, this.handItems.set(slot.getIndex(), stack), stack, silent); // Paper - Fix silent equipment change
|
||||
break;
|
||||
case HUMANOID_ARMOR:
|
||||
- this.onEquipItem(slot, this.armorItems.set(slot.getIndex(), stack), stack);
|
||||
+ this.onEquipItem(slot, this.armorItems.set(slot.getIndex(), stack), stack, silent); // Paper - Fix silent equipment change
|
||||
break;
|
||||
case ANIMAL_ARMOR:
|
||||
ItemStack itemStack = this.bodyArmorItem;
|
||||
this.bodyArmorItem = stack;
|
||||
- this.onEquipItem(slot, itemStack, stack);
|
||||
+ this.onEquipItem(slot, itemStack, stack, silent); // Paper - Fix silent equipment change
|
||||
}
|
||||
@@ -796,11 +_,18 @@
|
||||
};
|
||||
}
|
||||
+
|
||||
|
||||
+ // Paper start
|
||||
+ protected boolean shouldSkipLoot(EquipmentSlot slot) { // method to avoid to fallback into the global mob loot logic (i.e fox)
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
+
|
||||
@Override
|
||||
protected void dropCustomDeathLoot(ServerLevel level, DamageSource damageSource, boolean recentlyHit) {
|
||||
super.dropCustomDeathLoot(level, damageSource, recentlyHit);
|
||||
@@ -310,9 +270,9 @@
|
||||
for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||
+ if (this.shouldSkipLoot(equipmentSlot)) continue; // Paper
|
||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
||||
float equipmentDropChance = this.getEquipmentDropChance(equipmentSlot);
|
||||
if (equipmentDropChance != 0.0F) {
|
||||
@@ -951,7 +_,13 @@
|
||||
float f = this.dropChances.byEquipment(equipmentSlot);
|
||||
if (f != 0.0F) {
|
||||
@@ -820,7 +_,13 @@
|
||||
}
|
||||
|
||||
this.spawnAtLocation(level, itemBySlot);
|
||||
@@ -326,17 +286,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -981,7 +_,9 @@
|
||||
double d = this.getEquipmentDropChance(equipmentSlot);
|
||||
if (d > 1.0) {
|
||||
this.setItemSlot(equipmentSlot, ItemStack.EMPTY);
|
||||
+ this.forceDrops = true; // Paper - Add missing forceDrop toggles
|
||||
this.spawnAtLocation(level, itemBySlot);
|
||||
+ this.forceDrops = false; // Paper - Add missing forceDrop toggles
|
||||
}
|
||||
@@ -844,7 +_,9 @@
|
||||
set.add(equipmentSlot);
|
||||
} else if (this.dropChances.isPreserved(equipmentSlot)) {
|
||||
this.setItemSlot(equipmentSlot, ItemStack.EMPTY);
|
||||
+ this.forceDrops = true; // Paper - Add missing forceDrop toggles
|
||||
this.spawnAtLocation(level, itemBySlot);
|
||||
+ this.forceDrops = false; // Paper - Add missing forceDrop toggles
|
||||
}
|
||||
}
|
||||
@@ -1269,6 +_,22 @@
|
||||
}
|
||||
@@ -1122,6 +_,22 @@
|
||||
public <T extends Mob> T convertTo(
|
||||
EntityType<T> entityType, ConversionParams conversionParams, EntitySpawnReason spawnReason, ConversionParams.AfterConversion<T> afterConversion
|
||||
) {
|
||||
@@ -359,7 +319,7 @@
|
||||
if (this.isRemoved()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -1277,13 +_,23 @@
|
||||
@@ -1130,13 +_,23 @@
|
||||
return null;
|
||||
} else {
|
||||
conversionParams.type().convert(this, mob, conversionParams);
|
||||
@@ -386,7 +346,7 @@
|
||||
}
|
||||
|
||||
return mob;
|
||||
@@ -1293,7 +_,20 @@
|
||||
@@ -1146,7 +_,20 @@
|
||||
|
||||
@Nullable
|
||||
public <T extends Mob> T convertTo(EntityType<T> entityType, ConversionParams coversionParams, ConversionParams.AfterConversion<T> afterConversion) {
|
||||
@@ -408,7 +368,7 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1329,7 +_,17 @@
|
||||
@@ -1182,7 +_,17 @@
|
||||
public boolean startRiding(Entity entity, boolean force) {
|
||||
boolean flag = super.startRiding(entity, force);
|
||||
if (flag && this.isLeashed()) {
|
||||
@@ -427,7 +387,7 @@
|
||||
}
|
||||
|
||||
return flag;
|
||||
@@ -1412,7 +_,7 @@
|
||||
@@ -1270,7 +_,7 @@
|
||||
float knockback = this.getKnockback(source, damageSource);
|
||||
if (knockback > 0.0F && source instanceof LivingEntity livingEntity) {
|
||||
livingEntity.knockback(
|
||||
|
||||
@@ -1,30 +1,21 @@
|
||||
--- a/net/minecraft/world/entity/NeutralMob.java
|
||||
+++ b/net/minecraft/world/entity/NeutralMob.java
|
||||
@@ -39,18 +_,11 @@
|
||||
} else {
|
||||
UUID uuid = tag.getUUID("AngryAt");
|
||||
this.setPersistentAngerTarget(uuid);
|
||||
- Entity entity = ((ServerLevel)level).getEntity(uuid);
|
||||
- if (entity != null) {
|
||||
- if (entity instanceof Mob mob) {
|
||||
- this.setTarget(mob);
|
||||
- this.setLastHurtByMob(mob);
|
||||
- }
|
||||
-
|
||||
- if (entity instanceof Player player) {
|
||||
- this.setTarget(player);
|
||||
- this.setLastHurtByPlayer(player);
|
||||
- }
|
||||
- }
|
||||
+ // Paper - Prevent entity loading causing async lookups; Moved diff to separate method
|
||||
+ // If this entity already survived its first tick, e.g. is loaded and ticked in sync, actively
|
||||
+ // tick the initial persistent anger.
|
||||
+ // If not, let the first tick on the baseTick call the method later down the line.
|
||||
+ if (this instanceof Entity entity && !entity.firstTick) this.tickInitialPersistentAnger(level);
|
||||
}
|
||||
@@ -35,9 +_,11 @@
|
||||
if (level instanceof ServerLevel serverLevel) {
|
||||
UUID uuid = tag.read("AngryAt", UUIDUtil.CODEC).orElse(null);
|
||||
this.setPersistentAngerTarget(uuid);
|
||||
- if ((uuid != null ? serverLevel.getEntity(uuid) : null) instanceof LivingEntity livingEntity) {
|
||||
- this.setTarget(livingEntity);
|
||||
- }
|
||||
+ // Paper - Prevent entity loading causing async lookups; Moved diff to separate method
|
||||
+ // If this entity already survived its first tick, e.g. is loaded and ticked in sync, actively
|
||||
+ // tick the initial persistent anger.
|
||||
+ // If not, let the first tick on the baseTick call the method later down the line.
|
||||
+ if (this instanceof Entity entity && !entity.firstTick) this.tickInitialPersistentAnger(level);
|
||||
}
|
||||
}
|
||||
@@ -104,7 +_,7 @@
|
||||
|
||||
@@ -90,7 +_,7 @@
|
||||
default void stopBeingAngry() {
|
||||
this.setLastHurtByMob(null);
|
||||
this.setPersistentAngerTarget(null);
|
||||
@@ -33,7 +24,7 @@
|
||||
this.setRemainingPersistentAngerTime(0);
|
||||
}
|
||||
|
||||
@@ -117,8 +_,33 @@
|
||||
@@ -101,8 +_,24 @@
|
||||
|
||||
void setTarget(@Nullable LivingEntity livingEntity);
|
||||
|
||||
@@ -52,17 +43,8 @@
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ Entity entity = ((ServerLevel)level).getEntity(uuid);
|
||||
+ if (entity != null) {
|
||||
+ if (entity instanceof Mob mob) {
|
||||
+ this.setTarget(mob, org.bukkit.event.entity.EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
|
||||
+ this.setLastHurtByMob(mob);
|
||||
+ }
|
||||
+
|
||||
+ if (entity instanceof Player player) {
|
||||
+ this.setTarget(player, org.bukkit.event.entity.EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
|
||||
+ this.setLastHurtByPlayer(player);
|
||||
+ }
|
||||
+ if ((uuid != null ? level.getEntity(uuid) : null) instanceof LivingEntity livingEntity) {
|
||||
+ this.setTarget(livingEntity, org.bukkit.event.entity.EntityTargetEvent.TargetReason.UNKNOWN, false);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Prevent entity loading causing async lookups
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/OminousItemSpawner.java
|
||||
+++ b/net/minecraft/world/entity/OminousItemSpawner.java
|
||||
@@ -76,7 +_,7 @@
|
||||
@@ -79,7 +_,7 @@
|
||||
entity = this.spawnProjectile(serverLevel, projectileItem, item);
|
||||
} else {
|
||||
entity = new ItemEntity(serverLevel, this.getX(), this.getY(), this.getZ(), item);
|
||||
@@ -9,7 +9,7 @@
|
||||
}
|
||||
|
||||
serverLevel.levelEvent(3021, this.blockPosition(), 1);
|
||||
@@ -90,7 +_,7 @@
|
||||
@@ -93,7 +_,7 @@
|
||||
ProjectileItem.DispenseConfig dispenseConfig = projectileItem.createDispenseConfig();
|
||||
dispenseConfig.overrideDispenseEvent().ifPresent(i -> level.levelEvent(i, this.blockPosition(), 0));
|
||||
Direction direction = Direction.DOWN;
|
||||
@@ -18,7 +18,7 @@
|
||||
projectileItem.asProjectile(level, this.position(), stack, direction),
|
||||
level,
|
||||
stack,
|
||||
@@ -99,7 +_,7 @@
|
||||
@@ -102,7 +_,7 @@
|
||||
direction.getStepZ(),
|
||||
dispenseConfig.power(),
|
||||
dispenseConfig.uncertainty()
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
--- a/net/minecraft/world/entity/TamableAnimal.java
|
||||
+++ b/net/minecraft/world/entity/TamableAnimal.java
|
||||
@@ -84,7 +_,7 @@
|
||||
@@ -77,7 +_,7 @@
|
||||
}
|
||||
|
||||
this.orderedToSit = compound.getBoolean("Sitting");
|
||||
this.orderedToSit = compound.getBooleanOr("Sitting", false);
|
||||
- this.setInSittingPose(this.orderedToSit);
|
||||
+ this.setInSittingPose(this.orderedToSit, false); // Paper - Add EntityToggleSitEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,8 +_,16 @@
|
||||
@@ -88,8 +_,16 @@
|
||||
@Override
|
||||
public boolean handleLeashAtDistance(Entity leashHolder, float distance) {
|
||||
if (this.isInSittingPose()) {
|
||||
@@ -28,7 +28,7 @@
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -155,6 +_,12 @@
|
||||
@@ -148,6 +_,12 @@
|
||||
}
|
||||
|
||||
public void setInSittingPose(boolean sitting) {
|
||||
@@ -41,7 +41,7 @@
|
||||
byte b = this.entityData.get(DATA_FLAGS_ID);
|
||||
if (sitting) {
|
||||
this.entityData.set(DATA_FLAGS_ID, (byte)(b | 1));
|
||||
@@ -227,7 +_,12 @@
|
||||
@@ -230,7 +_,12 @@
|
||||
if (this.level() instanceof ServerLevel serverLevel
|
||||
&& serverLevel.getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES)
|
||||
&& this.getOwner() instanceof ServerPlayer serverPlayer) {
|
||||
@@ -55,18 +55,18 @@
|
||||
}
|
||||
|
||||
super.die(cause);
|
||||
@@ -270,7 +_,14 @@
|
||||
@@ -273,7 +_,14 @@
|
||||
if (!this.canTeleportTo(new BlockPos(x, y, z))) {
|
||||
return false;
|
||||
} else {
|
||||
- this.moveTo(x + 0.5, y, z + 0.5, this.getYRot(), this.getXRot());
|
||||
- this.snapTo(x + 0.5, y, z + 0.5, this.getYRot(), this.getXRot());
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.entity.EntityTeleportEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTeleportEvent(this, x + 0.5, y, z + 0.5);
|
||||
+ if (event.isCancelled() || event.getTo() == null) { // Paper - prevent NP on null event to location
|
||||
+ return false;
|
||||
+ }
|
||||
+ org.bukkit.Location to = event.getTo();
|
||||
+ this.moveTo(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
|
||||
+ this.snapTo(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
|
||||
+ // CraftBukkit end
|
||||
this.navigation.stop();
|
||||
return true;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
|
||||
+++ b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
|
||||
@@ -153,20 +_,20 @@
|
||||
@@ -155,20 +_,20 @@
|
||||
double baseValue = this.getBaseValue();
|
||||
|
||||
for (AttributeModifier attributeModifier : this.getModifiersOrEmpty(AttributeModifier.Operation.ADD_VALUE)) {
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
+++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
@@ -162,4 +_,12 @@
|
||||
}
|
||||
@@ -148,4 +_,12 @@
|
||||
.ifPresent(attributeInstance -> attributeInstance.load(compoundOrEmpty));
|
||||
}
|
||||
}
|
||||
+
|
||||
|
||||
+4
-4
@@ -3,15 +3,15 @@
|
||||
@@ -38,7 +_,14 @@
|
||||
.findFirst()
|
||||
)
|
||||
.ifPresent(profession -> {
|
||||
- villager.setVillagerData(villager.getVillagerData().setProfession(profession));
|
||||
.ifPresent(reference -> {
|
||||
- villager.setVillagerData(villager.getVillagerData().withProfession(reference));
|
||||
+ // CraftBukkit start - Fire VillagerCareerChangeEvent where Villager gets employed
|
||||
+ org.bukkit.event.entity.VillagerCareerChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callVillagerCareerChangeEvent(villager, org.bukkit.craftbukkit.entity.CraftVillager.CraftProfession.minecraftToBukkit(profession), org.bukkit.event.entity.VillagerCareerChangeEvent.ChangeReason.EMPLOYED);
|
||||
+ org.bukkit.event.entity.VillagerCareerChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callVillagerCareerChangeEvent(villager, org.bukkit.craftbukkit.entity.CraftVillager.CraftProfession.minecraftHolderToBukkit(reference), org.bukkit.event.entity.VillagerCareerChangeEvent.ChangeReason.EMPLOYED);
|
||||
+ if (event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ villager.setVillagerData(villager.getVillagerData().setProfession(org.bukkit.craftbukkit.entity.CraftVillager.CraftProfession.bukkitToMinecraft(event.getProfession())));
|
||||
+ villager.setVillagerData(villager.getVillagerData().withProfession(org.bukkit.craftbukkit.entity.CraftVillager.CraftProfession.bukkitToMinecraftHolder(event.getProfession())));
|
||||
+ // CraftBukkit end
|
||||
villager.refreshBrain(level);
|
||||
});
|
||||
|
||||
Loaded 100 of 456 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user