mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-01 04:32:11 -07:00
1.21.5
Co-authored-by: Bjarne Koll <git@lynxplay.dev> Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com> Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Co-authored-by: MiniDigger | Martin <admin@minidigger.dev> Co-authored-by: Nassim Jahnke <nassim@njahnke.dev> Co-authored-by: Noah van der Aa <ndvdaa@gmail.com> Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Co-authored-by: Shane Freeder <theboyetronic@gmail.com> Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com> Co-authored-by: Tamion <70228790+notTamion@users.noreply.github.com> Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com>
This commit is contained in:
@@ -31,7 +31,7 @@ this fix, as the data will remain in the oversized file. Once the server returns
|
||||
to a jar with this fix, the data will be restored.
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
index d0854fa02be52f560fc91adeb8495a6bd22f6f74..783a2d80f6197dd0af0dc81909f0353a8ea2ecf4 100644
|
||||
index 43d38cf26224919cd53d7479753d658f4ab40dbc..4eb07097986aac67421dd8e6a17cc5436da91187 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
@@ -53,6 +53,7 @@ public class RegionFile implements AutoCloseable {
|
||||
@@ -119,7 +119,7 @@ index d0854fa02be52f560fc91adeb8495a6bd22f6f74..783a2d80f6197dd0af0dc81909f0353a
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index 5ac84d6b47e7fdc16e1c09b739829de3d316bf5b..51bf310423013d0ae9d3202d66e36a053a767197 100644
|
||||
index 5ac84d6b47e7fdc16e1c09b739829de3d316bf5b..763879cdc389fc4d80135b38aa96a5bec448ae9e 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -47,6 +47,43 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
@@ -139,10 +139,10 @@ index 5ac84d6b47e7fdc16e1c09b739829de3d316bf5b..51bf310423013d0ae9d3202d66e36a05
|
||||
+ if (oversizedData == null) {
|
||||
+ return chunk;
|
||||
+ }
|
||||
+ CompoundTag oversizedLevel = oversizedData.getCompound("Level");
|
||||
+ CompoundTag oversizedLevel = oversizedData.getCompoundOrEmpty("Level");
|
||||
+
|
||||
+ mergeChunkList(chunk.getCompound("Level"), oversizedLevel, "Entities", "Entities");
|
||||
+ mergeChunkList(chunk.getCompound("Level"), oversizedLevel, "TileEntities", "TileEntities");
|
||||
+ mergeChunkList(chunk.getCompoundOrEmpty("Level"), oversizedLevel, "Entities", "Entities");
|
||||
+ mergeChunkList(chunk.getCompoundOrEmpty("Level"), oversizedLevel, "TileEntities", "TileEntities");
|
||||
+
|
||||
+ return chunk;
|
||||
+ } catch (Throwable throwable) {
|
||||
@@ -153,8 +153,8 @@ index 5ac84d6b47e7fdc16e1c09b739829de3d316bf5b..51bf310423013d0ae9d3202d66e36a05
|
||||
+ }
|
||||
+
|
||||
+ private static void mergeChunkList(CompoundTag level, CompoundTag oversizedLevel, String key, String oversizedKey) {
|
||||
+ net.minecraft.nbt.ListTag levelList = level.getList(key, net.minecraft.nbt.Tag.TAG_COMPOUND);
|
||||
+ net.minecraft.nbt.ListTag oversizedList = oversizedLevel.getList(oversizedKey, net.minecraft.nbt.Tag.TAG_COMPOUND);
|
||||
+ net.minecraft.nbt.ListTag levelList = level.getListOrEmpty(key);
|
||||
+ net.minecraft.nbt.ListTag oversizedList = oversizedLevel.getListOrEmpty(oversizedKey);
|
||||
+
|
||||
+ if (!oversizedList.isEmpty()) {
|
||||
+ levelList.addAll(oversizedList);
|
||||
|
@@ -15,7 +15,7 @@ Adds villagers as separate config
|
||||
|
||||
diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ade6110cc6adb1263c0359ff7e96e96b959e61f3
|
||||
index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae69f36157e
|
||||
--- /dev/null
|
||||
+++ b/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
@@ -0,0 +1,318 @@
|
||||
@@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..ade6110cc6adb1263c0359ff7e96e96b
|
||||
+import net.minecraft.world.entity.ai.Brain;
|
||||
+import net.minecraft.world.entity.animal.Animal;
|
||||
+import net.minecraft.world.entity.animal.Bee;
|
||||
+import net.minecraft.world.entity.animal.Sheep;
|
||||
+import net.minecraft.world.entity.animal.sheep.Sheep;
|
||||
+import net.minecraft.world.entity.animal.horse.Llama;
|
||||
+import net.minecraft.world.entity.boss.EnderDragonPart;
|
||||
+import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
|
||||
@@ -338,7 +338,7 @@ index 0000000000000000000000000000000000000000..ade6110cc6adb1263c0359ff7e96e96b
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index d95413af04121fe91ca0f3b0c70025b9808acef9..ad665c7535c615d2b03a3e7864be435f933235dd 100644
|
||||
index 88b81a5fbc88e6240f86c1e780d80eb4b601df8c..00a5ed09caa2689543bd47bcd93d5a6141d0af46 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableList;
|
||||
@@ -357,19 +357,11 @@ index d95413af04121fe91ca0f3b0c70025b9808acef9..ad665c7535c615d2b03a3e7864be435f
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Path;
|
||||
@@ -95,7 +93,6 @@ import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||
import net.minecraft.world.level.storage.DimensionDataStorage;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
-import net.minecraft.world.phys.Vec3;
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index f45fb8ddb08d82ce76018b5a5c4fce5b3b319559..12f0dc36c5adcdbd9e1dad5f8512ac184da3960f 100644
|
||||
index 156f7ddc2fdc96b762598bad2a2b21f433518dc0..ef201f4add358fbf1818f3b2ec9e75fe2cce4c8b 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -551,6 +551,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -544,6 +544,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
profilerFiller.pop();
|
||||
}
|
||||
|
||||
@@ -377,7 +369,7 @@ index f45fb8ddb08d82ce76018b5a5c4fce5b3b319559..12f0dc36c5adcdbd9e1dad5f8512ac18
|
||||
this.entityTickList
|
||||
.forEach(
|
||||
entity -> {
|
||||
@@ -980,12 +981,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -982,12 +983,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
entity.totalEntityAge++; // Paper - age-like counter for all entities
|
||||
profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString());
|
||||
profilerFiller.incrementCounter("tickNonPassenger");
|
||||
@@ -394,7 +386,7 @@ index f45fb8ddb08d82ce76018b5a5c4fce5b3b319559..12f0dc36c5adcdbd9e1dad5f8512ac18
|
||||
}
|
||||
// Paper start - log detailed entity tick information
|
||||
} finally {
|
||||
@@ -996,7 +1000,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -998,7 +1002,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Paper end - log detailed entity tick information
|
||||
}
|
||||
|
||||
@@ -403,7 +395,7 @@ index f45fb8ddb08d82ce76018b5a5c4fce5b3b319559..12f0dc36c5adcdbd9e1dad5f8512ac18
|
||||
if (passengerEntity.isRemoved() || passengerEntity.getVehicle() != ridingEntity) {
|
||||
passengerEntity.stopRiding();
|
||||
} else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) {
|
||||
@@ -1006,12 +1010,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -1008,12 +1012,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(passengerEntity.getType()).toString());
|
||||
profilerFiller.incrementCounter("tickPassenger");
|
||||
@@ -427,10 +419,10 @@ index f45fb8ddb08d82ce76018b5a5c4fce5b3b319559..12f0dc36c5adcdbd9e1dad5f8512ac18
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/AgeableMob.java b/net/minecraft/world/entity/AgeableMob.java
|
||||
index a9f01e616ef6b0d74caf57cd68eb371a4fd30fd5..179f4e4b9b1eb57f78bbb2f9fa34b11ea79b7a88 100644
|
||||
index f9cfa9dd17bd259cfbc0d96bf48a17556b365d8b..201c6d6e2f5799a7678b16f01c85508bc72e8af5 100644
|
||||
--- a/net/minecraft/world/entity/AgeableMob.java
|
||||
+++ b/net/minecraft/world/entity/AgeableMob.java
|
||||
@@ -126,6 +126,23 @@ public abstract class AgeableMob extends PathfinderMob {
|
||||
@@ -129,6 +129,23 @@ public abstract class AgeableMob extends PathfinderMob {
|
||||
super.onSyncedDataUpdated(key);
|
||||
}
|
||||
|
||||
@@ -455,10 +447,10 @@ index a9f01e616ef6b0d74caf57cd68eb371a4fd30fd5..179f4e4b9b1eb57f78bbb2f9fa34b11e
|
||||
public void aiStep() {
|
||||
super.aiStep();
|
||||
diff --git a/net/minecraft/world/entity/AreaEffectCloud.java b/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
index 24735284fda151414d99faad401d25ba60995f9a..23b342cc31c7e72ade0e1ccad86a9ccf34380f13 100644
|
||||
index bf44f6b9c8710e0c9a85d44f6217501abc98a7b1..bfd904e468bbf2cc1a5b3353d3a69ad5087c81ae 100644
|
||||
--- a/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
+++ b/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
@@ -128,6 +128,16 @@ public class AreaEffectCloud extends Entity implements TraceableEntity {
|
||||
@@ -144,6 +144,16 @@ public class AreaEffectCloud extends Entity implements TraceableEntity {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
@@ -476,10 +468,10 @@ index 24735284fda151414d99faad401d25ba60995f9a..23b342cc31c7e72ade0e1ccad86a9ccf
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 2facc7ad69bfe28c2f928a026ba5ab37387ab039..6256d7f8f4ee8bd4e3673b4e069af5cc0069c8f2 100644
|
||||
index fd0cc1bf9e4425a0924ed77854907deec1a7348e..1c9e5f61d182cf60caa885135abddc879d602c48 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -381,6 +381,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -388,6 +388,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
private final int despawnTime; // Paper - entity despawn time limit
|
||||
public int totalEntityAge; // Paper - age-like counter for all entities
|
||||
public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges
|
||||
@@ -492,10 +484,10 @@ index 2facc7ad69bfe28c2f928a026ba5ab37387ab039..6256d7f8f4ee8bd4e3673b4e069af5cc
|
||||
+ public void inactiveTick() {
|
||||
+ }
|
||||
+ // Paper end - EAR 2
|
||||
// CraftBukkit end
|
||||
|
||||
public void setOrigin(@javax.annotation.Nonnull org.bukkit.Location location) {
|
||||
this.origin = location.toVector();
|
||||
@@ -414,6 +423,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
// Paper start
|
||||
@@ -403,6 +412,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.position = Vec3.ZERO;
|
||||
this.blockPosition = BlockPos.ZERO;
|
||||
this.chunkPosition = ChunkPos.ZERO;
|
||||
@@ -509,16 +501,18 @@ index 2facc7ad69bfe28c2f928a026ba5ab37387ab039..6256d7f8f4ee8bd4e3673b4e069af5cc
|
||||
SynchedEntityData.Builder builder = new SynchedEntityData.Builder(this);
|
||||
builder.define(DATA_SHARED_FLAGS_ID, (byte)0);
|
||||
builder.define(DATA_AIR_SUPPLY_ID, this.getMaxAirSupply());
|
||||
@@ -978,6 +994,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -958,6 +974,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
|
||||
} else {
|
||||
this.wasOnFire = this.isOnFire();
|
||||
if (type == MoverType.PISTON) {
|
||||
+ this.activatedTick = Math.max(this.activatedTick, MinecraftServer.currentTick + 20); // Paper - EAR 2
|
||||
+ this.activatedImmunityTick = Math.max(this.activatedImmunityTick, MinecraftServer.currentTick + 20); // Paper - EAR 2
|
||||
+ // Paper start - EAR 2
|
||||
+ this.activatedTick = Math.max(this.activatedTick, MinecraftServer.currentTick + 20);
|
||||
+ this.activatedImmunityTick = Math.max(this.activatedImmunityTick, MinecraftServer.currentTick + 20);
|
||||
+ // Paper end - EAR 2
|
||||
movement = this.limitPistonMovement(movement);
|
||||
if (movement.equals(Vec3.ZERO)) {
|
||||
return;
|
||||
@@ -991,6 +1009,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -971,6 +991,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.stuckSpeedMultiplier = Vec3.ZERO;
|
||||
this.setDeltaMovement(Vec3.ZERO);
|
||||
}
|
||||
@@ -533,10 +527,10 @@ index 2facc7ad69bfe28c2f928a026ba5ab37387ab039..6256d7f8f4ee8bd4e3673b4e069af5cc
|
||||
movement = this.maybeBackOffFromEdge(movement, type);
|
||||
Vec3 vec3 = this.collide(movement);
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index e0c310d970a687945b6a771b4ecb94044128c33c..4546aca8e2e144ec207653c713fc49f849908827 100644
|
||||
index 4123354a660f85905c8c2db1c5377201c2b8267e..7ba7a00b8dee651ca7a3cab5b64b4ae11aa66da9 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3103,6 +3103,14 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
@@ -3163,6 +3163,14 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -552,10 +546,10 @@ index e0c310d970a687945b6a771b4ecb94044128c33c..4546aca8e2e144ec207653c713fc49f8
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
|
||||
index e12b47ca5eeb842bae606c0c7a8e3e4cf7d468a9..e330bf990e4874baed1b21cd8c9b44d66ec5b823 100644
|
||||
index 8f5c377540f83911c8d245fb00569f08dbc6a690..73ba442b9d39bc021cd5eb6c1c0f98aed94a5a02 100644
|
||||
--- a/net/minecraft/world/entity/Mob.java
|
||||
+++ b/net/minecraft/world/entity/Mob.java
|
||||
@@ -215,6 +215,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
@@ -203,6 +203,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
return this.lookControl;
|
||||
}
|
||||
|
||||
@@ -651,10 +645,10 @@ index 789fea258d70e60d38271ebb31270562dc7eb3ab..d0ab3db7bbd2942db19f473474371b20
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index 8b034b6bda937b25dbb3d09b8293fed6d7dc512c..52a7ed0d991758bad0dcedcb7f97fb15ac6c6d04 100644
|
||||
index ea3afc27600cde05a17197b071f14972d2c832e6..6c0ebfb2be4e8b884456a2aa3d5fdc87e45a0e3c 100644
|
||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -124,6 +124,29 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
@@ -131,6 +131,29 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
return 0.04;
|
||||
}
|
||||
|
||||
@@ -685,10 +679,10 @@ index 8b034b6bda937b25dbb3d09b8293fed6d7dc512c..52a7ed0d991758bad0dcedcb7f97fb15
|
||||
public void tick() {
|
||||
if (this.getItem().isEmpty()) {
|
||||
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
|
||||
index 27568a1604d2dd5d46e836bbc25431929e218aa1..2b83262e4a13eae86df82913ce4f3121e3631a43 100644
|
||||
index 94032c60944f161519f0ddee69426cbfe3075170..e0e0d2ea7fc60e3142c675404d152eca60263240 100644
|
||||
--- a/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -265,11 +265,35 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
@@ -268,11 +268,35 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
return this.assignProfessionWhenSpawned;
|
||||
}
|
||||
|
||||
@@ -706,7 +700,7 @@ index 27568a1604d2dd5d46e836bbc25431929e218aa1..2b83262e4a13eae86df82913ce4f3121
|
||||
+ this.customServerAiStep(this.level().getMinecraftWorld(), true);
|
||||
+ }
|
||||
+ }
|
||||
+ maybeDecayGossip();
|
||||
+ this.maybeDecayGossip();
|
||||
+ super.inactiveTick();
|
||||
+ }
|
||||
+ // Paper end - EAR 2
|
||||
@@ -725,7 +719,7 @@ index 27568a1604d2dd5d46e836bbc25431929e218aa1..2b83262e4a13eae86df82913ce4f3121
|
||||
profilerFiller.pop();
|
||||
if (this.assignProfessionWhenSpawned) {
|
||||
this.assignProfessionWhenSpawned = false;
|
||||
@@ -293,7 +317,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
@@ -296,7 +320,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
this.lastTradedPlayer = null;
|
||||
}
|
||||
|
||||
@@ -734,19 +728,19 @@ index 27568a1604d2dd5d46e836bbc25431929e218aa1..2b83262e4a13eae86df82913ce4f3121
|
||||
Raid raidAt = level.getRaidAt(this.blockPosition());
|
||||
if (raidAt != null && raidAt.isActive() && !raidAt.isOver()) {
|
||||
level.broadcastEntityEvent(this, (byte)42);
|
||||
@@ -303,6 +327,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.isTrading()) {
|
||||
@@ -307,6 +331,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
this.stopTrading();
|
||||
}
|
||||
+ if (inactive) return; // Paper - EAR 2
|
||||
|
||||
+ if (inactive) return; // Paper - EAR 2
|
||||
super.customServerAiStep(level);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/entity/projectile/Arrow.java b/net/minecraft/world/entity/projectile/Arrow.java
|
||||
index c1e09e701757a300183b62d343ded03033e63aa7..56574f8ef879159edc0114da09300143a2c79a35 100644
|
||||
index 1f22f44abb21d1ed9a4870f668779efb8fd9b295..91ead824718eeea2afba3bc0ef619b8a24bb24b9 100644
|
||||
--- a/net/minecraft/world/entity/projectile/Arrow.java
|
||||
+++ b/net/minecraft/world/entity/projectile/Arrow.java
|
||||
@@ -66,6 +66,16 @@ public class Arrow extends AbstractArrow {
|
||||
@@ -70,6 +70,16 @@ public class Arrow extends AbstractArrow {
|
||||
builder.define(ID_EFFECT_COLOR, -1);
|
||||
}
|
||||
|
||||
@@ -764,10 +758,10 @@ index c1e09e701757a300183b62d343ded03033e63aa7..56574f8ef879159edc0114da09300143
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
index a3e4605a81eeaca77cc3a3ab937b75a415d83037..c7ae41b2cbc1eb85a6eb9c16813bd326fb8f49f0 100644
|
||||
index dcb7714b2edeab8cfb0358929d07bd04cead26bf..e0e193078e550225e163149638bf9e053c0531f8 100644
|
||||
--- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
+++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
@@ -102,6 +102,21 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier {
|
||||
@@ -109,6 +109,21 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier {
|
||||
return super.shouldRender(x, y, z) && !this.isAttachedToEntity();
|
||||
}
|
||||
|
||||
@@ -790,10 +784,10 @@ index a3e4605a81eeaca77cc3a3ab937b75a415d83037..c7ae41b2cbc1eb85a6eb9c16813bd326
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/vehicle/MinecartHopper.java b/net/minecraft/world/entity/vehicle/MinecartHopper.java
|
||||
index c553cf0592dfa606dbbb1e6854d3377b9feb5efb..8341e7f01606fca90e69384c16fc19bb9e20d1b7 100644
|
||||
index 6162415095b030b4cc47364c56fa66236b3b0535..a56d9cdeb6589a053ffaaf2cd599a98ae0a0989a 100644
|
||||
--- a/net/minecraft/world/entity/vehicle/MinecartHopper.java
|
||||
+++ b/net/minecraft/world/entity/vehicle/MinecartHopper.java
|
||||
@@ -47,6 +47,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
@@ -48,6 +48,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
if (flag != this.isEnabled()) {
|
||||
this.setEnabled(flag);
|
||||
}
|
||||
@@ -801,7 +795,7 @@ index c553cf0592dfa606dbbb1e6854d3377b9feb5efb..8341e7f01606fca90e69384c16fc19bb
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
@@ -100,11 +101,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
@@ -101,11 +102,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
|
||||
public boolean suckInItems() {
|
||||
if (HopperBlockEntity.suckInItems(this.level(), this)) {
|
||||
@@ -815,7 +809,7 @@ index c553cf0592dfa606dbbb1e6854d3377b9feb5efb..8341e7f01606fca90e69384c16fc19bb
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -139,4 +142,11 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
@@ -140,4 +143,11 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
public AbstractContainerMenu createMenu(int id, Inventory playerInventory) {
|
||||
return new HopperMenu(id, playerInventory, this);
|
||||
}
|
||||
@@ -828,27 +822,27 @@ index c553cf0592dfa606dbbb1e6854d3377b9feb5efb..8341e7f01606fca90e69384c16fc19bb
|
||||
+
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 32f184288f6065259c921293922c1b0163df4dc4..0f346faa82b988e86834c38837f6f11bea7f31c6 100644
|
||||
index 1aa98e4f70627632d3e676395c28fa0ecca72f56..1f26826b2161cfeb27e5b2060e178b493e9142d9 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -153,6 +153,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
|
||||
@@ -143,6 +143,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
@Nullable
|
||||
public List<net.minecraft.world.entity.item.ItemEntity> captureDrops;
|
||||
public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<SpawnCategory> ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>();
|
||||
+ // Paper start
|
||||
+ // Paper start - EAR 2
|
||||
+ public int wakeupInactiveRemainingAnimals;
|
||||
+ public int wakeupInactiveRemainingFlying;
|
||||
+ public int wakeupInactiveRemainingMonsters;
|
||||
+ public int wakeupInactiveRemainingVillagers;
|
||||
+ // Paper end
|
||||
+ // Paper end - EAR 2
|
||||
public boolean populating;
|
||||
public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
|
||||
// Paper start - add paper world config
|
||||
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
index ce880bd45fbda4829d17de8507034b3a39c68cbb..ee2f8e8deb35059824b5730a1442f383dc79f01c 100644
|
||||
index f8d10be7a0aa7f66f05126e75187025c040e3494..1669b76800756000a2f620610b3c8c8b6c48dd4a 100644
|
||||
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
@@ -149,6 +149,10 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
||||
@@ -153,6 +153,10 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
||||
}
|
||||
|
||||
entity.setDeltaMovement(d1, d2, d3);
|
||||
|
@@ -5,7 +5,7 @@ Subject: [PATCH] Anti-Xray
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java
|
||||
index 81ff677e970ffbe7ad5381e56852e33cf7a8ea45..184e6c6fe2ba522d0ea0774604839320c4152371 100644
|
||||
index b9a838d638571bca1d00a620cedf169a3fa87e9d..329e9562e9c2b25228b04c21ff7353d2d8d6e5f6 100644
|
||||
--- a/io/papermc/paper/FeatureHooks.java
|
||||
+++ b/io/papermc/paper/FeatureHooks.java
|
||||
@@ -37,20 +37,25 @@ public final class FeatureHooks {
|
||||
@@ -55,10 +55,10 @@ index d4872b7f4e9591b3b1c67406312905851303f521..cb41460e94161675e2ab43f4b1b5286e
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
index 5d1943d37dfad0c12e77179f0866851532d983e9..3aea76690bc3e35758d3bf274777130af17d8a0f 100644
|
||||
index 89761bd368d75b8fb84f850fb3f8162fa280e236..272da41db7ce4619a8e459a2f0a2221e42f58a40 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
@@ -28,7 +28,13 @@ public class ClientboundLevelChunkPacketData {
|
||||
@@ -33,13 +33,23 @@ public class ClientboundLevelChunkPacketData {
|
||||
private final byte[] buffer;
|
||||
private final List<ClientboundLevelChunkPacketData.BlockEntityInfo> blockEntitiesData;
|
||||
|
||||
@@ -69,12 +69,10 @@ index 5d1943d37dfad0c12e77179f0866851532d983e9..3aea76690bc3e35758d3bf274777130a
|
||||
+ }
|
||||
+ public ClientboundLevelChunkPacketData(LevelChunk levelChunk, io.papermc.paper.antixray.ChunkPacketInfo<net.minecraft.world.level.block.state.BlockState> chunkPacketInfo) {
|
||||
+ // Paper end
|
||||
this.heightmaps = new CompoundTag();
|
||||
|
||||
for (Entry<Heightmap.Types, Heightmap> entry : levelChunk.getHeightmaps()) {
|
||||
@@ -38,7 +44,11 @@ public class ClientboundLevelChunkPacketData {
|
||||
}
|
||||
|
||||
this.heightmaps = levelChunk.getHeightmaps()
|
||||
.stream()
|
||||
.filter(entry1 -> entry1.getKey().sendToClient())
|
||||
.collect(Collectors.toMap(Entry::getKey, entry1 -> (long[])entry1.getValue().getRawData().clone()));
|
||||
this.buffer = new byte[calculateChunkSize(levelChunk)];
|
||||
- extractChunkData(new FriendlyByteBuf(this.getWriteBuffer()), levelChunk);
|
||||
+ // Paper start - Anti-Xray - Add chunk packet info
|
||||
@@ -84,8 +82,8 @@ index 5d1943d37dfad0c12e77179f0866851532d983e9..3aea76690bc3e35758d3bf274777130a
|
||||
+ extractChunkData(new FriendlyByteBuf(this.getWriteBuffer()), levelChunk, chunkPacketInfo);
|
||||
this.blockEntitiesData = Lists.newArrayList();
|
||||
|
||||
for (Entry<BlockPos, BlockEntity> entryx : levelChunk.getBlockEntities().entrySet()) {
|
||||
@@ -85,9 +95,17 @@ public class ClientboundLevelChunkPacketData {
|
||||
for (Entry<BlockPos, BlockEntity> entry : levelChunk.getBlockEntities().entrySet()) {
|
||||
@@ -82,9 +92,17 @@ public class ClientboundLevelChunkPacketData {
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
@@ -145,10 +143,10 @@ index 3a384175f8e7f204234bbaf3081bdc20c47a0d4b..5699bc15eba92e22433a20cb8326b59f
|
||||
|
||||
private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buffer) {
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index da8848e2a3e3745949eb2356a049451d30f763a7..192977dd661ee795ada13db895db770293e9b402 100644
|
||||
index ef201f4add358fbf1818f3b2ec9e75fe2cce4c8b..fe9b4484d683fe48f435a053c9c90557fdf80e7b 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -348,7 +348,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -343,7 +343,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
org.bukkit.generator.BiomeProvider biomeProvider // CraftBukkit
|
||||
) {
|
||||
// CraftBukkit start
|
||||
@@ -156,13 +154,13 @@ index da8848e2a3e3745949eb2356a049451d30f763a7..192977dd661ee795ada13db895db7702
|
||||
+ super(serverLevelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(levelStorageAccess.levelDirectory.path(), serverLevelData.getLevelName(), dimension.location(), spigotConfig, server.registryAccess(), serverLevelData.getGameRules())), dispatcher); // Paper - create paper world configs; Async-Anti-Xray: Pass executor
|
||||
this.pvpMode = server.isPvpAllowed();
|
||||
this.levelStorageAccess = levelStorageAccess;
|
||||
this.uuid = org.bukkit.craftbukkit.util.WorldUUID.getUUID(levelStorageAccess.levelDirectory.path().toFile());
|
||||
this.uuid = org.bukkit.craftbukkit.util.WorldUUID.getOrCreate(levelStorageAccess.levelDirectory.path().toFile());
|
||||
diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index 47ed3ad5c0b4753f58e0bafff5e5e70b2f0bb40b..623c069f1fe079e020c6391a3db1a3d95cd3dbf5 100644
|
||||
index b5378d6d73b6dab56bf664024f3f82496e9a9487..b604cba2490a747661d6819251bc3b9a1d35c7d4 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -299,6 +299,7 @@ public class ServerPlayerGameMode {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDamageAbortEvent(this.player, pos, this.player.getInventory().getSelected()); // CraftBukkit
|
||||
@@ -296,6 +296,7 @@ public class ServerPlayerGameMode {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDamageAbortEvent(this.player, pos, this.player.getInventory().getSelectedItem()); // CraftBukkit
|
||||
}
|
||||
}
|
||||
+ this.level.chunkPacketBlockController.onPlayerLeftClickBlock(this, pos, action, face, maxBuildHeight, sequence); // Paper - Anti-Xray
|
||||
@@ -188,10 +186,10 @@ index 342bc843c384761e883de861044f4f8930ae8763..14878690a88fd4de3e2c127086607e6c
|
||||
if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), packetListener.getPlayer().getBukkitEntity()).callEvent();
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 600a08d6b45cb19dbe551cefbf726e68684a0837..ff0315cffdb282fdc0a1ffd15e2954caa76835c9 100644
|
||||
index a2a4dbcfb77d44657b3dfbe97cb629de215c29eb..73717609fccd9af12e2cc39824106f49426b581c 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -403,7 +403,7 @@ public abstract class PlayerList {
|
||||
@@ -407,7 +407,7 @@ public abstract class PlayerList {
|
||||
.getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
|
||||
player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
|
||||
new net.minecraft.world.level.chunk.EmptyLevelChunk(serverLevel, player.chunkPosition(), plains),
|
||||
@@ -201,18 +199,18 @@ index 600a08d6b45cb19dbe551cefbf726e68684a0837..ff0315cffdb282fdc0a1ffd15e2954ca
|
||||
}
|
||||
// Paper end - Send empty chunk
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 0f346faa82b988e86834c38837f6f11bea7f31c6..771d6ed6a7c889c09efd4ff6e20298c851eaa79f 100644
|
||||
index 1f26826b2161cfeb27e5b2060e178b493e9142d9..63f8b0c47e3321b74f4b6bcbc1e28cd751911198 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -168,6 +168,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
}
|
||||
// Paper end - add paper world config
|
||||
@@ -132,6 +132,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
private long subTickCount;
|
||||
|
||||
// CraftBukkit start
|
||||
+ public final io.papermc.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
|
||||
public static BlockPos lastPhysicsProblem; // Spigot
|
||||
private org.spigotmc.TickLimiter entityLimiter;
|
||||
private org.spigotmc.TickLimiter tileLimiter;
|
||||
@@ -214,7 +215,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
private final CraftWorld world;
|
||||
public boolean pvpMode;
|
||||
public org.bukkit.generator.ChunkGenerator generator;
|
||||
@@ -201,7 +202,8 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
org.bukkit.generator.BiomeProvider biomeProvider, // CraftBukkit
|
||||
org.bukkit.World.Environment env, // CraftBukkit
|
||||
java.util.function.Function<org.spigotmc.SpigotWorldConfig, // Spigot - create per world config
|
||||
@@ -222,24 +220,24 @@ index 0f346faa82b988e86834c38837f6f11bea7f31c6..771d6ed6a7c889c09efd4ff6e20298c8
|
||||
) {
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot
|
||||
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
|
||||
@@ -295,6 +297,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -278,6 +280,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {}
|
||||
});
|
||||
// CraftBukkit end
|
||||
this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime);
|
||||
this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime);
|
||||
+ this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new io.papermc.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : io.papermc.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray
|
||||
}
|
||||
|
||||
// Paper start - Cancel hit for vanished players
|
||||
@@ -495,6 +498,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// CraftBukkit end
|
||||
|
||||
BlockState blockState = chunkAt.setBlockState(pos, state, (flags & 64) != 0, (flags & 1024) == 0); // CraftBukkit custom NO_PLACE flag
|
||||
@@ -483,6 +486,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
snapshot.setFlags(flags); // Paper - always set the flag of the most recent call to mitigate issues with multiple update at the same pos with different flags
|
||||
}
|
||||
BlockState blockState = chunkAt.setBlockState(pos, state, flags);
|
||||
+ this.chunkPacketBlockController.onBlockChange(this, pos, state, blockState, flags, recursionLeft); // Paper - Anti-Xray
|
||||
|
||||
// CraftBukkit end
|
||||
if (blockState == null) {
|
||||
// CraftBukkit start - remove blockstate if failed (or the same)
|
||||
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
index c82780db7fe5b1557a7802d3111f38099be55ac1..d63d745a0220963a297cfedf1e8983aeb471a045 100644
|
||||
index c378f9e226df80ab0d4ebd06ae54ce556d0d94e7..97231db28146df56c727c9765f36277634d59a64 100644
|
||||
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
@@ -114,14 +114,14 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||
@@ -261,10 +259,10 @@ index c82780db7fe5b1557a7802d3111f38099be55ac1..d63d745a0220963a297cfedf1e8983ae
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index ce781ba2c8b3f9f051201d3809a9cb041036f93a..cad71ac79fc52225a192aa5c5d07b13c831fc2c1 100644
|
||||
index 8fa871512ad52c345f15b1f5fb1baf54bb2ec93b..08e2442f6965cc6eaab67bdf9340a5152c08db2a 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -109,7 +109,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
@@ -110,7 +110,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
@Nullable LevelChunk.PostLoadProcessor postLoad,
|
||||
@Nullable BlendingData blendingData
|
||||
) {
|
||||
@@ -274,7 +272,7 @@ index ce781ba2c8b3f9f051201d3809a9cb041036f93a..cad71ac79fc52225a192aa5c5d07b13c
|
||||
this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
index b3d600b0d6deaf44f232dfc86e1456c867e1c07f..a7fabde0f32f09d7f7bed65576ce469f069a21fa 100644
|
||||
index 2399a0f8839c0925a9923bae87362c2c9a217197..1aa4e39431a93a7789b74a2e3476a3e47605e2cc 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
@@ -38,9 +38,15 @@ public class LevelChunkSection {
|
||||
@@ -310,12 +308,12 @@ index b3d600b0d6deaf44f232dfc86e1456c867e1c07f..a7fabde0f32f09d7f7bed65576ce469f
|
||||
- this.biomes.write(buffer);
|
||||
+ this.states.write(buffer, chunkPacketInfo, chunkSectionIndex);
|
||||
+ this.biomes.write(buffer, null, chunkSectionIndex);
|
||||
+ // Paper end - Anti-Xray
|
||||
+ // Paper end - Anti-Xray - Add chunk packet info
|
||||
}
|
||||
|
||||
public int getSerializedSize() {
|
||||
diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
index e8ec28ce3fe13561b45c4654e174776d9d2d7b71..a6028a54c75de068515e95913b21160ab4326985 100644
|
||||
index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a336a3ae55 100644
|
||||
--- a/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
+++ b/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
@@ -28,6 +28,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -454,7 +452,7 @@ index e8ec28ce3fe13561b45c4654e174776d9d2d7b71..a6028a54c75de068515e95913b21160a
|
||||
this.acquire();
|
||||
@@ -172,24 +239,35 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
data.palette.read(buffer);
|
||||
buffer.readLongArray(data.storage.getRaw());
|
||||
buffer.readFixedSizeLongArray(data.storage.getRaw());
|
||||
this.data = data;
|
||||
+ this.addPresetValues(); // Paper - Anti-Xray - Add preset values (inefficient, but this isn't used by the server)
|
||||
} finally {
|
||||
@@ -527,10 +525,10 @@ index e8ec28ce3fe13561b45c4654e174776d9d2d7b71..a6028a54c75de068515e95913b21160a
|
||||
+ if (chunkPacketInfo != null) {
|
||||
+ chunkPacketInfo.setBits(chunkSectionIndex, this.configuration.bits());
|
||||
+ chunkPacketInfo.setPalette(chunkSectionIndex, this.palette);
|
||||
+ chunkPacketInfo.setIndex(chunkSectionIndex, buffer.writerIndex() + VarInt.getByteSize(this.storage.getRaw().length));
|
||||
+ chunkPacketInfo.setIndex(chunkSectionIndex, buffer.writerIndex());
|
||||
+ }
|
||||
+ // Paper end
|
||||
buffer.writeLongArray(this.storage.getRaw());
|
||||
+ // Paper end - Anti-Xray - Add chunk packet info
|
||||
buffer.writeFixedSizeLongArray(this.storage.getRaw());
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/PalettedContainerRO.java b/net/minecraft/world/level/chunk/PalettedContainerRO.java
|
||||
@@ -550,7 +548,7 @@ index bfbb1a2bb4abbb369a24f2f01439e9ea3e16794b..8d6ed8be4d93f7d4e6ea80c351020d88
|
||||
int getSerializedSize();
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
index c7c87bc8df86ceeef3e15a8f23fc252d4cee1984..3b55e7fb27d680204b8621666ae9200870def3eb 100644
|
||||
index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f96d5f6ec 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
@@ -94,7 +94,7 @@ public record SerializableChunkData(
|
||||
@@ -560,51 +558,46 @@ index c7c87bc8df86ceeef3e15a8f23fc252d4cee1984..3b55e7fb27d680204b8621666ae92008
|
||||
- Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState()
|
||||
+ Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), null // Paper - Anti-Xray
|
||||
);
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final String TAG_UPGRADE_DATA = "UpgradeData";
|
||||
@@ -128,6 +128,7 @@ public record SerializableChunkData(
|
||||
private static final Codec<List<SavedTick<Block>>> BLOCK_TICKS_CODEC = SavedTick.codec(BuiltInRegistries.BLOCK.byNameCodec()).listOf();
|
||||
private static final Codec<List<SavedTick<Fluid>>> FLUID_TICKS_CODEC = SavedTick.codec(BuiltInRegistries.FLUID.byNameCodec()).listOf();
|
||||
@@ -130,6 +130,7 @@ public record SerializableChunkData(
|
||||
|
||||
@Nullable
|
||||
public static SerializableChunkData parse(LevelHeightAccessor levelHeightAccessor, RegistryAccess registries, CompoundTag tag) {
|
||||
+ net.minecraft.server.level.ServerLevel serverLevel = (net.minecraft.server.level.ServerLevel) levelHeightAccessor; // Paper - Anti-Xray This is is seemingly only called from ChunkMap, where, we have a server level. We'll fight this later if needed.
|
||||
if (!tag.contains("Status", 8)) {
|
||||
if (tag.getString("Status").isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -212,18 +213,21 @@ public record SerializableChunkData(
|
||||
Codec<PalettedContainer<Holder<Biome>>> codec = makeBiomeCodecRW(registry); // CraftBukkit - read/write
|
||||
|
||||
for (int i2 = 0; i2 < list7.size(); i2++) {
|
||||
- CompoundTag compound2 = list7.getCompound(i2);
|
||||
+ CompoundTag compound2 = list7.getCompound(i2); final CompoundTag sectionData = compound2; // Paper - Anti-Xray - OBFHELPER
|
||||
int _byte = compound2.getByte("Y");
|
||||
LevelChunkSection levelChunkSection;
|
||||
if (_byte >= levelHeightAccessor.getMinSectionY() && _byte <= levelHeightAccessor.getMaxSectionY()) {
|
||||
+ // Paper start - Anti-Xray - Add preset block states
|
||||
+ BlockState[] presetBlockStates = serverLevel.chunkPacketBlockController.getPresetBlockStates(serverLevel, chunkPos, _byte);
|
||||
PalettedContainer<BlockState> palettedContainer;
|
||||
if (compound2.contains("block_states", 10)) {
|
||||
- palettedContainer = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, compound2.getCompound("block_states"))
|
||||
+ Codec<PalettedContainer<BlockState>> blockStateCodec = presetBlockStates == null ? BLOCK_STATE_CODEC : PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), presetBlockStates); // Paper - Anti-Xray
|
||||
+ palettedContainer = blockStateCodec.parse(NbtOps.INSTANCE, sectionData.getCompound("block_states")) // Paper - Anti-Xray
|
||||
.promotePartial(string -> logErrors(chunkPos, _byte, string))
|
||||
.getOrThrow(SerializableChunkData.ChunkReadException::new);
|
||||
} else {
|
||||
palettedContainer = new PalettedContainer<>(
|
||||
- Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES
|
||||
+ Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, presetBlockStates // Paper - Anti-Xray
|
||||
);
|
||||
}
|
||||
|
||||
@@ -234,7 +238,7 @@ public record SerializableChunkData(
|
||||
.getOrThrow(SerializableChunkData.ChunkReadException::new);
|
||||
} else {
|
||||
palettedContainerRo = new PalettedContainer<>(
|
||||
- registry.asHolderIdMap(), registry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES
|
||||
+ registry.asHolderIdMap(), registry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null // Paper - Anti-Xray - Add preset biomes
|
||||
);
|
||||
}
|
||||
|
||||
@@ -414,7 +418,7 @@ public record SerializableChunkData(
|
||||
@@ -190,15 +191,17 @@ public record SerializableChunkData(
|
||||
int byteOr = compoundTag.getByteOr("Y", (byte)0);
|
||||
LevelChunkSection levelChunkSection;
|
||||
if (byteOr >= levelHeightAccessor.getMinSectionY() && byteOr <= levelHeightAccessor.getMaxSectionY()) {
|
||||
+ final BlockState[] presetBlockStates = serverLevel.chunkPacketBlockController.getPresetBlockStates(serverLevel, chunkPos, byteOr); // Paper - Anti-Xray - Add preset block states
|
||||
+ final Codec<PalettedContainer<BlockState>> blockStateCodec = presetBlockStates == null ? BLOCK_STATE_CODEC : PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), presetBlockStates); // Paper - Anti-Xray
|
||||
PalettedContainer<BlockState> palettedContainer = compoundTag.getCompound("block_states")
|
||||
.map(
|
||||
- compoundTag1 -> BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, compoundTag1)
|
||||
+ compoundTag1 -> blockStateCodec.parse(NbtOps.INSTANCE, compoundTag1) // Paper - Anti-Xray
|
||||
.promotePartial(string -> logErrors(chunkPos, byteOr, string))
|
||||
.getOrThrow(SerializableChunkData.ChunkReadException::new)
|
||||
)
|
||||
.orElseGet(
|
||||
() -> new PalettedContainer<>(
|
||||
- Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES
|
||||
+ Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, presetBlockStates // Paper - Anti-Xray - Add preset biomes
|
||||
)
|
||||
);
|
||||
PalettedContainer<Holder<Biome>> palettedContainerRo = compoundTag.getCompound("biomes") // CraftBukkit - read/write
|
||||
@@ -209,7 +212,7 @@ public record SerializableChunkData(
|
||||
)
|
||||
.orElseGet(
|
||||
() -> new PalettedContainer<>(
|
||||
- registry.asHolderIdMap(), registry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES
|
||||
+ registry.asHolderIdMap(), registry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null // Paper - Anti-Xray - Add preset biomes
|
||||
)
|
||||
);
|
||||
levelChunkSection = new LevelChunkSection(palettedContainer, palettedContainerRo);
|
||||
@@ -382,7 +385,7 @@ public record SerializableChunkData(
|
||||
|
||||
// CraftBukkit start - read/write
|
||||
private static Codec<PalettedContainer<Holder<Biome>>> makeBiomeCodecRW(Registry<Biome> biomeRegistry) {
|
||||
|
@@ -269,7 +269,7 @@ index bc674b08a41d5529fe06c6d3f077051cf4138f73..ea8a894158c44c2e7943dea43ecd8e1f
|
||||
+ // Paper end - Use Velocity cipher
|
||||
}
|
||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||
index ad8f8428b75e37097487cdfbd0db2421ee4cbe37..208efae06c7c44f220d4192219a86ec55c98a2fe 100644
|
||||
index 2040b9555c430420a8a8697cc131d42eafb96fa1..4ed9611994c5c8da01fede690197527c5b3a5731 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -772,11 +772,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -336,10 +336,10 @@ index 7de11ba404f0b60e7f7b7c16954811a343688219..bd07e6a5aa1883786d789ea71711a0c0
|
||||
this.channels
|
||||
.add(
|
||||
diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index bb28453d230921d662ed69c8dd48021f428ef060..6689aeacf50d1498e8d23cce696fb4fecbd1cf39 100644
|
||||
index 5d48487568994860c153351ad4c6c33bc8aa5309..7950f4f88d8a83ed5610b7af4e134557d32da3f0 100644
|
||||
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -276,11 +276,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
@@ -275,11 +275,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
}
|
||||
|
||||
SecretKey secretKey = packet.getSecretKey(_private);
|
||||
|
@@ -14,19 +14,19 @@ movement will load only the chunk the player enters anyways and avoids loading
|
||||
massive amounts of surrounding chunks due to large AABB lookups.
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 054ece1d539d69a4b7eec57e681179343c7e75c3..6f35067c64f378e955261e763f2bda9a0a6d0153 100644
|
||||
index a8eaccde3ec9ed912cbc6df0b29e9f8136a46578..0f6ca6ef161ac2934ba761a1eca3215290c7262b 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -218,6 +218,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -223,6 +223,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
// 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
|
||||
|
||||
+ public boolean collisionLoadChunks = false; // Paper
|
||||
private @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity;
|
||||
|
||||
public org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntity() {
|
||||
diff --git a/net/minecraft/world/level/BlockCollisions.java b/net/minecraft/world/level/BlockCollisions.java
|
||||
index fd2c338db43aad070cc32c24891b40599c544ac9..2861ea4b699d403b1245f8be5a62503d366ded65 100644
|
||||
index ed6e4f9fd0c7ad1219e66bc1cb4038191dd6edd8..45a20dbb935b12d429153463dba5d6fd3385dd7a 100644
|
||||
--- a/net/minecraft/world/level/BlockCollisions.java
|
||||
+++ b/net/minecraft/world/level/BlockCollisions.java
|
||||
@@ -80,16 +80,37 @@ public class BlockCollisions<T> extends AbstractIterator<T> {
|
||||
@@ -76,7 +76,7 @@ index fd2c338db43aad070cc32c24891b40599c544ac9..2861ea4b699d403b1245f8be5a62503d
|
||||
&& (nextType != 2 || blockState.is(Blocks.MOVING_PISTON))) {
|
||||
VoxelShape collisionShape = this.context.getCollisionShape(blockState, this.collisionGetter, this.pos);
|
||||
diff --git a/net/minecraft/world/level/CollisionGetter.java b/net/minecraft/world/level/CollisionGetter.java
|
||||
index cb54c3aadd8f3c719d3f7ef1fda4aa517919b7c3..844f76a38884e823a558fe59c421ffd4711f80b4 100644
|
||||
index 79af1e4dd1f84580e509ac3e9a77bcd5531c8da6..a031d39854eb049a701f3de9e11c73419883d5ca 100644
|
||||
--- a/net/minecraft/world/level/CollisionGetter.java
|
||||
+++ b/net/minecraft/world/level/CollisionGetter.java
|
||||
@@ -50,11 +50,13 @@ public interface CollisionGetter extends BlockGetter {
|
||||
|
@@ -67,10 +67,10 @@ index 60b56a5086b8aad0fad693f686b89138b3a4c80d..5b079ec43c259368d0eed4e838588071
|
||||
this.firstIndices = new int[i];
|
||||
this.secondIndices = new int[i];
|
||||
diff --git a/net/minecraft/world/phys/shapes/Shapes.java b/net/minecraft/world/phys/shapes/Shapes.java
|
||||
index e1b4c4b53844b0755e0640a05e8782fd9a7700a2..e759221fb54aa510d2d8bbba47e1d794367aec6d 100644
|
||||
index fe8361535526d9aabdf80390aa84570c580981aa..e6038bbe8513e434daa9ea10bfa817afef0445db 100644
|
||||
--- a/net/minecraft/world/phys/shapes/Shapes.java
|
||||
+++ b/net/minecraft/world/phys/shapes/Shapes.java
|
||||
@@ -279,9 +279,22 @@ public final class Shapes {
|
||||
@@ -286,9 +286,22 @@ public final class Shapes {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -94,7 +94,7 @@ index e1b4c4b53844b0755e0640a05e8782fd9a7700a2..e759221fb54aa510d2d8bbba47e1d794
|
||||
if (list1 instanceof CubePointRange && list2 instanceof CubePointRange) {
|
||||
long l = lcm(i, i1);
|
||||
if (size * l <= 256L) {
|
||||
@@ -289,14 +302,21 @@ public final class Shapes {
|
||||
@@ -296,14 +309,21 @@ public final class Shapes {
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -9,11 +9,11 @@ creating too large of a packet to sed.
|
||||
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
index 3aea76690bc3e35758d3bf274777130af17d8a0f..9e321ef1c3d5803519b243685f4ee598dc0cf640 100644
|
||||
index 272da41db7ce4619a8e459a2f0a2221e42f58a40..526c117e0d53ad527eb610c79cdc46ec16b18c0c 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
@@ -27,6 +27,14 @@ public class ClientboundLevelChunkPacketData {
|
||||
private final CompoundTag heightmaps;
|
||||
@@ -32,6 +32,14 @@ public class ClientboundLevelChunkPacketData {
|
||||
private final Map<Heightmap.Types, long[]> heightmaps;
|
||||
private final byte[] buffer;
|
||||
private final List<ClientboundLevelChunkPacketData.BlockEntityInfo> blockEntitiesData;
|
||||
+ // Paper start - Handle oversized block entities in chunks
|
||||
@@ -27,23 +27,23 @@ index 3aea76690bc3e35758d3bf274777130af17d8a0f..9e321ef1c3d5803519b243685f4ee598
|
||||
|
||||
// Paper start - Anti-Xray - Add chunk packet info
|
||||
@Deprecated @io.papermc.paper.annotation.DoNotUse
|
||||
@@ -50,8 +58,18 @@ public class ClientboundLevelChunkPacketData {
|
||||
@@ -51,8 +59,18 @@ public class ClientboundLevelChunkPacketData {
|
||||
}
|
||||
extractChunkData(new FriendlyByteBuf(this.getWriteBuffer()), levelChunk, chunkPacketInfo);
|
||||
this.blockEntitiesData = Lists.newArrayList();
|
||||
+ int totalTileEntities = 0; // Paper - Handle oversized block entities in chunks
|
||||
|
||||
for (Entry<BlockPos, BlockEntity> entryx : levelChunk.getBlockEntities().entrySet()) {
|
||||
for (Entry<BlockPos, BlockEntity> entry : levelChunk.getBlockEntities().entrySet()) {
|
||||
+ // Paper start - Handle oversized block entities in chunks
|
||||
+ if (++totalTileEntities > BLOCK_ENTITY_LIMIT) {
|
||||
+ net.minecraft.network.protocol.Packet<ClientGamePacketListener> packet = entryx.getValue().getUpdatePacket();
|
||||
+ net.minecraft.network.protocol.Packet<ClientGamePacketListener> packet = entry.getValue().getUpdatePacket();
|
||||
+ if (packet != null) {
|
||||
+ this.extraPackets.add(packet);
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Handle oversized block entities in chunks
|
||||
this.blockEntitiesData.add(ClientboundLevelChunkPacketData.BlockEntityInfo.create(entryx.getValue()));
|
||||
this.blockEntitiesData.add(ClientboundLevelChunkPacketData.BlockEntityInfo.create(entry.getValue()));
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java b/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java
|
||||
|
@@ -5,7 +5,7 @@ Subject: [PATCH] optimize dirt and snow spreading
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java b/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java
|
||||
index 11937aa74efe08bdbd66a619c7a825f91d971afd..722f2b9a24679e0fc67aae2cd27051f96f962efe 100644
|
||||
index d1c112a50ca2c16e4a5c91be2cc91c302918a1c7..f8cc3f870d88715386bb4de0da81a74fa04fd216 100644
|
||||
--- a/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java
|
||||
+++ b/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java
|
||||
@@ -17,8 +17,13 @@ public abstract class SpreadingSnowyDirtBlock extends SnowyDirtBlock {
|
||||
@@ -58,7 +58,7 @@ index 11937aa74efe08bdbd66a619c7a825f91d971afd..722f2b9a24679e0fc67aae2cd27051f9
|
||||
for (int i = 0; i < 4; i++) {
|
||||
BlockPos blockPos = pos.offset(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1);
|
||||
- if (level.getBlockState(blockPos).is(Blocks.DIRT) && canPropagate(blockState, level, blockPos)) {
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, blockState.setValue(SNOWY, Boolean.valueOf(isSnowySetting(level.getBlockState(blockPos.above()))))); // CraftBukkit
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, blockState.setValue(SNOWY, isSnowySetting(level.getBlockState(blockPos.above()))), 3); // CraftBukkit
|
||||
+ // Paper start - Perf: optimize dirt and snow spreading
|
||||
+ if (pos.getX() == blockPos.getX() && pos.getY() == blockPos.getY() && pos.getZ() == blockPos.getZ()) {
|
||||
+ continue;
|
||||
@@ -71,7 +71,7 @@ index 11937aa74efe08bdbd66a619c7a825f91d971afd..722f2b9a24679e0fc67aae2cd27051f9
|
||||
+ access = level.getChunkAt(blockPos);
|
||||
+ }
|
||||
+ if (access.getBlockState(blockPos).is(Blocks.DIRT) && SpreadingSnowyDirtBlock.canPropagate(access, blockState, level, blockPos)) {
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, (BlockState) blockState.setValue(SpreadingSnowyDirtBlock.SNOWY, isSnowySetting(access.getBlockState(blockPos.above())))); // CraftBukkit
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, blockState.setValue(SNOWY, isSnowySetting(access.getBlockState(blockPos.above()))), 3); // CraftBukkit
|
||||
+ // Paper end - Perf: optimize dirt and snow spreading
|
||||
}
|
||||
}
|
||||
|
@@ -7,10 +7,10 @@ bypass the need to get a player chunk, then get the either,
|
||||
then unwrap it...
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index c3553385074108d686425a7637b8975076d906b9..2f49dbc919f7f5eea9abce6106723c72f5ae45fb 100644
|
||||
index 006d8abe66b2d66740b984d8ff7f56a41b9929f7..52104bcd74107bb9a475109230ca85dd2eba5b06 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -218,6 +218,12 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -224,6 +224,12 @@ public class ServerChunkCache extends ChunkSource {
|
||||
if (Thread.currentThread() != this.mainThread) {
|
||||
return CompletableFuture.<ChunkAccess>supplyAsync(() -> this.getChunk(x, z, chunkStatus, requireChunk), this.mainThreadProcessor).join();
|
||||
} else {
|
||||
@@ -23,7 +23,7 @@ index c3553385074108d686425a7637b8975076d906b9..2f49dbc919f7f5eea9abce6106723c72
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.incrementCounter("getChunk");
|
||||
long packedChunkPos = ChunkPos.asLong(x, z);
|
||||
@@ -252,30 +258,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -258,30 +264,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
if (Thread.currentThread() != this.mainThread) {
|
||||
return null;
|
||||
} else {
|
||||
|
@@ -84,7 +84,7 @@ index 98f0b1cf19d7a035849a9a2fa25e2be3a4c5a980..a81694a22e94cca6f7110f7d5b205d13
|
||||
|
||||
public static long getFlatIndex(long packedPos) {
|
||||
diff --git a/net/minecraft/core/SectionPos.java b/net/minecraft/core/SectionPos.java
|
||||
index 1780d8e14cea62971da75e4dcc80d1805434037b..ce8c394ea1a7bc5bf5c568c82e6158b19df517d8 100644
|
||||
index ce076662d2ffbb570c8c225e9635de490ea535e8..2fb2e3434c0e495ab4d5cb6d2718717cd0a269f2 100644
|
||||
--- a/net/minecraft/core/SectionPos.java
|
||||
+++ b/net/minecraft/core/SectionPos.java
|
||||
@@ -38,7 +38,7 @@ public class SectionPos extends Vec3i {
|
||||
@@ -167,7 +167,7 @@ index 1780d8e14cea62971da75e4dcc80d1805434037b..ce8c394ea1a7bc5bf5c568c82e6158b1
|
||||
}
|
||||
|
||||
public static long getZeroNode(int x, int z) {
|
||||
@@ -205,15 +210,17 @@ public class SectionPos extends Vec3i {
|
||||
@@ -209,15 +214,17 @@ public class SectionPos extends Vec3i {
|
||||
return asLong(blockToSectionCoord(blockPos.getX()), blockToSectionCoord(blockPos.getY()), blockToSectionCoord(blockPos.getZ()));
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ index 1780d8e14cea62971da75e4dcc80d1805434037b..ce8c394ea1a7bc5bf5c568c82e6158b1
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,16 +233,13 @@ public class SectionPos extends Vec3i {
|
||||
@@ -230,16 +237,13 @@ public class SectionPos extends Vec3i {
|
||||
}
|
||||
|
||||
public static Stream<SectionPos> cube(SectionPos center, int radius) {
|
||||
|
@@ -98,18 +98,27 @@ index c215d97c24e6501e1a48a76fc08bf48ff4dfe462..bd31d1cac0d022a72bd536c41d1ef811
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/ai/gossip/GossipContainer.java b/net/minecraft/world/entity/ai/gossip/GossipContainer.java
|
||||
index 2c839dc80f451c83135828a97aced1a531004bab..b74a4ce1b629d440681a1f5c026997ccaf1d0373 100644
|
||||
index d93ef8d7ff04ffd3d7434ea6e2d476115203215b..425ca1931fb0a5c33ba7aaf4f639409c9fea836f 100644
|
||||
--- a/net/minecraft/world/entity/ai/gossip/GossipContainer.java
|
||||
+++ b/net/minecraft/world/entity/ai/gossip/GossipContainer.java
|
||||
@@ -59,8 +59,22 @@ public class GossipContainer {
|
||||
return this.gossips.entrySet().stream().flatMap(gossip -> gossip.getValue().unpack(gossip.getKey()));
|
||||
@@ -28,7 +28,7 @@ import net.minecraft.util.VisibleForDebug;
|
||||
public class GossipContainer {
|
||||
public static final Codec<GossipContainer> CODEC = GossipContainer.GossipEntry.CODEC
|
||||
.listOf()
|
||||
- .xmap(GossipContainer::new, gossipContainer -> gossipContainer.unpack().toList());
|
||||
+ .xmap(GossipContainer::new, gossipContainer -> gossipContainer.decompress()); // Paper - Perf: Remove streams from hot code
|
||||
public static final int DISCARD_THRESHOLD = 2;
|
||||
public final Map<UUID, GossipContainer.EntityGossips> gossips = new HashMap<>();
|
||||
|
||||
@@ -65,8 +65,22 @@ public class GossipContainer {
|
||||
return this.gossips.entrySet().stream().flatMap(entry -> entry.getValue().unpack(entry.getKey()));
|
||||
}
|
||||
|
||||
+ // Paper start - Perf: Remove streams from hot code
|
||||
+ private List<GossipContainer.GossipEntry> decompress() {
|
||||
+ List<GossipContainer.GossipEntry> list = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
||||
+ for (Map.Entry<UUID, GossipContainer.EntityGossips> entry : this.gossips.entrySet()) {
|
||||
+ for (GossipContainer.GossipEntry cur : entry.getValue().decompress(entry.getKey())) {
|
||||
+ final List<GossipContainer.GossipEntry> list = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
||||
+ for (final Map.Entry<UUID, GossipContainer.EntityGossips> entry : this.gossips.entrySet()) {
|
||||
+ for (final GossipContainer.GossipEntry cur : entry.getValue().decompress(entry.getKey())) {
|
||||
+ if (cur.weightedValue() != 0) {
|
||||
+ list.add(cur);
|
||||
+ }
|
||||
@@ -125,16 +134,7 @@ index 2c839dc80f451c83135828a97aced1a531004bab..b74a4ce1b629d440681a1f5c026997cc
|
||||
if (list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
@@ -145,7 +159,7 @@ public class GossipContainer {
|
||||
|
||||
public <T> T store(DynamicOps<T> ops) {
|
||||
return GossipContainer.GossipEntry.LIST_CODEC
|
||||
- .encodeStart(ops, this.unpack().toList())
|
||||
+ .encodeStart(ops, this.decompress()) // Paper - Perf: Remove streams from hot code
|
||||
.resultOrPartial(errorMessage -> LOGGER.warn("Failed to serialize gossips: {}", errorMessage))
|
||||
.orElseGet(ops::emptyList);
|
||||
}
|
||||
@@ -172,12 +186,23 @@ public class GossipContainer {
|
||||
@@ -176,12 +190,23 @@ public class GossipContainer {
|
||||
final Object2IntMap<GossipType> entries = new Object2IntOpenHashMap<>();
|
||||
|
||||
public int weightedValue(Predicate<GossipType> gossipType) {
|
||||
@@ -194,7 +194,7 @@ index 38873e56e95dc772b184e4271f7af1fb411ac9f8..09fd13e2d958da8326276c4dadf25bf4
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/levelgen/Beardifier.java b/net/minecraft/world/level/levelgen/Beardifier.java
|
||||
index 1a09da5aa1ae047a002d6779326c2a29e47d32b5..131923282c9ecbcb1d7f45a826da907c02bd2716 100644
|
||||
index 8bc2dd4fa128fc2f88b974b8712cb0953a024eaa..74d8202b5c9bb2a3ee832be70f95c0b5cbecb460 100644
|
||||
--- a/net/minecraft/world/level/levelgen/Beardifier.java
|
||||
+++ b/net/minecraft/world/level/levelgen/Beardifier.java
|
||||
@@ -35,9 +35,10 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
|
||||
@@ -211,7 +211,7 @@ index 1a09da5aa1ae047a002d6779326c2a29e47d32b5..131923282c9ecbcb1d7f45a826da907c
|
||||
TerrainAdjustment terrainAdjustment = structureStart.getStructure().terrainAdaptation();
|
||||
|
||||
for (StructurePiece structurePiece : structureStart.getPieces()) {
|
||||
@@ -65,8 +66,7 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
|
||||
@@ -64,8 +65,7 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -48,10 +48,10 @@ index db31989ebe3d7021cfd2311439e9a00f819b0841..1373977b339405ef59bb3ea03d195285
|
||||
serverEntity.getLastSentYRot(),
|
||||
entity.getType(),
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 3dff97f13586be3b52bbe786852c185f6753a019..ff6503bf8eb88d1264c3d848a89d0255b4b3ae68 100644
|
||||
index 1463c31ba980ab0eb2174e3e891d1423a505e9dc..886340232b58afd59caa6df29e211589a7781070 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1208,6 +1208,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -1278,6 +1278,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.serverEntity.addPairing(player);
|
||||
}
|
||||
// Paper end - entity tracking events
|
||||
@@ -60,10 +60,10 @@ index 3dff97f13586be3b52bbe786852c185f6753a019..ff6503bf8eb88d1264c3d848a89d0255
|
||||
} else if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
||||
index db06f966077928419bfe469260f04d7dfda69f28..0fb253aa55a24b56b17f524b3261c5b75c7d7e59 100644
|
||||
index 0005a1784ccaa00e5d6d67e7be98445150487982..257ecbcf7d463eefb951867a5426eaf24e356305 100644
|
||||
--- a/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -90,6 +90,13 @@ public class ServerEntity {
|
||||
@@ -103,6 +103,13 @@ public class ServerEntity {
|
||||
this.trackedDataValues = entity.getEntityData().getNonDefaultValues();
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ index db06f966077928419bfe469260f04d7dfda69f28..0fb253aa55a24b56b17f524b3261c5b7
|
||||
public void sendChanges() {
|
||||
// Paper start - optimise collisions
|
||||
if (((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this.entity).moonrise$isHardColliding()) {
|
||||
@@ -131,7 +138,7 @@ public class ServerEntity {
|
||||
@@ -136,7 +143,7 @@ public class ServerEntity {
|
||||
this.sendDirtyEntityData();
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ index db06f966077928419bfe469260f04d7dfda69f28..0fb253aa55a24b56b17f524b3261c5b7
|
||||
byte b = Mth.packDegrees(this.entity.getYRot());
|
||||
byte b1 = Mth.packDegrees(this.entity.getXRot());
|
||||
boolean flag = Math.abs(b - this.lastSentYRot) >= 1 || Math.abs(b1 - this.lastSentXRot) >= 1;
|
||||
@@ -166,7 +173,7 @@ public class ServerEntity {
|
||||
@@ -171,7 +178,7 @@ public class ServerEntity {
|
||||
long l1 = this.positionCodec.encodeY(vec3);
|
||||
long l2 = this.positionCodec.encodeZ(vec3);
|
||||
boolean flag5 = l < -32768L || l > 32767L || l1 < -32768L || l1 > 32767L || l2 < -32768L || l2 > 32767L;
|
||||
@@ -95,7 +95,7 @@ index db06f966077928419bfe469260f04d7dfda69f28..0fb253aa55a24b56b17f524b3261c5b7
|
||||
this.wasOnGround = this.entity.onGround();
|
||||
this.teleportDelay = 0;
|
||||
packet = ClientboundEntityPositionSyncPacket.of(this.entity);
|
||||
@@ -231,6 +238,7 @@ public class ServerEntity {
|
||||
@@ -236,6 +243,7 @@ public class ServerEntity {
|
||||
}
|
||||
|
||||
this.entity.hasImpulse = false;
|
@@ -978,10 +978,10 @@ index 0000000000000000000000000000000000000000..ff747a1ecdf3c888bca0d69de4f85dcd
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
index 84e6c986917128d4488afa23d29c689cadb4f55d..f02232ce97779db0d12a5d5da1d767326d78ea4c 100644
|
||||
index cbdf514e190385339476a17c7426c55daec9f2a1..50eceaed6907a596c0c1cd87f5927e07d33a5dbb 100644
|
||||
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
@@ -290,6 +290,60 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -265,6 +265,60 @@ public class RedStoneWireBlock extends Block {
|
||||
return state.isFaceSturdy(level, pos, Direction.UP) || state.is(Blocks.HOPPER);
|
||||
}
|
||||
|
||||
@@ -1042,7 +1042,7 @@ index 84e6c986917128d4488afa23d29c689cadb4f55d..f02232ce97779db0d12a5d5da1d76732
|
||||
private void updatePowerStrength(Level level, BlockPos pos, BlockState state, @Nullable Orientation orientation, boolean updateShape) {
|
||||
if (useExperimentalEvaluator(level)) {
|
||||
new ExperimentalRedstoneWireEvaluator(this).updatePowerStrength(level, pos, state, orientation, updateShape);
|
||||
@@ -318,7 +372,7 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -293,7 +347,7 @@ public class RedStoneWireBlock extends Block {
|
||||
@Override
|
||||
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
if (!oldState.is(state.getBlock()) && !level.isClientSide) {
|
||||
@@ -1051,16 +1051,16 @@ index 84e6c986917128d4488afa23d29c689cadb4f55d..f02232ce97779db0d12a5d5da1d76732
|
||||
|
||||
for (Direction direction : Direction.Plane.VERTICAL) {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
@@ -337,7 +391,7 @@ public class RedStoneWireBlock extends Block {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
}
|
||||
|
||||
- this.updatePowerStrength(level, pos, state, null, false);
|
||||
+ this.updateSurroundingRedstone(level, pos, state, null, false); // Paper - Optimize redstone
|
||||
this.updateNeighborsOfNeighboringWires(level, pos);
|
||||
@@ -310,7 +364,7 @@ public class RedStoneWireBlock extends Block {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
}
|
||||
|
||||
- this.updatePowerStrength(level, pos, state, null, false);
|
||||
+ this.updateSurroundingRedstone(level, pos, state, null, false); // Paper - Optimize redstone
|
||||
this.updateNeighborsOfNeighboringWires(level, pos);
|
||||
}
|
||||
@@ -363,7 +417,7 @@ public class RedStoneWireBlock extends Block {
|
||||
}
|
||||
@@ -335,7 +389,7 @@ public class RedStoneWireBlock extends Block {
|
||||
if (!level.isClientSide) {
|
||||
if (neighborBlock != this || !useExperimentalEvaluator(level)) {
|
||||
if (state.canSurvive(level, pos)) {
|
||||
@@ -1070,7 +1070,7 @@ index 84e6c986917128d4488afa23d29c689cadb4f55d..f02232ce97779db0d12a5d5da1d76732
|
||||
dropResources(state, level, pos);
|
||||
level.removeBlock(pos, false);
|
||||
diff --git a/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java b/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java
|
||||
index 380fc51a252022195e178daccd8aa53dd1d71a2e..2d77780b6727f82ffc3cb216ca5f2d6483496cfd 100644
|
||||
index 3f6f3ca5a5e412e57fad635f52cd152520d6dca2..abcc144a086a45bf4cfa4d1a33e2ae10952e0da2 100644
|
||||
--- a/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java
|
||||
+++ b/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java
|
||||
@@ -44,7 +44,7 @@ public class DefaultRedstoneWireEvaluator extends RedstoneWireEvaluator {
|
@@ -2326,18 +2326,18 @@ index 0000000000000000000000000000000000000000..298076a0db4e6ee6e4775ac43bf749d9
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index a293d1481b5f4a1d18addc3e518486c639223f09..5bf38ab129451e867b638cfbd2d7be59cbf7f38d 100644
|
||||
index 8afe96bfdc37e57129f1bb4af5b6d5cc22c11aee..32db2b9e375c12cbf7abab69cc01e8ac2c7c3b6e 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -214,6 +214,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
public final UUID uuid;
|
||||
@@ -210,6 +210,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
public final java.util.UUID uuid;
|
||||
public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent
|
||||
public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent
|
||||
+ private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current)
|
||||
|
||||
public LevelChunk getChunkIfLoaded(int x, int z) {
|
||||
return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately
|
||||
@@ -2557,6 +2558,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@Override
|
||||
public @Nullable LevelChunk getChunkIfLoaded(int x, int z) {
|
||||
@@ -2552,6 +2553,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
return this.chunkSource.getGenerator().getSeaLevel();
|
||||
}
|
||||
|
||||
@@ -2352,12 +2352,12 @@ index a293d1481b5f4a1d18addc3e518486c639223f09..5bf38ab129451e867b638cfbd2d7be59
|
||||
@Override
|
||||
public void onCreated(Entity entity) {
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index a768f041fd16d253ec4ab5eb75288b1771d5cb00..1dbe7c7c1051c3972105534a07ce50d4cf98fc85 100644
|
||||
index eb4d03cfdb34243901cfba832d35559d5be9e876..013ed7dbe2309f562f63e66203179a90566e8115 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -2099,6 +2099,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
public abstract FuelValues fuelValues();
|
||||
@@ -2096,6 +2096,17 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ // Paper start - optimize redstone (Alternate Current)
|
||||
+ public alternate.current.wire.WireHandler getWireHandler() {
|
||||
@@ -2374,10 +2374,10 @@ index a768f041fd16d253ec4ab5eb75288b1771d5cb00..1dbe7c7c1051c3972105534a07ce50d4
|
||||
NONE("none"),
|
||||
BLOCK("block"),
|
||||
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
index f02232ce97779db0d12a5d5da1d767326d78ea4c..12c9d60314c99fb65e640d255a2d0c6b7790ad4d 100644
|
||||
index 50eceaed6907a596c0c1cd87f5927e07d33a5dbb..1943a6aad888647953e2d9dbbeedb0bd81c6f9df 100644
|
||||
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
@@ -290,7 +290,7 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -265,7 +265,7 @@ public class RedStoneWireBlock extends Block {
|
||||
return state.isFaceSturdy(level, pos, Direction.UP) || state.is(Blocks.HOPPER);
|
||||
}
|
||||
|
||||
@@ -2386,7 +2386,7 @@ index f02232ce97779db0d12a5d5da1d767326d78ea4c..12c9d60314c99fb65e640d255a2d0c6b
|
||||
// The bulk of the new functionality is found in RedstoneWireTurbo.java
|
||||
io.papermc.paper.redstone.RedstoneWireTurbo turbo = new io.papermc.paper.redstone.RedstoneWireTurbo(this);
|
||||
|
||||
@@ -372,7 +372,13 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -347,7 +347,13 @@ public class RedStoneWireBlock extends Block {
|
||||
@Override
|
||||
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
if (!oldState.is(state.getBlock()) && !level.isClientSide) {
|
||||
@@ -2401,22 +2401,22 @@ index f02232ce97779db0d12a5d5da1d767326d78ea4c..12c9d60314c99fb65e640d255a2d0c6b
|
||||
|
||||
for (Direction direction : Direction.Plane.VERTICAL) {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
@@ -391,7 +397,13 @@ public class RedStoneWireBlock extends Block {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
}
|
||||
|
||||
- this.updateSurroundingRedstone(level, pos, state, null, false); // Paper - Optimize redstone
|
||||
+ // Paper start - optimize redstone - replace call to updatePowerStrength
|
||||
+ if (level.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) {
|
||||
+ level.getWireHandler().onWireRemoved(pos, state); // Alternate Current
|
||||
+ } else {
|
||||
+ this.updateSurroundingRedstone(level, pos, state, null, false); // Vanilla/Eigencraft
|
||||
+ }
|
||||
+ // Paper end - optimize redstone
|
||||
this.updateNeighborsOfNeighboringWires(level, pos);
|
||||
@@ -364,7 +370,13 @@ public class RedStoneWireBlock extends Block {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
}
|
||||
|
||||
- this.updateSurroundingRedstone(level, pos, state, null, false); // Paper - Optimize redstone
|
||||
+ // Paper start - optimize redstone - replace call to updatePowerStrength
|
||||
+ if (level.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) {
|
||||
+ level.getWireHandler().onWireRemoved(pos, state); // Alternate Current
|
||||
+ } else {
|
||||
+ this.updateSurroundingRedstone(level, pos, state, null, false); // Vanilla/Eigencraft
|
||||
+ }
|
||||
+ // Paper end - optimize redstone
|
||||
this.updateNeighborsOfNeighboringWires(level, pos);
|
||||
}
|
||||
@@ -415,9 +427,15 @@ public class RedStoneWireBlock extends Block {
|
||||
}
|
||||
@@ -387,9 +399,15 @@ public class RedStoneWireBlock extends Block {
|
||||
@Override
|
||||
protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) {
|
||||
if (!level.isClientSide) {
|
@@ -150,7 +150,7 @@ index 0000000000000000000000000000000000000000..f47c12e9dd6cfa857ca07a764edc22de
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/recipebook/ServerPlaceRecipe.java b/net/minecraft/recipebook/ServerPlaceRecipe.java
|
||||
index 6475509689439636275b06b9eac33f0922d8fcfd..6c398c91909f42e352e80d0781549df9d834a060 100644
|
||||
index 6d3e3ec045d5b15a435f7217369968b33e082724..b7a3758af337270737041f84d10eb43784e42279 100644
|
||||
--- a/net/minecraft/recipebook/ServerPlaceRecipe.java
|
||||
+++ b/net/minecraft/recipebook/ServerPlaceRecipe.java
|
||||
@@ -40,6 +40,7 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
@@ -204,10 +204,10 @@ index 6475509689439636275b06b9eac33f0922d8fcfd..6c398c91909f42e352e80d0781549df9
|
||||
int i = this.inventory.findSlotMatchingCraftingIngredient(item, item1);
|
||||
if (i == -1) {
|
||||
diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java
|
||||
index 8a29d771046667db22fba166fa5337de1896cd0d..839cbb67d3d38960d9114a4db5bab911b66a573c 100644
|
||||
index 24d32c0163d27a7886bd4048d508591b89f714a4..dd406c5becacbc2d05b062726a8af88a1d6faba9 100644
|
||||
--- a/net/minecraft/world/entity/player/Inventory.java
|
||||
+++ b/net/minecraft/world/entity/player/Inventory.java
|
||||
@@ -185,12 +185,12 @@ public class Inventory implements Container, Nameable {
|
||||
@@ -230,12 +230,12 @@ public class Inventory implements Container, Nameable {
|
||||
return !stack.isDamaged() && !stack.isEnchanted() && !stack.has(DataComponents.CUSTOM_NAME);
|
||||
}
|
||||
|
@@ -45,7 +45,7 @@ index 984db72272d552c7210bd6f437ea88694ddd2828..dea2823a9d1d69dcb0a4759d8ea9b301
|
||||
public void close() throws IOException {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(this.buf, 0, this.count);
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index e35bb5534e2fbd2e30154a15ff6d39baa121608f..d263f78fa610ce6f6fb5a0f5e064e3d8335c2199 100644
|
||||
index 50bbd8c778bfa9fc9ce93ed09a6fe4dc1f516d51..e9c7e56343238cfce3f4a3c658f2983ca1ef3f0e 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -15,6 +15,7 @@ import net.minecraft.util.ExceptionCollector;
|
@@ -9,7 +9,7 @@ defaults are only included for certain entites, this allows setting
|
||||
limits for any entity type.
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
index 7aea4e343581b977d11af90f9f65eac3532eade1..d21ce54ebb5724c04eadf56a2cde701d5eeb5db2 100644
|
||||
index 1c82dcd38f789707e15e8cbec72ef9cdc7efdf56..ba20e87d2105ce53cdaf4049de2388d05fcd1b56 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
@@ -104,7 +104,18 @@ public final class ChunkEntitySlices {
|
||||
@@ -32,35 +32,35 @@ index 7aea4e343581b977d11af90f9f65eac3532eade1..d21ce54ebb5724c04eadf56a2cde701d
|
||||
if (entity.save(compoundTag)) {
|
||||
entitiesTag.add(compoundTag);
|
||||
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
|
||||
index 73cdfa5a315ed259b38dfa946a0b7955d9ac9f50..49201d6664656ebe34c84c1c84b5ea4878729062 100644
|
||||
index 4c57990c94721dd0973477669e1dadfab5f16404..8af02ed823da098a5592ef195c9fe8ed8f245b53 100644
|
||||
--- a/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/net/minecraft/world/entity/EntityType.java
|
||||
@@ -1420,9 +1420,20 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
public static Stream<Entity> loadEntitiesRecursive(final List<? extends Tag> entityTags, final Level level, final EntitySpawnReason spawnReason) {
|
||||
final Spliterator<? extends Tag> spliterator = entityTags.spliterator();
|
||||
return StreamSupport.stream(new Spliterator<Entity>() {
|
||||
+ final java.util.Map<EntityType<?>, Integer> loadedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super Entity> consumer) {
|
||||
return spliterator.tryAdvance(tag -> EntityType.loadEntityRecursive((CompoundTag)tag, level, spawnReason, entity -> {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (this.loadedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ this.loadedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
consumer.accept(entity);
|
||||
return entity;
|
||||
}));
|
||||
@@ -1430,9 +1430,20 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
}
|
||||
|
||||
public static Stream<Entity> loadEntitiesRecursive(List<? extends Tag> entityTags, Level level, EntitySpawnReason spawnReason) {
|
||||
+ final java.util.Map<EntityType<?>, Integer> loadedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
return entityTags.stream()
|
||||
.flatMap(tag -> tag.asCompound().stream())
|
||||
.mapMulti((compoundTag, consumer) -> loadEntityRecursive(compoundTag, level, spawnReason, entity -> {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (loadedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ loadedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
consumer.accept(entity);
|
||||
return entity;
|
||||
}));
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/EntityStorage.java b/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
index da05fb780c55381a7a08ced51d01764a645740b2..2856206eafddfcbcc1b65408deda40357f43a6f8 100644
|
||||
index bcc2a4081fac07c4579c3aabfe4353743f8cd876..f9fb1380be9cbe960127c208c65c19f770e50b6d 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
@@ -93,7 +93,18 @@ public class EntityStorage implements EntityPersistentStorage<Entity> {
|
||||
@@ -87,7 +87,18 @@ public class EntityStorage implements EntityPersistentStorage<Entity> {
|
||||
}
|
||||
} else {
|
||||
ListTag listTag = new ListTag();
|
@@ -617,7 +617,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
||||
return byteBuffer;
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index d263f78fa610ce6f6fb5a0f5e064e3d8335c2199..dad7f94b611cf0fc68b1a3878c458233f6bb6d61 100644
|
||||
index e9c7e56343238cfce3f4a3c658f2983ca1ef3f0e..f3ea8b9e8f4510112ec5e41727ebc0cf9ecee195 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -23,6 +23,36 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
@@ -686,7 +686,7 @@ index d263f78fa610ce6f6fb5a0f5e064e3d8335c2199..dad7f94b611cf0fc68b1a3878c458233
|
||||
|
||||
return var4;
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileVersion.java b/net/minecraft/world/level/chunk/storage/RegionFileVersion.java
|
||||
index 0c739ca5b01ac0ec35a11fd01c5fc65de97c2852..de7deee4b79c969a7797bd57b657a16404c15303 100644
|
||||
index 1649119f45d970a9bf1683d676c47ecfc18ad047..cc544f3199cd6af29e50362923d0651705877f16 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/RegionFileVersion.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFileVersion.java
|
||||
@@ -21,7 +21,7 @@ import org.slf4j.Logger;
|
||||
@@ -699,10 +699,10 @@ index 0c739ca5b01ac0ec35a11fd01c5fc65de97c2852..de7deee4b79c969a7797bd57b657a164
|
||||
public static final RegionFileVersion VERSION_GZIP = register(
|
||||
new RegionFileVersion(
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
index 879d411775a2fece1d8a970300cb3a550baa6305..6b6aaeca14178b5b709e20ae13552d42217f15c0 100644
|
||||
index 03d1527073cf827fc3e191915fe5f7f064e36c3b..749096358fccbd5d1d13801092255c51096eb001 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
@@ -120,6 +120,18 @@ public record SerializableChunkData(
|
||||
@@ -122,6 +122,18 @@ public record SerializableChunkData(
|
||||
}
|
||||
}
|
||||
// Paper end - guard against serializing mismatching coordinates
|
||||
@@ -711,17 +711,17 @@ index 879d411775a2fece1d8a970300cb3a550baa6305..6b6aaeca14178b5b709e20ae13552d42
|
||||
+ public static long getLastWorldSaveTime(final CompoundTag chunkData) {
|
||||
+ final int dataVersion = ChunkStorage.getVersion(chunkData);
|
||||
+ if (dataVersion < 2842) { // Level tag is removed after this version
|
||||
+ final CompoundTag levelData = chunkData.getCompound("Level");
|
||||
+ return levelData.getLong("LastUpdate");
|
||||
+ final CompoundTag levelData = chunkData.getCompoundOrEmpty("Level");
|
||||
+ return levelData.getLongOr("LastUpdate", 0L);
|
||||
+ } else {
|
||||
+ return chunkData.getLong("LastUpdate");
|
||||
+ return chunkData.getLongOr("LastUpdate", 0L);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Attempt to recalculate regionfile header if it is corrupt
|
||||
|
||||
// Paper start - Do not let the server load chunks from newer versions
|
||||
private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion();
|
||||
@@ -604,7 +616,7 @@ public record SerializableChunkData(
|
||||
@@ -571,7 +583,7 @@ public record SerializableChunkData(
|
||||
compoundTag.putInt("xPos", this.chunkPos.x);
|
||||
compoundTag.putInt("yPos", this.minSectionY);
|
||||
compoundTag.putInt("zPos", this.chunkPos.z);
|
||||
@@ -729,4 +729,4 @@ index 879d411775a2fece1d8a970300cb3a550baa6305..6b6aaeca14178b5b709e20ae13552d42
|
||||
+ compoundTag.putLong("LastUpdate", this.lastUpdateTime); // Paper - Diff on change
|
||||
compoundTag.putLong("InhabitedTime", this.inhabitedTime);
|
||||
compoundTag.putString("Status", BuiltInRegistries.CHUNK_STATUS.getKey(this.chunkStatus).toString());
|
||||
if (this.blendingData != null) {
|
||||
compoundTag.storeNullable("blending_data", BlendingData.Packed.CODEC, this.blendingData);
|
@@ -5,10 +5,10 @@ Subject: [PATCH] Incremental chunk and player saving
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 409c1134327bfcc338c3ac5e658a83cc396645d1..cc2d442682496197d29ace79b22e6cf6fb7edf5e 100644
|
||||
index 00f7f4356d6bffdd31f58b9d798c755edd9cd3ff..ea85cac4a41075efe8525c40755e7ebac6ca9dea 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -960,7 +960,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -952,7 +952,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
boolean var4;
|
||||
try {
|
||||
this.isSaving = true;
|
||||
@@ -17,7 +17,7 @@ index 409c1134327bfcc338c3ac5e658a83cc396645d1..cc2d442682496197d29ace79b22e6cf6
|
||||
var4 = this.saveAllChunks(suppressLog, flush, forced);
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
@@ -1533,9 +1533,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1531,9 +1531,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
this.ticksUntilAutosave--;
|
||||
@@ -50,11 +50,11 @@ index 409c1134327bfcc338c3ac5e658a83cc396645d1..cc2d442682496197d29ace79b22e6cf6
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
this.runAllTasks(); // Paper - move runAllTasks() into full server tick (previously for timings)
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 42995dac38248032b6abecc27124adfe12ec4cab..28a67294c3e678e01d5dfd68b950234213d8e55c 100644
|
||||
index debc511cf18d0be813803c200bd1cf0b07ba7974..2a4a40976215ea858c562c3f530db378896c6fcb 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1318,6 +1318,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
return !this.server.isUnderSpawnProtection(this, pos, player) && this.getWorldBorder().isWithinBounds(pos);
|
||||
@@ -1317,6 +1317,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
return !(entity instanceof Player player && (this.server.isUnderSpawnProtection(this, pos, player) || !this.getWorldBorder().isWithinBounds(pos)));
|
||||
}
|
||||
|
||||
+ // Paper start - Incremental chunk and player saving
|
||||
@@ -83,10 +83,10 @@ index 42995dac38248032b6abecc27124adfe12ec4cab..28a67294c3e678e01d5dfd68b9502342
|
||||
// Paper start - add close param
|
||||
this.save(progress, flush, skipSave, false);
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index f44600604a7bf68c990cd74a1ac2d7900ff6e88e..69b8074e18775c846d5991f40bc2e0a5186500ac 100644
|
||||
index bc901bc689c2690ac19e590bff1ae612b7071ee9..8e7ee4dc951eb53ccf65ab71214a0b89bd932ba0 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -180,6 +180,7 @@ import org.slf4j.Logger;
|
||||
@@ -189,6 +189,7 @@ import org.slf4j.Logger;
|
||||
|
||||
public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -95,10 +95,10 @@ index f44600604a7bf68c990cd74a1ac2d7900ff6e88e..69b8074e18775c846d5991f40bc2e0a5
|
||||
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
|
||||
private static final int FLY_STAT_RECORDING_SPEED = 25;
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 7d1d4abfb04829d8c4722e326c6c6b8fb2ab91f4..5a4960fdbd97d830ac79845697eea9372c48a13b 100644
|
||||
index 72524ff3399a4477dfa3db2f4e79bb14f6519a8b..6e22aedd36add8e39a82248193f324b36dfa27b5 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -482,6 +482,7 @@ public abstract class PlayerList {
|
||||
@@ -486,6 +486,7 @@ public abstract class PlayerList {
|
||||
|
||||
protected void save(ServerPlayer player) {
|
||||
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
|
||||
@@ -106,7 +106,7 @@ index 7d1d4abfb04829d8c4722e326c6c6b8fb2ab91f4..5a4960fdbd97d830ac79845697eea937
|
||||
this.playerIo.save(player);
|
||||
ServerStatsCounter serverStatsCounter = player.getStats(); // CraftBukkit
|
||||
if (serverStatsCounter != null) {
|
||||
@@ -1064,9 +1065,23 @@ public abstract class PlayerList {
|
||||
@@ -1068,9 +1069,23 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void saveAll() {
|
@@ -980,7 +980,7 @@ index 5c5724f5e3ad640f55aecbc1d8f71d1f59ecdc62..618fc0eb4fe70e46e55f3aa28e8eac1d
|
||||
|
||||
public boolean release(BlockPos pos) {
|
||||
diff --git a/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/net/minecraft/world/entity/ai/village/poi/PoiSection.java
|
||||
index 39cd1e3d8192d7077d6b7864d33933097cc6b986..b92ba4d194fd3af94c7af5d8e150fc4297c73ab8 100644
|
||||
index c3bcb494afe464207e805f8c40b03c700059c64a..063fca9686a6a048ba279a49271f4144beeff3b9 100644
|
||||
--- a/net/minecraft/world/entity/ai/village/poi/PoiSection.java
|
||||
+++ b/net/minecraft/world/entity/ai/village/poi/PoiSection.java
|
||||
@@ -26,7 +26,7 @@ import org.slf4j.Logger;
|
||||
@@ -1011,7 +1011,7 @@ index 778bd73a938c94ecb85ca0f8b686ff4e1baee040..79d4ce7712f16995b0de3be86477fb43
|
||||
return Optional.empty();
|
||||
} else {
|
||||
diff --git a/net/minecraft/world/level/portal/PortalForcer.java b/net/minecraft/world/level/portal/PortalForcer.java
|
||||
index ada2da62d3a40d67e64f5f8d7299f78b5c6f53cb..90ae71eb8cc7f925eb212f39731d70f3bff5ef0a 100644
|
||||
index aa31439af40e13006eff0036cef2905ac59390b3..b84d658bb06ab7b51cfc18d7405238554f65d2a5 100644
|
||||
--- a/net/minecraft/world/level/portal/PortalForcer.java
|
||||
+++ b/net/minecraft/world/level/portal/PortalForcer.java
|
||||
@@ -48,13 +48,38 @@ public class PortalForcer {
|
@@ -5,10 +5,10 @@ Subject: [PATCH] Optional per player mob spawns
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index ff6503bf8eb88d1264c3d848a89d0255b4b3ae68..9eed24939fc09f00a9dbce1be2ab9c34d024fd29 100644
|
||||
index 886340232b58afd59caa6df29e211589a7781070..4f4bcc4bbfcc9b191d12d667b8fc1e644a9d5957 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -236,11 +236,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -243,11 +243,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
@@ -43,20 +43,11 @@ index ff6503bf8eb88d1264c3d848a89d0255b4b3ae68..9eed24939fc09f00a9dbce1be2ab9c34
|
||||
protected ChunkGenerator generator() {
|
||||
return this.worldGenContext.generator();
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 87d4291a3944f706a694536da6de0f28c548ab8d..5576bf1d1d70ab7a010653d3207909b5de867e70 100644
|
||||
index 5d63bf024cbcbd2f627c64fee77553c9a512bd15..f863377a807b672f49f7140688f378eca2cf650b 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -517,7 +517,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
profilerFiller.popPush("shuffleChunks");
|
||||
// Paper start - chunk tick iteration optimisation
|
||||
this.shuffleRandom.setSeed(this.level.random.nextLong());
|
||||
- Util.shuffle(list, this.shuffleRandom);
|
||||
+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled
|
||||
// Paper end - chunk tick iteration optimisation
|
||||
this.tickChunks(profilerFiller, l, list);
|
||||
profilerFiller.pop();
|
||||
@@ -571,9 +571,18 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
private void tickChunks(ProfilerFiller profiler, long timeInhabited, List<LevelChunk> chunks) {
|
||||
@@ -541,9 +541,18 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
private void tickChunks(ProfilerFiller profiler, long timeInhabited) {
|
||||
profiler.popPush("naturalSpawnCount");
|
||||
int naturalSpawnChunkCount = this.distanceManager.getNaturalSpawnChunkCount();
|
||||
- NaturalSpawner.SpawnState spawnState = NaturalSpawner.createState(
|
||||
@@ -77,13 +68,22 @@ index 87d4291a3944f706a694536da6de0f28c548ab8d..5576bf1d1d70ab7a010653d3207909b5
|
||||
this.lastSpawnState = spawnState;
|
||||
profiler.popPush("spawnAndTick");
|
||||
boolean _boolean = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit
|
||||
@@ -572,7 +581,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
profiler.popPush("shuffleSpawningChunks");
|
||||
// Paper start - chunk tick iteration optimisation
|
||||
this.shuffleRandom.setSeed(this.level.random.nextLong());
|
||||
- Util.shuffle(list, this.shuffleRandom);
|
||||
+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled
|
||||
// Paper end - chunk tick iteration optimisation
|
||||
profiler.popPush("tickSpawningChunks");
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 02fb30a3adf92de0795aee213caf94a228b01ca0..67f6e40216e0be063a3cfb61427f095f7c74d785 100644
|
||||
index 8e7ee4dc951eb53ccf65ab71214a0b89bd932ba0..73a450e045eba5dbfc7a4e861e4c614c8f60d6b4 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -375,6 +375,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -403,6 +403,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
public boolean queueHealthUpdatePacket;
|
||||
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
public @Nullable net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
// Paper end - cancellable death event
|
||||
+ // Paper start - Optional per player mob spawns
|
||||
+ public static final int MOBCATEGORY_TOTAL_ENUMS = net.minecraft.world.entity.MobCategory.values().length;
|
||||
@@ -93,10 +93,10 @@ index 02fb30a3adf92de0795aee213caf94a228b01ca0..67f6e40216e0be063a3cfb61427f095f
|
||||
public org.bukkit.craftbukkit.entity.CraftPlayer.TransferCookieConnection transferCookieConnection;
|
||||
public String displayName;
|
||||
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
|
||||
index 913ea92ace9d610c25bf28f703a3b227044aea63..ef8bacbbb43a9b80281a313ca43b7efff5a93e03 100644
|
||||
index 3a864c568cd66a680760bb4df2cb020e323e9a9d..c710e08ab48075ce7854e56826adb8f0364b025b 100644
|
||||
--- a/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -72,6 +72,14 @@ public final class NaturalSpawner {
|
||||
@@ -66,6 +66,14 @@ public final class NaturalSpawner {
|
||||
public static NaturalSpawner.SpawnState createState(
|
||||
int spawnableChunkCount, Iterable<Entity> entities, NaturalSpawner.ChunkGetter chunkGetter, LocalMobCapCalculator calculator
|
||||
) {
|
||||
@@ -111,7 +111,7 @@ index 913ea92ace9d610c25bf28f703a3b227044aea63..ef8bacbbb43a9b80281a313ca43b7eff
|
||||
PotentialCalculator potentialCalculator = new PotentialCalculator();
|
||||
Object2IntOpenHashMap<MobCategory> map = new Object2IntOpenHashMap<>();
|
||||
|
||||
@@ -93,11 +101,16 @@ public final class NaturalSpawner {
|
||||
@@ -87,11 +95,16 @@ public final class NaturalSpawner {
|
||||
potentialCalculator.addCharge(entity.blockPosition(), mobSpawnCost.charge());
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ index 913ea92ace9d610c25bf28f703a3b227044aea63..ef8bacbbb43a9b80281a313ca43b7eff
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -135,7 +148,7 @@ public final class NaturalSpawner {
|
||||
@@ -129,7 +142,7 @@ public final class NaturalSpawner {
|
||||
if ((spawnFriendlies || !mobCategory.isFriendly())
|
||||
&& (spawnEnemies || mobCategory.isFriendly())
|
||||
&& (spawnPassives || !mobCategory.isPersistent())
|
||||
@@ -138,7 +138,7 @@ index 913ea92ace9d610c25bf28f703a3b227044aea63..ef8bacbbb43a9b80281a313ca43b7eff
|
||||
list.add(mobCategory);
|
||||
// CraftBukkit end
|
||||
}
|
||||
@@ -149,8 +162,37 @@ public final class NaturalSpawner {
|
||||
@@ -143,8 +156,37 @@ public final class NaturalSpawner {
|
||||
profilerFiller.push("spawner");
|
||||
|
||||
for (MobCategory mobCategory : categories) {
|
||||
@@ -150,8 +150,8 @@ index 913ea92ace9d610c25bf28f703a3b227044aea63..ef8bacbbb43a9b80281a313ca43b7eff
|
||||
+ if (level.paperConfig().entities.spawning.perPlayerMobSpawns) {
|
||||
+ // Copied from getFilteredSpawningCategories
|
||||
+ int limit = mobCategory.getMaxInstancesPerChunk();
|
||||
+ SpawnCategory spawnCategory = CraftSpawnCategory.toBukkit(mobCategory);
|
||||
+ if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
|
||||
+ org.bukkit.entity.SpawnCategory spawnCategory = org.bukkit.craftbukkit.util.CraftSpawnCategory.toBukkit(mobCategory);
|
||||
+ if (org.bukkit.craftbukkit.util.CraftSpawnCategory.isValidForLimits(spawnCategory)) {
|
||||
+ limit = level.getWorld().getSpawnLimit(spawnCategory);
|
||||
+ }
|
||||
+
|
||||
@@ -178,7 +178,7 @@ index 913ea92ace9d610c25bf28f703a3b227044aea63..ef8bacbbb43a9b80281a313ca43b7eff
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,9 +212,16 @@ public final class NaturalSpawner {
|
||||
@@ -164,9 +206,16 @@ public final class NaturalSpawner {
|
||||
public static void spawnCategoryForChunk(
|
||||
MobCategory category, ServerLevel level, LevelChunk chunk, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback
|
||||
) {
|
||||
@@ -196,7 +196,7 @@ index 913ea92ace9d610c25bf28f703a3b227044aea63..ef8bacbbb43a9b80281a313ca43b7eff
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,6 +238,12 @@ public final class NaturalSpawner {
|
||||
@@ -183,6 +232,12 @@ public final class NaturalSpawner {
|
||||
NaturalSpawner.SpawnPredicate filter,
|
||||
NaturalSpawner.AfterSpawnCallback callback
|
||||
) {
|
||||
@@ -209,7 +209,7 @@ index 913ea92ace9d610c25bf28f703a3b227044aea63..ef8bacbbb43a9b80281a313ca43b7eff
|
||||
StructureManager structureManager = level.structureManager();
|
||||
ChunkGenerator generator = level.getChunkSource().getGenerator();
|
||||
int y = pos.getY();
|
||||
@@ -252,9 +307,14 @@ public final class NaturalSpawner {
|
||||
@@ -247,9 +302,14 @@ public final class NaturalSpawner {
|
||||
++i;
|
||||
++i3;
|
||||
callback.run(mobForSpawn, chunk);
|
||||
@@ -225,7 +225,7 @@ index 913ea92ace9d610c25bf28f703a3b227044aea63..ef8bacbbb43a9b80281a313ca43b7eff
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -565,7 +625,7 @@ public final class NaturalSpawner {
|
||||
@@ -563,7 +623,7 @@ public final class NaturalSpawner {
|
||||
this.spawnPotential.addCharge(blockPos, d);
|
||||
MobCategory category = type.getCategory();
|
||||
this.mobCategoryCounts.addTo(category, 1);
|
@@ -6,10 +6,10 @@ Subject: [PATCH] Improve cancelling PreCreatureSpawnEvent with per player mob
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 9eed24939fc09f00a9dbce1be2ab9c34d024fd29..b3f498558614243cf633dcd71e3c49c2c55e6e0f 100644
|
||||
index 4f4bcc4bbfcc9b191d12d667b8fc1e644a9d5957..0d8aefe8c886eaa4c33cbab53b0ad1c016f0531f 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -255,8 +255,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -262,8 +262,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ index 9eed24939fc09f00a9dbce1be2ab9c34d024fd29..b3f498558614243cf633dcd71e3c49c2
|
||||
// Paper end - Optional per player mob spawns
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 5576bf1d1d70ab7a010653d3207909b5de867e70..6540b2d6a1062d883811ce240c49d30d1925b291 100644
|
||||
index f863377a807b672f49f7140688f378eca2cf650b..59e8a5e1b35c81883c9b1ca00c6e55d77584d8cc 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -576,7 +576,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
@@ -546,7 +546,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
|
||||
// re-set mob counts
|
||||
for (ServerPlayer player : this.level.players) {
|
||||
@@ -60,10 +60,10 @@ index 5576bf1d1d70ab7a010653d3207909b5de867e70..6540b2d6a1062d883811ce240c49d30d
|
||||
spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true);
|
||||
} else {
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 67f6e40216e0be063a3cfb61427f095f7c74d785..3de65c4025be91d938a350c884975cb6edc234d3 100644
|
||||
index 73a450e045eba5dbfc7a4e861e4c614c8f60d6b4..105d6b3a40067f9e8ae5bbd9f2872171f73b3d07 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -379,6 +379,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -407,6 +407,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
public static final int MOBCATEGORY_TOTAL_ENUMS = net.minecraft.world.entity.MobCategory.values().length;
|
||||
public final int[] mobCounts = new int[MOBCATEGORY_TOTAL_ENUMS];
|
||||
// Paper end - Optional per player mob spawns
|
||||
@@ -72,10 +72,10 @@ index 67f6e40216e0be063a3cfb61427f095f7c74d785..3de65c4025be91d938a350c884975cb6
|
||||
public org.bukkit.craftbukkit.entity.CraftPlayer.TransferCookieConnection transferCookieConnection;
|
||||
public String displayName;
|
||||
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
|
||||
index ef8bacbbb43a9b80281a313ca43b7efff5a93e03..17ce115e887cbbb06ad02ab7ddb488e27342c0e4 100644
|
||||
index 17b13baa3465530b11ff918c806c772eb5c39a2c..afd6da5c361e1dcf311a9afe8a7efe2faef2556a 100644
|
||||
--- a/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -285,6 +285,11 @@ public final class NaturalSpawner {
|
||||
@@ -279,6 +279,11 @@ public final class NaturalSpawner {
|
||||
|
||||
// Paper start - PreCreatureSpawnEvent
|
||||
PreSpawnStatus doSpawning = isValidSpawnPostitionForType(level, category, structureManager, generator, spawnerData, mutableBlockPos, d2);
|
@@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..24a2090e068ad3c0d08705050944abdf
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index cc2d442682496197d29ace79b22e6cf6fb7edf5e..ae220a732c78ab076261f20b5a54c71d7fceb407 100644
|
||||
index ea85cac4a41075efe8525c40755e7ebac6ca9dea..7af29d3dc7b337d74cee5df7cbca35c420643370 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1708,6 +1708,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1706,6 +1706,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
serverLevel.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
|
||||
serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent
|
||||
serverLevel.updateLagCompensationTick(); // Paper - lag compensation
|
||||
@@ -60,10 +60,10 @@ index cc2d442682496197d29ace79b22e6cf6fb7edf5e..ae220a732c78ab076261f20b5a54c71d
|
||||
/* Drop global time updates
|
||||
if (this.tickCount % 20 == 0) {
|
||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||
index b393be76bead3c66ab0bd8a0e6fd9b9ef81d8e28..76f50437396f8f856381d0fbef52953ef7c263f6 100644
|
||||
index 5329dc9259f30011d277336bfc76da18c15d5d81..8391f51b7dd584dd346bda5dccbee900d4fa9c2d 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -827,10 +827,16 @@ public final class ItemStack implements DataComponentHolder {
|
||||
@@ -832,10 +832,16 @@ public final class ItemStack implements DataComponentHolder {
|
||||
}
|
||||
|
||||
public ItemStack copy() {
|
||||
@@ -83,18 +83,18 @@ index b393be76bead3c66ab0bd8a0e6fd9b9ef81d8e28..76f50437396f8f856381d0fbef52953e
|
||||
return itemStack;
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
index 2ebdf1ad323bb53dfe9eed319e25856b35a1443c..77618757c0e678532dbab814aceed83f7f1cd892 100644
|
||||
index 7783ff94e5183737d01c75c521b70b4fbd8c34a6..a1075c26d55cc01219acd94d0138f81aa9d34c48 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
@@ -26,6 +26,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -33,6 +33,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class BlockEntity {
|
||||
+ static boolean ignoreBlockEntityUpdates; // Paper - Perf: Optimize Hoppers
|
||||
// CraftBukkit start - data containers
|
||||
private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
|
||||
public org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer;
|
||||
@@ -196,6 +197,7 @@ public abstract class BlockEntity {
|
||||
public final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer;
|
||||
@@ -202,6 +203,7 @@ public abstract class BlockEntity {
|
||||
|
||||
public void setChanged() {
|
||||
if (this.level != null) {
|
||||
@@ -103,10 +103,10 @@ index 2ebdf1ad323bb53dfe9eed319e25856b35a1443c..77618757c0e678532dbab814aceed83f
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78fa880b4cd 100644
|
||||
index 9a03934dd4d96184f37b9ff5661eb7bd76150464..15d4f60942c0cc612c1468b4c0fda886867a67cb 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -139,18 +139,56 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -143,18 +143,56 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78f
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
@@ -174,6 +212,206 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -178,6 +216,206 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78f
|
||||
private static boolean ejectItems(Level level, BlockPos pos, HopperBlockEntity blockEntity) {
|
||||
Container attachedContainer = getAttachedContainer(level, pos, blockEntity);
|
||||
if (attachedContainer == null) {
|
||||
@@ -183,57 +421,60 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -187,57 +425,60 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
if (isFullContainer(attachedContainer, opposite)) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -485,7 +485,7 @@ index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78f
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,6 +529,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -292,6 +533,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
Container sourceContainer = getSourceContainer(level, hopper, blockPos, blockState);
|
||||
if (sourceContainer != null) {
|
||||
Direction direction = Direction.DOWN;
|
||||
@@ -493,7 +493,7 @@ index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78f
|
||||
|
||||
for (int i : getSlots(sourceContainer, direction)) {
|
||||
if (tryTakeInItemFromSlot(hopper, sourceContainer, i, direction, level)) { // Spigot
|
||||
@@ -313,55 +555,58 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -317,55 +559,58 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
private static boolean tryTakeInItemFromSlot(Hopper hopper, Container container, int slot, Direction direction, Level level) { // Spigot
|
||||
ItemStack item = container.getItem(slot);
|
||||
if (!item.isEmpty() && canTakeItemFromContainer(hopper, container, item, slot, direction)) {
|
||||
@@ -601,7 +601,7 @@ index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78f
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -370,13 +615,15 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -374,13 +619,15 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
public static boolean addItem(Container container, ItemEntity item) {
|
||||
boolean flag = false;
|
||||
// CraftBukkit start
|
||||
@@ -618,7 +618,7 @@ index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78f
|
||||
ItemStack itemStack = item.getItem().copy();
|
||||
ItemStack itemStack1 = addItem(null, container, itemStack, null);
|
||||
if (itemStack1.isEmpty()) {
|
||||
@@ -431,7 +678,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -435,7 +682,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
stack = stack.split(destination.getMaxStackSize());
|
||||
}
|
||||
// Spigot end
|
||||
@@ -628,7 +628,7 @@ index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78f
|
||||
stack = leftover; // Paper - Make hoppers respect inventory max stack size
|
||||
flag = true;
|
||||
} else if (canMergeItems(item, stack)) {
|
||||
@@ -519,13 +768,19 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -523,13 +772,19 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
|
||||
@Nullable
|
||||
public static Container getContainerAt(Level level, BlockPos pos) {
|
||||
@@ -650,7 +650,7 @@ index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78f
|
||||
blockContainer = getEntityContainer(level, x, y, z);
|
||||
}
|
||||
|
||||
@@ -551,14 +806,14 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -555,14 +810,14 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
|
||||
@Nullable
|
||||
private static Container getEntityContainer(Level level, double x, double y, double z) {
|
||||
@@ -669,10 +669,10 @@ index e58a32593e8b42bfc534d13457240860293dd3f4..5cd1326ad5d046c88b2b3449d610a78f
|
||||
|
||||
@Override
|
||||
diff --git a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
index 73b3ddb120d6b6f89e478960e78bed415baea205..f9c31da81d84033abfc1179fc643bceffe35da17 100644
|
||||
index 1c98d003907feb16de8f26377fceedf728afe7fb..eed5f8f912544b79c8ed54dcdc5eeacb6dcfaccd 100644
|
||||
--- a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
@@ -53,7 +53,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
|
||||
@@ -54,7 +54,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int index) {
|
@@ -6,27 +6,27 @@ Subject: [PATCH] Optimise collision checking in player move packet handling
|
||||
Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 12c83cb084563a4e3f7f357d8b600941544ef2b0..90e582ca30851857add5e2d830e9876667fd1807 100644
|
||||
index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062b48d43fa 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -563,7 +563,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -555,7 +555,7 @@ public class ServerGamePacketListenerImpl
|
||||
return;
|
||||
}
|
||||
|
||||
- boolean flag = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
|
||||
+ AABB oldBox = rootVehicle.getBoundingBox(); // Paper - copy from player movement packet
|
||||
+ final AABB oldBox = rootVehicle.getBoundingBox(); // Paper - copy from player movement packet
|
||||
d3 = d - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
d4 = d1 - this.vehicleLastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
d5 = d2 - this.vehicleLastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
@@ -573,6 +573,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -565,6 +565,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
rootVehicle.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
|
||||
+ boolean didCollide = toX != rootVehicle.getX() || toY != rootVehicle.getY() || toZ != rootVehicle.getZ(); // Paper - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be...
|
||||
double verticalDelta = d4; // Paper - Decompile fix, was named d11 previously, is now gone in the source
|
||||
+ final boolean didCollide = toX != rootVehicle.getX() || toY != rootVehicle.getY() || toZ != rootVehicle.getZ(); // Paper - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be...
|
||||
double verticalDelta = d4; // Paper - Decompile fix: lvt reassignment lost
|
||||
d3 = d - rootVehicle.getX();
|
||||
d4 = d1 - rootVehicle.getY();
|
||||
@@ -584,14 +585,22 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -576,14 +577,22 @@ public class ServerGamePacketListenerImpl
|
||||
d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
boolean flag2 = false;
|
||||
if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
|
||||
@@ -35,24 +35,24 @@ index 12c83cb084563a4e3f7f357d8b600941544ef2b0..90e582ca30851857add5e2d830e98766
|
||||
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
|
||||
}
|
||||
|
||||
rootVehicle.absMoveTo(d, d1, d2, f, f1);
|
||||
this.player.absMoveTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
rootVehicle.absSnapTo(d, d1, d2, f, f1);
|
||||
this.player.absSnapTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
- boolean flag3 = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
|
||||
- if (flag && (flag2 || !flag3)) {
|
||||
+ // Paper start - optimise out extra getCubes
|
||||
+ boolean teleportBack = flag2; // violating this is always a fail
|
||||
+ if (!teleportBack) {
|
||||
+ // note: only call after setLocation, or else getBoundingBox is wrong
|
||||
+ AABB newBox = rootVehicle.getBoundingBox();
|
||||
+ final AABB newBox = rootVehicle.getBoundingBox();
|
||||
+ if (didCollide || !oldBox.equals(newBox)) {
|
||||
+ teleportBack = this.hasNewCollision(serverLevel, rootVehicle, oldBox, newBox);
|
||||
+ } // else: no collision at all detected, why do we care?
|
||||
+ }
|
||||
+ if (teleportBack) { // Paper end - optimise out extra getCubes
|
||||
rootVehicle.absMoveTo(x, y, z, f, f1);
|
||||
this.player.absMoveTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
rootVehicle.absSnapTo(x, y, z, f, f1);
|
||||
this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle));
|
||||
@@ -669,9 +678,32 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -661,9 +670,32 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
private boolean noBlocksAround(Entity entity) {
|
||||
@@ -60,22 +60,22 @@ index 12c83cb084563a4e3f7f357d8b600941544ef2b0..90e582ca30851857add5e2d830e98766
|
||||
- .getBlockStates(entity.getBoundingBox().inflate(0.0625).expandTowards(0.0, -0.55, 0.0))
|
||||
- .allMatch(BlockBehaviour.BlockStateBase::isAir);
|
||||
+ // Paper start - stop using streams, this is already a known fixed problem in Entity#move
|
||||
+ AABB box = entity.getBoundingBox().inflate(0.0625).expandTowards(0.0, -0.55, 0.0);
|
||||
+ int minX = Mth.floor(box.minX);
|
||||
+ int minY = Mth.floor(box.minY);
|
||||
+ int minZ = Mth.floor(box.minZ);
|
||||
+ int maxX = Mth.floor(box.maxX);
|
||||
+ int maxY = Mth.floor(box.maxY);
|
||||
+ int maxZ = Mth.floor(box.maxZ);
|
||||
+ final AABB box = entity.getBoundingBox().inflate(0.0625).expandTowards(0.0, -0.55, 0.0);
|
||||
+ final int minX = Mth.floor(box.minX);
|
||||
+ final int minY = Mth.floor(box.minY);
|
||||
+ final int minZ = Mth.floor(box.minZ);
|
||||
+ final int maxX = Mth.floor(box.maxX);
|
||||
+ final int maxY = Mth.floor(box.maxY);
|
||||
+ final int maxZ = Mth.floor(box.maxZ);
|
||||
+
|
||||
+ Level level = entity.level();
|
||||
+ BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
|
||||
+ final Level level = entity.level();
|
||||
+ final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
|
||||
+
|
||||
+ for (int y = minY; y <= maxY; ++y) {
|
||||
+ for (int z = minZ; z <= maxZ; ++z) {
|
||||
+ for (int x = minX; x <= maxX; ++x) {
|
||||
+ pos.set(x, y, z);
|
||||
+ BlockState blockState = level.getBlockStateIfLoaded(pos);
|
||||
+ final BlockState blockState = level.getBlockStateIfLoaded(pos);
|
||||
+ if (blockState != null && !blockState.isAir()) {
|
||||
+ return false;
|
||||
+ }
|
||||
@@ -88,43 +88,43 @@ index 12c83cb084563a4e3f7f357d8b600941544ef2b0..90e582ca30851857add5e2d830e98766
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1371,7 +1403,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1430,7 +1462,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- AABB boundingBox = this.player.getBoundingBox();
|
||||
+ AABB boundingBox = this.player.getBoundingBox(); // Paper - diff on change, should be old AABB
|
||||
d3 = d - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
d4 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
d5 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
@@ -1410,6 +1442,7 @@ public class ServerGamePacketListenerImpl
|
||||
boolean flag1 = this.player.verticalCollisionBelow;
|
||||
this.player.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
|
||||
this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
|
||||
+ boolean didCollide = toX != this.player.getX() || toY != this.player.getY() || toZ != this.player.getZ(); // Paper - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be...
|
||||
// Paper start - prevent position desync
|
||||
if (this.awaitingPositionFromClient != null) {
|
||||
return; // ... thanks Mojang for letting move calls teleport across dimensions.
|
||||
@@ -1442,7 +1475,17 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
- AABB boundingBox = this.player.getBoundingBox();
|
||||
+ AABB boundingBox = this.player.getBoundingBox(); // Paper - diff on change, should be old AABB
|
||||
d3 = d - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
d4 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
d5 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
@@ -1469,6 +1501,7 @@ public class ServerGamePacketListenerImpl
|
||||
boolean flag1 = this.player.verticalCollisionBelow;
|
||||
this.player.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
|
||||
this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
|
||||
+ final boolean didCollide = toX != this.player.getX() || toY != this.player.getY() || toZ != this.player.getZ(); // Paper - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be...
|
||||
// Paper start - prevent position desync
|
||||
if (this.awaitingPositionFromClient != null) {
|
||||
return; // ... thanks Mojang for letting move calls teleport across dimensions.
|
||||
@@ -1501,7 +1534,17 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
// Paper start - Add fail move event
|
||||
- boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && serverLevel.noCollision(this.player, boundingBox) || this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2));
|
||||
+ // Paper start - optimise out extra getCubes
|
||||
+ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && movedWrongly;
|
||||
+ this.player.absMoveTo(d, d1, d2, f, f1); // prevent desync by tping to the set position, dropped for unknown reasons by mojang
|
||||
+ if (!this.player.noPhysics && !this.player.isSleeping() && !teleportBack) {
|
||||
+ AABB newBox = this.player.getBoundingBox();
|
||||
+ if (didCollide || !boundingBox.equals(newBox)) {
|
||||
+ // note: only call after setLocation, or else getBoundingBox is wrong
|
||||
+ teleportBack = this.hasNewCollision(serverLevel, this.player, boundingBox, newBox);
|
||||
+ } // else: no collision at all detected, why do we care?
|
||||
+ }
|
||||
+ // Paper end - optimise out extra getCubes
|
||||
if (teleportBack) {
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
|
||||
toX, toY, toZ, toYaw, toPitch, false);
|
||||
@@ -1578,7 +1621,7 @@ public class ServerGamePacketListenerImpl
|
||||
// Paper start - Add fail move event
|
||||
- boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && serverLevel.noCollision(this.player, boundingBox) || this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2));
|
||||
+ // Paper start - optimise out extra getCubes
|
||||
+ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && movedWrongly;
|
||||
+ this.player.absSnapTo(d, d1, d2, f, f1); // prevent desync by tping to the set position, dropped for unknown reasons by mojang
|
||||
+ if (!this.player.noPhysics && !this.player.isSleeping() && !teleportBack) {
|
||||
+ final AABB newBox = this.player.getBoundingBox();
|
||||
+ if (didCollide || !boundingBox.equals(newBox)) {
|
||||
+ // note: only call after setLocation, or else getBoundingBox is wrong
|
||||
+ teleportBack = this.hasNewCollision(serverLevel, this.player, boundingBox, newBox);
|
||||
+ } // else: no collision at all detected, why do we care?
|
||||
+ }
|
||||
+ // Paper end - optimise out extra getCubes
|
||||
if (teleportBack) {
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
|
||||
toX, toY, toZ, toYaw, toPitch, false);
|
||||
@@ -1638,7 +1681,7 @@ public class ServerGamePacketListenerImpl
|
||||
|
||||
private boolean updateAwaitingTeleport() {
|
||||
if (this.awaitingPositionFromClient != null) {
|
||||
@@ -133,7 +133,7 @@ index 12c83cb084563a4e3f7f357d8b600941544ef2b0..90e582ca30851857add5e2d830e98766
|
||||
this.awaitingTeleportTime = this.tickCount;
|
||||
this.teleport(
|
||||
this.awaitingPositionFromClient.x,
|
||||
@@ -1597,6 +1640,33 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1657,6 +1700,33 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,34 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 2 Feb 2025 10:57:48 -0800
|
||||
Subject: [PATCH] Do not record movement for vehicles/players unaffected by
|
||||
blocks
|
||||
|
||||
If the player is not affected by movement through blocks, then
|
||||
storing the movement would eventually invoke logic to apply effects
|
||||
caused by moving through such blocks. For example, moving through
|
||||
a portal in spectator mode and then later switching to creative mode
|
||||
would portal the player.
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 90e582ca30851857add5e2d830e9876667fd1807..c569cdfa4cba4f65892ffd4045c611837049f440 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -659,7 +659,7 @@ public class ServerGamePacketListenerImpl
|
||||
// CraftBukkit end
|
||||
|
||||
this.player.serverLevel().getChunkSource().move(this.player);
|
||||
- rootVehicle.recordMovementThroughBlocks(new Vec3(x, y, z), rootVehicle.position());
|
||||
+ if (!rootVehicle.isSpectator() && rootVehicle.isAffectedByBlocks()) rootVehicle.recordMovementThroughBlocks(new Vec3(x, y, z), rootVehicle.position()); // Paper - Do not record movement for vehicles/players unaffected by blocks
|
||||
Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z);
|
||||
this.handlePlayerKnownMovement(vec3);
|
||||
rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3);
|
||||
@@ -1577,7 +1577,7 @@ public class ServerGamePacketListenerImpl
|
||||
Vec3 vec3 = new Vec3(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z);
|
||||
this.player.setOnGroundWithMovement(packet.isOnGround(), packet.horizontalCollision(), vec3);
|
||||
this.player.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.isOnGround());
|
||||
- this.player.recordMovementThroughBlocks(new Vec3(x, y, z), this.player.position());
|
||||
+ if (!this.player.isSpectator() && this.player.isAffectedByBlocks()) this.player.recordMovementThroughBlocks(new Vec3(x, y, z), this.player.position()); // Paper - Do not record movement for vehicles/players unaffected by blocks
|
||||
this.handlePlayerKnownMovement(vec3);
|
||||
if (flag) {
|
||||
this.player.resetFallDistance();
|
@@ -1,6 +1,6 @@
|
||||
--- /dev/null
|
||||
+++ b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
|
||||
@@ -1,0 +_,332 @@
|
||||
@@ -1,0 +_,330 @@
|
||||
+package ca.spottedleaf.moonrise.paper.util;
|
||||
+
|
||||
+import ca.spottedleaf.concurrentutil.util.Priority;
|
||||
@@ -28,7 +28,7 @@
|
||||
+
|
||||
+ private static final Logger LOGGER = LogUtils.getLogger();
|
||||
+ private static final ChunkStep FULL_CHUNK_STEP = ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL);
|
||||
+ private static final TicketType<Long> CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo);
|
||||
+ private static final TicketType CHUNK_LOAD = TicketType.CHUNK_LOAD;
|
||||
+
|
||||
+ private long chunkLoadCounter = 0L;
|
||||
+
|
||||
@@ -82,11 +82,10 @@
|
||||
+ }
|
||||
+
|
||||
+ final int minLevel = 33 + getDistance(toStatus);
|
||||
+ final Long chunkReference = addTicket ? Long.valueOf(++this.chunkLoadCounter) : null;
|
||||
+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
|
||||
+
|
||||
+ if (addTicket) {
|
||||
+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel);
|
||||
+ }
|
||||
+ level.chunkSource.runDistanceManagerUpdates();
|
||||
+
|
||||
@@ -100,8 +99,8 @@
|
||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(thr);
|
||||
+ } finally {
|
||||
+ if (addTicket) {
|
||||
+ level.chunkSource.addTicketAtLevel(net.minecraft.server.level.TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
|
||||
+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
+ level.chunkSource.addTicketAtLevel(net.minecraft.server.level.TicketType.UNKNOWN, chunkPos, minLevel);
|
||||
+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel);
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
@@ -149,11 +148,10 @@
|
||||
+
|
||||
+ final int minLevel = 33 - (toStatus.ordinal() - 1);
|
||||
+ final int radius = toStatus.ordinal() - 1;
|
||||
+ final Long chunkReference = addTicket ? Long.valueOf(++this.chunkLoadCounter) : null;
|
||||
+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
|
||||
+
|
||||
+ if (addTicket) {
|
||||
+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel);
|
||||
+ }
|
||||
+ level.chunkSource.runDistanceManagerUpdates();
|
||||
+
|
||||
@@ -167,8 +165,8 @@
|
||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(thr);
|
||||
+ } finally {
|
||||
+ if (addTicket) {
|
||||
+ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
|
||||
+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
+ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel);
|
||||
+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel);
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
|
@@ -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,9 +1,10 @@
|
||||
--- a/com/mojang/logging/LogUtils.java
|
||||
+++ b/com/mojang/logging/LogUtils.java
|
||||
@@ -61,4 +_,9 @@
|
||||
@@ -61,4 +_,10 @@
|
||||
public static Logger getLogger() {
|
||||
return LoggerFactory.getLogger(STACK_WALKER.getCallerClass());
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public static Logger getClassLogger() {
|
||||
+ return LoggerFactory.getLogger(STACK_WALKER.getCallerClass().getSimpleName());
|
||||
|
@@ -1,28 +1,34 @@
|
||||
--- 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());
|
||||
+ this.initializeRotationDirections(); // Paper - Avoid Lazy Initialization for Enum Fields
|
||||
}
|
||||
@@ -123,6 +_,12 @@
|
||||
}
|
||||
);
|
||||
|
||||
private BooleanList packInversions() {
|
||||
@@ -139,7 +_,7 @@
|
||||
+ static {
|
||||
+ for (OctahedralGroup octahedralGroup : values()) {
|
||||
+ octahedralGroup.initializeRotationDirections(); // Paper - Avoid Lazy Initialization for Enum Fields
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private OctahedralGroup(final String name, final SymmetricGroup3 permutation, final boolean invertX, final boolean invertY, final boolean invertZ) {
|
||||
this.name = name;
|
||||
this.invertX = invertX;
|
||||
@@ -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 @@
|
||||
--- /dev/null
|
||||
+++ b/io/papermc/paper/FeatureHooks.java
|
||||
@@ -1,0 +_,234 @@
|
||||
@@ -1,0 +_,238 @@
|
||||
+package io.papermc.paper;
|
||||
+
|
||||
+import io.papermc.paper.command.PaperSubcommand;
|
||||
@@ -139,16 +139,16 @@
|
||||
+ public static java.util.Collection<org.bukkit.plugin.Plugin> getPluginChunkTickets(net.minecraft.server.level.ServerLevel world,
|
||||
+ int x, int z) {
|
||||
+ net.minecraft.server.level.DistanceManager chunkDistanceManager = world.getChunkSource().chunkMap.distanceManager;
|
||||
+ net.minecraft.util.SortedArraySet<net.minecraft.server.level.Ticket<?>> tickets = chunkDistanceManager.tickets.get(ChunkPos.asLong(x, z));
|
||||
+ List<net.minecraft.server.level.Ticket> tickets = chunkDistanceManager.ticketStorage.tickets.get(ChunkPos.asLong(x, z));
|
||||
+
|
||||
+ if (tickets == null) {
|
||||
+ return java.util.Collections.emptyList();
|
||||
+ }
|
||||
+
|
||||
+ com.google.common.collect.ImmutableList.Builder<org.bukkit.plugin.Plugin> ret = com.google.common.collect.ImmutableList.builder();
|
||||
+ for (net.minecraft.server.level.Ticket<?> ticket : tickets) {
|
||||
+ for (net.minecraft.server.level.Ticket ticket : tickets) {
|
||||
+ if (ticket.getType() == net.minecraft.server.level.TicketType.PLUGIN_TICKET) {
|
||||
+ ret.add((org.bukkit.plugin.Plugin) ticket.key);
|
||||
+ ret.add((org.bukkit.plugin.Plugin) ticket.getIdentifier());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
@@ -159,12 +159,12 @@
|
||||
+ Map<org.bukkit.plugin.Plugin, com.google.common.collect.ImmutableList.Builder<Chunk>> ret = new HashMap<>();
|
||||
+ net.minecraft.server.level.DistanceManager chunkDistanceManager = world.getChunkSource().chunkMap.distanceManager;
|
||||
+
|
||||
+ for (it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry<net.minecraft.util.SortedArraySet<net.minecraft.server.level.Ticket<?>>> chunkTickets : chunkDistanceManager.tickets.long2ObjectEntrySet()) {
|
||||
+ for (it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry<List<net.minecraft.server.level.Ticket>> chunkTickets : chunkDistanceManager.ticketStorage.tickets.long2ObjectEntrySet()) {
|
||||
+ long chunkKey = chunkTickets.getLongKey();
|
||||
+ net.minecraft.util.SortedArraySet<net.minecraft.server.level.Ticket<?>> tickets = chunkTickets.getValue();
|
||||
+ List<net.minecraft.server.level.Ticket> tickets = chunkTickets.getValue();
|
||||
+
|
||||
+ org.bukkit.Chunk chunk = null;
|
||||
+ for (net.minecraft.server.level.Ticket<?> ticket : tickets) {
|
||||
+ for (net.minecraft.server.level.Ticket ticket : tickets) {
|
||||
+ if (ticket.getType() != net.minecraft.server.level.TicketType.PLUGIN_TICKET) {
|
||||
+ continue;
|
||||
+ }
|
||||
@@ -173,7 +173,7 @@
|
||||
+ chunk = world.getWorld().getChunkAt(ChunkPos.getX(chunkKey), ChunkPos.getZ(chunkKey));
|
||||
+ }
|
||||
+
|
||||
+ ret.computeIfAbsent((org.bukkit.plugin.Plugin) ticket.key, (key) -> com.google.common.collect.ImmutableList.builder()).add(chunk);
|
||||
+ ret.computeIfAbsent((org.bukkit.plugin.Plugin) ticket.getIdentifier(), (key) -> com.google.common.collect.ImmutableList.builder()).add(chunk);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
@@ -215,7 +215,11 @@
|
||||
+ }
|
||||
+
|
||||
+ public static void closeEntityManager(net.minecraft.server.level.ServerLevel world, boolean save) {
|
||||
+ world.entityManager.close(save);
|
||||
+ try {
|
||||
+ world.entityManager.close(save);
|
||||
+ } catch (final java.io.IOException exception) {
|
||||
+ throw new RuntimeException("Failed to close entity manager", exception);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static java.util.concurrent.Executor getWorldgenExecutor() {
|
||||
|
@@ -1,14 +1,14 @@
|
||||
--- 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));
|
||||
}
|
||||
|
||||
+ // Paper start - add method to get by hex value
|
||||
+ @Nullable
|
||||
+ public static ChatFormatting getByHexValue(int i) {
|
||||
+ public static ChatFormatting getByHexValue(int color) {
|
||||
+ for (ChatFormatting value : values()) {
|
||||
+ if (value.getColor() != null && value.getColor() == i) {
|
||||
+ if (value.getColor() != null && value.getColor() == color) {
|
||||
+ return value;
|
||||
+ }
|
||||
+ }
|
||||
|
@@ -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) {
|
||||
|
@@ -18,11 +18,10 @@
|
||||
|
||||
public CommandSourceStack(
|
||||
CommandSource source,
|
||||
@@ -187,6 +_,30 @@
|
||||
this.chatMessageChainer
|
||||
@@ -188,6 +_,30 @@
|
||||
);
|
||||
}
|
||||
+
|
||||
|
||||
+ // Paper start - Expose 'with' functions from the CommandSourceStack
|
||||
+ @Override
|
||||
+ public CommandSourceStack withLocation(org.bukkit.Location location) {
|
||||
@@ -46,9 +45,10 @@
|
||||
+ );
|
||||
+ }
|
||||
+ // Paper end - Expose 'with' functions from the CommandSourceStack
|
||||
|
||||
+
|
||||
public CommandSourceStack withRotation(Vec2 rotation) {
|
||||
return this.rotation.equals(rotation)
|
||||
? this
|
||||
@@ -391,9 +_,44 @@
|
||||
|
||||
@Override
|
||||
@@ -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();
|
||||
}
|
||||
|
@@ -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
|
||||
));
|
||||
|
@@ -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.sanitizer.ItemObfuscationSession itemObfuscationSession = value.map.isEmpty()
|
||||
+ ? null // Avoid thread local lookup of current session if it won't be needed anyway.
|
||||
+ : io.papermc.paper.util.sanitizer.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.sanitizer.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.sanitizer.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 buffer, DataComponentType<T> component, Object value) {
|
||||
- codecGetter.apply(component).encode(buffer, (T)value);
|
||||
+ // Paper start - codec errors of random anonymous classes are useless
|
||||
+ try {
|
||||
+ codecGetter.apply(component).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
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -249,6 +_,42 @@
|
||||
|
||||
Builder() {
|
||||
}
|
||||
|
@@ -1,24 +1,24 @@
|
||||
--- 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(
|
||||
- "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(ChargedProjectiles.STREAM_CODEC).cacheEncoding()
|
||||
+ "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(io.papermc.paper.util.OversizedItemComponentSanitizer.CHARGED_PROJECTILES).cacheEncoding() // Paper - sanitize charged projectiles
|
||||
+ "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(io.papermc.paper.util.sanitizer.OversizedItemComponentSanitizer.CHARGED_PROJECTILES).cacheEncoding() // Paper - sanitize charged projectiles
|
||||
);
|
||||
public static final DataComponentType<BundleContents> BUNDLE_CONTENTS = register(
|
||||
- "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(BundleContents.STREAM_CODEC).cacheEncoding()
|
||||
+ "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(io.papermc.paper.util.OversizedItemComponentSanitizer.BUNDLE_CONTENTS).cacheEncoding() // Paper - sanitize bundle contents
|
||||
+ "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(io.papermc.paper.util.sanitizer.OversizedItemComponentSanitizer.BUNDLE_CONTENTS).cacheEncoding() // Paper - sanitize bundle contents
|
||||
);
|
||||
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(
|
||||
- "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(ItemContainerContents.STREAM_CODEC).cacheEncoding()
|
||||
+ "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(io.papermc.paper.util.OversizedItemComponentSanitizer.CONTAINER).cacheEncoding() // Paper - sanitize container contents
|
||||
+ "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(io.papermc.paper.util.sanitizer.OversizedItemComponentSanitizer.CONTAINER).cacheEncoding() // Paper - sanitize container contents
|
||||
);
|
||||
public static final DataComponentType<BlockItemStateProperties> BLOCK_STATE = register(
|
||||
"block_state", builder -> builder.persistent(BlockItemStateProperties.CODEC).networkSynchronized(BlockItemStateProperties.STREAM_CODEC).cacheEncoding()
|
||||
|
@@ -1,30 +1,27 @@
|
||||
--- a/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java
|
||||
@@ -40,13 +_,39 @@
|
||||
@@ -40,13 +_,36 @@
|
||||
d4 = 0.0;
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1); // Paper - shrink at end and single item in event
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1);
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, 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(d1, d2 + d4, d3));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // stack.grow(1); // Paper - shrink below
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true; // Paper
|
||||
+ boolean shrink = true;
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ shrink = false;
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
|
@@ -1,20 +1,11 @@
|
||||
--- a/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
|
||||
@@ -10,23 +_,46 @@
|
||||
@@ -9,24 +_,37 @@
|
||||
|
||||
public class DefaultDispenseItemBehavior implements DispenseItemBehavior {
|
||||
private static final int DEFAULT_ACCURACY = 6;
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ private Direction direction; // Paper - cache facing direction
|
||||
+ private boolean dropper;
|
||||
+
|
||||
+ public DefaultDispenseItemBehavior(boolean dropper) {
|
||||
+ this.dropper = dropper;
|
||||
+ }
|
||||
+
|
||||
+ public DefaultDispenseItemBehavior() {}
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
@Override
|
||||
public final ItemStack dispense(BlockSource blockSource, ItemStack item) {
|
||||
+ this.direction = blockSource.state().getValue(DispenserBlock.FACING); // Paper - cache facing direction
|
||||
@@ -32,7 +23,7 @@
|
||||
ItemStack itemStack = item.split(1);
|
||||
- spawnItem(blockSource.level(), itemStack, 6, direction, dispensePosition);
|
||||
+ // CraftBukkit start
|
||||
+ if (!DefaultDispenseItemBehavior.spawnItem(blockSource.level(), itemStack, 6, this.direction, dispensePosition, blockSource, this.dropper)) {
|
||||
+ if (!DefaultDispenseItemBehavior.spawnItem(blockSource.level(), itemStack, 6, this.direction, dispensePosition, blockSource)) {
|
||||
+ item.grow(1);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
@@ -50,37 +41,35 @@
|
||||
double d = position.x();
|
||||
double d1 = position.y();
|
||||
double d2 = position.z();
|
||||
@@ -43,7 +_,45 @@
|
||||
@@ -43,7 +_,43 @@
|
||||
level.random.triangle(0.2, 0.0172275 * speed),
|
||||
level.random.triangle(facing.getStepZ() * d3, 0.0172275 * speed)
|
||||
);
|
||||
+ return itemEntity; // CraftBukkit
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit - void -> boolean return, IPosition -> ISourceBlock last argument, dropper
|
||||
+ public static boolean spawnItem(Level level, ItemStack stack, int speed, Direction facing, Position dispensePosition, BlockSource blockSource, boolean dropper) {
|
||||
+ // CraftBukkit start - void -> boolean return
|
||||
+ public static boolean spawnItem(Level level, ItemStack stack, int speed, Direction facing, Position position, BlockSource blockSource) {
|
||||
+ if (stack.isEmpty()) return true;
|
||||
+ ItemEntity itemEntity = DefaultDispenseItemBehavior.prepareItem(level, stack, speed, facing, dispensePosition);
|
||||
+ ItemEntity itemEntity = DefaultDispenseItemBehavior.prepareItem(level, stack, speed, facing, position);
|
||||
+
|
||||
+ 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(stack);
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(itemEntity.getDeltaMovement()));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ itemEntity.setItem(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()));
|
||||
+ itemEntity.setDeltaMovement(org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getVelocity()));
|
||||
+ itemEntity.setDeltaMovement(org.bukkit.craftbukkit.util.CraftVector.toVec3(event.getVelocity()));
|
||||
+
|
||||
+ if (!dropper && !event.getItem().getType().equals(craftItem.getType())) {
|
||||
+ if (blockSource.state().is(net.minecraft.world.level.block.Blocks.DISPENSER) && !event.getItem().getType().equals(craftItem.getType())) {
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior.getClass() != DefaultDispenseItemBehavior.class) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ } else {
|
||||
|
@@ -1,31 +1,28 @@
|
||||
--- a/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
@@ -82,16 +_,48 @@
|
||||
@@ -83,16 +_,45 @@
|
||||
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
|
||||
EntityType<?> type = ((SpawnEggItem)item.getItem()).getType(blockSource.level().registryAccess(), item);
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ ServerLevel serverLevel = blockSource.level();
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1); // Paper - shrink below and single item in event
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1);
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, 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(0, 0, 0));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // item.grow(1); // Paper - shrink below
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true; // Paper
|
||||
+ boolean shrink = true;
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ shrink = false;
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
@@ -46,42 +43,40 @@
|
||||
}
|
||||
|
||||
- item.shrink(1);
|
||||
+ if (shrink) item.shrink(1); // Paper - actually handle here
|
||||
+ if (shrink) item.shrink(1);
|
||||
+ // CraftBukkit end
|
||||
blockSource.level().gameEvent(null, GameEvent.ENTITY_PLACE, blockSource.pos());
|
||||
return item;
|
||||
}
|
||||
@@ -109,12 +_,40 @@
|
||||
@@ -110,12 +_,38 @@
|
||||
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos blockPos = blockSource.pos().relative(direction);
|
||||
ServerLevel serverLevel = blockSource.level();
|
||||
+ // CraftBukkit start
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1); // Paper - shrink below and single item in event
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1);
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, 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(0, 0, 0));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // item.grow(1); // Paper - shrink below
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true; // Paper
|
||||
+ boolean shrink = true;
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ shrink = false;
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ final ItemStack newStack = org.bukkit.craftbukkit.inventory.CraftItemStack.unwrap(event.getItem()); // Paper - use event itemstack (unwrap is fine here because the stack won't be modified)
|
||||
Consumer<ArmorStand> consumer = EntityType.appendDefaultStackConfig(
|
||||
- armorStand1 -> armorStand1.setYRot(direction.toYRot()), serverLevel, item, null
|
||||
@@ -90,76 +85,37 @@
|
||||
ArmorStand armorStand = EntityType.ARMOR_STAND.spawn(serverLevel, consumer, blockPos, EntitySpawnReason.DISPENSER, false, false);
|
||||
if (armorStand != null) {
|
||||
- item.shrink(1);
|
||||
+ if (shrink) item.shrink(1); // Paper - actually handle here
|
||||
+ if (shrink) item.shrink(1); // Paper
|
||||
}
|
||||
|
||||
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 +_,35 @@
|
||||
new AABB(blockPos),
|
||||
abstractChestedHorse1 -> abstractChestedHorse1.isAlive() && !abstractChestedHorse1.hasChest()
|
||||
)) {
|
||||
- if (abstractChestedHorse.isTamed() && abstractChestedHorse.getSlot(499).set(item)) {
|
||||
- item.shrink(1);
|
||||
+ if (abstractChestedHorse.isTamed()/* && abstractChestedHorse.getSlot(499).set(item)*/) {
|
||||
+ ItemStack singleCopy = item.copyWithCount(1); // Paper - shrink below
|
||||
+ // CraftBukkit start
|
||||
+ ItemStack singleCopy = item.copyWithCount(1);
|
||||
+ 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(singleCopy);
|
||||
+ org.bukkit.event.block.BlockDispenseArmorEvent event = new org.bukkit.event.block.BlockDispenseArmorEvent(block, craftItem.clone(), abstractChestedHorse.getBukkitLivingEntity());
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ world.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ world.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // stack.grow(1); // Paper - shrink below (this was actually missing and should be here, added it commented out to be consistent)
|
||||
+ this.setSuccess(false);
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true; // Paper
|
||||
+ boolean shrink = true;
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ shrink = false;
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
+ }
|
||||
@@ -171,30 +127,25 @@
|
||||
this.setSuccess(true);
|
||||
return item;
|
||||
}
|
||||
@@ -195,8 +_,50 @@
|
||||
@@ -174,8 +_,45 @@
|
||||
DispensibleContainerItem dispensibleContainerItem = (DispensibleContainerItem)item.getItem();
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
Level level = blockSource.level();
|
||||
+ // CraftBukkit start
|
||||
+ int x = blockPos.getX();
|
||||
+ int y = blockPos.getY();
|
||||
+ int z = blockPos.getZ();
|
||||
+ BlockState iblockdata = level.getBlockState(blockPos);
|
||||
+ BlockState state = level.getBlockState(blockPos);
|
||||
+ ItemStack dispensedItem = item; // Paper - track changed item from the dispense event
|
||||
+ // Paper start - correctly check if the bucket place will succeed
|
||||
+ /* Taken from SolidBucketItem#emptyContents */
|
||||
+ boolean willEmptyContentsSolidBucketItem = dispensibleContainerItem instanceof net.minecraft.world.item.SolidBucketItem && level.isInWorldBounds(blockPos) && iblockdata.isAir();
|
||||
+ boolean willEmptyContentsSolidBucketItem = dispensibleContainerItem instanceof net.minecraft.world.item.SolidBucketItem && level.isInWorldBounds(blockPos) && state.isAir();
|
||||
+ /* Taken from BucketItem#emptyContents */
|
||||
+ boolean willEmptyBucketItem = dispensibleContainerItem instanceof final net.minecraft.world.item.BucketItem bucketItem && bucketItem.content instanceof net.minecraft.world.level.material.FlowingFluid && (iblockdata.isAir() || iblockdata.canBeReplaced(bucketItem.content) || (iblockdata.getBlock() instanceof net.minecraft.world.level.block.LiquidBlockContainer liquidBlockContainer && liquidBlockContainer.canPlaceLiquid(null, level, blockPos, iblockdata, bucketItem.content)));
|
||||
+ boolean willEmptyBucketItem = dispensibleContainerItem instanceof final net.minecraft.world.item.BucketItem bucketItem && bucketItem.content instanceof net.minecraft.world.level.material.FlowingFluid && (state.isAir() || state.canBeReplaced(bucketItem.content) || (state.getBlock() instanceof net.minecraft.world.level.block.LiquidBlockContainer liquidBlockContainer && liquidBlockContainer.canPlaceLiquid(null, level, blockPos, state, bucketItem.content)));
|
||||
+ if (willEmptyContentsSolidBucketItem || willEmptyBucketItem) {
|
||||
+ // Paper end - correctly check if the bucket place will succeed
|
||||
+ 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(item.copyWithCount(1)); // Paper - single item in event
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos));
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return item;
|
||||
@@ -203,7 +154,7 @@
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
@@ -223,7 +174,7 @@
|
||||
return this.consumeWithRemainder(blockSource, item, new ItemStack(Items.BUCKET));
|
||||
} else {
|
||||
return this.defaultDispenseItemBehavior.dispense(blockSource, item);
|
||||
@@ -219,12 +_,37 @@
|
||||
@@ -198,12 +_,19 @@
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
BlockState blockState = levelAccessor.getBlockState(blockPos);
|
||||
if (blockState.getBlock() instanceof BucketPickup bucketPickup) {
|
||||
@@ -234,64 +185,27 @@
|
||||
} else {
|
||||
levelAccessor.gameEvent(null, GameEvent.FLUID_PICKUP, blockPos);
|
||||
Item item1 = itemStack.getItem();
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ levelAccessor.getMinecraftWorld().getCraftServer().getPluginManager().callEvent(event);
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(blockSource, blockPos, item, this);
|
||||
+ if (result != null) {
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // 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;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ itemStack = bucketPickup.pickupBlock(null, levelAccessor, blockPos, blockState); // From above
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
+ itemStack = bucketPickup.pickupBlock(null, levelAccessor, blockPos, blockState); // CraftBukkit - from above
|
||||
return this.consumeWithRemainder(blockSource, item, new ItemStack(item1));
|
||||
}
|
||||
} else {
|
||||
@@ -236,17 +_,44 @@
|
||||
@Override
|
||||
protected ItemStack execute(BlockSource blockSource, ItemStack item) {
|
||||
ServerLevel serverLevel = blockSource.level();
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item); // Paper - ignore stack size on damageable items
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // 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;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
@@ -218,15 +_,26 @@
|
||||
this.setSuccess(true);
|
||||
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos blockPos = blockSource.pos().relative(direction);
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(blockSource, blockPos, item, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
BlockState blockState = serverLevel.getBlockState(blockPos);
|
||||
if (BaseFireBlock.canBePlacedAt(serverLevel, blockPos, direction)) {
|
||||
- serverLevel.setBlockAndUpdate(blockPos, BaseFireBlock.getState(serverLevel, blockPos));
|
||||
@@ -303,42 +217,26 @@
|
||||
+ }
|
||||
+ // 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 +_,46 @@
|
||||
this.setSuccess(true);
|
||||
Level level = blockSource.level();
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
+ // CraftBukkit start
|
||||
+ 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(item.copyWithCount(1)); // Paper - single item in event
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(blockSource, blockPos, item, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // 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;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ level.captureTreeGeneration = true;
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
+ level.captureTreeGeneration = true; // CraftBukkit
|
||||
if (!BoneMealItem.growCrop(item, level, blockPos) && !BoneMealItem.growWaterPlant(item, level, blockPos, null)) {
|
||||
this.setSuccess(false);
|
||||
} else if (!level.isClientSide) {
|
||||
@@ -346,26 +244,27 @@
|
||||
}
|
||||
+ // CraftBukkit start
|
||||
+ level.captureTreeGeneration = false;
|
||||
+ if (level.capturedBlockStates.size() > 0) {
|
||||
+ if (!level.capturedBlockStates.isEmpty()) {
|
||||
+ org.bukkit.TreeType treeType = net.minecraft.world.level.block.SaplingBlock.treeType;
|
||||
+ net.minecraft.world.level.block.SaplingBlock.treeType = null;
|
||||
+ org.bukkit.Location location = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(blockPos, level.getWorld());
|
||||
+ List<org.bukkit.block.BlockState> blocks = new java.util.ArrayList<>(level.capturedBlockStates.values());
|
||||
+ List<org.bukkit.block.BlockState> states = new java.util.ArrayList<>(level.capturedBlockStates.values());
|
||||
+ level.capturedBlockStates.clear();
|
||||
+ org.bukkit.event.world.StructureGrowEvent structureEvent = null;
|
||||
+ if (treeType != null) {
|
||||
+ structureEvent = new org.bukkit.event.world.StructureGrowEvent(location, treeType, false, null, blocks);
|
||||
+ structureEvent = new org.bukkit.event.world.StructureGrowEvent(location, treeType, false, null, states);
|
||||
+ org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent);
|
||||
+ }
|
||||
+
|
||||
+ org.bukkit.event.block.BlockFertilizeEvent fertilizeEvent = new org.bukkit.event.block.BlockFertilizeEvent(location.getBlock(), null, blocks);
|
||||
+ org.bukkit.event.block.BlockFertilizeEvent fertilizeEvent = new org.bukkit.event.block.BlockFertilizeEvent(location.getBlock(), null, states);
|
||||
+ fertilizeEvent.setCancelled(structureEvent != null && structureEvent.isCancelled());
|
||||
+ org.bukkit.Bukkit.getPluginManager().callEvent(fertilizeEvent);
|
||||
+
|
||||
+ if (!fertilizeEvent.isCancelled()) {
|
||||
+ for (org.bukkit.block.BlockState blockstate : blocks) {
|
||||
+ blockstate.update(true);
|
||||
+ blockSource.level().checkCapturedTreeStateForObserverNotify(blockPos, (org.bukkit.craftbukkit.block.CraftBlockState) blockstate); // Paper - notify observers even if grow failed
|
||||
+ for (org.bukkit.block.BlockState state : states) {
|
||||
+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) state;
|
||||
+ craftBlockState.place(craftBlockState.getFlags());
|
||||
+ blockSource.level().checkCapturedTreeStateForObserverNotify(blockPos, craftBlockState); // Paper - notify observers even if grow failed
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
@@ -373,79 +272,61 @@
|
||||
|
||||
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);
|
||||
+
|
||||
+ 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);
|
||||
+ }
|
||||
+
|
||||
+ 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);
|
||||
+ 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 @@
|
||||
Level level = blockSource.level();
|
||||
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos blockPos = blockSource.pos().relative(direction);
|
||||
@@ -266,11 +_,36 @@
|
||||
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
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event
|
||||
+ 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(serverLevel, 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(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos));
|
||||
+ 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));
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true;
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false;
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ 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);
|
||||
+ serverLevel.gameEvent(null, GameEvent.ENTITY_PLACE, org.bukkit.craftbukkit.util.CraftVector.toBlockPos(event.getVelocity())); // Paper - update game event position
|
||||
+ if (shrink) item.shrink(1); // Paper
|
||||
this.setSuccess(true);
|
||||
return item;
|
||||
}
|
||||
@@ -284,6 +_,13 @@
|
||||
Level level = blockSource.level();
|
||||
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos blockPos = blockSource.pos().relative(direction);
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(blockSource, blockPos, item, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
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,37 +335,21 @@
|
||||
}
|
||||
|
||||
return item;
|
||||
@@ -326,6 +_,29 @@
|
||||
@@ -312,6 +_,13 @@
|
||||
Level level = blockSource.level();
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
CarvedPumpkinBlock carvedPumpkinBlock = (CarvedPumpkinBlock)Blocks.CARVED_PUMPKIN;
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(blockSource, blockPos, item, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // 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;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
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,51 +358,34 @@
|
||||
}
|
||||
|
||||
return item;
|
||||
@@ -361,6 +_,29 @@
|
||||
@@ -347,6 +_,12 @@
|
||||
ServerLevel serverLevel = blockSource.level();
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
BlockState blockState = serverLevel.getBlockState(blockPos);
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - only single item in event
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(blockSource, blockPos, item, this);
|
||||
+ if (result != null) {
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // 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;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
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) {
|
||||
+ // Paper start - Call missing BlockDispenseEvent
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(blockSource, blockPos, item, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Call missing BlockDispenseEvent
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
RespawnAnchorBlock.charge(null, level, blockPos, blockState);
|
||||
item.shrink(1);
|
||||
} else {
|
||||
@@ -412,6 +_,29 @@
|
||||
@@ -398,6 +_,28 @@
|
||||
this.setSuccess(false);
|
||||
return item;
|
||||
} else {
|
||||
@@ -546,19 +394,18 @@
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item); // Paper - ignore stack size on damageable items
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseArmorEvent(block, craftItem.clone(), entitiesOfClass.get(0).getBukkitLivingEntity());
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ this.setSuccess(false);
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
+ }
|
||||
@@ -567,30 +414,30 @@
|
||||
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()) {
|
||||
+ // Paper start - Call missing BlockDispenseEvent
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(blockSource, blockPos, item, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Call missing BlockDispenseEvent
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
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 {
|
||||
+ // Paper start - Call missing BlockDispenseEvent
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(blockSource, blockPos1, item, this);
|
||||
+ if (result != null) {
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Call missing BlockDispenseEvent
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
if (!serverLevel.isClientSide) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
serverLevel.sendParticles(
|
||||
|
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
|
||||
@@ -14,10 +_,16 @@
|
||||
@@ -14,10 +_,17 @@
|
||||
|
||||
@Override
|
||||
protected ItemStack execute(BlockSource blockSource, ItemStack item) {
|
||||
@@ -13,12 +13,13 @@
|
||||
+ // Paper start
|
||||
+ return dispenseEquipment(blockSource, item, null);
|
||||
+ }
|
||||
+
|
||||
+ public static boolean dispenseEquipment(BlockSource blockSource, ItemStack item, @javax.annotation.Nullable DispenseItemBehavior currentBehavior) {
|
||||
+ // Paper end
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
List<LivingEntity> entitiesOfClass = blockSource.level()
|
||||
.getEntitiesOfClass(LivingEntity.class, new AABB(blockPos), entity -> entity.canEquipWithDispenser(item));
|
||||
@@ -26,13 +_,42 @@
|
||||
@@ -26,13 +_,39 @@
|
||||
} else {
|
||||
LivingEntity livingEntity = entitiesOfClass.getFirst();
|
||||
EquipmentSlot equipmentSlotForItem = livingEntity.getEquipmentSlotForItem(item);
|
||||
@@ -31,22 +32,19 @@
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack);
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseArmorEvent event = new org.bukkit.event.block.BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) livingEntity.getBukkitEntity());
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ world.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ world.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // stack.grow(1); // Paper - shrink below
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true; // Paper
|
||||
+ boolean shrink = true;
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ shrink = false;
|
||||
+ // Chain to handler for new item
|
||||
+ ItemStack eventStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ DispenseItemBehavior dispenseItemBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack); // Paper - Fix NPE with equippable and items without behavior
|
||||
+ if (dispenseItemBehavior != DispenseItemBehavior.NOOP && (currentBehavior == null || dispenseItemBehavior != currentBehavior)) { // Paper - fix possible StackOverflowError
|
||||
+ DispenseItemBehavior dispenseItemBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseItemBehavior != DispenseItemBehavior.NOOP && (currentBehavior == null || dispenseItemBehavior != currentBehavior)) {
|
||||
+ dispenseItemBehavior.dispense(blockSource, eventStack);
|
||||
+ return true;
|
||||
+ }
|
||||
@@ -55,7 +53,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();
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java
|
||||
@@ -57,12 +_,38 @@
|
||||
@@ -57,12 +_,35 @@
|
||||
}
|
||||
|
||||
Vec3 vec31 = new Vec3(d, d1 + d3, d2);
|
||||
@@ -11,22 +11,19 @@
|
||||
+ org.bukkit.block.Block block2 = org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack1);
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block2, craftItem.clone(), new org.bukkit.util.Vector(vec31.x, vec31.y, vec31.z));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block2, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(vec31));
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // stack.grow(1); // Paper - shrink below
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true; // Paper
|
||||
+ boolean shrink = true;
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ shrink = false;
|
||||
+ // Chain to handler for new item
|
||||
+ ItemStack eventStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ DispenseItemBehavior dispenseItemBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack); // Paper - Fix NPE with equippable and items without behavior
|
||||
+ DispenseItemBehavior dispenseItemBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseItemBehavior != DispenseItemBehavior.NOOP && dispenseItemBehavior != this) {
|
||||
+ dispenseItemBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java
|
||||
@@ -27,17 +_,39 @@
|
||||
@@ -27,17 +_,36 @@
|
||||
ServerLevel serverLevel = blockSource.level();
|
||||
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
|
||||
Position dispensePosition = this.dispenseConfig.positionFunction().getDispensePosition(blockSource, direction);
|
||||
@@ -15,38 +15,35 @@
|
||||
- this.dispenseConfig.uncertainty()
|
||||
- );
|
||||
- item.shrink(1);
|
||||
+ ItemStack itemstack1 = item.copyWithCount(1); // Paper - shrink below and single item in event
|
||||
+ ItemStack singleItemStack = item.copyWithCount(1); // Paper - shrink below and single item in event
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack1);
|
||||
+ 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) direction.getStepX(), (double) direction.getStepY(), (double) direction.getStepZ()));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(direction.getStepX(), direction.getStepY(), direction.getStepZ()));
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ // item.grow(1); // Paper - shrink below
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ boolean shrink = true; // Paper
|
||||
+ boolean shrink = true;
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ shrink = false; // Paper - shrink below
|
||||
+ shrink = false;
|
||||
+ // Chain to handler for new item
|
||||
+ ItemStack eventStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack); // Paper - Fix NPE with equippable and items without behavior
|
||||
+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) {
|
||||
+ idispensebehavior.dispense(blockSource, eventStack);
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // SPIGOT-7923: Avoid create projectiles with empty item
|
||||
+ if (!itemstack1.isEmpty()) {
|
||||
+ Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(serverLevel, dispensePosition, org.bukkit.craftbukkit.inventory.CraftItemStack.unwrap(event.getItem()), direction), serverLevel, itemstack1, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); // Paper - track changed items in the dispense event; unwrap is safe here because all uses of the stack make their own copies
|
||||
+ iprojectile.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource(blockSource.blockEntity());
|
||||
+ if (!singleItemStack.isEmpty()) {
|
||||
+ Projectile projectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(serverLevel, dispensePosition, org.bukkit.craftbukkit.inventory.CraftItemStack.unwrap(event.getItem()), direction), serverLevel, singleItemStack, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); // Paper - track changed items in the dispense event; unwrap is safe here because all uses of the stack make their own copies
|
||||
+ projectile.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource(blockSource.blockEntity());
|
||||
+ }
|
||||
+ if (shrink) item.shrink(1); // Paper - actually handle here
|
||||
+ if (shrink) item.shrink(1);
|
||||
+ // CraftBukkit end
|
||||
return item;
|
||||
}
|
||||
|
@@ -1,26 +1,24 @@
|
||||
--- a/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
@@ -20,9 +_,32 @@
|
||||
@@ -20,9 +_,30 @@
|
||||
@Override
|
||||
protected ItemStack execute(BlockSource blockSource, ItemStack item) {
|
||||
ServerLevel serverLevel = blockSource.level();
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item); // Paper - ignore stack size on damageable items
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ this.setSuccess(false);
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
|
@@ -1,17 +1,15 @@
|
||||
--- a/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java
|
||||
@@ -22,10 +_,38 @@
|
||||
@@ -22,10 +_,36 @@
|
||||
BlockPos blockPos = blockSource.pos().relative(direction);
|
||||
Direction direction1 = blockSource.level().isEmptyBlock(blockPos.below()) ? direction : Direction.UP;
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(blockSource.level(), blockSource.pos());
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1));
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||
+ if (!DispenserBlock.eventFired) {
|
||||
+ blockSource.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos));
|
||||
+ blockSource.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return item;
|
||||
@@ -20,7 +18,7 @@
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // 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
|
||||
+ DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
|
||||
+ if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
|
||||
+ dispenseBehavior.dispense(blockSource, eventStack);
|
||||
+ return item;
|
||||
|
@@ -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,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,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));
|
||||
|
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/gametest/framework/GameTestMainUtil.java
|
||||
+++ b/net/minecraft/gametest/framework/GameTestMainUtil.java
|
||||
@@ -77,7 +_,7 @@
|
||||
copyPacks(string, string1);
|
||||
}
|
||||
|
||||
- LevelStorageSource.LevelStorageAccess levelStorageAccess = LevelStorageSource.createDefault(Paths.get(string)).createAccess("gametestworld");
|
||||
+ LevelStorageSource.LevelStorageAccess levelStorageAccess = LevelStorageSource.createDefault(Paths.get(string)).createAccess("gametestworld", net.minecraft.world.level.dimension.LevelStem.OVERWORLD); // Paper
|
||||
PackRepository packRepository = ServerPacksSource.createPackRepository(levelStorageAccess);
|
||||
MinecraftServer.spin(
|
||||
thread -> GameTestServer.create(thread, levelStorageAccess, packRepository, optionalFromOption(optionSet, tests), optionSet.has(verify))
|
@@ -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,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);
|
@@ -0,0 +1,30 @@
|
||||
--- a/net/minecraft/gametest/framework/TestEnvironmentDefinition.java
|
||||
+++ b/net/minecraft/gametest/framework/TestEnvironmentDefinition.java
|
||||
@@ -132,11 +_,11 @@
|
||||
MinecraftServer server = level.getServer();
|
||||
|
||||
for (TestEnvironmentDefinition.SetGameRules.Entry<Boolean, GameRules.BooleanValue> entry : this.boolRules) {
|
||||
- gameRules.getRule(entry.key()).set(entry.value(), server);
|
||||
+ gameRules.getRule(entry.key()).set(entry.value(), level); // Paper - per-world
|
||||
}
|
||||
|
||||
for (TestEnvironmentDefinition.SetGameRules.Entry<Integer, GameRules.IntegerValue> entry : this.intRules) {
|
||||
- gameRules.getRule(entry.key()).set(entry.value(), server);
|
||||
+ gameRules.getRule(entry.key()).set(entry.value(), level); // Paper - per-world
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,11 +_,11 @@
|
||||
MinecraftServer server = level.getServer();
|
||||
|
||||
for (TestEnvironmentDefinition.SetGameRules.Entry<Boolean, GameRules.BooleanValue> entry : this.boolRules) {
|
||||
- gameRules.getRule(entry.key()).setFrom(GameRules.getType(entry.key()).createRule(), server);
|
||||
+ gameRules.getRule(entry.key()).setFrom(GameRules.getType(entry.key()).createRule(), level); // Paper - per-world
|
||||
}
|
||||
|
||||
for (TestEnvironmentDefinition.SetGameRules.Entry<Integer, GameRules.IntegerValue> entry : this.intRules) {
|
||||
- gameRules.getRule(entry.key()).setFrom(GameRules.getType(entry.key()).createRule(), server);
|
||||
+ gameRules.getRule(entry.key()).setFrom(GameRules.getType(entry.key()).createRule(), level); // Paper - per-world
|
||||
}
|
||||
}
|
||||
|
@@ -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));
|
||||
|
@@ -0,0 +1,33 @@
|
||||
--- a/net/minecraft/network/HashedStack.java
|
||||
+++ b/net/minecraft/network/HashedStack.java
|
||||
@@ -17,7 +_,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator) {
|
||||
+ public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator, final boolean simplifyMatching) { // Paper - add flag to simplify remote matching logic
|
||||
return stack.isEmpty();
|
||||
}
|
||||
};
|
||||
@@ -27,7 +_,7 @@
|
||||
hashedStack -> hashedStack instanceof HashedStack.ActualItem actualItem ? Optional.of(actualItem) : Optional.empty()
|
||||
);
|
||||
|
||||
- boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator);
|
||||
+ boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator, final boolean simplifyMatching); // Paper - add flag to simplify remote matching logic
|
||||
|
||||
static HashedStack create(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator) {
|
||||
return (HashedStack)(stack.isEmpty()
|
||||
@@ -47,10 +_,10 @@
|
||||
);
|
||||
|
||||
@Override
|
||||
- public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator) {
|
||||
+ public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator, final boolean simplifyMatching) { // Paper - add flag to simplify remote matching logic
|
||||
return this.count == stack.getCount()
|
||||
&& this.item.equals(stack.getItemHolder())
|
||||
- && this.components.matches(stack.getComponentsPatch(), hashGenerator);
|
||||
+ && (simplifyMatching || this.components.matches(stack.getComponentsPatch(), hashGenerator)); // Paper - add flag to simplify remote matching logic
|
||||
}
|
||||
}
|
||||
}
|
@@ -9,7 +9,7 @@
|
||||
- Component decorate(@Nullable ServerPlayer player, Component message);
|
||||
+ ChatDecorator PLAIN = (player, message) -> java.util.concurrent.CompletableFuture.completedFuture(message); // Paper - adventure; support async chat decoration events
|
||||
+
|
||||
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - adventure; support chat decoration events (callers should use the overload with CommandSourceStack)
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - adventure; support chat decoration events (callers should use the overload with CommandSourceStack)
|
||||
+ java.util.concurrent.CompletableFuture<Component> decorate(@Nullable ServerPlayer player, Component message); // Paper - adventure; support async chat decoration events
|
||||
+
|
||||
+ // Paper start - adventure; support async chat decoration events
|
||||
|
@@ -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)
|
||||
);
|
||||
|
@@ -4,7 +4,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse // Paper - validate separators - right now this method is only used for separator evaluation. Error on build if this changes to re-evaluate.
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - validate separators - right now this method is only used for separator evaluation. Error on build if this changes to re-evaluate.
|
||||
public static Optional<MutableComponent> updateForEntity(
|
||||
@Nullable CommandSourceStack commandSourceStack, Optional<Component> optionalComponent, @Nullable Entity entity, int recursionDepth
|
||||
) throws CommandSyntaxException {
|
||||
|
@@ -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) {
|
||||
|
@@ -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 @@
|
||||
@@ -389,6 +_,48 @@
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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());
|
||||
|
@@ -97,7 +97,7 @@
|
||||
- true,
|
||||
+ listed, // Paper - Add Listing API for Player
|
||||
player.connection.latency(),
|
||||
player.gameMode.getGameModeForPlayer(),
|
||||
player.gameMode(),
|
||||
player.getTabListDisplayName(),
|
||||
@@ -172,6 +_,11 @@
|
||||
Optionull.map(player.getChatSession(), RemoteChatSession::asData)
|
||||
|
@@ -4,7 +4,7 @@
|
||||
}
|
||||
|
||||
private static void pack(List<SynchedEntityData.DataValue<?>> dataValues, RegistryFriendlyByteBuf buffer) {
|
||||
+ try (io.papermc.paper.util.ItemObfuscationSession ignored = io.papermc.paper.util.ItemObfuscationSession.start(io.papermc.paper.configuration.GlobalConfiguration.get().anticheat.obfuscation.items.binding.level)) { // Paper - data sanitization
|
||||
+ try (io.papermc.paper.util.sanitizer.ItemObfuscationSession ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.start(io.papermc.paper.configuration.GlobalConfiguration.get().anticheat.obfuscation.items.binding.level)) { // Paper - data sanitization
|
||||
for (SynchedEntityData.DataValue<?> dataValue : dataValues) {
|
||||
dataValue.write(buffer);
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
buffer.writeVarInt(this.entity);
|
||||
int size = this.slots.size();
|
||||
|
||||
+ try (final io.papermc.paper.util.ItemObfuscationSession ignored = io.papermc.paper.util.ItemObfuscationSession.start(this.sanitize ? io.papermc.paper.configuration.GlobalConfiguration.get().anticheat.obfuscation.items.binding.level : io.papermc.paper.util.ItemObfuscationSession.ObfuscationLevel.NONE)) { // Paper - data sanitization
|
||||
+ try (final io.papermc.paper.util.sanitizer.ItemObfuscationSession ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.start(this.sanitize ? io.papermc.paper.configuration.GlobalConfiguration.get().anticheat.obfuscation.items.binding.level : io.papermc.paper.util.sanitizer.ItemObfuscationSession.ObfuscationLevel.NONE)) { // Paper - data sanitization
|
||||
for (int i = 0; i < size; i++) {
|
||||
Pair<EquipmentSlot, ItemStack> pair = this.slots.get(i);
|
||||
EquipmentSlot equipmentSlot = pair.getFirst();
|
||||
|
@@ -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);
|
||||
|
@@ -6,7 +6,7 @@
|
||||
);
|
||||
+ // Spigot start
|
||||
+ public ClientboundSystemChatPacket(net.md_5.bungee.api.chat.BaseComponent[] content, boolean overlay) {
|
||||
+ this(org.bukkit.craftbukkit.util.CraftChatMessage.fromJSON(net.md_5.bungee.chat.ComponentSerializer.toString(content)), overlay);
|
||||
+ this(org.bukkit.craftbukkit.util.CraftChatMessage.bungeeToVanilla(content), overlay);
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+ // Paper start
|
||||
|
@@ -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) {
|
@@ -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,14 +1,5 @@
|
||||
--- a/net/minecraft/network/syncher/SynchedEntityData.java
|
||||
+++ b/net/minecraft/network/syncher/SynchedEntityData.java
|
||||
@@ -45,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> key) {
|
||||
+ public <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> key) { // Paper - public
|
||||
return (SynchedEntityData.DataItem<T>)this.itemsById[key.id()];
|
||||
}
|
||||
|
||||
@@ -67,6 +_,13 @@
|
||||
}
|
||||
}
|
||||
|
@@ -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)) {
|
||||
|
@@ -8,7 +8,7 @@
|
||||
if (BuiltInRegistries.REGISTRY.keySet().isEmpty()) {
|
||||
throw new IllegalStateException("Unable to load registries");
|
||||
} else {
|
||||
@@ -54,11 +_,80 @@
|
||||
@@ -54,11 +_,85 @@
|
||||
EntitySelectorOptions.bootStrap();
|
||||
DispenseItemBehavior.bootStrap();
|
||||
CauldronInteraction.bootStrap();
|
||||
@@ -25,25 +25,30 @@
|
||||
+ // CraftBukkit start
|
||||
+ // TODO Check what of this is needed, maybe report it to Mojira. if deemed relevant, move to the respective classes
|
||||
+ // Used in CraftLegacy
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1008, "{Name:'minecraft:oak_sign',Properties:{rotation:'0'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'0'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1009, "{Name:'minecraft:oak_sign',Properties:{rotation:'1'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'1'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1010, "{Name:'minecraft:oak_sign',Properties:{rotation:'2'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'2'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1011, "{Name:'minecraft:oak_sign',Properties:{rotation:'3'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'3'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1012, "{Name:'minecraft:oak_sign',Properties:{rotation:'4'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'4'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1013, "{Name:'minecraft:oak_sign',Properties:{rotation:'5'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'5'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1014, "{Name:'minecraft:oak_sign',Properties:{rotation:'6'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'6'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1015, "{Name:'minecraft:oak_sign',Properties:{rotation:'7'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'7'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1016, "{Name:'minecraft:oak_sign',Properties:{rotation:'8'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'8'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1017, "{Name:'minecraft:oak_sign',Properties:{rotation:'9'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'9'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1018, "{Name:'minecraft:oak_sign',Properties:{rotation:'10'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'10'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1019, "{Name:'minecraft:oak_sign',Properties:{rotation:'11'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'11'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1020, "{Name:'minecraft:oak_sign',Properties:{rotation:'12'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'12'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1021, "{Name:'minecraft:oak_sign',Properties:{rotation:'13'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'13'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1022, "{Name:'minecraft:oak_sign',Properties:{rotation:'14'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'14'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1023, "{Name:'minecraft:oak_sign',Properties:{rotation:'15'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'15'}}");
|
||||
+ net.minecraft.util.datafix.fixes.ItemIdFix.ITEM_NAMES.put(323, "minecraft:oak_sign");
|
||||
+ for (int i = 0; i <= 15; i++) {
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(
|
||||
+ 1008 + i,
|
||||
+ new com.mojang.serialization.Dynamic<>(com.mojang.serialization.JavaOps.INSTANCE, java.util.Map.of(
|
||||
+ "Name", "minecraft:oak_sign",
|
||||
+ "Properties", java.util.Map.of("rotation", String.valueOf(i))
|
||||
+ )).convert(net.minecraft.nbt.NbtOps.INSTANCE),
|
||||
+ new com.mojang.serialization.Dynamic<>(com.mojang.serialization.JavaOps.INSTANCE, java.util.Map.of(
|
||||
+ "Name", "minecraft:standing_sign",
|
||||
+ "Properties", java.util.Map.of("rotation", String.valueOf(i))
|
||||
+ )).convert(net.minecraft.nbt.NbtOps.INSTANCE)
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1440, "{Name:'minecraft:portal',Properties:{axis:'x'}}", "{Name:'minecraft:portal',Properties:{axis:'x'}}");
|
||||
+ net.minecraft.util.datafix.fixes.BlockStateData.register(1440,
|
||||
+ new com.mojang.serialization.Dynamic<>(com.mojang.serialization.JavaOps.INSTANCE, java.util.Map.of(
|
||||
+ "Name", "minecraft:portal",
|
||||
+ "Properties", java.util.Map.of("axis", "x")
|
||||
+ )).convert(net.minecraft.nbt.NbtOps.INSTANCE),
|
||||
+ new com.mojang.serialization.Dynamic<>(com.mojang.serialization.JavaOps.INSTANCE, java.util.Map.of(
|
||||
+ "Name", "minecraft:portal",
|
||||
+ "Properties", java.util.Map.of("axis", "x")
|
||||
+ )).convert(net.minecraft.nbt.NbtOps.INSTANCE)
|
||||
+ );
|
||||
+
|
||||
+ net.minecraft.util.datafix.fixes.ItemIdFix.ITEM_NAMES.put(409, "minecraft:prismarine_shard");
|
||||
+ net.minecraft.util.datafix.fixes.ItemIdFix.ITEM_NAMES.put(410, "minecraft:prismarine_crystals");
|
||||
|
@@ -52,13 +52,13 @@
|
||||
+ File configFile = (File) optionSet.valueOf("bukkit-settings");
|
||||
+ org.bukkit.configuration.file.YamlConfiguration configuration = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(configFile);
|
||||
+ configuration.options().copyDefaults(true);
|
||||
+ configuration.setDefaults(org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(new java.io.InputStreamReader(Main.class.getClassLoader().getResourceAsStream("configurations/bukkit.yml"), com.google.common.base.Charsets.UTF_8)));
|
||||
+ configuration.setDefaults(org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(new java.io.InputStreamReader(Main.class.getClassLoader().getResourceAsStream("configurations/bukkit.yml"), java.nio.charset.StandardCharsets.UTF_8)));
|
||||
+ configuration.save(configFile);
|
||||
+
|
||||
+ File commandFile = (File) optionSet.valueOf("commands-settings");
|
||||
+ org.bukkit.configuration.file.YamlConfiguration commandsConfiguration = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(commandFile);
|
||||
+ commandsConfiguration.options().copyDefaults(true);
|
||||
+ commandsConfiguration.setDefaults(org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(new java.io.InputStreamReader(Main.class.getClassLoader().getResourceAsStream("configurations/commands.yml"), com.google.common.base.Charsets.UTF_8)));
|
||||
+ commandsConfiguration.setDefaults(org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(new java.io.InputStreamReader(Main.class.getClassLoader().getResourceAsStream("configurations/commands.yml"), java.nio.charset.StandardCharsets.UTF_8)));
|
||||
+ commandsConfiguration.save(commandFile);
|
||||
+ // CraftBukkit end
|
||||
LOGGER.info("Initialized '{}' and '{}'", path1.toAbsolutePath(), path2.toAbsolutePath());
|
||||
@@ -116,7 +116,7 @@
|
||||
Dynamic<?> dataTag;
|
||||
if (levelStorageAccess.hasWorldData()) {
|
||||
LevelSummary summary;
|
||||
@@ -169,12 +_,30 @@
|
||||
@@ -169,12 +_,33 @@
|
||||
}
|
||||
|
||||
Dynamic<?> dynamic = dataTag;
|
||||
@@ -134,12 +134,15 @@
|
||||
+ }
|
||||
+ File mcMeta = new File(bukkitDataPackFolder, "pack.mcmeta");
|
||||
+ try {
|
||||
+ com.google.common.io.Files.write("{\n"
|
||||
+ + " \"pack\": {\n"
|
||||
+ + " \"description\": \"Data pack for resources provided by Bukkit plugins\",\n"
|
||||
+ + " \"pack_format\": " + SharedConstants.getCurrentVersion().getPackVersion(net.minecraft.server.packs.PackType.SERVER_DATA) + "\n"
|
||||
+ + " }\n"
|
||||
+ + "}\n", mcMeta, com.google.common.base.Charsets.UTF_8);
|
||||
+ com.google.common.io.Files.asCharSink(mcMeta, java.nio.charset.StandardCharsets.UTF_8).write("""
|
||||
+ {
|
||||
+ "pack": {
|
||||
+ "description": "Data pack for resources provided by Bukkit plugins",
|
||||
+ "pack_format": %d
|
||||
+ }
|
||||
+ }
|
||||
+ """.formatted(SharedConstants.getCurrentVersion().getPackVersion(net.minecraft.server.packs.PackType.SERVER_DATA))
|
||||
+ );
|
||||
+ } catch (java.io.IOException ex) {
|
||||
+ throw new RuntimeException("Could not initialize Bukkit datapack", ex);
|
||||
+ }
|
||||
@@ -180,11 +183,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 +244,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/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -174,11 +_,13 @@
|
||||
@@ -173,11 +_,13 @@
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements ServerInfo, ChunkIOErrorReporter, CommandSource {
|
||||
@@ -15,7 +15,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 @@
|
||||
@@ -217,6 +_,7 @@
|
||||
private Map<ResourceKey<Level>, ServerLevel> levels = Maps.newLinkedHashMap();
|
||||
private PlayerList playerList;
|
||||
private volatile boolean running = true;
|
||||
@@ -23,7 +23,7 @@
|
||||
private boolean stopped;
|
||||
private int tickCount;
|
||||
private int ticksUntilAutosave = 6000;
|
||||
@@ -226,11 +_,15 @@
|
||||
@@ -225,11 +_,15 @@
|
||||
private boolean preventProxyConnections;
|
||||
private boolean pvp;
|
||||
private boolean allowFlight;
|
||||
@@ -41,7 +41,7 @@
|
||||
@Nullable
|
||||
private KeyPair keyPair;
|
||||
@Nullable
|
||||
@@ -271,10 +_,37 @@
|
||||
@@ -270,10 +_,37 @@
|
||||
private final SuppressedExceptionCollector suppressedExceptions = new SuppressedExceptionCollector();
|
||||
private final DiscontinuousFrame tickFrame;
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
if (Runtime.getRuntime().availableProcessors() > 4) {
|
||||
thread.setPriority(8);
|
||||
}
|
||||
@@ -286,6 +_,10 @@
|
||||
@@ -285,6 +_,10 @@
|
||||
}
|
||||
|
||||
public MinecraftServer(
|
||||
@@ -91,7 +91,7 @@
|
||||
Thread serverThread,
|
||||
LevelStorageSource.LevelStorageAccess storageSource,
|
||||
PackRepository packRepository,
|
||||
@@ -296,9 +_,10 @@
|
||||
@@ -295,9 +_,10 @@
|
||||
ChunkProgressListenerFactory progressListenerFactory
|
||||
) {
|
||||
super("Server");
|
||||
@@ -103,7 +103,7 @@
|
||||
throw new IllegalStateException("Missing Overworld dimension data");
|
||||
} else {
|
||||
this.proxy = proxy;
|
||||
@@ -309,7 +_,7 @@
|
||||
@@ -308,7 +_,7 @@
|
||||
services.profileCache().setExecutor(this);
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
this.tickRateManager = new ServerTickRateManager(this);
|
||||
this.progressListenerFactory = progressListenerFactory;
|
||||
this.storageSource = storageSource;
|
||||
@@ -328,6 +_,38 @@
|
||||
@@ -327,6 +_,38 @@
|
||||
this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures());
|
||||
this.tickFrame = TracyClient.createDiscontinuousFrame("Server Tick");
|
||||
}
|
||||
@@ -151,7 +151,7 @@
|
||||
}
|
||||
|
||||
private void readScoreboard(DimensionDataStorage dataStorage) {
|
||||
@@ -336,18 +_,13 @@
|
||||
@@ -335,18 +_,13 @@
|
||||
|
||||
protected abstract boolean initServer() throws IOException;
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
if (profiledDuration != null) {
|
||||
profiledDuration.finish(true);
|
||||
}
|
||||
@@ -364,25 +_,265 @@
|
||||
@@ -363,25 +_,265 @@
|
||||
protected void forceDifficulty() {
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@
|
||||
+
|
||||
+ primaryLevelData.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end)
|
||||
+ if (this.options.has("forceUpgrade")) {
|
||||
+ net.minecraft.server.Main.forceUpgrade(levelStorageAccess, net.minecraft.util.datafix.DataFixers.getDataFixer(), this.options.has("eraseCache"), () -> true, registryAccess, this.options.has("recreateRegionFiles"));
|
||||
+ net.minecraft.server.Main.forceUpgrade(levelStorageAccess, primaryLevelData, net.minecraft.util.datafix.DataFixers.getDataFixer(), this.options.has("eraseCache"), () -> true, registryAccess, this.options.has("recreateRegionFiles"));
|
||||
+ }
|
||||
+
|
||||
+ // Now modelled off the createLevels method
|
||||
@@ -457,7 +457,7 @@
|
||||
if (!serverLevelData.isInitialized()) {
|
||||
try {
|
||||
setInitialSpawn(serverLevel, serverLevelData, worldOptions.generateBonusChest(), isDebugWorld);
|
||||
@@ -403,47 +_,30 @@
|
||||
@@ -402,47 +_,30 @@
|
||||
|
||||
serverLevelData.setInitialized(true);
|
||||
}
|
||||
@@ -522,7 +522,7 @@
|
||||
int spawnHeight = chunkSource.getGenerator().getSpawnHeight(level);
|
||||
if (spawnHeight < level.getMinY()) {
|
||||
BlockPos worldPosition = chunkPos.getWorldPosition();
|
||||
@@ -495,26 +_,31 @@
|
||||
@@ -494,36 +_,48 @@
|
||||
serverLevelData.setGameType(GameType.SPECTATOR);
|
||||
}
|
||||
|
||||
@@ -557,12 +557,11 @@
|
||||
|
||||
- for (ServerLevel serverLevel1 : this.levels.values()) {
|
||||
+ if (true) {
|
||||
+ ServerLevel serverLevel1 = serverLevel;
|
||||
+ final ServerLevel serverLevel1 = serverLevel;
|
||||
+ // CraftBukkit end
|
||||
ForcedChunksSavedData forcedChunksSavedData = serverLevel1.getDataStorage().get(ForcedChunksSavedData.factory(), "chunks");
|
||||
if (forcedChunksSavedData != null) {
|
||||
LongIterator longIterator = forcedChunksSavedData.getChunks().iterator();
|
||||
@@ -527,10 +_,17 @@
|
||||
TicketStorage ticketStorage = serverLevel1.getDataStorage().get(TicketStorage.TYPE);
|
||||
if (ticketStorage != null) {
|
||||
ticketStorage.activateAllDeactivatedTickets();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,11 +582,11 @@
|
||||
}
|
||||
|
||||
public GameType getDefaultGameType() {
|
||||
@@ -559,11 +_,14 @@
|
||||
@@ -552,11 +_,14 @@
|
||||
flag = true;
|
||||
}
|
||||
|
||||
+ /* // CraftBukkit start - moved to WorldServer.save
|
||||
+ /* // CraftBukkit start - moved to ServerLevel#save
|
||||
ServerLevel serverLevel1 = this.overworld();
|
||||
ServerLevelData serverLevelData = this.worldData.overworldData();
|
||||
serverLevelData.setWorldBorder(serverLevel1.getWorldBorder().createSettings());
|
||||
@@ -598,7 +597,7 @@
|
||||
if (flush) {
|
||||
for (ServerLevel serverLevel2 : this.getAllLevels()) {
|
||||
LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", serverLevel2.getChunkSource().chunkMap.getStorageName());
|
||||
@@ -593,18 +_,48 @@
|
||||
@@ -586,18 +_,48 @@
|
||||
this.stopServer();
|
||||
}
|
||||
|
||||
@@ -648,7 +647,7 @@
|
||||
}
|
||||
|
||||
LOGGER.info("Saving worlds");
|
||||
@@ -646,6 +_,25 @@
|
||||
@@ -639,6 +_,25 @@
|
||||
} catch (IOException var4) {
|
||||
LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), var4);
|
||||
}
|
||||
@@ -674,7 +673,7 @@
|
||||
}
|
||||
|
||||
public String getLocalIp() {
|
||||
@@ -661,6 +_,14 @@
|
||||
@@ -654,6 +_,14 @@
|
||||
}
|
||||
|
||||
public void halt(boolean waitForServer) {
|
||||
@@ -689,7 +688,7 @@
|
||||
this.running = false;
|
||||
if (waitForServer) {
|
||||
try {
|
||||
@@ -671,6 +_,57 @@
|
||||
@@ -664,6 +_,57 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,7 +746,7 @@
|
||||
protected void runServer() {
|
||||
try {
|
||||
if (!this.initServer()) {
|
||||
@@ -681,6 +_,35 @@
|
||||
@@ -674,6 +_,35 @@
|
||||
this.statusIcon = this.loadStatusIcon().orElse(null);
|
||||
this.status = this.buildServerStatus();
|
||||
|
||||
@@ -783,7 +782,7 @@
|
||||
while (this.running) {
|
||||
long l;
|
||||
if (!this.isPaused() && this.tickRateManager.isSprinting() && this.tickRateManager.checkShouldSprintThisTick()) {
|
||||
@@ -693,11 +_,30 @@
|
||||
@@ -686,11 +_,30 @@
|
||||
if (l1 > OVERLOADED_THRESHOLD_NANOS + 20L * l
|
||||
&& this.nextTickTimeNanos - this.lastOverloadWarningNanos >= OVERLOADED_WARNING_INTERVAL_NANOS + 100L * l) {
|
||||
long l2 = l1 / l;
|
||||
@@ -814,7 +813,7 @@
|
||||
|
||||
boolean flag = l == 0L;
|
||||
if (this.debugCommandProfilerDelayStart) {
|
||||
@@ -705,6 +_,8 @@
|
||||
@@ -698,6 +_,8 @@
|
||||
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount);
|
||||
}
|
||||
|
||||
@@ -823,7 +822,7 @@
|
||||
this.nextTickTimeNanos += l;
|
||||
|
||||
try (Profiler.Scope scope = Profiler.use(this.createProfiler())) {
|
||||
@@ -755,7 +_,7 @@
|
||||
@@ -748,7 +_,7 @@
|
||||
this.services.profileCache().clearExecutor();
|
||||
}
|
||||
|
||||
@@ -832,7 +831,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -807,7 +_,14 @@
|
||||
@@ -800,7 +_,14 @@
|
||||
}
|
||||
|
||||
private boolean haveTime() {
|
||||
@@ -848,7 +847,7 @@
|
||||
}
|
||||
|
||||
public static boolean throwIfFatalException() {
|
||||
@@ -852,6 +_,12 @@
|
||||
@@ -845,6 +_,12 @@
|
||||
|
||||
@Override
|
||||
public TickTask wrapRunnable(Runnable runnable) {
|
||||
@@ -861,7 +860,7 @@
|
||||
return new TickTask(this.tickCount, runnable);
|
||||
}
|
||||
|
||||
@@ -871,15 +_,16 @@
|
||||
@@ -864,15 +_,16 @@
|
||||
if (super.pollTask()) {
|
||||
return true;
|
||||
} else {
|
||||
@@ -880,7 +879,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -927,26 +_,44 @@
|
||||
@@ -920,26 +_,44 @@
|
||||
}
|
||||
|
||||
public void tickServer(BooleanSupplier hasTimeLeft) {
|
||||
@@ -926,7 +925,7 @@
|
||||
this.tickCount++;
|
||||
this.tickRateManager.tick();
|
||||
this.tickChildren(hasTimeLeft);
|
||||
@@ -956,11 +_,19 @@
|
||||
@@ -949,11 +_,19 @@
|
||||
}
|
||||
|
||||
this.ticksUntilAutosave--;
|
||||
@@ -947,7 +946,7 @@
|
||||
profilerFiller.push("tallying");
|
||||
long l = Util.getNanos() - nanos;
|
||||
int i1 = this.tickCount % 100;
|
||||
@@ -968,12 +_,17 @@
|
||||
@@ -961,12 +_,17 @@
|
||||
this.aggregatedTickTimesNanos += l;
|
||||
this.tickTimesNanos[i1] = l;
|
||||
this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)l / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F;
|
||||
@@ -966,7 +965,7 @@
|
||||
LOGGER.debug("Autosave started");
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("save");
|
||||
@@ -1015,7 +_,7 @@
|
||||
@@ -1008,7 +_,7 @@
|
||||
private ServerStatus buildServerStatus() {
|
||||
ServerStatus.Players players = this.buildPlayerStatus();
|
||||
return new ServerStatus(
|
||||
@@ -975,7 +974,7 @@
|
||||
Optional.of(players),
|
||||
Optional.of(ServerStatus.Version.current()),
|
||||
Optional.ofNullable(this.statusIcon),
|
||||
@@ -1029,7 +_,7 @@
|
||||
@@ -1022,7 +_,7 @@
|
||||
if (this.hidesOnlinePlayers()) {
|
||||
return new ServerStatus.Players(maxPlayers, players.size(), List.of());
|
||||
} else {
|
||||
@@ -984,7 +983,7 @@
|
||||
ObjectArrayList<GameProfile> list = new ObjectArrayList<>(min);
|
||||
int randomInt = Mth.nextInt(this.random, 0, players.size() - min);
|
||||
|
||||
@@ -1046,17 +_,66 @@
|
||||
@@ -1039,17 +_,66 @@
|
||||
protected void tickChildren(BooleanSupplier hasTimeLeft) {
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing());
|
||||
@@ -1051,7 +1050,7 @@
|
||||
|
||||
profilerFiller.push("tick");
|
||||
|
||||
@@ -1070,7 +_,9 @@
|
||||
@@ -1063,7 +_,9 @@
|
||||
|
||||
profilerFiller.pop();
|
||||
profilerFiller.pop();
|
||||
@@ -1061,7 +1060,7 @@
|
||||
|
||||
profilerFiller.popPush("connection");
|
||||
this.tickConnection();
|
||||
@@ -1148,6 +_,22 @@
|
||||
@@ -1141,6 +_,22 @@
|
||||
return this.levels.get(dimension);
|
||||
}
|
||||
|
||||
@@ -1084,7 +1083,7 @@
|
||||
public Set<ResourceKey<Level>> levelKeys() {
|
||||
return this.levels.keySet();
|
||||
}
|
||||
@@ -1177,7 +_,7 @@
|
||||
@@ -1170,7 +_,7 @@
|
||||
|
||||
@DontObfuscate
|
||||
public String getServerModName() {
|
||||
@@ -1093,7 +1092,7 @@
|
||||
}
|
||||
|
||||
public SystemReport fillSystemReport(SystemReport systemReport) {
|
||||
@@ -1212,7 +_,7 @@
|
||||
@@ -1205,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public void sendSystemMessage(Component component) {
|
||||
@@ -1102,7 +1101,7 @@
|
||||
}
|
||||
|
||||
public KeyPair getKeyPair() {
|
||||
@@ -1250,11 +_,14 @@
|
||||
@@ -1243,11 +_,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1112,9 +1111,9 @@
|
||||
- this.updateMobSpawningFlags();
|
||||
- this.getPlayerList().getPlayers().forEach(this::sendDifficultyUpdate);
|
||||
+ // Paper start - per level difficulty
|
||||
+ public void setDifficulty(ServerLevel level, Difficulty difficulty, boolean forceUpdate) {
|
||||
+ net.minecraft.world.level.storage.PrimaryLevelData worldData = (net.minecraft.world.level.storage.PrimaryLevelData) level.serverLevelData;
|
||||
+ if (forceUpdate || !worldData.isDifficultyLocked()) {
|
||||
+ public void setDifficulty(ServerLevel level, Difficulty difficulty, boolean forced) {
|
||||
+ net.minecraft.world.level.storage.PrimaryLevelData worldData = level.serverLevelData;
|
||||
+ if (forced || !worldData.isDifficultyLocked()) {
|
||||
+ worldData.setDifficulty(worldData.isHardcore() ? Difficulty.HARD : difficulty);
|
||||
+ level.setSpawnSettings(worldData.getDifficulty() != Difficulty.PEACEFUL && ((net.minecraft.server.dedicated.DedicatedServer) this).settings.getProperties().spawnMonsters);
|
||||
+ // this.getPlayerList().getPlayers().forEach(this::sendDifficultyUpdate);
|
||||
@@ -1122,7 +1121,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1264,7 +_,7 @@
|
||||
@@ -1257,7 +_,7 @@
|
||||
|
||||
private void updateMobSpawningFlags() {
|
||||
for (ServerLevel serverLevel : this.getAllLevels()) {
|
||||
@@ -1131,7 +1130,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1340,10 +_,20 @@
|
||||
@@ -1333,10 +_,20 @@
|
||||
|
||||
@Override
|
||||
public String getMotd() {
|
||||
@@ -1153,7 +1152,7 @@
|
||||
this.motd = motd;
|
||||
}
|
||||
|
||||
@@ -1366,7 +_,7 @@
|
||||
@@ -1359,7 +_,7 @@
|
||||
}
|
||||
|
||||
public ServerConnectionListener getConnection() {
|
||||
@@ -1162,7 +1161,7 @@
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
@@ -1452,7 +_,7 @@
|
||||
@@ -1445,7 +_,7 @@
|
||||
@Override
|
||||
public void executeIfPossible(Runnable task) {
|
||||
if (this.isStopped()) {
|
||||
@@ -1171,7 +1170,7 @@
|
||||
} else {
|
||||
super.executeIfPossible(task);
|
||||
}
|
||||
@@ -1491,7 +_,13 @@
|
||||
@@ -1484,7 +_,14 @@
|
||||
return this.functionManager;
|
||||
}
|
||||
|
||||
@@ -1180,12 +1179,13 @@
|
||||
public CompletableFuture<Void> reloadResources(Collection<String> selectedIds) {
|
||||
+ return this.reloadResources(selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.PLUGIN);
|
||||
+ }
|
||||
+
|
||||
+ public CompletableFuture<Void> reloadResources(Collection<String> selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause cause) {
|
||||
+ // Paper end - Add ServerResourcesReloadedEvent
|
||||
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 @@
|
||||
@@ -1492,7 +_,7 @@
|
||||
.thenCompose(
|
||||
list -> {
|
||||
CloseableResourceManager closeableResourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, list);
|
||||
@@ -1194,7 +1194,7 @@
|
||||
return ReloadableServerResources.loadResources(
|
||||
closeableResourceManager,
|
||||
this.registries,
|
||||
@@ -1520,20 +_,39 @@
|
||||
@@ -1513,20 +_,39 @@
|
||||
)
|
||||
.thenAcceptAsync(
|
||||
reloadableResources -> {
|
||||
@@ -1236,7 +1236,7 @@
|
||||
},
|
||||
this
|
||||
);
|
||||
@@ -1550,7 +_,7 @@
|
||||
@@ -1543,7 +_,7 @@
|
||||
DataPackConfig dataPackConfig = initialDataConfig.dataPacks();
|
||||
FeatureFlagSet featureFlagSet = initMode ? FeatureFlagSet.of() : initialDataConfig.enabledFeatures();
|
||||
FeatureFlagSet featureFlagSet1 = initMode ? FeatureFlags.REGISTRY.allFlags() : initialDataConfig.enabledFeatures();
|
||||
@@ -1245,7 +1245,7 @@
|
||||
if (safeMode) {
|
||||
return configureRepositoryWithSelection(packRepository, List.of("vanilla"), featureFlagSet, false);
|
||||
} else {
|
||||
@@ -1605,7 +_,7 @@
|
||||
@@ -1598,7 +_,7 @@
|
||||
private static WorldDataConfiguration configureRepositoryWithSelection(
|
||||
PackRepository packRepository, Collection<String> selectedPacks, FeatureFlagSet enabledFeatures, boolean safeMode
|
||||
) {
|
||||
@@ -1254,7 +1254,7 @@
|
||||
enableForcedFeaturePacks(packRepository, enabledFeatures);
|
||||
DataPackConfig selectedPacks1 = getSelectedPacks(packRepository, safeMode);
|
||||
FeatureFlagSet featureFlagSet = packRepository.getRequestedFeatureFlags().join(enabledFeatures);
|
||||
@@ -1637,7 +_,7 @@
|
||||
@@ -1630,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1263,7 +1263,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1651,11 +_,12 @@
|
||||
@@ -1644,11 +_,12 @@
|
||||
public void kickUnlistedPlayers(CommandSourceStack commandSource) {
|
||||
if (this.isEnforceWhitelist()) {
|
||||
PlayerList playerList = commandSource.getServer().getPlayerList();
|
||||
@@ -1278,7 +1278,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1859,6 +_,22 @@
|
||||
@@ -1852,6 +_,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1289,19 +1289,14 @@
|
||||
+ }
|
||||
+
|
||||
+ public static MinecraftServer getServer() {
|
||||
+ return SERVER; // Paper
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public static RegistryAccess getDefaultRegistryAccess() {
|
||||
+ return org.bukkit.craftbukkit.CraftRegistry.getMinecraftRegistry();
|
||||
+ return SERVER;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
private ProfilerFiller createProfiler() {
|
||||
if (this.willStartRecordingMetrics) {
|
||||
this.metricsRecorder = ActiveMetricsRecorder.createStarted(
|
||||
@@ -1980,16 +_,22 @@
|
||||
@@ -1973,16 +_,22 @@
|
||||
}
|
||||
|
||||
public void logChatMessage(Component content, ChatType.Bound boundChatType, @Nullable String header) {
|
||||
@@ -1328,7 +1323,7 @@
|
||||
}
|
||||
|
||||
public boolean logIPs() {
|
||||
@@ -2122,4 +_,53 @@
|
||||
@@ -2115,4 +_,53 @@
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -68,7 +68,7 @@
|
||||
});
|
||||
}
|
||||
@@ -247,7 +_,7 @@
|
||||
public void flushDirty(ServerPlayer serverPlayer) {
|
||||
public void flushDirty(ServerPlayer player, boolean showAdvancements) {
|
||||
if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) {
|
||||
Map<ResourceLocation, AdvancementProgress> map = new HashMap<>();
|
||||
- Set<AdvancementHolder> set = new HashSet<>();
|
||||
|
@@ -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
|
||||
|
@@ -7,11 +7,9 @@
|
||||
- MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache
|
||||
+ MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache, @javax.annotation.Nullable io.papermc.paper.configuration.PaperConfigurations paperConfigurations // Paper - add paper configuration files
|
||||
) {
|
||||
- private static final String USERID_CACHE_FILE = "usercache.json";
|
||||
-
|
||||
public static final String USERID_CACHE_FILE = "usercache.json";
|
||||
|
||||
- public static Services create(YggdrasilAuthenticationService authenticationService, File profileRepository) {
|
||||
+ public static final String USERID_CACHE_FILE = "usercache.json"; // Paper - private -> public
|
||||
+
|
||||
+ // Paper start - add paper configuration files
|
||||
+ public Services(MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache) {
|
||||
+ this(sessionService, servicesKeySet, profileRepository, profileCache, null);
|
||||
|
@@ -8,15 +8,6 @@
|
||||
int maxStackSize = itemStack.getMaxStackSize();
|
||||
int i = maxStackSize * 100;
|
||||
if (count > i) {
|
||||
@@ -66,7 +_,7 @@
|
||||
ItemStack itemStack1 = item.createItemStack(min, false);
|
||||
boolean flag = serverPlayer.getInventory().add(itemStack1);
|
||||
if (flag && itemStack1.isEmpty()) {
|
||||
- ItemEntity itemEntity = serverPlayer.drop(itemStack, false);
|
||||
+ ItemEntity itemEntity = serverPlayer.drop(itemStack, false, false, false); // CraftBukkit - SPIGOT-2942: Add boolean to call event
|
||||
if (itemEntity != null) {
|
||||
itemEntity.makeFakeItem();
|
||||
}
|
||||
@@ -95,11 +_,11 @@
|
||||
|
||||
if (targets.size() == 1) {
|
||||
|
@@ -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 {
|
||||
|
@@ -6,10 +6,10 @@
|
||||
|
||||
+ 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)) {
|
||||
+ if (serverPlayer.setRespawnPosition(new ServerPlayer.RespawnConfig(resourceKey, pos, angle, true), false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND)) {
|
||||
+ actualTargets.add(serverPlayer);
|
||||
+ }
|
||||
+ // Paper end - Add PlayerSetSpawnEvent
|
||||
|
@@ -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;
|
||||
});
|
||||
|
@@ -33,56 +33,24 @@
|
||||
this.serverTextFilter = ServerTextFilter.createFromConfig(settings.getProperties());
|
||||
this.serverLinks = createServerLinks(settings);
|
||||
}
|
||||
@@ -102,26 +_,95 @@
|
||||
@@ -102,6 +_,10 @@
|
||||
Thread thread = new Thread("Server console handler") {
|
||||
@Override
|
||||
public void run() {
|
||||
- BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
|
||||
-
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.Main.useConsole) return;
|
||||
+ if (!org.bukkit.craftbukkit.Main.useConsole) return; // CraftBukkit
|
||||
+ // Paper start - Use TerminalConsoleAppender
|
||||
+ new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start();
|
||||
+ /*
|
||||
+ jline.console.ConsoleReader bufferedreader = DedicatedServer.this.reader;
|
||||
+ // MC-33041, SPIGOT-5538: if System.in is not valid due to javaw, then return
|
||||
+ try {
|
||||
+ System.in.available();
|
||||
+ } catch (IOException ex) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
|
||||
|
||||
String string1;
|
||||
try {
|
||||
- while (!DedicatedServer.this.isStopped() && DedicatedServer.this.isRunning() && (string1 = bufferedReader.readLine()) != null) {
|
||||
- DedicatedServer.this.handleConsoleInput(string1, DedicatedServer.this.createCommandSourceStack());
|
||||
+ // CraftBukkit start - JLine disabling compatibility
|
||||
+ while (!DedicatedServer.this.isStopped() && DedicatedServer.this.isRunning()) {
|
||||
+ if (org.bukkit.craftbukkit.Main.useJline) {
|
||||
+ string1 = bufferedreader.readLine(">", null);
|
||||
+ } else {
|
||||
+ string1 = bufferedreader.readLine();
|
||||
+ }
|
||||
+
|
||||
+ // SPIGOT-5220: Throttle if EOF (ctrl^d) or stdin is /dev/null
|
||||
+ if (string1 == null) {
|
||||
+ try {
|
||||
+ Thread.sleep(50L);
|
||||
+ } catch (InterruptedException ex) {
|
||||
+ Thread.currentThread().interrupt();
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (string1.trim().length() > 0) { // Trim to filter lines which are just spaces
|
||||
+ DedicatedServer.this.issueCommand(s, DedicatedServer.this.getServerCommandListener());
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
@@ -111,17 +_,41 @@
|
||||
}
|
||||
} catch (IOException var4) {
|
||||
DedicatedServer.LOGGER.error("Exception handling console input", (Throwable)var4);
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
- }
|
||||
+ }*/
|
||||
+ // Paper end - Use TerminalConsoleAppender
|
||||
}
|
||||
};
|
||||
+ // CraftBukkit start - TODO: handle command-line logging arguments
|
||||
@@ -93,21 +61,7 @@
|
||||
+ }
|
||||
+ global.addHandler(new org.bukkit.craftbukkit.util.ForwardLogHandler());
|
||||
+
|
||||
+ // Paper start - Not needed with TerminalConsoleAppender
|
||||
+ final org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getRootLogger();
|
||||
+ /*
|
||||
+ final org.apache.logging.log4j.core.Logger logger = ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger());
|
||||
+ for (org.apache.logging.log4j.core.Appender appender : logger.getAppenders().values()) {
|
||||
+ if (appender instanceof org.apache.logging.log4j.core.appender.ConsoleAppender) {
|
||||
+ logger.removeAppender(appender);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ TerminalConsoleWriterThread writerThread = new TerminalConsoleWriterThread(System.out, this.reader);
|
||||
+ this.reader.setCompletionHandler(new TerminalCompletionHandler(writerThread, this.reader.getCompletionHandler()));
|
||||
+ writerThread.start();
|
||||
+ */
|
||||
+ // Paper end - Not needed with TerminalConsoleAppender
|
||||
+
|
||||
+ System.setOut(org.apache.logging.log4j.io.IoBuilder.forLogger(logger).setLevel(org.apache.logging.log4j.Level.INFO).buildPrintStream());
|
||||
+ System.setErr(org.apache.logging.log4j.io.IoBuilder.forLogger(logger).setLevel(org.apache.logging.log4j.Level.WARN).buildPrintStream());
|
||||
@@ -187,7 +141,7 @@
|
||||
InetAddress inetAddress = null;
|
||||
if (!this.getLocalIp().isEmpty()) {
|
||||
inetAddress = InetAddress.getByName(this.getLocalIp());
|
||||
@@ -147,36 +_,62 @@
|
||||
@@ -147,36 +_,61 @@
|
||||
if (this.getPort() < 0) {
|
||||
this.setPort(properties.serverPort);
|
||||
}
|
||||
@@ -210,7 +164,6 @@
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ // this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); // Spigot - moved up
|
||||
+ this.server.loadPlugins();
|
||||
+ this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP);
|
||||
+ // CraftBukkit end
|
||||
|
@@ -15,7 +15,7 @@
|
||||
+ }
|
||||
+
|
||||
+ private String getOverride(String name, String value) {
|
||||
+ if ((this.options != null) && (this.options.has(name))) {
|
||||
+ if (this.options != null && this.options.has(name)) {
|
||||
+ return String.valueOf(this.options.valueOf(name));
|
||||
+ }
|
||||
+
|
||||
|
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -145,6 +_,33 @@
|
||||
@@ -149,6 +_,33 @@
|
||||
public int serverViewDistance;
|
||||
private final WorldGenContext worldGenContext;
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
public ChunkMap(
|
||||
ServerLevel level,
|
||||
LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
@@ -171,13 +_,19 @@
|
||||
@@ -176,13 +_,19 @@
|
||||
this.level = level;
|
||||
RegistryAccess registryAccess = level.registryAccess();
|
||||
long seed = level.getSeed();
|
||||
@@ -56,7 +56,7 @@
|
||||
this.mainThreadExecutor = mainThreadExecutor;
|
||||
ConsecutiveExecutor consecutiveExecutor = new ConsecutiveExecutor(dispatcher, "worldgen");
|
||||
this.progressListener = progressListener;
|
||||
@@ -207,6 +_,12 @@
|
||||
@@ -213,6 +_,12 @@
|
||||
this.chunksToEagerlySave.add(chunkPos.toLong());
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
protected ChunkGenerator generator() {
|
||||
return this.worldGenContext.generator();
|
||||
}
|
||||
@@ -354,9 +_,9 @@
|
||||
@@ -352,9 +_,9 @@
|
||||
}
|
||||
);
|
||||
stringBuilder.append("Updating:").append(System.lineSeparator());
|
||||
@@ -81,17 +81,15 @@
|
||||
CrashReport crashReport = CrashReport.forThrowable(exception, "Chunk loading");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Chunk loading");
|
||||
crashReportCategory.setDetail("Details", details);
|
||||
@@ -392,6 +_,9 @@
|
||||
@@ -390,6 +_,7 @@
|
||||
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
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderCreate(this.level, holder); // Paper
|
||||
}
|
||||
|
||||
this.updatingChunkMap.put(chunkPos, holder);
|
||||
@@ -420,8 +_,8 @@
|
||||
@@ -418,8 +_,8 @@
|
||||
|
||||
protected void saveAllChunks(boolean flush) {
|
||||
if (flush) {
|
||||
@@ -102,7 +100,7 @@
|
||||
.stream()
|
||||
.filter(ChunkHolder::wasAccessibleSinceLastSave)
|
||||
.peek(ChunkHolder::refreshAccessibility)
|
||||
@@ -447,7 +_,7 @@
|
||||
@@ -445,7 +_,7 @@
|
||||
this.nextChunkSaveTime.clear();
|
||||
long millis = Util.getMillis();
|
||||
|
||||
@@ -111,7 +109,7 @@
|
||||
this.saveChunkIfNeeded(chunkHolder, millis);
|
||||
}
|
||||
}
|
||||
@@ -468,6 +_,7 @@
|
||||
@@ -466,6 +_,7 @@
|
||||
public boolean hasWork() {
|
||||
return this.lightEngine.hasLightWork()
|
||||
|| !this.pendingUnloads.isEmpty()
|
||||
@@ -119,7 +117,7 @@
|
||||
|| !this.updatingChunkMap.isEmpty()
|
||||
|| this.poiManager.hasWork()
|
||||
|| !this.toDrop.isEmpty()
|
||||
@@ -526,7 +_,11 @@
|
||||
@@ -524,7 +_,11 @@
|
||||
this.scheduleUnload(chunkPos, chunkHolder);
|
||||
} else {
|
||||
ChunkAccess latestChunk = chunkHolder.getLatestChunk();
|
||||
@@ -132,7 +130,7 @@
|
||||
if (latestChunk instanceof LevelChunk levelChunk) {
|
||||
levelChunk.setLoaded(false);
|
||||
}
|
||||
@@ -540,7 +_,9 @@
|
||||
@@ -538,7 +_,9 @@
|
||||
this.lightEngine.tryScheduleUpdate();
|
||||
this.progressListener.onStatusChange(latestChunk.getPos(), null);
|
||||
this.nextChunkSaveTime.remove(latestChunk.getPos().toLong());
|
||||
@@ -143,7 +141,7 @@
|
||||
}
|
||||
}, this.unloadQueue::add).whenComplete((_void, error) -> {
|
||||
if (error != null) {
|
||||
@@ -856,7 +_,7 @@
|
||||
@@ -854,7 +_,7 @@
|
||||
}
|
||||
|
||||
public int size() {
|
||||
@@ -152,7 +150,7 @@
|
||||
}
|
||||
|
||||
public net.minecraft.server.level.DistanceManager getDistanceManager() {
|
||||
@@ -864,7 +_,7 @@
|
||||
@@ -862,7 +_,7 @@
|
||||
}
|
||||
|
||||
protected Iterable<ChunkHolder> getChunks() {
|
||||
@@ -161,9 +159,9 @@
|
||||
}
|
||||
|
||||
void dumpChunks(Writer writer) throws IOException {
|
||||
@@ -888,10 +_,10 @@
|
||||
@@ -885,10 +_,10 @@
|
||||
.addColumn("fluid_ticks")
|
||||
.build(writer);
|
||||
TickingTracker tickingTracker = this.distanceManager.tickingTracker();
|
||||
|
||||
- for (Entry<ChunkHolder> entry : this.visibleChunkMap.long2ObjectEntrySet()) {
|
||||
- long longKey = entry.getLongKey();
|
||||
@@ -175,7 +173,7 @@
|
||||
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 @@
|
||||
@@ -928,11 +_,13 @@
|
||||
}
|
||||
|
||||
private CompletableFuture<Optional<CompoundTag>> readChunk(ChunkPos pos) {
|
||||
@@ -191,18 +189,28 @@
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
void forEachSpawnCandidateChunk(Consumer<ChunkHolder> action) {
|
||||
@@ -951,12 +_,34 @@
|
||||
void collectSpawningChunks(List<LevelChunk> output) {
|
||||
@@ -942,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);
|
||||
}
|
||||
}
|
||||
@@ -962,13 +_,35 @@
|
||||
}
|
||||
|
||||
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);
|
||||
TriState triState = this.distanceManager.hasPlayersNearby(chunkPos.toLong());
|
||||
- return triState == TriState.DEFAULT ? this.anyPlayerCloseEnoughForSpawningInternal(chunkPos) : triState.toBoolean(true);
|
||||
+ return triState == TriState.DEFAULT ? this.anyPlayerCloseEnoughForSpawningInternal(chunkPos, reducedRange) : triState.toBoolean(true);
|
||||
+ // Spigot end
|
||||
}
|
||||
|
||||
@@ -224,12 +232,12 @@
|
||||
+ if (event == null || event.isCancelled()) continue;
|
||||
+ blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4));
|
||||
+ }
|
||||
+ // Paper end - PlayerNaturallySpawnCreaturesEvent
|
||||
+ if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos, blockRange)) {
|
||||
+ // Paper end - PlayerNaturallySpawnCreaturesEvent
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -972,7 +_,7 @@
|
||||
@@ -984,7 +_,7 @@
|
||||
Builder<ServerPlayer> builder = ImmutableList.builder();
|
||||
|
||||
for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
|
||||
@@ -238,7 +246,7 @@
|
||||
builder.add(serverPlayer);
|
||||
}
|
||||
}
|
||||
@@ -981,12 +_,12 @@
|
||||
@@ -993,12 +_,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,13 +255,13 @@
|
||||
if (player.isSpectator()) {
|
||||
return false;
|
||||
} else {
|
||||
double d = euclideanDistanceSquared(chunkPos, player);
|
||||
double d = euclideanDistanceSquared(chunkPos, player.position());
|
||||
- return d < 16384.0;
|
||||
+ return d < range; // Spigot
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,9 +_,19 @@
|
||||
@@ -1120,9 +_,19 @@
|
||||
}
|
||||
|
||||
public void addEntity(Entity entity) {
|
||||
@@ -273,7 +281,7 @@
|
||||
if (i != 0) {
|
||||
int updateInterval = type.updateInterval();
|
||||
if (this.entityMap.containsKey(entity.getId())) {
|
||||
@@ -1126,6 +_,7 @@
|
||||
@@ -1146,6 +_,7 @@
|
||||
}
|
||||
|
||||
protected void removeEntity(Entity entity) {
|
||||
@@ -281,16 +289,7 @@
|
||||
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 @@
|
||||
@@ -1278,10 +_,10 @@
|
||||
final Entity entity;
|
||||
private final int range;
|
||||
SectionPos lastSectionPos;
|
||||
@@ -298,12 +297,12 @@
|
||||
+ 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.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 @@
|
||||
@@ -1325,24 +_,47 @@
|
||||
}
|
||||
|
||||
public void removePlayer(ServerPlayer player) {
|
||||
@@ -356,7 +355,7 @@
|
||||
}
|
||||
} else if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
@@ -1331,6 +_,7 @@
|
||||
@@ -1359,6 +_,7 @@
|
||||
|
||||
for (Entity entity : this.entity.getIndirectPassengers()) {
|
||||
int i1 = entity.getType().clientTrackingRange() * 16;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/DistanceManager.java
|
||||
+++ b/net/minecraft/server/level/DistanceManager.java
|
||||
@@ -107,6 +_,12 @@
|
||||
@@ -72,6 +_,12 @@
|
||||
}
|
||||
|
||||
if (!this.chunksToUpdateFutures.isEmpty()) {
|
||||
@@ -13,51 +13,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 +26,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;
|
||||
|
@@ -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 void addTicketAtLevel(TicketType ticketType, ChunkPos chunkPos, int ticketLevel) {
|
||||
+ this.ticketStorage.addTicket(new Ticket(ticketType, ticketLevel), chunkPos);
|
||||
+ }
|
||||
+
|
||||
+ public <T> void removeTicketAtLevel(TicketType<T> ticketType, ChunkPos chunkPos, int ticketLevel, T identifier) {
|
||||
+ this.distanceManager.removeTicket(ticketType, chunkPos, ticketLevel, identifier);
|
||||
+ public void removeTicketAtLevel(TicketType ticketType, ChunkPos chunkPos, int ticketLevel) {
|
||||
+ this.ticketStorage.removeTicket(new Ticket(ticketType, ticketLevel), chunkPos);
|
||||
+ }
|
||||
+
|
||||
+ // "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,16 +122,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -287,7 +_,7 @@
|
||||
return this.mainThreadProcessor.pollTask();
|
||||
}
|
||||
|
||||
- boolean runDistanceManagerUpdates() {
|
||||
+ public boolean runDistanceManagerUpdates() { // Paper - public
|
||||
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 +146,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 +161,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 +188,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 +203,7 @@
|
||||
}
|
||||
|
||||
public String getChunkDebugData(ChunkPos chunkPos) {
|
||||
@@ -603,12 +_,18 @@
|
||||
@@ -618,12 +_,18 @@
|
||||
|
||||
@Override
|
||||
public boolean pollTask() {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user