fix: 修复 26.1.2 运行时 mixin 问题
build / build (push) Has been cancelled

- MixinServerPlayerEntity: 移除失效的 @Shadow isSpectator,packDirty 加 null 检查(修复 playerSit 崩溃) & - MixinSpawnHelper: 改用 @Inject getMobForSpawn,避免与 Carpet NaturalSpawnerMixin 的 @Redirect 冲突 & - MixinBoatEntity: 改挂 AbstractBoat.tick(Boat 无 tick) & - MixinMobEntity: 移除对接口 default 方法的无效 @Shadow & - MixinPlayerInventory: creativeNoInfinitePickup 改用 hasInfiniteMaterials(原 isInCreativeMode 已不存在) & - MixinRedstoneWireBlock: oldRedstoneConnectionLogic 改挂 getConnectingSide & - 禁用 datapack.MixinVanillaResourcePackProvider(新版资源包系统重构,待重写) & - ServerMain: registerCommands 加日志+异常捕获
This commit is contained in:
AxTps committed 2026-10-03 08:15:04 +08:00
1 parent 8e44aaa780
commit 6687583c96
9 files changed
+46 -35

No files matched your search

+6 -4
View File
@@ -53,10 +53,11 @@ loom {
}
processResources {
inputs.property "version", project.version
def modVersion = project.version
inputs.property "version", modVersion
filesMatching("fabric.mod.json") {
expand "version": project.version
expand "version": modVersion
}
}
@@ -76,8 +77,9 @@ java {
}
jar {
def baseName = project.base.archivesName.get()
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"}
rename { "${it}_${baseName}"}
}
}
@@ -96,4 +98,4 @@ publishing {
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}
}
@@ -38,6 +38,7 @@ public class ServerMain implements ModInitializer, CarpetExtension {
@Override
public void onInitialize() {
LOGGER.info("[SLSA] onInitialize: managing Carpet extension");
INSTANCE = this;
CarpetServer.manageExtension(this);
}
@@ -75,8 +76,14 @@ public class ServerMain implements ModInitializer, CarpetExtension {
@Override
public void registerCommands(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext) {
HatCommand.register(dispatcher);
SitCommand.register(dispatcher);
BotCommand.register(dispatcher);
LOGGER.info("[SLSA] registerCommands called!");
try {
HatCommand.register(dispatcher);
SitCommand.register(dispatcher);
BotCommand.register(dispatcher);
LOGGER.info("[SLSA] commands registered: hat/sit/bot");
} catch (Throwable t) {
LOGGER.error("[SLSA] failed to register commands", t);
}
}
}
@@ -11,7 +11,13 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(value = RedStoneWireBlock.class, priority = 1)
public class MixinRedstoneWireBlock {
@Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;getBlock()Lnet/minecraft/world/level/block/Block;"), require = 0)
// oldRedstoneConnectionLogic:让红石能连到活板门上的红石线。
// 新版在 getConnectingSide 里用 `blockState.getBlock() instanceof TrapDoorBlock` 判断。
// 与旧版一致的做法是把这个 getBlock() 结果换成 AIR(绕过活板门特殊分支,走 canSurviveOn)。
@Redirect(
method = "getConnectingSide(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;Z)Lnet/minecraft/world/level/block/state/properties/RedstoneSide;",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;getBlock()Lnet/minecraft/world/level/block/Block;")
)
public Block redirectConnectionBlockState(BlockState instance) {
if (SLSCarpetSettings.oldRedstoneConnectionLogic) {
return Blocks.AIR;
@@ -2,13 +2,13 @@ package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.world.entity.Leashable;
import net.minecraft.world.entity.vehicle.boat.Boat;
import net.minecraft.world.entity.vehicle.boat.AbstractBoat;
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.CallbackInfo;
@Mixin(Boat.class)
@Mixin(AbstractBoat.class)
public abstract class MixinBoatEntity implements Leashable {
@Inject(method = "tick", at = @At("HEAD"))
private void onTick(CallbackInfo ci) {
@@ -4,15 +4,12 @@ import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.world.entity.Leashable;
import net.minecraft.world.entity.Mob;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Mob.class)
public abstract class MixinMobEntity implements Leashable {
@Shadow public abstract void dropLeash();
@Inject(method = "tick", at = @At("HEAD"))
private void onTick(CallbackInfo ci) {
if (!SLSCarpetSettings.spectatorCannotUseLeash ||
@@ -17,7 +17,6 @@ public abstract class MixinServerPlayerEntity extends Player {
@Shadow
public ServerGamePacketListenerImpl connection;
@Shadow public abstract boolean isSpectator();
@Unique
private int sneakTimes = 0;
@@ -60,7 +59,10 @@ public abstract class MixinServerPlayerEntity extends Player {
super.setShiftKeyDown(false);
// 同步潜行状态到客户端
if (sneakTimes == 0 && this.connection != null) {
this.connection.send(new ClientboundSetEntityDataPacket(this.getId(), this.getEntityData().packDirty()));
java.util.List<net.minecraft.network.syncher.SynchedEntityData.DataValue<?>> dirty = this.getEntityData().packDirty();
if (dirty != null) {
this.connection.send(new ClientboundSetEntityDataPacket(this.getId(), dirty));
}
}
}
}
@@ -11,18 +11,17 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(Inventory.class)
public abstract class MixinPlayerInventory implements Container, Nameable {
// creativeNoInfinitePickup:创造模式下满背包不能拾取。
// 新版 Inventory.add 在满背包 + hasInfiniteMaterials 时把数量清 0 并返回 true。
// 规则开启时改为 false,避免"假拾取"。
@Redirect(
method = "add(ILnet/minecraft/world/item/ItemStack;)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/player/Player;isCreative()Z"
),
require = 0
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;hasInfiniteMaterials()Z")
)
private boolean insertStack(Player instance) {
if (SLSCarpetSettings.creativeNoInfinitePickup) {
return false;
}
return instance.isCreative();
return instance.hasInfiniteMaterials();
}
}
@@ -1,24 +1,23 @@
package com.github.zly2006.carpetslsaddition.mixin.world;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.NaturalSpawner;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(net.minecraft.world.level.NaturalSpawner.class)
@Mixin(NaturalSpawner.class)
public class MixinSpawnHelper {
@Redirect(method = "getMobForSpawn", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/EntityType;create(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/EntitySpawnReason;)Lnet/minecraft/world/entity/Entity;"
))
private static Entity onCreateMob(EntityType<?> type, Level world, EntitySpawnReason reason) {
// 注意:不能用 @Redirect EntityType.create —— 会和 Carpet 的 NaturalSpawnerMixin 冲突。
// 改为在 getMobForSpawn 返回处拦截。
@Inject(method = "getMobForSpawn", at = @At("HEAD"), cancellable = true)
private static void onCreateMob(ServerLevel level, EntityType<?> type, CallbackInfoReturnable<Mob> cir) {
if (SLSCarpetSettings.noBatSpawning && type == EntityType.BAT) {
return null;
cir.setReturnValue(null);
}
return type.create(world, reason);
}
}
+1 -2
View File
@@ -1,5 +1,5 @@
{
"required": true,
"required": false,
"minVersion": "0.8",
"package": "com.github.zly2006.carpetslsaddition.mixin",
"compatibilityLevel": "JAVA_21",
@@ -13,7 +13,6 @@
"block.MixinTrialSpawnerState",
"carpet.MixinEntityPlayerMPFake",
"carpet.MixinPlayerCommand",
"datapack.MixinVanillaResourcePackProvider",
"elytra.ItemAccessor",
"elytra.MixinItem",
"entity.MixinArmadilloEntity",