mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-26 18:39:23 +00:00
Current implementation of OP lock is not an appropriate solution to prevent plugins that contain backdoor or malicious code. There are many ways to bypass this check to manipulate the OP list or permissions. The best way to prevent this kind of grief is to get plugins from valid and trustworthy places.
290 lines
14 KiB
Diff
290 lines
14 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: hayanesuru <hayanesuru@outlook.jp>
|
|
Date: Sat, 9 Aug 2025 18:12:11 +0900
|
|
Subject: [PATCH] optimize checkInsideBlocks
|
|
|
|
|
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
|
index 0366217ac729a967ba69fb256481479255d347be..afc9788b69a9398c295a6fe3801b82fb6d6c3384 100644
|
|
--- a/net/minecraft/world/entity/Entity.java
|
|
+++ b/net/minecraft/world/entity/Entity.java
|
|
@@ -1818,72 +1818,57 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
private void checkInsideBlocks(Vec3 vec3, Vec3 vec31, InsideBlockEffectApplier.StepBasedCollector stepBasedCollector, LongSet set) {
|
|
final Level level = this.level();
|
|
AABB aabb = this.getBoundingBox().move(vec31.subtract(this.position())).deflate(1.0E-5F);
|
|
- final net.minecraft.world.level.chunk.ChunkAccess[] cachedChunk = { null };
|
|
- final long[] cachedChunkPos = { Long.MIN_VALUE };
|
|
|
|
- BlockGetter.forEachBlockIntersectedBetween(
|
|
+ BlockGetter.leaf$forEachBlockIntersectedBetween(
|
|
+ set,
|
|
vec3,
|
|
vec31,
|
|
aabb,
|
|
(pos, index) -> {
|
|
+ final int posX = pos.getX();
|
|
+ final int posY = pos.getY();
|
|
+ final int posZ = pos.getZ();
|
|
+ BlockState blockState = level.getBlockStateIfLoadedUnchecked(posX, posY, posZ);
|
|
+ if (blockState == null) {
|
|
+ blockState = level.getBlockState(pos);
|
|
+ }
|
|
+ if (blockState.isAir()) {
|
|
+ this.debugBlockIntersection(pos, false, false);
|
|
+ return true;
|
|
+ }
|
|
if (!this.isAlive()) {
|
|
return false;
|
|
- } else {
|
|
- final int chunkX = pos.getX() >> 4;
|
|
- final int chunkZ = pos.getZ() >> 4;
|
|
- final long currentChunkPos = ChunkPos.asLong(chunkX, chunkZ);
|
|
- BlockState blockState;
|
|
-
|
|
- if (cachedChunkPos[0] != currentChunkPos) {cachedChunk[0] = level.getChunkIfLoaded(chunkX, chunkZ);cachedChunkPos[0] = currentChunkPos;}
|
|
-
|
|
- if (cachedChunk[0] != null) {blockState = cachedChunk[0].getBlockState(pos);
|
|
- } else {
|
|
- blockState = level.getBlockStateIfLoaded(pos);
|
|
- if (blockState == null) {blockState = Blocks.AIR.defaultBlockState();}
|
|
+ }
|
|
+ VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(level, pos, this);
|
|
+ boolean flag = entityInsideCollisionShape == Shapes.block()
|
|
+ || this.collidedWithShapeMovingFrom(vec3, vec31, entityInsideCollisionShape.move(new Vec3(pos)).toAabbs());
|
|
+ if (flag) {
|
|
+ try {
|
|
+ stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on
|
|
+ blockState.entityInside(level, pos, this, stepBasedCollector);
|
|
+ this.onInsideBlock(blockState);
|
|
+ } catch (Throwable var14) {
|
|
+ CrashReport crashReport = CrashReport.forThrowable(var14, "Colliding entity with block");
|
|
+ CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with");
|
|
+ CrashReportCategory.populateBlockDetails(crashReportCategory, level, pos, blockState);
|
|
+ CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision");
|
|
+ this.fillCrashReportCategory(crashReportCategory1);
|
|
+ throw new ReportedException(crashReport);
|
|
}
|
|
+ }
|
|
|
|
- final long posLong = pos.asLong();
|
|
- if (blockState.isAir()) {
|
|
- this.debugBlockIntersection(pos, false, false);
|
|
- return true;
|
|
- } else if (!set.add(posLong)) {
|
|
- return true;
|
|
- } else {
|
|
- VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(level, pos, this);
|
|
- boolean flag = entityInsideCollisionShape == Shapes.block()
|
|
- || this.collidedWithShapeMovingFrom(vec3, vec31, entityInsideCollisionShape.move(new Vec3(pos)).toAabbs());
|
|
-
|
|
- if (flag) {
|
|
- try {
|
|
- stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on
|
|
- blockState.entityInside(level, pos, this, stepBasedCollector);
|
|
- this.onInsideBlock(blockState);
|
|
- } catch (Throwable var14) {
|
|
- CrashReport crashReport = CrashReport.forThrowable(var14, "Colliding entity with block");
|
|
- CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with");
|
|
- CrashReportCategory.populateBlockDetails(crashReportCategory, level, pos, blockState);
|
|
- CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision");
|
|
- this.fillCrashReportCategory(crashReportCategory1);
|
|
- throw new ReportedException(crashReport);
|
|
- }
|
|
- }
|
|
-
|
|
- final FluidState fluidState = blockState.getFluidState();
|
|
- boolean flag1 = !fluidState.isEmpty() && this.collidedWithFluid(fluidState, pos, vec3, vec31);
|
|
-
|
|
- if (flag1) {
|
|
- stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on
|
|
- fluidState.entityInside(level, pos, this, stepBasedCollector);
|
|
- }
|
|
-
|
|
- this.debugBlockIntersection(pos, flag, flag1);
|
|
- return true;
|
|
- }
|
|
+ boolean flag1 = (blockState.tagFlag & org.dreeam.leaf.util.BlockMasks.FLUID) != 0
|
|
+ && this.collidedWithFluid(blockState.getFluidState(), pos, vec3, vec31);
|
|
+ if (flag1) {
|
|
+ stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on
|
|
+ blockState.getFluidState().entityInside(level, pos, this, stepBasedCollector);
|
|
}
|
|
+ this.debugBlockIntersection(pos, flag, flag1);
|
|
+ return true;
|
|
}
|
|
);
|
|
}
|
|
-// Leaf end - optimize checkInsideBlocks calls
|
|
+ // Leaf end - optimize checkInsideBlocks calls
|
|
|
|
private void debugBlockIntersection(BlockPos blockPos, boolean flag, boolean flag1) {
|
|
}
|
|
diff --git a/net/minecraft/world/entity/InsideBlockEffectApplier.java b/net/minecraft/world/entity/InsideBlockEffectApplier.java
|
|
index 92b9c324cb6aab415abe2e77c5844b74c251a42f..eba3896b73c70f29732388373e89bf7ce3a07c92 100644
|
|
--- a/net/minecraft/world/entity/InsideBlockEffectApplier.java
|
|
+++ b/net/minecraft/world/entity/InsideBlockEffectApplier.java
|
|
@@ -33,6 +33,7 @@ public interface InsideBlockEffectApplier {
|
|
// Leaf start - optimize checkInsideBlocks calls
|
|
private static final InsideBlockEffectType[] APPLY_ORDER = InsideBlockEffectType.values();
|
|
private static final int NO_STEP = -1;
|
|
+ private int flags = 0;
|
|
|
|
private final Consumer<Entity>[] effectsInStep = new Consumer[APPLY_ORDER.length];
|
|
private final List<Consumer<Entity>>[] beforeEffectsInStep = new List[APPLY_ORDER.length];
|
|
@@ -40,13 +41,13 @@ public interface InsideBlockEffectApplier {
|
|
|
|
private static final List<Consumer<Entity>> EMPTY_LIST = List.of();
|
|
|
|
- private final List<Consumer<Entity>> finalEffects = new ArrayList<>();
|
|
+ private final List<Consumer<Entity>> finalEffects = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
|
private int lastStep = -1;
|
|
|
|
public StepBasedCollector() {
|
|
for (int i = 0; i < APPLY_ORDER.length; i++) {
|
|
- beforeEffectsInStep[i] = new ArrayList<>(2);
|
|
- afterEffectsInStep[i] = new ArrayList<>(2);
|
|
+ beforeEffectsInStep[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(2);
|
|
+ afterEffectsInStep[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(2);
|
|
}
|
|
}
|
|
|
|
@@ -100,6 +101,10 @@ public interface InsideBlockEffectApplier {
|
|
}
|
|
|
|
private void flushStep() {
|
|
+ final int flags = this.flags;
|
|
+ if (flags == 0) {
|
|
+ return;
|
|
+ }
|
|
final int len = APPLY_ORDER.length;
|
|
final List<Consumer<Entity>>[] beforeArr = this.beforeEffectsInStep;
|
|
final Consumer<Entity>[] effectArr = this.effectsInStep;
|
|
@@ -107,6 +112,9 @@ public interface InsideBlockEffectApplier {
|
|
final List<Consumer<Entity>> finalList = this.finalEffects;
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
+ if (((1 << i) & flags) == 0) {
|
|
+ continue;
|
|
+ }
|
|
// Process before effects
|
|
List<Consumer<Entity>> beforeList = beforeArr[i];
|
|
if (!beforeList.isEmpty()) {
|
|
@@ -128,21 +136,28 @@ public interface InsideBlockEffectApplier {
|
|
afterList.clear();
|
|
}
|
|
}
|
|
+ this.flags = 0;
|
|
}
|
|
|
|
@Override
|
|
public void apply(InsideBlockEffectType type) {
|
|
- effectsInStep[type.ordinal()] = recorded(type);
|
|
+ int i = type.ordinal();
|
|
+ effectsInStep[i] = recorded(type);
|
|
+ this.flags |= 1 << i;
|
|
}
|
|
|
|
@Override
|
|
public void runBefore(InsideBlockEffectType type, Consumer<Entity> effect) {
|
|
- beforeEffectsInStep[type.ordinal()].add(effect);
|
|
+ int i = type.ordinal();
|
|
+ beforeEffectsInStep[i].add(effect);
|
|
+ this.flags |= 1 << i;
|
|
}
|
|
|
|
@Override
|
|
public void runAfter(InsideBlockEffectType type, Consumer<Entity> effect) {
|
|
- afterEffectsInStep[type.ordinal()].add(effect);
|
|
+ int i = type.ordinal();
|
|
+ afterEffectsInStep[i].add(effect);
|
|
+ this.flags |= 1 << i;
|
|
}
|
|
|
|
// Paper start - track position inside effect was triggered on
|
|
diff --git a/net/minecraft/world/level/BlockGetter.java b/net/minecraft/world/level/BlockGetter.java
|
|
index eeddffbe6a47dc1a42c07f286bfec0cbde33fc17..b0da274c944fcef6aaae39b43f05a79110e4bb16 100644
|
|
--- a/net/minecraft/world/level/BlockGetter.java
|
|
+++ b/net/minecraft/world/level/BlockGetter.java
|
|
@@ -255,6 +255,81 @@ public interface BlockGetter extends LevelHeightAccessor {
|
|
}
|
|
}
|
|
|
|
+ // Leaf start
|
|
+ static boolean leaf$forEachBlockIntersectedBetween(it.unimi.dsi.fastutil.longs.LongSet set, Vec3 from, Vec3 to, AABB boundingBox, BlockGetter.BlockStepVisitor visitor) {
|
|
+ Vec3 vec3 = to.subtract(from);
|
|
+ BlockPos.MutableBlockPos cursor = new BlockPos.MutableBlockPos();
|
|
+ if (vec3.lengthSqr() < Mth.square(0.99999F)) {
|
|
+ int pos1x = Mth.floor(boundingBox.minX);
|
|
+ int pos1y = Mth.floor(boundingBox.minY);
|
|
+ int pos1z = Mth.floor(boundingBox.minZ);
|
|
+ int pos2x = Mth.floor(boundingBox.maxX);
|
|
+ int pos2y = Mth.floor(boundingBox.maxY);
|
|
+ int pos2z = Mth.floor(boundingBox.maxZ);
|
|
+ int x1 = Math.min(pos1x, pos2x);
|
|
+ int y1 = Math.min(pos1y, pos2y);
|
|
+ int z1 = Math.min(pos1z, pos2z);
|
|
+ int i = Math.max(pos1x, pos2x) - x1 + 1;
|
|
+ int i1 = Math.max(pos1y, pos2y) - y1 + 1;
|
|
+ int i2 = Math.max(pos1z, pos2z) - z1 + 1;
|
|
+ int i3 = i * i1 * i2;
|
|
+ int index = 0;
|
|
+ while (index != i3) {
|
|
+ int i4 = index % i;
|
|
+ int i5 = index / i;
|
|
+ int i6 = i5 % i1;
|
|
+ int i7 = i5 / i1;
|
|
+ index++;
|
|
+ int x0 = x1 + i4;
|
|
+ int y0 = y1 + i6;
|
|
+ int z0 = z1 + i7;
|
|
+ if (set.add(BlockPos.asLong(x0, y0, z0)) && !visitor.visit(cursor.set(x0, y0, z0), 0)) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ } else {
|
|
+ Vec3 minPosition = boundingBox.getMinPosition();
|
|
+ Vec3 vec31 = minPosition.subtract(vec3);
|
|
+ int i = addCollisionsAlongTravel(set, vec31, minPosition, boundingBox, visitor);
|
|
+ if (i < 0) {
|
|
+ return false;
|
|
+ } else {
|
|
+ int pos1x = Mth.floor(boundingBox.minX);
|
|
+ int pos1y = Mth.floor(boundingBox.minY);
|
|
+ int pos1z = Mth.floor(boundingBox.minZ);
|
|
+ int pos2x = Mth.floor(boundingBox.maxX);
|
|
+ int pos2y = Mth.floor(boundingBox.maxY);
|
|
+ int pos2z = Mth.floor(boundingBox.maxZ);
|
|
+ int x1 = Math.min(pos1x, pos2x);
|
|
+ int y1 = Math.min(pos1y, pos2y);
|
|
+ int z1 = Math.min(pos1z, pos2z);
|
|
+ int j = Math.max(pos1x, pos2x) - x1 + 1;
|
|
+ int i1 = Math.max(pos1y, pos2y) - y1 + 1;
|
|
+ int i2 = Math.max(pos1z, pos2z) - z1 + 1;
|
|
+ int i3 = j * i1 * i2;
|
|
+ int index = 0;
|
|
+ while (index != i3) {
|
|
+ int i4 = index % j;
|
|
+ int i5 = index / j;
|
|
+ int i6 = i5 % i1;
|
|
+ int i7 = i5 / i1;
|
|
+ index++;
|
|
+ int x0 = x1 + i4;
|
|
+ int y0 = y1 + i6;
|
|
+ int z0 = z1 + i7;
|
|
+ if (set.add(BlockPos.asLong(x0, y0, z0)) && !visitor.visit(cursor.set(x0, y0, z0), i + 1)) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Leaf end
|
|
+
|
|
private static int addCollisionsAlongTravel(LongSet output, Vec3 from, Vec3 to, AABB boundingBox, BlockGetter.BlockStepVisitor stepVisitor) {
|
|
Vec3 vec3 = to.subtract(from);
|
|
int floor = Mth.floor(from.x);
|