feat: 落沙替换改回固定目标版,移除记录器mixin
build / build (push) Has been cancelled

记录+回放方案会把沙子替换成自己(记录命中沙子自身变更),不可用。改为沙子下落直接变legacyFallingBlockTarget。移除LevelChunkMixin。
This commit is contained in:
AxTps committed 2026-10-04 20:36:57 +08:00
1 parent a32a784f87
commit 01dc9fa79c
4 files changed
+18 -50

No files matched your search

@@ -2,18 +2,22 @@ package com.github.zly2006.carpetslsaddition.mixin.legacy;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.util.LegacyBlockChangeRecorder;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.Identifier;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
/**
* [旧版] 落沙替换的核心注入点——重建 1.12 的"替换窗口"(记录+回放版)。
* [旧版] 落沙替换——固定目标版。
*
* <p>当 {@code legacyFallingBlockReplace} 开启时,若该位置在最近 {@code WINDOW_TICKS} 内被改动过,
* 就用记录的新方块作为下落实体的内容。这样玩家搭建的装置(改变世界方块)会决定下落实体的内容。
* <p>26.1.2 单线程下 1.12 的"替换窗口"物理不存在,本 mixin 采用直接方案:
* 当 {@code legacyFallingBlockReplace} 开启且配置了 {@code legacyFallingBlockTarget} 时,
* 把下落实体的方块状态替换为目标方块的默认状态——沙子下落即变目标方块。
*/
@Mixin(net.minecraft.world.entity.item.FallingBlockEntity.class)
public class FallingBlockEntityMixin {
@@ -24,17 +28,19 @@ public class FallingBlockEntityMixin {
argsOnly = true,
index = 2
)
private static BlockState legacyReplaceFallingState(BlockState original, net.minecraft.world.level.Level level, BlockPos pos, BlockState state) {
private static BlockState legacyReplaceFallingState(BlockState original, Level level, BlockPos pos, BlockState state) {
if (!SLSCarpetSettings.legacyExploitMode || !SLSCarpetSettings.legacyFallingBlockReplace) {
return original;
}
ServerMain.LOGGER.info("[SLSA-DEBUG] fall() pos={} original={}", pos, original.getBlock());
BlockState recent = LegacyBlockChangeRecorder.getRecentChange(pos);
if (recent != null && !recent.isAir()) {
ServerMain.LOGGER.info("[SLSA-DEBUG] >>> REPLACE at {}: {} -> {}", pos, original.getBlock(), recent.getBlock());
return recent;
String target = SLSCarpetSettings.legacyFallingBlockTarget;
if (target == null || target.isEmpty() || "#none".equals(target)) {
return original;
}
ServerMain.LOGGER.info("[SLSA-DEBUG] no recent change at {}, recent={}", pos, recent);
return original;
Block block = BuiltInRegistries.BLOCK.getOptional(Identifier.withDefaultNamespace(target)).orElse(null);
if (block == null) {
return original;
}
ServerMain.LOGGER.info("[SLSA-DEBUG] >>> REPLACE at {}: {} -> {}", pos, original.getBlock(), block);
return block.defaultBlockState();
}
}
@@ -34,7 +34,6 @@ public abstract class FallingBlockMixin {
@Inject(method = "getDelayAfterPlace", at = @At("HEAD"), cancellable = true)
private void legacyDelayAfterPlace(CallbackInfoReturnable<Integer> cir) {
if (SLSCarpetSettings.legacyExploitMode && SLSCarpetSettings.legacyInstantFall) {
com.github.zly2006.carpetslsaddition.ServerMain.LOGGER.info("[SLSA-DEBUG] getDelayAfterPlace called -> 0");
cir.setReturnValue(0);
}
}
@@ -73,7 +72,6 @@ public abstract class FallingBlockMixin {
@Inject(method = "tick", at = @At("HEAD"))
private void legacyTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource rand, CallbackInfo ci) {
if (SLSCarpetSettings.legacyExploitMode && SLSCarpetSettings.legacyInstantFall) {
com.github.zly2006.carpetslsaddition.ServerMain.LOGGER.info("[SLSA-DEBUG] FallingBlock.tick pos={}", pos);
LegacyExploitState.markInstantFall(pos);
}
}
@@ -1,35 +0,0 @@
package com.github.zly2006.carpetslsaddition.mixin.legacy;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.util.LegacyBlockChangeRecorder;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/**
* [旧版] 方块变更记录——为"替换窗口"提供数据源。
*
* <p>hook {@link LevelChunk#setBlockState}:当规则开启时,记录每次方块变更(位置 + 新状态 + 当前 tick)。
* 重力方块下落时({@code FallingBlockEntityMixin})会查询此记录,
* 若该位置"刚被改过",就用记录的新方块作为下落实体内容——重建 1.12 的窗口替换效果。
*
* <p>仅在 {@code legacyExploitMode} + {@code legacyFallingBlockReplace} 同时开启时记录,避免性能损耗。
*/
@Mixin(LevelChunk.class)
public abstract class LevelChunkMixin {
@Inject(method = "setBlockState", at = @At("RETURN"))
private void legacyRecordBlockChange(BlockPos pos, BlockState newState, int flags, CallbackInfoReturnable<BlockState> cir) {
if (!SLSCarpetSettings.legacyExploitMode || !SLSCarpetSettings.legacyFallingBlockReplace) {
return;
}
if (newState == null) {
return;
}
LegacyBlockChangeRecorder.record(pos, newState);
}
}
@@ -20,7 +20,6 @@
"legacy.FallingBlockEntityMixin",
"legacy.ScheduledTickMixin",
"legacy.ChunkMapMixin",
"legacy.LevelChunkMixin",
"entity.MixinArmadilloEntity",
"entity.MixinArmorStandEntity",
"entity.MixinBoatEntity",