mirror of
https://github.com/SparklyPower/SparklyPaper.git
synced 2025-12-23 17:09:22 +00:00
Update to Paper 1.21.4 (post hard fork™️ edition)
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Mon, 13 Jan 2025 13:20:31 -0300
|
||||
Subject: [PATCH] SparklyPaper config files
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 97a294d2f5c1ddf0af7ffec3e1425eb329c5751b..4c420e17d936132bb4569776911757fd959e93d6 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -224,6 +224,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
|
||||
this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
|
||||
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
|
||||
+ // SparklyPaper start
|
||||
+ try {
|
||||
+ net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils.INSTANCE.init((java.io.File) options.valueOf("sparklypaper-settings"));
|
||||
+ } catch (Exception e) {
|
||||
+ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.sparklypower.sparklypaper.SparklyPaperCommands.INSTANCE.registerCommands(this);
|
||||
+ // SparklyPaper end
|
||||
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
|
||||
|
||||
this.setPvpAllowed(properties.pvp);
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 2bbebb4335d927f240abcac67a5b423e38dc33d7..27c2ea4a387ee5f7d078a42cb57f146cb748501d 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -170,6 +170,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
// Paper end - add paper world config
|
||||
|
||||
public final io.papermc.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
|
||||
+ public net.sparklypower.sparklypaper.configs.SparklyPaperConfig.SparklyPaperWorldConfig sparklyPaperConfig; // SparklyPaper
|
||||
public static BlockPos lastPhysicsProblem; // Spigot
|
||||
private org.spigotmc.TickLimiter entityLimiter;
|
||||
private org.spigotmc.TickLimiter tileLimiter;
|
||||
@@ -853,6 +854,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
// Paper end - getblock optimisations - cache world height/sections
|
||||
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
|
||||
+ this.sparklyPaperConfig = net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils.INSTANCE.getWorldSettings(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // SparklyPaper
|
||||
this.generator = gen;
|
||||
this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Mon, 13 Jan 2025 14:19:31 -0300
|
||||
Subject: [PATCH] Skip "distanceToSqr" call in "ServerEntity#sendChanges" if
|
||||
the delta movement hasn't changed
|
||||
|
||||
The "distanceToSqr" call is a bit expensive, so avoiding it is pretty nice, around ~15% calls are skipped with this check
|
||||
|
||||
We could also check if the x,y,z coordinates are equal, but for now, let's just keep the identity check, which also helps us since Minecraft's code does reuse the original delta movement Vec3 object
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
||||
index 0fb253aa55a24b56b17f524b3261c5b75c7d7e59..8d0c259efc31de7de0ca5b900376677552e81f81 100644
|
||||
--- a/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -195,6 +195,7 @@ public class ServerEntity {
|
||||
|
||||
if (this.entity.hasImpulse || this.trackDelta || this.entity instanceof LivingEntity && ((LivingEntity)this.entity).isFallFlying()) {
|
||||
Vec3 deltaMovement = this.entity.getDeltaMovement();
|
||||
+ if (deltaMovement != this.lastSentMovement) { // SparklyPaper start - skip distanceToSqr call in ServerEntity#sendChanges if the delta movement hasn't changed
|
||||
double d = deltaMovement.distanceToSqr(this.lastSentMovement);
|
||||
if (d > 1.0E-7 || d > 0.0 && deltaMovement.lengthSqr() == 0.0) {
|
||||
this.lastSentMovement = deltaMovement;
|
||||
@@ -212,6 +213,7 @@ public class ServerEntity {
|
||||
this.broadcast.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement));
|
||||
}
|
||||
}
|
||||
+ } // SparklyPaper end
|
||||
}
|
||||
|
||||
if (packet != null) {
|
||||
@@ -0,0 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Fri, 17 Nov 2023 14:22:41 -0300
|
||||
Subject: [PATCH] Skip "MapItem#update()" if the map does not have the
|
||||
CraftMapRenderer present
|
||||
|
||||
Optimizes "image in map" maps, without requiring the map to be locked, which some old map plugins may not do
|
||||
|
||||
This has the disadvantage that the vanilla map data will never be updated while the CraftMapRenderer is not present, but that's not a huuuge problem for us
|
||||
|
||||
diff --git a/net/minecraft/world/item/MapItem.java b/net/minecraft/world/item/MapItem.java
|
||||
index 8795d54cff569c911e0a535f38a0ec4130f7b4d5..31960e54bf5ed4aa31cd12b60ab0fa263902ce2c 100644
|
||||
--- a/net/minecraft/world/item/MapItem.java
|
||||
+++ b/net/minecraft/world/item/MapItem.java
|
||||
@@ -277,7 +277,7 @@ public class MapItem extends Item {
|
||||
savedData.tickCarriedBy(player, stack);
|
||||
}
|
||||
|
||||
- if (!savedData.locked && (isSelected || entity instanceof Player && ((Player)entity).getOffhandItem() == stack)) {
|
||||
+ if (!savedData.locked && (!level.sparklyPaperConfig.getSkipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer() || savedData.mapView.getRenderers().stream().anyMatch(mapRenderer -> mapRenderer.getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class)) && (isSelected || entity instanceof Player && ((Player)entity).getOffhandItem() == stack)) { // SparklyPaper - don't update maps if they don't have the CraftMapRenderer in the render list
|
||||
this.update(level, entity, savedData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Mon, 13 Jan 2025 14:32:08 -0300
|
||||
Subject: [PATCH] Skip dirty stats copy when requesting player stats
|
||||
|
||||
|
||||
diff --git a/net/minecraft/stats/ServerStatsCounter.java b/net/minecraft/stats/ServerStatsCounter.java
|
||||
index 6c5205fe1dc6387a77b1edbdcab748d39e775d7f..c6e4a7668ed923d93bd7f67d19af82d5d84a0dc0 100644
|
||||
--- a/net/minecraft/stats/ServerStatsCounter.java
|
||||
+++ b/net/minecraft/stats/ServerStatsCounter.java
|
||||
@@ -81,11 +81,15 @@ public class ServerStatsCounter extends StatsCounter {
|
||||
this.dirty.add(stat);
|
||||
}
|
||||
|
||||
+ // SparklyPaper start - Skip dirty stats copy when requesting player stats
|
||||
+ /*
|
||||
private Set<Stat<?>> getDirty() {
|
||||
Set<Stat<?>> set = Sets.newHashSet(this.dirty);
|
||||
this.dirty.clear();
|
||||
return set;
|
||||
}
|
||||
+ */
|
||||
+ // SparklyPaper end
|
||||
|
||||
public void parseLocal(DataFixer fixerUpper, String json) {
|
||||
try {
|
||||
@@ -190,10 +194,12 @@ public class ServerStatsCounter extends StatsCounter {
|
||||
public void sendStats(ServerPlayer player) {
|
||||
Object2IntMap<Stat<?>> map = new Object2IntOpenHashMap<>();
|
||||
|
||||
- for (Stat<?> stat : this.getDirty()) {
|
||||
+ for (Stat<?> stat : this.dirty) { // SparklyPaper - Skip dirty stats copy when requesting player stats
|
||||
map.put(stat, this.getValue(stat));
|
||||
}
|
||||
|
||||
+ this.dirty.clear(); // SparklyPaper - Skip dirty stats copy when requesting player stats
|
||||
+
|
||||
player.connection.send(new ClientboundAwardStatsPacket(map));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Sun, 19 Nov 2023 12:35:16 -0300
|
||||
Subject: [PATCH] Skip EntityScheduler's executeTick checks if there isn't any
|
||||
tasks to be run
|
||||
|
||||
On each tick, Paper runs EntityScheduler's executeTick of each entity. This is a bit expensive, due to ArrayDeque's size() call because it ain't a simple "get the current queue size" function, due to the thread checks, and because it needs to iterate all entities in all worlds.
|
||||
|
||||
To avoid the hefty ArrayDeque's size() call, we check if we *really* need to execute the executeTick, by adding all entities with scheduled tasks to a global set.
|
||||
|
||||
Most entities won't have any scheduled tasks, so this is a nice performance bonus. These optimizations, however, wouldn't work in a Folia environment, but because in SparklyPaper executeTick is always executed on the main thread, it ain't an issue for us (yay).
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index ae220a732c78ab076261f20b5a54c71d7fceb407..6ad6bfe60026be304aa2178d5f04a79531cc66a6 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -303,6 +303,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
|
||||
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
|
||||
public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
|
||||
+ public final Set<net.minecraft.world.entity.Entity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
|
||||
|
||||
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
|
||||
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
|
||||
@@ -1659,6 +1660,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit
|
||||
// Paper start - Folia scheduler API
|
||||
((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) org.bukkit.Bukkit.getGlobalRegionScheduler()).tick();
|
||||
+ // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
||||
+ for (final net.minecraft.world.entity.Entity entity : entitiesWithScheduledTasks) {
|
||||
+ if (entity.isRemoved()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final org.bukkit.craftbukkit.entity.CraftEntity bukkit = entity.getBukkitEntityRaw();
|
||||
+ if (bukkit != null) {
|
||||
+ bukkit.taskScheduler.executeTick();
|
||||
+ }
|
||||
+ }
|
||||
+ /*
|
||||
getAllLevels().forEach(level -> {
|
||||
for (final net.minecraft.world.entity.Entity entity : level.getEntities().getAll()) {
|
||||
if (entity.isRemoved()) {
|
||||
@@ -1670,6 +1683,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
});
|
||||
+ */
|
||||
+ // SparklyPaper end
|
||||
// Paper end - Folia scheduler API
|
||||
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper
|
||||
profilerFiller.push("commandFunctions");
|
||||
@@ -0,0 +1,180 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Mon, 13 Jan 2025 14:50:47 -0300
|
||||
Subject: [PATCH] Blazingly Simple Farm Checks
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/CropBlock.java b/net/minecraft/world/level/block/CropBlock.java
|
||||
index bc0969f40814094e42a860a72314fccd1a66fabe..c14de811ae7cead820a00a87b9d2ce8cfb241d92 100644
|
||||
--- a/net/minecraft/world/level/block/CropBlock.java
|
||||
+++ b/net/minecraft/world/level/block/CropBlock.java
|
||||
@@ -87,6 +87,57 @@ public class CropBlock extends BushBlock implements BonemealableBlock {
|
||||
if (level.getRawBrightness(pos, 0) >= 9) {
|
||||
int age = this.getAge(state);
|
||||
if (age < this.getMaxAge()) {
|
||||
+ // SparklyPaper start - Blazingly simple farm checks
|
||||
+ if (level.sparklyPaperConfig.getBlazinglySimpleFarmChecks().getEnabled()) {
|
||||
+ // These checks are similar to getGrowthSpeed, but we have "inlined" them because we want to access stuff like the farm block data later on
|
||||
+ // Is the block below us moisturised?
|
||||
+ BlockPos farmlandBelowTheCurrentBlock = pos.below();
|
||||
+ BlockState farmlandBelowTheCurrentBlockData = level.getBlockState(farmlandBelowTheCurrentBlock);
|
||||
+ float f = level.sparklyPaperConfig.getBlazinglySimpleFarmChecks().getDefaultGrowthSpeed();
|
||||
+ boolean isCurrentFarmlandStateMoist = false;
|
||||
+ if (farmlandBelowTheCurrentBlockData.is(Blocks.FARMLAND)) {
|
||||
+ if ((Integer) farmlandBelowTheCurrentBlockData.getValue(FarmBlock.MOISTURE) > 0) {
|
||||
+ // If we are currently moist, increase the speed!
|
||||
+ f = level.sparklyPaperConfig.getBlazinglySimpleFarmChecks().getMoistGrowthSpeed();
|
||||
+ isCurrentFarmlandStateMoist = true;
|
||||
+ }
|
||||
+ }
|
||||
+ // If we are skipping the middle aging stages, we need to change the growth speed and the next stage accordingly
|
||||
+ if (level.sparklyPaperConfig.getBlazinglySimpleFarmChecks().getSkipMiddleAgingStagesForCrops()) {
|
||||
+ f = f / getMaxAge();
|
||||
+ age = getMaxAge() - 1;
|
||||
+ }
|
||||
+
|
||||
+ // Spigot start
|
||||
+ int modifier;
|
||||
+ if (this == Blocks.BEETROOTS) {
|
||||
+ modifier = level.spigotConfig.beetrootModifier;
|
||||
+ } else if (this == Blocks.CARROTS) {
|
||||
+ modifier = level.spigotConfig.carrotModifier;
|
||||
+ } else if (this == Blocks.POTATOES) {
|
||||
+ modifier = level.spigotConfig.potatoModifier;
|
||||
+ // Paper start
|
||||
+ } else if (this == Blocks.TORCHFLOWER_CROP) {
|
||||
+ modifier = level.spigotConfig.torchFlowerModifier;
|
||||
+ // Paper end
|
||||
+ } else {
|
||||
+ modifier = level.spigotConfig.wheatModifier;
|
||||
+ }
|
||||
+
|
||||
+ if (random.nextFloat() < (modifier / (100.0f * (Math.floor((25.0F / f) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution
|
||||
+ // Spigot end
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, this.getStateForAge(age + 1), 2)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Now that we know that the crop will grow... is the next stage the crop's max age? If yes, we are going to check if the farm land is moist!
|
||||
+ if (age + 1 == getMaxAge() && isCurrentFarmlandStateMoist && !FarmBlock.isNearWater(level, farmlandBelowTheCurrentBlock)) {
|
||||
+ // Whoops, farm land ain't moist!
|
||||
+ // From FarmBlock, set the moisture to 0
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(level, farmlandBelowTheCurrentBlock, (BlockState) farmlandBelowTheCurrentBlockData.setValue(FarmBlock.MOISTURE, 0), 2); // CraftBukkit
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
float growthSpeed = getGrowthSpeed(this, level, pos);
|
||||
// Spigot start
|
||||
int modifier = 100;
|
||||
@@ -108,6 +159,8 @@ public class CropBlock extends BushBlock implements BonemealableBlock {
|
||||
// Spigot end
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, this.getStateForAge(age + 1), 2); // CraftBukkit
|
||||
}
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/FarmBlock.java b/net/minecraft/world/level/block/FarmBlock.java
|
||||
index 47c9b32c89e7e6f84a279c2f6098ada77dc58b6b..06a33e6f6118c2f2dce567efc2e23cbf877b7a9c 100644
|
||||
--- a/net/minecraft/world/level/block/FarmBlock.java
|
||||
+++ b/net/minecraft/world/level/block/FarmBlock.java
|
||||
@@ -95,6 +95,19 @@ public class FarmBlock extends Block {
|
||||
@Override
|
||||
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
|
||||
int moistureValue = state.getValue(MOISTURE);
|
||||
+ // SparklyPaper start - Blazingly simple farm checks
|
||||
+ if (level.sparklyPaperConfig.getBlazinglySimpleFarmChecks().getEnabled()) {
|
||||
+ if (moistureValue == 0) { // We only care about non-moisturised farm blocks
|
||||
+ if (FarmBlock.isNearWater(level, pos)) {
|
||||
+ // Make it MOIST!
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(level, pos, (BlockState) state.setValue(FarmBlock.MOISTURE, 7), 2); // CraftBukkit
|
||||
+ } else if (!FarmBlock.shouldMaintainFarmland(level, pos)) {
|
||||
+ FarmBlock.turnToDirt((Entity) null, state, level, pos);
|
||||
+ }
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
if (moistureValue > 0 && level.paperConfig().tickRates.wetFarmland != 1 && (level.paperConfig().tickRates.wetFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % level.paperConfig().tickRates.wetFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks
|
||||
if (moistureValue == 0 && level.paperConfig().tickRates.dryFarmland != 1 && (level.paperConfig().tickRates.dryFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % level.paperConfig().tickRates.dryFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks
|
||||
if (!isNearWater(level, pos) && !level.isRainingAt(pos.above())) {
|
||||
@@ -154,7 +167,7 @@ public class FarmBlock extends Block {
|
||||
return level.getBlockState(pos.above()).is(BlockTags.MAINTAINS_FARMLAND);
|
||||
}
|
||||
|
||||
- private static boolean isNearWater(LevelReader level, BlockPos pos) {
|
||||
+ public static boolean isNearWater(LevelReader level, BlockPos pos) { // SparklyPaper - make public for the Blazingly simple farm checks
|
||||
// Paper start - Perf: remove abstract block iteration
|
||||
int xOff = pos.getX();
|
||||
int yOff = pos.getY();
|
||||
diff --git a/net/minecraft/world/level/block/StemBlock.java b/net/minecraft/world/level/block/StemBlock.java
|
||||
index 3dca57dd0c00dc64724cbc7f5a71963da9d12fd5..9839821365484bac93023b1aa542619dae4c88cf 100644
|
||||
--- a/net/minecraft/world/level/block/StemBlock.java
|
||||
+++ b/net/minecraft/world/level/block/StemBlock.java
|
||||
@@ -79,6 +79,56 @@ public class StemBlock extends BushBlock implements BonemealableBlock {
|
||||
@Override
|
||||
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
|
||||
if (level.getRawBrightness(pos, 0) >= 9) {
|
||||
+ // SparklyPaper start - Blazingly simple farm checks
|
||||
+ if (level.sparklyPaperConfig.getBlazinglySimpleFarmChecks().getEnabled()) {
|
||||
+ // These checks are similar to getGrowthSpeed, but we have "inlined" them because we want to access stuff like the farm block data later on
|
||||
+ // Is the block below us moisturised?
|
||||
+ BlockPos farmlandBelowTheCurrentBlock = pos.below();
|
||||
+ BlockState farmlandBelowTheCurrentBlockData = level.getBlockState(farmlandBelowTheCurrentBlock);
|
||||
+ float f = level.sparklyPaperConfig.getBlazinglySimpleFarmChecks().getDefaultGrowthSpeed();
|
||||
+ boolean isCurrentFarmlandStateMoist = false;
|
||||
+ if (farmlandBelowTheCurrentBlockData.is(Blocks.FARMLAND)) {
|
||||
+ if ((Integer) farmlandBelowTheCurrentBlockData.getValue(FarmBlock.MOISTURE) > 0) {
|
||||
+ // If we are currently moist, increase the speed!
|
||||
+ f = level.sparklyPaperConfig.getBlazinglySimpleFarmChecks().getMoistGrowthSpeed();
|
||||
+ isCurrentFarmlandStateMoist = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (random.nextFloat() < ((this == Blocks.PUMPKIN_STEM ? level.spigotConfig.pumpkinModifier : level.spigotConfig.melonModifier) / (100.0f * (Math.floor((25.0F / f) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution
|
||||
+ int i = (Integer) state.getValue(StemBlock.AGE);
|
||||
+
|
||||
+ if (i < 7) {
|
||||
+ state = (BlockState) state.setValue(StemBlock.AGE, i + 1);
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state, 2); // CraftBukkit
|
||||
+ } else {
|
||||
+ Direction enumdirection = Direction.Plane.HORIZONTAL.getRandomDirection(random);
|
||||
+ BlockPos blockposition1 = pos.relative(enumdirection);
|
||||
+ BlockState iblockdata1 = level.getBlockState(blockposition1.below());
|
||||
+
|
||||
+ if (level.getBlockState(blockposition1).isAir() && (iblockdata1.is(Blocks.FARMLAND) || iblockdata1.is(BlockTags.DIRT))) {
|
||||
+ Registry<Block> iregistry = net.minecraft.core.registries.BuiltInRegistries.BLOCK;
|
||||
+ Optional<Block> optional = iregistry.getOptional(this.fruit);
|
||||
+ Optional<Block> optional1 = iregistry.getOptional(this.attachedStem);
|
||||
+
|
||||
+ if (optional.isPresent() && optional1.isPresent()) {
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockposition1, ((Block) optional.get()).defaultBlockState())) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Now that we know that the crop will grow... is the next stage the crop's max age? If yes, we are going to check if the farm land is moist!
|
||||
+ if (isCurrentFarmlandStateMoist && !FarmBlock.isNearWater(level, farmlandBelowTheCurrentBlock)) {
|
||||
+ // Whoops, farm land ain't moist!
|
||||
+ // From FarmBlock, set the moisture to 0
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(level, farmlandBelowTheCurrentBlock, (BlockState) farmlandBelowTheCurrentBlockData.setValue(FarmBlock.MOISTURE, 0), 2); // CraftBukkit
|
||||
+ }
|
||||
+ level.setBlockAndUpdate(pos, (BlockState) ((Block) optional1.get()).defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, enumdirection));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
float growthSpeed = CropBlock.getGrowthSpeed(this, level, pos);
|
||||
if (random.nextFloat() < ((this == Blocks.PUMPKIN_STEM ? level.spigotConfig.pumpkinModifier : level.spigotConfig.melonModifier) / (100.0f * (Math.floor((25.0F / growthSpeed) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution
|
||||
int ageValue = state.getValue(AGE);
|
||||
@@ -105,6 +155,8 @@ public class StemBlock extends BushBlock implements BonemealableBlock {
|
||||
}
|
||||
}
|
||||
}
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,109 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Tue, 21 Nov 2023 16:50:04 -0300
|
||||
Subject: [PATCH] Spooky month optimizations
|
||||
|
||||
The quintessential patch that other performance forks also have for... some reason??? I thought that this optimization was too funny to not do it in SparklyPaper.
|
||||
|
||||
Caches when Bat's spooky season starts and ends, and when Skeleton and Zombies halloween starts and ends. The epoch is updated every 90 days. If your server is running for 90+ days straight without restarts, congratulations!
|
||||
|
||||
Avoids unnecessary date checks, even tho that this shouldn't really improve performance that much... unless you have a lot of bats/zombies/skeletons spawning.
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 6ad6bfe60026be304aa2178d5f04a79531cc66a6..4dbf2d9aa52029122f4816ca3504fa330b28a29b 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -304,6 +304,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
|
||||
public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
|
||||
public final Set<net.minecraft.world.entity.Entity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
|
||||
+ public net.sparklypower.sparklypaper.HalloweenManager halloweenManager = new net.sparklypower.sparklypaper.HalloweenManager(); // SparklyPaper - Spooky month optimizations
|
||||
|
||||
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
|
||||
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 4c420e17d936132bb4569776911757fd959e93d6..6ac73610f6039290c4ef3dde2206b6863d2b5067 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -233,6 +233,10 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
net.sparklypower.sparklypaper.SparklyPaperCommands.INSTANCE.registerCommands(this);
|
||||
// SparklyPaper end
|
||||
+ // SparklyPaper start - Spooky month optimizations
|
||||
+ halloweenManager.startHalloweenEpochTask();
|
||||
+ halloweenManager.waitUntilEpochHasBeenUpdated();
|
||||
+ // SparklyPaper end
|
||||
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
|
||||
|
||||
this.setPvpAllowed(properties.pvp);
|
||||
diff --git a/net/minecraft/world/entity/ambient/Bat.java b/net/minecraft/world/entity/ambient/Bat.java
|
||||
index 5ebe7b1dce367d5c5e1136b97b2b9f6737595201..b003fa86fab9a6106c9875205d73e49e46904498 100644
|
||||
--- a/net/minecraft/world/entity/ambient/Bat.java
|
||||
+++ b/net/minecraft/world/entity/ambient/Bat.java
|
||||
@@ -231,7 +231,7 @@ public class Bat extends AmbientCreature {
|
||||
} else {
|
||||
int maxLocalRawBrightness = level.getMaxLocalRawBrightness(pos);
|
||||
int i = 4;
|
||||
- if (isHalloween()) {
|
||||
+ if (level.getServer().halloweenManager.isSpookySeason()) {
|
||||
i = 7;
|
||||
} else if (randomSource.nextBoolean()) {
|
||||
return false;
|
||||
@@ -243,12 +243,15 @@ public class Bat extends AmbientCreature {
|
||||
}
|
||||
}
|
||||
|
||||
+ // SparklyPaper - Spooky month optimizations
|
||||
+ /*
|
||||
private static boolean isHalloween() {
|
||||
LocalDate localDate = LocalDate.now();
|
||||
int i = localDate.get(ChronoField.DAY_OF_MONTH);
|
||||
int i1 = localDate.get(ChronoField.MONTH_OF_YEAR);
|
||||
return i1 == 10 && i >= 20 || i1 == 11 && i <= 3;
|
||||
}
|
||||
+ */
|
||||
|
||||
private void setupAnimationStates() {
|
||||
if (this.isResting()) {
|
||||
diff --git a/net/minecraft/world/entity/monster/AbstractSkeleton.java b/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
index 37abc7769573e3cdda380166dd086551d5e7bd88..be623fd09ca573922297d3af3cd114160ec05061 100644
|
||||
--- a/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
+++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
@@ -158,10 +158,12 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
|
||||
this.reassessWeaponGoal();
|
||||
this.setCanPickUpLoot(this.level().paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.skeletons || random.nextFloat() < 0.55F * difficulty.getSpecialMultiplier()); // Paper - Add world settings for mobs picking up loot
|
||||
if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
|
||||
- LocalDate localDate = LocalDate.now();
|
||||
- int i = localDate.get(ChronoField.DAY_OF_MONTH);
|
||||
- int i1 = localDate.get(ChronoField.MONTH_OF_YEAR);
|
||||
- if (i1 == 10 && i == 31 && random.nextFloat() < 0.25F) {
|
||||
+ // SparklyPaper start - Spooky month optimizations
|
||||
+ // LocalDate localDate = LocalDate.now();
|
||||
+ // int i = localDate.get(ChronoField.DAY_OF_MONTH);
|
||||
+ // int i1 = localDate.get(ChronoField.MONTH_OF_YEAR);
|
||||
+ if (this.getServer().halloweenManager.isHalloween() /* i1 == 10 && i == 31 */&& random.nextFloat() < 0.25F) {
|
||||
+ // SparklyPaper end
|
||||
this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(random.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN));
|
||||
this.armorDropChances[EquipmentSlot.HEAD.getIndex()] = 0.0F;
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java
|
||||
index 637790ff833abaa0c52fdee204abba7077d12ccc..600b96d4b2645e26fd690ac70d3901d567b7bc24 100644
|
||||
--- a/net/minecraft/world/entity/monster/Zombie.java
|
||||
+++ b/net/minecraft/world/entity/monster/Zombie.java
|
||||
@@ -550,10 +550,12 @@ public class Zombie extends Monster {
|
||||
}
|
||||
|
||||
if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
|
||||
- LocalDate localDate = LocalDate.now();
|
||||
- int i = localDate.get(ChronoField.DAY_OF_MONTH);
|
||||
- int i1 = localDate.get(ChronoField.MONTH_OF_YEAR);
|
||||
- if (i1 == 10 && i == 31 && random.nextFloat() < 0.25F) {
|
||||
+ // SparklyPaper start - Spooky month optimizations
|
||||
+ // LocalDate localDate = LocalDate.now();
|
||||
+ // int i = localDate.get(ChronoField.DAY_OF_MONTH);
|
||||
+ // int i1 = localDate.get(ChronoField.MONTH_OF_YEAR);
|
||||
+ if (this.getServer().halloweenManager.isHalloween() /* i1 == 10 && i == 31 */&& random.nextFloat() < 0.25F) {
|
||||
+ // SparklyPaper end
|
||||
this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(random.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN));
|
||||
this.armorDropChances[EquipmentSlot.HEAD.getIndex()] = 0.0F;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Mon, 13 Jan 2025 15:03:52 -0300
|
||||
Subject: [PATCH] Optimize canSee checks
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index b3f498558614243cf633dcd71e3c49c2c55e6e0f..ad9ab7fe6df3880c730388a50741b7938b037ff2 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1232,7 +1232,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
flag = flag && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
|
||||
// Paper end - Configurable entity tracking range by Y
|
||||
// CraftBukkit start - respect vanish API
|
||||
- if (flag && !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Paper - only consider hits
|
||||
+ if (flag && !player.getBukkitEntity().canSeeChunkMapUpdatePlayer(this.entity.getBukkitEntity())) { // Paper - only consider hits // SparklyPaper - optimize canSee checks
|
||||
flag = false;
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Mon, 13 Jan 2025 16:41:37 -0300
|
||||
Subject: [PATCH] Fix MC-117075: TE Unload Lag Spike
|
||||
|
||||
We replaced the `blockEntityTickers` list with a custom list based on fastutil's `ObjectArrayList` with a small yet huge change for us: A method that allows us to remove a list of indexes from the list.
|
||||
|
||||
This is WAY FASTER than using `removeAll` with a list of entries to be removed, because we don't need to calculate the identity of each block entity to be removed, and we can jump directly to where the search should begin, giving a performance boost for small removals (because we don't need to loop thru the entire list to find what element should be removed) and a performance boost for big removals (no need to calculate the identity of each block entity).
|
||||
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 27c2ea4a387ee5f7d078a42cb57f146cb748501d..644ab8b2c797f0675530a3efe23a878899689d66 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -115,7 +115,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
public static final int TICKS_PER_DAY = 24000;
|
||||
public static final int MAX_ENTITY_SPAWN_Y = 20000000;
|
||||
public static final int MIN_ENTITY_SPAWN_Y = -20000000;
|
||||
- public final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList(); // Paper - public
|
||||
+ public final net.sparklypower.sparklypaper.BlockEntityTickersList blockEntityTickers = new net.sparklypower.sparklypaper.BlockEntityTickersList(); // Paper - public // SparklyPaper - optimize block entity removals
|
||||
protected final NeighborUpdater neighborUpdater;
|
||||
private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
|
||||
private boolean tickingBlockEntities;
|
||||
@@ -1479,7 +1479,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
TickingBlockEntity tickingBlockEntity = this.blockEntityTickers.get(this.tileTickPosition);
|
||||
// Spigot end
|
||||
if (tickingBlockEntity.isRemoved()) {
|
||||
- toRemove.add(tickingBlockEntity); // Paper - Fix MC-117075; use removeAll
|
||||
+ this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // toRemove.add(tickingBlockEntity); // SparklyPaper - optimize block entity removals // Paper - Fix MC-117075; use removeAll
|
||||
} else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) {
|
||||
tickingBlockEntity.tick();
|
||||
// Paper start - rewrite chunk system
|
||||
@@ -1491,6 +1491,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
}
|
||||
this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075
|
||||
|
||||
+ this.blockEntityTickers.removeMarkedEntries(); // SparklyPaper - optimize block entity removals
|
||||
this.tickingBlockEntities = false;
|
||||
profilerFiller.pop();
|
||||
this.spigotConfig.currentPrimedTnt = 0; // Spigot
|
||||
@@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Mon, 6 Nov 2023 21:54:33 -0300
|
||||
Subject: [PATCH] Track how much MSPT each world used
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 4dbf2d9aa52029122f4816ca3504fa330b28a29b..c15c11ab3feaca918ac0185383cd1653200cd186 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1737,7 +1737,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
profilerFiller.push("tick");
|
||||
|
||||
try {
|
||||
+ long i = Util.getNanos(); // SparklyPaper - track world's MSPT
|
||||
serverLevel.tick(hasTimeLeft);
|
||||
+ // SparklyPaper start - track world's MSPT
|
||||
+ long j = Util.getNanos() - i;
|
||||
+
|
||||
+ // These are from the "tickServer" function
|
||||
+ serverLevel.tickTimes5s.add(this.tickCount, j);
|
||||
+ serverLevel.tickTimes10s.add(this.tickCount, j);
|
||||
+ serverLevel.tickTimes60s.add(this.tickCount, j);
|
||||
+ // SparklyPaper end
|
||||
} catch (Throwable var7) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var7, "Exception ticking world");
|
||||
serverLevel.fillReportDetails(crashReport);
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index ebeeb63c3dca505a3ce8b88feaa5d2ca20ec24a2..59465ab6d7723d27b1597cc7094b5044a3f24250 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -570,6 +570,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
// Paper end - chunk tick iteration
|
||||
|
||||
+ // SparklyPaper start - track world's MSPT
|
||||
+ public final MinecraftServer.TickTimes tickTimes5s = new MinecraftServer.TickTimes(100);
|
||||
+ public final MinecraftServer.TickTimes tickTimes10s = new MinecraftServer.TickTimes(200);
|
||||
+ public final MinecraftServer.TickTimes tickTimes60s = new MinecraftServer.TickTimes(1200);
|
||||
+ // SparklyPaper end
|
||||
+
|
||||
public ServerLevel(
|
||||
MinecraftServer server,
|
||||
Executor dispatcher,
|
||||
@@ -0,0 +1,21 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Wed, 5 Jun 2024 15:20:00 -0300
|
||||
Subject: [PATCH] Reset dirty flag when loading maps from the disk
|
||||
|
||||
By default, the server will start rewriting all map datas to the disk after loading it, even if the map didn't have any changes
|
||||
|
||||
This also slows down world saving a lot if you have a lot of maps
|
||||
|
||||
diff --git a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
index f5a131e870a4f1ad06ebfb1f360720cf19656fb5..2aed9d55ea1a93b323865141a69c9947759eae29 100644
|
||||
--- a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
+++ b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
@@ -197,6 +197,7 @@ public class MapItemSavedData extends SavedData {
|
||||
}
|
||||
}
|
||||
|
||||
+ mapItemSavedData.setDirty(false); // SparklyPaper - reset dirty flag when loading maps from the disk (context for updates: this modification is at the end of the map "load" function)
|
||||
return mapItemSavedData;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Mon, 10 Jun 2024 13:06:30 -0300
|
||||
Subject: [PATCH] Helpful NMS packet changes
|
||||
|
||||
Some nice changes to the packet internals to make packet sending and manipulation easier for us to avoid Reflection and JVM internals (ooo theUnsafe spooky) usage
|
||||
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java b/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
|
||||
index 1373977b339405ef59bb3ea03d195285c96dd3fe..20a782d1bb7355bbdc0822a02204e1e05dc44145 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
|
||||
@@ -22,7 +22,7 @@ public class ClientboundAddEntityPacket implements Packet<ClientGamePacketListen
|
||||
private static final double LIMIT = 3.9;
|
||||
private final int id;
|
||||
private final UUID uuid;
|
||||
- private final EntityType<?> type;
|
||||
+ public EntityType<?> type; // SparklyPaper - Helpful NMS packet changes: remove final and make public
|
||||
private final double x;
|
||||
private final double y;
|
||||
private final double z;
|
||||
@@ -180,6 +180,32 @@ public class ClientboundAddEntityPacket implements Packet<ClientGamePacketListen
|
||||
return Mth.unpackDegrees(this.yHeadRot);
|
||||
}
|
||||
|
||||
+ // SparklyPaper - Helpful NMS packet changes: expose raw rotational fields
|
||||
+ public int getXaRaw() {
|
||||
+ return this.xa;
|
||||
+ }
|
||||
+
|
||||
+ public int getYaRaw() {
|
||||
+ return this.ya;
|
||||
+ }
|
||||
+
|
||||
+ public int getZaRaw() {
|
||||
+ return this.za;
|
||||
+ }
|
||||
+
|
||||
+ public byte getXRotRaw() {
|
||||
+ return this.xRot;
|
||||
+ }
|
||||
+
|
||||
+ public byte getYRotRaw() {
|
||||
+ return this.yRot;
|
||||
+ }
|
||||
+
|
||||
+ public byte getYHeadRotRaw() {
|
||||
+ return this.yHeadRot;
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
+
|
||||
public int getData() {
|
||||
return this.data;
|
||||
}
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundBlockUpdatePacket.java b/net/minecraft/network/protocol/game/ClientboundBlockUpdatePacket.java
|
||||
index 8fca836e63731c5cef95bbc07e6e1414c9f02bea..c412dcab882abe11ecae34700df3e62ece464b82 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundBlockUpdatePacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundBlockUpdatePacket.java
|
||||
@@ -19,7 +19,7 @@ public class ClientboundBlockUpdatePacket implements Packet<ClientGamePacketList
|
||||
ClientboundBlockUpdatePacket::new
|
||||
);
|
||||
private final BlockPos pos;
|
||||
- public final BlockState blockState;
|
||||
+ public BlockState blockState; // SparklyPaper - Helpful NMS packet changes: remove final
|
||||
|
||||
public ClientboundBlockUpdatePacket(BlockPos pos, BlockState blockState) {
|
||||
this.pos = pos;
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
index 9e321ef1c3d5803519b243685f4ee598dc0cf640..851931062c4401817aad14721ac7fb0362c3b418 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
@@ -25,7 +25,7 @@ import net.minecraft.world.level.levelgen.Heightmap;
|
||||
public class ClientboundLevelChunkPacketData {
|
||||
private static final int TWO_MEGABYTES = 2097152;
|
||||
private final CompoundTag heightmaps;
|
||||
- private final byte[] buffer;
|
||||
+ public byte[] buffer; // SparklyPaper - Helpful NMS packet changes: remove final and make public
|
||||
private final List<ClientboundLevelChunkPacketData.BlockEntityInfo> blockEntitiesData;
|
||||
// Paper start - Handle oversized block entities in chunks
|
||||
private final java.util.List<net.minecraft.network.protocol.Packet<?>> extraPackets = new java.util.ArrayList<>();
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundRotateHeadPacket.java b/net/minecraft/network/protocol/game/ClientboundRotateHeadPacket.java
|
||||
index 4bcbf4bff67d4d4958d56764a273cf4a66b9dd0c..fd621a5d02170f6aa297dbd6a08ba1fef60e54c9 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundRotateHeadPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundRotateHeadPacket.java
|
||||
@@ -20,6 +20,13 @@ public class ClientboundRotateHeadPacket implements Packet<ClientGamePacketListe
|
||||
this.yHeadRot = yHeadRot;
|
||||
}
|
||||
|
||||
+ // SparklyPaper start - Helpful NMS packet changes: add entity ID constructor
|
||||
+ public ClientboundRotateHeadPacket(int entityId, byte headYaw) {
|
||||
+ this.entityId = entityId;
|
||||
+ this.yHeadRot = headYaw;
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
+
|
||||
private ClientboundRotateHeadPacket(FriendlyByteBuf buffer) {
|
||||
this.entityId = buffer.readVarInt();
|
||||
this.yHeadRot = buffer.readByte();
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java b/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
||||
index 10b46c59d83d1274cf491f217df2355d13b594c1..de8767eb8a01e1fed06fbb9d8d5904a83fd19bf5 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
||||
@@ -17,9 +17,9 @@ public class ClientboundSectionBlocksUpdatePacket implements Packet<ClientGamePa
|
||||
ClientboundSectionBlocksUpdatePacket::write, ClientboundSectionBlocksUpdatePacket::new
|
||||
);
|
||||
private static final int POS_IN_SECTION_BITS = 12;
|
||||
- private final SectionPos sectionPos;
|
||||
- private final short[] positions;
|
||||
- private final BlockState[] states;
|
||||
+ public SectionPos sectionPos; // SparklyPaper - Helpful NMS packet changes: remove final and make public
|
||||
+ public short[] positions; // SparklyPaper - Helpful NMS packet changes: remove final and make public
|
||||
+ public BlockState[] states; // SparklyPaper - Helpful NMS packet changes: remove final and make public
|
||||
|
||||
public ClientboundSectionBlocksUpdatePacket(SectionPos sectionPos, ShortSet positions, LevelChunkSection section) {
|
||||
this.sectionPos = sectionPos;
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundSetCameraPacket.java b/net/minecraft/network/protocol/game/ClientboundSetCameraPacket.java
|
||||
index 2545057c7f1f355f59f1e7da06ce08fd2d997b43..9920fe2d2f2f74f372731f1be5abaa4953344632 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundSetCameraPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundSetCameraPacket.java
|
||||
@@ -22,6 +22,12 @@ public class ClientboundSetCameraPacket implements Packet<ClientGamePacketListen
|
||||
this.cameraId = buffer.readVarInt();
|
||||
}
|
||||
|
||||
+ // SparklyPaper - Helpful NMS packet changes: add direct entityId constructor
|
||||
+ public ClientboundSetCameraPacket(int entityId) {
|
||||
+ this.cameraId = entityId;
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
+
|
||||
private void write(FriendlyByteBuf buffer) {
|
||||
buffer.writeVarInt(this.cameraId);
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/Display.java b/net/minecraft/world/entity/Display.java
|
||||
index ff49fdcddb43ee479a377aa219eb18fcaefeffca..33a47487f79fdc5164ff6a6d639dfe5834deed0d 100644
|
||||
--- a/net/minecraft/world/entity/Display.java
|
||||
+++ b/net/minecraft/world/entity/Display.java
|
||||
@@ -800,7 +800,7 @@ public abstract class Display extends Entity {
|
||||
public static final byte FLAG_ALIGN_RIGHT = 16;
|
||||
private static final byte INITIAL_TEXT_OPACITY = -1;
|
||||
public static final int INITIAL_BACKGROUND = 1073741824;
|
||||
- private static final EntityDataAccessor<Component> DATA_TEXT_ID = SynchedEntityData.defineId(Display.TextDisplay.class, EntityDataSerializers.COMPONENT);
|
||||
+ public static final EntityDataAccessor<Component> DATA_TEXT_ID = SynchedEntityData.defineId(Display.TextDisplay.class, EntityDataSerializers.COMPONENT); // SparklyPaper - Helpful NMS packet changes: make public
|
||||
public static final EntityDataAccessor<Integer> DATA_LINE_WIDTH_ID = SynchedEntityData.defineId(Display.TextDisplay.class, EntityDataSerializers.INT);
|
||||
public static final EntityDataAccessor<Integer> DATA_BACKGROUND_COLOR_ID = SynchedEntityData.defineId(
|
||||
Display.TextDisplay.class, EntityDataSerializers.INT
|
||||
@@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Tue, 25 Jun 2024 02:52:32 -0300
|
||||
Subject: [PATCH] Add CraftItemRecipeEvent
|
||||
|
||||
Used when a player OR a crafter block crafts an item, as an alternative to PrepareItemCraftEvent and CraftItemEvent, because both events are not triggered when a item is crafted from a crafter
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 27ef385a85b13ceb58e8d149849983107c539b31..7f9ed94576c94161070fd1be1544aaed9aac0c6b 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3156,6 +3156,21 @@ public class ServerGamePacketListenerImpl
|
||||
} else {
|
||||
event = new CraftItemEvent(recipe, inventory, type, slotNum, click, action);
|
||||
}
|
||||
+ // SparklyPaper start - add CraftItemRecipeEvent
|
||||
+ // We will pigback a bit on the current implementation
|
||||
+ net.sparklypower.sparklypaper.event.inventory.CraftItemRecipeEvent craftItemRecipeEvent = new net.sparklypower.sparklypaper.event.inventory.CraftItemRecipeEvent(
|
||||
+ ((CraftingInventory) top).getMatrix(), // We cannot use the top inventory directly because (it seems) that the first slot is the "result" slot
|
||||
+ recipe,
|
||||
+ event.getCurrentItem()
|
||||
+ );
|
||||
+ if (craftItemRecipeEvent.callEvent()) {
|
||||
+ event.setCurrentItem(craftItemRecipeEvent.getResult());
|
||||
+ } else {
|
||||
+ event.setCancelled(true);
|
||||
+ cancelled = true;
|
||||
+ event.setCurrentItem(craftItemRecipeEvent.getResult());
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/CrafterBlock.java b/net/minecraft/world/level/block/CrafterBlock.java
|
||||
index 5f5966278faf86ed9b28955c80ba845c0cb75595..751969d28951f59f381aa6bf7ad42d55d3e84d57 100644
|
||||
--- a/net/minecraft/world/level/block/CrafterBlock.java
|
||||
+++ b/net/minecraft/world/level/block/CrafterBlock.java
|
||||
@@ -167,6 +167,13 @@ public class CrafterBlock extends BaseEntityBlock {
|
||||
}
|
||||
itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResult());
|
||||
// CraftBukkit end
|
||||
+ // SparklyPaper - add CraftItemRecipeEvent
|
||||
+ net.sparklypower.sparklypaper.event.inventory.CraftItemRecipeEvent sparklyEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callCraftItemRecipeEvent(crafterBlockEntity, recipeHolder.toBukkitRecipe(), itemStack);
|
||||
+ if (sparklyEvent.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(sparklyEvent.getResult());
|
||||
+ // SparklyPaper end
|
||||
if (itemStack.isEmpty()) {
|
||||
level.levelEvent(1050, pos, 0);
|
||||
} else {
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Fri, 23 Aug 2024 16:20:45 -0300
|
||||
Subject: [PATCH] Allow throttling hopper checks if the target container is
|
||||
full
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 5cd1326ad5d046c88b2b3449d610a78fa880b4cd..d512f44dcfc480b5608555aa319c93342ae5b208 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -419,6 +419,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
} else {
|
||||
Direction opposite = blockEntity.facing.getOpposite();
|
||||
if (isFullContainer(attachedContainer, opposite)) {
|
||||
+ if (level.sparklyPaperConfig.getTicksPer().getHopperCooldownWhenTargetContainerIsFull() != 0) blockEntity.setCooldown(level.sparklyPaperConfig.getTicksPer().getHopperCooldownWhenTargetContainerIsFull()); // SparklyPaper - Allow throttling hopper checks if the target container is full
|
||||
return false;
|
||||
} else {
|
||||
// Paper start - Perf: Optimize Hoppers
|
||||
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Sat, 4 Jan 2025 23:58:55 -0300
|
||||
Subject: [PATCH] Add PlayerMoveControllableVehicleEvent
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 7f9ed94576c94161070fd1be1544aaed9aac0c6b..da190c2ab2080344dc11903aec51598af18d7556 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -587,6 +587,31 @@ public class ServerGamePacketListenerImpl
|
||||
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
|
||||
}
|
||||
|
||||
+ // SparklyPaper start - Add PlayerMoveControllableVehicleEvent
|
||||
+ org.bukkit.entity.Player craftPlayer = this.getCraftPlayer();
|
||||
+ org.bukkit.entity.Entity bukkitVehicle = rootVehicle.getBukkitEntity();
|
||||
+ if (bukkitVehicle instanceof org.bukkit.entity.Vehicle) {
|
||||
+ net.sparklypower.sparklypaper.event.player.PlayerMoveControllableVehicleEvent playerMoveControllableVehicleEvent = new net.sparklypower.sparklypaper.event.player.PlayerMoveControllableVehicleEvent(
|
||||
+ craftPlayer,
|
||||
+ (org.bukkit.entity.Vehicle) bukkitVehicle,
|
||||
+ new org.bukkit.Location(craftPlayer.getWorld(), x, y, z, f, f1),
|
||||
+ new org.bukkit.Location(craftPlayer.getWorld(), d, d1, d2, f, f1)
|
||||
+ );
|
||||
+ if (!playerMoveControllableVehicleEvent.callEvent()) {
|
||||
+ // Cancelled, move back!
|
||||
+ rootVehicle.absMoveTo(x, y, z, f, f1);
|
||||
+ this.player.absMoveTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
+ this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle));
|
||||
+ return;
|
||||
+ }
|
||||
+ d = playerMoveControllableVehicleEvent.getTo().x();
|
||||
+ d1 = playerMoveControllableVehicleEvent.getTo().y();
|
||||
+ d2 = playerMoveControllableVehicleEvent.getTo().z();
|
||||
+ f = playerMoveControllableVehicleEvent.getTo().getYaw();
|
||||
+ f1 = playerMoveControllableVehicleEvent.getTo().getPitch();
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
+
|
||||
rootVehicle.absMoveTo(d, d1, d2, f, f1);
|
||||
this.player.absMoveTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
// Paper start - optimise out extra getCubes
|
||||
@@ -0,0 +1,86 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Wed, 8 Jan 2025 22:48:04 -0300
|
||||
Subject: [PATCH] Add PlayerPreMoveEvent
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index da190c2ab2080344dc11903aec51598af18d7556..f637d2be3d67a928ed7f78eaa7aa80cbea85a3e6 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1422,7 +1422,7 @@ public class ServerGamePacketListenerImpl
|
||||
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
|
||||
- boolean flag = d4 > 0.0;
|
||||
+ boolean flag = d4 > 0.0; // SparklyPaper - diff on change, used to reset the fall distance, checks if d7 is > 0.0D (player is moving upwards)
|
||||
if (this.player.onGround() && !packet.isOnGround() && flag) {
|
||||
// Paper start - Add PlayerJumpEvent
|
||||
org.bukkit.entity.Player player = this.getCraftPlayer();
|
||||
@@ -1456,7 +1456,37 @@ 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
|
||||
+ // SparklyPaper start - Add PlayerPreMoveEvent event
|
||||
+ boolean isOnGround = packet.isOnGround();
|
||||
+ boolean horizontalCollision = packet.horizontalCollision();
|
||||
+ if (net.sparklypower.sparklypaper.event.player.PlayerPreMoveEvent.getHandlerList().getRegisteredListeners().length != 0) {
|
||||
+ org.bukkit.entity.Player player = this.getCraftPlayer();
|
||||
+ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
|
||||
+ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
|
||||
+
|
||||
+ // If the packet contains movement information then we update the To location with the correct XYZ.
|
||||
+ if (packet.hasPos) {
|
||||
+ to.setX(packet.x);
|
||||
+ to.setY(packet.y);
|
||||
+ to.setZ(packet.z);
|
||||
+ }
|
||||
+
|
||||
+ // If the packet contains look information then we update the To location with the correct Yaw & Pitch.
|
||||
+ if (packet.hasRot) {
|
||||
+ to.setYaw(packet.yRot);
|
||||
+ to.setPitch(packet.xRot);
|
||||
+ }
|
||||
+
|
||||
+ net.sparklypower.sparklypaper.event.player.PlayerPreMoveEvent event = new net.sparklypower.sparklypaper.event.player.PlayerPreMoveEvent(player, from, to, packet.isOnGround(), packet.horizontalCollision(), flag);
|
||||
+
|
||||
+ if (event.callEvent()) {
|
||||
+ isOnGround = event.isOnGround();
|
||||
+ horizontalCollision = event.isHorizontalCollision();
|
||||
+ flag = event.isResetFallDistance();
|
||||
+ }
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
+ this.player.onGround = isOnGround; // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move // SparklyPaper - Add PlayerPreMoveEvent
|
||||
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) {
|
||||
@@ -1590,15 +1620,15 @@ public class ServerGamePacketListenerImpl
|
||||
&& this.noBlocksAround(this.player);
|
||||
this.player.serverLevel().getChunkSource().move(this.player);
|
||||
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.setOnGroundWithMovement(isOnGround, horizontalCollision, vec3); // SparklyPaper - Add PlayerPreMoveEvent
|
||||
+ this.player.doCheckFallDamage(vec3.x, vec3.y, vec3.z, isOnGround); // SparklyPaper - Add PlayerPreMoveEvent
|
||||
this.player.recordMovementThroughBlocks(new Vec3(x, y, z), this.player.position());
|
||||
this.handlePlayerKnownMovement(vec3);
|
||||
if (flag) {
|
||||
this.player.resetFallDistance();
|
||||
}
|
||||
|
||||
- if (packet.isOnGround()
|
||||
+ if (isOnGround // SparklyPaper - Add PlayerPreMoveEvent
|
||||
|| this.player.hasLandedInLiquid()
|
||||
|| this.player.onClimbable()
|
||||
|| this.player.isSpectator()
|
||||
@@ -1613,7 +1643,7 @@ public class ServerGamePacketListenerImpl
|
||||
this.lastGoodZ = this.player.getZ();
|
||||
} else {
|
||||
this.internalTeleport(x, y, z, f, f1); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet.
|
||||
- this.player.doCheckFallDamage(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z, packet.isOnGround());
|
||||
+ this.player.doCheckFallDamage(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z, isOnGround); // SparklyPaper - Add PlayerPreMoveEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Sun, 12 Jan 2025 23:26:44 -0300
|
||||
Subject: [PATCH] Add PreEntityShootBowEvent
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/item/BowItem.java b/net/minecraft/world/item/BowItem.java
|
||||
index 57c933af200551162774f1d473437521e5a85833..9d8a6763efcdd2a57507e208c34faa3f180d5421 100644
|
||||
--- a/net/minecraft/world/item/BowItem.java
|
||||
+++ b/net/minecraft/world/item/BowItem.java
|
||||
@@ -33,6 +33,11 @@ public class BowItem extends ProjectileWeaponItem {
|
||||
} else {
|
||||
int i = this.getUseDuration(stack, entity) - timeLeft;
|
||||
float powerForTime = getPowerForTime(i);
|
||||
+ // SparklyPaper start - Add PreEntityShootBowEvent
|
||||
+ net.sparklypower.sparklypaper.event.entity.PreEntityShootBowEvent event = new net.sparklypower.sparklypaper.event.entity.PreEntityShootBowEvent(player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), player.getUsedItemHand() == InteractionHand.MAIN_HAND ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND, powerForTime);
|
||||
+ if (!event.callEvent())
|
||||
+ return false;
|
||||
+ // SparklyPaper end
|
||||
if (powerForTime < 0.1) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -0,0 +1,967 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Tue, 7 Nov 2023 01:34:14 -0300
|
||||
Subject: [PATCH] Parallel world ticking
|
||||
|
||||
"mom can we have folia?" "we already have folia at home" folia at home:
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
||||
index b5817aa8f537593f6d9fc6b612c82ccccb250ac7..2dbbd33690265cbacd4c6516d24bc64890f50990 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
||||
@@ -1031,7 +1031,7 @@ public final class ChunkHolderManager {
|
||||
if (changedFullStatus.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
- if (!TickThread.isTickThread()) {
|
||||
+ if (!TickThread.isTickThreadFor(world)) { // SparklyPaper - parallel world ticking
|
||||
this.taskScheduler.scheduleChunkTask(() -> {
|
||||
final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate;
|
||||
for (int i = 0, len = changedFullStatus.size(); i < len; ++i) {
|
||||
@@ -1057,7 +1057,7 @@ public final class ChunkHolderManager {
|
||||
|
||||
// note: never call while inside the chunk system, this will absolutely break everything
|
||||
public void processUnloads() {
|
||||
- TickThread.ensureTickThread("Cannot unload chunks off-main");
|
||||
+ TickThread.ensureTickThread(world, "Cannot unload chunks off-main"); // SparklyPaper - parallel world ticking
|
||||
|
||||
if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) {
|
||||
throw new IllegalStateException("Cannot unload chunks recursively");
|
||||
@@ -1339,7 +1339,7 @@ public final class ChunkHolderManager {
|
||||
|
||||
List<NewChunkHolder> changedFullStatus = null;
|
||||
|
||||
- final boolean isTickThread = TickThread.isTickThread();
|
||||
+ final boolean isTickThread = TickThread.isTickThreadFor(world);
|
||||
|
||||
boolean ret = false;
|
||||
final boolean canProcessFullUpdates = processFullUpdates & isTickThread;
|
||||
diff --git a/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java b/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java
|
||||
index 4a881636ba21fae9e50950bbba2b4321b71d35ab..ef76ff3671d38b482ac9932560e574d0d8cd9318 100644
|
||||
--- a/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java
|
||||
@@ -46,7 +46,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java b/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
|
||||
index bd5bbc7e55c6bea77991fe5a3c0c2580313d16c5..a231e08edba33bd55bed9a34129615f5e6dddb4d 100644
|
||||
--- a/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
|
||||
@@ -78,7 +78,7 @@ public class DefaultDispenseItemBehavior implements DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
level.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/core/dispenser/DispenseItemBehavior.java b/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
index 717c84165d5e25cd384f56b7cb976abf6669b6f0..8771e808cdf90fa6590140654da4eab08e15e58f 100644
|
||||
--- a/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
@@ -89,7 +89,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
level.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
levelAccessor.getMinecraftWorld().getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
level.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -510,8 +510,8 @@ public interface DispenseItemBehavior {
|
||||
// CraftBukkit start
|
||||
level.captureTreeGeneration = false;
|
||||
if (level.capturedBlockStates.size() > 0) {
|
||||
- org.bukkit.TreeType treeType = net.minecraft.world.level.block.SaplingBlock.treeType;
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = null;
|
||||
+ org.bukkit.TreeType treeType = net.minecraft.world.level.block.SaplingBlock.treeTypeRT.get(); // SparklyPaper - parallel world ticking
|
||||
+ net.minecraft.world.level.block.SaplingBlock.treeTypeRT.set(null); // SparklyPaper - parallel world ticking
|
||||
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());
|
||||
level.capturedBlockStates.clear();
|
||||
@@ -548,7 +548,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
level.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -591,7 +591,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
level.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -644,7 +644,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
level.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -702,7 +702,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@@ -783,7 +783,7 @@ public interface DispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
|
||||
index 3595bbd05fb3e8fe57e38d4e2df5c6237046b726..2b02d7cbc7fbb916c240f2d16bab365dbc1b8e56 100644
|
||||
--- a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
|
||||
@@ -39,7 +39,7 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java b/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java
|
||||
index 116395b6c00a0814922516707544a9ff26d68835..672ebd0cfc144d9b7315dcebf1e8007912ad7412 100644
|
||||
--- a/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java
|
||||
@@ -62,7 +62,7 @@ public class MinecartDispenseItemBehavior extends DefaultDispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java
|
||||
index 449d9b72ff4650961daa9d1bd25940f3914a6b12..df07b55924c1edca11eebd9debc75d9f184ede9d 100644
|
||||
--- a/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java
|
||||
@@ -32,7 +32,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior {
|
||||
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(block, craftItem.clone(), new org.bukkit.util.Vector((double) direction.getStepX(), (double) direction.getStepY(), (double) direction.getStepZ()));
|
||||
- if (!DispenserBlock.eventFired) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
index 626e9feb6a6e7a2cbc7c63e30ba4fb6b923e85c7..6ac9a0fc92eb9801bed3bc296988ee224afffa14 100644
|
||||
--- a/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
@@ -25,7 +25,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior {
|
||||
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) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
serverLevel.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java b/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java
|
||||
index 5ab2c8333178335515e619b87ae420f948c83bd1..c98e3748ff467f75f0a0e5a429563feaf06105f3 100644
|
||||
--- a/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java
|
||||
@@ -27,7 +27,7 @@ public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior {
|
||||
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(), new org.bukkit.util.Vector(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||
- if (!DispenserBlock.eventFired) {
|
||||
+ if (!DispenserBlock.eventFired.get()) { // SparklyPaper - parallel world ticking
|
||||
blockSource.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index c15c11ab3feaca918ac0185383cd1653200cd186..1bc0e3397a1299bdbe37a69097ece7d7395421f7 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -305,6 +305,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
|
||||
public final Set<net.minecraft.world.entity.Entity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
|
||||
public net.sparklypower.sparklypaper.HalloweenManager halloweenManager = new net.sparklypower.sparklypaper.HalloweenManager(); // SparklyPaper - Spooky month optimizations
|
||||
+ public java.util.concurrent.Semaphore serverLevelTickingSemaphore = null; // SparklyPaper - parallel world ticking
|
||||
|
||||
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
|
||||
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
|
||||
@@ -1720,6 +1721,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
this.isIteratingOverLevels = true; // Paper - Throw exception on world create while being ticked
|
||||
+ // SparklyPaper start - parallel world ticking
|
||||
+ java.util.ArrayDeque<java.util.concurrent.Future<ServerLevel>> tasks = new java.util.ArrayDeque<>();
|
||||
+ try {
|
||||
for (ServerLevel serverLevel : this.getAllLevels()) {
|
||||
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
|
||||
@@ -1736,27 +1740,46 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
profilerFiller.push("tick");
|
||||
|
||||
- try {
|
||||
- long i = Util.getNanos(); // SparklyPaper - track world's MSPT
|
||||
- serverLevel.tick(hasTimeLeft);
|
||||
- // SparklyPaper start - track world's MSPT
|
||||
- long j = Util.getNanos() - i;
|
||||
-
|
||||
- // These are from the "tickServer" function
|
||||
- serverLevel.tickTimes5s.add(this.tickCount, j);
|
||||
- serverLevel.tickTimes10s.add(this.tickCount, j);
|
||||
- serverLevel.tickTimes60s.add(this.tickCount, j);
|
||||
- // SparklyPaper end
|
||||
- } catch (Throwable var7) {
|
||||
- CrashReport crashReport = CrashReport.forThrowable(var7, "Exception ticking world");
|
||||
- serverLevel.fillReportDetails(crashReport);
|
||||
- throw new ReportedException(crashReport);
|
||||
- }
|
||||
+ serverLevelTickingSemaphore.acquire();
|
||||
+ tasks.add(
|
||||
+ serverLevel.tickExecutor.submit(() -> {
|
||||
+ try {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread currentThread = (ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread) Thread.currentThread();
|
||||
+ currentThread.currentlyTickingServerLevel = serverLevel;
|
||||
+
|
||||
+ long i = Util.getNanos(); // SparklyPaper - track world's MSPT
|
||||
+ serverLevel.tick(hasTimeLeft);
|
||||
+ // SparklyPaper start - track world's MSPT
|
||||
+ long j = Util.getNanos() - i;
|
||||
+
|
||||
+ // These are from the "tickServer" function
|
||||
+ serverLevel.tickTimes5s.add(this.tickCount, j);
|
||||
+ serverLevel.tickTimes10s.add(this.tickCount, j);
|
||||
+ serverLevel.tickTimes60s.add(this.tickCount, j);
|
||||
+ // SparklyPaper end
|
||||
+ } catch (Throwable throwable) {
|
||||
+ CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
|
||||
+
|
||||
+ serverLevel.fillReportDetails(crashreport);
|
||||
+ throw new ReportedException(crashreport);
|
||||
+ } finally {
|
||||
+ serverLevelTickingSemaphore.release();
|
||||
+ }
|
||||
+ }, serverLevel)
|
||||
+ );
|
||||
|
||||
profilerFiller.pop();
|
||||
profilerFiller.pop();
|
||||
serverLevel.explosionDensityCache.clear(); // Paper - Optimize explosions
|
||||
}
|
||||
+
|
||||
+ while (!tasks.isEmpty()) {
|
||||
+ tasks.pop().get();
|
||||
+ }
|
||||
+ } catch (java.lang.InterruptedException | java.util.concurrent.ExecutionException e) {
|
||||
+ throw new RuntimeException(e); // Propagate exception
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
|
||||
|
||||
profilerFiller.popPush("connection");
|
||||
@@ -1847,6 +1870,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
Map<ResourceKey<Level>, ServerLevel> oldLevels = this.levels;
|
||||
Map<ResourceKey<Level>, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels);
|
||||
newLevels.remove(level.dimension());
|
||||
+ level.tickExecutor.shutdown(); // SparklyPaper - parallel world ticking (We remove it in here instead of ServerLevel.close() because ServerLevel.close() is never called!)
|
||||
this.levels = Collections.unmodifiableMap(newLevels);
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 6ac73610f6039290c4ef3dde2206b6863d2b5067..0c5dbfe1d7e17796c1a60bcb1f97673ddff4d94e 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -233,6 +233,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
net.sparklypower.sparklypaper.SparklyPaperCommands.INSTANCE.registerCommands(this);
|
||||
// SparklyPaper end
|
||||
+ serverLevelTickingSemaphore = new java.util.concurrent.Semaphore(net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils.INSTANCE.getConfig().getParallelWorldTicking().getThreads()); // SparklyPaper - parallel world ticking
|
||||
+ DedicatedServer.LOGGER.info("Using " + serverLevelTickingSemaphore.availablePermits() + " permits for parallel world ticking"); // SparklyPaper - parallel world ticking
|
||||
// SparklyPaper start - Spooky month optimizations
|
||||
halloweenManager.startHalloweenEpochTask();
|
||||
halloweenManager.waitUntilEpochHasBeenUpdated();
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 59465ab6d7723d27b1597cc7094b5044a3f24250..7d0e5184289b37c6c9acc34341b8d84399ba653f 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -184,7 +184,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
private final MinecraftServer server;
|
||||
public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type
|
||||
private int lastSpawnChunkRadius;
|
||||
- final EntityTickList entityTickList = new EntityTickList();
|
||||
+ final EntityTickList entityTickList = new EntityTickList(this); // SparklyPaper - parallel world ticking
|
||||
// Paper - rewrite chunk system
|
||||
private final GameEventDispatcher gameEventDispatcher;
|
||||
public boolean noSave;
|
||||
@@ -208,6 +208,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
private final StructureCheck structureCheck;
|
||||
private final boolean tickTime;
|
||||
private final RandomSequences randomSequences;
|
||||
+ public java.util.concurrent.ExecutorService tickExecutor; // SparklyPaper - parallel world ticking
|
||||
|
||||
// CraftBukkit start
|
||||
public final LevelStorageSource.LevelStorageAccess levelStorageAccess;
|
||||
@@ -687,6 +688,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.chunkDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController((ServerLevel)(Object)this, this.chunkTaskScheduler);
|
||||
// Paper end - rewrite chunk system
|
||||
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
+ this.tickExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new net.sparklypower.sparklypaper.ServerLevelTickExecutorThreadFactory(getWorld().getName())); // SparklyPaper - parallel world ticking
|
||||
}
|
||||
|
||||
// Paper start
|
||||
@@ -1226,7 +1228,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
// Paper start - rewrite chunk system
|
||||
if ((++this.tickedBlocksOrFluids & 7L) != 0L) {
|
||||
- ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks();
|
||||
+ // ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks)
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
|
||||
@@ -1239,7 +1241,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
// Paper start - rewrite chunk system
|
||||
if ((++this.tickedBlocksOrFluids & 7L) != 0L) {
|
||||
- ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks();
|
||||
+ // ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks)
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
|
||||
@@ -1497,6 +1499,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
private void addPlayer(ServerPlayer player) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add player off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
Entity entity = this.getEntities().get(player.getUUID());
|
||||
if (entity != null) {
|
||||
LOGGER.warn("Force-added player with duplicate UUID {}", player.getUUID());
|
||||
@@ -1509,7 +1512,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
// CraftBukkit start
|
||||
private boolean addEntity(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
|
||||
- org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add entity off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
entity.generation = false; // Paper - Don't fire sync event during generation; Reset flag if it was added during a ServerLevel generation process
|
||||
// Paper start - extra debug info
|
||||
if (entity.valid) {
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index f347ff8d863f4bcef46604c757de112cb3fe445c..532df406e9fb41ab2ccfd59bcc7a614d6ada6548 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -423,6 +423,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
return this.viewDistanceHolder;
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
+ public boolean hasTickedAtLeastOnceInNewWorld = false; // SparklyPaper - parallel world ticking (fixes bug in DreamResourceReset where the inventory is opened AFTER the player has changed worlds, if you click with the quick tp torch in a chest, because the inventory is opened AFTER the player has teleported)
|
||||
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) {
|
||||
super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile);
|
||||
@@ -792,6 +793,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ hasTickedAtLeastOnceInNewWorld = true; // SparklyPaper - parallel world ticking (see: PARALLEL_NOTES.md - Opening an inventory after a world switch)
|
||||
// CraftBukkit start
|
||||
if (this.joining) {
|
||||
this.joining = false;
|
||||
@@ -1415,6 +1417,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
return this;
|
||||
} else {
|
||||
// CraftBukkit start
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot change dimension of a player off-main, from world " + serverLevel().getWorld().getName() + " to world " + level.getWorld().getName()); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
/*
|
||||
this.isChangingDimension = true;
|
||||
LevelData levelData = level.getLevelData();
|
||||
@@ -1768,6 +1771,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
return OptionalInt.empty();
|
||||
} else {
|
||||
// CraftBukkit start
|
||||
+ // SparklyPaper start - parallel world ticking (see: PARALLEL_NOTES.md - Opening an inventory after a world switch)
|
||||
+ if (!hasTickedAtLeastOnceInNewWorld) {
|
||||
+ MinecraftServer.LOGGER.warn("Ignoring request to open container " + abstractContainerMenu + " because we haven't ticked in the current world yet!", new Throwable());
|
||||
+ return OptionalInt.empty();
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
this.containerMenu = abstractContainerMenu; // Moved up
|
||||
if (!this.isImmobile())
|
||||
this.connection
|
||||
@@ -1832,6 +1841,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
}
|
||||
@Override
|
||||
public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ // SparklyPaper start - parallel world ticking (debugging)
|
||||
+ if (net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils.INSTANCE.getLogContainerCreationStacktraces()) {
|
||||
+ MinecraftServer.LOGGER.warn("Closing " + this.getBukkitEntity().getName() + " inventory that was created at", this.containerMenu.containerCreationStacktrace);
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
|
||||
// Paper end - Inventory close reason
|
||||
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 03feaf0adb8ee87e33744a4615dc2507a02f92d7..d6e13845fce443ae9b8f2c9a4ee5b00c4c5cc831 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -113,7 +113,7 @@ public abstract class PlayerList {
|
||||
private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
|
||||
private final MinecraftServer server;
|
||||
public final List<ServerPlayer> players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety
|
||||
- private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();
|
||||
+ private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap(); // SparklyPaper - parallel world ticking (we don't need to replace the original map because we never iterate on top of this map)
|
||||
private final UserBanList bans = new UserBanList(USERBANLIST_FILE);
|
||||
private final IpBanList ipBans = new IpBanList(IPBANLIST_FILE);
|
||||
private final ServerOpList ops = new ServerOpList(OPLIST_FILE);
|
||||
@@ -134,7 +134,7 @@ public abstract class PlayerList {
|
||||
|
||||
// CraftBukkit start
|
||||
private org.bukkit.craftbukkit.CraftServer cserver;
|
||||
- private final Map<String,ServerPlayer> playersByName = new java.util.HashMap<>();
|
||||
+ private final Map<String,ServerPlayer> playersByName = new java.util.HashMap<>(); // SparklyPaper - parallel world ticking (we don't need to replace the original map because we never iterate on top of this map)
|
||||
public @Nullable String collideRuleTeamName; // Paper - Configurable player collision
|
||||
|
||||
public PlayerList(MinecraftServer server, LayeredRegistryAccess<RegistryLayer> registries, PlayerDataStorage playerIo, int maxPlayers) {
|
||||
@@ -150,6 +150,7 @@ public abstract class PlayerList {
|
||||
abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor
|
||||
|
||||
public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie cookie) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot place new player off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
player.isRealPlayer = true; // Paper
|
||||
player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed
|
||||
GameProfile gameProfile = player.getGameProfile();
|
||||
@@ -714,6 +715,13 @@ public abstract class PlayerList {
|
||||
return this.respawn(player, keepInventory, reason, eventReason, null);
|
||||
}
|
||||
public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason, org.bukkit.Location location) {
|
||||
+ System.out.println("respawning player - current player container is " + player.containerMenu + " but their inventory is " + player.inventoryMenu);
|
||||
+ // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
+ if (location != null) // TODO: Is this really never null, or is IntelliJ IDEA tripping? Because I'm pretty sure that this can be null and there isn't any @NotNull annotations
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot respawn player off-main, from world " + player.serverLevel().getWorld().getName() + " to world " + location.getWorld().getName());
|
||||
+ else
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot respawn player off-main, respawning in world " + player.serverLevel().getWorld().getName());
|
||||
+ // SparklyPaper end
|
||||
player.stopRiding(); // CraftBukkit
|
||||
this.players.remove(player);
|
||||
this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
|
||||
@@ -724,6 +732,7 @@ public abstract class PlayerList {
|
||||
ServerPlayer serverPlayer = player;
|
||||
Level fromWorld = player.level();
|
||||
player.wonGame = false;
|
||||
+ serverPlayer.hasTickedAtLeastOnceInNewWorld = false; // SparklyPaper - parallel world ticking (see: PARALLEL_NOTES.md - Opening an inventory after a world switch)
|
||||
// CraftBukkit end
|
||||
serverPlayer.connection = player.connection;
|
||||
serverPlayer.restoreFrom(player, keepInventory);
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 1d0151a042ed5de4e235ef0bdac1a0e8240e85e7..731aecb84f87b6de41029b88e0c5c7ce2bab20cb 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -822,7 +822,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
// CraftBukkit start
|
||||
public void postTick() {
|
||||
// No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle
|
||||
- if (!(this instanceof ServerPlayer) && this.isAlive()) { // Paper - don't attempt to teleport dead entities
|
||||
+ if (false && !(this instanceof ServerPlayer) && this.isAlive()) { // Paper - don't attempt to teleport dead entities // SparklyPaper - parallel world ticking (see issue #9, this is executed in the server level tick for non-player entities)
|
||||
this.handlePortal();
|
||||
}
|
||||
}
|
||||
@@ -3808,6 +3808,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
private Entity teleportCrossDimension(ServerLevel level, TeleportTransition teleportTransition) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(level, "Cannot teleport entity to another world off-main, from world " + this.level.getWorld().getName() + " to world " + level.getWorld().getName()); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
List<Entity> passengers = this.getPassengers();
|
||||
List<Entity> list = new ArrayList<>(passengers.size());
|
||||
this.ejectPassengers();
|
||||
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 50af953a4698a3c6e16b840fab764dd733b3fbc9..27b6fcb12f1f6a36529fbf19f10ca6330280525a 100644
|
||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -91,8 +91,14 @@ public abstract class AbstractContainerMenu {
|
||||
}
|
||||
public void startOpen() {}
|
||||
// CraftBukkit end
|
||||
+ public Throwable containerCreationStacktrace; // SparklyPaper - parallel world ticking (debugging)
|
||||
|
||||
protected AbstractContainerMenu(@Nullable MenuType<?> menuType, int containerId) {
|
||||
+ // SparklyPaper - parallel world ticking (debugging)
|
||||
+ if (net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils.INSTANCE.getLogContainerCreationStacktraces()) {
|
||||
+ this.containerCreationStacktrace = new Throwable();
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
this.menuType = menuType;
|
||||
this.containerId = containerId;
|
||||
}
|
||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||
index 76f50437396f8f856381d0fbef52953ef7c263f6..199fec37b2c2b2ea6a55700cb8f4ec98aeb6504a 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -407,8 +407,8 @@ public final class ItemStack implements DataComponentHolder {
|
||||
if (interactionResult.consumesAction() && serverLevel.captureTreeGeneration && !serverLevel.capturedBlockStates.isEmpty()) {
|
||||
serverLevel.captureTreeGeneration = false;
|
||||
org.bukkit.Location location = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(clickedPos, serverLevel.getWorld());
|
||||
- org.bukkit.TreeType treeType = net.minecraft.world.level.block.SaplingBlock.treeType;
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = null;
|
||||
+ org.bukkit.TreeType treeType = net.minecraft.world.level.block.SaplingBlock.treeTypeRT.get(); // SparklyPaper - parallel world ticking
|
||||
+ net.minecraft.world.level.block.SaplingBlock.treeTypeRT.set(null);
|
||||
List<org.bukkit.craftbukkit.block.CraftBlockState> blocks = new java.util.ArrayList<>(serverLevel.capturedBlockStates.values());
|
||||
serverLevel.capturedBlockStates.clear();
|
||||
org.bukkit.event.world.StructureGrowEvent structureEvent = null;
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 644ab8b2c797f0675530a3efe23a878899689d66..b43cc51c23da0228aafd99d56e2a6e5cc05496ed 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -171,6 +171,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
public final io.papermc.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
|
||||
public net.sparklypower.sparklypaper.configs.SparklyPaperConfig.SparklyPaperWorldConfig sparklyPaperConfig; // SparklyPaper
|
||||
+ public io.papermc.paper.redstone.RedstoneWireTurbo turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((net.minecraft.world.level.block.RedStoneWireBlock) net.minecraft.world.level.block.Blocks.REDSTONE_WIRE); // SparklyPaper - parallel world ticking (moved to world)
|
||||
public static BlockPos lastPhysicsProblem; // Spigot
|
||||
private org.spigotmc.TickLimiter entityLimiter;
|
||||
private org.spigotmc.TickLimiter tileLimiter;
|
||||
@@ -1100,6 +1101,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
@Override
|
||||
public boolean setBlock(BlockPos pos, BlockState state, int flags, int recursionLeft) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, pos, "Updating block asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
// CraftBukkit start - tree generation
|
||||
if (this.captureTreeGeneration) {
|
||||
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
@@ -1484,7 +1486,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
tickingBlockEntity.tick();
|
||||
// Paper start - rewrite chunk system
|
||||
if ((++tickedEntities & 7) == 0) {
|
||||
- ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
|
||||
+ // ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks(); // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks)
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
}
|
||||
@@ -1508,7 +1510,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
|
||||
// Paper end - Prevent block entity and entity crashes
|
||||
}
|
||||
- this.moonrise$midTickTasks(); // Paper - rewrite chunk system
|
||||
+ // this.moonrise$midTickTasks(); // Paper - rewrite chunk system // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks)
|
||||
}
|
||||
|
||||
// Paper start - Option to prevent armor stands from doing entity lookups
|
||||
@@ -1651,6 +1653,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
@Nullable
|
||||
public BlockEntity getBlockEntity(BlockPos pos, boolean validate) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThreadOrAsyncThread((ServerLevel) this, "Cannot read world asynchronously"); // SparklyPaper - parallel world ticking
|
||||
// Paper start - Perf: Optimize capturedTileEntities lookup
|
||||
net.minecraft.world.level.block.entity.BlockEntity blockEntity;
|
||||
if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(pos)) != null) {
|
||||
@@ -1668,6 +1671,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
}
|
||||
|
||||
public void setBlockEntity(BlockEntity blockEntity) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel) this, "Cannot modify world asynchronously"); // SparklyPaper - parallel world ticking
|
||||
BlockPos blockPos = blockEntity.getBlockPos();
|
||||
if (!this.isOutsideBuildHeight(blockPos)) {
|
||||
// CraftBukkit start
|
||||
@@ -1752,6 +1756,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
@Override
|
||||
public List<Entity> getEntities(@Nullable Entity entity, AABB boundingBox, Predicate<? super Entity> predicate) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, boundingBox, "Cannot getEntities asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
Profiler.get().incrementCounter("getEntities");
|
||||
List<Entity> list = Lists.newArrayList();
|
||||
|
||||
@@ -2064,8 +2069,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
public abstract RecipeAccess recipeAccess();
|
||||
|
||||
public BlockPos getBlockRandomPos(int x, int y, int z, int yMask) {
|
||||
- this.randValue = this.randValue * 3 + 1013904223;
|
||||
- int i = this.randValue >> 2;
|
||||
+ int i = this.random.nextInt() >> 2; // SparklyPaper - parallel world ticking
|
||||
return new BlockPos(x + (i & 15), y + (i >> 16 & yMask), z + (i >> 8 & 15));
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/DispenserBlock.java b/net/minecraft/world/level/block/DispenserBlock.java
|
||||
index e0a4d41e5bcf144ea4c10d6f633c3a95ed2c5aec..ff99bff5b1986798ac8170def2809cc0c553e500 100644
|
||||
--- a/net/minecraft/world/level/block/DispenserBlock.java
|
||||
+++ b/net/minecraft/world/level/block/DispenserBlock.java
|
||||
@@ -50,7 +50,8 @@ public class DispenserBlock extends BaseEntityBlock {
|
||||
private static final DefaultDispenseItemBehavior DEFAULT_BEHAVIOR = new DefaultDispenseItemBehavior();
|
||||
public static final Map<Item, DispenseItemBehavior> DISPENSER_REGISTRY = new IdentityHashMap<>();
|
||||
private static final int TRIGGER_DURATION = 4;
|
||||
- public static boolean eventFired = false; // CraftBukkit
|
||||
+ // public static boolean eventFired = false; // CraftBukkit // SparklyPaper - parallel world ticking
|
||||
+ public static ThreadLocal<Boolean> eventFired = ThreadLocal.withInitial(() -> Boolean.FALSE); // SparklyPaper - parallel world ticking
|
||||
|
||||
@Override
|
||||
public MapCodec<? extends DispenserBlock> codec() {
|
||||
@@ -96,7 +97,7 @@ public class DispenserBlock extends BaseEntityBlock {
|
||||
DispenseItemBehavior dispenseMethod = this.getDispenseMethod(level, item);
|
||||
if (dispenseMethod != DispenseItemBehavior.NOOP) {
|
||||
if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(level, pos, item, randomSlot)) return; // Paper - Add BlockPreDispenseEvent
|
||||
- DispenserBlock.eventFired = false; // CraftBukkit - reset event status
|
||||
+ DispenserBlock.eventFired.set(Boolean.FALSE); // CraftBukkit - reset event status // SparklyPaper - parallel world ticking
|
||||
dispenserBlockEntity.setItem(randomSlot, dispenseMethod.dispense(blockSource, item));
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/FungusBlock.java b/net/minecraft/world/level/block/FungusBlock.java
|
||||
index 85f0eac75784565c658c5178c544f969db3d6f54..bfa0b1f72497cefecc112d9f484896edc9ec6f36 100644
|
||||
--- a/net/minecraft/world/level/block/FungusBlock.java
|
||||
+++ b/net/minecraft/world/level/block/FungusBlock.java
|
||||
@@ -76,9 +76,9 @@ public class FungusBlock extends BushBlock implements BonemealableBlock {
|
||||
// CraftBukkit start
|
||||
.map((value) -> {
|
||||
if (this == Blocks.WARPED_FUNGUS) {
|
||||
- SaplingBlock.treeType = org.bukkit.TreeType.WARPED_FUNGUS;
|
||||
+ SaplingBlock.treeTypeRT.set(org.bukkit.TreeType.WARPED_FUNGUS); // SparklyPaper - parallel world ticking
|
||||
} else if (this == Blocks.CRIMSON_FUNGUS) {
|
||||
- SaplingBlock.treeType = org.bukkit.TreeType.CRIMSON_FUNGUS;
|
||||
+ SaplingBlock.treeTypeRT.set(org.bukkit.TreeType.CRIMSON_FUNGUS); // SparklyPaper - parallel world ticking
|
||||
}
|
||||
return value;
|
||||
})
|
||||
diff --git a/net/minecraft/world/level/block/MushroomBlock.java b/net/minecraft/world/level/block/MushroomBlock.java
|
||||
index 904369f4d7db41026183f2de7c96c2f0f4dc204d..1ef0cf368fe9de49c7ba0ba3b647108b5bbe3e48 100644
|
||||
--- a/net/minecraft/world/level/block/MushroomBlock.java
|
||||
+++ b/net/minecraft/world/level/block/MushroomBlock.java
|
||||
@@ -94,7 +94,7 @@ public class MushroomBlock extends BushBlock implements BonemealableBlock {
|
||||
return false;
|
||||
} else {
|
||||
level.removeBlock(pos, false);
|
||||
- SaplingBlock.treeType = (this == Blocks.BROWN_MUSHROOM) ? org.bukkit.TreeType.BROWN_MUSHROOM : org.bukkit.TreeType.RED_MUSHROOM; // CraftBukkit
|
||||
+ SaplingBlock.treeTypeRT.set((this == Blocks.BROWN_MUSHROOM) ? org.bukkit.TreeType.BROWN_MUSHROOM : org.bukkit.TreeType.RED_MUSHROOM); // CraftBukkit // SparklyPaper - parallel world ticking
|
||||
if (optional.get().value().place(level, level.getChunkSource().getGenerator(), random, pos)) {
|
||||
return true;
|
||||
} else {
|
||||
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..833b180741cd361562d86794b16e3cd6a25410d5 100644
|
||||
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
@@ -292,7 +292,7 @@ public class RedStoneWireBlock extends Block {
|
||||
|
||||
// Paper start - Optimize redstone (Eigencraft)
|
||||
// The bulk of the new functionality is found in RedstoneWireTurbo.java
|
||||
- io.papermc.paper.redstone.RedstoneWireTurbo turbo = new io.papermc.paper.redstone.RedstoneWireTurbo(this);
|
||||
+ // io.papermc.paper.redstone.RedstoneWireTurbo turbo = new io.papermc.paper.redstone.RedstoneWireTurbo(this); // SparklyPaper - parallel world ticking (moved to world)
|
||||
|
||||
/*
|
||||
* Modified version of pre-existing updateSurroundingRedstone, which is called from
|
||||
@@ -308,7 +308,7 @@ public class RedStoneWireBlock extends Block {
|
||||
if (orientation != null) {
|
||||
source = pos.relative(orientation.getFront().getOpposite());
|
||||
}
|
||||
- turbo.updateSurroundingRedstone(worldIn, pos, state, source);
|
||||
+ worldIn.turbo.updateSurroundingRedstone(worldIn, pos, state, source); // SparklyPaper - parallel world ticking
|
||||
return;
|
||||
}
|
||||
updatePowerStrength(worldIn, pos, state, orientation, blockAdded);
|
||||
@@ -336,7 +336,7 @@ public class RedStoneWireBlock extends Block {
|
||||
// [Space Walker] suppress shape updates and emit those manually to
|
||||
// bypass the new neighbor update stack.
|
||||
if (level.setBlock(pos, state, Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS)) {
|
||||
- turbo.updateNeighborShapes(level, pos, state);
|
||||
+ level.turbo.updateNeighborShapes(level, pos, state); // SparklyPaper - parallel world ticking
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/SaplingBlock.java b/net/minecraft/world/level/block/SaplingBlock.java
|
||||
index e014f052e9b0f5ca6b28044e2389782b7d0e0cb8..c9091b66f5ddf7bd7145becdfc5e252163b03300 100644
|
||||
--- a/net/minecraft/world/level/block/SaplingBlock.java
|
||||
+++ b/net/minecraft/world/level/block/SaplingBlock.java
|
||||
@@ -26,7 +26,7 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock {
|
||||
protected static final float AABB_OFFSET = 6.0F;
|
||||
protected static final VoxelShape SHAPE = Block.box(2.0, 0.0, 2.0, 14.0, 12.0, 14.0);
|
||||
protected final TreeGrower treeGrower;
|
||||
- public static org.bukkit.TreeType treeType; // CraftBukkit
|
||||
+ public static final ThreadLocal<org.bukkit.TreeType> treeTypeRT = new ThreadLocal<>(); // CraftBukkit // SparklyPaper - parallel world ticking (from Folia)
|
||||
|
||||
@Override
|
||||
public MapCodec<? extends SaplingBlock> codec() {
|
||||
@@ -63,8 +63,8 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock {
|
||||
this.treeGrower.growTree(level, level.getChunkSource().getGenerator(), pos, state, random);
|
||||
level.captureTreeGeneration = false;
|
||||
if (!level.capturedBlockStates.isEmpty()) {
|
||||
- org.bukkit.TreeType treeType = SaplingBlock.treeType;
|
||||
- SaplingBlock.treeType = null;
|
||||
+ org.bukkit.TreeType treeType = SaplingBlock.treeTypeRT.get(); // SparklyPaper - parallel world ticking
|
||||
+ SaplingBlock.treeTypeRT.set(null); // SparklyPaper - parallel world ticking
|
||||
org.bukkit.Location location = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level.getWorld());
|
||||
java.util.List<org.bukkit.block.BlockState> blocks = new java.util.ArrayList<>(level.capturedBlockStates.values());
|
||||
level.capturedBlockStates.clear();
|
||||
diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
index 26db603ed681a6c302596627d4dd5bf8a9bafc4e..a2df3546922ea27b948ed89450428a27f65d93ed 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
@@ -77,6 +77,12 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
|
||||
return canUnlock(player, code, displayName, null);
|
||||
}
|
||||
public static boolean canUnlock(Player player, LockCode code, Component displayName, @Nullable BlockEntity blockEntity) {
|
||||
+ // SparklyPaper - parallel world ticking (see: PARALLEL_NOTES.md - Opening an inventory after a world switch)
|
||||
+ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != serverPlayer.serverLevel()) {
|
||||
+ net.minecraft.server.MinecraftServer.LOGGER.warn("Player " + serverPlayer.getScoreboardName() + " (" + serverPlayer.getStringUUID() + ") attempted to open a BlockEntity @ " + blockEntity.getLevel().getWorld().getName() + " " + blockEntity.getBlockPos().getX() + ", " + blockEntity.getBlockPos().getY() + ", " + blockEntity.getBlockPos().getZ() + " while they were in a different world " + serverPlayer.level().getWorld().getName() + " than the block themselves!");
|
||||
+ return false;
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != null && blockEntity.getLevel().getBlockEntity(blockEntity.getBlockPos()) == blockEntity) {
|
||||
final org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(blockEntity.getLevel(), blockEntity.getBlockPos());
|
||||
net.kyori.adventure.text.Component lockedMessage = net.kyori.adventure.text.Component.translatable("container.isLocked", io.papermc.paper.adventure.PaperAdventure.asAdventure(displayName));
|
||||
diff --git a/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||
index 1638eccef431fb68775af624110f1968f0c6dabd..a1096b17ddd4f02cdbe5615030803df88d200ed7 100644
|
||||
--- a/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||
@@ -43,9 +43,9 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
|
||||
// Paper end - Fix NPE in SculkBloomEvent world access
|
||||
|
||||
public static void serverTick(Level level, BlockPos pos, BlockState state, SculkCatalystBlockEntity sculkCatalyst) {
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = sculkCatalyst.getBlockPos(); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep.
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverrideRT.set(pos); // SparklyPaper - parallel world ticking // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep.
|
||||
sculkCatalyst.catalystListener.getSculkSpreader().updateCursors(level, pos, level.getRandom(), true);
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = null; // CraftBukkit
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverrideRT.set(null); // SparklyPaper - parallel world ticking // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/net/minecraft/world/level/block/grower/TreeGrower.java b/net/minecraft/world/level/block/grower/TreeGrower.java
|
||||
index cf7311c507de09a8f89934e430b2201e8bdffe51..2ad658fa8e42f26a37fed9faff421827cb72607b 100644
|
||||
--- a/net/minecraft/world/level/block/grower/TreeGrower.java
|
||||
+++ b/net/minecraft/world/level/block/grower/TreeGrower.java
|
||||
@@ -204,55 +204,59 @@ public final class TreeGrower {
|
||||
// CraftBukkit start
|
||||
private void setTreeType(Holder<ConfiguredFeature<?, ?>> holder) {
|
||||
ResourceKey<ConfiguredFeature<?, ?>> treeFeature = holder.unwrapKey().get();
|
||||
+ // SparklyPaper start - parallel world ticking
|
||||
+ org.bukkit.TreeType treeType;
|
||||
if (treeFeature == TreeFeatures.OAK || treeFeature == TreeFeatures.OAK_BEES_005) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.TREE;
|
||||
+ treeType = org.bukkit.TreeType.TREE;
|
||||
} else if (treeFeature == TreeFeatures.HUGE_RED_MUSHROOM) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.RED_MUSHROOM;
|
||||
+ treeType = org.bukkit.TreeType.RED_MUSHROOM;
|
||||
} else if (treeFeature == TreeFeatures.HUGE_BROWN_MUSHROOM) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.BROWN_MUSHROOM;
|
||||
+ treeType = org.bukkit.TreeType.BROWN_MUSHROOM;
|
||||
} else if (treeFeature == TreeFeatures.JUNGLE_TREE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.COCOA_TREE;
|
||||
+ treeType = org.bukkit.TreeType.COCOA_TREE;
|
||||
} else if (treeFeature == TreeFeatures.JUNGLE_TREE_NO_VINE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.SMALL_JUNGLE;
|
||||
+ treeType = org.bukkit.TreeType.SMALL_JUNGLE;
|
||||
} else if (treeFeature == TreeFeatures.PINE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.TALL_REDWOOD;
|
||||
+ treeType = org.bukkit.TreeType.TALL_REDWOOD;
|
||||
} else if (treeFeature == TreeFeatures.SPRUCE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.REDWOOD;
|
||||
+ treeType = org.bukkit.TreeType.REDWOOD;
|
||||
} else if (treeFeature == TreeFeatures.ACACIA) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.ACACIA;
|
||||
+ treeType = org.bukkit.TreeType.ACACIA;
|
||||
} else if (treeFeature == TreeFeatures.BIRCH || treeFeature == TreeFeatures.BIRCH_BEES_005) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.BIRCH;
|
||||
+ treeType = org.bukkit.TreeType.BIRCH;
|
||||
} else if (treeFeature == TreeFeatures.SUPER_BIRCH_BEES_0002) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.TALL_BIRCH;
|
||||
+ treeType = org.bukkit.TreeType.TALL_BIRCH;
|
||||
} else if (treeFeature == TreeFeatures.SWAMP_OAK) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.SWAMP;
|
||||
+ treeType = org.bukkit.TreeType.SWAMP;
|
||||
} else if (treeFeature == TreeFeatures.FANCY_OAK || treeFeature == TreeFeatures.FANCY_OAK_BEES_005) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.BIG_TREE;
|
||||
+ treeType = org.bukkit.TreeType.BIG_TREE;
|
||||
} else if (treeFeature == TreeFeatures.JUNGLE_BUSH) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.JUNGLE_BUSH;
|
||||
+ treeType = org.bukkit.TreeType.JUNGLE_BUSH;
|
||||
} else if (treeFeature == TreeFeatures.DARK_OAK) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.DARK_OAK;
|
||||
+ treeType = org.bukkit.TreeType.DARK_OAK;
|
||||
} else if (treeFeature == TreeFeatures.MEGA_SPRUCE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.MEGA_REDWOOD;
|
||||
+ treeType = org.bukkit.TreeType.MEGA_REDWOOD;
|
||||
} else if (treeFeature == TreeFeatures.MEGA_PINE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.MEGA_PINE;
|
||||
+ treeType = org.bukkit.TreeType.MEGA_PINE;
|
||||
} else if (treeFeature == TreeFeatures.MEGA_JUNGLE_TREE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.JUNGLE;
|
||||
+ treeType = org.bukkit.TreeType.JUNGLE;
|
||||
} else if (treeFeature == TreeFeatures.AZALEA_TREE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.AZALEA;
|
||||
+ treeType = org.bukkit.TreeType.AZALEA;
|
||||
} else if (treeFeature == TreeFeatures.MANGROVE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.MANGROVE;
|
||||
+ treeType = org.bukkit.TreeType.MANGROVE;
|
||||
} else if (treeFeature == TreeFeatures.TALL_MANGROVE) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.TALL_MANGROVE;
|
||||
+ treeType = org.bukkit.TreeType.TALL_MANGROVE;
|
||||
} else if (treeFeature == TreeFeatures.CHERRY || treeFeature == TreeFeatures.CHERRY_BEES_005) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.CHERRY;
|
||||
+ treeType = org.bukkit.TreeType.CHERRY;
|
||||
} else if (treeFeature == TreeFeatures.PALE_OAK || treeFeature == TreeFeatures.PALE_OAK_BONEMEAL) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.PALE_OAK;
|
||||
+ treeType = org.bukkit.TreeType.PALE_OAK;
|
||||
} else if (treeFeature == TreeFeatures.PALE_OAK_CREAKING) {
|
||||
- net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.PALE_OAK_CREAKING;
|
||||
+ treeType = org.bukkit.TreeType.PALE_OAK_CREAKING;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown tree generator " + treeFeature);
|
||||
}
|
||||
+ net.minecraft.world.level.block.SaplingBlock.treeTypeRT.set(treeType); // SparklyPaper - parallel world ticking
|
||||
+ // SparklyPaper end
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 761fdcd4a4e18f45547afd8edff44f61c6eeacb4..17fb7161171cbe44d145cf0065826f49183880b0 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -360,6 +360,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
|
||||
@Nullable
|
||||
public BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving, boolean doPlace) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, pos, "Updating block asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
// CraftBukkit end
|
||||
int y = pos.getY();
|
||||
LevelChunkSection section = this.getSection(this.getSectionIndex(y));
|
||||
diff --git a/net/minecraft/world/level/entity/EntityTickList.java b/net/minecraft/world/level/entity/EntityTickList.java
|
||||
index 423779a2b690f387a4f0bd07b97b50e0baefda76..24f9632e73d73c2ad68ebf30eb0e4cca7befae2d 100644
|
||||
--- a/net/minecraft/world/level/entity/EntityTickList.java
|
||||
+++ b/net/minecraft/world/level/entity/EntityTickList.java
|
||||
@@ -10,17 +10,26 @@ import net.minecraft.world.entity.Entity;
|
||||
|
||||
public class EntityTickList {
|
||||
private final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<net.minecraft.world.entity.Entity> entities = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>(); // Paper - rewrite chunk system
|
||||
+ // SparklyPaper start - parallel world ticking
|
||||
+ // Used to track async entity additions/removals/loops
|
||||
+ private final net.minecraft.server.level.ServerLevel serverLevel;
|
||||
+ public EntityTickList(net.minecraft.server.level.ServerLevel serverLevel) {
|
||||
+ this.serverLevel = serverLevel;
|
||||
+ }
|
||||
+ // SparklyPaper end
|
||||
|
||||
private void ensureActiveIsNotIterated() {
|
||||
// Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
public void add(Entity entity) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist addition"); // Paper // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
this.ensureActiveIsNotIterated();
|
||||
this.entities.add(entity); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
public void remove(Entity entity) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist removal"); // Paper // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
this.ensureActiveIsNotIterated();
|
||||
this.entities.remove(entity); // Paper - rewrite chunk system
|
||||
}
|
||||
@@ -30,6 +39,7 @@ public class EntityTickList {
|
||||
}
|
||||
|
||||
public void forEach(Consumer<Entity> entity) {
|
||||
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverLevel, "Asynchronous entity ticklist iteration"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
|
||||
// Paper start - rewrite chunk system
|
||||
// To ensure nothing weird happens with dimension travelling, do not iterate over new entries...
|
||||
// (by dfl iterator() is configured to not iterate over new entries)
|
||||
diff --git a/net/minecraft/world/level/saveddata/maps/MapIndex.java b/net/minecraft/world/level/saveddata/maps/MapIndex.java
|
||||
index ffe604f8397a002800e6ecc2f878d0f6f1c98703..ee022449c1e00a106687496a1dfb98fc0d86fb72 100644
|
||||
--- a/net/minecraft/world/level/saveddata/maps/MapIndex.java
|
||||
+++ b/net/minecraft/world/level/saveddata/maps/MapIndex.java
|
||||
@@ -34,17 +34,20 @@ public class MapIndex extends SavedData {
|
||||
|
||||
@Override
|
||||
public CompoundTag save(CompoundTag tag, HolderLookup.Provider registries) {
|
||||
+ synchronized (this.usedAuxIds) { // SparklyPaper start - make map data thread-safe
|
||||
for (Entry<String> entry : this.usedAuxIds.object2IntEntrySet()) {
|
||||
tag.putInt(entry.getKey(), entry.getIntValue());
|
||||
}
|
||||
-
|
||||
+ } // SparklyPaper end - make map data thread-safe
|
||||
return tag;
|
||||
}
|
||||
|
||||
public MapId getFreeAuxValueForMap() {
|
||||
+ synchronized (this.usedAuxIds) { // SparklyPaper start - make map data thread-safe
|
||||
int i = this.usedAuxIds.getInt("map") + 1;
|
||||
this.usedAuxIds.put("map", i);
|
||||
this.setDirty();
|
||||
return new MapId(i);
|
||||
+ } // SparklyPaper end - make map data thread-safe
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Sat, 1 Jun 2024 01:22:41 -0300
|
||||
Subject: [PATCH] SPARKLYPOWER Remap SparklyPower hacky legacy NBT tags
|
||||
|
||||
This is only useful for us in SparklyPower, but yeah...
|
||||
|
||||
diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java
|
||||
index 2d29d89cc45866822189a62bffbe1a8fe57c477b..688230454b42fd7da72833ca8fe631e6fba06eb9 100644
|
||||
--- a/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java
|
||||
+++ b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java
|
||||
@@ -1221,6 +1221,7 @@ public final class ConverterItemStackToDataComponents {
|
||||
ret.setString("id", this.id);
|
||||
ret.setInt("count", this.count);
|
||||
if (!this.tag.isEmpty()) {
|
||||
+ net.sparklypower.sparklypaper.LegacyNBTRemapper.INSTANCE.remap(this.tag); // SparklyPaper - Remap SparklyPower hacky legacy NBT tags
|
||||
this.components.setMap("minecraft:custom_data", this.tag);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Wed, 12 Jun 2024 11:53:09 -0300
|
||||
Subject: [PATCH] SPARKLYPOWER Add custom blocks
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/Blocks.java b/net/minecraft/world/level/block/Blocks.java
|
||||
index 0401a5e88fe7840ae667748409411ab73888799c..d83e8b92b77f6b8179b24f07eae528dda5f12ed2 100644
|
||||
--- a/net/minecraft/world/level/block/Blocks.java
|
||||
+++ b/net/minecraft/world/level/block/Blocks.java
|
||||
@@ -6775,6 +6775,52 @@ public class Blocks {
|
||||
public static final Block POTTED_CLOSED_EYEBLOSSOM = register(
|
||||
"potted_closed_eyeblossom", properties -> new FlowerPotBlock(CLOSED_EYEBLOSSOM, properties), flowerPotProperties().randomTicks()
|
||||
);
|
||||
+ // SparklyPaper start - SparklyPower Survival custom blocks
|
||||
+ // Blocks' strength should be synced with the replaced block on the client side!
|
||||
+ public static final Block SPARKLYPOWER_RAINBOW_WOOL = register(
|
||||
+ "sparklypower_rainbow_wool",
|
||||
+ Block::new,
|
||||
+ BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_RED).strength(0.5F).sound(SoundType.GRASS)
|
||||
+ );
|
||||
+ public static final Block SPARKLYPOWER_RAINBOW_CONCRETE = register(
|
||||
+ "sparklypower_rainbow_concrete",
|
||||
+ Block::new,
|
||||
+ BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_RED).strength(0.5F).sound(SoundType.GRASS)
|
||||
+ );
|
||||
+ public static final Block SPARKLYPOWER_RAINBOW_TERRACOTTA = register(
|
||||
+ "sparklypower_rainbow_terracotta",
|
||||
+ Block::new,
|
||||
+ BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_RED).strength(0.5F).sound(SoundType.GRASS)
|
||||
+ );
|
||||
+ public static final Block SPARKLYPOWER_ASPHALT_SERVER = register(
|
||||
+ "sparklypower_asphalt_server",
|
||||
+ Block::new,
|
||||
+ BlockBehaviour.Properties.of()
|
||||
+ .mapColor(MapColor.COLOR_BLACK)
|
||||
+ .instrument(NoteBlockInstrument.BASEDRUM)
|
||||
+ .requiresCorrectToolForDrops()
|
||||
+ .strength(1.5F, 6.0F)
|
||||
+ );
|
||||
+ public static final Block SPARKLYPOWER_ASPHALT_SERVER_SLAB = register(
|
||||
+ "sparklypower_asphalt_server_slab",
|
||||
+ SlabBlock::new,
|
||||
+ BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLACK).instrument(NoteBlockInstrument.BASEDRUM).requiresCorrectToolForDrops().strength(2.0F, 6.0F)
|
||||
+ );
|
||||
+ public static final Block SPARKLYPOWER_ASPHALT_PLAYER = register(
|
||||
+ "sparklypower_asphalt_player",
|
||||
+ Block::new,
|
||||
+ BlockBehaviour.Properties.of()
|
||||
+ .mapColor(MapColor.COLOR_BLACK)
|
||||
+ .instrument(NoteBlockInstrument.BASEDRUM)
|
||||
+ .requiresCorrectToolForDrops()
|
||||
+ .strength(1.5F, 6.0F)
|
||||
+ );
|
||||
+ public static final Block SPARKLYPOWER_ASPHALT_PLAYER_SLAB = register(
|
||||
+ "sparklypower_asphalt_player_slab",
|
||||
+ SlabBlock::new,
|
||||
+ BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLACK).instrument(NoteBlockInstrument.BASEDRUM).requiresCorrectToolForDrops().strength(2.0F, 6.0F)
|
||||
+ );
|
||||
+ // SparklyPaper end
|
||||
|
||||
private static ToIntFunction<BlockState> litBlockEmission(int lightValue) {
|
||||
return state -> state.getValue(BlockStateProperties.LIT) ? lightValue : 0;
|
||||
Reference in New Issue
Block a user