9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-31 04:46:37 +00:00

修复碰撞体积不同步

This commit is contained in:
XiaoMoMi
2025-05-25 22:57:50 +08:00
parent 6326ca5808
commit a679027c6a
14 changed files with 77 additions and 18 deletions

View File

@@ -1,6 +1,6 @@
package net.momirealms.craftengine.bukkit.block;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.shared.block.BlockShape;
public class BukkitBlockShape implements BlockShape {
@@ -11,7 +11,12 @@ public class BukkitBlockShape implements BlockShape {
}
@Override
public Object getShape(Object thisObj, Object[] args) throws Exception {
return Reflections.method$BlockBehaviour$getShape.invoke(Reflections.field$StateHolder$owner.get(this.rawBlockState), this.rawBlockState, args[1], args[2], args[3]);
public Object getShape(Object thisObj, Object[] args) {
return FastNMS.INSTANCE.method$BlockState$getShape(this.rawBlockState, args[1], args[2], args[3]);
}
@Override
public Object getCollisionShape(Object thisObj, Object[] args) {
return FastNMS.INSTANCE.method$BlockState$getCollisionShape(this.rawBlockState, args[1], args[2], args[3]);
}
}

View File

@@ -93,7 +93,7 @@ public class NearLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior {
if (Reflections.method$FluidState$getType.invoke(fluidStateAbove) != Reflections.instance$Fluids$EMPTY) {
return false;
}
if (this.onWater && (WATER.contains(Reflections.method$FluidState$getType.invoke(fluidState)) || Reflections.field$StateHolder$owner.get(belowState) == Reflections.instance$Blocks$ICE)) {
if (this.onWater && (WATER.contains(Reflections.method$FluidState$getType.invoke(fluidState)) || FastNMS.INSTANCE.method$BlockState$getBlock(belowState) == Reflections.instance$Blocks$ICE)) {
return true;
}
if (this.onLava && LAVA.contains(Reflections.method$FluidState$getType.invoke(fluidState))) {

View File

@@ -71,7 +71,7 @@ public class OnLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior {
if (Reflections.method$FluidState$getType.invoke(fluidStateAbove) != Reflections.instance$Fluids$EMPTY) {
return false;
}
if (this.onWater && (Reflections.method$FluidState$getType.invoke(fluidState) == Reflections.instance$Fluids$WATER || Reflections.field$StateHolder$owner.get(belowState) == Reflections.instance$Blocks$ICE)) {
if (this.onWater && (Reflections.method$FluidState$getType.invoke(fluidState) == Reflections.instance$Fluids$WATER || FastNMS.INSTANCE.method$BlockState$getBlock(belowState) == Reflections.instance$Blocks$ICE)) {
return true;
}
if (this.onLava && Reflections.method$FluidState$getType.invoke(fluidState) == Reflections.instance$Fluids$LAVA) {

View File

@@ -248,6 +248,9 @@ public class BukkitInjector {
// getShape
.method(ElementMatchers.is(Reflections.method$BlockBehaviour$getShape))
.intercept(MethodDelegation.to(GetShapeInterceptor.INSTANCE))
// getCollisionShape
.method(ElementMatchers.is(Reflections.method$BlockBehaviour$getCollisionShape))
.intercept(MethodDelegation.to(GetCollisionShapeInterceptor.INSTANCE))
// mirror
.method(ElementMatchers.is(Reflections.method$BlockBehaviour$mirror))
.intercept(MethodDelegation.to(MirrorInterceptor.INSTANCE))
@@ -923,6 +926,21 @@ public class BukkitInjector {
}
}
public static class GetCollisionShapeInterceptor {
public static final GetCollisionShapeInterceptor INSTANCE = new GetCollisionShapeInterceptor();
@RuntimeType
public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) throws Exception {
ObjectHolder<BlockShape> holder = ((ShapeHolder) thisObj).getShapeHolder();
try {
return holder.value().getCollisionShape(thisObj, args);
} catch (Exception e) {
CraftEngine.instance().logger().severe("Failed to run getCollisionShape", e);
return superMethod.call();
}
}
}
public static class MirrorInterceptor {
public static final MirrorInterceptor INSTANCE = new MirrorInterceptor();

View File

@@ -1209,7 +1209,7 @@ public class PacketConsumers {
// not a custom block
if (BlockStateUtils.isVanillaBlock(stateId)) {
if (Config.enableSoundSystem()) {
Object blockOwner = Reflections.field$StateHolder$owner.get(blockState);
Object blockOwner = FastNMS.INSTANCE.method$BlockState$getBlock(blockState);
if (BukkitBlockManager.instance().isBlockSoundRemoved(blockOwner)) {
player.startMiningBlock(pos, blockState, null);
return;

View File

@@ -531,7 +531,7 @@ public class BukkitServerPlayer extends Player {
// send hit sound if the sound is removed
if (currentTick - this.lastHitBlockTime > 3) {
Object blockOwner = Reflections.field$StateHolder$owner.get(this.destroyedState);
Object blockOwner = FastNMS.INSTANCE.method$BlockState$getBlock(this.destroyedState);
Object soundType = Reflections.field$BlockBehaviour$soundType.get(blockOwner);
Object soundEvent = Reflections.field$SoundType$hitSound.get(soundType);
Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent);

View File

@@ -140,11 +140,7 @@ public class BlockStateUtils {
}
public static Object getBlockOwner(Object blockState) {
try {
return Reflections.field$StateHolder$owner.get(blockState);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
return FastNMS.INSTANCE.method$BlockState$getBlock(blockState);
}
public static int physicsEventToId(BlockPhysicsEvent event) throws ReflectiveOperationException {

View File

@@ -2523,11 +2523,11 @@ public class Reflections {
)
);
public static final Field field$StateHolder$owner = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$StateHolder, Object.class, 0
)
);
// public static final Field field$StateHolder$owner = requireNonNull(
// ReflectionUtils.getDeclaredField(
// clazz$StateHolder, Object.class, 0
// )
// );
public static final Class<?> clazz$CollisionContext = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
@@ -2542,6 +2542,12 @@ public class Reflections {
)
);
public static final Method method$BlockBehaviour$getCollisionShape = requireNonNull(
ReflectionUtils.getDeclaredMethod(
clazz$BlockBehaviour, clazz$VoxelShape, new String[]{"getCollisionShape", "c"}, clazz$BlockState, clazz$BlockGetter, clazz$BlockPos, clazz$CollisionContext
)
);
public static final Method method$BlockBehaviour$tick = requireNonNull(
ReflectionUtils.getDeclaredMethod(
clazz$BlockBehaviour, void.class, new String[]{"tick", "a"}, clazz$BlockState, clazz$ServerLevel, clazz$BlockPos, clazz$RandomSource
@@ -6803,4 +6809,10 @@ public class Reflections {
Optional.ofNullable(ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, void.class, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Block, clazz$BlockPos, boolean.class))
.orElse(ReflectionUtils.getMethod(clazz$BlockBehaviour, void.class, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Block, clazz$BlockPos, boolean.class))
);
// public static final Method method$BlockBehaviour$getEntityInsideCollisionShape = requireNonNull(
// ReflectionUtils.getDeclaredMethod(
// clazz$BlockBehaviour, clazz$VoxelShape, clazz$BlockState, clazz$BlockGetter, clazz$BlockPos, clazz$Entity
// )
// );
}