如何使用 mixins 更改接口的方法?在 Minecraft Forge 1.18.2 上使用 Spongepowered

问题描述 投票:0回答:1

所以我正在使用 IntelliJ IDEA 来修改 Minecraft Forge 1.18.2,并且我尝试使用 SpongePowered mixins 来更改

isEmptyBlock
类的
LevelReader
方法。

但是

LevelReader
是一个界面,如果我尝试编辑界面,模组将不会运行。 在InterWebs上找了好久,还是一无所获。

所以问题是:

那么如何更改接口的方法呢?

我正在使用此代码:在:

MixinLevelReader

package net.iateminecraft.jetpacksfix.mixin;

import com.mojang.logging.LogUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.LevelAccessor;
import org.slf4j.Logger;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(LevelReader.class)
public abstract class MixinLevelReader {
    @Unique
    private static final Logger LOGGER = LogUtils.getLogger();
    @Unique
    LevelAccessor world = (LevelAccessor) (Object) this;

    @Inject(at = @At("HEAD"), method = "isEmptyBlock(Lnet/minecraft/core/BlockPos;)Z", cancellable = true)
    private void isEmptyBlock(BlockPos blockposition, CallbackInfoReturnable<Boolean> callback) {
        LOGGER.info(String.valueOf(world.getBlockState(blockposition).isAir()));
        callback.setReturnValue(world.getBlockState(blockposition).isAir());
    }
}

当我运行

./gradlew :build
时,它会编译得很好,但是一旦我运行
./gradlew :runClient
,就会出现错误:
Caused by: org.spongepowered.asm.mixin.transformer.throwables.InvalidMixinException: @Mixin target type mismatch: net.minecraft.world.level.LevelReader is an interface in org.spongepowered.asm.mixin.transformer.MixinInfo$SubType$Standard@75b6dd5b

java minecraft mixins minecraft-forge spongeapi
1个回答
0
投票

在 Forge 上,您将无法这样做,因为 1.18.2 中使用的版本太旧,无法在界面上使用

@Redirect
@Inject
的新功能。您必须使用完整默认方法的
@Overwrite
,这样您就可以在正确的位置添加代码。另一种方法是在
@Override
之类的东西上使用
ServerLevel
,您可以在其中添加一个“实现”默认父方法的方法:


    @Override
    public boolean isEmptyBlock(BlockPos pos) {
        // Do something before
        if (net.minecraft.world.level.LevelReader.super.isEmptyBlock(isEmptyBlock)) {
            // do something after if true
        }
        // do something here as well
    }
© www.soinside.com 2019 - 2024. All rights reserved.