baseline of 26.1.2
WARNING: no patch merged, we will start merge later there are to many update between 1.21.11 and 26.1.2, so we need more time to build a base version which can stable to use
This commit is contained in:
-55
@@ -1,55 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Sun, 3 Aug 2025 14:26:37 +0800
|
||||
Subject: [PATCH] Add config to disable some check for operators
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 90e044ab3476d91819dddf14054d4626358da363..5c5dfcefd9ce6c9d7f69fb6d03216805b9e63822 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -392,7 +392,7 @@ public class ServerGamePacketListenerImpl
|
||||
this.tickCount++;
|
||||
this.knownMovePacketCount = this.receivedMovePacketCount;
|
||||
if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) {
|
||||
- if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) {
|
||||
+ if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player) && !(fun.bm.lophine.config.modules.misc.DisableCheckConfig.disableOpFlyCheck && MinecraftServer.getServer().getPlayerList().isOp(this.player.nameAndId()))) { // Lophine - disable fly check for operator
|
||||
// LOGGER.warn("{} was kicked for floating too long!", this.player.getPlainTextName()); // Paper - Logging moved to net.minecraft.server.network.ServerCommonPacketListenerImpl.disconnect()
|
||||
this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingPlayer, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_PLAYER); // Paper - use configurable kick message & kick event cause
|
||||
return true;
|
||||
@@ -411,7 +411,7 @@ public class ServerGamePacketListenerImpl
|
||||
this.vehicleLastGoodY = this.lastVehicle.getY();
|
||||
this.vehicleLastGoodZ = this.lastVehicle.getZ();
|
||||
if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) {
|
||||
- if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle)) {
|
||||
+ if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle) && !(fun.bm.lophine.config.modules.misc.DisableCheckConfig.disableOpFlyCheck && MinecraftServer.getServer().getPlayerList().isOp(this.player.nameAndId()))) { // Lophine - disable fly check for operator
|
||||
// LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getPlainTextName()); // Paper - Logging moved to net.minecraft.server.network.ServerCommonPacketListenerImpl.disconnect()
|
||||
this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingVehicle, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_VEHICLE); // Paper - use configurable kick message & kick event cause
|
||||
return true;
|
||||
@@ -662,7 +662,7 @@ public class ServerGamePacketListenerImpl
|
||||
d5 = d2 - rootVehicle.getZ();
|
||||
d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
boolean flag1 = false;
|
||||
- if (!me.earthme.luminol.config.modules.misc.DisableWarningConfig.disableMovedWronglyThresholdWarning && d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
|
||||
+ if (!me.earthme.luminol.config.modules.misc.DisableWarningConfig.disableMovedWronglyThresholdWarning && d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !(fun.bm.lophine.config.modules.misc.DisableCheckConfig.disableOpMoveCheck && MinecraftServer.getServer().getPlayerList().isOp(this.player.nameAndId()))) { // Spigot // Lophine - disable move check for operator
|
||||
flag1 = true; // Paper - diff on change, this should be moved wrongly
|
||||
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getPlainTextName(), this.player.getPlainTextName(), Math.sqrt(d7));
|
||||
}
|
||||
@@ -1564,7 +1564,7 @@ public class ServerGamePacketListenerImpl
|
||||
// Paper start - Add fail move event
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY,
|
||||
toX, toY, toZ, toYaw, toPitch, true);
|
||||
- if (!event.isAllowed()) {
|
||||
+ if (!event.isAllowed() && !(fun.bm.lophine.config.modules.misc.DisableCheckConfig.disableOpMoveCheck && MinecraftServer.getServer().getPlayerList().isOp(this.player.nameAndId()))) { // Lophine - disable move check for operator
|
||||
if (event.getLogWarning()) {
|
||||
LOGGER.warn("{} moved too quickly! {},{},{}", this.player.getPlainTextName(), d3, d4, d5);
|
||||
}
|
||||
@@ -1643,7 +1643,7 @@ public class ServerGamePacketListenerImpl
|
||||
// Paper start - Add fail move event
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_WRONGLY,
|
||||
toX, toY, toZ, toYaw, toPitch, true);
|
||||
- if (!event.isAllowed()) {
|
||||
+ if (!event.isAllowed() && !(fun.bm.lophine.config.modules.misc.DisableCheckConfig.disableOpMoveCheck && MinecraftServer.getServer().getPlayerList().isOp(this.player.nameAndId()))) { // Lophine - disable move check for operator
|
||||
movedWrongly = true;
|
||||
if (event.getLogWarning())
|
||||
// Paper end
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Tue, 29 Apr 2025 23:03:56 +0800
|
||||
Subject: [PATCH] Add config to enable cross region damage trace
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 607ce65a719e333ce2275346a356032327d00ccf..dcdb01fe5333d407a10f9872d09992c7b438ddeb 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1445,6 +1445,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
this.awardStat(Stats.ENTITY_KILLED_BY.get(killCredit.getType()));
|
||||
killCredit.awardKillScore(this, damageSource);
|
||||
this.createWitherRose(killCredit);
|
||||
+ // Luminol Start - Cross Region Damage trace
|
||||
+ } else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
|
||||
+ final LivingEntity entitylivingnew = this.getKillCreditOrigin();
|
||||
+ if (entitylivingnew != null) {
|
||||
+ this.damageTransferToAsync(entitylivingnew, cause);
|
||||
+ }
|
||||
+ // Luminol End - Cross Region Damage trace
|
||||
}
|
||||
|
||||
this.level().broadcastEntityEvent(this, EntityEvent.DEATH);
|
||||
@@ -1468,6 +1475,24 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
}
|
||||
// Leaves end - exp fix
|
||||
|
||||
+ // Luminol Start - Cross Region Damage trace
|
||||
+ private void damageTransferToAsync(LivingEntity entity, DamageSource cause) {
|
||||
+ // Operations running on current entity
|
||||
+ this.awardStat(Stats.ENTITY_KILLED_BY.get(entity.getType()));
|
||||
+ this.createWitherRose(entity);
|
||||
+
|
||||
+ // the entity might be in another tickregion sometimes, so we need to schedule the task onto the entity
|
||||
+ // to ensure thread safe
|
||||
+ entity.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> {
|
||||
+ try {
|
||||
+ nmsEntity.awardKillScore(this, cause);
|
||||
+ } catch (Throwable ex) {
|
||||
+ LOGGER.error(ex.getMessage(), ex);
|
||||
+ }
|
||||
+ }, null, 1L);
|
||||
+ }
|
||||
+ // Luminol End - Cross Region Damage trace
|
||||
+
|
||||
private void tellNeutralMobsThatIDied() {
|
||||
AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0);
|
||||
this.level()
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 7a63f52efca133d9d1a773da2443333009d87113..5bae274f5ee869e540e4330e03af671b6b18313d 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1975,6 +1975,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
final LivingEntity killer = this.getKillCredit();
|
||||
if (killer != null) {
|
||||
killer.awardKillScore(this, damageSource);
|
||||
+ // Luminol Start - Cross Region Damage trace
|
||||
+ } else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
|
||||
+ final LivingEntity killernew = this.getKillCreditOrigin();
|
||||
+ if (killernew != null) {
|
||||
+ this.damageTransferToAsync(killernew, damageSource);
|
||||
+ }
|
||||
+ // Luminol End - Cross Region Damage trace
|
||||
}
|
||||
}); // Paper end
|
||||
this.postDeathDropItems(deathEvent); // Paper
|
||||
@@ -1985,6 +1992,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
return deathEvent; // Paper
|
||||
}
|
||||
|
||||
+ // Luminol Start - Cross Region Damage trace
|
||||
+ private void damageTransferToAsync(LivingEntity entity, DamageSource damageSource) {
|
||||
+ entity.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> {
|
||||
+ try {
|
||||
+ nmsEntity.awardKillScore(this, damageSource);
|
||||
+ } catch (Throwable ex) {
|
||||
+ LOGGER.error(ex.getMessage(), ex);
|
||||
+ }
|
||||
+ }, null, 1L );
|
||||
+ }
|
||||
+ // Luminol End - Cross Region Damage trace
|
||||
+
|
||||
protected void dropEquipment(ServerLevel level) {
|
||||
}
|
||||
protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled
|
||||
@@ -2612,6 +2631,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
}
|
||||
}
|
||||
|
||||
+ // Luminol Start - Cross Region Damage trace
|
||||
+ @Nullable
|
||||
+ public LivingEntity getKillCreditOrigin() {
|
||||
+ if (this.lastHurtByPlayer != null) {
|
||||
+ return this.lastHurtByPlayer.getEntity(this.level(), Player.class);
|
||||
+ } else if (this.lastHurtByMob != null) {
|
||||
+ return this.lastHurtByMob.getEntity(this.level(), LivingEntity.class);
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Luminol End - Cross Region Damage trace
|
||||
+
|
||||
public final float getMaxHealth() {
|
||||
return (float)this.getAttributeValue(Attributes.MAX_HEALTH);
|
||||
}
|
||||
-158
@@ -1,158 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Wed, 5 Feb 2025 15:22:19 +0800
|
||||
Subject: [PATCH] Add config to enable raytracing tracker
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index bca2c5410aa543d2bb421e53893e9163508b3568..fdccb06c918d387e46c29ede7337159db8c5d9ca 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1350,7 +1350,7 @@ public class ChunkMap extends SimpleRegionStorage implements ChunkHolder.PlayerP
|
||||
double d1 = vec3_dx * vec3_dx + vec3_dz * vec3_dz; // Paper
|
||||
double d2 = d * d;
|
||||
// Paper start - Configurable entity tracking range by Y
|
||||
- boolean flag = d1 <= d2;
|
||||
+ boolean flag = d1 <= d2 && !entity.isCulled(); // Luminol - Ray tracing entity tracker
|
||||
if (flag && level.paperConfig().entities.trackingRangeY.enabled) {
|
||||
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||
if (rangeY != -1) {
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 040c0f8d26554ba583ecf370e2df3690d8f48dd6..22e68cabb4554c3e21e6f4ef316186f60ec77511 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -152,7 +152,7 @@ import org.jetbrains.annotations.Contract;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
-public abstract class Entity implements SyncedDataHolder, DebugValueSource, Nameable, ItemOwner, SlotProvider, EntityAccess, ScoreHolder, DataComponentGetter, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker
|
||||
+public abstract class Entity implements SyncedDataHolder, DebugValueSource, Nameable, ItemOwner, SlotProvider, EntityAccess, ScoreHolder, DataComponentGetter, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity, dev.tr7zw.entityculling.versionless.access.Cullable { // Paper - rewrite chunk system // Paper - optimise entity tracker // Luminol - Ray tracing entity tracker
|
||||
// CraftBukkit start
|
||||
private static final int CURRENT_LEVEL = 2;
|
||||
static boolean isLevelAtLeast(ValueInput input, int level) {
|
||||
@@ -6442,4 +6442,46 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
// Paper end - Expose entity id counter
|
||||
|
||||
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
|
||||
+
|
||||
+ private long lasttime = 0;
|
||||
+ private boolean culled = false;
|
||||
+ private boolean outOfCamera = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTimeout() {
|
||||
+ this.lasttime = System.currentTimeMillis() + 1000;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isForcedVisible() {
|
||||
+ return this.lasttime > System.currentTimeMillis();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCulled(boolean value) {
|
||||
+ this.culled = value;
|
||||
+ if (!value) {
|
||||
+ setTimeout();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCulled() {
|
||||
+ if (!fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled)
|
||||
+ return false;
|
||||
+ return this.culled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setOutOfCamera(boolean value) {
|
||||
+ this.outOfCamera = value;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isOutOfCamera() {
|
||||
+ if (!fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled)
|
||||
+ return false;
|
||||
+ return this.outOfCamera;
|
||||
+ }
|
||||
+
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
|
||||
index 0590d5723854a03a59fe9471710802f4e64e50b8..4f8ff2c024d6f2e67c5fa38fe2e660ba39e35499 100644
|
||||
--- a/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/net/minecraft/world/entity/EntityType.java
|
||||
@@ -1254,6 +1254,9 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
public final int passengerTickTimerId;
|
||||
public final int passengerInactiveTickTimerId;
|
||||
// Folia end - profiler
|
||||
+ // Luminol - Raytracing entity tracker
|
||||
+ public boolean skipRaytracningCheck = false;
|
||||
+ // Luminol end
|
||||
|
||||
public EntityType(
|
||||
EntityType.EntityFactory<T> factory,
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 67c0f4027a1e8b364694b5ed8b71965f2fe9b359..0f6e1428cc71c370af45db3e2a4f47c66e5d8628 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -189,6 +189,25 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
return (org.bukkit.craftbukkit.entity.CraftHumanEntity) super.getBukkitEntity();
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Luminol start - Raytracing entity tracker
|
||||
+ public dev.tr7zw.entityculling.CullTask cullTask;
|
||||
+ {
|
||||
+ if (!fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled) {
|
||||
+ this.cullTask = null;
|
||||
+ }else {
|
||||
+ final com.logisticscraft.occlusionculling.OcclusionCullingInstance culling = new com.logisticscraft.occlusionculling.OcclusionCullingInstance(
|
||||
+ fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance,
|
||||
+ new dev.tr7zw.entityculling.DefaultChunkDataProvider(this.level())
|
||||
+ );
|
||||
+
|
||||
+ this.cullTask = new dev.tr7zw.entityculling.CullTask(
|
||||
+ culling, this,
|
||||
+ fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.hitboxLimit,
|
||||
+ fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.checkIntervalMs
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
+ // Luminol end
|
||||
|
||||
public Player(Level level, GameProfile gameProfile) {
|
||||
super(EntityType.PLAYER, level);
|
||||
@@ -245,6 +264,26 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ // Luminol start - Ray tracing entity tracker
|
||||
+ if (!fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled) {
|
||||
+ if (this.cullTask != null) this.cullTask.signalStop();
|
||||
+ this.cullTask = null;
|
||||
+ }else {
|
||||
+ final com.logisticscraft.occlusionculling.OcclusionCullingInstance culling = new com.logisticscraft.occlusionculling.OcclusionCullingInstance(
|
||||
+ fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance,
|
||||
+ new dev.tr7zw.entityculling.DefaultChunkDataProvider(this.level())
|
||||
+ );
|
||||
+
|
||||
+ this.cullTask = new dev.tr7zw.entityculling.CullTask(
|
||||
+ culling, this,
|
||||
+ fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.hitboxLimit,
|
||||
+ fun.bm.lophine.config.modules.experiment.RayTrackingEntityTrackerConfig.checkIntervalMs
|
||||
+ );
|
||||
+ }
|
||||
+ if (this.cullTask != null) this.cullTask.setup();
|
||||
+ if (this.cullTask != null) this.cullTask.requestCullSignal(); // Luminol - Ray tracing entity tracker
|
||||
+ // Luminol end
|
||||
+
|
||||
this.noPhysics = this.isSpectator();
|
||||
if (this.isSpectator() || this.isPassenger()) {
|
||||
this.setOnGround(false);
|
||||
@@ -1353,6 +1392,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
if (this.hasContainerOpen()) {
|
||||
this.doCloseContainer();
|
||||
}
|
||||
+ if (this.cullTask != null) this.cullTask.signalStop(); // Luminol - Ray tracing entity tracker
|
||||
}
|
||||
|
||||
@Override
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Thu, 4 Sep 2025 02:14:16 +0800
|
||||
Subject: [PATCH] Add config to enable function command
|
||||
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index 4fa276ba05a550cdf7ce48617056c5a4d4a18006..6cb0d4daf0f275b95d5ca09275e40ab32258eb39 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -215,7 +215,9 @@ public class Commands {
|
||||
FillCommand.register(this.dispatcher, context);
|
||||
FillBiomeCommand.register(this.dispatcher, context);
|
||||
ForceLoadCommand.register(this.dispatcher);
|
||||
- //FunctionCommand.register(this.dispatcher); // Folia - region threading - TODO
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.function) {
|
||||
+ FunctionCommand.register(this.dispatcher); // Folia - region threading - TODO
|
||||
+ }
|
||||
GameModeCommand.register(this.dispatcher);
|
||||
GameRuleCommand.register(this.dispatcher, context);
|
||||
GiveCommand.register(this.dispatcher, context);
|
||||
-94
@@ -1,94 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Fri, 16 Jan 2026 02:34:43 +0800
|
||||
Subject: [PATCH] Add config to enable save-all command
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
index 17108636a5728efe98a064001e00e3ca098b1f51..7748e9ac04fbd3f5259d92fc908d90889cba86c8 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
@@ -350,6 +350,8 @@ public final class RegionizedServer {
|
||||
// tick player ping sample
|
||||
this.tickPlayerSample();
|
||||
|
||||
+ fun.bm.lophine.utils.SaveAllUtil.checkTimeout(); // Lophine - save-all fix
|
||||
+
|
||||
// tick worlds
|
||||
for (final ServerLevel world : this.worlds) {
|
||||
this.globalTick(world, tickCount);
|
||||
diff --git a/io/papermc/paper/threadedregions/TickRegions.java b/io/papermc/paper/threadedregions/TickRegions.java
|
||||
index 02c004bc7f9a0203523ce4b27cd766d6bdc478c0..3d86e21198f2888422330b6f7c27712f40a6aabc 100644
|
||||
--- a/io/papermc/paper/threadedregions/TickRegions.java
|
||||
+++ b/io/papermc/paper/threadedregions/TickRegions.java
|
||||
@@ -190,6 +190,8 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
|
||||
public final ThreadedRegionizer.ThreadedRegion<TickRegionData, TickRegionSectionData> region;
|
||||
public final ServerLevel world;
|
||||
|
||||
+ public long lastSavedTime = 0; // Lophine - save-all fix
|
||||
+
|
||||
// generic regionised data
|
||||
private final Reference2ReferenceOpenHashMap<RegionizedData<?>, Object> regionizedData = new Reference2ReferenceOpenHashMap<>();
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index 6cb0d4daf0f275b95d5ca09275e40ab32258eb39..48628174299f8f18170198df1834d6174bd1fafa 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -294,7 +294,11 @@ public class Commands {
|
||||
PardonCommand.register(this.dispatcher);
|
||||
PardonIpCommand.register(this.dispatcher);
|
||||
//PerfCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
- //SaveAllCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
+ // Lophine start - Add a config to enable save all command
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.saveAll) {
|
||||
+ SaveAllCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
+ }
|
||||
+ // Lophine end - Add a config to enable save all command
|
||||
SaveOffCommand.register(this.dispatcher);
|
||||
SaveOnCommand.register(this.dispatcher);
|
||||
SetPlayerIdleTimeoutCommand.register(this.dispatcher);
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 8ce5cdda24d63b33b39e32f9712fafa3917f27c5..25324d81bbe876dbe47b33bd5749b72e4283bf80 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1656,6 +1656,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Folia start - region threading
|
||||
public void tickServer(long startTime, long scheduledEnd, long targetBuffer,
|
||||
io.papermc.paper.threadedregions.TickRegions.TickRegionData region) {
|
||||
+ // Lophine start - save-all fix
|
||||
+ if (fun.bm.lophine.utils.SaveAllUtil.isSaving()) {
|
||||
+ fun.bm.lophine.utils.SaveAllUtil.postRegionSave(region);
|
||||
+ }
|
||||
+ // Lophine end - save-all fix
|
||||
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
|
||||
// Folia end - region threading
|
||||
org.spigotmc.WatchdogThread.tick(); // Spigot
|
||||
diff --git a/net/minecraft/server/commands/SaveAllCommand.java b/net/minecraft/server/commands/SaveAllCommand.java
|
||||
index e37b71402179c73146ff67babc228ccfb996f8f4..cfdb60bd89d83282f2202a5585bac22a6002e138 100644
|
||||
--- a/net/minecraft/server/commands/SaveAllCommand.java
|
||||
+++ b/net/minecraft/server/commands/SaveAllCommand.java
|
||||
@@ -21,7 +21,9 @@ public class SaveAllCommand {
|
||||
}
|
||||
|
||||
private static int saveAll(CommandSourceStack source, boolean flush) throws CommandSyntaxException {
|
||||
- source.sendSuccess(() -> Component.translatable("commands.save.saving"), false);
|
||||
+ // Lophine start - save all
|
||||
+ fun.bm.lophine.utils.SaveAllUtil.preSaveAll(source, flush);
|
||||
+/* source.sendSuccess(() -> Component.translatable("commands.save.saving"), false);
|
||||
MinecraftServer server = source.getServer();
|
||||
boolean flag = server.saveEverything(true, flush, true);
|
||||
if (!flag) {
|
||||
@@ -29,6 +31,12 @@ public class SaveAllCommand {
|
||||
} else {
|
||||
source.sendSuccess(() -> Component.translatable("commands.save.success"), true);
|
||||
return 1;
|
||||
- }
|
||||
+ }*/
|
||||
+ return 1;
|
||||
}
|
||||
+
|
||||
+ public static SimpleCommandExceptionType getErrorFailed() {
|
||||
+ return ERROR_FAILED;
|
||||
+ }
|
||||
+ // Lophine end - save all
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 29 Sep 2025 22:56:03 +0800
|
||||
Subject: [PATCH] Add config to enable scoreboard command
|
||||
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index 48628174299f8f18170198df1834d6174bd1fafa..91e2f3e9e85622adbd3799473634e716383bbe94 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -241,7 +241,11 @@ public class Commands {
|
||||
RotateCommand.register(this.dispatcher);
|
||||
SayCommand.register(this.dispatcher);
|
||||
//ScheduleCommand.register(this.dispatcher); // Folia - region threading
|
||||
- //ScoreboardCommand.register(this.dispatcher, context); // Folia - region threading
|
||||
+ // Lophine start - Add a config to enable scoreboard command
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.scoreboard) {
|
||||
+ ScoreboardCommand.register(this.dispatcher, context); // Folia - region threading
|
||||
+ }
|
||||
+ // Lophine start - Add a config to enable scoreboard command
|
||||
SeedCommand.register(this.dispatcher, selection != Commands.CommandSelection.INTEGRATED);
|
||||
VersionCommand.register(this.dispatcher, selection != Commands.CommandSelection.INTEGRATED);
|
||||
SetBlockCommand.register(this.dispatcher, context);
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 21 Jan 2026 21:28:21 +0800
|
||||
Subject: [PATCH] Add config to enable tick command
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
index 7748e9ac04fbd3f5259d92fc908d90889cba86c8..80b5d151e0dd6fa44794187875b4b80519839d81 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
@@ -332,6 +332,11 @@ public final class RegionizedServer {
|
||||
this.randomWalk();
|
||||
*/
|
||||
++this.tickCount;
|
||||
+ // Luminol start - Add a config to enable tick command
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.tick) {
|
||||
+ MinecraftServer.tickRateManager.tick();
|
||||
+ }
|
||||
+ // Luminol end - Add a config to enable tick command
|
||||
// expire invalid click command callbacks
|
||||
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.ADVENTURE_CLICK_MANAGER.handleQueue((int)this.tickCount); // Paper // Folia - region threading - moved to global tick
|
||||
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.DIALOG_CLICK_MANAGER.handleQueue((int)this.tickCount); // Paper // Folia - region threading - moved to global tick
|
||||
@@ -357,6 +362,13 @@ public final class RegionizedServer {
|
||||
this.globalTick(world, tickCount);
|
||||
}
|
||||
|
||||
+ // Luminol start - Add a config to enable tick command
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.tick) {
|
||||
+ MinecraftServer.tickRateManager.reduceSprintTicks();
|
||||
+ MinecraftServer.tickRateManager.endTickWork();
|
||||
+ }
|
||||
+ // Luminol end - Add a config to enable tick command
|
||||
+
|
||||
// tick connections
|
||||
this.tickConnections();
|
||||
|
||||
@@ -492,7 +504,7 @@ public final class RegionizedServer {
|
||||
}
|
||||
|
||||
private void tickTime(final ServerLevel world, final long tickCount) {
|
||||
- if (world.tickTime) {
|
||||
+ if ((!fun.bm.lophine.config.modules.experiment.CommandConfig.tick || world.tickRateManager().runsNormally()) && world.tickTime) { // Luminol - Add a config to enable tick command
|
||||
if (world.getGameRules().get(GameRules.ADVANCE_TIME)) {
|
||||
world.setDayTime(world.levelData.getDayTime() + tickCount);
|
||||
}
|
||||
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
||||
index 0f4e8ee9438135e24e0f61a1390c59573b9e9c3f..65699d2ad66c686a8b7d1b951787ddd766800a94 100644
|
||||
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
||||
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
||||
@@ -40,8 +40,8 @@ public final class TickRegionScheduler {
|
||||
}
|
||||
}
|
||||
|
||||
- public static final int TICK_RATE = 20;
|
||||
- public static final long TIME_BETWEEN_TICKS = 1_000_000_000L / TICK_RATE; // ns
|
||||
+ public static float TICK_RATE = 20; // Luminol - Add tick command support
|
||||
+ public static long TIME_BETWEEN_TICKS = (long) (1_000_000_000L / TICK_RATE); // ns // Luminol - Add tick command support
|
||||
// Folia start - watchdog
|
||||
public static final FoliaWatchdogThread WATCHDOG_THREAD = new FoliaWatchdogThread();
|
||||
static {
|
||||
@@ -448,8 +448,23 @@ public final class TickRegionScheduler {
|
||||
final long cpuStart = MEASURE_CPU_TIME ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : 0L;
|
||||
final long tickStart = System.nanoTime();
|
||||
|
||||
- // use max(), don't assume that tickStart >= scheduledStart
|
||||
- final long tickCount = Math.max(1L, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
|
||||
+ // Luminol start - Add a config to enable tick command
|
||||
+ final long tickCount;
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.tick) {
|
||||
+ if (MinecraftServer.tickRateManager.isSprinting() && MinecraftServer.tickRateManager.checkShouldSprintThisTick()) {
|
||||
+ TICK_RATE = net.minecraft.server.commands.TickCommand.MAX_TICKRATE;
|
||||
+ TIME_BETWEEN_TICKS = (long) (1_000_000_000L / TICK_RATE);
|
||||
+ tickCount = 1;
|
||||
+ } else {
|
||||
+ TICK_RATE = MinecraftServer.tickRateManager.tickrate();
|
||||
+ TIME_BETWEEN_TICKS = (long) (1_000_000_000L / TICK_RATE);
|
||||
+ tickCount = Math.max(1L, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
|
||||
+ }
|
||||
+ } else {
|
||||
+ // use max(), don't assume that tickStart >= scheduledStart
|
||||
+ tickCount = Math.max(1L, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
|
||||
+ }
|
||||
+ // Luminol end - Add tick command support
|
||||
|
||||
if (!this.tryMarkTicking()) {
|
||||
if (!this.cancelled.get()) {
|
||||
@@ -498,6 +513,11 @@ public final class TickRegionScheduler {
|
||||
try {
|
||||
// next start isn't updated until the end of this tick
|
||||
this.tickRegion(tickCount, tickStart, scheduledEnd);
|
||||
+ // Luminol start - Add a config to enable tick command
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.tick) {
|
||||
+ MinecraftServer.tickRateManager.endTickWork();
|
||||
+ }
|
||||
+ // Luminol end - Add a config to enable tick command
|
||||
} catch (final Throwable thr) {
|
||||
this.scheduler.regionFailed(this, false, thr);
|
||||
// regionFailed will schedule a shutdown, so we should avoid letting this region tick further
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index 91e2f3e9e85622adbd3799473634e716383bbe94..21466c225db02a5be74bf60b5ea831c5bea8a7e8 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -262,7 +262,11 @@ public class Commands {
|
||||
TeleportCommand.register(this.dispatcher);
|
||||
TellRawCommand.register(this.dispatcher, context);
|
||||
//TestCommand.register(this.dispatcher, context); // Folia - region threading
|
||||
- //TickCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
+ // Luminol start - Add a config to enable tick command
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.tick) {
|
||||
+ TickCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
+ }
|
||||
+ // Luminol end - Add a config to enable tick command
|
||||
TimeCommand.register(this.dispatcher);
|
||||
TitleCommand.register(this.dispatcher, context);
|
||||
//TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 25324d81bbe876dbe47b33bd5749b72e4283bf80..504f21c5f1e3101e7164b97059aecce630d18cee 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -270,7 +270,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private @Nullable String serverId;
|
||||
public MinecraftServer.ReloadableResources resources;
|
||||
private final StructureTemplateManager structureTemplateManager;
|
||||
- private final ServerTickRateManager tickRateManager;
|
||||
+ public static ServerTickRateManager tickRateManager; // Luminol - Add tick command support
|
||||
private final ServerDebugSubscribers debugSubscribers = new ServerDebugSubscribers(this);
|
||||
protected WorldData worldData;
|
||||
private LevelData.RespawnData effectiveRespawnData = LevelData.RespawnData.DEFAULT;
|
||||
diff --git a/net/minecraft/server/ServerTickRateManager.java b/net/minecraft/server/ServerTickRateManager.java
|
||||
index 4257c47d33e3773fac766817138cc21c55d9ab76..95f6b1cbd5e33151c326689bc72292ff38a48803 100644
|
||||
--- a/net/minecraft/server/ServerTickRateManager.java
|
||||
+++ b/net/minecraft/server/ServerTickRateManager.java
|
||||
@@ -106,7 +106,7 @@ public class ServerTickRateManager extends TickRateManager {
|
||||
return false;
|
||||
} else if (this.remainingSprintTicks > 0L) {
|
||||
this.sprintTickStartTime = System.nanoTime();
|
||||
- this.remainingSprintTicks--;
|
||||
+ // this.remainingSprintTicks--; // Luminol - Add tick command support
|
||||
return true;
|
||||
} else {
|
||||
this.finishTickSprint();
|
||||
@@ -114,6 +114,12 @@ public class ServerTickRateManager extends TickRateManager {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Luminol start - Add tick command support
|
||||
+ public void reduceSprintTicks() {
|
||||
+ this.remainingSprintTicks--;
|
||||
+ }
|
||||
+ // Luminol end - Add tick command support
|
||||
+
|
||||
public void endTickWork() {
|
||||
this.sprintTimeSpend = this.sprintTimeSpend + (System.nanoTime() - this.sprintTickStartTime);
|
||||
}
|
||||
diff --git a/net/minecraft/server/commands/TickCommand.java b/net/minecraft/server/commands/TickCommand.java
|
||||
index 14c46d585fc9bfbf9a57340508ea2e5076ac39d6..99096896a4512eed579b234e7fa0c6e9c3e8c246 100644
|
||||
--- a/net/minecraft/server/commands/TickCommand.java
|
||||
+++ b/net/minecraft/server/commands/TickCommand.java
|
||||
@@ -14,7 +14,7 @@ import net.minecraft.server.ServerTickRateManager;
|
||||
import net.minecraft.util.TimeUtil;
|
||||
|
||||
public class TickCommand {
|
||||
- private static final float MAX_TICKRATE = 10000.0F;
|
||||
+ public static final float MAX_TICKRATE = 10000.0F; // Luminol - Add tick command support
|
||||
private static final String DEFAULT_TICKRATE = String.valueOf(20);
|
||||
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
||||
-94
@@ -1,94 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 2 Jul 2025 23:36:25 +0800
|
||||
Subject: [PATCH] Fix datapack command save function
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 504f21c5f1e3101e7164b97059aecce630d18cee..d5b680fc6e13ec26d0db2448009e4cbe59933e22 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2437,6 +2437,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return this.reloadResources(selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.PLUGIN);
|
||||
}
|
||||
|
||||
+ // Lophine start - region thread skip reload // TODO - add reload support
|
||||
+ public void saveDatapacks(Collection<String> selectedIds) {
|
||||
+ this.packRepository.setSelected(selectedIds, false); // Paper - add pendingReload flag to determine required pack loading - false as this is *after* a reload (see above)
|
||||
+ WorldDataConfiguration worldDataConfiguration = new WorldDataConfiguration(
|
||||
+ getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()
|
||||
+ );
|
||||
+ this.worldData.setDataConfiguration(worldDataConfiguration);
|
||||
+ }
|
||||
+ // Lophine end - region thread skip reload // TODO - add reload support
|
||||
+
|
||||
public CompletableFuture<Void> reloadResources(Collection<String> selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause cause) {
|
||||
// Paper end - Add ServerResourcesReloadedEvent
|
||||
CompletableFuture<Void> completableFuture = CompletableFuture.<ImmutableList>supplyAsync(
|
||||
diff --git a/net/minecraft/server/commands/DataPackCommand.java b/net/minecraft/server/commands/DataPackCommand.java
|
||||
index bb36fa4559cdfe82079af1c39516239119ff06f4..8c530eef0e416d8b96f190ada358d77d34dbc8ac 100644
|
||||
--- a/net/minecraft/server/commands/DataPackCommand.java
|
||||
+++ b/net/minecraft/server/commands/DataPackCommand.java
|
||||
@@ -98,7 +98,7 @@ public class DataPackCommand {
|
||||
dispatcher.register(
|
||||
Commands.literal("datapack")
|
||||
.requires(Commands.hasPermission(Commands.LEVEL_GAMEMASTERS))
|
||||
- /*.then( // Luminol - Add back read-only datapack command
|
||||
+ .then(
|
||||
Commands.literal("enable")
|
||||
.then(
|
||||
Commands.argument("name", StringArgumentType.string())
|
||||
@@ -160,11 +160,11 @@ public class DataPackCommand {
|
||||
.suggests(SELECTED_PACKS)
|
||||
.executes(commandContext -> disablePack(commandContext.getSource(), getPack(commandContext, "name", false)))
|
||||
)
|
||||
- )*/ // Luminol - Add back read-only datapack command
|
||||
+ )
|
||||
.then(
|
||||
Commands.literal("list")
|
||||
.executes(commandContext -> listPacks(commandContext.getSource()))
|
||||
- // .then(Commands.literal("available").executes(commandContext -> listAvailablePacks(commandContext.getSource()))) // Luminol - Add back read-only datapack command
|
||||
+ .then(Commands.literal("available").executes(commandContext -> listAvailablePacks(commandContext.getSource())))
|
||||
.then(Commands.literal("enabled").executes(commandContext -> listEnabledPacks(commandContext.getSource())))
|
||||
)
|
||||
.then(
|
||||
@@ -252,7 +252,7 @@ public class DataPackCommand {
|
||||
}
|
||||
|
||||
private static int listPacks(CommandSourceStack source) {
|
||||
- return listEnabledPacks(source) ;// + listAvailablePacks(source); // Luminol - Add back read-only datapack command
|
||||
+ return listEnabledPacks(source) + listAvailablePacks(source);
|
||||
}
|
||||
|
||||
private static int listAvailablePacks(CommandSourceStack source) {
|
||||
@@ -280,7 +280,7 @@ public class DataPackCommand {
|
||||
|
||||
private static int listEnabledPacks(CommandSourceStack source) {
|
||||
PackRepository packRepository = source.getServer().getPackRepository();
|
||||
- // packRepository.reload(); // Luminol - Add back read-only datapack command
|
||||
+ packRepository.reload();
|
||||
Collection<? extends Pack> selectedPacks = packRepository.getSelectedPacks();
|
||||
if (selectedPacks.isEmpty()) {
|
||||
source.sendSuccess(() -> Component.translatable("commands.datapack.list.enabled.none"), false);
|
||||
diff --git a/net/minecraft/server/commands/ReloadCommand.java b/net/minecraft/server/commands/ReloadCommand.java
|
||||
index fcca0babb4e7929cc168fc8b9ad47619e6feb1a5..bac5f4e023f8b73eebea0f31fd253e04c8809918 100644
|
||||
--- a/net/minecraft/server/commands/ReloadCommand.java
|
||||
+++ b/net/minecraft/server/commands/ReloadCommand.java
|
||||
@@ -16,11 +16,17 @@ public class ReloadCommand {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static void reloadPacks(Collection<String> selectedIds, CommandSourceStack source) {
|
||||
+ // Lophine start - region thread skip reload // TODO - add reload support
|
||||
+ source.getServer().saveDatapacks(selectedIds);
|
||||
+ source.getSender().sendMessage("You need to restart server to load datapacks update.");
|
||||
+ if (false) {
|
||||
source.getServer().reloadResources(selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.COMMAND).exceptionally(throwable -> { // Paper - Add ServerResourcesReloadedEvent
|
||||
LOGGER.warn("Failed to execute reload", throwable);
|
||||
source.sendFailure(Component.translatable("commands.reload.failure"));
|
||||
return null;
|
||||
});
|
||||
+ }
|
||||
+ // Lophine end - region thread skip reload // TODO - add reload support
|
||||
}
|
||||
|
||||
private static Collection<String> discoverNewPacks(PackRepository packRepository, WorldData worldData, Collection<String> selectedIds) {
|
||||
@@ -1,159 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Sun, 3 Aug 2025 15:24:01 +0800
|
||||
Subject: [PATCH] Leaves: Base Protocol Core
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc14e2e0225009cf9919072f7f/leaves-server/minecraft-patches/features/0004-Leaves-Protocol-Core.patch)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
index 80b5d151e0dd6fa44794187875b4b80519839d81..8d32d906f87a1cb866a7497ee0de3045e9adce2c 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
@@ -369,6 +369,8 @@ public final class RegionizedServer {
|
||||
}
|
||||
// Luminol end - Add a config to enable tick command
|
||||
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleTick(); // Leaves - protocol
|
||||
+
|
||||
// tick connections
|
||||
this.tickConnections();
|
||||
|
||||
diff --git a/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java b/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java
|
||||
index 1da034752064312962a4144f91be5265a9a08997..081ca42b6a6644eb8c2b5ac9105fecf8ad39d501 100644
|
||||
--- a/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java
|
||||
+++ b/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java
|
||||
@@ -40,13 +40,22 @@ public interface CustomPacketPayload {
|
||||
|
||||
@Override
|
||||
public void encode(B buffer, CustomPacketPayload value) {
|
||||
+ // Leaves start - protocol core
|
||||
+ if (value instanceof org.leavesmc.leaves.protocol.core.LeavesCustomPayload payload) {
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.encode(buffer, payload);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - protocol core
|
||||
this.writeCap(buffer, value.type(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomPacketPayload decode(B buffer) {
|
||||
Identifier identifier = buffer.readIdentifier();
|
||||
- return (CustomPacketPayload)this.findCodec(identifier).decode(buffer);
|
||||
+ // Leaves start - protocol core
|
||||
+ var payload = org.leavesmc.leaves.protocol.core.LeavesProtocolManager.decode(identifier, buffer);
|
||||
+ return java.util.Objects.requireNonNullElseGet(payload, () -> this.findCodec(identifier).decode(buffer));
|
||||
+ // Leaves end - protocol core
|
||||
}
|
||||
};
|
||||
}
|
||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index 0bf2173c5445de021090c2d0264afc440b005bdc..076bfe7a7b57f8d3b29ef0aaad117707678da7a3 100644
|
||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -58,6 +58,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
public @Nullable String playerBrand;
|
||||
public final java.util.Set<String> pluginMessagerChannels;
|
||||
// Paper end - retain certain values
|
||||
+ public final GameProfile profile; // Leaves - protocol core
|
||||
|
||||
public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie) {
|
||||
this.server = server;
|
||||
@@ -71,6 +72,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
this.pluginMessagerChannels = cookie.channels();
|
||||
this.keepAlive = cookie.keepAlive();
|
||||
// Paper end
|
||||
+ this.profile = cookie.gameProfile(); // Leaves - protocol core
|
||||
}
|
||||
|
||||
// Paper start - configuration phase API
|
||||
@@ -161,6 +163,18 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
|
||||
@Override
|
||||
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
|
||||
+ // Leaves start - protocol
|
||||
+ if (packet.payload() instanceof org.leavesmc.leaves.protocol.core.LeavesCustomPayload leavesPayload) {
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePayload(org.leavesmc.leaves.protocol.core.ProtocolUtils.createSelector(this), leavesPayload);
|
||||
+ return;
|
||||
+ }
|
||||
+ if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.DiscardedPayload(net.minecraft.resources.Identifier id, byte[] data)) {
|
||||
+ if (org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleBytebuf(org.leavesmc.leaves.protocol.core.ProtocolUtils.createSelector(this), id, io.netty.buffer.Unpooled.wrappedBuffer(data))) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - protocol
|
||||
+
|
||||
// Paper start
|
||||
if (!(packet.payload() instanceof final net.minecraft.network.protocol.common.custom.DiscardedPayload discardedPayload)) {
|
||||
return;
|
||||
@@ -220,10 +234,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
final String channel = new String(data, from, length, java.nio.charset.StandardCharsets.US_ASCII);
|
||||
if (register) {
|
||||
bridge.addChannel(channel);
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleMinecraftRegister(channel, org.leavesmc.leaves.protocol.core.ProtocolUtils.createSelector(this)); // Leaves - protocol
|
||||
} else {
|
||||
bridge.removeChannel(channel);
|
||||
}
|
||||
- // Paper end
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -386,9 +401,9 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
net.minecraft.server.level.ServerPlayer player = serverGamePacketListener.player;
|
||||
org.bukkit.event.player.PlayerKickEvent.Cause cause = disconnectionDetails.disconnectionReason().orElseThrow().game().orElse(org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
|
||||
org.bukkit.event.player.PlayerKickEvent event = new org.bukkit.event.player.PlayerKickEvent(
|
||||
- player.getBukkitEntity(),
|
||||
- io.papermc.paper.adventure.PaperAdventure.asAdventure(disconnectionDetails.reason()),
|
||||
- rawLeaveMessage, cause
|
||||
+ player.getBukkitEntity(),
|
||||
+ io.papermc.paper.adventure.PaperAdventure.asAdventure(disconnectionDetails.reason()),
|
||||
+ rawLeaveMessage, cause
|
||||
|
||||
);
|
||||
|
||||
@@ -421,10 +436,10 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
|
||||
private void disconnect0(DisconnectionDetails disconnectionDetails) {
|
||||
this.connection
|
||||
- .send(
|
||||
- new ClientboundDisconnectPacket(disconnectionDetails.reason()),
|
||||
- PacketSendListener.thenRun(() -> this.connection.disconnect(disconnectionDetails))
|
||||
- );
|
||||
+ .send(
|
||||
+ new ClientboundDisconnectPacket(disconnectionDetails.reason()),
|
||||
+ PacketSendListener.thenRun(() -> this.connection.disconnect(disconnectionDetails))
|
||||
+ );
|
||||
this.onDisconnect(disconnectionDetails);
|
||||
this.connection.setReadOnly();
|
||||
// CraftBukkit - Don't wait
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index d2b2bf35b3f5704f3bca94d0fe3b70206c2fbf96..c8be04b8a50bac52150a1fdd238634e630e1765e 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -315,6 +315,8 @@ public abstract class PlayerList {
|
||||
//return; // Folia - region threading - must still allow the player to connect, as we must add to chunk map before handling disconnect
|
||||
}
|
||||
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player);
|
||||
+
|
||||
final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
|
||||
|
||||
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
|
||||
@@ -511,6 +513,7 @@ public abstract class PlayerList {
|
||||
return this.remove(player, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? player.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(player.getDisplayName())));
|
||||
}
|
||||
public net.kyori.adventure.text.@Nullable Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) {
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerLeave(player); // Leaves - protocol
|
||||
// Paper end - Fix kick event leave message not being sent
|
||||
ServerLevel serverLevel = player.level();
|
||||
player.awardStat(Stats.LEAVE_GAME);
|
||||
@@ -1401,6 +1404,7 @@ public abstract class PlayerList {
|
||||
serverPlayer.connection.send(clientboundUpdateRecipesPacket);
|
||||
serverPlayer.getRecipeBook().sendInitialRecipeBook(serverPlayer);
|
||||
}
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleDataPackReload(); // Leaves - protocol core
|
||||
}
|
||||
|
||||
public boolean isAllowCommandsForAllPlayers() {
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 29 Oct 2025 00:09:09 +0800
|
||||
Subject: [PATCH] Leaves: Configurable trading with the void
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index b0546cb4af7291013399e67d98bced98a5fffc0f..bf340425dc2a1545b9069badcf054d4c2f6a405f 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -3058,7 +3058,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Spigot start
|
||||
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
|
||||
// Paper start - Fix merchant inventory not closing on entity removal
|
||||
- if (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) {
|
||||
+ if (!fun.bm.lophine.config.modules.function.OldFeatureConfig.villagerVoidTrade && entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) { // Leaves - Configurable trading with the void
|
||||
merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED);
|
||||
}
|
||||
// Paper end - Fix merchant inventory not closing on entity removal
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index c8be04b8a50bac52150a1fdd238634e630e1765e..2eb551390aa66d89988df9ca23cf0dd7ccfd6577 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -555,7 +555,7 @@ public abstract class PlayerList {
|
||||
player.stopRiding();
|
||||
rootVehicle.getPassengersAndSelf().forEach(entity -> {
|
||||
// Paper start - Fix villager boat exploit
|
||||
- if (entity instanceof net.minecraft.world.entity.npc.villager.AbstractVillager villager) {
|
||||
+ if (!fun.bm.lophine.config.modules.function.OldFeatureConfig.villagerVoidTrade && entity instanceof net.minecraft.world.entity.npc.villager.AbstractVillager villager) { // Leaves - Configurable trading with the void
|
||||
final net.minecraft.world.entity.player.Player human = villager.getTradingPlayer();
|
||||
if (human != null) {
|
||||
villager.setTradingPlayer(null);
|
||||
diff --git a/net/minecraft/world/inventory/MerchantMenu.java b/net/minecraft/world/inventory/MerchantMenu.java
|
||||
index 6dfee62a46a5882df7f405e59d762647289d7866..1192a6ab33a9481397b84c9cf0a24fbbcb0ed065 100644
|
||||
--- a/net/minecraft/world/inventory/MerchantMenu.java
|
||||
+++ b/net/minecraft/world/inventory/MerchantMenu.java
|
||||
@@ -74,6 +74,7 @@ public class MerchantMenu extends AbstractContainerMenu {
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.villagerVoidTrade) return this.trader.getTradingPlayer() == player; // Leaves - Configurable trading with the void
|
||||
if (!checkReachable) return true; // Paper - checkReachable
|
||||
return this.trader.stillValid(player);
|
||||
}
|
||||
@@ -1,472 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Sat, 26 Jul 2025 01:11:54 +0800
|
||||
Subject: [PATCH] Leaves: Item overstack util
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/46cccfc39cafbca1681620d03947bc3ad558327f/leaves-server/minecraft-patches/features/0034-Item-overstack-util.patch)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/commands/arguments/item/ItemInput.java b/net/minecraft/commands/arguments/item/ItemInput.java
|
||||
index 8e08cb90dc94171a8da7126fe18c46eaa49a58f2..a7804a0d099c79c81eb45eb20402a001d8734529 100644
|
||||
--- a/net/minecraft/commands/arguments/item/ItemInput.java
|
||||
+++ b/net/minecraft/commands/arguments/item/ItemInput.java
|
||||
@@ -39,11 +39,13 @@ public class ItemInput {
|
||||
public ItemStack createItemStack(int count, boolean allowOversizedStacks) throws CommandSyntaxException {
|
||||
ItemStack itemStack = new ItemStack(this.item, count);
|
||||
itemStack.applyComponents(this.components);
|
||||
- if (allowOversizedStacks && count > itemStack.getMaxStackSize()) {
|
||||
- throw ERROR_STACK_TOO_BIG.create(this.getItemName(), itemStack.getMaxStackSize());
|
||||
+ // Leaves start - item over-stack util
|
||||
+ if (allowOversizedStacks && count > org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack)) {
|
||||
+ throw ERROR_STACK_TOO_BIG.create(this.getItemName(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack));
|
||||
} else {
|
||||
return itemStack;
|
||||
}
|
||||
+ // Leaves end - item over-stack util
|
||||
}
|
||||
|
||||
public String serialize(HolderLookup.Provider levelRegistry) {
|
||||
diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java
|
||||
index 1281eadb2d0c5b4ce5e3afd51d8205f9a4ef011c..b1446dfb4689174ee9f55cec6080622ec34de250 100644
|
||||
--- a/net/minecraft/server/commands/GiveCommand.java
|
||||
+++ b/net/minecraft/server/commands/GiveCommand.java
|
||||
@@ -54,7 +54,7 @@ public class GiveCommand {
|
||||
|
||||
private static int giveItem(CommandSourceStack source, ItemInput item, Collection<ServerPlayer> targets, int count) throws CommandSyntaxException {
|
||||
ItemStack itemStack = item.createItemStack(1, false);
|
||||
- int maxStackSize = itemStack.getMaxStackSize();
|
||||
+ int maxStackSize = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util
|
||||
int i = maxStackSize * 100;
|
||||
if (count > i) {
|
||||
source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", i, itemStack.getDisplayName()));
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 5c5dfcefd9ce6c9d7f69fb6d03216805b9e63822..d35ef52a6adb9a560138d1a2af32969c3a73f42b 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3170,7 +3170,7 @@ public class ServerGamePacketListenerImpl
|
||||
} else if (slot.mayPlace(cursor)) {
|
||||
if (ItemStack.isSameItemSameComponents(clickedItem, cursor)) {
|
||||
int toPlace = packet.buttonNum() == 0 ? cursor.getCount() : 1;
|
||||
- toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.getCount());
|
||||
+ toPlace = Math.min(toPlace, org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(clickedItem) - clickedItem.getCount()); // Leaves - item over-stack util
|
||||
toPlace = Math.min(toPlace, slot.container.getMaxStackSize() - clickedItem.getCount());
|
||||
if (toPlace == 1) {
|
||||
action = InventoryAction.PLACE_ONE;
|
||||
@@ -3206,7 +3206,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
} else if (ItemStack.isSameItemSameComponents(cursor, clickedItem)) {
|
||||
if (clickedItem.getCount() >= 0) {
|
||||
- if (clickedItem.getCount() + cursor.getCount() <= cursor.getMaxStackSize()) {
|
||||
+ if (clickedItem.getCount() + cursor.getCount() <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(cursor)) { // Leaves - item over-stack util
|
||||
// As of 1.5, this is result slots only
|
||||
action = InventoryAction.PICKUP_ALL;
|
||||
}
|
||||
@@ -3423,6 +3423,7 @@ public class ServerGamePacketListenerImpl
|
||||
this.player.containerMenu.broadcastFullState();
|
||||
} else {
|
||||
this.player.containerMenu.broadcastChanges();
|
||||
+ if (org.leavesmc.leaves.util.ItemOverstackUtils.hasOverstackingItem()) this.player.containerMenu.broadcastCarriedItem(); // Leaves - item over-stack util - force send carried item
|
||||
}
|
||||
if (packet.buttonNum() == Inventory.SLOT_OFFHAND && this.player.containerMenu != this.player.inventoryMenu) this.player.containerSynchronizer.sendOffHandSlotChange(); // Paper - update offhand data when the player is clicking in an inventory not their own as the sychronizer does not include offhand slots
|
||||
if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
|
||||
@@ -3534,7 +3535,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45;
|
||||
- boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= itemStack.getMaxStackSize();
|
||||
+ boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util
|
||||
if (flag || (flag1 && !ItemStack.matches(this.player.inventoryMenu.getSlot(packet.slotNum()).getItem(), packet.itemStack()))) { // Insist on valid slot
|
||||
// CraftBukkit start - Call click event
|
||||
org.bukkit.inventory.InventoryView inventory = this.player.inventoryMenu.getBukkitView();
|
||||
@@ -3576,6 +3577,7 @@ public class ServerGamePacketListenerImpl
|
||||
this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemStack);
|
||||
this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemStack);
|
||||
this.player.inventoryMenu.broadcastChanges();
|
||||
+ if (org.leavesmc.leaves.util.ItemOverstackUtils.hasOverstackingItem()) this.player.containerMenu.sendSingleSlot(packet.slotNum(), itemStack); // Leaves - item over-stack util - force send carried item
|
||||
if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
|
||||
} else if (flag && flag2) {
|
||||
if (this.dropSpamThrottler.isUnderThreshold()) {
|
||||
diff --git a/net/minecraft/world/Container.java b/net/minecraft/world/Container.java
|
||||
index b63cecafd841b97a694f6d2610141dcdb8f30574..392678778dc2a036c1e3db4b6bb2800e452d3cd0 100644
|
||||
--- a/net/minecraft/world/Container.java
|
||||
+++ b/net/minecraft/world/Container.java
|
||||
@@ -37,6 +37,12 @@ public interface Container extends Clearable, SlotProvider, Iterable<ItemStack>,
|
||||
return Math.min(this.getMaxStackSize(), stack.getMaxStackSize());
|
||||
}
|
||||
|
||||
+ // Leaves start - item over-stack util
|
||||
+ default int getMaxStackLeaves(ItemStack stack) {
|
||||
+ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack));
|
||||
+ }
|
||||
+ // Leaves end - item over-stack util
|
||||
+
|
||||
void setChanged();
|
||||
|
||||
boolean stillValid(Player player);
|
||||
diff --git a/net/minecraft/world/SimpleContainer.java b/net/minecraft/world/SimpleContainer.java
|
||||
index 0233c2b5e40c33330870e598431897a2ff98c2a3..3cf1819a9c82da2d2e0c43187e204353e3643369 100644
|
||||
--- a/net/minecraft/world/SimpleContainer.java
|
||||
+++ b/net/minecraft/world/SimpleContainer.java
|
||||
@@ -210,7 +210,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
|
||||
@Override
|
||||
public void setItem(int index, ItemStack stack) {
|
||||
this.items.set(index, stack);
|
||||
- stack.limitSize(this.getMaxStackSize(stack));
|
||||
+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util
|
||||
this.setChanged();
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
|
||||
}
|
||||
|
||||
private void moveItemsBetweenStacks(ItemStack stack, ItemStack other) {
|
||||
- int maxStackSize = this.getMaxStackSize(other);
|
||||
+ int maxStackSize = this.getMaxStackLeaves(other); // Leaves - item over-stack util
|
||||
int min = Math.min(stack.getCount(), maxStackSize - other.getCount());
|
||||
if (min > 0) {
|
||||
other.grow(min);
|
||||
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index 16c42a5e35c6ee1df640e5831818099fab6338f1..f3f067c62dc024a747d059608ae7a2e8740dbff2 100644
|
||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -271,10 +271,15 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish
|
||||
|
||||
private boolean isMergable() {
|
||||
ItemStack item = this.getItem();
|
||||
- return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < item.getMaxStackSize(); // Paper - Alternative item-despawn-rate
|
||||
+ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(item); // Paper - Alternative item-despawn-rate // Leaves - item over-stack util
|
||||
}
|
||||
|
||||
private void tryToMerge(ItemEntity itemEntity) {
|
||||
+ // Leaves start - item over-stack util
|
||||
+ if (org.leavesmc.leaves.util.ItemOverstackUtils.tryStackItems(this, itemEntity)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - item over-stack util
|
||||
ItemStack item = this.getItem();
|
||||
ItemStack item1 = itemEntity.getItem();
|
||||
if (Objects.equals(this.target, itemEntity.target) && areMergable(item, item1)) {
|
||||
diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java
|
||||
index 41e59f3739945ca7f6ab710c993b5c0f15fcd529..b849b04f227b43d036f4f6b3ae7accfafc389d9f 100644
|
||||
--- a/net/minecraft/world/entity/player/Inventory.java
|
||||
+++ b/net/minecraft/world/entity/player/Inventory.java
|
||||
@@ -166,10 +166,12 @@ public class Inventory implements Container, Nameable {
|
||||
}
|
||||
|
||||
private boolean hasRemainingSpaceForItem(ItemStack destination, ItemStack origin) {
|
||||
+ // Leaves start - item over-stack util
|
||||
return !destination.isEmpty()
|
||||
- && destination.isStackable()
|
||||
- && destination.getCount() < this.getMaxStackSize(destination)
|
||||
+ && org.leavesmc.leaves.util.ItemOverstackUtils.isStackable(destination)
|
||||
+ && destination.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(destination)
|
||||
&& ItemStack.isSameItemSameComponents(destination, origin); // Paper - check if itemstack is stackable first
|
||||
+ // Leaves end - item over-stack util
|
||||
}
|
||||
|
||||
// CraftBukkit start - Watch method above! :D
|
||||
@@ -182,7 +184,7 @@ public class Inventory implements Container, Nameable {
|
||||
}
|
||||
|
||||
if (this.hasRemainingSpaceForItem(itemInSlot, itemStack)) {
|
||||
- remains -= (itemInSlot.getMaxStackSize() < this.getMaxStackSize() ? itemInSlot.getMaxStackSize() : this.getMaxStackSize()) - itemInSlot.getCount();
|
||||
+ remains -= (org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInSlot) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInSlot) : this.getMaxStackSize()) - itemInSlot.getCount(); // Leaves - item over-stack util
|
||||
}
|
||||
if (remains <= 0) {
|
||||
return itemStack.getCount();
|
||||
@@ -191,7 +193,7 @@ public class Inventory implements Container, Nameable {
|
||||
|
||||
ItemStack itemInOffhand = this.equipment.get(EquipmentSlot.OFFHAND);
|
||||
if (this.hasRemainingSpaceForItem(itemInOffhand, itemStack)) {
|
||||
- remains -= (itemInOffhand.getMaxStackSize() < this.getMaxStackSize() ? itemInOffhand.getMaxStackSize() : this.getMaxStackSize()) - itemInOffhand.getCount();
|
||||
+ remains -= (org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInOffhand) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInOffhand) : this.getMaxStackSize()) - itemInOffhand.getCount(); // Leaves - item over-stack util
|
||||
}
|
||||
if (remains <= 0) {
|
||||
return itemStack.getCount();
|
||||
@@ -315,7 +317,7 @@ public class Inventory implements Container, Nameable {
|
||||
this.setItem(slot, item);
|
||||
}
|
||||
|
||||
- int i = this.getMaxStackSize(item) - item.getCount();
|
||||
+ int i = this.getMaxStackLeaves(item) - item.getCount(); // Leaves - item over-stack util
|
||||
int min = Math.min(count, i);
|
||||
if (min == 0) {
|
||||
return count;
|
||||
@@ -421,7 +423,7 @@ public class Inventory implements Container, Nameable {
|
||||
break;
|
||||
}
|
||||
|
||||
- int i = stack.getMaxStackSize() - this.getItem(slotWithRemainingSpace).getCount();
|
||||
+ int i = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack) - this.getItem(slotWithRemainingSpace).getCount(); // Leaves - item over-stack util
|
||||
if (this.add(slotWithRemainingSpace, stack.split(i)) && sendPacket && this.player instanceof ServerPlayer serverPlayer) {
|
||||
serverPlayer.connection.send(this.createInventoryUpdatePacket(slotWithRemainingSpace));
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/player/StackedItemContents.java b/net/minecraft/world/entity/player/StackedItemContents.java
|
||||
index 00dbc0d125b2c8c208ffa46f9084c6317efaba90..1f57b3c60fd0cbfdd65e06f8994525ade6dc6bd9 100644
|
||||
--- a/net/minecraft/world/entity/player/StackedItemContents.java
|
||||
+++ b/net/minecraft/world/entity/player/StackedItemContents.java
|
||||
@@ -36,7 +36,7 @@ public class StackedItemContents {
|
||||
}
|
||||
|
||||
public void accountStack(ItemStack stack) {
|
||||
- this.accountStack(stack, stack.getMaxStackSize());
|
||||
+ this.accountStack(stack, org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack)); // Leaves - item over-stack util
|
||||
}
|
||||
|
||||
public void accountStack(ItemStack stack, int maxStackSize) {
|
||||
diff --git a/net/minecraft/world/entity/vehicle/ContainerEntity.java b/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
index 44276ba9c7aab306cfd12833a834ebe61cf64e7c..0a19a7782f3fa27c41e02393e887ba7cc727012b 100644
|
||||
--- a/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
+++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
@@ -162,7 +162,7 @@ public interface ContainerEntity extends Container, MenuProvider {
|
||||
default void setChestVehicleItem(int slot, ItemStack stack) {
|
||||
this.unpackChestVehicleLootTable(null);
|
||||
this.getItemStacks().set(slot, stack);
|
||||
- stack.limitSize(this.getMaxStackSize(stack));
|
||||
+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util
|
||||
}
|
||||
|
||||
default @Nullable SlotAccess getChestVehicleSlot(final int slot) {
|
||||
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 3b1c6a2397950ceb167890961b635cc69aaf8950..e7ea8849e8fa942709f505145e8076f064476206 100644
|
||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -292,6 +292,13 @@ public abstract class AbstractContainerMenu {
|
||||
this.sendAllDataToRemote();
|
||||
}
|
||||
|
||||
+ // Leaves start - item over-stack util
|
||||
+ public void sendSingleSlot(int slotIndex, ItemStack item) {
|
||||
+ if (this.synchronizer != null) {
|
||||
+ this.synchronizer.sendSlotChange(this, slotIndex, item);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - item over-stack util
|
||||
private void updateDataSlotListeners(int slotIndex, int value) {
|
||||
for (ContainerListener containerListener : this.containerListeners) {
|
||||
containerListener.dataChanged(this, slotIndex, value);
|
||||
@@ -448,7 +455,7 @@ public abstract class AbstractContainerMenu {
|
||||
&& (this.quickcraftType == 2 || carried1.getCount() >= this.quickcraftSlots.size())
|
||||
&& this.canDragTo(slot1)) {
|
||||
int i2 = slot1.hasItem() ? slot1.getItem().getCount() : 0;
|
||||
- int min = Math.min(itemStack.getMaxStackSize(), slot1.getMaxStackSize(itemStack));
|
||||
+ int min = Math.min(org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack), slot1.getMaxStackSize(itemStack)); // Leaves - item over-stack util
|
||||
int min1 = Math.min(getQuickCraftPlaceCount(this.quickcraftSlots, this.quickcraftType, itemStack) + i2, min);
|
||||
count -= min1 - i2;
|
||||
// slot1.setByPlayer(itemStack.copyWithCount(min1));
|
||||
@@ -556,7 +563,7 @@ public abstract class AbstractContainerMenu {
|
||||
slot.setByPlayer(carried2);
|
||||
}
|
||||
} else if (ItemStack.isSameItemSameComponents(carried, carried2)) {
|
||||
- Optional<ItemStack> optional1 = slot.tryRemove(carried.getCount(), carried2.getMaxStackSize() - carried2.getCount(), player);
|
||||
+ Optional<ItemStack> optional1 = slot.tryRemove(carried.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(carried2) - carried2.getCount(), player); // Leaves - item over-stack util
|
||||
optional1.ifPresent(itemStack2 -> {
|
||||
carried2.grow(itemStack2.getCount());
|
||||
slot.onTake(player, itemStack2);
|
||||
@@ -618,7 +625,7 @@ public abstract class AbstractContainerMenu {
|
||||
Slot slot2 = this.slots.get(slotIndex);
|
||||
if (slot2.hasItem()) {
|
||||
ItemStack itemStack = slot2.getItem();
|
||||
- this.setCarried(itemStack.copyWithCount(itemStack.getMaxStackSize()));
|
||||
+ this.setCarried(itemStack.copyWithCount(org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack))); // Leaves - item over-stack util
|
||||
}
|
||||
} else if (clickType == ClickType.THROW && this.getCarried().isEmpty() && slotIndex >= 0) {
|
||||
Slot slot2 = this.slots.get(slotIndex);
|
||||
@@ -653,15 +660,15 @@ public abstract class AbstractContainerMenu {
|
||||
int maxStackSize = button == 0 ? 1 : -1;
|
||||
|
||||
for (int i3 = 0; i3 < 2; i3++) {
|
||||
- for (int i4 = count; i4 >= 0 && i4 < this.slots.size() && itemStack.getCount() < itemStack.getMaxStackSize(); i4 += maxStackSize) {
|
||||
+ for (int i4 = count; i4 >= 0 && i4 < this.slots.size() && itemStack.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); i4 += maxStackSize) { // Leaves - item over-stack util
|
||||
Slot slot3 = this.slots.get(i4);
|
||||
if (slot3.hasItem()
|
||||
&& canItemQuickReplace(slot3, itemStack, true)
|
||||
&& slot3.mayPickup(player)
|
||||
&& this.canTakeItemForPickAll(itemStack, slot3)) {
|
||||
ItemStack item1 = slot3.getItem();
|
||||
- if (i3 != 0 || item1.getCount() != item1.getMaxStackSize()) {
|
||||
- ItemStack itemStack1 = slot3.safeTake(item1.getCount(), itemStack.getMaxStackSize() - itemStack.getCount(), player);
|
||||
+ if (i3 != 0 || item1.getCount() != org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(item1)) { // Leaves - item over-stack util
|
||||
+ ItemStack itemStack1 = slot3.safeTake(item1.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack) - itemStack.getCount(), player); // Leaves - item over-stack util
|
||||
itemStack.grow(itemStack1.getCount());
|
||||
}
|
||||
}
|
||||
@@ -763,7 +770,7 @@ public abstract class AbstractContainerMenu {
|
||||
i = endIndex - 1;
|
||||
}
|
||||
|
||||
- if (stack.isStackable()) {
|
||||
+ if (org.leavesmc.leaves.util.ItemOverstackUtils.isStackable(stack)) { // Leaves - item over-stack util
|
||||
while (!stack.isEmpty() && (reverseDirection ? i >= startIndex : i < endIndex)) {
|
||||
Slot slot = this.slots.get(i);
|
||||
ItemStack item = slot.getItem();
|
||||
@@ -864,7 +871,7 @@ public abstract class AbstractContainerMenu {
|
||||
public static boolean canItemQuickReplace(@Nullable Slot slot, ItemStack stack, boolean stackSizeMatters) {
|
||||
boolean flag = slot == null || !slot.hasItem();
|
||||
return !flag && ItemStack.isSameItemSameComponents(stack, slot.getItem())
|
||||
- ? slot.getItem().getCount() + (stackSizeMatters ? 0 : stack.getCount()) <= stack.getMaxStackSize()
|
||||
+ ? slot.getItem().getCount() + (stackSizeMatters ? 0 : stack.getCount()) <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack) // Leaves - item over-stack util
|
||||
: flag;
|
||||
}
|
||||
|
||||
@@ -872,7 +879,7 @@ public abstract class AbstractContainerMenu {
|
||||
return switch (type) {
|
||||
case 0 -> Mth.floor((float)stack.getCount() / slots.size());
|
||||
case 1 -> 1;
|
||||
- case 2 -> stack.getMaxStackSize();
|
||||
+ case 2 -> org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack); // Leaves - item over-stack util
|
||||
default -> stack.getCount();
|
||||
};
|
||||
}
|
||||
@@ -895,7 +902,7 @@ public abstract class AbstractContainerMenu {
|
||||
for (int i = 0; i < container.getContainerSize(); i++) {
|
||||
ItemStack item = container.getItem(i);
|
||||
if (!item.isEmpty()) {
|
||||
- f += (float)item.getCount() / container.getMaxStackSize(item);
|
||||
+ f += Math.clamp((float) item.getCount() / container.getMaxStackSize(item), 0f, 1f); // Leaves - item over-stack util
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/inventory/MerchantContainer.java b/net/minecraft/world/inventory/MerchantContainer.java
|
||||
index a4203c416c7a83557055099a9ea8f43ac2b18b21..46c8026876e851ec4a31fd34c9b64623469ffb8d 100644
|
||||
--- a/net/minecraft/world/inventory/MerchantContainer.java
|
||||
+++ b/net/minecraft/world/inventory/MerchantContainer.java
|
||||
@@ -108,7 +108,7 @@ public class MerchantContainer implements Container {
|
||||
@Override
|
||||
public void setItem(int index, ItemStack stack) {
|
||||
this.itemStacks.set(index, stack);
|
||||
- stack.limitSize(this.getMaxStackSize(stack));
|
||||
+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util
|
||||
if (this.isPaymentSlot(index)) {
|
||||
this.updateSellItem();
|
||||
}
|
||||
diff --git a/net/minecraft/world/inventory/Slot.java b/net/minecraft/world/inventory/Slot.java
|
||||
index 2b7e245ebf3bb471a1d817c4b5d56a64790cbab7..00083df87439ff0fa56e09853931b60579520d0e 100644
|
||||
--- a/net/minecraft/world/inventory/Slot.java
|
||||
+++ b/net/minecraft/world/inventory/Slot.java
|
||||
@@ -75,7 +75,7 @@ public class Slot {
|
||||
}
|
||||
|
||||
public int getMaxStackSize(ItemStack stack) {
|
||||
- return Math.min(this.getMaxStackSize(), stack.getMaxStackSize());
|
||||
+ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack)); // Leaves - item over-stack util
|
||||
}
|
||||
|
||||
public @Nullable Identifier getNoItemIcon() {
|
||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||
index ed2971b54afbebe37a7ff61798778a4249b79856..73a97f4f62fe7d27b441cab58c6c86ffce011060 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -174,7 +174,7 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||
private int popTime;
|
||||
@Deprecated
|
||||
private @Nullable Item item;
|
||||
- PatchedDataComponentMap components;
|
||||
+ public PatchedDataComponentMap components; // Leaves - item over-stack util
|
||||
private @Nullable Entity entityRepresentation;
|
||||
|
||||
public static DataResult<ItemStack> validateStrict(ItemStack stack) {
|
||||
@@ -200,7 +200,8 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||
} else {
|
||||
Holder<Item> holder = Item.STREAM_CODEC.decode(buffer);
|
||||
DataComponentPatch dataComponentPatch = codec.decode(buffer);
|
||||
- return new ItemStack(holder, varInt, dataComponentPatch);
|
||||
+ ItemStack itemStack = new ItemStack(holder, varInt, dataComponentPatch);
|
||||
+ return org.leavesmc.leaves.util.ItemOverstackUtils.decodeMaxStackSize(itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,13 +210,15 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||
if (value.isEmpty() || value.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem()
|
||||
buffer.writeVarInt(0);
|
||||
} else {
|
||||
- buffer.writeVarInt(io.papermc.paper.util.sanitizer.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.sanitizer.ItemObfuscationSession.currentSession(), value, value.getCount())); // Paper - potentially sanitize count
|
||||
- Item.STREAM_CODEC.encode(buffer, value.getItemHolder());
|
||||
+ // Leaves start - item over-stack util
|
||||
+ final ItemStack itemStack = org.leavesmc.leaves.util.ItemOverstackUtils.encodeMaxStackSize(value.copy());
|
||||
+ buffer.writeVarInt(io.papermc.paper.util.sanitizer.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.sanitizer.ItemObfuscationSession.currentSession(), itemStack, itemStack.getCount())); // Paper - potentially sanitize count
|
||||
+ Item.STREAM_CODEC.encode(buffer, itemStack.getItemHolder());
|
||||
// Paper start - adventure; conditionally render translatable components
|
||||
boolean prev = net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.get();
|
||||
- try (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.withContext(c -> c.itemStack(value))) { // pass the itemstack as context to the obfuscation session
|
||||
+ try (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.withContext(c -> c.itemStack(itemStack))) { // pass the itemstack as context to the obfuscation session
|
||||
net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(true);
|
||||
- codec.encode(buffer, value.components.asPatch());
|
||||
+ codec.encode(buffer, itemStack.components.asPatch());
|
||||
} finally {
|
||||
net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(prev);
|
||||
}
|
||||
@@ -309,7 +312,7 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||
|
||||
for (ItemStack itemStack : itemContainerContents.nonEmptyItems()) {
|
||||
int count = itemStack.getCount();
|
||||
- int maxStackSize = itemStack.getMaxStackSize();
|
||||
+ int maxStackSize = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util
|
||||
if (count > maxStackSize) {
|
||||
return DataResult.error(() -> "Item stack with count of " + count + " was larger than maximum: " + maxStackSize);
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/CrafterBlock.java b/net/minecraft/world/level/block/CrafterBlock.java
|
||||
index c5fe15844d405a27cdae18c903dd481c25b437de..3faa541c4a4623e915269d6241e1a3a3c6e374ff 100644
|
||||
--- a/net/minecraft/world/level/block/CrafterBlock.java
|
||||
+++ b/net/minecraft/world/level/block/CrafterBlock.java
|
||||
@@ -191,7 +191,7 @@ public class CrafterBlock extends BaseEntityBlock {
|
||||
Direction direction = state.getValue(ORIENTATION).front();
|
||||
Container containerAt = HopperBlockEntity.getContainerAt(level, pos.relative(direction));
|
||||
ItemStack itemStack = stack.copy();
|
||||
- if (containerAt != null && (containerAt instanceof CrafterBlockEntity || stack.getCount() > containerAt.getMaxStackSize(stack))) {
|
||||
+ if (containerAt != null && (containerAt instanceof CrafterBlockEntity || stack.getCount() > containerAt.getMaxStackLeaves(stack))) { // Leaves - item over-stack util
|
||||
// CraftBukkit start - InventoryMoveItemEvent
|
||||
org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack);
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
index 9346f2deca8eeca29fa2fced416247fd1609249e..07236e86638faa3231917af507cdd37ac49b1270 100644
|
||||
--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -412,7 +412,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
ItemStack itemStack = this.items.get(index);
|
||||
boolean flag = !stack.isEmpty() && ItemStack.isSameItemSameComponents(itemStack, stack);
|
||||
this.items.set(index, stack);
|
||||
- stack.limitSize(this.getMaxStackSize(stack));
|
||||
+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util
|
||||
if (index == 0 && !flag && this.level instanceof ServerLevel serverLevel) {
|
||||
this.cookingTotalTime = getTotalCookTime(serverLevel, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API
|
||||
this.cookingTimer = 0;
|
||||
diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
index 8f80c469c309bf61328c4f98037495f47a38c3c1..b4127d4b4386b98205275a9a0ef8067ccf287e67 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
@@ -134,7 +134,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
|
||||
@Override
|
||||
public void setItem(int slot, ItemStack stack) {
|
||||
this.getItems().set(slot, stack);
|
||||
- stack.limitSize(this.getMaxStackSize(stack));
|
||||
+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util
|
||||
this.setChanged();
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 53c50d776e5ca66e5903a464d763a7df5b7672be..6cdb59762b5b223a220d420ff99fa9eadc64f3e0 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -145,7 +145,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
public void setItem(int index, ItemStack stack) {
|
||||
this.unpackLootTable(null);
|
||||
this.getItems().set(index, stack);
|
||||
- stack.limitSize(this.getMaxStackSize(stack));
|
||||
+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -741,9 +741,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
if (item.isEmpty()) {
|
||||
// Spigot start - SPIGOT-6693, SimpleContainer#setItem
|
||||
ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size
|
||||
- if (!stack.isEmpty() && stack.getCount() > destination.getMaxStackSize()) {
|
||||
+ if (!stack.isEmpty() && (stack.getCount() > destination.getMaxStackSize() || stack.getCount() > stack.getMaxStackSize())) { // Leaves - item over-stack util
|
||||
leftover = stack; // Paper - Make hoppers respect inventory max stack size
|
||||
- stack = stack.split(destination.getMaxStackSize());
|
||||
+ stack = stack.split(Math.min(destination.getMaxStackSize(), stack.getMaxStackSize())); // Leaves - item over-stack util
|
||||
}
|
||||
// Spigot end
|
||||
//IGNORE_TILE_UPDATES.set(Boolean.TRUE); // Paper - Perf: Optimize Hoppers // Folia - region threading // Luminol - vanilla hopper
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 7 Jul 2025 15:33:57 +0800
|
||||
Subject: [PATCH] Leaves: Old Explosion Damage Calculator
|
||||
|
||||
Co-authored by: MC_XiaoHei <xor7xiaohei@gmail.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/3e96b237749a960f297f211d439ffc9ea7fd2381/leaves-server/minecraft-patches/features/0134-Old-wet-tnt-explode-behavior.patch)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
|
||||
index 08a1be57e1057a9e961eeb8f59cd12e98ed52bab..33ee967d8a7d4ce2c455db9ffaac740cd589e6f3 100644
|
||||
--- a/net/minecraft/world/level/ServerExplosion.java
|
||||
+++ b/net/minecraft/world/level/ServerExplosion.java
|
||||
@@ -717,6 +717,7 @@ public class ServerExplosion implements Explosion {
|
||||
public boolean shouldAffectBlocklikeEntities() {
|
||||
boolean flag = this.level.getGameRules().get(GameRules.MOB_GRIEFING);
|
||||
boolean flag1 = this.source == null || this.source.getType() != EntityType.BREEZE_WIND_CHARGE && this.source.getType() != EntityType.WIND_CHARGE;
|
||||
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldExplosionDamageCalculator) flag1 = flag1 && (this.source == null || !this.source.isInWater()); // Leaves - Old MC TNT wet explosion no item damage
|
||||
return flag ? flag1 : this.blockInteraction.shouldAffectBlocklikeEntities() && flag1;
|
||||
}
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Fri, 11 Apr 2025 16:53:57 +0800
|
||||
Subject: [PATCH] Leaves: Old raid behavior
|
||||
|
||||
Co-authored by: huanli233 <392352840@qq.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/79d9ef74c2684eb49060f07e1ab31c827326c9a5/leaves-server/minecraft-patches/features/0106-Old-raid-behavior.patch)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/effect/BadOmenMobEffect.java b/net/minecraft/world/effect/BadOmenMobEffect.java
|
||||
index 80f17f33f670018240c854df589cf90cdeab6e70..c9af615ff9120c07787f436dbb6024e54e3a498b 100644
|
||||
--- a/net/minecraft/world/effect/BadOmenMobEffect.java
|
||||
+++ b/net/minecraft/world/effect/BadOmenMobEffect.java
|
||||
@@ -22,6 +22,11 @@ class BadOmenMobEffect extends MobEffect {
|
||||
&& !serverPlayer.isSpectator()
|
||||
&& level.getDifficulty() != Difficulty.PEACEFUL
|
||||
&& level.isVillage(serverPlayer.blockPosition())) {
|
||||
+ // Leaves start - Revert raid changes
|
||||
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) {
|
||||
+ return level.getRaids().createOrExtendRaid(serverPlayer, serverPlayer.blockPosition()) == null;
|
||||
+ }
|
||||
+ // Leaves end - Revert raid changes
|
||||
Raid raidAt = level.getRaidAt(serverPlayer.blockPosition());
|
||||
if (raidAt == null || raidAt.getRaidOmenLevel() < raidAt.getMaxRaidOmenLevel()) {
|
||||
serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier));
|
||||
diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java
|
||||
index dcdd6f230ff153a7b58d13b963d32376b1905b72..be9c78f2cf121e8ae55c1b18685877637a25ec80 100644
|
||||
--- a/net/minecraft/world/entity/raid/Raid.java
|
||||
+++ b/net/minecraft/world/entity/raid/Raid.java
|
||||
@@ -264,7 +264,7 @@ public class Raid {
|
||||
}
|
||||
|
||||
public boolean absorbRaidOmen(ServerPlayer player) {
|
||||
- MobEffectInstance effect = player.getEffect(MobEffects.RAID_OMEN);
|
||||
+ MobEffectInstance effect = player.getEffect(fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? MobEffects.BAD_OMEN : MobEffects.RAID_OMEN); // Leaves - old Raid Behavior
|
||||
if (effect == null) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -341,7 +341,13 @@ public class Raid {
|
||||
}
|
||||
|
||||
if (flag1) {
|
||||
- this.waveSpawnPos = this.getValidSpawnPos(level);
|
||||
+ // Leaves Start - old FindSpawnPosition
|
||||
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) {
|
||||
+ this.waveSpawnPos = this.preCalcRavagerSpawnLocation(level, this.raidCooldownTicks < 100 ? 1 : 0);
|
||||
+ } else {
|
||||
+ this.waveSpawnPos = this.getValidSpawnPos(level);
|
||||
+ }
|
||||
+ // Leaves End - old FindSpawnPosition
|
||||
}
|
||||
|
||||
if (this.raidCooldownTicks == 300 || this.raidCooldownTicks % 20 == 0) {
|
||||
@@ -396,7 +402,14 @@ public class Raid {
|
||||
int i = 0;
|
||||
|
||||
while (this.shouldSpawnGroup()) {
|
||||
- BlockPos blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20));
|
||||
+ // Leaves Start - old FindSpawnPosition
|
||||
+ BlockPos blockPos;
|
||||
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) {
|
||||
+ blockPos = this.getRavagerSpawnLocation(level, i, 20);
|
||||
+ } else {
|
||||
+ blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20));
|
||||
+ }
|
||||
+ // Leaves End - old FindSpawnPosition
|
||||
if (blockPos != null) {
|
||||
this.started = true;
|
||||
this.spawnGroup(level, blockPos);
|
||||
@@ -408,7 +421,7 @@ public class Raid {
|
||||
i++;
|
||||
}
|
||||
|
||||
- if (i > 5) {
|
||||
+ if (i > (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? 3 : 5)) { // Leaves - old FindSpawnPosition
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(level, this, org.bukkit.event.raid.RaidStopEvent.Reason.UNSPAWNABLE); // CraftBukkit
|
||||
this.stop();
|
||||
break;
|
||||
@@ -702,7 +715,7 @@ public class Raid {
|
||||
int i2 = this.center.getX() + Mth.floor(Mth.cos(f2) * 32.0F * f) + level.random.nextInt(3) * Mth.floor(f);
|
||||
int i3 = this.center.getZ() + Mth.floor(Mth.sin(f2) * 32.0F * f) + level.random.nextInt(3) * Mth.floor(f);
|
||||
int height = level.getHeight(Heightmap.Types.WORLD_SURFACE, i2, i3);
|
||||
- if (Mth.abs(height - this.center.getY()) <= 96) {
|
||||
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior || Mth.abs(height - this.center.getY()) <= 96) { // Leaves - skippable
|
||||
mutableBlockPos.set(i2, height, i3);
|
||||
if (!level.isVillage(mutableBlockPos) || i <= 7) {
|
||||
int i4 = 10;
|
||||
@@ -721,6 +734,36 @@ public class Raid {
|
||||
return null;
|
||||
}
|
||||
|
||||
+ // Leaves Start - old FindSpawnPosition
|
||||
+ @Nullable
|
||||
+ private BlockPos findRandomSpawnPos(ServerLevel level, int n, int n2) {
|
||||
+ int n3 = 2 - n;
|
||||
+ BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
||||
+ SpawnPlacementType spawnPlacementType = SpawnPlacements.getPlacementType(EntityType.RAVAGER);
|
||||
+ for (int i = 0; i < n2; ++i) {
|
||||
+ float f = level.random.nextFloat() * ((float)Math.PI * 2);
|
||||
+ int n4 = this.center.getX() + Mth.floor(Mth.cos(f) * 32.0f * (float)n3) + level.random.nextInt(5);
|
||||
+ int n5 = this.center.getZ() + Mth.floor(Mth.sin(f) * 32.0f * (float)n3) + level.random.nextInt(5);
|
||||
+ int n6 = level.getHeight(Heightmap.Types.WORLD_SURFACE, n4, n5);
|
||||
+ mutableBlockPos.set(n4, n6, n5);
|
||||
+ if (level.isVillage(mutableBlockPos) && n < 2) continue;
|
||||
+ if (!level.hasChunksAt(mutableBlockPos.getX() - 10, mutableBlockPos.getZ() - 10, mutableBlockPos.getX() + 10, mutableBlockPos.getZ() + 10) || !level.isPositionEntityTicking(mutableBlockPos) || !spawnPlacementType.isSpawnPositionOk(level, mutableBlockPos, EntityType.RAVAGER) && (!level.getBlockState((BlockPos)mutableBlockPos.below()).is(Blocks.SNOW) || !level.getBlockState(mutableBlockPos).isAir())) continue;
|
||||
+ return mutableBlockPos;
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ private Optional<BlockPos> getValidSpawnPos(ServerLevel level, int n) {
|
||||
+ for (int i = 0; i < 3; ++i) {
|
||||
+ BlockPos blockPos = this.findRandomSpawnPos(level, n, 1);
|
||||
+ if (blockPos == null) continue;
|
||||
+ return Optional.of(blockPos);
|
||||
+ }
|
||||
+ return Optional.empty();
|
||||
+ }
|
||||
+ // Leaves End - old FindSpawnPosition
|
||||
+
|
||||
+
|
||||
private boolean addWaveMob(ServerLevel level, int wave, Raider raider) {
|
||||
// Folia start - make raids thread-safe
|
||||
if (!this.ownsRaid(level)) {
|
||||
@@ -883,4 +926,43 @@ public class Raid {
|
||||
this.spawnsPerWaveBeforeBonus = spawnsPerWaveBeforeBonus;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Leaves start - old FindSpawnPosition
|
||||
+ private BlockPos getRavagerSpawnLocation(ServerLevel serverWorld, int proximity, int tries) {
|
||||
+ int i = proximity == 0 ? 2 : 2 - proximity;
|
||||
+ BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();
|
||||
+ SpawnPlacementType spawnLocation = SpawnPlacements.getPlacementType(EntityType.RAVAGER);
|
||||
+
|
||||
+ for (int j = 0; j < tries; j++) {
|
||||
+ float f = serverWorld.random.nextFloat() * (float) (Math.PI * 2);
|
||||
+ int k = this.center.getX() + Mth.floor(Mth.cos(f) * 32.0F * (float) i + serverWorld.random.nextInt(5));
|
||||
+ int l = this.center.getZ() + Mth.floor(Mth.sin(f) * 32.0F * (float) i + serverWorld.random.nextInt(5));
|
||||
+ int m = serverWorld.getHeight(Heightmap.Types.WORLD_SURFACE, k, l);
|
||||
+ mutable.set(k, m, l);
|
||||
+
|
||||
+ if (serverWorld.isVillage(mutable) && proximity < 2) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (serverWorld.hasChunksAt(mutable.getX() - 10, mutable.getZ() - 10, mutable.getX() + 10, mutable.getZ() + 10)
|
||||
+ && serverWorld.isPositionEntityTicking(mutable)
|
||||
+ && (spawnLocation.isSpawnPositionOk(serverWorld, mutable, EntityType.RAVAGER)
|
||||
+ || serverWorld.getBlockState(mutable.below()).is(Blocks.SNOW)
|
||||
+ && serverWorld.getBlockState(mutable).isAir())
|
||||
+ ) {
|
||||
+ return mutable;
|
||||
+ }
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ private Optional<BlockPos> preCalcRavagerSpawnLocation(ServerLevel serverWorld, int proximity) {
|
||||
+ for (int i = 0; i < 3; i++) {
|
||||
+ BlockPos blockPos = this.getRavagerSpawnLocation(serverWorld, proximity, 1);
|
||||
+ if (blockPos != null) {
|
||||
+ return Optional.of(blockPos);
|
||||
+ }
|
||||
+ }
|
||||
+ return Optional.empty();
|
||||
+ }
|
||||
+ // Leaves end - old FindSpawnPosition
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
|
||||
index 5e8245e6dd8a07ece83dd1bc20e351a92044e7a0..2b7894a4104d4cb237746a3e66d4368b6f8f3c1e 100644
|
||||
--- a/net/minecraft/world/entity/raid/Raider.java
|
||||
+++ b/net/minecraft/world/entity/raid/Raider.java
|
||||
@@ -127,6 +127,43 @@ public abstract class Raider extends PatrollingMonster {
|
||||
|
||||
currentRaid.removeFromRaid(serverLevel, this, false);
|
||||
}
|
||||
+
|
||||
+ // Leaves start - Revert raid changes
|
||||
+ if (this.level() instanceof ServerLevel) {
|
||||
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior && !this.hasRaid()) {
|
||||
+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
|
||||
+ net.minecraft.world.entity.player.Player entityhuman = null;
|
||||
+ if (entity instanceof net.minecraft.world.entity.player.Player player) {
|
||||
+ entityhuman = player;
|
||||
+ } else if (entity instanceof net.minecraft.world.entity.animal.wolf.Wolf wolf) {
|
||||
+ LivingEntity entityliving = wolf.getOwner();
|
||||
+ if (wolf.isTame() && entityliving instanceof net.minecraft.world.entity.player.Player player) {
|
||||
+ entityhuman = player;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (entityhuman != null && !itemstack.isEmpty() && this.isCaptain()) {
|
||||
+ net.minecraft.world.effect.MobEffectInstance mobeffect = entityhuman.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN);
|
||||
+ int i = 1;
|
||||
+
|
||||
+ if (mobeffect != null) {
|
||||
+ i += mobeffect.getAmplifier();
|
||||
+ entityhuman.removeEffectNoUpdate(net.minecraft.world.effect.MobEffects.BAD_OMEN);
|
||||
+ } else {
|
||||
+ --i;
|
||||
+ }
|
||||
+
|
||||
+ i = net.minecraft.util.Mth.clamp(i, 0, 4);
|
||||
+ net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, i, false, false, true);
|
||||
+
|
||||
+ if (serverLevel.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.RAIDS)) {
|
||||
+ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit
|
||||
+ }
|
||||
+ this.setPatrolLeader(false);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - Revert raid changes
|
||||
}
|
||||
|
||||
super.die(damageSource);
|
||||
@@ -1,25 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 23 Jul 2025 20:28:40 +0800
|
||||
Subject: [PATCH] Leaves: Redstone Shears Wrench
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/79d9ef74c2684eb49060f07e1ab31c827326c9a5/leaves-server/minecraft-patches/features/0009-Redstone-Shears-Wrench.patch)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/item/ShearsItem.java b/net/minecraft/world/item/ShearsItem.java
|
||||
index 5e25ddf78f72ada318ef28d29199de9b93fe667e..6f48162a25e20d2439935e8995cede9497626322 100644
|
||||
--- a/net/minecraft/world/item/ShearsItem.java
|
||||
+++ b/net/minecraft/world/item/ShearsItem.java
|
||||
@@ -80,7 +80,10 @@ public class ShearsItem extends Item {
|
||||
|
||||
return InteractionResult.SUCCESS;
|
||||
} else {
|
||||
- return super.useOn(context);
|
||||
+ // Leaves start - shears wrench
|
||||
+ InteractionResult result = org.leavesmc.leaves.util.ShearsWrenchUtil.tryApplyRotate(context, blockState);
|
||||
+ return result == null ? super.useOn(context) : result;
|
||||
+ // Leaves end - shears wrench
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Sun, 3 Aug 2025 15:19:23 +0800
|
||||
Subject: [PATCH] Leaves: Servux Protocol
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc14e2e0225009cf9919072f7f/leaves-server/minecraft-patches/features/0090-Servux-Protocol.patch)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/ServerTickRateManager.java b/net/minecraft/server/ServerTickRateManager.java
|
||||
index 95f6b1cbd5e33151c326689bc72292ff38a48803..e1974bbebbd10b75ea02955d9ced198d54c8a6f1 100644
|
||||
--- a/net/minecraft/server/ServerTickRateManager.java
|
||||
+++ b/net/minecraft/server/ServerTickRateManager.java
|
||||
@@ -135,4 +135,10 @@ public class ServerTickRateManager extends TickRateManager {
|
||||
player.connection.send(ClientboundTickingStatePacket.from(this));
|
||||
player.connection.send(ClientboundTickingStepPacket.from(this));
|
||||
}
|
||||
+
|
||||
+ // Leaves start - servux
|
||||
+ public long getRemainingSprintTicks() {
|
||||
+ return remainingSprintTicks;
|
||||
+ }
|
||||
+ // Leaves end - servux
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index bf340425dc2a1545b9069badcf054d4c2f6a405f..eb5722848d1c77044807510cd6a46a46c5763509 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2491,6 +2491,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.server.updateEffectiveRespawnData();
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ org.leavesmc.leaves.protocol.servux.ServuxHudDataProtocol.refreshSpawnMetadata = true; // Leaves - servux
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Sun, 16 Nov 2025 17:47:48 +0800
|
||||
Subject: [PATCH] LeavesHooks
|
||||
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
index faf62f8c9453f8e7a21b1e141577f1f4539cd2f9..4e5985a3e4969f466980558190324350019ba8af 100644
|
||||
--- a/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
@@ -29,7 +29,7 @@ import net.minecraft.world.phys.AABB;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
-public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks {
|
||||
+public class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks {
|
||||
|
||||
private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger();
|
||||
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Fri, 15 Aug 2025 02:29:30 +0800
|
||||
Subject: [PATCH] Compatibility fix for Raid Revert and Cross Region Damage
|
||||
Trace
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 5bae274f5ee869e540e4330e03af671b6b18313d..3fe9afe55b4d61db8030479d3d74b8656679cb10 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1240,6 +1240,29 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
}
|
||||
}
|
||||
|
||||
+ // Lophine Start - raid revert adapt Cross Region Damage trace
|
||||
+ public boolean addEffect(MobEffectInstance effectInstance, EntityPotionEffectEvent.Cause cause, boolean fireEvent, boolean async) {
|
||||
+ if (!async || ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this)) {
|
||||
+ return addEffect(effectInstance, this, cause, fireEvent);
|
||||
+ } else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
|
||||
+ postToAddEffect(effectInstance, this, cause, fireEvent);
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private void postToAddEffect(MobEffectInstance effectInstance, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) {
|
||||
+ if (entity != null)
|
||||
+ entity.getBukkitEntity().taskScheduler.schedule((Entity nmsEntity) -> {
|
||||
+ try {
|
||||
+ addEffect(effectInstance, nmsEntity, cause, fireEvent);
|
||||
+ } catch (Throwable ex) {
|
||||
+ LOGGER.error(ex.getMessage(), ex);
|
||||
+ }
|
||||
+ }, null, 1L );
|
||||
+ }
|
||||
+ // Lophine End - raid revert adapt Cross Region Damage trace
|
||||
+
|
||||
public boolean canBeAffected(MobEffectInstance effectInstance) {
|
||||
if (this.getType().is(EntityTypeTags.IMMUNE_TO_INFESTED)) {
|
||||
return !effectInstance.is(MobEffects.INFESTED);
|
||||
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
|
||||
index 2b7894a4104d4cb237746a3e66d4368b6f8f3c1e..03e3290367790add702a5856aaff3be465ea548c 100644
|
||||
--- a/net/minecraft/world/entity/raid/Raider.java
|
||||
+++ b/net/minecraft/world/entity/raid/Raider.java
|
||||
@@ -157,7 +157,7 @@ public abstract class Raider extends PatrollingMonster {
|
||||
net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, i, false, false, true);
|
||||
|
||||
if (serverLevel.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.RAIDS)) {
|
||||
- entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit
|
||||
+ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true, fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled); // Lophine - raid revert adapt Cross Region Damage trace
|
||||
}
|
||||
this.setPatrolLeader(false);
|
||||
}
|
||||
-175
@@ -1,175 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Thu, 20 Feb 2025 01:00:28 +0800
|
||||
Subject: [PATCH] Purpur: Barrels and enderchests 6 rows
|
||||
|
||||
Co-authored by: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
As part of: Purpur (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18f6d99ff389289766ec9d/purpur-server/minecraft-patches/features/0003-Barrels-and-enderchests-6-rows.patch)
|
||||
Licensed under: MIT (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18f6d99ff389289766ec9d/LICENSE)
|
||||
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 2eb551390aa66d89988df9ca23cf0dd7ccfd6577..0d322ef4aa3e70c9edbb9fa8ba368bef916eb93d 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -963,6 +963,10 @@ public abstract class PlayerList {
|
||||
player.getBukkitEntity().recalculatePermissions(); // CraftBukkit
|
||||
this.server.getCommands().sendCommands(player);
|
||||
} // Paper - Add sendOpLevel API
|
||||
+
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ player.enderChestSlotCount = fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows : 27;
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
}
|
||||
|
||||
// Paper start - whitelist verify event / login event
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 0f6e1428cc71c370af45db3e2a4f47c66e5d8628..83612969b6058f444fc17e360cdcc4a8846f79aa 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -179,6 +179,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
private int currentImpulseContextResetGraceTime = 0;
|
||||
public boolean affectsSpawning = true; // Paper - Affects Spawning API
|
||||
public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage
|
||||
+ public int enderChestSlotCount = -1; // Purpur - Barrels and enderchests 6 rows
|
||||
|
||||
// CraftBukkit start
|
||||
public boolean fauxSleeping;
|
||||
diff --git a/net/minecraft/world/inventory/ChestMenu.java b/net/minecraft/world/inventory/ChestMenu.java
|
||||
index 1fb3a34ea872dec73658fac59743e46ef8db5151..41ebe774edfe3c37afecda514a6eb7db978d5aa8 100644
|
||||
--- a/net/minecraft/world/inventory/ChestMenu.java
|
||||
+++ b/net/minecraft/world/inventory/ChestMenu.java
|
||||
@@ -66,10 +66,30 @@ public class ChestMenu extends AbstractContainerMenu {
|
||||
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, 6);
|
||||
}
|
||||
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ public static ChestMenu oneRow(int syncId, Inventory playerInventory, Container inventory) {
|
||||
+ return new ChestMenu(MenuType.GENERIC_9x1, syncId, playerInventory, inventory, 1);
|
||||
+ }
|
||||
+
|
||||
+ public static ChestMenu twoRows(int syncId, Inventory playerInventory, Container inventory) {
|
||||
+ return new ChestMenu(MenuType.GENERIC_9x2, syncId, playerInventory, inventory, 2);
|
||||
+ }
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
+
|
||||
public static ChestMenu threeRows(int containerId, Inventory playerInventory, Container container) {
|
||||
return new ChestMenu(MenuType.GENERIC_9x3, containerId, playerInventory, container, 3);
|
||||
}
|
||||
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ public static ChestMenu fourRows(int syncId, Inventory playerInventory, Container inventory) {
|
||||
+ return new ChestMenu(MenuType.GENERIC_9x4, syncId, playerInventory, inventory, 4);
|
||||
+ }
|
||||
+
|
||||
+ public static ChestMenu fiveRows(int syncId, Inventory playerInventory, Container inventory) {
|
||||
+ return new ChestMenu(MenuType.GENERIC_9x5, syncId, playerInventory, inventory, 5);
|
||||
+ }
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
+
|
||||
public static ChestMenu sixRows(int containerId, Inventory playerInventory, Container container) {
|
||||
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, container, 6);
|
||||
}
|
||||
diff --git a/net/minecraft/world/inventory/PlayerEnderChestContainer.java b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
||||
index 9749909b8253b432bb2f7fba2cd8ff17a8579b30..42df617d7b62af45bd56e9594689974f790f6c19 100644
|
||||
--- a/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
||||
+++ b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
||||
@@ -26,11 +26,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
|
||||
}
|
||||
|
||||
public PlayerEnderChestContainer(Player owner) {
|
||||
- super(27);
|
||||
+ super(fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows : 27);
|
||||
this.owner = owner;
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ @Override
|
||||
+ public int getContainerSize() {
|
||||
+ return owner.enderChestSlotCount < 0 ? super.getContainerSize() : owner.enderChestSlotCount;
|
||||
+ }
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
+
|
||||
public void setActiveChest(EnderChestBlockEntity enderChestBlockEntity) {
|
||||
this.activeChest = enderChestBlockEntity;
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/EnderChestBlock.java b/net/minecraft/world/level/block/EnderChestBlock.java
|
||||
index 383e8285d366c7f594b0b4ff55b367970c9b69e4..202a986762794da9440365953fcb950c6eefa774 100644
|
||||
--- a/net/minecraft/world/level/block/EnderChestBlock.java
|
||||
+++ b/net/minecraft/world/level/block/EnderChestBlock.java
|
||||
@@ -85,8 +85,14 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
|
||||
enderChestInventory.setActiveChest(enderChestBlockEntity); // Needs to happen before ChestMenu.threeRows as it is required for opening animations
|
||||
if (level instanceof ServerLevel serverLevel && player.openMenu(
|
||||
new SimpleMenuProvider(
|
||||
- (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE
|
||||
- )
|
||||
+ (containerId, playerInventory, player1) -> switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows) {
|
||||
+ case 6 -> ChestMenu.sixRows(containerId, playerInventory, enderChestInventory);
|
||||
+ case 5 -> ChestMenu.fiveRows(containerId, playerInventory, enderChestInventory);
|
||||
+ case 4 -> ChestMenu.fourRows(containerId, playerInventory, enderChestInventory);
|
||||
+ case 2 -> ChestMenu.twoRows(containerId, playerInventory, enderChestInventory);
|
||||
+ case 1 -> ChestMenu.oneRow(containerId, playerInventory, enderChestInventory);
|
||||
+ default -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory);
|
||||
+ }, CONTAINER_TITLE) // Purpur - Barrels and enderchests 6 rows
|
||||
).isPresent()) {
|
||||
// Paper end - Fix InventoryOpenEvent cancellation - moved up;
|
||||
player.awardStat(Stats.OPEN_ENDERCHEST);
|
||||
diff --git a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
index dcec63c1c2634a3e83ee3cac26f6e51441c37f6d..e5cfbf41525b0d454bb83691354afb4513723571 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
@@ -59,7 +59,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
// CraftBukkit end
|
||||
private static final Component DEFAULT_NAME = Component.translatable("container.barrel");
|
||||
- private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ private NonNullList<ItemStack> items = NonNullList.withSize(switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
|
||||
+ case 6 -> 54;
|
||||
+ case 5 -> 45;
|
||||
+ case 4 -> 36;
|
||||
+ case 2 -> 18;
|
||||
+ case 1 -> 9;
|
||||
+ default -> 27;
|
||||
+ }, ItemStack.EMPTY);
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
+
|
||||
public final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
|
||||
@Override
|
||||
protected void onOpen(Level level, BlockPos pos, BlockState state) {
|
||||
@@ -111,7 +121,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
|
||||
@Override
|
||||
public int getContainerSize() {
|
||||
- return 27;
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ return switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
|
||||
+ case 6 -> 54;
|
||||
+ case 5 -> 45;
|
||||
+ case 4 -> 36;
|
||||
+ case 2 -> 18;
|
||||
+ case 1 -> 9;
|
||||
+ default -> 27;
|
||||
+ };
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -132,7 +151,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
|
||||
@Override
|
||||
protected AbstractContainerMenu createMenu(int id, Inventory player) {
|
||||
- return ChestMenu.threeRows(id, player, this);
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ return switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
|
||||
+ case 6 -> ChestMenu.sixRows(id, player, this);
|
||||
+ case 5 -> ChestMenu.fiveRows(id, player, this);
|
||||
+ case 4 -> ChestMenu.fourRows(id, player, this);
|
||||
+ case 2 -> ChestMenu.twoRows(id, player, this);
|
||||
+ case 1 -> ChestMenu.oneRow(id, player, this);
|
||||
+ default -> ChestMenu.threeRows(id, player, this);
|
||||
+ };
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Thu, 12 Jun 2025 04:44:24 +0800
|
||||
Subject: [PATCH] I18n support
|
||||
|
||||
|
||||
diff --git a/net/minecraft/locale/Language.java b/net/minecraft/locale/Language.java
|
||||
index 7b9e2a1a208b46a69c16e6afd8b502259893574f..c300ae4363298fecef8fa9bf739f01c0a11e145f 100644
|
||||
--- a/net/minecraft/locale/Language.java
|
||||
+++ b/net/minecraft/locale/Language.java
|
||||
@@ -36,6 +36,7 @@ public abstract class Language {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
BiConsumer<String, String> biConsumer = map::put;
|
||||
parseTranslations(biConsumer, "/assets/minecraft/lang/en_us.json");
|
||||
+ fun.bm.lophine.utils.ServerI18nUtil.loadLophineI18nDefault(biConsumer);
|
||||
deprecatedTranslationsInfo.applyToMap(map);
|
||||
final Map<String, String> map1 = Map.copyOf(map);
|
||||
return new Language() {
|
||||
@@ -65,7 +66,7 @@ public abstract class Language {
|
||||
};
|
||||
}
|
||||
|
||||
- private static void parseTranslations(BiConsumer<String, String> output, String languagePath) {
|
||||
+ public static void parseTranslations(BiConsumer<String, String> output, String languagePath) { // Lophine - private -> public
|
||||
try (InputStream resourceAsStream = Language.class.getResourceAsStream(languagePath)) {
|
||||
loadFromJson(resourceAsStream, output);
|
||||
} catch (JsonParseException | IOException var7) {
|
||||
diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
|
||||
index f41c70c6cb2e9fae43bad9dd66546417fe38f14a..0bb0877011cac3184b881bfa35f10ef83d7341de 100644
|
||||
--- a/net/minecraft/server/Main.java
|
||||
+++ b/net/minecraft/server/Main.java
|
||||
@@ -151,6 +151,8 @@ public class Main {
|
||||
return;
|
||||
}
|
||||
|
||||
+ fun.bm.lophine.utils.ServerI18nUtil.preInit(); // Lophine - I18n support
|
||||
+
|
||||
// Paper start - Detect headless JRE
|
||||
String awtException = io.papermc.paper.util.ServerEnvironment.awtDependencyCheck();
|
||||
if (awtException != null) {
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 4abfcaae4fe024296961987704e2a11a03ee518b..5fbcb5eac1d5449247da77b6120edbe2f2dd1d58 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -262,6 +262,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
||||
// Paper end - initialize global and world-defaults configuration
|
||||
me.earthme.luminol.config.ConfigManager.loadConfigFiles(); // Luminol - load config file
|
||||
+ fun.bm.lophine.utils.ServerI18nUtil.init(); // Lophine - I18n support
|
||||
if (false) this.server.spark.enableEarlyIfRequested(); // Paper - spark // Luminol - Force disable builtin spark
|
||||
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
|
||||
if (this.convertOldUsers()) {
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 19 May 2025 00:42:17 +0800
|
||||
Subject: [PATCH] Old zombie reinforcement
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/zombie/Zombie.java b/net/minecraft/world/entity/monster/zombie/Zombie.java
|
||||
index 7a9394d4555464312418964f1a7a5d2581496774..3fcd32cc77458ce196ce0e468c1a99f456a57604 100644
|
||||
--- a/net/minecraft/world/entity/monster/zombie/Zombie.java
|
||||
+++ b/net/minecraft/world/entity/monster/zombie/Zombie.java
|
||||
@@ -314,7 +314,7 @@ public class Zombie extends Monster {
|
||||
int floor = Mth.floor(this.getX());
|
||||
int floor1 = Mth.floor(this.getY());
|
||||
int floor2 = Mth.floor(this.getZ());
|
||||
- EntityType<? extends Zombie> type = this.getType();
|
||||
+ EntityType<? extends Zombie> type = fun.bm.lophine.config.modules.function.OldFeatureConfig.oldZombieReinforcement ? EntityType.ZOMBIE : this.getType(); // Lophine - old zombie reinforcement
|
||||
Zombie zombie = type.create(level, EntitySpawnReason.REINFORCEMENT);
|
||||
if (zombie == null) {
|
||||
return true;
|
||||
@@ -1,40 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 19 May 2025 00:06:03 +0800
|
||||
Subject: [PATCH] Spawn invulnerable time
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index dcdb01fe5333d407a10f9872d09992c7b438ddeb..6df8f98afa7810815b8d7c86b3dac57cd5915682 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -240,6 +240,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
private int lastSentFood = -99999999;
|
||||
private boolean lastFoodSaturationZero = true;
|
||||
public int lastSentExp = -99999999;
|
||||
+ protected int spawnInvulnerableTime = 60; // Lophine - spawn invulnerable time
|
||||
private ChatVisiblity chatVisibility = ChatVisiblity.FULL;
|
||||
public ParticleStatus particleStatus = ParticleStatus.ALL;
|
||||
private boolean canChatColor = true;
|
||||
@@ -898,6 +899,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
this.connection.tickClientLoadTimeout();
|
||||
this.gameMode.tick();
|
||||
this.wardenSpawnTracker.tick();
|
||||
+ if (this.spawnInvulnerableTime > 0) --this.spawnInvulnerableTime; // Lophine - spawn invulnerable time
|
||||
if (this.invulnerableTime > 0) {
|
||||
this.invulnerableTime--;
|
||||
}
|
||||
@@ -1536,6 +1538,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
if (this.isInvulnerableTo(level, damageSource)) {
|
||||
return false;
|
||||
} else {
|
||||
+ // Lophine start - spawn invulnerable time
|
||||
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.spawnInvulnerableTime) {
|
||||
+ if (this.spawnInvulnerableTime > 0 && !damageSource.is(net.minecraft.tags.DamageTypeTags.BYPASSES_INVULNERABILITY)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Lophine end - spawn invulnerable time
|
||||
Entity entity = damageSource.getEntity();
|
||||
if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false.
|
||||
!(entity instanceof Player player && !this.canHarmPlayer(player))
|
||||
@@ -1,773 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bacteriawa <A3167717663@hotmail.com>
|
||||
Date: Sat, 30 Aug 2025 17:16:32 +0800
|
||||
Subject: [PATCH] Leaves: Fakeplayer
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/advancements/criterion/SimpleCriterionTrigger.java b/net/minecraft/advancements/criterion/SimpleCriterionTrigger.java
|
||||
index 368a9d33f93c2e85abe4cf10df5a85c09fb03dd6..2b78040daeb3b09c08494cbc1d4a9d36080895f9 100644
|
||||
--- a/net/minecraft/advancements/criterion/SimpleCriterionTrigger.java
|
||||
+++ b/net/minecraft/advancements/criterion/SimpleCriterionTrigger.java
|
||||
@@ -39,6 +39,7 @@ public abstract class SimpleCriterionTrigger<T extends SimpleCriterionTrigger.Si
|
||||
}
|
||||
|
||||
protected void trigger(ServerPlayer player, Predicate<T> testTrigger) {
|
||||
+ if (player instanceof org.leavesmc.leaves.bot.ServerBot) return; // Leaves - bot skip
|
||||
PlayerAdvancements advancements = player.getAdvancements();
|
||||
Set<CriterionTrigger.Listener<T>> set = (Set) advancements.criterionData.get(this); // Paper - fix PlayerAdvancements leak
|
||||
if (set != null && !set.isEmpty()) {
|
||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||
index 9f444988d40208a1bfa9f147ef80489f81115e93..ab2fa0b86564622501238305714fff014e2b2a56 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -74,7 +74,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
public boolean preparing = true;
|
||||
// Spigot end
|
||||
private volatile @Nullable PacketListener disconnectListener;
|
||||
- private volatile @Nullable PacketListener packetListener;
|
||||
+ public volatile @Nullable PacketListener packetListener; // Leaves - private -> protected // Lophine protected -> public
|
||||
private @Nullable DisconnectionDetails disconnectionDetails;
|
||||
private boolean encrypted;
|
||||
private final java.util.concurrent.atomic.AtomicBoolean disconnectionHandled = new java.util.concurrent.atomic.AtomicBoolean(false); // Folia - region threading - may be called concurrently during configuration stage
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index d5b680fc6e13ec26d0db2448009e4cbe59933e22..385c71d70ed9e5a3ae25fbecaefd6773c467d31d 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -425,6 +425,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
// Folia end - regionised ticking
|
||||
|
||||
+ private org.leavesmc.leaves.bot.BotList botList; // Leaves - fakeplayer
|
||||
+
|
||||
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
|
||||
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
|
||||
AtomicReference<S> atomicReference = new AtomicReference<>();
|
||||
@@ -1050,6 +1052,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Folia end - region threading
|
||||
|
||||
public void stopServer() {
|
||||
+ // Leaves end - save or remove bot
|
||||
+ if (!this.getBotList().forceShutdown && !this.getBotList().removeAll()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - save or remove bot
|
||||
// Folia start - region threading
|
||||
// halt scheduler
|
||||
// don't wait, we may be on a scheduler thread
|
||||
@@ -1668,7 +1675,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
int i = this.pauseWhenEmptySeconds() * 20;
|
||||
this.removeDisabledPluginsBlockingSleep(); // Paper - API to allow/disallow tick sleeping
|
||||
if (false && i > 0) { // Folia - region threading - this is complicated to implement, and even if done correctly is messy
|
||||
- if (this.playerList.getPlayerCount() == 0 && !this.tickRateManager.isSprinting() && this.pluginsBlockingSleep.isEmpty()) { // Paper - API to allow/disallow tick sleeping
|
||||
+ if (this.playerList.getPlayerCount() == 0 && this.botList.bots.isEmpty() && !this.tickRateManager.isSprinting() && this.pluginsBlockingSleep.isEmpty()) { // Paper - API to allow/disallow tick sleeping // Leaves - fakeplayer
|
||||
this.emptyTicks++;
|
||||
} else {
|
||||
this.emptyTicks = 0;
|
||||
@@ -1801,6 +1808,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.isSaving = true;
|
||||
if (playerSaveInterval > 0) {
|
||||
this.playerList.saveAll(playerSaveInterval);
|
||||
+ org.leavesmc.leaves.bot.BotList.INSTANCE.saveAllResumeBots(playerSaveInterval); // Leaves - resident fakeplayer
|
||||
}
|
||||
for (final ServerLevel level : (region == null ? this.getAllLevels() : Arrays.asList(region.world))) { // Folia - region threading
|
||||
if (level.paperConfig().chunks.autoSaveInterval.value() > 0) {
|
||||
@@ -2027,6 +2035,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
public void tickConnection() {
|
||||
this.getConnection().tick();
|
||||
+ this.botList.networkTick(); // Leaves - fakeplayer
|
||||
}
|
||||
|
||||
private void synchronizeTime(ServerLevel level) {
|
||||
@@ -3161,6 +3170,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return this.debugSubscribers;
|
||||
}
|
||||
|
||||
+ // Leaves start - fakeplayer
|
||||
+ protected void setBotList(org.leavesmc.leaves.bot.BotList botList) {
|
||||
+ this.botList = botList;
|
||||
+ }
|
||||
+
|
||||
+ public org.leavesmc.leaves.bot.BotList getBotList() {
|
||||
+ return botList;
|
||||
+ }
|
||||
+ // Leaves end - fakeplayer
|
||||
+
|
||||
public record ReloadableResources(CloseableResourceManager resourceManager, ReloadableServerResources managers) implements AutoCloseable {
|
||||
@Override
|
||||
public void close() {
|
||||
diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java
|
||||
index c9e6cd428e4c74b14a992de9ffe85a5a707c4e6b..5bf7eb5b906cefa57a1dfcf828ff7872dbceac4f 100644
|
||||
--- a/net/minecraft/server/PlayerAdvancements.java
|
||||
+++ b/net/minecraft/server/PlayerAdvancements.java
|
||||
@@ -166,6 +166,11 @@ public class PlayerAdvancements {
|
||||
}
|
||||
|
||||
public boolean award(AdvancementHolder advancement, String criterionKey) {
|
||||
+ // Leaves start - bot can't get advancement
|
||||
+ if (player instanceof org.leavesmc.leaves.bot.ServerBot) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Leaves end - bot can't get advancement
|
||||
boolean flag = false;
|
||||
AdvancementProgress orStartProgress = this.getOrStartProgress(advancement);
|
||||
boolean isDone = orStartProgress.isDone();
|
||||
diff --git a/net/minecraft/server/commands/BanIpCommands.java b/net/minecraft/server/commands/BanIpCommands.java
|
||||
index d92492bca62fb02fe7a9e4e220cb8651c4d1e16d..7d0752f9a6a90cf389a9cb5829ab02606266f204 100644
|
||||
--- a/net/minecraft/server/commands/BanIpCommands.java
|
||||
+++ b/net/minecraft/server/commands/BanIpCommands.java
|
||||
@@ -44,6 +44,12 @@ public class BanIpCommands {
|
||||
return banIp(source, username, reason);
|
||||
} else {
|
||||
ServerPlayer playerByName = source.getServer().getPlayerList().getPlayerByName(username);
|
||||
+ // Leaves start - disable ban
|
||||
+ if (playerByName instanceof org.leavesmc.leaves.bot.ServerBot) {
|
||||
+ source.sendFailure(Component.literal("Permission denied"));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ // Leaves end - disable ban
|
||||
if (playerByName != null) {
|
||||
return banIp(source, playerByName.getIpAddress(), reason);
|
||||
} else {
|
||||
diff --git a/net/minecraft/server/commands/BanPlayerCommands.java b/net/minecraft/server/commands/BanPlayerCommands.java
|
||||
index 978ef2e996a78e907f959bfe99d47de832427011..9644e68ba2c295fcda2d4a3034277520ade91bca 100644
|
||||
--- a/net/minecraft/server/commands/BanPlayerCommands.java
|
||||
+++ b/net/minecraft/server/commands/BanPlayerCommands.java
|
||||
@@ -45,7 +45,15 @@ public class BanPlayerCommands {
|
||||
UserBanList bans = source.getServer().getPlayerList().getBans();
|
||||
int i = 0;
|
||||
|
||||
+ boolean hasBot = false; // Leaves - disable kick
|
||||
for (NameAndId nameAndId : players) {
|
||||
+ // Leaves start - disable ban
|
||||
+ if (nameAndId.isBot()) {
|
||||
+ source.sendFailure(Component.literal("Permission denied"));
|
||||
+ hasBot = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Leaves end - disable ban
|
||||
if (!bans.isBanned(nameAndId)) {
|
||||
UserBanListEntry userBanListEntry = new UserBanListEntry(
|
||||
nameAndId, null, source.getTextName(), null, reason == null ? null : reason.getString()
|
||||
@@ -63,7 +71,13 @@ public class BanPlayerCommands {
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
- throw ERROR_ALREADY_BANNED.create();
|
||||
+ // Leaves start - disable kick
|
||||
+ if (hasBot) {
|
||||
+ return i;
|
||||
+ } else {
|
||||
+ throw ERROR_ALREADY_BANNED.create();
|
||||
+ }
|
||||
+ // Leaves end - disable kick
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
diff --git a/net/minecraft/server/commands/KickCommand.java b/net/minecraft/server/commands/KickCommand.java
|
||||
index 5f78d629bab84acb2fa43a9fcc1cec52b4e91ae3..1c6059bd23afdd555d2dc8c533a5b027957c7b3a 100644
|
||||
--- a/net/minecraft/server/commands/KickCommand.java
|
||||
+++ b/net/minecraft/server/commands/KickCommand.java
|
||||
@@ -46,9 +46,17 @@ public class KickCommand {
|
||||
if (!source.getServer().isPublished()) {
|
||||
throw ERROR_SINGLEPLAYER.create();
|
||||
} else {
|
||||
+ boolean hasBot = false; // Leaves - disable kick
|
||||
int i = 0;
|
||||
|
||||
for (ServerPlayer serverPlayer : players) {
|
||||
+ // Leaves start - disable kick
|
||||
+ if (serverPlayer instanceof org.leavesmc.leaves.bot.ServerBot) {
|
||||
+ source.sendFailure(Component.literal("Permission denied"));
|
||||
+ hasBot = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Leaves end - disable kick
|
||||
if (!source.getServer().isSingleplayerOwner(serverPlayer.nameAndId())) {
|
||||
serverPlayer.connection.disconnect(reason, org.bukkit.event.player.PlayerKickEvent.Cause.KICK_COMMAND); // Paper - kick event cause
|
||||
source.sendSuccess(() -> Component.translatable("commands.kick.success", serverPlayer.getDisplayName(), reason), true);
|
||||
@@ -57,7 +65,13 @@ public class KickCommand {
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
- throw ERROR_KICKING_OWNER.create();
|
||||
+ // Leaves start - disable kick
|
||||
+ if (hasBot) {
|
||||
+ return i;
|
||||
+ } else {
|
||||
+ throw ERROR_KICKING_OWNER.create();
|
||||
+ }
|
||||
+ // Leaves end - disable kick
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
diff --git a/net/minecraft/server/commands/OpCommand.java b/net/minecraft/server/commands/OpCommand.java
|
||||
index 07332a86e6e0441bafacb020f27ec36a277f1486..590891d70a71ab30ceae3a3cf1923745e7c20b26 100644
|
||||
--- a/net/minecraft/server/commands/OpCommand.java
|
||||
+++ b/net/minecraft/server/commands/OpCommand.java
|
||||
@@ -43,6 +43,7 @@ public class OpCommand {
|
||||
int i = 0;
|
||||
|
||||
for (NameAndId nameAndId : players) {
|
||||
+ if (nameAndId.isBot()) continue; // Leaves - disable op
|
||||
if (!playerList.isOp(nameAndId)) {
|
||||
playerList.op(nameAndId);
|
||||
i++;
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 5fbcb5eac1d5449247da77b6120edbe2f2dd1d58..69cc67b7618d38e65ccb1f4c58013ef116886ad2 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -252,6 +252,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
|
||||
// Spigot start
|
||||
+ this.setBotList(new org.leavesmc.leaves.bot.BotList(this)); // Leaves - fakeplayer
|
||||
this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage));
|
||||
org.spigotmc.SpigotConfig.init((java.io.File) this.options.valueOf("spigot-settings"));
|
||||
org.spigotmc.SpigotConfig.registerCommands();
|
||||
@@ -263,6 +264,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
// Paper end - initialize global and world-defaults configuration
|
||||
me.earthme.luminol.config.ConfigManager.loadConfigFiles(); // Luminol - load config file
|
||||
fun.bm.lophine.utils.ServerI18nUtil.init(); // Lophine - I18n support
|
||||
+ this.getBotList().loadResumeBotInfo(); // Leaves - load resident bot info
|
||||
if (false) this.server.spark.enableEarlyIfRequested(); // Paper - spark // Luminol - Force disable builtin spark
|
||||
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
|
||||
if (this.convertOldUsers()) {
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index fdccb06c918d387e46c29ede7337159db8c5d9ca..4cd5c5659ac098c3b7ff95efb94b1987e2dd40d0 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1386,6 +1386,13 @@ public class ChunkMap extends SimpleRegionStorage implements ChunkHolder.PlayerP
|
||||
}
|
||||
} else {
|
||||
this.removePlayer(player);
|
||||
+ // Leaves start - render bot
|
||||
+ if (entity instanceof org.leavesmc.leaves.bot.ServerBot bot) {
|
||||
+ if (bot.needSendFakeData(player)) {
|
||||
+ bot.sendFakeData(player.connection, false);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - render bot
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index eb5722848d1c77044807510cd6a46a46c5763509..88efbe2bcb5621432b67366116150a3dab52e510 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -220,6 +220,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
public final boolean tickTime; // Folia - region threading
|
||||
private final RandomSequences randomSequences;
|
||||
final LevelDebugSynchronizers debugSynchronizers = new LevelDebugSynchronizers(this);
|
||||
+ final List<ServerPlayer> realPlayers; // Leaves - skip
|
||||
|
||||
// CraftBukkit start
|
||||
public final LevelStorageSource.LevelStorageAccess levelStorageAccess;
|
||||
@@ -669,6 +670,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Paper end - rewrite chunk system
|
||||
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
this.updateTickData(); // Folia - region threading - make sure it is initialised before ticked
|
||||
+ this.realPlayers = Lists.newArrayList(); // Leaves - skip
|
||||
}
|
||||
|
||||
// Folia start - region threading
|
||||
@@ -2518,6 +2520,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
return this.players;
|
||||
}
|
||||
|
||||
+ // Leaves start - fakeplayer skip
|
||||
+ public List<ServerPlayer> realPlayers() {
|
||||
+ return this.realPlayers;
|
||||
+ }
|
||||
+ // Leaves end - fakeplayer skip
|
||||
+
|
||||
@Override
|
||||
public void updatePOIOnBlockStateChange(BlockPos pos, BlockState oldState, BlockState newState) {
|
||||
Optional<Holder<PoiType>> optional = PoiTypes.forState(oldState);
|
||||
@@ -2991,6 +2999,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.add(serverPlayer);
|
||||
+ // Leaves start - skip
|
||||
+ if (!(serverPlayer instanceof org.leavesmc.leaves.bot.ServerBot)) {
|
||||
+ ServerLevel.this.realPlayers.add(serverPlayer);
|
||||
+ }
|
||||
+ // Leaves end - skip
|
||||
if (serverPlayer.isReceivingWaypoints()) {
|
||||
ServerLevel.this.getWaypointManager().addPlayer(serverPlayer);
|
||||
}
|
||||
@@ -3072,6 +3085,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
ServerLevel.this.getChunkSource().removeEntity(entity);
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.remove(serverPlayer);
|
||||
+ // Leaves start - skip
|
||||
+ if (!(serverPlayer instanceof org.leavesmc.leaves.bot.ServerBot)) {
|
||||
+ ServerLevel.this.realPlayers.remove(serverPlayer);
|
||||
+ }
|
||||
+ // Leaves end - skip
|
||||
ServerLevel.this.getWaypointManager().removePlayer(serverPlayer);
|
||||
ServerLevel.this.updateSleepingPlayerList();
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 6df8f98afa7810815b8d7c86b3dac57cd5915682..7c2d53ca863c2e50c6871938efc426ddefff9b5c 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -227,7 +227,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
private static final boolean DEFAULT_SPAWN_EXTRA_PARTICLES_ON_FALL = false;
|
||||
public ServerGamePacketListenerImpl connection;
|
||||
private final MinecraftServer server;
|
||||
- public final ServerPlayerGameMode gameMode;
|
||||
+ public ServerPlayerGameMode gameMode; // Leaves - not final
|
||||
private final PlayerAdvancements advancements;
|
||||
private final ServerStatsCounter stats;
|
||||
private float lastRecordedHealthAndAbsorption = Float.MIN_VALUE;
|
||||
@@ -248,7 +248,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
private @Nullable Entity camera;
|
||||
public boolean isChangingDimension;
|
||||
public boolean seenCredits = false;
|
||||
- private final ServerRecipeBook recipeBook;
|
||||
+ protected ServerRecipeBook recipeBook; // Leaves - not final and private -> protected
|
||||
private @Nullable Vec3 levitationStartPos;
|
||||
private int levitationStartTime;
|
||||
private boolean disconnected;
|
||||
@@ -1495,7 +1495,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
}
|
||||
// Luminol End - Cross Region Damage trace
|
||||
|
||||
- private void tellNeutralMobsThatIDied() {
|
||||
+ protected void tellNeutralMobsThatIDied() { // Leaves private -> protected
|
||||
AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0);
|
||||
this.level()
|
||||
.getEntitiesOfClass(Mob.class, aabb, EntitySelector.NO_SPECTATORS)
|
||||
@@ -2132,6 +2132,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
this.teleportSpectators(teleportTransition, serverLevel);
|
||||
+ // Leaves start - bot support
|
||||
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
|
||||
+ this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(this, true)); // Leaves - render bot
|
||||
+ }
|
||||
+ // Leaves end - bot support
|
||||
// CraftBukkit start
|
||||
org.bukkit.event.player.PlayerChangedWorldEvent changeEvent = new org.bukkit.event.player.PlayerChangedWorldEvent(this.getBukkitEntity(), serverLevel.getWorld());
|
||||
this.level().getCraftServer().getPluginManager().callEvent(changeEvent);
|
||||
diff --git a/net/minecraft/server/players/CachedUserNameToIdResolver.java b/net/minecraft/server/players/CachedUserNameToIdResolver.java
|
||||
index 345bdb0ff82b8cd8c63e5ff1f2dabb68a1e54b77..c9a7c1c37155e0d339b880179a5988c9a6cb3797 100644
|
||||
--- a/net/minecraft/server/players/CachedUserNameToIdResolver.java
|
||||
+++ b/net/minecraft/server/players/CachedUserNameToIdResolver.java
|
||||
@@ -122,6 +122,12 @@ public class CachedUserNameToIdResolver implements UserNameToIdResolver {
|
||||
|
||||
@Override
|
||||
public Optional<NameAndId> get(String name) {
|
||||
+ // Leaves start - fix bot
|
||||
+ org.leavesmc.leaves.bot.ServerBot bot = org.leavesmc.leaves.bot.BotList.INSTANCE.getBotByName(name);
|
||||
+ if (bot != null) {
|
||||
+ return Optional.of(bot.nameAndId());
|
||||
+ }
|
||||
+ // Leaves end - fix bot
|
||||
String string = name.toLowerCase(Locale.ROOT);
|
||||
boolean stateLocked = true; try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
|
||||
CachedUserNameToIdResolver.GameProfileInfo gameProfileInfo = this.profilesByName.get(string);
|
||||
diff --git a/net/minecraft/server/players/NameAndId.java b/net/minecraft/server/players/NameAndId.java
|
||||
index 05b4a75f6597e8613c91344d100bb7f005d169a7..9a5006362c12e972d031c48be4d30362d88d1c00 100644
|
||||
--- a/net/minecraft/server/players/NameAndId.java
|
||||
+++ b/net/minecraft/server/players/NameAndId.java
|
||||
@@ -8,18 +8,22 @@ import java.util.UUID;
|
||||
import net.minecraft.core.UUIDUtil;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
-public record NameAndId(UUID id, String name) {
|
||||
+public record NameAndId(UUID id, String name, boolean isBot) { // Leaves - fakeplayer
|
||||
public static final Codec<NameAndId> CODEC = RecordCodecBuilder.create(
|
||||
instance -> instance.group(UUIDUtil.STRING_CODEC.fieldOf("id").forGetter(NameAndId::id), Codec.STRING.fieldOf("name").forGetter(NameAndId::name))
|
||||
.apply(instance, NameAndId::new)
|
||||
);
|
||||
|
||||
public NameAndId(GameProfile profile) {
|
||||
- this(profile.id(), profile.name());
|
||||
+ this(profile.id(), profile.name(), com.google.common.collect.Iterables.getFirst(profile.properties().get("is_bot"), "false").equals("true")); // Leaves - fakeplayer
|
||||
}
|
||||
|
||||
public NameAndId(com.mojang.authlib.yggdrasil.response.NameAndId nameAndId) {
|
||||
- this(nameAndId.id(), nameAndId.name());
|
||||
+ this(nameAndId.id(), nameAndId.name(), false); // Leaves - fakeplayer
|
||||
+ }
|
||||
+
|
||||
+ public NameAndId(UUID uuid, String name) {
|
||||
+ this(uuid, name, false); // Leaves - fakeplayer
|
||||
}
|
||||
|
||||
public static @Nullable NameAndId fromJson(JsonObject json) {
|
||||
@@ -33,7 +37,7 @@ public record NameAndId(UUID id, String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
- return new NameAndId(uuid, json.get("name").getAsString());
|
||||
+ return new NameAndId(uuid, json.get("name").getAsString(), false); // Leaves - fakeplayer
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -46,7 +50,7 @@ public record NameAndId(UUID id, String name) {
|
||||
|
||||
public static NameAndId createOffline(String name) {
|
||||
UUID uuid = UUIDUtil.createOfflinePlayerUUID(name);
|
||||
- return new NameAndId(uuid, name);
|
||||
+ return new NameAndId(uuid, name, false); // Leaves - fakeplayer
|
||||
}
|
||||
|
||||
// Paper start - utility method for common conversion back to the game profile
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 0d322ef4aa3e70c9edbb9fa8ba368bef916eb93d..3a5319739f0687fc6f09b2ac8ee31716593fe0de 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -317,6 +317,19 @@ public abstract class PlayerList {
|
||||
|
||||
org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player);
|
||||
|
||||
+ // Leaves start - bot support
|
||||
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
|
||||
+ org.leavesmc.leaves.bot.ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName());
|
||||
+ if (bot != null) {
|
||||
+ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false, false);
|
||||
+ }
|
||||
+ this.server.getBotList().bots.forEach(bot1 -> {
|
||||
+ bot1.sendPlayerInfo(player);
|
||||
+ bot1.sendFakeDataIfNeed(player, true);
|
||||
+ }); // Leaves - render bot
|
||||
+ }
|
||||
+ // Leaves end - bot support
|
||||
+
|
||||
final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
|
||||
|
||||
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
|
||||
@@ -791,6 +804,12 @@ public abstract class PlayerList {
|
||||
).callEvent();
|
||||
// Paper end
|
||||
|
||||
+ // Leaves start - bot support
|
||||
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
|
||||
+ this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(serverPlayer, true)); // Leaves - render bot
|
||||
+ }
|
||||
+ // Leaves end - bot support
|
||||
+
|
||||
return serverPlayer;
|
||||
}
|
||||
|
||||
@@ -892,11 +911,16 @@ public abstract class PlayerList {
|
||||
|
||||
public String[] getPlayerNamesArray() {
|
||||
List<ServerPlayer> players = new java.util.ArrayList<>(this.players); // Folia - region threading
|
||||
- String[] strings = new String[this.players.size()];
|
||||
+ String[] strings = new String[this.players.size() + this.server.getBotList().bots.size()]; // Leaves - fakeplayer support
|
||||
|
||||
for (int i = 0; i < players.size(); i++) { // Folia - region threading
|
||||
strings[i] = players.get(i).getGameProfile().name(); // Folia - region threading
|
||||
}
|
||||
+ // Leaves start - fakeplayer support
|
||||
+ for (int i = this.players.size(); i < strings.length; ++i) {
|
||||
+ strings[i] = this.server.getBotList().bots.get(i - this.players.size()).getGameProfile().name();
|
||||
+ }
|
||||
+ // Leaves end - fakeplayer support
|
||||
|
||||
return strings;
|
||||
}
|
||||
@@ -1016,7 +1040,14 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public @Nullable ServerPlayer getPlayerByName(String username) {
|
||||
- return this.playersByName.get(username.toLowerCase(java.util.Locale.ROOT)); // Spigot
|
||||
+ // Leaves start - fakeplayer support
|
||||
+ username = username.toLowerCase(java.util.Locale.ROOT);
|
||||
+ ServerPlayer player = this.playersByName.get(username);
|
||||
+ if (player == null) {
|
||||
+ player = this.server.getBotList().getBotByName(username);
|
||||
+ }
|
||||
+ return player; // Spigot
|
||||
+ // Leaves end - fakeplayer support
|
||||
}
|
||||
|
||||
public void broadcast(@Nullable Player except, double x, double y, double z, double radius, ResourceKey<Level> dimension, Packet<?> packet) {
|
||||
@@ -1353,7 +1384,13 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public @Nullable ServerPlayer getPlayer(UUID playerUUID) {
|
||||
- return this.playersByUUID.get(playerUUID);
|
||||
+ // Leaves start - fakeplayer support
|
||||
+ ServerPlayer player = this.playersByUUID.get(playerUUID);
|
||||
+ if (player == null) {
|
||||
+ player = this.server.getBotList().getBot(playerUUID);
|
||||
+ }
|
||||
+ return player;
|
||||
+ // Leaves start - fakeplayer support
|
||||
}
|
||||
|
||||
public @Nullable ServerPlayer getPlayer(String name) {
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 22e68cabb4554c3e21e6f4ef316186f60ec77511..5ac53fcdca5fa6aae0452840e78d67653ceececb 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -1235,7 +1235,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
|
||||
BlockPos onPosLegacy = this.getOnPosLegacy();
|
||||
BlockState blockState = this.level().getBlockState(onPosLegacy);
|
||||
- if (this.isLocalInstanceAuthoritative()) {
|
||||
+ if (this.isLocalInstanceAuthoritative() || this instanceof org.leavesmc.leaves.bot.ServerBot) { // Leaves - ServerBot needs check fall damage
|
||||
this.checkFallDamage(vec3.y, this.onGround(), blockState, onPosLegacy);
|
||||
}
|
||||
|
||||
@@ -1570,7 +1570,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
}
|
||||
|
||||
// Paper start - optimise collisions
|
||||
- private Vec3 collide(Vec3 movement) {
|
||||
+ public Vec3 collide(Vec3 movement) { // Leaves - private -> public
|
||||
final boolean xZero = movement.x == 0.0;
|
||||
final boolean yZero = movement.y == 0.0;
|
||||
final boolean zZero = movement.z == 0.0;
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 3fe9afe55b4d61db8030479d3d74b8656679cb10..c0ebd700caa950948c58846eaf164afc14f87f09 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3319,7 +3319,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
private void travelRidden(Player player, Vec3 travelVector) {
|
||||
Vec3 riddenInput = this.getRiddenInput(player, travelVector);
|
||||
this.tickRidden(player, riddenInput);
|
||||
- if (this.canSimulateMovement()) {
|
||||
+ if (this.canSimulateMovement() || this.getControllingPassenger() instanceof org.leavesmc.leaves.bot.ServerBot) { // Leaves - Fakeplayer
|
||||
this.setSpeed(this.getRiddenSpeed(player));
|
||||
this.travel(riddenInput);
|
||||
} else {
|
||||
@@ -4228,7 +4228,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
// Paper start - lag compensate eating
|
||||
// we add 1 to the expected time to avoid lag compensating when we should not
|
||||
final boolean shouldLagCompensate = this.useItem.has(DataComponents.FOOD) && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1L + this.totalEatTimeTicks) * 50L * (1000L * 1000L));
|
||||
- if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !this.level().isClientSide() && !usingItem.useOnRelease()) {
|
||||
+ if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !(this instanceof org.leavesmc.leaves.bot.ServerBot) && !this.level().isClientSide() && !usingItem.useOnRelease()) {
|
||||
this.useItemRemaining = 0;
|
||||
// Paper end - lag compensate eating
|
||||
this.completeUsingItem();
|
||||
@@ -4413,6 +4413,23 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
this.stopUsingItem();
|
||||
}
|
||||
|
||||
+ // Leaves start - Fakeplayer
|
||||
+ public boolean releaseUsingItemWithResult() {
|
||||
+ ItemStack itemInHand = this.getItemInHand(this.getUsedItemHand());
|
||||
+ boolean result = false;
|
||||
+ if (!this.useItem.isEmpty() && ItemStack.isSameItem(itemInHand, this.useItem)) {
|
||||
+ this.useItem = itemInHand;
|
||||
+ result = this.useItem.releaseUsingWithResult(this.level(), this, this.getUseItemRemainingTicks());
|
||||
+ if (this.useItem.useOnRelease()) {
|
||||
+ this.updatingUsingItem();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ this.stopUsingItem();
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Leaves end - Fakeplayer
|
||||
+
|
||||
public void stopUsingItem() {
|
||||
if (!this.level().isClientSide()) {
|
||||
boolean isUsingItem = this.isUsingItem();
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 83612969b6058f444fc17e360cdcc4a8846f79aa..29ca31b05ec5636243b13fee8b3399d5e21808b4 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -168,7 +168,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
private int lastLevelUpTime;
|
||||
public GameProfile gameProfile;
|
||||
private boolean reducedDebugInfo;
|
||||
- private ItemStack lastItemInMainHand = ItemStack.EMPTY;
|
||||
+ protected ItemStack lastItemInMainHand = ItemStack.EMPTY;
|
||||
private final ItemCooldowns cooldowns = this.createItemCooldowns();
|
||||
private Optional<GlobalPos> lastDeathLocation = Optional.empty();
|
||||
public @Nullable FishingHook fishing;
|
||||
@@ -349,6 +349,12 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - fakeplayer
|
||||
+ protected void livingEntityTick() {
|
||||
+ super.tick();
|
||||
+ }
|
||||
+ // Leaves end - fakeplayer
|
||||
+
|
||||
@Override
|
||||
protected float getMaxHeadRotationRelativeToBody() {
|
||||
return this.isBlocking() ? 15.0F : super.getMaxHeadRotationRelativeToBody();
|
||||
@@ -574,7 +580,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
public void removeEntitiesOnShoulder() {
|
||||
}
|
||||
|
||||
- private void touch(Entity entity) {
|
||||
+ public void touch(Entity entity) { // Leaves - private -> public
|
||||
entity.playerTouch(this);
|
||||
}
|
||||
|
||||
@@ -1251,7 +1257,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
// Paper end - Configurable sprint interruption on attack
|
||||
}
|
||||
|
||||
- if (target instanceof ServerPlayer && target.hurtMarked) {
|
||||
+ if ((target instanceof ServerPlayer && !(target instanceof org.leavesmc.leaves.bot.ServerBot)) && target.hurtMarked) { // Leaves - bot knockback
|
||||
// CraftBukkit start - Add Velocity Event
|
||||
boolean cancelled = false;
|
||||
org.bukkit.entity.Player player = (org.bukkit.entity.Player) target.getBukkitEntity();
|
||||
diff --git a/net/minecraft/world/entity/projectile/FishingHook.java b/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 71f6acc07d222fe512bf8d9fbaad35cb36bcf2d6..a9f5d503fbe50e54f2f44be2ca6d414430f4481e 100644
|
||||
--- a/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -58,7 +58,7 @@ public class FishingHook extends Projectile {
|
||||
public static final EntityDataAccessor<Integer> DATA_HOOKED_ENTITY = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.INT);
|
||||
private static final EntityDataAccessor<Boolean> DATA_BITING = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.BOOLEAN);
|
||||
private int life;
|
||||
- private int nibble;
|
||||
+ public int nibble; // Leaves - private -> public
|
||||
public int timeUntilLured;
|
||||
public int timeUntilHooked;
|
||||
public float fishAngle;
|
||||
diff --git a/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java b/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java
|
||||
index fc1b3501114108d0166256c514a225337955e461..56bc87fefc82c77077bfed50accbde778c0059ea 100644
|
||||
--- a/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java
|
||||
+++ b/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java
|
||||
@@ -270,6 +270,11 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
|
||||
}
|
||||
|
||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
+ } else if (this.getControllingPassenger() instanceof org.leavesmc.leaves.bot.ServerBot) { // Leaves start - Fakeplayer
|
||||
+ this.floatBoat();
|
||||
+ this.controlBoat();
|
||||
+ this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
+ // Leaves end - Fakeplayer
|
||||
} else {
|
||||
this.setDeltaMovement(Vec3.ZERO);
|
||||
}
|
||||
@@ -380,6 +385,13 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - Fakeplayer
|
||||
+ @Override
|
||||
+ public boolean canSimulateMovement() {
|
||||
+ return super.canSimulateMovement() || this.getControllingPassenger() instanceof org.leavesmc.leaves.bot.ServerBot;
|
||||
+ }
|
||||
+ // Leaves end - Fakeplayer
|
||||
+
|
||||
protected @Nullable SoundEvent getPaddleSound() {
|
||||
return switch (this.getStatus()) {
|
||||
case IN_WATER, UNDER_WATER, UNDER_FLOWING_WATER -> SoundEvents.BOAT_PADDLE_WATER;
|
||||
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index e7ea8849e8fa942709f505145e8076f064476206..4935234fba5977246aa303bf8162404813b5491e 100644
|
||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -404,6 +404,7 @@ public abstract class AbstractContainerMenu {
|
||||
|
||||
private void doClick(int slotIndex, int button, ClickType clickType, Player player) {
|
||||
Inventory inventory = player.getInventory();
|
||||
+ if (!doClickCheck(slotIndex, button, clickType, player)) return; // Leaves - doClick check
|
||||
if (clickType == ClickType.QUICK_CRAFT) {
|
||||
int i = this.quickcraftStatus;
|
||||
this.quickcraftStatus = getQuickcraftHeader(button);
|
||||
@@ -678,6 +679,22 @@ public abstract class AbstractContainerMenu {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - doClick check
|
||||
+ private boolean doClickCheck(int slotIndex, int button, ClickType actionType, Player player) {
|
||||
+ if (slotIndex < 0) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ Slot slot = getSlot(slotIndex);
|
||||
+ ItemStack itemStack = slot.getItem();
|
||||
+ net.minecraft.world.item.component.CustomData customData = itemStack.get(net.minecraft.core.component.DataComponents.CUSTOM_DATA);
|
||||
+ if (customData != null && customData.contains("Leaves.Gui.Placeholder")) {
|
||||
+ return !customData.copyTag().getBoolean("Leaves.Gui.Placeholder").orElse(false);
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Leaves end - doClick check
|
||||
+
|
||||
private boolean tryItemClickBehaviourOverride(Player player, ClickAction action, Slot slot, ItemStack clickedItem, ItemStack carriedItem) {
|
||||
FeatureFlagSet featureFlagSet = player.level().enabledFeatures();
|
||||
return carriedItem.isItemEnabled(featureFlagSet) && carriedItem.overrideStackedOnOther(slot, action, player)
|
||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||
index 73a97f4f62fe7d27b441cab58c6c86ffce011060..ea6285b7f53f391c84519aa7ae39164cf5740b81 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -456,7 +456,7 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(serverLevel, player, hand, blocks.getFirst(), clickedPos);
|
||||
}
|
||||
|
||||
- if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
|
||||
+ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild()) && (!(player instanceof org.leavesmc.leaves.bot.ServerBot))) { // Leaves - Fakeplayer skip this check
|
||||
interactionResult = InteractionResult.FAIL; // cancel placement
|
||||
// PAIL: Remove this when MC-99075 fixed
|
||||
player.containerMenu.forceHeldSlot(hand);
|
||||
@@ -987,6 +987,20 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - Fakeplayer
|
||||
+ public boolean releaseUsingWithResult(Level level, LivingEntity livingEntity, int timeLeft) {
|
||||
+ ItemStack itemStack = this.copy();
|
||||
+ if (this.getItem().releaseUsing(this, level, livingEntity, timeLeft)) {
|
||||
+ ItemStack itemStack1 = this.applyAfterUseComponentSideEffects(livingEntity, itemStack);
|
||||
+ if (itemStack1 != this) {
|
||||
+ livingEntity.setItemInHand(livingEntity.getUsedItemHand(), itemStack1);
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Leaves end - Fakeplayer
|
||||
+
|
||||
public boolean useOnRelease() {
|
||||
return this.getItem().useOnRelease(this);
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
index 557ea70254a8d6dd87c656098c5632bdcbe3df8f..1d60054146f970ec24054d2c76a27e2d8620ec67 100644
|
||||
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
@@ -145,7 +145,7 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
||||
break;
|
||||
}
|
||||
|
||||
- if (!(entity instanceof ServerPlayer)) {
|
||||
+ if (!(entity instanceof ServerPlayer) || (entity instanceof org.leavesmc.leaves.bot.ServerBot)) { // Leaves - bot slime block
|
||||
Vec3 deltaMovement = entity.getDeltaMovement();
|
||||
double d1 = deltaMovement.x;
|
||||
double d2 = deltaMovement.y;
|
||||
diff --git a/net/minecraft/world/level/levelgen/PhantomSpawner.java b/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
index e9c40ecb2309d386a2214593181f2d4f289eb28b..17dff8aed5015bfd22d021e2fcf536265d179139 100644
|
||||
--- a/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
+++ b/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
@@ -49,6 +49,11 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
ServerStatsCounter stats = serverPlayer.getStats();
|
||||
int i = Mth.clamp(stats.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
|
||||
int i1 = 24000;
|
||||
+ // Leaves start - fakeplayer spawn
|
||||
+ if (serverPlayer instanceof org.leavesmc.leaves.bot.ServerBot bot && bot.getConfigValue(org.leavesmc.leaves.bot.agent.Configs.SPAWN_PHANTOM)) {
|
||||
+ i1 = Math.max(bot.notSleepTicks, 1);
|
||||
+ }
|
||||
+ // Leaves end - fakeplayer spawn
|
||||
if (randomSource.nextInt(i) >= 72000) {
|
||||
BlockPos blockPos1 = blockPos.above(20 + randomSource.nextInt(15))
|
||||
.east(-10 + randomSource.nextInt(21))
|
||||
diff --git a/net/minecraft/world/level/storage/LevelResource.java b/net/minecraft/world/level/storage/LevelResource.java
|
||||
index bef794c3f58c41d910aa0bcc63fbdeea7225fddf..a601da588e6973cc5b87d3e3eeba49b53f6d9a6d 100644
|
||||
--- a/net/minecraft/world/level/storage/LevelResource.java
|
||||
+++ b/net/minecraft/world/level/storage/LevelResource.java
|
||||
@@ -15,7 +15,7 @@ public class LevelResource {
|
||||
public static final LevelResource ROOT = new LevelResource(".");
|
||||
private final String id;
|
||||
|
||||
- private LevelResource(String id) {
|
||||
+ public LevelResource(String id) { // Leaves - private -> public
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Fri, 3 Oct 2025 19:43:36 +0800
|
||||
Subject: [PATCH] Modify merge ItemEntity logic
|
||||
|
||||
Add followTickSequenceMerge to modify merge items, due to Paper's modification of the merge radius, when the merge radius is large and stacks containing many items get stuck in an unexpected position, individual items may never reach their destination. This configuration option is added to fix this behavior.
|
||||
|
||||
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index f3f067c62dc024a747d059608ae7a2e8740dbff2..1b8a963726ee2b2244d429f1e7e3a08034bfbd70 100644
|
||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -283,7 +283,7 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish
|
||||
ItemStack item = this.getItem();
|
||||
ItemStack item1 = itemEntity.getItem();
|
||||
if (Objects.equals(this.target, itemEntity.target) && areMergable(item, item1)) {
|
||||
- if (item1.getCount() < item.getCount()) {
|
||||
+ if (fun.bm.lophine.config.modules.misc.ItemEntityConfig.followTickSequenceMerge || item1.getCount() < item.getCount()) { // Lophine - add follow Tick Sequence Merge, see Paper#13073
|
||||
merge(this, item, itemEntity, item1);
|
||||
} else {
|
||||
merge(itemEntity, item1, this, item);
|
||||
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Mon, 3 Feb 2025 16:51:01 +0800
|
||||
Subject: [PATCH] Leaves: Syncmatica Protocol
|
||||
|
||||
This patch is Powered by Syncmatica(https://github.com/End-Tech/syncmatica)
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index d35ef52a6adb9a560138d1a2af32969c3a73f42b..df66e24c61af9d57d619c91849e28f1bec64a036 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -338,9 +338,12 @@ public class ServerGamePacketListenerImpl
|
||||
this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(player.getUUID(), server::enforceSecureProfile);
|
||||
this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat
|
||||
this.tickEndEvent = new io.papermc.paper.event.packet.ClientTickEndEvent(player.getBukkitEntity()); // Paper - add client tick end event
|
||||
+ this.exchangeTarget = new org.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget(this); // Leaves - Syncmatica Protocol
|
||||
this.playerGameConnection = new io.papermc.paper.connection.PaperPlayerGameConnection(this); // Paper
|
||||
}
|
||||
|
||||
+ public final org.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget exchangeTarget; // Leaves - Syncmatica Protocol
|
||||
+
|
||||
// Paper start - configuration phase API
|
||||
@Override
|
||||
public io.papermc.paper.connection.PlayerCommonConnection getApiConnection() {
|
||||
@@ -1,25 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Mon, 3 Feb 2025 13:03:42 +0800
|
||||
Subject: [PATCH] Leaves: BBOR Protocol
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 435acf0fe5e80ca371d1145befc2cfaa917a89e3..77577d0df9b14a7ad55b2866c2ac31863226458b 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -758,6 +758,11 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
|
||||
public void setLoaded(boolean loaded) {
|
||||
this.loaded = loaded;
|
||||
+ // Leaves start - bbor
|
||||
+ if (loaded) {
|
||||
+ org.leavesmc.leaves.protocol.BBORProtocol.onChunkLoaded(this);
|
||||
+ }
|
||||
+ // Leaves end - bbor
|
||||
}
|
||||
|
||||
public Level getLevel() {
|
||||
@@ -1,140 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bacteriawa <A3167717663@hotmail.com>
|
||||
Date: Fri, 13 Feb 2026 16:17:36 +0800
|
||||
Subject: [PATCH] Leaves: Jade Protocol
|
||||
|
||||
This patch is Powered by Jade(https://github.com/Snownee/Jade)
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 7c2d53ca863c2e50c6871938efc426ddefff9b5c..8c1e6837b0328c66fdda322c3c7ceba31c4f017f 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1451,7 +1451,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
} else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
|
||||
final LivingEntity entitylivingnew = this.getKillCreditOrigin();
|
||||
if (entitylivingnew != null) {
|
||||
- this.damageTransferToAsync(entitylivingnew, cause);
|
||||
+ this.damageTransferToAsync(entitylivingnew, damageSource);
|
||||
}
|
||||
// Luminol End - Cross Region Damage trace
|
||||
}
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index df66e24c61af9d57d619c91849e28f1bec64a036..8386757c5fd3d8df3ae77a4eeeb25a2f28840cda 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3843,7 +3843,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
@Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add PlayerLoadedWorldEvent
|
||||
- private void markClientLoaded() {
|
||||
+ public void markClientLoaded() { // Lophine - private -> public
|
||||
// Paper start - Add PlayerLoadedWorldEvent
|
||||
this.markClientLoaded(false);
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
index 901e4e9897e76cd4158d7f8bb8ec829df8ff8196..59b9373c7a14e42d9e5f691354a7616d16856215 100644
|
||||
--- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
+++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
@@ -64,7 +64,7 @@ public class Armadillo extends Animal {
|
||||
public final AnimationState rollOutAnimationState = new AnimationState();
|
||||
public final AnimationState rollUpAnimationState = new AnimationState();
|
||||
public final AnimationState peekAnimationState = new AnimationState();
|
||||
- private int scuteTime;
|
||||
+ public int scuteTime; // Leaves - private -> public
|
||||
private boolean peekReceivedClient = false;
|
||||
|
||||
public Armadillo(EntityType<? extends Animal> type, Level level) {
|
||||
diff --git a/net/minecraft/world/entity/animal/frog/Tadpole.java b/net/minecraft/world/entity/animal/frog/Tadpole.java
|
||||
index f65cfb908aac16e6df4d209c6b5c3ee5065289d3..9afada8ca16775752468e1b14cd97daf26325fc4 100644
|
||||
--- a/net/minecraft/world/entity/animal/frog/Tadpole.java
|
||||
+++ b/net/minecraft/world/entity/animal/frog/Tadpole.java
|
||||
@@ -244,7 +244,7 @@ public class Tadpole extends AbstractFish {
|
||||
}
|
||||
}
|
||||
|
||||
- private int getTicksLeftUntilAdult() {
|
||||
+ public int getTicksLeftUntilAdult() { // Leaves - private -> public
|
||||
return Math.max(0, ticksToBeFrog - this.age);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/storage/loot/LootPool.java b/net/minecraft/world/level/storage/loot/LootPool.java
|
||||
index 43b8f4674602532f0273ebc5a0233476d10f6735..2ed995e68cf7812c74c3ba15b49450b2b5f3f0f8 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/LootPool.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/LootPool.java
|
||||
@@ -37,7 +37,7 @@ public class LootPool {
|
||||
)
|
||||
.apply(instance, LootPool::new)
|
||||
);
|
||||
- private final List<LootPoolEntryContainer> entries;
|
||||
+ public final List<LootPoolEntryContainer> entries; // Leaves - private -> public
|
||||
private final List<LootItemCondition> conditions;
|
||||
private final Predicate<LootContext> compositeCondition;
|
||||
private final List<LootItemFunction> functions;
|
||||
diff --git a/net/minecraft/world/level/storage/loot/LootTable.java b/net/minecraft/world/level/storage/loot/LootTable.java
|
||||
index 35b5154473a3021dcae1f2ad016a77bcfb058c58..3d338b354c3d558a1c4ec20c149e8f26ed27da1e 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/LootTable.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/LootTable.java
|
||||
@@ -50,7 +50,7 @@ public class LootTable {
|
||||
public static final LootTable EMPTY = new LootTable(LootContextParamSets.EMPTY, Optional.empty(), List.of(), List.of());
|
||||
private final ContextKeySet paramSet;
|
||||
private final Optional<Identifier> randomSequence;
|
||||
- private final List<LootPool> pools;
|
||||
+ public final List<LootPool> pools; // Leaves - private -> public
|
||||
private final List<LootItemFunction> functions;
|
||||
private final BiFunction<ItemStack, LootContext, ItemStack> compositeFunction;
|
||||
public org.bukkit.craftbukkit.CraftLootTable craftLootTable; // CraftBukkit
|
||||
diff --git a/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java b/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java
|
||||
index eeaa49e9f70a18b5d39493aeff73f31b05ac2faa..8cd0403d7873c4c37caef75935b06b056c3d951d 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java
|
||||
@@ -16,7 +16,7 @@ public abstract class CompositeEntryBase extends LootPoolEntryContainer {
|
||||
return "Empty children list";
|
||||
}
|
||||
};
|
||||
- protected final List<LootPoolEntryContainer> children;
|
||||
+ public final List<LootPoolEntryContainer> children; // Leaves - private -> public
|
||||
private final ComposableEntryContainer composedChildren;
|
||||
|
||||
protected CompositeEntryBase(List<LootPoolEntryContainer> children, List<LootItemCondition> conditions) {
|
||||
diff --git a/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java b/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java
|
||||
index cfa05e882d2987cfab4c9d555a2de065b29fdf7e..4bacc9e2fb94d1b24887e7f0e9ce628814393209 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java
|
||||
@@ -14,7 +14,7 @@ import net.minecraft.world.level.storage.loot.predicates.ConditionUserBuilder;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
|
||||
public abstract class LootPoolEntryContainer implements ComposableEntryContainer {
|
||||
- protected final List<LootItemCondition> conditions;
|
||||
+ public final List<LootItemCondition> conditions; // Leaves - private -> public
|
||||
private final Predicate<LootContext> compositeCondition;
|
||||
|
||||
protected LootPoolEntryContainer(List<LootItemCondition> conditions) {
|
||||
diff --git a/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java b/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java
|
||||
index 141026601cd9a4561426b85fd1f8e7dc0544fbd7..a5d7ebb93c147bf0f806ac3c9b2dc4b878573944 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java
|
||||
@@ -29,7 +29,7 @@ public class NestedLootTable extends LootPoolSingletonContainer {
|
||||
return "->{inline}";
|
||||
}
|
||||
};
|
||||
- private final Either<ResourceKey<LootTable>, LootTable> contents;
|
||||
+ public final Either<ResourceKey<LootTable>, LootTable> contents; // Leaves - private -> public
|
||||
|
||||
private NestedLootTable(
|
||||
Either<ResourceKey<LootTable>, LootTable> contents, int weight, int quality, List<LootItemCondition> conditions, List<LootItemFunction> functions
|
||||
diff --git a/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java b/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java
|
||||
index bae72197acc929c7ed3e964f156115d728eb2176..8f3094f42f3366a1313d70c0b27fbe5632b2082a 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java
|
||||
@@ -12,7 +12,7 @@ import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.ValidationContext;
|
||||
|
||||
public abstract class CompositeLootItemCondition implements LootItemCondition {
|
||||
- protected final List<LootItemCondition> terms;
|
||||
+ public final List<LootItemCondition> terms; // Leaves - private -> public
|
||||
private final Predicate<LootContext> composedPredicate;
|
||||
|
||||
protected CompositeLootItemCondition(List<LootItemCondition> terms, Predicate<LootContext> composedPredicate) {
|
||||
@@ -1,21 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Fri, 7 Feb 2025 14:23:43 +0800
|
||||
Subject: [PATCH] Leaves: Xaero Map Protocol
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 3a5319739f0687fc6f09b2ac8ee31716593fe0de..36cd1a0307ff1a734eb5f4f3cc013781692e7ad8 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1126,6 +1126,7 @@ public abstract class PlayerList {
|
||||
//player.connection.send(new ClientboundSetChunkCacheRadiusPacket(io.papermc.paper.FeatureHooks.getViewDistance(level))); // Paper - rewrite chunk system
|
||||
//player.connection.send(new ClientboundSetSimulationDistancePacket(io.papermc.paper.FeatureHooks.getSimulationDistance(level))); // Paper - rewrite chunk system
|
||||
// Paper end - view distances
|
||||
+ org.leavesmc.leaves.protocol.XaeroMapProtocol.onSendWorldInfo(player); // Leaves - xaero map protocol
|
||||
if (level.isRaining()) {
|
||||
// CraftBukkit start - handle player weather
|
||||
// player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0.0F));
|
||||
@@ -1,43 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Thu, 27 Mar 2025 13:04:35 +0800
|
||||
Subject: [PATCH] Leaves: Support REI protocol
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/item/crafting/SmithingTransformRecipe.java b/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
|
||||
index d02609198253b51f632db46c40afd737d686c520..7296e0b73f1c8e32374f39238d1dfac62bc41afb 100644
|
||||
--- a/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
|
||||
+++ b/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
|
||||
@@ -82,6 +82,12 @@ public class SmithingTransformRecipe implements SmithingRecipe {
|
||||
);
|
||||
}
|
||||
|
||||
+ // Leaves start - REI
|
||||
+ public SlotDisplay getResult() {
|
||||
+ return this.result.display();
|
||||
+ }
|
||||
+ // Leaves end - REI
|
||||
+
|
||||
// CraftBukkit start
|
||||
@Override
|
||||
public org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id) {
|
||||
diff --git a/net/minecraft/world/item/crafting/SmithingTrimRecipe.java b/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
|
||||
index 6582370cfa3d58a7ac08d574e26e7a93d243bdaa..07501a27e6032e578b823d9b617166a9e78fcb20 100644
|
||||
--- a/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
|
||||
+++ b/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
|
||||
@@ -84,6 +84,12 @@ public class SmithingTrimRecipe implements SmithingRecipe {
|
||||
return Optional.of(this.addition);
|
||||
}
|
||||
|
||||
+ // Leaves start
|
||||
+ public Holder<TrimPattern> pattern() {
|
||||
+ return pattern;
|
||||
+ }
|
||||
+ // Leaves end
|
||||
+
|
||||
@Override
|
||||
public RecipeSerializer<SmithingTrimRecipe> getSerializer() {
|
||||
return RecipeSerializer.SMITHING_TRIM;
|
||||
@@ -1,95 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 27 Oct 2025 15:38:29 +0800
|
||||
Subject: [PATCH] Leaves: Wool Hopper Counter
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: MIT
|
||||
|
||||
This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet)
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 6cdb59762b5b223a220d420ff99fa9eadc64f3e0..fe93f0d6b2b7e8503da068179f5d7667634c7ff3 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -229,8 +229,30 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
flag |= validator.getAsBoolean(); // Paper - note: this is not a validator, it's what adds/sucks in items
|
||||
}
|
||||
|
||||
+ // Leaves start - Wool hopper counter
|
||||
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled()) {
|
||||
+ net.minecraft.world.item.DyeColor woolColor = org.leavesmc.leaves.util.WoolUtils.getWoolColorAtPosition(level, blockEntity.getBlockPos().relative(state.getValue(HopperBlock.FACING)));
|
||||
+ if (woolColor != null) {
|
||||
+ for (int i = 0; i < Short.MAX_VALUE; i++) {
|
||||
+ flag |= suckInItems(level, blockEntity);
|
||||
+ if (!flag) {
|
||||
+ break;
|
||||
+ } else {
|
||||
+ woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - Wool hopper counter
|
||||
+
|
||||
if (flag) {
|
||||
blockEntity.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
|
||||
+ // Leaves start - Wool hopper counter
|
||||
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos))) {
|
||||
+ blockEntity.setCooldown(0);
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Leaves end - Wool hopper counter
|
||||
setChanged(level, pos, state);
|
||||
// Leaves start - Lithium Sleeping Block Entity
|
||||
if (me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled
|
||||
@@ -462,6 +484,13 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
// Paper end - Perf: Optimize Hoppers
|
||||
|
||||
private static boolean ejectItems(Level level, BlockPos pos, HopperBlockEntity blockEntity) {
|
||||
+ // Leaves start - hopper counter
|
||||
+ if (org.leavesmc.leaves.util.HopperCounter.isEnabled()) {
|
||||
+ if (woolHopperCounter(level, pos, level.getBlockState(pos), HopperBlockEntity.getContainerAt(level, pos))) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - hopper counter
|
||||
Container attachedContainer = me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled ? blockEntity.getInsertInventory(level) : getAttachedContainer(level, pos, blockEntity); // Leaves - Lithium Sleeping Block Entity
|
||||
if (attachedContainer == null) {
|
||||
return false;
|
||||
@@ -537,6 +566,26 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - hopper counter
|
||||
+ private static boolean woolHopperCounter(Level level, BlockPos blockPos, BlockState state, @Nullable Container container) {
|
||||
+ if (container == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.minecraft.world.item.DyeColor woolColor = org.leavesmc.leaves.util.WoolUtils.getWoolColorAtPosition(level, blockPos.relative(state.getValue(HopperBlock.FACING)));
|
||||
+ if (woolColor != null) {
|
||||
+ for (int i = 0; i < container.getContainerSize(); ++i) {
|
||||
+ if (!container.getItem(i).isEmpty()) {
|
||||
+ ItemStack itemstack = container.getItem(i);
|
||||
+ org.leavesmc.leaves.util.HopperCounter.getCounter(woolColor).add(level.getServer(), itemstack);
|
||||
+ container.setItem(i, ItemStack.EMPTY);
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Leaves end - hopper counter
|
||||
+
|
||||
private static int[] getSlots(Container container, Direction direction) {
|
||||
if (container instanceof WorldlyContainer worldlyContainer) {
|
||||
return worldlyContainer.getSlotsForFace(direction);
|
||||
@@ -681,6 +730,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
|
||||
public static boolean addItem(Container container, ItemEntity item) {
|
||||
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && item.isRemoved()) return false; // Leaves - Wool hopper counter
|
||||
boolean flag = false;
|
||||
// CraftBukkit start
|
||||
if (org.bukkit.event.inventory.InventoryPickupItemEvent.getHandlerList().getRegisteredListeners().length > 0) { // Paper - optimize hoppers
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Mon, 3 Feb 2025 13:51:26 +0800
|
||||
Subject: [PATCH] Leaves: Alternative block placement Protocol
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: MIT
|
||||
|
||||
This patch is Powered by
|
||||
carpet-extra(https://github.com/gnembon/carpet-extra)
|
||||
MasaGadget(https://github.com/plusls/MasaGadget)
|
||||
litematica(https://github.com/maruohon/litematica)
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 8386757c5fd3d8df3ae77a4eeeb25a2f28840cda..fd74636d911596daae8cfe563c2dd5e3d37a1549 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2134,7 +2134,7 @@ public class ServerGamePacketListenerImpl
|
||||
if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this.player.level(), blockPos.getX() >> 4, blockPos.getZ() >> 4, 8) && this.player.isWithinBlockInteractionRange(blockPos, 1.0)) { // Folia - do not allow players to interact with blocks outside the current region
|
||||
Vec3 vec3 = location.subtract(Vec3.atCenterOf(blockPos));
|
||||
double d = 1.0000001;
|
||||
- if (Math.abs(vec3.x()) < 1.0000001 && Math.abs(vec3.y()) < 1.0000001 && Math.abs(vec3.z()) < 1.0000001) {
|
||||
+ if (fun.bm.lophine.config.modules.function.protocol.AlternativeBlockPlacementProtocolConfig.needIgnoreDistance() ||Math.abs(vec3.x()) < 1.0000001 && Math.abs(vec3.y()) < 1.0000001 && Math.abs(vec3.z()) < 1.0000001) { // Leaves - disableDistanceCheckForUseItem
|
||||
Direction direction = hitResult.getDirection();
|
||||
this.player.resetLastActionTime();
|
||||
int maxY = this.player.level().getMaxY();
|
||||
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
|
||||
index 73ce7c82c0bd28c2e43ca40ba35c4603b21375ad..a5d3caab2072b2c9bf8fdcbdb7c52c2dee16cfaf 100644
|
||||
--- a/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/net/minecraft/world/item/BlockItem.java
|
||||
@@ -147,7 +147,7 @@ public class BlockItem extends Item {
|
||||
}
|
||||
|
||||
protected @Nullable BlockState getPlacementState(BlockPlaceContext context) {
|
||||
- BlockState stateForPlacement = this.getBlock().getStateForPlacement(context);
|
||||
+ BlockState stateForPlacement = this.getBlock().getRealStateForPlacement(context); // Leaves - alternativeBlockPlacement
|
||||
return stateForPlacement != null && this.canPlace(context, stateForPlacement) ? stateForPlacement : null;
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/item/StandingAndWallBlockItem.java b/net/minecraft/world/item/StandingAndWallBlockItem.java
|
||||
index d75c95d728efc0b4064f562ca80b68b23883feaf..be685383b8e7c8111e976fc560f16d43d6545a34 100644
|
||||
--- a/net/minecraft/world/item/StandingAndWallBlockItem.java
|
||||
+++ b/net/minecraft/world/item/StandingAndWallBlockItem.java
|
||||
@@ -26,14 +26,14 @@ public class StandingAndWallBlockItem extends BlockItem {
|
||||
|
||||
@Override
|
||||
protected @Nullable BlockState getPlacementState(BlockPlaceContext context) {
|
||||
- BlockState stateForPlacement = this.wallBlock.getStateForPlacement(context);
|
||||
+ BlockState stateForPlacement = this.wallBlock.getRealStateForPlacement(context); // Leaves - alternativeBlockPlacement
|
||||
BlockState blockState = null;
|
||||
LevelReader level = context.getLevel();
|
||||
BlockPos clickedPos = context.getClickedPos();
|
||||
|
||||
for (Direction direction : context.getNearestLookingDirections()) {
|
||||
if (direction != this.attachmentDirection.getOpposite()) {
|
||||
- BlockState blockState1 = direction == this.attachmentDirection ? this.getBlock().getStateForPlacement(context) : stateForPlacement;
|
||||
+ BlockState blockState1 = direction == this.attachmentDirection ? this.getBlock().getRealStateForPlacement(context) : stateForPlacement; // Leaves - alternativeBlockPlacement
|
||||
if (blockState1 != null && this.canPlace(level, blockState1, clickedPos)) {
|
||||
blockState = blockState1;
|
||||
break;
|
||||
diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java
|
||||
index 492b1615d96133c5082e0f16015f114299f8082f..fb47a2acb0e4232359f5da061c1620a7b1d6c476 100644
|
||||
--- a/net/minecraft/world/level/block/Block.java
|
||||
+++ b/net/minecraft/world/level/block/Block.java
|
||||
@@ -489,6 +489,32 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
public void stepOn(Level level, BlockPos pos, BlockState state, Entity entity) {
|
||||
}
|
||||
|
||||
+ // Leaves start - alternativeBlockPlacement
|
||||
+ public @Nullable BlockState getRealStateForPlacement(BlockPlaceContext context) {
|
||||
+ BlockState vanillaState = this.getStateForPlacement(context);
|
||||
+ switch (fun.bm.lophine.config.modules.function.protocol.AlternativeBlockPlacementProtocolConfig.alternativeBlockPlacement) {
|
||||
+ case fun.bm.lophine.enums.EnumAlternativePlaceType.CARPET -> {
|
||||
+ BlockState tryState = org.leavesmc.leaves.protocol.CarpetAlternativeBlockPlacement.alternativeBlockPlacement(this, context);
|
||||
+ if (tryState != null) {
|
||||
+ return tryState;
|
||||
+ }
|
||||
+ }
|
||||
+ case fun.bm.lophine.enums.EnumAlternativePlaceType.CARPET_FIX -> {
|
||||
+ BlockState tryState = org.leavesmc.leaves.protocol.CarpetAlternativeBlockPlacement.alternativeBlockPlacementFix(this, context);
|
||||
+ if (tryState != null) {
|
||||
+ return tryState;
|
||||
+ }
|
||||
+ }
|
||||
+ case fun.bm.lophine.enums.EnumAlternativePlaceType.LITEMATICA -> {
|
||||
+ if (vanillaState != null) {
|
||||
+ return org.leavesmc.leaves.protocol.LitematicaEasyPlaceProtocol.applyPlacementProtocol(vanillaState, context);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return vanillaState;
|
||||
+ }
|
||||
+ // Leaves end - alternativeBlockPlacement
|
||||
+
|
||||
public @Nullable BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
return this.defaultBlockState();
|
||||
}
|
||||
@@ -1,567 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Sun, 16 Nov 2025 15:48:12 +0800
|
||||
Subject: [PATCH] Leaves: Replay Mod API
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves) & ReplayMod (https://github.com/ReplayMod)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
This patch is Powered by ReplayMod (https://github.com/ReplayMod)
|
||||
|
||||
diff --git a/net/minecraft/commands/CommandSourceStack.java b/net/minecraft/commands/CommandSourceStack.java
|
||||
index f046aca874eb3376696baaad3719a6987afbfe22..268b2c6b981c8164fb829eb8a33beb213fe60bcf 100644
|
||||
--- a/net/minecraft/commands/CommandSourceStack.java
|
||||
+++ b/net/minecraft/commands/CommandSourceStack.java
|
||||
@@ -562,7 +562,7 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
|
||||
|
||||
@Override
|
||||
public Collection<String> getOnlinePlayerNames() {
|
||||
- return this.entity instanceof ServerPlayer sourcePlayer && !sourcePlayer.getBukkitEntity().hasPermission("paper.bypass-visibility.tab-completion") ? this.getServer().getPlayerList().getPlayers().stream().filter(serverPlayer -> sourcePlayer.getBukkitEntity().canSee(serverPlayer.getBukkitEntity())).map(serverPlayer -> serverPlayer.getGameProfile().name()).toList() : Lists.newArrayList(this.server.getPlayerNames()); // Paper - Make CommandSourceStack respect hidden players
|
||||
+ return this.entity instanceof ServerPlayer sourcePlayer && !(sourcePlayer instanceof org.leavesmc.leaves.replay.ServerPhotographer) && !sourcePlayer.getBukkitEntity().hasPermission("paper.bypass-visibility.tab-completion") ? this.getServer().getPlayerList().getPlayers().stream().filter(serverPlayer -> sourcePlayer.getBukkitEntity().canSee(serverPlayer.getBukkitEntity())).map(serverPlayer -> serverPlayer.getGameProfile().name()).toList() : Lists.newArrayList(this.server.getPlayerNames()); // Paper - Make CommandSourceStack respect hidden players // Leaves - only real player
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/net/minecraft/commands/arguments/selector/EntitySelector.java b/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
index af71e0e1eb1c93745f3e4954ecc8fbd2ad4808a3..f3829564681faff3ae8971ed90b947b4a082a636 100644
|
||||
--- a/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
+++ b/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
@@ -126,11 +126,12 @@ public class EntitySelector {
|
||||
return this.findPlayers(source);
|
||||
} else if (this.playerName != null) {
|
||||
ServerPlayer playerByName = source.getServer().getPlayerList().getPlayerByName(this.playerName);
|
||||
+ playerByName = playerByName instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : playerByName; // Leaves - skip photographer
|
||||
return playerByName == null ? List.of() : List.of(playerByName);
|
||||
} else if (this.entityUUID != null) {
|
||||
for (ServerLevel serverLevel : source.getServer().getAllLevels()) {
|
||||
Entity entity = serverLevel.getEntity(this.entityUUID);
|
||||
- if (entity != null) {
|
||||
+ if (entity != null && !(entity instanceof org.leavesmc.leaves.replay.ServerPhotographer)) {
|
||||
if (entity.getType().isEnabled(source.enabledFeatures())) {
|
||||
return List.of(entity);
|
||||
}
|
||||
@@ -144,7 +145,7 @@ public class EntitySelector {
|
||||
AABB absoluteAabb = this.getAbsoluteAabb(vec3);
|
||||
if (this.currentEntity) {
|
||||
Predicate<Entity> predicate = this.getPredicate(vec3, absoluteAabb, null);
|
||||
- return source.getEntity() != null && predicate.test(source.getEntity()) ? List.of(source.getEntity()) : List.of();
|
||||
+ return source.getEntity() != null && !(source.getEntity() instanceof org.leavesmc.leaves.replay.ServerPhotographer) && predicate.test(source.getEntity()) ? List.of(source.getEntity()) : List.of(); // Leaves - skip photographer
|
||||
} else {
|
||||
Predicate<Entity> predicate = this.getPredicate(vec3, absoluteAabb, source.enabledFeatures());
|
||||
List<Entity> list = new ObjectArrayList<>();
|
||||
@@ -155,6 +156,7 @@ public class EntitySelector {
|
||||
this.addEntities(list, serverLevel1, absoluteAabb, predicate);
|
||||
}
|
||||
}
|
||||
+ list.removeIf(entity -> entity instanceof org.leavesmc.leaves.replay.ServerPhotographer); // Leaves - skip photographer
|
||||
|
||||
return this.sortAndLimit(vec3, list);
|
||||
}
|
||||
@@ -190,9 +192,11 @@ public class EntitySelector {
|
||||
this.checkPermissions(source);
|
||||
if (this.playerName != null) {
|
||||
ServerPlayer playerByName = source.getServer().getPlayerList().getPlayerByName(this.playerName);
|
||||
+ playerByName = playerByName instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : playerByName; // Leaves - skip photographer
|
||||
return playerByName == null ? List.of() : List.of(playerByName);
|
||||
} else if (this.entityUUID != null) {
|
||||
ServerPlayer playerByName = source.getServer().getPlayerList().getPlayer(this.entityUUID);
|
||||
+ playerByName = playerByName instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : playerByName; // Leaves - skip photographer
|
||||
return playerByName == null ? List.of() : List.of(playerByName);
|
||||
} else {
|
||||
Vec3 vec3 = this.position.apply(source.getPosition());
|
||||
@@ -204,11 +208,11 @@ public class EntitySelector {
|
||||
int resultLimit = this.getResultLimit();
|
||||
List<ServerPlayer> players;
|
||||
if (this.isWorldLimited()) {
|
||||
- players = source.getLevel().getPlayers(predicate, resultLimit);
|
||||
+ players = source.getLevel().getPlayers((player -> !(player instanceof org.leavesmc.leaves.replay.ServerPhotographer) && predicate.test(player)), resultLimit); // Leaves - skip photographer
|
||||
} else {
|
||||
players = new ObjectArrayList<>();
|
||||
|
||||
- for (ServerPlayer serverPlayer1 : source.getServer().getPlayerList().getPlayers()) {
|
||||
+ for (ServerPlayer serverPlayer1 : source.getServer().getPlayerList().realPlayers) { // Leaves - only real players
|
||||
if (predicate.test(serverPlayer1)) {
|
||||
players.add(serverPlayer1);
|
||||
if (players.size() >= resultLimit) {
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 385c71d70ed9e5a3ae25fbecaefd6773c467d31d..24f83a6875219aaf4b29e2461afcd0478a391014 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1896,7 +1896,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
private ServerStatus.Players buildPlayerStatus() {
|
||||
- List<ServerPlayer> players = new java.util.ArrayList<>(this.playerList.getPlayers()); // Folia - region threading
|
||||
+ List<ServerPlayer> players = new java.util.ArrayList<>(this.playerList.realPlayers); // Folia - region threading
|
||||
int maxPlayers = this.getMaxPlayers();
|
||||
if (this.hidesOnlinePlayers()) {
|
||||
return new ServerStatus.Players(maxPlayers, players.size(), List.of());
|
||||
@@ -2111,7 +2111,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
- return this.playerList.getPlayerCount();
|
||||
+ return this.playerList.realPlayers.size(); // Leaves - only real player
|
||||
}
|
||||
|
||||
public String[] getPlayerNames() {
|
||||
@@ -2315,7 +2315,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
} else {
|
||||
int i = 0;
|
||||
|
||||
- for (ServerPlayer serverPlayer : this.getPlayerList().getPlayers()) {
|
||||
+ for (ServerPlayer serverPlayer : this.getPlayerList().realPlayers) { // Leaves - only real players
|
||||
serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Folia - region threading
|
||||
// Paper start - Expand PlayerGameModeChangeEvent
|
||||
org.bukkit.event.player.PlayerGameModeChangeEvent event = player.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null); // Folia - region threading
|
||||
@@ -2500,7 +2500,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (Thread.currentThread() != this.serverThread) return; // Paper
|
||||
// Paper start - we don't need to save everything, just advancements
|
||||
// this.getPlayerList().saveAll();
|
||||
- for (final ServerPlayer player : this.getPlayerList().getPlayers()) {
|
||||
+ for (final ServerPlayer player : this.getPlayerList().realPlayers) { // Leaves - only real players
|
||||
player.getAdvancements().save();
|
||||
}
|
||||
// Paper end - we don't need to save everything, just advancements
|
||||
@@ -2638,7 +2638,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
PlayerList playerList = this.getPlayerList();
|
||||
UserWhiteList whiteList = playerList.getWhiteList();
|
||||
|
||||
- for (ServerPlayer serverPlayer : Lists.newArrayList(playerList.getPlayers())) {
|
||||
+ for (ServerPlayer serverPlayer : Lists.newArrayList(playerList.realPlayers)) { // Leaves - only real player
|
||||
if (!whiteList.isWhiteListed(serverPlayer.nameAndId()) && !this.getPlayerList().isOp(serverPlayer.nameAndId())) { // Paper - Fix kicking ops when whitelist is reloaded (MC-171420)
|
||||
serverPlayer.connection.disconnect(net.kyori.adventure.text.Component.text(org.spigotmc.SpigotConfig.whitelistMessage), org.bukkit.event.player.PlayerKickEvent.Cause.WHITELIST); // Paper - use configurable message & kick event cause
|
||||
}
|
||||
diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java
|
||||
index 5bf7eb5b906cefa57a1dfcf828ff7872dbceac4f..85923708c32a0597e98e028eeec501f2ea07b63b 100644
|
||||
--- a/net/minecraft/server/PlayerAdvancements.java
|
||||
+++ b/net/minecraft/server/PlayerAdvancements.java
|
||||
@@ -167,7 +167,7 @@ public class PlayerAdvancements {
|
||||
|
||||
public boolean award(AdvancementHolder advancement, String criterionKey) {
|
||||
// Leaves start - bot can't get advancement
|
||||
- if (player instanceof org.leavesmc.leaves.bot.ServerBot) {
|
||||
+ if (player instanceof org.leavesmc.leaves.bot.ServerBot || player instanceof org.leavesmc.leaves.replay.ServerPhotographer) { // Leaves - and photographer
|
||||
return false;
|
||||
}
|
||||
// Leaves end - bot can't get advancement
|
||||
diff --git a/net/minecraft/server/ServerScoreboard.java b/net/minecraft/server/ServerScoreboard.java
|
||||
index 04a62e5ab9c0d0b9b7959280b0e0ea3ff388c017..e4260ec1938a43d41e007ad67a2b5be96a00227c 100644
|
||||
--- a/net/minecraft/server/ServerScoreboard.java
|
||||
+++ b/net/minecraft/server/ServerScoreboard.java
|
||||
@@ -249,7 +249,7 @@ public class ServerScoreboard extends Scoreboard {
|
||||
public void startTrackingObjective(Objective objective) {
|
||||
List<Packet<?>> startTrackingPackets = this.getStartTrackingPackets(objective);
|
||||
|
||||
- for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
|
||||
+ for (ServerPlayer serverPlayer : this.server.getPlayerList().realPlayers) { // Leaves - only real players
|
||||
if (serverPlayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board
|
||||
for (Packet<?> packet : startTrackingPackets) {
|
||||
serverPlayer.connection.send(packet);
|
||||
@@ -275,7 +275,7 @@ public class ServerScoreboard extends Scoreboard {
|
||||
public void stopTrackingObjective(Objective objective) {
|
||||
List<Packet<?>> stopTrackingPackets = this.getStopTrackingPackets(objective);
|
||||
|
||||
- for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
|
||||
+ for (ServerPlayer serverPlayer : this.server.getPlayerList().realPlayers) { // Leaves - only real players
|
||||
if (serverPlayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board
|
||||
for (Packet<?> packet : stopTrackingPackets) {
|
||||
serverPlayer.connection.send(packet);
|
||||
diff --git a/net/minecraft/server/commands/ListPlayersCommand.java b/net/minecraft/server/commands/ListPlayersCommand.java
|
||||
index e7c778a7f292fd0749cbd5e6586ad1b93ac7f29e..024b56405bb58801b17a6adad7fec7a461d12a5c 100644
|
||||
--- a/net/minecraft/server/commands/ListPlayersCommand.java
|
||||
+++ b/net/minecraft/server/commands/ListPlayersCommand.java
|
||||
@@ -33,7 +33,7 @@ public class ListPlayersCommand {
|
||||
private static int format(CommandSourceStack source, Function<ServerPlayer, Component> nameExtractor) {
|
||||
PlayerList playerList = source.getServer().getPlayerList();
|
||||
// CraftBukkit start
|
||||
- List<ServerPlayer> playersTemp = playerList.getPlayers();
|
||||
+ List<ServerPlayer> playersTemp = playerList.realPlayers;
|
||||
if (source.getBukkitSender() instanceof org.bukkit.entity.Player) {
|
||||
org.bukkit.entity.Player sender = (org.bukkit.entity.Player) source.getBukkitSender();
|
||||
playersTemp = playersTemp.stream().filter((ep) -> sender.canSee(ep.getBukkitEntity())).collect(java.util.stream.Collectors.toList());
|
||||
diff --git a/net/minecraft/server/commands/OpCommand.java b/net/minecraft/server/commands/OpCommand.java
|
||||
index 590891d70a71ab30ceae3a3cf1923745e7c20b26..0ede1e5c73a0071e854de70f81ae1fc6a1d6dc59 100644
|
||||
--- a/net/minecraft/server/commands/OpCommand.java
|
||||
+++ b/net/minecraft/server/commands/OpCommand.java
|
||||
@@ -25,7 +25,7 @@ public class OpCommand {
|
||||
(commandContext, suggestionsBuilder) -> {
|
||||
PlayerList playerList = commandContext.getSource().getServer().getPlayerList();
|
||||
return SharedSuggestionProvider.suggest(
|
||||
- playerList.getPlayers()
|
||||
+ playerList.realPlayers // Leaves - only real player
|
||||
.stream()
|
||||
.filter(serverPlayer -> !playerList.isOp(serverPlayer.nameAndId()))
|
||||
.map(serverPlayer -> serverPlayer.getGameProfile().name()),
|
||||
diff --git a/net/minecraft/server/commands/ParticleCommand.java b/net/minecraft/server/commands/ParticleCommand.java
|
||||
index b5cb0fd45c1e33f40ff38e86772c9e6cc06c10a0..e9ac6ee47fd9c3d73e55a3467bb1c53f931609d0 100644
|
||||
--- a/net/minecraft/server/commands/ParticleCommand.java
|
||||
+++ b/net/minecraft/server/commands/ParticleCommand.java
|
||||
@@ -36,7 +36,7 @@ public class ParticleCommand {
|
||||
0.0F,
|
||||
0,
|
||||
false,
|
||||
- commandContext.getSource().getServer().getPlayerList().getPlayers()
|
||||
+ commandContext.getSource().getServer().getPlayerList().realPlayers // Leaves - only real player
|
||||
)
|
||||
)
|
||||
.then(
|
||||
@@ -50,7 +50,7 @@ public class ParticleCommand {
|
||||
0.0F,
|
||||
0,
|
||||
false,
|
||||
- context1.getSource().getServer().getPlayerList().getPlayers()
|
||||
+ context1.getSource().getServer().getPlayerList().realPlayers // Leaves - only real player
|
||||
)
|
||||
)
|
||||
.then(
|
||||
@@ -68,7 +68,7 @@ public class ParticleCommand {
|
||||
FloatArgumentType.getFloat(context1, "speed"),
|
||||
IntegerArgumentType.getInteger(context1, "count"),
|
||||
false,
|
||||
- context1.getSource().getServer().getPlayerList().getPlayers()
|
||||
+ context1.getSource().getServer().getPlayerList().realPlayers // Leaves - only real player
|
||||
)
|
||||
)
|
||||
.then(
|
||||
@@ -82,7 +82,7 @@ public class ParticleCommand {
|
||||
FloatArgumentType.getFloat(context1, "speed"),
|
||||
IntegerArgumentType.getInteger(context1, "count"),
|
||||
true,
|
||||
- context1.getSource().getServer().getPlayerList().getPlayers()
|
||||
+ context1.getSource().getServer().getPlayerList().realPlayers // Leaves - only real player
|
||||
)
|
||||
)
|
||||
.then(
|
||||
@@ -112,7 +112,7 @@ public class ParticleCommand {
|
||||
FloatArgumentType.getFloat(context1, "speed"),
|
||||
IntegerArgumentType.getInteger(context1, "count"),
|
||||
false,
|
||||
- context1.getSource().getServer().getPlayerList().getPlayers()
|
||||
+ context1.getSource().getServer().getPlayerList().realPlayers // Leaves - only real player
|
||||
)
|
||||
)
|
||||
.then(
|
||||
diff --git a/net/minecraft/server/commands/TeamMsgCommand.java b/net/minecraft/server/commands/TeamMsgCommand.java
|
||||
index 0ae4d68dfe42004839a0c5ad457de592f6b4af8b..1d1e396e4b29f33669872fb39e3a7f1d474a49f7 100644
|
||||
--- a/net/minecraft/server/commands/TeamMsgCommand.java
|
||||
+++ b/net/minecraft/server/commands/TeamMsgCommand.java
|
||||
@@ -40,7 +40,7 @@ public class TeamMsgCommand {
|
||||
} else {
|
||||
List<ServerPlayer> list = commandSourceStack.getServer()
|
||||
.getPlayerList()
|
||||
- .getPlayers()
|
||||
+ .realPlayers // Leaves - only real players
|
||||
.stream()
|
||||
.filter(player -> player == entityOrException || player.getTeam() == team)
|
||||
.toList();
|
||||
diff --git a/net/minecraft/server/commands/WhitelistCommand.java b/net/minecraft/server/commands/WhitelistCommand.java
|
||||
index 305273583b3d2ad233c6cd67883baad15fe572eb..ce2939eac9c66e0c6eaac1570c4da19d908662ad 100644
|
||||
--- a/net/minecraft/server/commands/WhitelistCommand.java
|
||||
+++ b/net/minecraft/server/commands/WhitelistCommand.java
|
||||
@@ -44,7 +44,7 @@ public class WhitelistCommand {
|
||||
(commandContext, suggestionsBuilder) -> {
|
||||
PlayerList playerList = commandContext.getSource().getServer().getPlayerList();
|
||||
return SharedSuggestionProvider.suggest(
|
||||
- playerList.getPlayers()
|
||||
+ playerList.realPlayers // Leaves - only real player
|
||||
.stream()
|
||||
.map(Player::nameAndId)
|
||||
.filter(nameAndId -> !playerList.getWhiteList().isWhiteListed(nameAndId))
|
||||
diff --git a/net/minecraft/server/gui/PlayerListComponent.java b/net/minecraft/server/gui/PlayerListComponent.java
|
||||
index 5a8cd3e6b448a4472092690cf589bca10b142126..158593b1a6384db635a1f224919b24c174944b10 100644
|
||||
--- a/net/minecraft/server/gui/PlayerListComponent.java
|
||||
+++ b/net/minecraft/server/gui/PlayerListComponent.java
|
||||
@@ -17,8 +17,8 @@ public class PlayerListComponent extends JList<String> {
|
||||
if (this.tickCount++ % 20 == 0) {
|
||||
Vector<String> list = new Vector<>();
|
||||
|
||||
- for (int i = 0; i < this.server.getPlayerList().getPlayers().size(); i++) {
|
||||
- list.add(this.server.getPlayerList().getPlayers().get(i).getGameProfile().name());
|
||||
+ for (int i = 0; i < this.server.getPlayerList().realPlayers.size(); i++) {
|
||||
+ list.add(this.server.getPlayerList().realPlayers.get(i).getGameProfile().name());
|
||||
}
|
||||
|
||||
this.setListData(list);
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 88efbe2bcb5621432b67366116150a3dab52e510..9345bdb2770e7c27488c547012020337fc651edc 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -3000,7 +3000,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.add(serverPlayer);
|
||||
// Leaves start - skip
|
||||
- if (!(serverPlayer instanceof org.leavesmc.leaves.bot.ServerBot)) {
|
||||
+ if (!(serverPlayer instanceof org.leavesmc.leaves.bot.ServerBot) && !(serverPlayer instanceof org.leavesmc.leaves.replay.ServerPhotographer)) { // and photographer
|
||||
ServerLevel.this.realPlayers.add(serverPlayer);
|
||||
}
|
||||
// Leaves end - skip
|
||||
@@ -3086,7 +3086,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.remove(serverPlayer);
|
||||
// Leaves start - skip
|
||||
- if (!(serverPlayer instanceof org.leavesmc.leaves.bot.ServerBot)) {
|
||||
+ if (!(serverPlayer instanceof org.leavesmc.leaves.bot.ServerBot) && !(serverPlayer instanceof org.leavesmc.leaves.replay.ServerPhotographer)) { // and photographer
|
||||
ServerLevel.this.realPlayers.remove(serverPlayer);
|
||||
}
|
||||
// Leaves end - skip
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 8c1e6837b0328c66fdda322c3c7ceba31c4f017f..ca751564d9189e873d4a53be9a2c68b2a04a8624 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -202,7 +202,7 @@ import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system
|
||||
- private static final Logger LOGGER = LogUtils.getLogger();
|
||||
+ protected static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final long LAST_SAVE_ABSENT = Long.MIN_VALUE; public long lastSave = LAST_SAVE_ABSENT; // Paper // Folia - threaded regions - changed to nanoTime
|
||||
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
|
||||
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
|
||||
@@ -669,7 +669,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
// Paper start - Expand PlayerGameModeChangeEvent
|
||||
this.loadGameTypes(input);
|
||||
}
|
||||
- private void loadGameTypes(ValueInput input) {
|
||||
+ public void loadGameTypes(ValueInput input) { // Lophine - private -> public
|
||||
if (this.server.getForcedGameType() != null && this.server.getForcedGameType() != readPlayerMode(input, "playerGameType")) {
|
||||
if (new org.bukkit.event.player.PlayerGameModeChangeEvent(this.getBukkitEntity(), org.bukkit.GameMode.getByValue(this.server.getDefaultGameType().getId()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null).callEvent()) {
|
||||
this.gameMode.setGameModeForPlayer(this.server.getForcedGameType(), GameType.DEFAULT_MODE);
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 36cd1a0307ff1a734eb5f4f3cc013781692e7ad8..0c3e6c1f70289c63bfe424a49374602f25ff5c0b 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -130,6 +130,7 @@ public abstract class PlayerList {
|
||||
private int simulationDistance;
|
||||
private boolean allowCommandsForAllPlayers;
|
||||
private int sendAllPlayerInfoIn;
|
||||
+ public final List<ServerPlayer> realPlayers = new java.util.concurrent.CopyOnWriteArrayList(); // Leaves - replay api
|
||||
|
||||
// CraftBukkit start
|
||||
private org.bukkit.craftbukkit.CraftServer cserver;
|
||||
@@ -218,6 +219,123 @@ public abstract class PlayerList {
|
||||
|
||||
abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor
|
||||
|
||||
+ // Leaves start - replay mod api
|
||||
+ public void placeNewPhotographer(Connection connection, org.leavesmc.leaves.replay.ServerPhotographer player, ServerLevel worldserver) {
|
||||
+ player.isRealPlayer = true; // Paper
|
||||
+ player.loginTime = System.currentTimeMillis(); // Paper
|
||||
+
|
||||
+ ServerLevel worldserver1 = worldserver;
|
||||
+
|
||||
+ player.setServerLevel(worldserver1);
|
||||
+ player.spawnIn(worldserver1);
|
||||
+ player.gameMode.setLevel((ServerLevel) player.level());
|
||||
+
|
||||
+ LevelData worlddata = worldserver1.getLevelData();
|
||||
+
|
||||
+ //player.loadGameTypes(null); // simply fix for https://github.com/MC-XiaoHei/ISeeYou/issues/70
|
||||
+ ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player, CommonListenerCookie.createInitial(player.gameProfile, false));
|
||||
+ GameRules gamerules = worldserver1.getGameRules();
|
||||
+ boolean flag = gamerules.get(GameRules.IMMEDIATE_RESPAWN);
|
||||
+ boolean flag1 = gamerules.get(GameRules.REDUCED_DEBUG_INFO);
|
||||
+ boolean flag2 = gamerules.get(GameRules.LIMITED_CRAFTING);
|
||||
+
|
||||
+ playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), worldserver1.getWorld().getSendViewDistance(), worldserver1.getWorld().getSimulationDistance(), flag1, !flag, flag2, player.createCommonSpawnInfo(worldserver1), this.server.enforceSecureProfile())); // Paper - replace old player chunk management
|
||||
+ player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
|
||||
+ playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
|
||||
+ playerconnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities()));
|
||||
+ playerconnection.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot()));
|
||||
+ RecipeManager craftingmanager = this.server.getRecipeManager();
|
||||
+ playerconnection.send(new ClientboundUpdateRecipesPacket(craftingmanager.getSynchronizedItemProperties(), craftingmanager.getSynchronizedStonecutterRecipes()));
|
||||
+
|
||||
+ this.sendPlayerPermissionLevel(player);
|
||||
+ player.getStats().markAllDirty();
|
||||
+ player.getRecipeBook().sendInitialRecipeBook(player);
|
||||
+ this.updateEntireScoreboard(worldserver1.getScoreboard(), player);
|
||||
+ this.server.invalidateStatus();
|
||||
+
|
||||
+ playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
|
||||
+ ServerStatus serverping = this.server.getStatus();
|
||||
+
|
||||
+ if (serverping != null) {
|
||||
+ player.sendServerStatus(serverping);
|
||||
+ }
|
||||
+
|
||||
+ this.players.add(player);
|
||||
+ this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot
|
||||
+ this.playersByUUID.put(player.getUUID(), player);
|
||||
+
|
||||
+ player.suppressTrackerForLogin = true;
|
||||
+ worldserver1.getCurrentWorldData().connections.add(player.connection.connection);
|
||||
+ worldserver1.addNewPlayer(player);
|
||||
+ this.server.getCustomBossEvents().onPlayerConnect(player);
|
||||
+ org.bukkit.craftbukkit.entity.CraftPlayer bukkitPlayer = player.getBukkitEntity();
|
||||
+
|
||||
+ player.containerMenu.transferTo(player.containerMenu, bukkitPlayer);
|
||||
+ if (!player.connection.isAcceptingMessages()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // Leaves - protocol
|
||||
+
|
||||
+ // Leaves start - bot support
|
||||
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
|
||||
+ org.leavesmc.leaves.bot.ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName());
|
||||
+ if (bot != null) {
|
||||
+ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false, false);
|
||||
+ }
|
||||
+ this.server.getBotList().bots.forEach(bot1 -> {
|
||||
+ bot1.sendPlayerInfo(player);
|
||||
+ bot1.sendFakeDataIfNeed(player, true);
|
||||
+ }); // Leaves - render bot
|
||||
+ }
|
||||
+ // Leaves end - bot support
|
||||
+
|
||||
+ final List<ServerPlayer> onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1);
|
||||
+ final List<ServerPlayer> playerList = List.copyOf(this.players); // Lophine - copy to avoid ConcurrentModificationException
|
||||
+ for (ServerPlayer serverPlayer : playerList) {
|
||||
+ if (serverPlayer == player || !bukkitPlayer.canSee(serverPlayer.getBukkitEntity())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ // Leaves start - skip photographer
|
||||
+ if (serverPlayer instanceof org.leavesmc.leaves.replay.ServerPhotographer) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Leaves end - skip photographer
|
||||
+
|
||||
+ onlinePlayers.add(serverPlayer);
|
||||
+ }
|
||||
+ if (!onlinePlayers.isEmpty()) {
|
||||
+ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers, player));
|
||||
+ }
|
||||
+
|
||||
+ player.sentListPacket = true;
|
||||
+ player.suppressTrackerForLogin = false;
|
||||
+ player.level().getChunkSource().chunkMap.addEntity(player);
|
||||
+
|
||||
+ this.sendLevelInfo(player, worldserver1);
|
||||
+
|
||||
+ if (player.level() == worldserver1 && !worldserver1.players().contains(player)) {
|
||||
+ worldserver1.addNewPlayer(player);
|
||||
+ this.server.getCustomBossEvents().onPlayerConnect(player);
|
||||
+ }
|
||||
+
|
||||
+ worldserver1 = player.level();
|
||||
+ for (MobEffectInstance mobeffect : player.getActiveEffects()) {
|
||||
+ playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect, false));
|
||||
+ }
|
||||
+
|
||||
+ if (player.isDeadOrDying()) {
|
||||
+ net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> plains = worldserver1.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME)
|
||||
+ .getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
|
||||
+ new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains),
|
||||
+ worldserver1.getLightEngine(), null, null, false)
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - replay mod api
|
||||
+
|
||||
public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie cookie) {
|
||||
player.isRealPlayer = true; // Paper
|
||||
player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed
|
||||
@@ -292,6 +410,7 @@ public abstract class PlayerList {
|
||||
|
||||
// player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below
|
||||
this.players.add(player);
|
||||
+ this.realPlayers.add(player); // Leaves - replay api
|
||||
this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot
|
||||
this.playersByUUID.put(player.getUUID(), player);
|
||||
// this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below
|
||||
@@ -507,6 +626,7 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
protected void save(ServerPlayer player) {
|
||||
+ if (player instanceof org.leavesmc.leaves.replay.ServerPhotographer) return; // Leaves - skip photographer
|
||||
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
|
||||
player.lastSave = System.nanoTime(); // Folia - region threading - changed to nanoTime tracking
|
||||
this.playerIo.save(player);
|
||||
@@ -521,6 +641,44 @@ public abstract class PlayerList {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - replay mod api
|
||||
+ public void removePhotographer(org.leavesmc.leaves.replay.ServerPhotographer entityplayer) {
|
||||
+ ServerLevel worldserver = entityplayer.level();
|
||||
+
|
||||
+ entityplayer.awardStat(Stats.LEAVE_GAME);
|
||||
+
|
||||
+ if (entityplayer.containerMenu != entityplayer.inventoryMenu) {
|
||||
+ entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT);
|
||||
+ }
|
||||
+
|
||||
+ if (server.isSameThread()) entityplayer.doTick();
|
||||
+
|
||||
+ if (this.collideRuleTeamName != null) {
|
||||
+ final net.minecraft.world.scores.Scoreboard scoreBoard = this.server.getLevel(Level.OVERWORLD).getScoreboard();
|
||||
+ final PlayerTeam team = scoreBoard.getPlayersTeam(this.collideRuleTeamName);
|
||||
+ if (entityplayer.getTeam() == team && team != null) {
|
||||
+ scoreBoard.removePlayerFromTeam(entityplayer.getScoreboardName(), team);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ worldserver.getCurrentWorldData().connections.remove(entityplayer.connection.connection);
|
||||
+ worldserver.removePlayerImmediately(entityplayer, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
|
||||
+ entityplayer.retireScheduler();
|
||||
+ entityplayer.getAdvancements().stopListening();
|
||||
+ this.players.remove(entityplayer);
|
||||
+ this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT));
|
||||
+ this.server.getCustomBossEvents().onPlayerDisconnect(entityplayer);
|
||||
+ UUID uuid = entityplayer.getUUID();
|
||||
+ ServerPlayer entityplayer1 = this.playersByUUID.get(uuid);
|
||||
+
|
||||
+ if (entityplayer1 == entityplayer) {
|
||||
+ this.playersByUUID.remove(uuid);
|
||||
+ }
|
||||
+
|
||||
+ this.cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity());
|
||||
+ }
|
||||
+ // Leaves stop - replay mod api
|
||||
+
|
||||
public net.kyori.adventure.text.@Nullable Component remove(ServerPlayer player) { // CraftBukkit - return string // Paper - return Component
|
||||
// Paper start - Fix kick event leave message not being sent
|
||||
return this.remove(player, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? player.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(player.getDisplayName())));
|
||||
@@ -595,6 +753,7 @@ public abstract class PlayerList {
|
||||
player.getBukkitEntity().packetProcessor.close(); // Folia - region threading
|
||||
player.getAdvancements().stopListening();
|
||||
this.players.remove(player);
|
||||
+ this.realPlayers.remove(player); // Leaves - replay api
|
||||
this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
|
||||
this.server.getCustomBossEvents().onPlayerDisconnect(player);
|
||||
UUID uuid = player.getUUID();
|
||||
@@ -910,15 +1069,15 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public String[] getPlayerNamesArray() {
|
||||
- List<ServerPlayer> players = new java.util.ArrayList<>(this.players); // Folia - region threading
|
||||
- String[] strings = new String[this.players.size() + this.server.getBotList().bots.size()]; // Leaves - fakeplayer support
|
||||
+ List<ServerPlayer> players = new java.util.ArrayList<>(this.realPlayers); // Folia - region threading
|
||||
+ String[] strings = new String[players.size() + this.server.getBotList().bots.size()]; // Leaves - fakeplayer support, and skip photographer
|
||||
|
||||
for (int i = 0; i < players.size(); i++) { // Folia - region threading
|
||||
strings[i] = players.get(i).getGameProfile().name(); // Folia - region threading
|
||||
}
|
||||
// Leaves start - fakeplayer support
|
||||
- for (int i = this.players.size(); i < strings.length; ++i) {
|
||||
- strings[i] = this.server.getBotList().bots.get(i - this.players.size()).getGameProfile().name();
|
||||
+ for (int i = players.size(); i < strings.length; ++i) { // Leaves - only real players
|
||||
+ strings[i] = this.server.getBotList().bots.get(i - players.size()).getGameProfile().name(); // Leaves - only real players
|
||||
}
|
||||
// Leaves end - fakeplayer support
|
||||
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index c0ebd700caa950948c58846eaf164afc14f87f09..e4ae4354e81f34f0db410333fc9b8e17383a5f41 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -262,7 +262,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
public int useItemRemaining;
|
||||
protected int fallFlyTicks;
|
||||
private long lastKineticHitFeedbackTime = -2147483648L;
|
||||
- private BlockPos lastPos;
|
||||
+ protected BlockPos lastPos;
|
||||
private Optional<BlockPos> lastClimbablePos = Optional.empty();
|
||||
private @Nullable DamageSource lastDamageSource;
|
||||
private long lastDamageStamp = Long.MIN_VALUE; // Folia - region threading
|
||||
-243
@@ -1,243 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bacteriawa <A3167717663@hotmail.com>
|
||||
Date: Sat, 7 Feb 2026 23:57:50 +0800
|
||||
Subject: [PATCH] Leaves: Catch update suppression crash
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/network/PacketProcessor.java b/net/minecraft/network/PacketProcessor.java
|
||||
index cf162ec136309d05c5aa03042652ab3932935917..469ffd54eb5af980f49061bbec0a72f4e888f8a3 100644
|
||||
--- a/net/minecraft/network/PacketProcessor.java
|
||||
+++ b/net/minecraft/network/PacketProcessor.java
|
||||
@@ -107,7 +107,20 @@ public class PacketProcessor implements AutoCloseable {
|
||||
final int packetTimerId = profiler.getOrCreateTimerAndStart(() -> "Packet Handler: ".concat(io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(ListenerAndPacket.this.packet.getClass().getName()))); try { // Folia - profiler
|
||||
this.packet.handle(this.listener);
|
||||
} finally { profiler.stopTimer(packetTimerId); } // Folia - profiler
|
||||
- } catch (Exception var3) {
|
||||
+ // Leaves start - update suppression crash fix
|
||||
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ if (this.listener instanceof net.minecraft.server.network.ServerGamePacketListenerImpl gamePacketListener) {
|
||||
+ exception.providePlayer(gamePacketListener.player);
|
||||
+ }
|
||||
+ exception.consume();
|
||||
+ } catch (Exception var3) {
|
||||
+ if (var3.getCause() instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ if (this.listener instanceof net.minecraft.server.network.ServerGamePacketListenerImpl gamePacketListener) {
|
||||
+ exception.providePlayer(gamePacketListener.player);
|
||||
+ }
|
||||
+ exception.consume();
|
||||
+ }
|
||||
+ // Leaves end - update suppression crash fix
|
||||
if (var3 instanceof ReportedException reportedException && reportedException.getCause() instanceof OutOfMemoryError) {
|
||||
throw PacketUtils.makeReportedException(var3, this.packet, this.listener);
|
||||
}
|
||||
diff --git a/net/minecraft/network/protocol/PacketUtils.java b/net/minecraft/network/protocol/PacketUtils.java
|
||||
index ab80a66646a7ebe2862221ac342b06c14fcfc734..7834f3da4d0ff4a5cdec46b023d7348369a12e96 100644
|
||||
--- a/net/minecraft/network/protocol/PacketUtils.java
|
||||
+++ b/net/minecraft/network/protocol/PacketUtils.java
|
||||
@@ -34,6 +34,7 @@ public class PacketUtils {
|
||||
}
|
||||
|
||||
public static <T extends PacketListener> ReportedException makeReportedException(Exception exception, Packet<T> packet, T packetListener) {
|
||||
+
|
||||
if (exception instanceof ReportedException reportedException) {
|
||||
fillCrashReport(reportedException.getReport(), packetListener, packet);
|
||||
return reportedException;
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 24f83a6875219aaf4b29e2461afcd0478a391014..9457d86461b032ff2dac338620c3d4a54e6c7071 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1978,11 +1978,27 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
try {
|
||||
profiler.startTimer(serverLevel.tickTimerId); try { // Folia - profiler
|
||||
serverLevel.tick(hasTimeLeft, region); // Folia - region threading
|
||||
+ // Leaves start - update suppression crash fix
|
||||
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ exception.provideLevel(serverLevel);
|
||||
+ exception.consume();
|
||||
} finally { profiler.stopTimer(serverLevel.tickTimerId); } // Folia - profiler
|
||||
} catch (Throwable var7) {
|
||||
- CrashReport crashReport = CrashReport.forThrowable(var7, "Exception ticking world");
|
||||
- serverLevel.fillReportDetails(crashReport);
|
||||
- throw new ReportedException(crashReport);
|
||||
+ org.leavesmc.leaves.util.UpdateSuppressionException updateSuppressionException = null;
|
||||
+ if (var7 instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ updateSuppressionException = exception;
|
||||
+ } else if (var7.getCause() instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ updateSuppressionException = exception;
|
||||
+ }
|
||||
+ if (updateSuppressionException != null) {
|
||||
+ updateSuppressionException.provideLevel(serverLevel);
|
||||
+ updateSuppressionException.consume();
|
||||
+ } else {
|
||||
+ // Leaves end - update suppression crash fix
|
||||
+ CrashReport crashReport = CrashReport.forThrowable(var7, "Exception ticking world");
|
||||
+ serverLevel.fillReportDetails(crashReport);
|
||||
+ throw new ReportedException(crashReport);
|
||||
+ }
|
||||
}
|
||||
|
||||
profilerFiller.pop();
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 9345bdb2770e7c27488c547012020337fc651edc..447b3e6149716a3ca4b9721746ea471c94c56e67 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -894,7 +894,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Kaiiju end
|
||||
|
||||
profilerFiller.push("tick");
|
||||
- this.guardEntityTick(this::tickNonPassenger, entity);
|
||||
+ // Lophine start - update suppression crash fix
|
||||
+ if (fun.bm.lophine.config.modules.fixes.UpdateSuppressionCrashFixConfig.enabled) {
|
||||
+ try {
|
||||
+ this.guardEntityTick(this::tickNonPassenger, entity); // Lophine changed
|
||||
+ // Leaves start - update suppression crash fix - for dragon dupe
|
||||
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ exception.provideLevel(this);
|
||||
+ exception.consume();
|
||||
+ // Leaves end - update suppression crash fix - for dragon dupe
|
||||
+ }
|
||||
+ } else {
|
||||
+ this.guardEntityTick(this::tickNonPassenger, entity);
|
||||
+ }
|
||||
+ // Lophine end - update suppression crash fix
|
||||
profilerFiller.pop();
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index ca751564d9189e873d4a53be9a2c68b2a04a8624..e6ec0788b88d3431c06134c879b4bae9c769dac1 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1108,6 +1108,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
|
||||
// Folia - region threading - move to main tick loop where we can detect duplicates
|
||||
// CraftBukkit end
|
||||
+ // Leaves start - update suppression crash fix
|
||||
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ exception.providePlayer(this);
|
||||
+ exception.provideLevel(this.level());
|
||||
+ exception.consume();
|
||||
+ // Leaves start - update suppression crash fix
|
||||
} catch (Throwable var4) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var4, "Ticking player");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Player being ticked");
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 5ac53fcdca5fa6aae0452840e78d67653ceececb..26de0d418e0dcbb4ecd88630d75c677fdc7ff93d 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -1427,9 +1427,19 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
this.walkingStepSound(pos, state);
|
||||
}
|
||||
|
||||
+ // Leaves start - update suppression crash fix
|
||||
if (broadcastGameEvent) {
|
||||
- this.level().gameEvent(GameEvent.STEP, this.position(), GameEvent.Context.of(this, state));
|
||||
+ try {
|
||||
+ this.level().gameEvent(net.minecraft.world.level.gameevent.GameEvent.STEP, this.position(), net.minecraft.world.level.gameevent.GameEvent.Context.of(this, state));
|
||||
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ exception.provideBlock(level, pos, state.getBlock());
|
||||
+ if (this instanceof net.minecraft.server.level.ServerPlayer player) {
|
||||
+ exception.providePlayer(player);
|
||||
+ }
|
||||
+ exception.consume();
|
||||
+ }
|
||||
}
|
||||
+ // Leaves end - update suppression crash fix
|
||||
|
||||
return true;
|
||||
} else {
|
||||
diff --git a/net/minecraft/world/level/block/ShulkerBoxBlock.java b/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
index cb0471b06c33d1f79ba5b7a9b6036ba6b089d2be..46d6c6e3befc70a6878e12a4d75575e6d48d10ca 100644
|
||||
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
@@ -181,7 +181,17 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
|
||||
|
||||
@Override
|
||||
protected int getAnalogOutputSignal(BlockState state, Level level, BlockPos pos, Direction direction) {
|
||||
- return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(level.getBlockEntity(pos));
|
||||
+ // Leaves start - update suppression crash fix
|
||||
+ try {
|
||||
+ return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(level.getBlockEntity(pos));
|
||||
+ } catch (ClassCastException ex) {
|
||||
+ if (fun.bm.lophine.config.modules.fixes.UpdateSuppressionCrashFixConfig.enabled) {
|
||||
+ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, null, this, null, ex);
|
||||
+ } else {
|
||||
+ throw ex;
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - update suppression crash fix
|
||||
}
|
||||
|
||||
public static Block getBlockByColor(@Nullable DyeColor color) {
|
||||
diff --git a/net/minecraft/world/level/block/state/StateHolder.java b/net/minecraft/world/level/block/state/StateHolder.java
|
||||
index c020d1944a25e2cd247e30a97c35bf93731d694a..74967f20099ea58cea1f9fc0f2387d8c45b54748 100644
|
||||
--- a/net/minecraft/world/level/block/state/StateHolder.java
|
||||
+++ b/net/minecraft/world/level/block/state/StateHolder.java
|
||||
@@ -104,7 +104,16 @@ public abstract class StateHolder<O, S> implements ca.spottedleaf.moonrise.patch
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
- throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner);
|
||||
+ // Leaves start - update suppression crash fix
|
||||
+ IllegalArgumentException iae = new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner);
|
||||
+ if (fun.bm.lophine.config.modules.fixes.UpdateSuppressionCrashFixConfig.enabled) {
|
||||
+ org.leavesmc.leaves.util.UpdateSuppressionException exception = new org.leavesmc.leaves.util.UpdateSuppressionException(null, null, null, null, iae);
|
||||
+ if (exception.getStackTrace()[1].getClassName().startsWith("net.minecraft")) {
|
||||
+ throw exception;
|
||||
+ }
|
||||
+ }
|
||||
+ throw iae;
|
||||
+ // Leaves end - update suppression crash fix
|
||||
// Paper end - optimise blockstate property access
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 77577d0df9b14a7ad55b2866c2ac31863226458b..5551d80a81c2878136f96b3e695c4888c7105a49 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -383,7 +383,7 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
if (blockState == state) {
|
||||
return null;
|
||||
} else {
|
||||
- Block block = state.getBlock();
|
||||
+ Block block = state.getBlock(); try { // Leaves start - update suppression crash fix
|
||||
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING).update(i, y, i2, state);
|
||||
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES).update(i, y, i2, state);
|
||||
this.heightmaps.get(Heightmap.Types.OCEAN_FLOOR).update(i, y, i2, state);
|
||||
@@ -457,6 +457,7 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
this.markUnsaved();
|
||||
return blockState;
|
||||
}
|
||||
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException e) { e.provideBlock(level, pos, block); throw e; } // Leaves - update suppression crash fix
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/redstone/NeighborUpdater.java b/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
index af21821513f11011e7bf3841d2f79cb99e4cd517..32488203ff074b675f5c8831d157b1d91bae48a9 100644
|
||||
--- a/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
+++ b/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
@@ -63,9 +63,22 @@ public interface NeighborUpdater {
|
||||
} finally { if (levelChunk != null) levelChunk.getChunkHot().stopTickingAndCount(); } // KioCG
|
||||
// Spigot start
|
||||
} catch (StackOverflowError ex) {
|
||||
+ // Leaves start - update suppression crash fix
|
||||
+ if (fun.bm.lophine.config.modules.fixes.UpdateSuppressionCrashFixConfig.enabled) {
|
||||
+ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, level, neighborBlock, null, ex);
|
||||
+ }
|
||||
level.lastPhysicsProblem = pos.immutable();
|
||||
// Spigot end
|
||||
} catch (Throwable var9) {
|
||||
+ if (fun.bm.lophine.config.modules.fixes.UpdateSuppressionCrashFixConfig.enabled) {
|
||||
+ if (var9 instanceof org.leavesmc.leaves.util.UpdateSuppressionException ue) {
|
||||
+ ue.provideBlock(level, pos, neighborBlock);
|
||||
+ throw ue;
|
||||
+ } else {
|
||||
+ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, level, neighborBlock, null, var9);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - update suppression crash fix
|
||||
CrashReport crashReport = CrashReport.forThrowable(var9, "Exception while updating neighbours");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Block being updated");
|
||||
crashReportCategory.setDetail(
|
||||
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bacteriawa <A3167717663@hotmail.com>
|
||||
Date: Sat, 15 Nov 2025 01:12:39 +0800
|
||||
Subject: [PATCH] Leaves: CCE update suppression
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/ShulkerBoxBlock.java b/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
index 46d6c6e3befc70a6878e12a4d75575e6d48d10ca..77840814806c7d07b58cd716cf7ec095e894498a 100644
|
||||
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
@@ -183,7 +183,9 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
|
||||
protected int getAnalogOutputSignal(BlockState state, Level level, BlockPos pos, Direction direction) {
|
||||
// Leaves start - update suppression crash fix
|
||||
try {
|
||||
- return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(level.getBlockEntity(pos));
|
||||
+ return fun.bm.lophine.config.modules.experiment.RedStoneConfig.cce ?
|
||||
+ AbstractContainerMenu.getRedstoneSignalFromContainer((net.minecraft.world.Container) level.getBlockEntity(pos)) : // Leaves - make cce happy(?)
|
||||
+ AbstractContainerMenu.getRedstoneSignalFromBlockEntity(level.getBlockEntity(pos));
|
||||
} catch (ClassCastException ex) {
|
||||
if (fun.bm.lophine.config.modules.fixes.UpdateSuppressionCrashFixConfig.enabled) {
|
||||
throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, null, this, null, ex);
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Wed, 14 Jun 2023 12:07:07 +0800
|
||||
Subject: [PATCH] Leaves: Redstone ignore upwards update
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/ComparatorBlock.java b/net/minecraft/world/level/block/ComparatorBlock.java
|
||||
index 578e7c8dc601f53cf2a068685c6901bfaf47e763..0686aa5425c00e10beb381f3c3ff3c554603cd49 100644
|
||||
--- a/net/minecraft/world/level/block/ComparatorBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ComparatorBlock.java
|
||||
@@ -58,6 +58,7 @@ public class ComparatorBlock extends DiodeBlock implements EntityBlock {
|
||||
BlockState neighborState,
|
||||
RandomSource random
|
||||
) {
|
||||
+ if (fun.bm.lophine.config.modules.experiment.RedStoneConfig.redstoneIgnoreUpwardsUpdate && direction == Direction.DOWN) return state; // Leaves - behavior to 1.20.1
|
||||
return direction == Direction.DOWN && !this.canSurviveOn(level, neighborPos, neighborState)
|
||||
? Blocks.AIR.defaultBlockState()
|
||||
: super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random);
|
||||
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
index ba253a9af6141d8ea99c064e3cc0c6486c221098..48f9e234e4025633cbc41d334d88ada36c2e0d7b 100644
|
||||
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
@@ -178,7 +178,7 @@ public class RedStoneWireBlock extends Block {
|
||||
RandomSource random
|
||||
) {
|
||||
if (direction == Direction.DOWN) {
|
||||
- return !this.canSurviveOn(level, neighborPos, neighborState) ? Blocks.AIR.defaultBlockState() : state;
|
||||
+ return fun.bm.lophine.config.modules.experiment.RedStoneConfig.redstoneIgnoreUpwardsUpdate ? state : !this.canSurviveOn(level, neighborPos, neighborState) ? Blocks.AIR.defaultBlockState() : state; // Leaves - behavior to 1.19
|
||||
} else if (direction == Direction.UP) {
|
||||
return this.getConnectionState(level, state, pos);
|
||||
} else {
|
||||
@@ -238,7 +238,7 @@ public class RedStoneWireBlock extends Block {
|
||||
BlockPos blockPos = pos.relative(direction);
|
||||
BlockState blockState = level.getBlockState(blockPos);
|
||||
if (nonNormalCubeAbove) {
|
||||
- boolean flag = blockState.getBlock() instanceof TrapDoorBlock || this.canSurviveOn(level, blockPos, blockState);
|
||||
+ boolean flag = (!fun.bm.lophine.config.modules.experiment.RedStoneConfig.redstoneIgnoreUpwardsUpdate && blockState.getBlock() instanceof TrapDoorBlock) || this.canSurviveOn(level, blockPos, blockState); // Leaves - behavior to 1.19
|
||||
if (flag && shouldConnectTo(level.getBlockState(blockPos.above()))) {
|
||||
if (blockState.isFaceSturdy(level, blockPos, direction.getOpposite())) {
|
||||
return RedstoneSide.UP;
|
||||
diff --git a/net/minecraft/world/level/block/RepeaterBlock.java b/net/minecraft/world/level/block/RepeaterBlock.java
|
||||
index 87e1a32376adc5a15f035b62bc1f672c507cd230..26c10c1fecb976f3ef0338aa78603d454d1b3fe8 100644
|
||||
--- a/net/minecraft/world/level/block/RepeaterBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RepeaterBlock.java
|
||||
@@ -68,6 +68,7 @@ public class RepeaterBlock extends DiodeBlock {
|
||||
BlockState neighborState,
|
||||
RandomSource random
|
||||
) {
|
||||
+ if (fun.bm.lophine.config.modules.experiment.RedStoneConfig.redstoneIgnoreUpwardsUpdate && direction == Direction.DOWN) return state; // Leaves - behavior to 1.20.1
|
||||
if (direction == Direction.DOWN && !this.canSurviveOn(level, neighborPos, neighborState)) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
} else {
|
||||
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 17 Nov 2025 18:41:08 +0800
|
||||
Subject: [PATCH] Instant Block Updater
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index 33d186d660ce3e3dc8cf26cd521fa99291ff78a5..ce1918d12b88835ea79a5c0dc90e0315c408830b 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -494,7 +494,7 @@ public final class RegionizedWorldData {
|
||||
public long lastMidTickExecuteFailure;
|
||||
// From Level
|
||||
public boolean populating;
|
||||
- public final CollectingNeighborUpdater neighborUpdater;
|
||||
+ public final net.minecraft.world.level.redstone.NeighborUpdater neighborUpdater;
|
||||
public boolean captureBlockStates = false;
|
||||
public boolean captureTreeGeneration = false;
|
||||
public final Map<BlockPos, CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
|
||||
@@ -582,7 +582,7 @@ public final class RegionizedWorldData {
|
||||
this.world = world;
|
||||
this.blockLevelTicks = new LevelTicks<>(world::isPositionTickingWithEntitiesLoaded, world, true);
|
||||
this.fluidLevelTicks = new LevelTicks<>(world::isPositionTickingWithEntitiesLoaded, world, false);
|
||||
- this.neighborUpdater = new CollectingNeighborUpdater(world, world.neighbourUpdateMax);
|
||||
+ this.neighborUpdater = fun.bm.lophine.config.modules.experiment.RedStoneConfig.instantBlockUpdater ? new net.minecraft.world.level.redstone.InstantNeighborUpdater(world) : new CollectingNeighborUpdater(world, world.neighbourUpdateMax); // Lophine - Instant Block Updater
|
||||
this.nearbyPlayers = new NearbyPlayers(world);
|
||||
this.wireHandler = new alternate.current.wire.WireHandler(world);
|
||||
this.turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((RedStoneWireBlock)Blocks.REDSTONE_WIRE);
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 447b3e6149716a3ca4b9721746ea471c94c56e67..d8a2f8a1fbf0189e86ccbce70a84641a143cdb91 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -927,12 +927,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Paper - rewrite chunk system
|
||||
profilerFiller.pop();
|
||||
profilerFiller.push("debugSynchronizers");
|
||||
+ // Lophine start - instant neighbor updates
|
||||
+ if (regionizedWorldData.neighborUpdater instanceof net.minecraft.world.level.redstone.CollectingNeighborUpdater neighborUpdater) {
|
||||
if (this.debugSynchronizers.hasAnySubscriberFor(DebugSubscriptions.NEIGHBOR_UPDATES)) {
|
||||
- regionizedWorldData.neighborUpdater // Folia - region threading
|
||||
- .setDebugListener(blockPos -> this.debugSynchronizers.broadcastEventToTracking(blockPos, DebugSubscriptions.NEIGHBOR_UPDATES, blockPos));
|
||||
+ neighborUpdater // Folia - region threading
|
||||
+ .setDebugListener(blockPos -> this.debugSynchronizers.broadcastEventToTracking(blockPos, DebugSubscriptions.NEIGHBOR_UPDATES, blockPos));
|
||||
} else {
|
||||
- regionizedWorldData.neighborUpdater.setDebugListener(null); // Folia - region threading
|
||||
+ neighborUpdater.setDebugListener(null); // Folia - region threading
|
||||
}
|
||||
+ }
|
||||
+ // Lophine end - instant neighbor updates
|
||||
|
||||
this.debugSynchronizers.tick(this.server.debugSubscribers());
|
||||
profilerFiller.pop();
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Tue, 18 Nov 2025 00:24:32 +0800
|
||||
Subject: [PATCH] Revert TrapDoorBlock changes form Paper
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/TrapDoorBlock.java b/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
index b45ae50db32c4156b8f8008335673d20c570c72d..af78831441f362b0129aa864854ce5a64d544640 100644
|
||||
--- a/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
+++ b/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
@@ -128,37 +128,7 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW
|
||||
if (!level.isClientSide()) {
|
||||
boolean hasNeighborSignal = level.hasNeighborSignal(pos);
|
||||
if (hasNeighborSignal != state.getValue(POWERED)) {
|
||||
- // CraftBukkit start
|
||||
- org.bukkit.block.Block bblock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
- int power = bblock.getBlockPower();
|
||||
- int oldPower = state.getValue(TrapDoorBlock.OPEN) ? 15 : 0;
|
||||
-
|
||||
- if (oldPower == 0 ^ power == 0 || neighborBlock.defaultBlockState().isSignalSource()) {
|
||||
- org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bblock, oldPower, power);
|
||||
- level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
- hasNeighborSignal = eventRedstone.getNewCurrent() > 0;
|
||||
- }
|
||||
- // CraftBukkit end
|
||||
- // Paper start - break redstone on trapdoors early
|
||||
- boolean open = state.getValue(TrapDoorBlock.OPEN) != hasNeighborSignal;
|
||||
- // note: this must run before any state for this block/its neighbours are written to the world
|
||||
- // we allow the redstone event to fire so that plugins can block
|
||||
- if (hasNeighborSignal && open) { // if we are now powered and it caused the trap door to open
|
||||
- // in this case, first check for the redstone on top first
|
||||
- BlockPos abovePos = pos.above();
|
||||
- BlockState above = level.getBlockState(abovePos);
|
||||
- if (above.getBlock() instanceof RedStoneWireBlock) {
|
||||
- level.setBlock(abovePos, Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS | Block.UPDATE_NEIGHBORS);
|
||||
- Block.popResource(level, abovePos, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.REDSTONE));
|
||||
- // now check that this didn't change our state
|
||||
- if (level.getBlockState(pos) != state) {
|
||||
- // our state was changed, so we cannot propagate this update
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- if (open) {
|
||||
- // Paper end - break redstone on trapdoors early
|
||||
+ if (state.getValue(OPEN) != hasNeighborSignal) {
|
||||
state = state.setValue(OPEN, hasNeighborSignal);
|
||||
this.playSound(null, level, pos, hasNeighborSignal);
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Tue, 18 Nov 2025 00:35:13 +0800
|
||||
Subject: [PATCH] Leaves: Prevent loss of item drops due to update suppression
|
||||
when breaking blocks
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc14e2e0225009cf9919072f7f/leaves-server/minecraft-patches/features/0090-Servux-Protocol.patch)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index 3301e521a79adbc6dd76be05e69cce1c97f8697e..8dc1db0e6bafba19e07a7fa78f3920d572d38466 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -386,7 +386,18 @@ public class ServerPlayerGameMode {
|
||||
this.level.getCurrentWorldData().captureDrops = new java.util.ArrayList<>(); // Folia - region threading
|
||||
// CraftBukkit end
|
||||
BlockState blockState1 = block.playerWillDestroy(this.level, pos, blockState, this.player);
|
||||
- boolean flag = this.level.removeBlock(pos, false);
|
||||
+ // Leaves start - Prevent loss of item drops due to update suppression when breaking blocks
|
||||
+ boolean flag;
|
||||
+ org.leavesmc.leaves.util.UpdateSuppressionException ex = null;
|
||||
+ try {
|
||||
+ flag = this.level.removeBlock(pos, false);
|
||||
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException e) {
|
||||
+ ex = e;
|
||||
+ ex.provideBlock(level, pos, block);
|
||||
+ ex.providePlayer(this.player);
|
||||
+ flag = false;
|
||||
+ }
|
||||
+ // Leaves end - Prevent loss of item drops due to update suppression when breaking blocks
|
||||
if (SharedConstants.DEBUG_BLOCK_BREAK) {
|
||||
LOGGER.info("server broke {} {} -> {}", pos, blockState1, this.level.getBlockState(pos));
|
||||
}
|
||||
@@ -418,6 +429,7 @@ public class ServerPlayerGameMode {
|
||||
if (event.isDropItems()) {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, itemsToDrop); // Paper - capture all item additions to the world
|
||||
}
|
||||
+ if (ex != null) throw ex; // Leaves - Prevent loss of item drops due to update suppression when breaking blocks
|
||||
|
||||
// Drop event experience
|
||||
if (flag) {
|
||||
-811
@@ -1,811 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Tue, 18 Nov 2025 23:11:26 +0800
|
||||
Subject: [PATCH] Leaves: Old Block remove behaviour
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/Containers.java b/net/minecraft/world/Containers.java
|
||||
index da10ca5ef12be1a834adda9243c082dadde24ec0..f682930f765d04f0a278b0648c2773ab5d4d740e 100644
|
||||
--- a/net/minecraft/world/Containers.java
|
||||
+++ b/net/minecraft/world/Containers.java
|
||||
@@ -51,4 +51,15 @@ public class Containers {
|
||||
public static void updateNeighboursAfterDestroy(BlockState state, Level level, BlockPos pos) {
|
||||
level.updateNeighbourForOutputSignal(pos, state.getBlock());
|
||||
}
|
||||
+
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ public static void dropContentsOnDestroy(BlockState state, BlockState newState, Level level, BlockPos pos) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ if (level.getBlockEntity(pos) instanceof Container container) {
|
||||
+ dropContents(level, pos, container);
|
||||
+ level.updateNeighbourForOutputSignal(pos, state.getBlock());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/AbstractFurnaceBlock.java b/net/minecraft/world/level/block/AbstractFurnaceBlock.java
|
||||
index dcc1bb4fcee9646212a424c03f77370ffa577fee..ca5cf7526082b9d3a7887dd77313e2c0012efebb 100644
|
||||
--- a/net/minecraft/world/level/block/AbstractFurnaceBlock.java
|
||||
+++ b/net/minecraft/world/level/block/AbstractFurnaceBlock.java
|
||||
@@ -51,6 +51,26 @@ public abstract class AbstractFurnaceBlock extends BaseEntityBlock {
|
||||
return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite());
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
+ if (blockEntity instanceof AbstractFurnaceBlockEntity) {
|
||||
+ if (level instanceof ServerLevel) {
|
||||
+ Containers.dropContents(level, pos, (AbstractFurnaceBlockEntity)blockEntity);
|
||||
+ ((AbstractFurnaceBlockEntity)blockEntity).getRecipesToAwardAndPopExperience((ServerLevel)level, net.minecraft.world.phys.Vec3.atCenterOf(pos));
|
||||
+ }
|
||||
+
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ level.updateNeighbourForOutputSignal(pos, this);
|
||||
+ } else {
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/BarrelBlock.java b/net/minecraft/world/level/block/BarrelBlock.java
|
||||
index 8139799a24274cfb70a99d301c2688c0360720c6..b224d3756120cd82d1381c55a95ad63c18c123b7 100644
|
||||
--- a/net/minecraft/world/level/block/BarrelBlock.java
|
||||
+++ b/net/minecraft/world/level/block/BarrelBlock.java
|
||||
@@ -49,6 +49,14 @@ public class BarrelBlock extends BaseEntityBlock {
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ Containers.dropContentsOnDestroy(state, newState, level, pos);
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/BasePressurePlateBlock.java b/net/minecraft/world/level/block/BasePressurePlateBlock.java
|
||||
index 7135a6bc87f90fafa94d0783aaf7b42d66449010..afd06de092a75c6c4f7b8848055e314b0c241029 100644
|
||||
--- a/net/minecraft/world/level/block/BasePressurePlateBlock.java
|
||||
+++ b/net/minecraft/world/level/block/BasePressurePlateBlock.java
|
||||
@@ -125,6 +125,19 @@ public abstract class BasePressurePlateBlock extends Block {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!isMoving && !state.is(newState.getBlock())) {
|
||||
+ if (this.getSignalForState(state) > 0) {
|
||||
+ this.updateNeighbours(level, pos);
|
||||
+ }
|
||||
+
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (!movedByPiston && this.getSignalForState(state) > 0) {
|
||||
diff --git a/net/minecraft/world/level/block/BaseRailBlock.java b/net/minecraft/world/level/block/BaseRailBlock.java
|
||||
index 504f38ce16f6a5d2b748a5c71c69f5be5886ceb5..db0b38db5675cb248e31e7a5988c35496561ad6f 100644
|
||||
--- a/net/minecraft/world/level/block/BaseRailBlock.java
|
||||
+++ b/net/minecraft/world/level/block/BaseRailBlock.java
|
||||
@@ -121,6 +121,23 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!isMoving) {
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ if (state.getValue(this.getShapeProperty()).isSlope()) {
|
||||
+ level.updateNeighborsAt(pos.above(), this);
|
||||
+ }
|
||||
+
|
||||
+ if (this.isStraight) {
|
||||
+ level.updateNeighborsAt(pos, this);
|
||||
+ level.updateNeighborsAt(pos.below(), this);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (!movedByPiston) {
|
||||
diff --git a/net/minecraft/world/level/block/BrewingStandBlock.java b/net/minecraft/world/level/block/BrewingStandBlock.java
|
||||
index bd6dc109fd9c37666f23ccd17c0eab8aff95e777..e25103c62a41e3fb0a8f7e84496cacc73ed71a74 100644
|
||||
--- a/net/minecraft/world/level/block/BrewingStandBlock.java
|
||||
+++ b/net/minecraft/world/level/block/BrewingStandBlock.java
|
||||
@@ -78,6 +78,14 @@ public class BrewingStandBlock extends BaseEntityBlock {
|
||||
level.addParticle(ParticleTypes.SMOKE, d, d1, d2, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ Containers.dropContentsOnDestroy(state, newState, level, pos);
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/ButtonBlock.java b/net/minecraft/world/level/block/ButtonBlock.java
|
||||
index 27ca29f1d3e0e68229edef3b32634ce9b054824a..ea2c5d79fc41f58b263ec34b53df436e0043ef53 100644
|
||||
--- a/net/minecraft/world/level/block/ButtonBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ButtonBlock.java
|
||||
@@ -132,6 +132,19 @@ public class ButtonBlock extends FaceAttachedHorizontalDirectionalBlock {
|
||||
return isOn ? this.type.buttonClickOn() : this.type.buttonClickOff();
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!isMoving && !state.is(newState.getBlock())) {
|
||||
+ if (state.getValue(POWERED)) {
|
||||
+ this.updateNeighbours(state, level, pos);
|
||||
+ }
|
||||
+
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (!movedByPiston && state.getValue(POWERED)) {
|
||||
diff --git a/net/minecraft/world/level/block/CampfireBlock.java b/net/minecraft/world/level/block/CampfireBlock.java
|
||||
index b9e11a361e91cf3d5c929330fc0ba59cfe903198..4985fcfef75abbe2be9cd5e6111de4d60237bafa 100644
|
||||
--- a/net/minecraft/world/level/block/CampfireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/CampfireBlock.java
|
||||
@@ -105,6 +105,20 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB
|
||||
return InteractionResult.TRY_WITH_EMPTY_HAND;
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
+ if (blockEntity instanceof CampfireBlockEntity) {
|
||||
+ net.minecraft.world.Containers.dropContents(level, pos, ((CampfireBlockEntity)blockEntity).getItems());
|
||||
+ }
|
||||
+
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier, boolean pastEdges) {
|
||||
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
|
||||
diff --git a/net/minecraft/world/level/block/ChestBlock.java b/net/minecraft/world/level/block/ChestBlock.java
|
||||
index fa2dce759419f62825000718361f47c6f208cdb2..64c0616c294bd7c7b62ae376d50369500b948390 100644
|
||||
--- a/net/minecraft/world/level/block/ChestBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ChestBlock.java
|
||||
@@ -280,6 +280,14 @@ public class ChestBlock extends AbstractChestBlock<ChestBlockEntity> implements
|
||||
return this.chestCanConnectTo(blockState) && blockState.getValue(TYPE) == ChestType.SINGLE ? blockState.getValue(FACING) : null;
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ Containers.dropContentsOnDestroy(state, newState, level, pos);
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/ChiseledBookShelfBlock.java b/net/minecraft/world/level/block/ChiseledBookShelfBlock.java
|
||||
index cea0f015290137a5284f4a3021c954272b3db543..53d983505b4c92824083ecd123901874d04704c5 100644
|
||||
--- a/net/minecraft/world/level/block/ChiseledBookShelfBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ChiseledBookShelfBlock.java
|
||||
@@ -149,6 +149,27 @@ public class ChiseledBookShelfBlock extends BaseEntityBlock implements Selectabl
|
||||
SLOT_OCCUPIED_PROPERTIES.forEach(property -> builder.add(property));
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ if (level.getBlockEntity(pos) instanceof ChiseledBookShelfBlockEntity chiseledBookShelfBlockEntity && !chiseledBookShelfBlockEntity.isEmpty()) {
|
||||
+ for (int i = 0; i < 6; i++) {
|
||||
+ ItemStack item = chiseledBookShelfBlockEntity.getItem(i);
|
||||
+ if (!item.isEmpty()) {
|
||||
+ Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), item);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ chiseledBookShelfBlockEntity.clearContent();
|
||||
+ level.updateNeighbourForOutputSignal(pos, this);
|
||||
+ }
|
||||
+
|
||||
+ super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/CrafterBlock.java b/net/minecraft/world/level/block/CrafterBlock.java
|
||||
index 3faa541c4a4623e915269d6241e1a3a3c6e374ff..18c660893a33ecf70c3d225525505852e4449182 100644
|
||||
--- a/net/minecraft/world/level/block/CrafterBlock.java
|
||||
+++ b/net/minecraft/world/level/block/CrafterBlock.java
|
||||
@@ -128,6 +128,14 @@ public class CrafterBlock extends BaseEntityBlock {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
+ Containers.dropContentsOnDestroy(state, newState, level, pos);
|
||||
+ super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/CreakingHeartBlock.java b/net/minecraft/world/level/block/CreakingHeartBlock.java
|
||||
index dfb9a10622ba2a0c2759bb563fefd729f1109865..c735e7de1b88de531dd00a2cc2dd4a1394b808e6 100644
|
||||
--- a/net/minecraft/world/level/block/CreakingHeartBlock.java
|
||||
+++ b/net/minecraft/world/level/block/CreakingHeartBlock.java
|
||||
@@ -152,6 +152,16 @@ public class CreakingHeartBlock extends BaseEntityBlock {
|
||||
builder.add(AXIS, STATE, NATURAL);
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
+ if (level.getBlockEntity(pos) instanceof CreakingHeartBlockEntity creakingHeartBlockEntity) {
|
||||
+ creakingHeartBlockEntity.removeProtector(null);
|
||||
+ }
|
||||
+ super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/DecoratedPotBlock.java b/net/minecraft/world/level/block/DecoratedPotBlock.java
|
||||
index dd20e3c57352859ab931692445c83669da94f629..e8c216831b66cd0f4e989797030119388a3378a5 100644
|
||||
--- a/net/minecraft/world/level/block/DecoratedPotBlock.java
|
||||
+++ b/net/minecraft/world/level/block/DecoratedPotBlock.java
|
||||
@@ -164,6 +164,14 @@ public class DecoratedPotBlock extends BaseEntityBlock implements SimpleWaterlog
|
||||
return new DecoratedPotBlockEntity(pos, state);
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
+ Containers.dropContentsOnDestroy(state, newState, level, pos);
|
||||
+ super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/DiodeBlock.java b/net/minecraft/world/level/block/DiodeBlock.java
|
||||
index b34e051b4a672d44872a74e810f978373e73af05..4525d718016fe125e3cdb1c1798fe9483213ba49 100644
|
||||
--- a/net/minecraft/world/level/block/DiodeBlock.java
|
||||
+++ b/net/minecraft/world/level/block/DiodeBlock.java
|
||||
@@ -176,6 +176,16 @@ public abstract class DiodeBlock extends HorizontalDirectionalBlock {
|
||||
if (me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled && this instanceof ComparatorBlock && !oldState.is(Blocks.COMPARATOR)) org.leavesmc.leaves.lithium.common.block.entity.inventory_comparator_tracking.ComparatorTracking.notifyNearbyBlockEntitiesAboutNewComparator(level, pos); // Leaves - Lithium Sleeping Block Entity
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!isMoving && !state.is(newState.getBlock())) {
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ this.updateNeighborsInFront(level, pos, state);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (!movedByPiston) {
|
||||
diff --git a/net/minecraft/world/level/block/DispenserBlock.java b/net/minecraft/world/level/block/DispenserBlock.java
|
||||
index 2ef2861041f3aaf85ea64458c43c5d83fdab9bfc..0828d663647f7c3267a4a9392a3b0b8e6e54928c 100644
|
||||
--- a/net/minecraft/world/level/block/DispenserBlock.java
|
||||
+++ b/net/minecraft/world/level/block/DispenserBlock.java
|
||||
@@ -147,6 +147,14 @@ public class DispenserBlock extends BaseEntityBlock {
|
||||
return this.defaultBlockState().setValue(FACING, context.getNearestLookingDirection().getOpposite());
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ Containers.dropContentsOnDestroy(state, newState, level, pos);
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/HopperBlock.java b/net/minecraft/world/level/block/HopperBlock.java
|
||||
index 3c349b4216d934068c26017820884593662f471e..4c5a12784e97e599891d40d5ce784b4f8c1e5b15 100644
|
||||
--- a/net/minecraft/world/level/block/HopperBlock.java
|
||||
+++ b/net/minecraft/world/level/block/HopperBlock.java
|
||||
@@ -133,6 +133,14 @@ public class HopperBlock extends BaseEntityBlock implements org.leavesmc.leaves.
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ Containers.dropContentsOnDestroy(state, newState, level, pos);
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/JukeboxBlock.java b/net/minecraft/world/level/block/JukeboxBlock.java
|
||||
index a4b824dab307705559a76b954a3e47d30dd65889..bc036d8e9d241ea9178808fce39c4e5115d5f753 100644
|
||||
--- a/net/minecraft/world/level/block/JukeboxBlock.java
|
||||
+++ b/net/minecraft/world/level/block/JukeboxBlock.java
|
||||
@@ -73,6 +73,19 @@ public class JukeboxBlock extends BaseEntityBlock {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ if (level.getBlockEntity(pos) instanceof JukeboxBlockEntity jukeboxBlockEntity) {
|
||||
+ jukeboxBlockEntity.popOutTheItem();
|
||||
+ }
|
||||
+
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/LecternBlock.java b/net/minecraft/world/level/block/LecternBlock.java
|
||||
index 52b9bd310c731c407fc4264559084debec81d3d9..0b991825d48ad64c1c68fd7c6bded7583572dded 100644
|
||||
--- a/net/minecraft/world/level/block/LecternBlock.java
|
||||
+++ b/net/minecraft/world/level/block/LecternBlock.java
|
||||
@@ -198,6 +198,36 @@ public class LecternBlock extends BaseEntityBlock {
|
||||
changePowered(level, pos, state, false);
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ if (state.getValue(HAS_BOOK)) {
|
||||
+ this.popBook(state, level, pos);
|
||||
+ }
|
||||
+
|
||||
+ if (state.getValue(POWERED)) {
|
||||
+ updateBelow(level, pos, state);
|
||||
+ }
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void popBook(BlockState state, Level level, BlockPos pos) {
|
||||
+ if (level.getBlockEntity(pos) instanceof LecternBlockEntity lecternBlockEntity) { // CraftBukkit - don't validate, type may be changed already // Leaves - the method with validate arg already removed by paper...
|
||||
+ Direction direction = state.getValue(FACING);
|
||||
+ ItemStack itemStack = lecternBlockEntity.getBook().copy();
|
||||
+ if (itemStack.isEmpty()) return; // CraftBukkit - SPIGOT-5500
|
||||
+ float f = 0.25F * direction.getStepX();
|
||||
+ float f1 = 0.25F * direction.getStepZ();
|
||||
+ net.minecraft.world.entity.item.ItemEntity itemEntity = new net.minecraft.world.entity.item.ItemEntity(level, pos.getX() + 0.5 + f, pos.getY() + 1, pos.getZ() + 0.5 + f1, itemStack);
|
||||
+ itemEntity.setDefaultPickUpDelay();
|
||||
+ level.addFreshEntity(itemEntity);
|
||||
+ lecternBlockEntity.clearContent();
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (state.getValue(POWERED)) {
|
||||
diff --git a/net/minecraft/world/level/block/LeverBlock.java b/net/minecraft/world/level/block/LeverBlock.java
|
||||
index 5f03e9fed3d4a8c3b72ca05be0b62ef45ac291f7..359fe5d611bcebe4cb98b9d8cea26b255adb167e 100644
|
||||
--- a/net/minecraft/world/level/block/LeverBlock.java
|
||||
+++ b/net/minecraft/world/level/block/LeverBlock.java
|
||||
@@ -124,6 +124,19 @@ public class LeverBlock extends FaceAttachedHorizontalDirectionalBlock {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!isMoving && !state.is(newState.getBlock())) {
|
||||
+ if (state.getValue(POWERED)) {
|
||||
+ this.updateNeighbours(state, level, pos);
|
||||
+ }
|
||||
+
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (!movedByPiston && state.getValue(POWERED)) {
|
||||
diff --git a/net/minecraft/world/level/block/LightningRodBlock.java b/net/minecraft/world/level/block/LightningRodBlock.java
|
||||
index dbfe086123c4b3cdc866111e1b6ec37d8d38d394..adad6e538b128729b72b7d44cabbd0cfba7417f9 100644
|
||||
--- a/net/minecraft/world/level/block/LightningRodBlock.java
|
||||
+++ b/net/minecraft/world/level/block/LightningRodBlock.java
|
||||
@@ -120,6 +120,18 @@ public class LightningRodBlock extends RodBlock implements SimpleWaterloggedBloc
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ if (state.getValue(POWERED)) {
|
||||
+ this.updateNeighbours(state, level, pos);
|
||||
+ }
|
||||
+ super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (state.getValue(POWERED)) {
|
||||
diff --git a/net/minecraft/world/level/block/ObserverBlock.java b/net/minecraft/world/level/block/ObserverBlock.java
|
||||
index 3c12d8e23f20b666b0005e597ba2e803c02d5d78..17c371f4c24e8a81705bdd322b1de5de4b8be8b7 100644
|
||||
--- a/net/minecraft/world/level/block/ObserverBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ObserverBlock.java
|
||||
@@ -127,6 +127,17 @@ public class ObserverBlock extends DirectionalBlock {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ if (state.getValue(POWERED) && level.getBlockTicks().hasScheduledTick(pos, this)) {
|
||||
+ this.updateNeighborsInFront(level, pos, state.setValue(POWERED, Boolean.FALSE));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (state.getValue(POWERED) && level.getBlockTicks().hasScheduledTick(pos, this)) {
|
||||
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
index 48f9e234e4025633cbc41d334d88ada36c2e0d7b..5c154d15e5aa45988436722595c7fca74e166c9a 100644
|
||||
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
@@ -368,6 +368,27 @@ public class RedStoneWireBlock extends Block {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!isMoving && !state.is(newState.getBlock())) {
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ for (Direction direction : Direction.values()) {
|
||||
+ level.updateNeighborsAt(pos.relative(direction), this);
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - optimize redstone - replace call to updatePowerStrength
|
||||
+ if (level.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) {
|
||||
+ level.getWireHandler().onWireRemoved(pos, state); // Alternate Current
|
||||
+ } else {
|
||||
+ this.updateSurroundingRedstone(level, pos, state, null, false); // Vanilla/Eigencraft
|
||||
+ }
|
||||
+ // Paper end - optimize redstone
|
||||
+ this.updateNeighborsOfNeighboringWires(level, pos);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (!movedByPiston) {
|
||||
diff --git a/net/minecraft/world/level/block/RedstoneTorchBlock.java b/net/minecraft/world/level/block/RedstoneTorchBlock.java
|
||||
index d1dbfc821f068f14bf975842f66251816ea5c985..fe13504a7d2d685e43183dd7b3219f1605570adb 100644
|
||||
--- a/net/minecraft/world/level/block/RedstoneTorchBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedstoneTorchBlock.java
|
||||
@@ -53,6 +53,15 @@ public class RedstoneTorchBlock extends BaseTorchBlock {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!isMoving) {
|
||||
+ this.notifyNeighbors(level, pos, state);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (!movedByPiston) {
|
||||
diff --git a/net/minecraft/world/level/block/SculkSensorBlock.java b/net/minecraft/world/level/block/SculkSensorBlock.java
|
||||
index 80e6ba8f026a6565696f18304507b2d0a347650c..593fab3d2a70bcd6832dd777afa4973f22abbaeb 100644
|
||||
--- a/net/minecraft/world/level/block/SculkSensorBlock.java
|
||||
+++ b/net/minecraft/world/level/block/SculkSensorBlock.java
|
||||
@@ -128,6 +128,18 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ if (getPhase(state) == SculkSensorPhase.ACTIVE) {
|
||||
+ updateNeighbours(level, pos, state);
|
||||
+ }
|
||||
+ super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (getPhase(state) == SculkSensorPhase.ACTIVE) {
|
||||
diff --git a/net/minecraft/world/level/block/SculkShriekerBlock.java b/net/minecraft/world/level/block/SculkShriekerBlock.java
|
||||
index 2815fb48530de3a2f9ef0f472a0fd0a2c32140b6..6b5e5bbbeb11bd8ce100ef3c215dfcf4b387e595 100644
|
||||
--- a/net/minecraft/world/level/block/SculkShriekerBlock.java
|
||||
+++ b/net/minecraft/world/level/block/SculkShriekerBlock.java
|
||||
@@ -68,6 +68,16 @@ public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterlo
|
||||
super.stepOn(level, pos, state, entity);
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
+ if (level instanceof ServerLevel serverLevel && state.getValue(SHRIEKING) && !state.is(newState.getBlock())) {
|
||||
+ serverLevel.getBlockEntity(pos, BlockEntityType.SCULK_SHRIEKER).ifPresent(sculkShrieker -> sculkShrieker.tryRespond(serverLevel));
|
||||
+ }
|
||||
+ super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
|
||||
if (state.getValue(SHRIEKING)) {
|
||||
diff --git a/net/minecraft/world/level/block/ShulkerBoxBlock.java b/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
index 77840814806c7d07b58cd716cf7ec095e894498a..e820cd03e695649a8f83e23ae822524a8f78e23b 100644
|
||||
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
@@ -150,6 +150,19 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
|
||||
// Paper end - re-set loot table if it was cleared
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
+ if (blockEntity instanceof ShulkerBoxBlockEntity) {
|
||||
+ level.updateNeighbourForOutputSignal(pos, state.getBlock());
|
||||
+ }
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
Containers.updateNeighboursAfterDestroy(state, level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/TripWireBlock.java b/net/minecraft/world/level/block/TripWireBlock.java
|
||||
index 9d005c3db8f0c784cdd7217e7b110daa703a9cf3..190d7cd818f768bd44fc1b4e62af2c9b3aacbe4d 100644
|
||||
--- a/net/minecraft/world/level/block/TripWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/TripWireBlock.java
|
||||
@@ -108,6 +108,16 @@ public class TripWireBlock extends Block {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
|
||||
+ if (!isMoving && !state.is(newState.getBlock())) {
|
||||
+ this.updateSource(level, pos, state.setValue(POWERED, Boolean.TRUE));
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
|
||||
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
index 42a5e9a7f5d604e4821a116ba13319df052faf97..e90e142cfb15335522a48ad82aa90018ed8ec349 100644
|
||||
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
@@ -244,6 +244,25 @@ public class TripWireHookBlock extends Block {
|
||||
level.updateNeighborsAt(pos.relative(opposite), block, orientation);
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!isMoving && !state.is(newState.getBlock())) {
|
||||
+ boolean attachedValue = state.getValue(ATTACHED);
|
||||
+ boolean poweredValue = state.getValue(POWERED);
|
||||
+ if (attachedValue || poweredValue) {
|
||||
+ calculateState(level, pos, state, true, false, -1, null);
|
||||
+ }
|
||||
+
|
||||
+ if (poweredValue) {
|
||||
+ notifyNeighbors(this, level, pos, state.getValue(FACING));
|
||||
+ }
|
||||
+
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (!movedByPiston) {
|
||||
diff --git a/net/minecraft/world/level/block/entity/BlockEntityType.java b/net/minecraft/world/level/block/entity/BlockEntityType.java
|
||||
index 6a9d23d25a79c73d5792011faf0e5a1c4c25bc64..84e0d3cd3c349f0d588a4b4c2d6844480a92b4ca 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BlockEntityType.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BlockEntityType.java
|
||||
@@ -306,7 +306,7 @@ public class BlockEntityType<T extends BlockEntity> {
|
||||
}
|
||||
|
||||
public boolean isValid(BlockState state) {
|
||||
- return this.validBlocks.contains(state.getBlock());
|
||||
+ return fun.bm.lophine.config.modules.experiment.RedStoneConfig.oldBlockRemoveBehaviour || this.validBlocks.contains(state.getBlock()); // Leaves - behaviour 1.21.1-
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
diff --git a/net/minecraft/world/level/block/piston/MovingPistonBlock.java b/net/minecraft/world/level/block/piston/MovingPistonBlock.java
|
||||
index 58b78e6b9a43605940420d8cb0f1163ee3f0a5ff..eebf03ece11052f07702951b9335bc151e160848 100644
|
||||
--- a/net/minecraft/world/level/block/piston/MovingPistonBlock.java
|
||||
+++ b/net/minecraft/world/level/block/piston/MovingPistonBlock.java
|
||||
@@ -65,6 +65,18 @@ public class MovingPistonBlock extends BaseEntityBlock {
|
||||
return createTickerHelper(blockEntityType, BlockEntityType.PISTON, PistonMovingBlockEntity::tick);
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
+ if (blockEntity instanceof PistonMovingBlockEntity) {
|
||||
+ ((PistonMovingBlockEntity)blockEntity).finalTick();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
public void destroy(LevelAccessor level, BlockPos pos, BlockState state) {
|
||||
BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite());
|
||||
diff --git a/net/minecraft/world/level/block/piston/PistonHeadBlock.java b/net/minecraft/world/level/block/piston/PistonHeadBlock.java
|
||||
index b369e80a4fc371a3762e34e7d4d180b86d1d190f..0b412e360b090dc85d1726eb8f51c69b47061276 100644
|
||||
--- a/net/minecraft/world/level/block/piston/PistonHeadBlock.java
|
||||
+++ b/net/minecraft/world/level/block/piston/PistonHeadBlock.java
|
||||
@@ -78,6 +78,19 @@ public class PistonHeadBlock extends DirectionalBlock {
|
||||
return super.playerWillDestroy(level, pos, state, player);
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ @Override
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
+ if (!state.is(newState.getBlock())) {
|
||||
+ super.onRemove(state, level, pos, newState, isMoving);
|
||||
+ BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite());
|
||||
+ if (this.isFittingBase(state, level.getBlockState(blockPos))) {
|
||||
+ level.destroyBlock(blockPos, true);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
@Override
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite());
|
||||
diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index 418517faeaf40ae2f7dea5635e4232cd89db3ead..0de2f6627fb6295d7927ac3e37026f4daf68cfd3 100644
|
||||
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -171,6 +171,15 @@ public abstract class BlockBehaviour implements FeatureElement, org.leavesmc.lea
|
||||
org.spigotmc.AsyncCatcher.catchOp("block onPlace"); // Spigot
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("block remove"); // Spigot
|
||||
+ if (state.hasBlockEntity() && !state.is(newState.getBlock())) {
|
||||
+ level.removeBlockEntity(pos);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
}
|
||||
|
||||
@@ -866,6 +875,12 @@ public abstract class BlockBehaviour implements FeatureElement, org.leavesmc.lea
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ public void onRemove(Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
+ this.getBlock().onRemove(this.asState(), level, pos, newState, movedByPiston);
|
||||
+ }
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
+
|
||||
public void affectNeighborsAfterRemoval(ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
this.getBlock().affectNeighborsAfterRemoval(this.asState(), level, pos, movedByPiston);
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 5551d80a81c2878136f96b3e695c4888c7105a49..73dd8e67938fbfff745b189c06a93174976ba1bf 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -406,22 +406,28 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
boolean flag = !blockState.is(block);
|
||||
boolean flag1 = (flags & Block.UPDATE_MOVE_BY_PISTON) != 0;
|
||||
boolean flag2 = (flags & Block.UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS) == 0;
|
||||
- if (flag && blockState.hasBlockEntity() && !state.shouldChangedStateKeepBlockEntity(blockState)) {
|
||||
- if (!this.level.isClientSide() && flag2) {
|
||||
- BlockEntity blockEntity = this.level.getBlockEntity(pos);
|
||||
- if (blockEntity != null) {
|
||||
- blockEntity.preRemoveSideEffects(pos, blockState);
|
||||
+ // Leaves start - behaviour 1.21.1-
|
||||
+ if (!fun.bm.lophine.config.modules.experiment.RedStoneConfig.oldBlockRemoveBehaviour) {
|
||||
+ if (flag && blockState.hasBlockEntity() && !state.shouldChangedStateKeepBlockEntity(blockState)) {
|
||||
+ if (!this.level.isClientSide() && flag2) {
|
||||
+ BlockEntity blockEntity = this.level.getBlockEntity(pos);
|
||||
+ if (blockEntity != null) {
|
||||
+ blockEntity.preRemoveSideEffects(pos, blockState);
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
|
||||
- this.removeBlockEntity(pos);
|
||||
- }
|
||||
+ this.removeBlockEntity(pos);
|
||||
+ }
|
||||
|
||||
- if ((flag || block instanceof BaseRailBlock)
|
||||
- && this.level instanceof ServerLevel serverLevel
|
||||
- && ((flags & Block.UPDATE_NEIGHBORS) != 0 || flag1)) {
|
||||
- blockState.affectNeighborsAfterRemoval(serverLevel, pos, flag1);
|
||||
+ if ((flag || block instanceof BaseRailBlock)
|
||||
+ && this.level instanceof ServerLevel serverLevel
|
||||
+ && ((flags & Block.UPDATE_NEIGHBORS) != 0 || flag1)) {
|
||||
+ blockState.affectNeighborsAfterRemoval(serverLevel, pos, flag1);
|
||||
+ }
|
||||
+ } else {
|
||||
+ blockState.onRemove(this.level, pos, state, flag1);
|
||||
}
|
||||
+ // Leaves end - behaviour 1.21.1-
|
||||
|
||||
if (!section.getBlockState(i, i1, i2).is(block)) {
|
||||
return null;
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Tue, 18 Nov 2025 23:26:27 +0800
|
||||
Subject: [PATCH] Leaves: Do not reset placed block on exception & Do not
|
||||
prevent block entity and entity crash at LevelChunk
|
||||
|
||||
Co-authored by: MC_XiaoHei <xiaohei.xor7@outlook.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
|
||||
index a5d3caab2072b2c9bf8fdcbdb7c52c2dee16cfaf..4bb36d2965785fadf628a9bfac4fa2aa305aaf65 100644
|
||||
--- a/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/net/minecraft/world/item/BlockItem.java
|
||||
@@ -77,20 +77,22 @@ public class BlockItem extends Item {
|
||||
BlockState blockState = level.getBlockState(clickedPos);
|
||||
if (blockState.is(placementState.getBlock())) {
|
||||
blockState = this.updateBlockStateFromTag(clickedPos, level, itemInHand, blockState);
|
||||
+ // Leaves start - we do not need this
|
||||
// Paper start - Reset placed block on exception
|
||||
- try {
|
||||
+ // try {
|
||||
this.updateCustomBlockEntityTag(clickedPos, level, player, itemInHand, blockState);
|
||||
updateBlockEntityComponents(level, clickedPos, itemInHand);
|
||||
- } catch (Exception ex) {
|
||||
- ((org.bukkit.craftbukkit.block.CraftBlockState) oldBukkitState).revertPlace();
|
||||
- if (player instanceof ServerPlayer serverPlayer) {
|
||||
- org.apache.logging.log4j.LogManager.getLogger().error("Player {} tried placing invalid block", player.getScoreboardName(), ex);
|
||||
- serverPlayer.getBukkitEntity().kickPlayer("Packet processing error");
|
||||
- return InteractionResult.FAIL;
|
||||
- }
|
||||
- throw ex; // Rethrow exception if not placed by a player
|
||||
- }
|
||||
+ // } catch (Exception ex) {
|
||||
+ // ((org.bukkit.craftbukkit.block.CraftBlockState) oldBukkitState).revertPlace();
|
||||
+ // if (player instanceof ServerPlayer serverPlayer) {
|
||||
+ // org.apache.logging.log4j.LogManager.getLogger().error("Player {} tried placing invalid block", player.getScoreboardName(), ex);
|
||||
+ // serverPlayer.getBukkitEntity().kickPlayer("Packet processing error");
|
||||
+ // return InteractionResult.FAIL;
|
||||
+ // }
|
||||
+ // throw ex; // Rethrow exception if not placed by a player
|
||||
+ // }
|
||||
// Paper end - Reset placed block on exception
|
||||
+ // Leaves end - we dot not need this
|
||||
blockState.getBlock().setPlacedBy(level, clickedPos, blockState, player, itemInHand);
|
||||
// CraftBukkit start
|
||||
if (bukkitState != null) {
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 73dd8e67938fbfff745b189c06a93174976ba1bf..8e56c2237f9d49d0b09b62c0933283f77aaae679 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -1001,12 +1001,14 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
|
||||
profilerFiller.pop();
|
||||
} catch (Throwable var5) {
|
||||
+ // Leaves start - do not prevent here
|
||||
// Paper start - Prevent block entity and entity crashes
|
||||
- final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", LevelChunk.this.getLevel().getWorld().getName(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
|
||||
- net.minecraft.server.MinecraftServer.LOGGER.error(msg, var5);
|
||||
- net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, var5))); // Paper - ServerExceptionEvent
|
||||
- LevelChunk.this.removeBlockEntity(this.getPos());
|
||||
+ // final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", LevelChunk.this.getLevel().getWorld().getName(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
|
||||
+ // net.minecraft.server.MinecraftServer.LOGGER.error(msg, var5);
|
||||
+ // net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, var5))); // Paper - ServerExceptionEvent
|
||||
+ // LevelChunk.this.removeBlockEntity(this.getPos());
|
||||
// Paper end - Prevent block entity and entity crashes
|
||||
+ // Leaves end - do not prevent here
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 3 Dec 2025 16:28:34 +0800
|
||||
Subject: [PATCH] Global Entities Counter
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index ce1918d12b88835ea79a5c0dc90e0315c408830b..c5caad99caed20e2bb4475fcf057417ee27d737c 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -576,6 +576,9 @@ public final class RegionizedWorldData {
|
||||
}
|
||||
// Luminol end
|
||||
|
||||
+ public int uniqueId = -1; // Lophine - Global Entities Counter
|
||||
+ public boolean underGlobalEntitiesCounter = false; // Lophine - Global Entities Counter
|
||||
+
|
||||
public final TickRegions.TickRegionData regionData;
|
||||
|
||||
public RegionizedWorldData(final ServerLevel world, final TickRegions.TickRegionData regionData) {
|
||||
@@ -588,6 +591,15 @@ public final class RegionizedWorldData {
|
||||
this.turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((RedStoneWireBlock)Blocks.REDSTONE_WIRE);
|
||||
this.regionData = regionData;
|
||||
|
||||
+ // Lophine start - Global Entities Counter
|
||||
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
|
||||
+ uniqueId = fun.bm.lophine.utils.EntitiesCounterUtil.generateUniqueId();
|
||||
+ fun.bm.lophine.utils.EntitiesCounterUtil.reportAreaMap(world, spawnChunkTracker, uniqueId);
|
||||
+ fun.bm.lophine.utils.EntitiesCounterUtil.addDataToLoaded(world, loadedEntities, uniqueId);
|
||||
+ underGlobalEntitiesCounter = true;
|
||||
+ }
|
||||
+ // Lophine end - Global Entities Counter
|
||||
+
|
||||
// tasks may be drained before the region ticks, so we must set up the tick data early just in case
|
||||
this.updateTickData();
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index f4c9c551fc39bae38e283ccbbc3cd116f0536a64..db13211b24208d8addd3c210155bc244b58f3942 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -506,6 +506,25 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
this.chunkMap.tick(hasTimeLeft);
|
||||
profilerFiller.pop();
|
||||
this.clearCache();
|
||||
+ // Lophine start - Global Entities Counter
|
||||
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
|
||||
+ io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.level.getCurrentWorldData();
|
||||
+ if (regionizedWorldData != null) {
|
||||
+ if (regionizedWorldData.underGlobalEntitiesCounter) {
|
||||
+ if (regionizedWorldData.getLocalPlayers().isEmpty()) {
|
||||
+ fun.bm.lophine.utils.EntitiesCounterUtil.onWorldDataUnload(level, regionizedWorldData.uniqueId);
|
||||
+ regionizedWorldData.underGlobalEntitiesCounter = false;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (!regionizedWorldData.getLocalPlayers().isEmpty()) {
|
||||
+ fun.bm.lophine.utils.EntitiesCounterUtil.reportAreaMap(level, regionizedWorldData.spawnChunkTracker, regionizedWorldData.uniqueId);
|
||||
+ fun.bm.lophine.utils.EntitiesCounterUtil.addDataToLoaded(level, (ca.spottedleaf.moonrise.common.list.ReferenceList<Entity>) regionizedWorldData.getLoadedEntities(), regionizedWorldData.uniqueId);
|
||||
+ regionizedWorldData.underGlobalEntitiesCounter = true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Lophine end - Global Entities Counter
|
||||
}
|
||||
|
||||
private void tickChunks() {
|
||||
@@ -570,7 +589,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
}
|
||||
spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true); // Folia - region threading - note: function only cares about loaded entities, doesn't need all
|
||||
} else {
|
||||
+ // Lophine start - Global Entities Counter
|
||||
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
|
||||
+ spawnState = fun.bm.lophine.utils.EntitiesCounterUtil.runRemainingTasks(level, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false);
|
||||
+ } else {
|
||||
spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading - note: function only cares about loaded entities, doesn't need all
|
||||
+ }
|
||||
+ // Lophine end - Global Entities Counter
|
||||
}
|
||||
} finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); } // Folia - profiler
|
||||
// Paper end - Optional per player mob spawns
|
||||
@@ -578,7 +603,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
boolean flag = this.level.getGameRules().get(GameRules.SPAWN_MOBS) && !this.level.getLocalPlayers().isEmpty(); // CraftBukkit // Folia - region threading
|
||||
int i = this.level.getGameRules().get(GameRules.RANDOM_TICK_SPEED);
|
||||
List<MobCategory> filteredSpawningCategories;
|
||||
- if (flag && (this.spawnEnemies || this.spawnFriendlies)) { // Paper
|
||||
+ if (spawnState != null && flag && (this.spawnEnemies || this.spawnFriendlies)) { // Paper // Lophine - Global Entities Counter
|
||||
// Paper start - PlayerNaturallySpawnCreaturesEvent
|
||||
for (ServerPlayer entityPlayer : this.level.getLocalPlayers()) { // Folia - region threading
|
||||
int chunkRange = Math.min(level.spigotConfig.mobSpawnRange, entityPlayer.getBukkitEntity().getViewDistance());
|
||||
@@ -636,7 +661,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
this.level.tickThunder(chunk);
|
||||
}
|
||||
|
||||
- if (!spawnCategories.isEmpty()) {
|
||||
+ if (spawnState != null && !spawnCategories.isEmpty()) { // Lophine - Global Entities Counter
|
||||
if (this.level.getWorldBorder().isWithinBounds(pos)) { // Paper - rewrite chunk system
|
||||
NaturalSpawner.spawnForChunk(this.level, chunk, spawnState, spawnCategories);
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index d8a2f8a1fbf0189e86ccbce70a84641a143cdb91..76930a603a5bf07e62e8ef3a41bbb5213dcc8aea 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -765,6 +765,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
public void tick(BooleanSupplier hasTimeLeft, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - regionised ticking
|
||||
+ // Lophine start - Global Entities Counter
|
||||
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
|
||||
+ if (fun.bm.lophine.utils.EntitiesCounterUtil.canRunNewTask(this)) fun.bm.lophine.utils.EntitiesCounterUtil.tick(this);
|
||||
+ }
|
||||
+ // Lophine end - Global Entities Counter
|
||||
final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.getCurrentWorldData(); // Folia - regionised ticking
|
||||
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
|
||||
index c6985d2a9d1093943d754d77089bd4c3d5baf3ee..a8807f80f1b11d7f5dae3b96a0e215e3e105fdd0 100644
|
||||
--- a/net/minecraft/world/entity/Mob.java
|
||||
+++ b/net/minecraft/world/entity/Mob.java
|
||||
@@ -806,6 +806,44 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
}
|
||||
}
|
||||
} else {
|
||||
+ // Lophine start - fix some bug if player is cross scheduler >> to remove monster if the region don't have any valid player
|
||||
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
|
||||
+ List<net.minecraft.server.level.ServerPlayer> playerList = this.level().getServer().getPlayerList().getPlayers();
|
||||
+ if (!playerList.isEmpty()) {
|
||||
+ double d = -1.0;
|
||||
+ Vec3 vec3 = null;
|
||||
+ for (net.minecraft.server.level.ServerPlayer player1 : playerList) {
|
||||
+ if (player1.level() != this.level()) continue;
|
||||
+ double d1 = player1.distanceToSqr(this.position());
|
||||
+ if (d == -1.0 || d1 < d) {
|
||||
+ d = d1;
|
||||
+ vec3 = player1.position();
|
||||
+ }
|
||||
+ }
|
||||
+ if (vec3 != null) {
|
||||
+ // copy from PaperMC
|
||||
+ // Paper start - Configurable despawn distances
|
||||
+ final io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DespawnRangePair despawnRangePair = this.level().paperConfig().entities.spawning.despawnRanges.get(this.getType().getCategory());
|
||||
+ final io.papermc.paper.configuration.type.DespawnRange.Shape shape = this.level().paperConfig().entities.spawning.despawnRangeShape;
|
||||
+ final double dy = Math.abs(vec3.y - this.getY());
|
||||
+ final double dySqr = Mth.square(dy);
|
||||
+ final double dxSqr = Mth.square(vec3.x - this.getX());
|
||||
+ final double dzSqr = Mth.square(vec3.z - this.getZ());
|
||||
+ final double distanceSquared = dxSqr + dzSqr + dySqr;
|
||||
+ // Despawn if hard/soft limit is exceeded
|
||||
+ if (despawnRangePair.hard().shouldDespawn(shape, dxSqr, dySqr, dzSqr, dy) && this.removeWhenFarAway(distanceSquared)) {
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
+ }
|
||||
+
|
||||
+ if (despawnRangePair.soft().shouldDespawn(shape, dxSqr, dySqr, dzSqr, dy)) {
|
||||
+ if (this.noActionTime > 600 && this.random.nextInt(800) == 0 && this.removeWhenFarAway(distanceSquared)) {
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Lophine end
|
||||
this.noActionTime = 0;
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
|
||||
index 91f0fbd75bc93355dc872390d91af83c76dc1dce..e7223540a7cef20b661bdb857ffba962d0f5d348 100644
|
||||
--- a/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -116,7 +116,7 @@ public final class NaturalSpawner {
|
||||
return new NaturalSpawner.SpawnState(spawnableChunkCount, map, potentialCalculator, calculator);
|
||||
}
|
||||
|
||||
- static Biome getRoughBiome(BlockPos pos, ChunkAccess chunk) {
|
||||
+ public static Biome getRoughBiome(BlockPos pos, ChunkAccess chunk) { // Lophine - protected -> public
|
||||
return chunk.getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ())).value();
|
||||
}
|
||||
|
||||
@@ -585,7 +585,7 @@ public final class NaturalSpawner {
|
||||
private @Nullable EntityType<?> lastCheckedType;
|
||||
private double lastCharge;
|
||||
|
||||
- SpawnState(
|
||||
+ public SpawnState( // Lophine - protected -> public
|
||||
int spawnableChunkCount,
|
||||
Object2IntOpenHashMap<MobCategory> mobCategoryCounts,
|
||||
PotentialCalculator spawnPotential,
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 17 Dec 2025 00:20:57 +0800
|
||||
Subject: [PATCH] Add null check in RegionizedWorldData >> conections
|
||||
|
||||
some of our function patches will crash because of get null in conn.getPlayer(), then when we process player.chunkPosition() will get NPE, so we need to fix it.
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index c5caad99caed20e2bb4475fcf057417ee27d737c..c2e50a03a41958d9b44753adc9a9bf4ea1fb24a4 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -251,14 +251,17 @@ public final class RegionizedWorldData {
|
||||
regionToData.get(CoordinateUtils.getChunkKey(pos.x >> chunkToRegionShift, pos.z >> chunkToRegionShift)).itemEntityMovementTrackerMap.put(key, tracker);
|
||||
}
|
||||
// Luminol end
|
||||
+ Set<Connection> cons = new java.util.HashSet<>(from.connections.size()); // Lophine - save all connections we have processed in connection process
|
||||
// connections
|
||||
for (final Connection conn : from.connections) {
|
||||
final ServerPlayer player = conn.getPlayer();
|
||||
+ if (player == null) continue; // Lophine - skip null player connections
|
||||
final ChunkPos pos = player.chunkPosition();
|
||||
// Note: It is impossible for an entity in the world to _not_ be in an entity chunk, which means
|
||||
// the chunk holder must _exist_, and so the region section exists.
|
||||
regionToData.get(CoordinateUtils.getChunkKey(pos.x >> chunkToRegionShift, pos.z >> chunkToRegionShift))
|
||||
.connections.add(conn);
|
||||
+ cons.add(conn); // Lophine - save all connections we have processed in connection process
|
||||
}
|
||||
// entities
|
||||
for (final ServerPlayer player : from.localPlayers) {
|
||||
@@ -269,6 +272,13 @@ public final class RegionizedWorldData {
|
||||
into.localPlayers.add(player);
|
||||
player.getBukkitEntity().updateRegion(into);
|
||||
into.nearbyPlayers.addPlayer(player);
|
||||
+ // Lophine start - we need to process the connection if player's connection is not processed, if connection.player is null, next tick will clean up it
|
||||
+ final Connection conn = player.connection.connection;
|
||||
+ if (!cons.contains(conn)) {
|
||||
+ regionToData.get(CoordinateUtils.getChunkKey(pos.x >> chunkToRegionShift, pos.z >> chunkToRegionShift))
|
||||
+ .connections.add(conn);
|
||||
+ }
|
||||
+ // Lophine end
|
||||
}
|
||||
for (final Entity entity : from.allEntities) {
|
||||
final ChunkPos pos = entity.chunkPosition();
|
||||
@@ -636,6 +646,7 @@ public final class RegionizedWorldData {
|
||||
private static void cleanUpConnection(final Connection conn) {
|
||||
// note: ALL connections HERE have a player
|
||||
final ServerPlayer player = conn.getPlayer();
|
||||
+ if (player == null) return; // Lophine - skip null player connections
|
||||
// now that the connection is removed, we can allow this region to die
|
||||
player.level().moonrise$getChunkTaskScheduler().chunkHolderManager.removeTicketAtLevel(
|
||||
ServerGamePacketListenerImpl.DISCONNECT_TICKET, player.connection.disconnectPos,
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Tue, 13 Jan 2026 21:04:59 +0800
|
||||
Subject: [PATCH] Add removed check before all checks start in addEffect
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index e4ae4354e81f34f0db410333fc9b8e17383a5f41..fc8833655102ca98bb331782a624af79cbef414f 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1186,6 +1186,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
public boolean addEffect(MobEffectInstance effectInstance, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) {
|
||||
// Paper end - Don't fire sync event during generation
|
||||
// org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API
|
||||
+ if (this.isRemoved()) return false; // Lophine - shouldn't be possible to add effects to removed entity
|
||||
if (!this.hasNullCallback()) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add effects to entities asynchronously"); // Folia - region threading
|
||||
if (this.isTickingEffects) {
|
||||
this.effectsToProcess.add(new ProcessableEffect(effectInstance, cause));
|
||||
@@ -1,148 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Sun, 8 Mar 2026 23:56:06 +0800
|
||||
Subject: [PATCH] Leaves: Creative fly no clip
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/da12a58e8d3bd3cd13b52a60676d5a1e03acd30a/leaves-server/minecraft-patches/features/0049-Creative-fly-no-clip.patch)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java
|
||||
index f2ec0bd8cca3c08d558790537e17a8a2f95f1953..29d904b02a2c7b3d25261ca26c7c0479b00999ef 100644
|
||||
--- a/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -199,7 +199,7 @@ public class ExperienceOrb extends Entity {
|
||||
Player prevTarget = this.followingPlayer; // CraftBukkit - store old target
|
||||
if (this.followingPlayer == null || this.followingPlayer.isSpectator() || this.followingPlayer.distanceToSqr(this) > 64.0) {
|
||||
Player nearestPlayer = this.level().getNearestPlayer(this, 8.0);
|
||||
- if (nearestPlayer != null && !nearestPlayer.isSpectator() && !nearestPlayer.isDeadOrDying()) {
|
||||
+ if (nearestPlayer != null && !nearestPlayer.isCreativeFlyOrSpectator() && !nearestPlayer.isDeadOrDying()) { // Leaves - creative no clip
|
||||
this.followingPlayer = nearestPlayer;
|
||||
} else {
|
||||
this.followingPlayer = null;
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 29ca31b05ec5636243b13fee8b3399d5e21808b4..8966953ee80a1527c9c4cc4d0a7a3bdb2197a2da 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -285,8 +285,8 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
if (this.cullTask != null) this.cullTask.requestCullSignal(); // Luminol - Ray tracing entity tracker
|
||||
// Luminol end
|
||||
|
||||
- this.noPhysics = this.isSpectator();
|
||||
- if (this.isSpectator() || this.isPassenger()) {
|
||||
+ this.noPhysics = this.isCreativeFlyOrSpectator(); // Leaves - creative no clip
|
||||
+ if (this.isCreativeFlyOrSpectator() || this.isPassenger()) { // Leaves - creative no clip
|
||||
this.setOnGround(false);
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.SWIMMING)) {
|
||||
Pose desiredPose = this.getDesiredPose();
|
||||
Pose pose;
|
||||
- if (this.isSpectator() || this.isPassenger() || this.canPlayerFitWithinBlocksAndEntitiesWhen(desiredPose)) {
|
||||
+ if (this.isCreativeFlyOrSpectator() || this.isPassenger() || this.canPlayerFitWithinBlocksAndEntitiesWhen(desiredPose)) { // Leaves - creative no clip
|
||||
pose = desiredPose;
|
||||
} else if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING)) {
|
||||
pose = Pose.CROUCHING;
|
||||
@@ -544,7 +544,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
this.updateSwingTime();
|
||||
this.yHeadRot = this.getYRot();
|
||||
this.setSpeed((float)this.getAttributeValue(Attributes.MOVEMENT_SPEED));
|
||||
- if (this.getHealth() > 0.0F && !this.isSpectator()) {
|
||||
+ if (this.getHealth() > 0.0F && !this.isCreativeFlyOrSpectator()) { // Leaves - creative no clip
|
||||
AABB aabb;
|
||||
if (this.isPassenger() && !this.getVehicle().isRemoved()) {
|
||||
aabb = this.getBoundingBox().minmax(this.getVehicle().getBoundingBox()).inflate(1.0, 0.0, 1.0);
|
||||
@@ -1877,9 +1877,29 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
return this.gameMode() == GameType.SPECTATOR;
|
||||
}
|
||||
|
||||
+ // Leaves start - creative no clip
|
||||
+ public boolean isCreativeFlyOrSpectator() {
|
||||
+ return isSpectator() || (fun.bm.lophine.config.modules.function.CreativeFlyNoClipConfig.enabled && isCreative() && getAbilities().flying);
|
||||
+ }
|
||||
+
|
||||
+ public boolean canSpectatingPlace(net.minecraft.world.level.LevelReader world, BlockState state, BlockPos pos, net.minecraft.world.phys.shapes.CollisionContext context) {
|
||||
+ if (this.isCreativeFlyOrSpectator()) {
|
||||
+ net.minecraft.world.phys.shapes.VoxelShape voxelShape = state.getCollisionShape(world, pos, context);
|
||||
+ return voxelShape.isEmpty() || world.isUnobstructed(this, voxelShape.move(pos.getX(), pos.getY(), pos.getZ()));
|
||||
+ } else {
|
||||
+ return world.isUnobstructed(state, pos, context);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) {
|
||||
+ return !isCreativeFlyOrSpectator() && super.isCollidable(ignoreClimbing);
|
||||
+ }
|
||||
+ // Leaves end - creative no clip
|
||||
+
|
||||
@Override
|
||||
public boolean canBeHitByProjectile() {
|
||||
- return !this.isSpectator() && super.canBeHitByProjectile();
|
||||
+ return !this.isCreativeFlyOrSpectator() && super.canBeHitByProjectile(); // Leaves - creative no clip
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
|
||||
index 4bb36d2965785fadf628a9bfac4fa2aa305aaf65..44786e4f77285f1fbd4643f560105e410035afeb 100644
|
||||
--- a/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/net/minecraft/world/item/BlockItem.java
|
||||
@@ -170,8 +170,9 @@ public class BlockItem extends Item {
|
||||
protected boolean canPlace(BlockPlaceContext context, BlockState state) {
|
||||
Player player = context.getPlayer();
|
||||
// CraftBukkit start
|
||||
+ CollisionContext collisionContext = player == null ? CollisionContext.empty() : CollisionContext.placementContext(player);
|
||||
Level world = context.getLevel(); // Paper - Cancel hit for vanished players
|
||||
- boolean canBuild = (!this.mustSurvive() || state.canSurvive(world, context.getClickedPos())) && world.checkEntityCollision(state, player, CollisionContext.placementContext(player), context.getClickedPos(), true); // Paper - Cancel hit for vanished players
|
||||
+ boolean canBuild = (!this.mustSurvive() || state.canSurvive(world, context.getClickedPos())) && ((fun.bm.lophine.config.modules.function.CreativeFlyNoClipConfig.enabled && context.getPlayer() != null) ? context.getPlayer().canSpectatingPlace(world, state, context.getClickedPos(), collisionContext) : world.checkEntityCollision(state, player, collisionContext, context.getClickedPos(), true)); // Paper - Cancel hit for vanished players // Leaves - creative no clip
|
||||
org.bukkit.entity.Player bukkitPlayer = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null;
|
||||
|
||||
org.bukkit.event.block.BlockCanBuildEvent event = new org.bukkit.event.block.BlockCanBuildEvent(
|
||||
diff --git a/net/minecraft/world/item/StandingAndWallBlockItem.java b/net/minecraft/world/item/StandingAndWallBlockItem.java
|
||||
index be685383b8e7c8111e976fc560f16d43d6545a34..6a2219b45eae0ff6fc48de9a6e6cabf2ec60cb07 100644
|
||||
--- a/net/minecraft/world/item/StandingAndWallBlockItem.java
|
||||
+++ b/net/minecraft/world/item/StandingAndWallBlockItem.java
|
||||
@@ -44,7 +44,7 @@ public class StandingAndWallBlockItem extends BlockItem {
|
||||
// return blockState != null && level.isUnobstructed(blockState, clickedPos, CollisionContext.empty()) ? blockState : null;
|
||||
// CraftBukkit start
|
||||
if (blockState != null) {
|
||||
- boolean defaultReturn = level.isUnobstructed(blockState, clickedPos, CollisionContext.empty());
|
||||
+ boolean defaultReturn = (fun.bm.lophine.config.modules.function.CreativeFlyNoClipConfig.enabled && context.getPlayer() != null) ? context.getPlayer().canSpectatingPlace(level, blockState, clickedPos, CollisionContext.empty()) : level.isUnobstructed(blockState, clickedPos, CollisionContext.empty()); // Leaves - creative no clip
|
||||
org.bukkit.entity.Player player = (context.getPlayer() instanceof net.minecraft.server.level.ServerPlayer serverPlayer) ? serverPlayer.getBukkitEntity() : null;
|
||||
|
||||
org.bukkit.event.block.BlockCanBuildEvent event = new org.bukkit.event.block.BlockCanBuildEvent(org.bukkit.craftbukkit.block.CraftBlock.at(context.getLevel(), clickedPos), player, org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(blockState), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent
|
||||
diff --git a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
||||
index 17110035f4b0f144c29b8ff8bf7d0d39efc8103a..1b7f0bfa66e632678164ac64e03855e75bab1305 100644
|
||||
--- a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
||||
@@ -153,7 +153,7 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl
|
||||
List<Entity> entities = level.getEntities(null, progressDeltaAabb);
|
||||
if (!entities.isEmpty()) {
|
||||
for (Entity entity : entities) {
|
||||
- if (entity.getPistonPushReaction() != PushReaction.IGNORE) {
|
||||
+ if (entity.getPistonPushReaction() != PushReaction.IGNORE && !(entity instanceof net.minecraft.world.entity.player.Player player && player.isCreativeFlyOrSpectator())) { // Leaves - creative no clip
|
||||
entity.move(
|
||||
MoverType.SHULKER_BOX,
|
||||
new Vec3(
|
||||
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
index 1d60054146f970ec24054d2c76a27e2d8620ec67..a5469971734a3f4f08d676426821fbf059c526dc 100644
|
||||
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
@@ -161,7 +161,7 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
||||
d3 = movementDirection.getStepZ();
|
||||
}
|
||||
|
||||
- entity.setDeltaMovement(d1, d2, d3);
|
||||
+ if (!(entity instanceof net.minecraft.world.entity.player.Player player) || !player.isCreativeFlyOrSpectator()) entity.setDeltaMovement(d1, d2, d3); // Leaves - creative no clip
|
||||
// Paper - EAR items stuck in slime pushed by a piston
|
||||
entity.activatedTick = Math.max(entity.activatedTick, io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() + 10); // Folia - region threading
|
||||
entity.activatedImmunityTick = Math.max(entity.activatedImmunityTick, io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() + 10); // Folia - region threading
|
||||
@@ -197,6 +197,7 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
||||
}
|
||||
|
||||
private static void moveEntityByPiston(Direction noClipDirection, Entity entity, double progress, Direction direction) {
|
||||
+ if (entity instanceof net.minecraft.world.entity.player.Player player && player.isCreativeFlyOrSpectator()) return; // Leaves - creative no clip
|
||||
NOCLIP.set(noClipDirection);
|
||||
Vec3 vec3 = entity.position();
|
||||
entity.move(MoverType.PISTON, new Vec3(progress * direction.getStepX(), progress * direction.getStepY(), progress * direction.getStepZ()));
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user